이전 포스트에서는 MySQL을 연동하는 방법을 알아보았습니다.

하지만 이 방법으로는 나중에 추가적인 기능을 개발하고, 또 다시 연동하는 데 있어서 매우 어려움이 있습니다..

즉, 계속해서 데이터베이스를 다시 접근하고 닫고를 반복해야 하는 이유 때문입니다.


따라서, DB를 따로 새로운 클래스로 구분하여 이를 사용하는 방법이 필요합니다.


이번에는 MySQL을 이용하기 위한 클래스 생성 및 연동하는 방법을 알아보도록 하겠습니다.


다른 플라스크 예제는 아래의 링크를 살펴봐주시기 바랍니다~



[Python Flask] 웹 페이지 만들기 01 - 환경 설정

[Python Flask] 웹 페이지 만들기 02 - 기본 파일 작성하기

[Python Flask] 웹 페이지 만들기 03 - 파이썬에서 웹으로 값 전달

[Python Flask] 웹 페이지 만들기 04 - Bootstrap 연동하기

[Python Flask] 웹 페이지 만들기 05 - MySQL 연동하기(pymysql)






01. 개발 디렉토리 설정 변경

먼저 개발을 수행하기 앞서, 프로젝트 내부에 있는 디렉토리를 추가적으로 생성할 필요가 있습니다.

우리가 추가할 디렉토리는 다음과 같이 나타나 있습니다.


[Project Name]

└ [app]

      └ [test]

            └ 테스트를 위한 폴더

      └ [module]

            └ 모듈로써 사용할 python 소스

      └ [schema]

            └ MySQL에서 실행할 SQL 소스

      └ [static]

            └ 자바스크립트, CSS, 이미지 등...

      └ [templates]

            └ HTML 파일들(폴더별로 정리 가능)

            └ [test]

                  └ 테스트를 위한 폴더

└ config.py

└ run.py


기존의 디렉토리에 module이라는 폴더를 새로 생성하고 그 아래에 우리가 사용할 module로써 사용할 python 소스를 작성할 것입니다.

여기서 우리는 dbModule.py라는 파일을 생성합니다.




02. Database 클래스 모듈 파일 작성

이 파일은 새로운 기능을 생성할 때마다 import 시켜 사용될 파일입니다.

dbModule.py 파일은 다음과 같습니다.

# file name : dbModule.py
# pwd : /project_name/app/module/dbModule.py

import pymysql

class Database():
    def __init__(self):
        self.db = pymysql.connect(host='localhost',
                                  user='root',
                                  password='your_password',
                                  db='your_dbname',
                                  charset='utf8')
        self.cursor = self.db.cursor(pymysql.cursors.DictCursor)

    def execute(self, query, args={}):
        self.cursor.execute(query, args)  

    def executeOne(self, query, args={}):
        self.cursor.execute(query, args)
        row = self.cursor.fetchone()
        return row

    def executeAll(self, query, args={}):
        self.cursor.execute(query, args)
        row = self.cursor.fetchall()
        return row

    def commit():
        self.db.commit()


원래는 Database 클래스를 선언하고, execute함수를 사용한 후 fetch함수와 commit() 함수 등으로 DB를 이용해야 했습니다.

하지만 위와 같은 클래스를 이용하면 보다 편리하게 사용할 수 있게 됩니다.

그러면 이제 이 클래스를 사용해보도록 하겠습니다.




03. Database 클래스 사용 예제

이 예제는 Database를 사용하기 위한 예제입니다.

여기서 제공되는 예제는 sql 소스, python 소스, HTML 소스가 있습니다.


SQL 예제 소스

-- file name : test.sql
-- pwd : /project_name/app/schema/test.sql

CREATE DATABASE testDB default CHARACTER SET UTF8;

use testDB;

CREATE TABLE testTable(
    idx      INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    test     VARCHAR(256) NOT NULL
) CHARSET=utf8;


이제 이 예제를 이용하여 INSERT, SELECT, UPDATE를 모두 실습해보도록 합니다.

먼저 실습 파이썬 파일을 제작하기 전에 Ubuntu 16.04. 의 MySQL에 테이블을 생성하도록 합니다.


MySQL DB 생성 및 Table 생성은 다음 예제와 같습니다.


이제 DB 생성과 Table 생성이 모두 완료되었으니, INSERT 예제와 SELECT, UPDATE 예제를 살펴보시겠습니다.



HTML 소스 예제

먼저 HTML 소스를 통해 파이썬 소스를 실행할 버튼들을 만들어봅시다.

HTML 소스는 다음과 같습니다.

<!DOCTYPE html>
<html lang="en">
<head>
  <h1> head Test </h1><br>
</head>

<body>

  <input type="button" value="INSERT 예제" onclick="location.href='/test/insert'">
  <input type="button" value="SELECT 예제" onclick="location.href='/test/select'">
  <input type="button" value="UPDATE 예제" onclick="location.href='/test/update'">

  <br><br><br>
  <div>
      INSERT result : {{result}}
  </div>
  <br>
  <div>
      SELECT result idx  : {{resultData.idx}}<br>
      SELECT result test : {{resultData.test}}
  </div>
  <br>
  <div>
      UPDATE result idx  : {{resultUPDATE.idx}}<br>
      UPDATE result test : {{resultUPDATE.test}}
  </div>
  <br>
  
</body>
</html>


여기서 각각 INSERT 예제, SELECT 예제, UPDATE 예제를 실행시킬 버튼과 결과를 보여주는 영역을 작성했습니다.

이제 파이썬 소스를 보시겠습니다.



Python 소스 예제

Python 소스는 위의 HTML 소스 예제와 마찬가지로 각각의 예제로 작성되었습니다.

# file name : test.py
# pwd : /project_name/app/test/test.py

from flask import Blueprint, request, render_template, flash, redirect, url_for
from flask import current_app as current_app

from app.module import dbModule

test = Blueprint('test', __name__, url_prefix='/test')

@test.route('/', methods=['GET'])
def index():
    return render_template('/test/test.html',
                            result=None,
                            resultData=None,
                            resultUPDATE=None)



# INSERT 함수 예제
@test.route('/insert', methods=['GET'])
def insert():
    db_class = dbModule.Database()

    sql      = "INSERT INTO testDB.testTable(test) \
                VALUES('%s')" % ('testData')
    db_class.execute(sql)
    db_class.commit()

    return render_template('/test/test.html',
                           result='insert is done!',
                           resultData=None,
                           resultUPDATE=None)



# SELECT 함수 예제
@test.route('/select', methods=['GET'])
def select():
    db_class = dbModule.Database()

    sql      = "SELECT idx, test \
                FROM testDB.testTable"
    row      = db_class.executeAll(sql)

    print(row)

    return render_template('/test/test.html',
                            result=None,
                            resultData=row[0],
                            resultUPDATE=None)



# UPDATE 함수 예제
@test.route('/update', methods=['GET'])
def update():
    db_class = dbModule.Database()

    sql      = "UPDATE testDB.testTable \
                SET test='%s' \
                WHERE test='testData'" % ('update_Data')
    db_class.execute(sql)    
    db_class.commit()

    sql      = "SELECT idx, test \
                FROM testDB.testTable"
    row      = db_class.executeAll(sql)

    return render_template('/test/test.html',
                            result=None,
                            resultData=None,
                            resultUPDATE=row[0])



이제 이 파일을 실행시키게 되면 다음과 같은 모습으로 나타나게 됩니다.


INSERT 예제 수행 결과


SELECT 예제 수행 결과


UPDATE 예제 수행 결과



Python Flask는 다양한 sql 모듈을 사용할 수 있습니다.

간단하게 SQL 파일을 사용하려면 sqlite를 사용하면 되고, MySQL과 같은 체계적인 시스템을 사용하려면 pymysql을 사용하면 됩니다.


이번 포스트에서는 MySQL과의 연동을 위해 pymysql 모듈을 사용하려고 합니다.


다른 플라스크 예제는 아래의 링크를 살펴봐주시기 바랍니다~



[Python Flask] 웹 페이지 만들기 01 - 환경 설정

[Python Flask] 웹 페이지 만들기 02 - 기본 파일 작성하기

[Python Flask] 웹 페이지 만들기 03 - 파이썬에서 웹으로 값 전달

[Python Flask] 웹 페이지 만들기 04 - Bootstrap 연동하기

[Python Flask] 웹 페이지 만들기 06 - MySQL 연동하기(DB 클래스 생성)




먼저 pymysql의 예제입니다.


CREATE Table 예제

이 예제는 데이터베이스를 연결하고 Table을 생성하는 방법을 나타냅니다.

import pymysql

# database에 접근
db = pymysql.connect(host='localhost',
                     port=3306,
                     user='root',
                     passwd='your_password',
                     db='your_dbname',
                     charset='utf8')

# database를 사용하기 위한 cursor를 세팅합니다.
cursor = db.cursor()

# SQL query 작성
sql = """CREATE TABLE test_table(
         idx  INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
         name VARCHAR(256) NOT NULL,
         nick VARCHAR(256) NOT NULL
         );"""

# SQL query 실행
cursor.execute(sql)

# SQL query가 잘 실행됐는지 table을 살펴보도록 합니다.
# 이미 4번 라인에서 use database를 수행한 것과 다름 없으니 show tables라는 명령을 수행해도 문제가 없습니다.
cursor.execute("show tables") 

# 데이터 변화 적용
# CREATE 혹은 DROP, DELETE, UPDATE, INSERT와 같이 Database 내부의 데이터에 영향을 주는 함수의 경우 commit()을 해주어야 합니다.
db.commit()

# Database 닫기
db.close()

위의 예제에서 대략적인 내용은 모두 작성되었습니다.


이를 조금 더 깔끔하게 한다면 다음과 같이 작성해보는 것도 괜찮을 것 같습니다..

import pymysql
 
db = pymysql.connect(host='localhost',
                     port=3306,
                     user='root',
                     passwd='your_password',
                     db='your_dbname',
                     charset='utf8')
try:
    with db.cursor() as cursor:
        sql = """
            CREATE TABLE test_table(
                   idx  INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
                   name VARCHAR(256) NOT NULL,
                   nick VARCHAR(256) NOT NULL,
            );
        """
        cursor.execute(sql)
        db.commit()
finally:
    db.close()



INSERT 예제

이 예제는 Database와 Table이 완성된 후 Table 내에 데이터를 삽입하는 방법에 대한 예제입니다.

# db 연결작업은 위의 예제에서...

# SQL query 작성
sql = """INSERT INTO test_table(name, nick)
         VALUES('test_name', 'test_nickname');"""

# SQL query 실행
cursor.execute(sql)

# 데이터 변화 적용
db.commit()


위의 예제로 test_table에 'test_name'과 'test_nickname'이라는 값을 삽입하게 됩니다.




SELECT 예제

이 예제는 Database와 Tables 내에 데이터를 조회하는 방법에 대한 예제입니다.

# db 연결작업은 위의 예제에서...

# SQL query 작성
sql = """SELECT * FROM test_table"""

# SQL query 실행
cursor.execute(sql)

# SQL query 실행 결과를 가져옴
result = cursor.fetchall()


SELECT에서는 db.commit() 함수를 실행시키지 않습니다.

이는 DB 내부의 데이터에 영향을 주지 않고, 단지 조회만 했기 때문입니다.

단, 조회된 데이터는 우리가 사용할 수 있어야 하기 때문에 따로 result라는 변수에 실행 결과 값을 가져와야겠지요.

이를 위해서는 fetchall() 함수 혹은 fetchone() 함수를 이용하여 값을 가져와야 합니다.


데이터가 여러 개라면 fetchall() 함수를, 데이터가 하나라면 fetchone() 함수를 사용하는 것이 좋습니다.


가져온 결과는 다음과 같습니다.

print(result)
# ['name' : 'test_name', 'nick' : 'test_nickname']


결과는 dictionary 형태로 가져와집니다.

이를 유념하영 사용하는 것이 좋습니다.



UPDATE 예제

이 예제는 Database와 Tables 내에 데이터를 변경하는 방법에 대한 예제입니다.

# db 연결작업은 위의 예제에서...

# SQL query 작성
sql = """UPDATE test_table SET name='%s', nick='%s'
         WHERE name='%s' """ % ('new_test', 'new_nick', 'test_name')
         
# SQL query 실행
cursor.execute(sql)

# 데이터 변화 적용
db.commit()


위의 예제는 기존에 업로드한 데이터를 변경하는 예제입니다.

이름이 'test_name'인 데이터의 name 컬럼과 nick 컬럼을 각각 'new_test', 'new_nick'으로 변경하는 예제입니다.


이제 이러한 예제를 이용하여 다음 포스트에서는 데이터를 쓰고 업로드 하는 방법을 알아보도록 하겠습니다.





이전의 포스트에서는 Flask를 사용하기 이전에 시작하는 법을 작성했습니다.

이번에는 파이썬에서 값을 전달하는 방법을 알아보도록 하겠습니다.


Javascript 혹은 HTML 자체로 값을 생성해서 웹을 사용한다는 건 사실상 불가능합니다.

PHP와 같은 플랫폼에서도 시스템 내부(백엔드)에서 MySQL과 연동한다거나 값을 긁어와 뿌려주는 기본적인 기능이 있는 것처럼, Python Flask에도 이러한 기능이 있습니다.


단, Flask에서는 마치 함수 내에 인자값을 던져주듯이 한다는 점이 조금 독특합니다.


다른 플라스크 예제는 아래의 링크를 살펴봐주시기 바랍니다~



[Python Flask] 웹 페이지 만들기 01 - 환경 설정

[Python Flask] 웹 페이지 만들기 02 - 기본 파일 작성하기

[Python Flask] 웹 페이지 만들기 04 - Bootstrap 연동하기

[Python Flask] 웹 페이지 만들기 05 - MySQL 연동하기(pymysql)

[Python Flask] 웹 페이지 만들기 06 - MySQL 연동하기(DB 클래스 생성)






01. Python에서 작성한 값 넘겨주기

먼저 이전에 작성했던 index.py 코드에 다음과 같은 값을 넣어주었다고 가정합시다.

# file name : index.py
# pwd : /project_name/app/main/index.py
from flask import Blueprint, request, render_template, flash, redirect, url_for
from flask import current_app as current_app

main = Blueprint('main', __name__, url_prefix='/')

@main.route('/main', methods=['GET'])
def index():
    testData = 'testData array'

    return render_template('/main/index.html', testDataHtml=testData)


위에 표시된 10번과 12번 라인은 조금 추가되고 수정된 영역입니다.


먼저 10번 라인은 여러분이 데이터를 HTML 파일에 전달하고자 하는 데이터입니다.

굳이 String 값일 필요는 없지만, 저는 대부분 String 값 혹은 Dictionary 데이터를 전달하는 것을 선호합니다.

(기본적으로 MySQL에서 나온 값이 Dictionary 형태를 띄기 때문입니다. MySQL은 다음 포스트에서 다루도록 하겠습니다.)


이제 이 값을 render_template 함수의 두 번재 인자값으로 넣어주려고 합니다.

12번 라인에서 testDataHtml 이라는 변수 이름에 String 데이터가 저장된 testData를 넣어줍니다.

변수 이름은 아무렇게나 지어도 상관없습니다~


이제 이 데이터를 어떻게 전달 받는지가 중요합니다.




02. Python에서 넘겨받은 값 사용하기

HTML 소스를 보시겠습니다.

<html>
    <head>
        This is Main page Head<br>
    </head>
    <body>
        This is Main Page Body<br>
        And This is Accepted Data : {{testDataHtml}}
    </body>
</html>


위의 소스코드는 이전의 소스코드보다 조금 추가된 게 있습니다. ㅎㅎ

단, 유의해서 보실 부분이 바로 7번 라인입니다.


자세히 보시면 중괄호가 두 번 되어있고, Python에서 넘겨준 인자값의 변수 이름이 그대로 들어가 있는 것을 볼 수 있습니다.

즉, 우리가 저장했던 값이 저 변수에 들어가 있으니, 이 값을 불러와 뿌려주겠다는 의미입니다.





03. 결과


testData array라는 값이 제대로 출력되는 것을 볼 수 있습니다.

이를 활용하여 여러 가지를 할 수 있을 것입니다.




이전의 포스트에서는 Flask를 사용하기 이전에 환경 설정을 수행한 것을 작성했습니다.

이번에는 본격적으로 예제를 통해 시작해보도록 하겠습니다.


아참, 시작하기 앞서 해당 반드시 환경 설정을 마무리 하시기 바랍니다.


[Python Flask] 웹 페이지 만들기 01 - 환경 설정


앞으로 작성될 파이썬 파일과 HTML 파일은 Ubuntu 16.04 환경에서 작성할 것입니다.


이외의 다른 플라스크 예제는 아래의 링크를 살펴봐주시기 바랍니다~



[Python Flask] 웹 페이지 만들기 03 - 파이썬에서 웹으로 값 전달

[Python Flask] 웹 페이지 만들기 04 - Bootstrap 연동하기

[Python Flask] 웹 페이지 만들기 05 - MySQL 연동하기(pymysql)

[Python Flask] 웹 페이지 만들기 06 - MySQL 연동하기(DB 클래스 생성)






01. run.py 작성

먼저 프로그램을 시작하는 프로그램을 작성해야 합니다.

run.py 라는 프로그램을 [Project Name] - [app] 디렉토리에 생성하여 다음과 같이 작성합니다.

# file name : run.py
# pwd : /project_name/run.py

from app import app

app.run(host="0.0.0.0", port=80)


생각보다 별 거 없는 내용에 안심하시면 안 됩니다.

뒤에는 더한 코드들과 신경쓸 것들이 넘쳐나기 때문이지요...


먼저 run.py는 위와 같이 해두어도 무관하니 이제 우리가 작성할 메인 페이지를 작성해보도록 합시다.




02. __init__ 파일 작성

__init__.py 파일은 위에서 선언한 from app import app을 통해 실행되는 모든 파일들을 전체적으로 초기화 및 실행하기 위한 파일입니다.

때문에 위의 파일은 하위 디렉토리의 모든 파일을 초기화 및 실행해주는 파일이 필요하다는 것입니다.

그 파일을 작성하는 방법은 다음과 같습니다.

# file name : __init__.py
# pwd : /project_name/app/__init__.py

from flask import Flask

app = Flask(__name__)

# 추가할 모듈이 있다면 추가
# config 파일이 있다면 추가

# 앞으로 새로운 폴더를 만들어서 파일을 추가할 예정임
# from app.main.[파일 이름] --> app 폴더 아래에 main 폴더 아래에 [파일 이름].py 를 import 한 것임

# 위에서 추가한 파일을 연동해주는 역할
# app.register_blueprint(추가한 파일)


위의 주석들은 아래에서 파일을 입력한 후 알아보도록 하겠습니다.




03. 메인 페이지 파일 작성

메인페이지와 이제 앞으로 여러분이 추가할 내용에 따라 다르게 구분을 해주는 것이 좋겠지요?

때문에 저는 main 페이지를 작성하기 위해 폴더별로 구분을 해주었습니다.


아래의 소스코드는 [Project Name] - [app] - [main] - index.py 와 같은 순서로 디렉토리를 구분하여 만들었습니다.

# file name : index.py
# pwd : /project_name/app/main/index.py

from flask import Blueprint, request, render_template, flash, redirect, url_for
from flask import current_app as app
# 추가할 모듈이 있다면 추가

main = Blueprint('main', __name__, url_prefix='/')

@main.route('/main', methods=['GET'])
def index():
      # /main/index.html은 사실 /project_name/app/templates/main/index.html을 가리킵니다.
      return render_template('/main/index.html')


위의 소스 파일에서 유의해야 할 점을 표시해보았습니다.


먼저 8번 라인은 index 파일을 들어갔을 때 어떻게 이름을 설정할지 결정하는 부분이며, url_prefix는 URL을 어떻게 뒤에 붙일지 결정하는 부분입니다.

그리고 10번 라인은 파일 내부에서 어떤 경로로 나타낼지 결정하는 부분입니다.

11번 라인은 큰 의미는 없지만, 나중에 url_for에서 사용될 함수 이름을 유심히 봐두시기 바랍니다.

13번 라인은 12번 라인의 설명과 같습니다.


파이썬 소스를 모두 작성했다면 이제 13번 라인에서 불려들일 template 파일 즉, HTML 파일을 작성해주어야 합니다.


HTML 파일은 다음과 같습니다.

<!--file name : index.html-->
<!--pwd : /project_name/app/templates/main/index.html-->
<html>
	<head>
		This is Main page Head
	</head>
	<body>
		This is Main Page Body
	</body>
</html>


위의 코드는 생각보다 별 것 없지요.

맞습니다.

Flask에서는 자동으로 Flask가 HTML 모습을 만들어주는 게 아니라, 우리가 직접 일일이 껍데기를 만들어서 불러오는 형식을 가지고 있습니다.

하지만 번거롭다고 생각하지 마시기 바랍니다.


다 그래요.....(저는 사실 파이썬으로 코딩만 하면 웹페이지가 이쁘게 나올 줄 알았네요.. 허허)



이제 02.__init__ 파일 작성에서 나온 from app.main.[파일이름]에 대해 수정을 해봅시다.


다음과 같이 수정해볼 수 있습니다.

# file name : __init__.py
# pwd : /project_name/app/__init__.py

from flask import Flask
# 추가할 모듈이 있다면 추가

app = Flask(__name__)

# 파일 이름이 index.py이므로
from app.main.index import main as main 

# 위에서 추가한 파일을 연동해주는 역할
app.register_blueprint(main) # as main으로 설정해주었으므로


이제 python3 run.py를 통해 실행해보도록 합시다~



앙 안 이쁘다..


HTML 파일이 영 아니기 때문이 저렇게 나오는 것이지요..


이제 이 다음 포스트에서는 Python 코드에서 HTML로 데이터를 넘겨주는 방법에 대해 알아보도록 하겠습니다.


Python에서 날짜와 시간을 다루는 모듈을 사용해야 해서 찾아보는데 꽤 종류가 많아서 정리해보려고 합니다.


datetime.now() 함수(현재 시간 표현하기)

import datetime
 
now = datetime.datetime.now()
print(now)
# 현재 시간을 나타냄
# 2019-02-06 18:29:36.768516
 
Date = now.strftime('%Y-%m-%d')
print(Date)
# 현재 시간의 년/월/일만 표시
# 2019-02-06
 
Time = now.strftime('%H:%M:%S')
print(nowTime)
# 현재 시간의 시/분/초만 표시
# 18:29:36
 
DateAndTime = now.strftime('%Y-%m-%d %H:%M:%S')
print(DateAndTime)
# 현재 시간을 '년'-'월'-'일' '시':'분':'초'의 형태의 문자열로 표현
# DateAndTime에는 string 값이 들어가 있음


String 형태로 된 날짜와 시간을 datetime 값으로 바꾸려면 특정 함수를 사용해야 합니다.


datetime.strptime() 함수(str to datetime)

import datetime

StrDateTime = '2019-02-06 18:29:36'
DateTime = datetime.datetime.strptime(StrDateTime, '%Y-%m-%d %H:%M:%S')
print(type(DateTime))
# datetime 형태의 <class 'datetime.datetime'>가 출력됨 --> 문자열 형태가 아님
print(DateTime)
# datetime 형태의 값으로 2019-02-06 18:29:36이 출력됨 --> 문자열 형태가 아님


만약 datetime 형태로 된 날짜와 시간을 string 값으로 바꾸려면 다음과 같은 함수를 사용해야 합니다.


datetime.strftime() 함수(datetime to str)

import datetime

nowDateTime = datetime.datetime.now()
strDateTime = datetime.strftime('%Y-%m-%d %H:%M:%S')
print(type(DateTime))
# str 형태라고 출력됨
print(DateTime)
# 2019-02-06 18:29:36 -- 현재 시간이 출력됨



datetime.replace() 함수(시간 및 날짜 변경)

import datetime
 
DateTime = datetime.datetime.strptime('2019-02-06 18:29:36', '%Y-%m-%d %H:%M:%S')
print(DateTime) 
# 2019-02-06 18:29:36
 
AnotherDateTime = DateTime.replace(day=7)

print(DateTime) 
# 2019-02-06 18:29:36
print(AnotherDateTime)
# 2019-02-07 18:29:36


만약 datetime 값의 특정 날짜 혹은 시간을 바꿔주기 위해서는 replace 함수를 사용해야 합니다.

또한 변경하고자 하는 날짜 혹은 시간을 인자값으로 넣어주어야 합니다.


사용할 수 있는 인자값의 종류는 다음과 같습니다.


1. year (년도)

2. month (월)

3. day (날짜)

4. hour (시간)

5. minute (분)

6. second (초)

7. microsecond(마이크로 초)


이밖에도 응용할 수 있는 방법은 여러가지가 있습니다.


'PYTHON > Python 3.x' 카테고리의 다른 글

[Python] 딕셔너리 정렬하기  (1) 2019.02.05

파이썬 딕셔너리에 입력된 key 값과 value 값들을 정렬해야 할 때가 있습니다.

그럴 때 해결할 수 있는 방법을 사용해보려고 합니다.


각각 Key를 이용한 방법과 Value를 이용한 방법이 있습니다.

딕셔녀리는 {Key : Value}와 같은 구조를 가지고 있기 때문에 어떤 값으로 정렬을 수행할지 상황에 따라 다르기 마련이지요.




01. Key를 이용한 정렬

해결 방법은 list를 정렬할 때와 마찬가지로 sorted 함수를 사용하면 됩니다.


sorted() 함수 사용

dict = {'A' : 1, 'D' : 4, 'C' : 3, 'B' : 2}
sdict = sorted(dict.items())
# items() 함수는 key-value 쌍이 tuple로 구성된 리스트가 리턴됩니다.


결과는 다음과 같이 나타납니다.

>> [('A', 1), ('B', 2), ('C', 3), ('D', 4)]

만약 반대 순서대로(내림차순) 정렬하고 싶다면 간단하게 다음과 같이 reverse 인자값에 True를 넣어주시면 됩니다.


sorted()함수 사용 및 reverse 인자값 설정

dict = {'A' : 1, 'D' : 4, 'C' : 3, 'B' : 2}
sdict = sorted(dict.items(), reverse=True)
# items() 함수는 key-value 쌍이 tuple로 구성된 리스트가 리턴됩니다.
# reverse 인자값에 True를 넣어주면 내림차순으로 하겠다고 설정됩니다.
# reverse의 default 값은 False입니다.


결과는 다음과 같이 나타납니다.

>> [('D', 4), ('C', 3), ('B', 2), ('A', 1)]




02. Value를 이용한 정렬

value 값은 key를 이용하는 것보다 조금 더 복잡합니다.

하지만 크게 어려울 것이 없습니다.

다음과 같이 sorted 함수를 이용하여, 인자를 더 넣어주시면 됩니다.


먼저 원래의 결과와 동일한 결과를 뽑기 위한 코드는 다음과 같습니다.


sorted() 함수 사용 및 operator를 통한 인자값 설정

import operator

dict = {'A' : 1, 'D' : 4, 'C' : 3, 'B' : 2}
sdict = sorted(dict.items(), key=operator.itemgetter(0))
# 인자값에 있는 key=operator.itemgetter(0)는 정렬하고자 하는 키 값을 0번째 인덱스 기준으로 하겠다는 것입니다.
# 0번째 인자는 Key입니다.


결과는 다음과 같이 나타납니다.

>> [('A', 1), ('B', 2), ('C', 3), ('D', 4)]


위의 코드를 차근차근 설명하면 다음과 같습니다.


1. {'A' : 1, 'D' : 4, 'C' : 3, 'B' : 2} 값을 2의 리스트 형태로 바꿔준다.

2. [('A', 1), ('B', 2), ('C', 3), ('D', 4)]와 같이 변경된 값 중에, 0번째(영어로 된 인자값) 부분을 기준으로 결정한다.

3. 정해진 기준을 통해 정렬을 수행한다.

4. 영어가 기준이기 때문에 영어 오름차순으로 정렬된다.


이와 같은 흐름으로 실행되면, 이제 Value를 기준으로 바꿔줄 수 있겠습니다. ><


0번째는 Key이기 때문에 1번째는 Value입니다.

즉, Value를 기준으로 정렬해주는 코드는 다음과 같이 딱 한 곳만 수정하면 됩니다.


sorted() 함수 사용 및 operator를 통한 인자값 설정

import operator

dict = {'A' : 1, 'D' : 4, 'C' : 3, 'B' : 2}
sdict = sorted(dict.items(), key=operator.itemgetter(1))
# 인자값에 있는 key=operator.itemgetter(1)는 정렬하고자 하는 키 값을 1번째 인덱스 기준으로 하겠다는 것입니다.
# 1번째 인자는 Value입니다.


결과는 다음과 같이 나타납니다.

>> [('A', 1), ('B', 2), ('C', 3), ('D', 4)]


생각해보니 key와 value의 순서가 같게 나오게 되네요 허허....


무튼 위와 같이 하게 되면 정렬이 완료됩니다.



'PYTHON > Python 3.x' 카테고리의 다른 글

[Python] 날짜와 시간 관련 모듈  (0) 2019.02.06

파이썬에서 숫자를 출력하고자 하는데, 앞에 0을 붙여주고 싶을 때 해결 방법을 찾아보았습니다.

이때 사용할 수 있는 함수가 zfill()이라는 함수와 rjust()라는 함수가 있는데, 함수를 다음과 같이 사용할 수 있습니다.


01. zfill(width) 함수 사용

#"002"
"2".zfill(3)

#"50000"
"50000".zfill(5)

#"00123"
"123".zfill(5)




02. rjust(width, [fillchar]) 함수 사용

#"002"
"2".rjust(3, "0")

#"50000"
"50000".rjust(5, "0")

#"00123"
"123".rjust(5, "0")

#"aa123"
"123".rjust(5, "a")

rjust 함수는 원하는 문자를 따로 지정해줄 수 있기 때문에 "a"와 같이 다른 문자열로 앞 부분을 채워줄 수 있는 특징이 있습니다.









'PYTHON > Python 문법' 카테고리의 다른 글

Python Iterator란?? Python Iterable이란??  (0) 2017.01.27
Python Yield란?? What is the Yield??  (3) 2017.01.26
Python2.X Python3.X 함께 쓰기  (0) 2017.01.02
Python으로 파일 다운로드  (5) 2015.08.07

pygame은 python을 통해 게임을 만들 수 있도록 지원해주는 모듈입니다.

pygame의 구조와 사용법을 자세하게 다뤄보도록 하려고 합니다.


00. pygame 모듈 설치

pygame은 python 2.x와 python 3.x 모두에서 지원합니다.

때문에 설치를 위한 명령어는 다음과 같습니다.

C:/ > pip install pygame


만약 pip 명령어로 pygame이 잘 실행되지 않으시면 다음 링크에서 해결해보시면 될 것 같습니다.


python의 pip 명령이 들지 않을 때(python pip error)




01. pygame 기본 구조

pygame의 기본 구조는 다음과 같습니다.

위의 기본 구조를 바탕으로 소스 기반으로 설명하겠습니다.



Source - pygame 선언(import)

# Import a library of functions called 'pygame'
import pygame

# Import a library of functions called 'pygame' as pg
import pygame as pg

아주 당연한 말씀이겠지만, python을 실행할 때 pygame을 import 해주셔야 사용할 수 있습니다.

혹은, 우리가 사용하기 편하도록 pygame이라는 모듈의 이름을 pg라고 바꾸어 선언해주실 수 있습니다.

이는 초기화 단계에서 굳이 새로운 변수를 만들지 않고, pygame 대신 pg라는 이름으로 사용해줄 수 있어 편리합니다.



Source - pygame 초기화

# Initialize the game engine
pygame.init()

여기서도 마찬가지로, 당연하게도 pygame 모듈을 사용할 때 초기화(init)를 해주어야 합니다.

초기화는 위의 소스에서처럼 간단하게 pygame 모듈 이름 뒤에 .init() 함수를 사용해주는 방법을 사용하면 됩니다.



Source - pygame에서 사용할 전역 변수 선언

# Define the colors we will use in RGB format
BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)
BLUE  = (  0,   0, 255)
GREEN = (  0, 255,   0)
RED   = (255,   0,   0)

# Set the height and width of the screen
size   = [400, 300]
screen = pygame.display.set_mode(size)
 
pygame.display.set_caption("Game Title")
 
#Loop until the user clicks the close button.
done = False
clock = pygame.time.Clock()

pygame에서 사용할 여러 가지 변수나 설정은 위의 소스처럼 전역 변수로 만들어주는 것이 꽤 도움이 됩니다.

전역 변수로 만들어서 사용하게 되면, 어느 함수에서나 가져다 쓰기 편하고, 공통적으로 쓰이는 변수 같은 경우는 일일이 인자값을 설정해주는 번거로움도 줄어들기 때문입니다.

대체적으로 색깔, 위치, 화면 설정 등의 변수를 전역 변수로 사용하는 경우가 많습니다.

이 밖에도, 위의 소스를 통해 설명드릴 게 아주 많습니다. 허허.


15번째 라인과 16번째 라인을 먼저 보시겠습니다.

# Set the height and width of the screen
size   = [400, 300]
screen = pygame.display.set_mode(size)

15번째 라인은 pygame으로 생성할 창의 크기를 정해준 변수입니다. x축의 길이는 400, y축의 길이는 300이라고 설정하는 것과 같습니다.

16번째 라인은 pygame으로 생성할 창의 크기를 설정한 변수를 통해 GUI 창을 설정해는 변수입니다.

화면을 초기화, 화면에 데이터를 추가하는 것 등은 해당 screen 변수를 통해 적용되어집니다.


18번째 라인을 보시겠습니다.

pygame.display.set_caption("Game Title")

해당 라인은 GUI 창이 켜질 때, 창 이름을 설정하는 라인입니다.

이름은 한 번 설정하게 되면, 게임이 꺼지기 전까지 사라지지 않기 때문에 해당 라인은 전역 변수가 선언되는 라인에서 실행해주었습니다.


22번째 라인을 보시겠습니다.

#Loop until the user clicks the close button.
done = False
clock = pygame.time.Clock()

이 라인은 화면을 초당 몇 번 출력하는가를 설정하기 위해 선언되는 변수입니다.

초당 화면 출력은, 게임에서 FPS(Frame Per Second) 혹은 Frame Rate라고 합니다.

해당 변수를 이용하여 게임의 FPS를 설정해줄 수 있습니다.



Source - pygame 메인 루프

while not done:
 
    # This limits the while loop to a max of 10 times per second.
    # Leave this out and we will use all CPU we can.
    clock.tick(10)
    
    # Main Event Loop
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done=True # Flag that we are done so we exit this loop
 
    # All drawing code happens after the for loop and but
    # inside the main while done==False loop.
     
    # Clear the screen and set the screen background
    screen.fill(WHITE)

    '''
    Your Work.....
    '''
    pygame.draw.polygon(screen, GREEN, [[30, 150], [125, 100], [220, 150]], 5)
    pygame.draw.polygon(screen, GREEN, [[30, 150], [125, 100], [220, 150]], 0)
    pygame.draw.lines(screen, RED, False, [[50, 150], [50, 250], [200, 250], [200, 150]], 5)
    pygame.draw.rect(screen, BLACK, [75, 175, 75, 50], 5)
    pygame.draw.rect(screen, BLUE, [75, 175, 75, 50], 0)
    pygame.draw.line(screen, BLACK, [112, 175], [112, 225], 5)
    pygame.draw.line(screen, BLACK, [75, 200], [150, 200], 5)

    # Go ahead and update the screen with what we've drawn.
    # This MUST happen after all the other drawing commands.
    pygame.display.flip()

pygame의 핵심은 메인 루프에 있다고 해도 과언이 아닙니다.

여기서 가장 중요한 '게임 실행 동안 발생한 이벤트에 대한 설정''사용자의 게임 알고리즘'이 해당 영역에 작성되어야 하기 때문입니다.

위의 소스에서 중요한 부분을 골라 설명해보도록 하겠습니다.


28번째 라인을 먼저 보시겠습니다.

# This limits the while loop to a max of 10 times per second.
# Leave this out and we will use all CPU we can.
clock.tick(10)

해당 라인은 위에서 설정한 pygame.time.Clock()을 선언한 clock 함수를 통해 FPS(초당 프레임)를 설정해주는 라인입니다.

값을 10으로 한 것은 초당 10번의 화면을 출력해주겠다는 의미입니다.

해당 값이 높을 수록 CPU를 많이 먹게 됩니다.

또한 프레임이 너무 높아서 모니터가 제대로 출력하지 못하는 경우도 있으니 주의해서 사용하시는 게 좋습니다.

기본적으로 10 혹은 30 혹은 60이 가장 좋습니다.


31번째, 32번째, 33번째 라인을 보시겠습니다.

# Main Event Loop
for event in pygame.event.get(): # User did something
    if event.type == pygame.QUIT: # If user clicked close
        done=True # Flag that we are done so we exit this loop

31번째 라인은 pygame.event.get() 함수를 통해 게임 중간에 발생한 이벤트를 캐치하여 검사하기 위한 인덱스로 사용하겠다는 의미입니다.

간단히 설명하면, 게임 중에 마우스 클릭, 혹은 키보드 클릭 등에 대한 이벤트가 발생하면 이를 인지하고, 과연 어떤 이벤트가 발생했는지 for문을 통해 검사하는 구조를 위한 라인입니다.

32번째 라인은 pygame.event.get() 함수를 통해 가져온 이벤트가 만약 pygame.QUIT 이라는 값과 일치하는지 검사하는 라인입니다.

해당 QUIT 값은 pygame이 종료되는 이벤트를 말하며, GUI 창에서 x 버튼을 누르면 발생하는 이벤트입니다.

33번째 라인은 만약 종료 이벤트가 맞다면 메인 루프의 while문이 더 이상 돌아가지 않도록 하기 위해 바꿔주는 것입니다.

만약 PC에서 오류가 발생하여, 게임이 꺼져야 함에도 불구하고 꺼지지 않을 경우, while문이 돌아가지 않게 하여 강제로 꺼질 수 있도록 하는 일종의 안전장치라고 보시면 됩니다.

항상 게임을 종료할 때는 while문이 종료할 수 있도록 합시다!


39번째 라인을 보시겠습니다.

    # Clear the screen and set the screen background
    screen.fill(WHITE)

해당 라인은 전체 화면을 관리하는 변수인 screen을 통해 fill() 함수를 실행한 것입니다.

fill() 함수는 화면 전체를 특정 색깔로 모두 채워주는 함수입니다.

여기서는 화면 전체를 WHITE 즉, RGB 값이 (255, 255, 255)인 값으로 채워주는 것을 말합니다.

그렇게 되면 하얀 화면이 출력되겠습니다.


41번째, 42번째, 43번째 라인을 보시겠습니다.

    '''
    Your Work.....
    '''
    pygame.draw.polygon(screen, GREEN, [[30, 150], [125, 100], [220, 150]], 5)
    pygame.draw.polygon(screen, GREEN, [[30, 150], [125, 100], [220, 150]], 0)
    pygame.draw.lines(screen, RED, False, [[50, 150], [50, 250], [200, 250], [200, 150]], 5)
    pygame.draw.rect(screen, BLACK, [75, 175, 75, 50], 5)
    pygame.draw.rect(screen, BLUE, [75, 175, 75, 50], 0)
    pygame.draw.line(screen, BLACK, [112, 175], [112, 225], 5)
    pygame.draw.line(screen, BLACK, [75, 200], [150, 200], 5)

사실 실제로 사용자의 행위가 작성된 곳은 44 ~ 50번째 라인입니다.

이는 제가 임의로 작성한 집을 그리기 위한 도형 함수를 나열한 것입니다.

해당 영역에는 여러분께서 원하는 작업을 자유롭게 작성하시면 됩니다.

만약 pygame.draw 함수에 대해 더 자세히 보고싶으시면 아래의 링크를 통해 참고하시면 될 것 같습니다.



사각형 - pygame.draw.rect

삼각형 - pygame.draw.polygon

원 - pygame.draw.circle

타원 - pygame.draw.ellipse

원(특정 부분까지 그리기) - pygame.draw.arc

선 - pygame.draw.line

여러 개의 선 - pygame.draw.lines

부드러운 선 - pygame.draw.aaline

여러 개의 부드러운 선 - pygame.draw.aalines




54번째 라인을 보시겠습니다.

    # Go ahead and update the screen with what we've drawn.
    # This MUST happen after all the other drawing commands.
    pygame.display.flip()

54번째 라인은 위에서 작성한 그리기 함수를 통해 지금까지 화면에 작성한 모든 행위를 업데이트해주기 위한 함수입니다.

즉, 해당 54번째 라인이 없으면, 지금까지 사용한 pygame.draw 함수들은 출력이 되지 않습니다.

물론 screen.fill(WHITE) 함수 또한 실행되지 않은 채 화면은 업데이트 되지 않을 것입니다.

때문에 반드시 pygame의 메인 루프의 끝에는 해당 pygame.display.flip() 함수를 사용해주셔야 합니다.


Source - pygame 전체 예제

# Import a library of functions called 'pygame'
import pygame

# Initialize the game engine
pygame.init()

# Define the colors we will use in RGB format
BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)
BLUE  = (  0,   0, 255)
GREEN = (  0, 255,   0)
RED   = (255,   0,   0)

# Set the height and width of the screen
size   = [400, 300]
screen = pygame.display.set_mode(size)
 
pygame.display.set_caption("Game Title")
 
#Loop until the user clicks the close button.
done = False
clock = pygame.time.Clock()
 
while not done:
 
    # This limits the while loop to a max of 10 times per second.
    # Leave this out and we will use all CPU we can.
    clock.tick(10)
    
    # Main Event Loop
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done=True # Flag that we are done so we exit this loop
 
    # All drawing code happens after the for loop and but
    # inside the main while done==False loop.
     
    # Clear the screen and set the screen background
    screen.fill(WHITE)

    '''
    Your Work.....
    '''
    pygame.draw.polygon(screen, GREEN, [[30, 150], [125, 100], [220, 150]], 5)
    pygame.draw.polygon(screen, GREEN, [[30, 150], [125, 100], [220, 150]], 0)
    pygame.draw.lines(screen, RED, False, [[50, 150], [50, 250], [200, 250], [200, 150]], 5)
    pygame.draw.rect(screen, BLACK, [75, 175, 75, 50], 5)
    pygame.draw.rect(screen, BLUE, [75, 175, 75, 50], 0)
    pygame.draw.line(screen, BLACK, [112, 175], [112, 225], 5)
    pygame.draw.line(screen, BLACK, [75, 200], [150, 200], 5)

    # Go ahead and update the screen with what we've drawn.
    # This MUST happen after all the other drawing commands.
    pygame.display.flip()
 
# Be IDLE friendly
pygame.quit()

위의 소스들을 모두 종합해놓은 예제입니다.

실행해보시면 다음과 같습니다.



여기까지 pygame의 기본 실행 구조와 사용법에 대해 간단히 알아보았습니다.

긴 글 읽어주셔서 감사합니다.


PyGame 모듈은 다양한 기능을 지원하는데, 그 중에서 여러가지 도형을 그릴 수 있는 메소드들을 소개하도록 하겠습니다.


00. PyGame 지원되는 도형

PyGame에서 지원되는 도형은 다음과 같습니다.

메소드

도형

설명

 pygame.draw.rect

 사각형

 화면에 사각형을 그려줍니다.

 pygame.draw.polygon

 삼각형

 화면에 삼각혁을 그려줍니다.

 pygame.draw.circle

 원

 화면에 원을 그려줍니다.

 pygame.draw.ellipse

 타원

 화면에 타원을 그려줍니다.

 pygame.draw.arc

 원

 화면에 원하는 만큼의 원을 그려줍니다.

 원을 얼마나 그려줄지 정할 수 있습니다.

 pygame.draw.line

 선

 화면에 선을 그려줍니다.

 pygame.draw.lines

 여러 개의 선

 화면에 여러 개의 선을 이어서 그립니다.

 pygame.draw.aaline

 부드러운 선

 화면에 부드러운 선을 그려줍니다.

 pygame.draw.aalines

 부드러운 선들

 화면에 부드러운 선을 여러 개 이어서 그립니다.


여기서는 pygame.draw.aalines를 이용하여 여러 개의 선을 그리는 방법을 살펴볼 것입니다.

만약 다른 draw 메소드를 참고하고 싶으시다면 아래의 링크에서 선택하시면 될 것 같습니다.




사각형 - pygame.draw.rect

삼각형 - pygame.draw.polygon

원 - pygame.draw.circle

타원 - pygame.draw.ellipse

원(특정 부분까지 그리기) - pygame.draw.arc

선 - pygame.draw.line

여러 개의 선 - pygame.draw.lines

부드러운 선 - pygame.draw.aaline



01. pygame.draw.aalines 함수

pygame에서 지원하는 여러 개의 선 그리기 함수인 aalines 함수는 다음과 같은 인자값들을 받습니다.



 pygame.draw.aalines(Surface, Color, Closed, PointList, Blend=1)

  Draws a sequence on a surface. You must pass at least two points in the sequence of points. The closed argument is a simple Boolean and if true, a line will be draw between the first and last points. The Boolean blend argument set to true will blend the shades with existing shades instead of overwriting them. This function accepts floating point values for the end points.




변수 

설명

Surface

 pygame을 실행할 때 전체적으로 화면을 선언한 변수 값

Color

 선의 색깔로 (R, G, B)의 형태로 데이터의 값을 삽입함

Closed

 이어지는 여러 개의 선을 다 그리고 하나의 구역으로 설정할지 결정

PointList

 여러 개의 선을 그릴 위치들을 입력함

Blend

 Anti-Aliasing(부드러움) 설정 여부로, True 혹은 False를 입력함


위의 변수들은 예제 소스코드를 통해 설명하도록 하겠습니다.


02. pygame.draw.aalines를 이용한 여러 개의 선 그리기(예제)

먼저 소스코드를 살펴보면 다음과 같습니다.


Source

# Import a library of functions called 'pygame'
import pygame

# Initialize the game engine
pygame.init()
 
# Define the colors we will use in RGB format
BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)
BLUE  = (  0,   0, 255)
GREEN = (  0, 255,   0)
RED   = (255,   0,   0)
 
# Set the height and width of the screen
size   = [400, 300]
screen = pygame.display.set_mode(size)
 
pygame.display.set_caption("Drawing Rectangle")
 
#Loop until the user clicks the close button.
done = False
clock = pygame.time.Clock()
 
while not done:
 
    # This limits the while loop to a max of 10 times per second.
    # Leave this out and we will use all CPU we can.
    clock.tick(10)
     
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done=True # Flag that we are done so we exit this loop
 
    # All drawing code happens after the for loop and but
    # inside the main while done==False loop.
     
    # Clear the screen and set the screen background
    screen.fill(WHITE)

    # Draw on the screen a RED lines from (0,80) to (50, 90) to (200, 80) to (220, 30) 
    # Closed = False, Blend = True,  1 pixel wide.
    pygame.draw.aalines(screen, RED, False, [[0, 80], [50, 90], [200, 80], [220, 30]], True)

    # Draw on the screen a BLUE lines from (100,180) to (150,190) to (300, 180) to (320, 130) 
    # Closed = True,  Blend = False, 1 pixel wide.
    pygame.draw.aalines(screen, BLUE, True, [[100, 180], [150, 190], [300, 180], [320, 130]], True)
     
    # Go ahead and update the screen with what we've drawn.
    # This MUST happen after all the other drawing commands.
    pygame.display.flip()
 
# Be IDLE friendly
pygame.quit()

전체적인 소스는 위와 같습니다.

이제 아래에서는 소스를 특정하여 나눠서 설명을 해보도록 하겠습니다.



Variable - Surface

# Set the height and width of the screen
size   = [400, 300]
screen = pygame.display.set_mode(size)

먼저, 16번째 줄의 screen 변수를 보면, 해당 변수에는 화면 전체를 설정하기 위한 값이 들어가 있습니다.

화면을 새로고침 해주거나, 화면을 채워주거나 할 때 해당 변수를 이용합니다.

pygame.draw.lines 함수의 Surface는 이러한 화면 설정 변수를 넣어주시면 됩니다.


Variable - Color

# Define the colors we will use in RGB format
BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)
BLUE  = (  0,   0, 255)
GREEN = (  0, 255,   0)
RED   = (255,   0,   0)

다음으로, 8 ~ 12번 라인을 보시면, Tuple 형태의 값이 설정되어 있는 것을 보실 수 있습니다.

세 개의 값이 0 ~ 255의 범위를 가지게 되는데, 이렇게 설정된 값이 색깔(RGB) 값으로 Color 변수가 들어갈 곳에 넣어주시면 됩니다.


Variable - Closed

    # Draw on the screen a RED lines from (0,80) to (50, 90) to (200, 80) to (220, 30) 
    # Closed = False, Blend = True,  1 pixel wide.
    pygame.draw.aalines(screen, RED, False, [[0, 80], [50, 90], [200, 80], [220, 30]], True)

    # Draw on the screen a BLUE lines from (100,180) to (150,190) to (300, 180) to (320, 130) 
    # Closed = True,  Blend = False, 1 pixel wide.
    pygame.draw.aalines(screen, BLUE, True, [[100, 180], [150, 190], [300, 180], [320, 130]], True)

먼저 42번째 라인과 46번째 라인을 살펴보면 False와 True로 되어 있는 인자값을 보실 수 있습니다.

42번째 라인의 값의 False일 경우는 빨간색 선으로 보시면 되고,

46번째 라인의 값의 True일 경우는 파란색 선으로 보시면 됩니다.




빨간색 선을 보면 하나의 구역으로 나눠지지 않고, 선분만 이어져있는 것을 볼 수 있습니다.

파란색 선을 보면 하나의 구역으로 나눠져서 선분들이 이어져 있는 곳을 사각형으로 만들어낸 모습으로 보입니다.

파란색 선처럼 구역을 Closed 하고 싶을 때는 True, 빨간색 선처럼 구역이 없이 선만 그리고 싶을 때는 False를 하면 됩니다.


Variable - Blend

    # Draw on the screen a RED lines from (0,80) to (50, 90) to (200, 80) to (220, 30) 
    # Closed = False, Blend = True,  1 pixel wide.
    pygame.draw.aalines(screen, RED, False, [[0, 80], [50, 90], [200, 80], [220, 30]], True)

    # Draw on the screen a BLUE lines from (100,180) to (150,190) to (300, 180) to (320, 130) 
    # Closed = True,  Blend = False, 1 pixel wide.
    pygame.draw.aalines(screen, BLUE, True, [[100, 180], [150, 190], [300, 180], [320, 130]], True)

42번째 라인과 46번째 라인을 보시면 두 함수의 Blend는 각각 True와 False인 것을 확인할 수 있습니다.

Blend는 Anti-Aliasing 즉, 부드럽게 선을 그려줄지에 대한 선택을 말합니다.

만약 True로 값을 설정하여 함수를 실행한다면, 그려지는 선은 매우 부드럽게 그려지게 됩니다.

반대로 False로 값을 설정하여 함수를 실행항다면, 그려지는 선은 그림판으로 그린 것처럼 부드럽지 않게 그려지게 됩니다.

기본적으로 Blend는 True로 설정되어 있습니다.

True와 False의 비교는 아래의 그림과 같습니다.



위의 그림은 lines를 사용하여 부드럽지 않은 선을 그렸을 때와 aalines를 사용하여 부드러운 선을 그렸을 때를 비교한 것입니다.

lines와 aalines의 차이는 Anti-Aliasing이 가능한가 안 한가의 차이점이라고 보실 수 있습니다.



03. 주의할 점

소스코드의 인자값을 보시면 아실 수 있겠지만, 해당 함수는 선의 두께를 지정해줄 수 없습니다.

즉, 기본적으로 선분의 길이가 1이라는 의미입니다.

부드러운 선, 부드럽지 않은 선 모두 두께가 1로 고정되어 있기 때문에, 부드러운 선을 그리고 싶으시다면, 두께가 1인 것을 감안하여 사용해야 합니다.


+ Recent posts