====== python ====== ===== prepare ===== ==== on WSL2 ==== {{page>:public:computer:wsl#python_settings&noheader}} ==== get python ==== [[https://python.org|python official site]] ==== settings ==== * Editors * Visual Studio Code * Vim * Sublimetext * pyCharm $ python3 hello_world.py ===== variables and types ===== * 변수 이름은 snake_case로 * 문자열은 "This is a string", 'This is also a string.' 모두 가능 * {string_variable}.title() -> 첫 글자 대문자로 * {string_variable}.upeer() * {string_variable}.lower() * f-string * full_name = f"{first_name} {last_name}" * full_name = "{} {}".format(fist_name, last_name) * escape characters; \', \\, \n, \r, \t, \b, \f, \ooo, \xhh * {string_variable}.rstrip() -> 오른쪽 공백 삭제, .strip() -> 양쪽 공백 제거, .lstrip() -> 왼쪽 공백 제거 * numeric; integer, floating point number, underscored number -> 15_000_000_000 * 상수는 대문자로; MAX_CONNECTIONS = 5000 * comments; # message = "Hello Python" print(message) >>> import this ===== list ===== * 대괄호 []와 콤마 , * 이름을 복수형으로 * 인덱스는 0부터, [-1]은 끝에서부터의 인덱스 bicycles = ['trek', 'cannondale', 'redline', 'specialized'] print(bicycles) print(bicycles[0]) print(bicycles[0].title()) bicycles[0] = 'mini bell' # change value bicycles.append('trek') # append value bicycles.insert(0, 'strida') # insert value del bicycles[0] # delete popped_bicycle = bicycles.pop() # pop value (stack) #popped_bicycle = bicycles.pop(0) # pop value by index bicycles.remove('redline') # remove by value bicycles.sort() # sort permanently by alphabet bicycles.sort(reverse=True) # reverse sort print(sorted(bicycles)) # sort temporarily bicycles.reverse() # len(bicycles) ===== list handling ===== magicians = ['alice', 'david', 'carolina'] for magician in magicians: print(magician) for value in range(1, 5): # 1 ~ 4 print(value) numbers = list(range(1, 6)) # numbers = [1, 2, 3, 4, 5] even_numbers = list(range(2, 11, 2)) # even_numbers = [2, 4, 6, 8, 10] squares = [] for value in range(1, 11): square = value ** 2 squares.appen(square) # squares = [value ** 2 for value in range(1,11)] print(squares) digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] min(digits) max(digits) sum(digits) * slice; 원래 리스트 유지 * players[0:3] # index 0에서부터 3개까지 자름 [:3] * players[2:] # index 2부터 끝까지 * players[-3:] # 끝에서 셋 * 복사 * my_friends = your_friends[:] * my_friends = your_friends는 포인터 같은 역할 * tuple(immutable) * 대괄호 대신 소괄호 ()와 콤마 , * 한 개 항목의 튜플이더라도 콤마 필요; my_t = (3,) * Coding style; PEP(Python Enhancement Proposal) 8 * 들여쓰기 공백 네 칸 * 행 길이 79자 * [[https://www.python.org/dev/peps/pep-0008/|PEP 8 -- Style Guide for Python Code]] ===== if state ===== cars = ['audi', 'bmw', 'subaru', 'toyota'] for car in cars: if car == 'bmw': print(car.upper()) else: print(car.title()) * == ; equals to * != ; not equals * <, <=, >, >= * and, or * in; 'mushrooms' in requested_toppings * not in; * boolean expression; True, False * if, if-else, if-elif-else if age < 4: # GOOD if age<4: #bad ===== dictionary ===== * key-value pair * 중괄호 {} alien_0 = {'color': 'green', 'points': 5} print(alien_0['color']) print(alien_0['points']) alien_0['x_position'] = 0 alien_0['y_position'] = 25 dict_0 = {} # 빈 값으로 딕셔너리 선언 del alien_0['points'] # points key 제거 favorite_languages = { 'jen': 'python', 'sarah': 'c', 'edward': 'ruby', 'phil': 'python', } point_value = alien_0.get('points', 'No point value assigned.') # key가 없을 경우의 default 값을 지정하여 error 방지 user_0 = { 'username': 'efermi', 'first': 'enrico', 'last': 'fermi', } for key, value in user_0.items(): print(f"\nKey: {key}") print(f"Value: {value}") for name in favorite_languages.key(): print(name.title()) for language in favorite_languages.values(): print(language.title()) for language in set(favorite_languages.values()): # set는 중복을 제거한 고유한 데이터 형식 print(language.title()) * nesting * 딕셔너리 안에 리스트, 리스트 안에 딕셔너리, 딕셔너리 안에 딕셔너리... ===== user input and while loop ===== * 사용자 입력 message = input("Tell me something and I will repeat it back to you: ") print(message) prompt = "If you tell us who you are we can personalize the messages you see." prompt += "\nWhat is you first name? " name = input(prompt) print(f"\nHello, {name}!") * 형변환; int(string) * modulo operator % * while loop current_number = 1 while currnet_number <= 5: print(current_number) current_number += 1 message = "" while message != 'quit': message = input(prompt) print(message) * flag; bool 변수를 이용하여 while 처리 * break; 루푸 빠져 나가기 * continue; 루프의 처음으로 * 무한 루프 주의 ===== function ===== def greet_user(): # 함수 정의 """간단한 환영 인사를 표시합니다""" # document string 혹은 docstring 따옴표 세개"""로 둘러쌈 print("Hello") greet_user() def describe_pet(animal_type, pet_name='dog'): # 기본 값이 있는 파라메터는 뒤쪽에 """반려동물에 관한 정보를 출력합니다""" print(f"\nI have a {animal_type}.") print(f"My {animal_type}'s name is {pet_name.title()}.") #return 값 describe_pet('hamster', 'harry) describe_pet(animal_type='hamster', pet_name='harry') describe_pet(pet_name='harry', animal_type='hamster') describe_pet('willie') * function에 리스트를 넘길 때 function_name(list_name[:])로 사본을 넘기면 원래 값이 유지 (Call by value), 리스트를 넘기면 원래 리스트가 수정됨 (Call by reference). * 함수 정의/호출시 기본값 지정할 때 공백을 쓰지 않는다 def make_pizza(*toppings): # 여러 개의 매개변수 빈 튜플 def build_profile(first, last, **user_info): # 빈 딕셔너리 * 함수를 모듈로 저장 * 소문자 import pizza # pizza.py 파일을 열고 그 파일에 있는 모든 함수 사용 pizza.make_pizza() # pizza 모듈 안의 make_pizza() 함수 호출 # 모듈에서 일부 함수만 사용 from module_name import function_name from module_name import function_0, function_1, function_3 # 별칭; 함수의 별칭으로 호출 from pizza import make_pizza as mp from module_name import function_name as fn # 모둘의 별청 import pizza as p import module_name as mn # 모든 함수 비추천 from pizza import * from module_name import * ===== class ===== class Dog: # 대문자로 시작 """개를 모델화하는 시도""" # docstring def __init__(self, name, age): # 생성자 메서드, 반드시 구현 ""name과 age 속성 초기화""" self.name = name self.age = age def sit(self): """명령에 따라 앉는 개""" print(f"{self.name} is now sitting.") def roll_over(self): """명령에 따라 구르는 개""" print(f"{self.name} rolled over!") my_dog = Dog('Willie', 6) my_dog.sit() my_dog.roll_over() * super() 메서드로 superclass에 접근 * override. * CamelCase from car import Car # car.py 안에 Car 클래스 하나만 있을 경우 from car import ElectricCar # car.py 안에 여러 클래스 중 ElectricCar 만 임포트 from car import Car, ElectricCar # car.py 안에 Car, ElectricCar 클래스 임포트 import car # car.py 안에 있는 모든 클래스 임포트 from module_name import * from electric_car import ElectricCar as EC # electric_car.py의 ElectricCar 클래스를 EC로 임포트 * python standard library from random import randint randint(1, 6) from random import choice choiced_value = choice(list_values) ===== file and exception ===== # 기본적인 읽기 file_path = '/home/..../openfile.txt' with open(file_path) as file_object: contents = file_object.read() print(contents) # 라인씩 읽기 with open(filename) as file_object: for line in file_object: print(line) filename = 'pi_digits.txt' with open(filename) as file_object: lines = file_object.readlines() for line in lines: print(line.rstrip()) print(f"{pi_string[:52]...") # 52번째 캐릭터까지만 # write a file filename = 'prg.txt' with open(filename, 'w') as file_object: # w: write mode, r: read mode, a: append mode, r+; read and write. default is 'r' file_object.write("I love programming.") #open(filename, encoding='utf-8') try: print(5/0) except ZeroDivisionError: # FileNotFoundError, print("You can't divide by zero!") #pass # 조용히 실패하기, except 블럭 안에 아무것도 하지 않고 pass만. else: print("try block success.") * string.replace(find_string, replace_string) * string.count(find_string) returns count import json json.dump(contents, file_object) # contents를 file_object에 저장, with open(filename, 'w') 사용 loaded_object = json.load(file_object) # with open(filename) * refactoring; 코드를 더 사용하기 쉽게 재구성 ===== code test ===== * unit test, * test cases; unit test의 묶음 import unittest class NamesTestCase(unittest.TestCase): #unittest.TestCase를 상속 받는 클래스 생성 def setUp(self): # 각 메서드를 실행하기 전에 .... .... def test_first_last_name(self): .... .... self.assertEqual(formatted_name, 'Janis Joplin') # 예상한 결과가 일치하는 지 단언assert. if __name__ == '__main__': # 다른 프로그램에서 임포트하지 않고 직접 실행하면 __name__의 값은 '__main__'이 된다. unittest.main() ^ method ^ example ^ | assertEqual(a,b) | a == b임을 확인 | |assertNotEqual(a,b) | a != b임을 확인 | | assertTrue(x) | x가 True임을 확인 | | assertFalse(x) | x가 False임을 확인 | | assertIn(item, list) | item이 list 안에 있음을 확인 | | assertNotIn(item, list) | item이 list 안에 있지 않음을 확인 | ===== game ===== * pygame $ python3 -m pip install --user pygame import sys import pygame import pygame.font import pygame.sprite import Sprite import pygame.sprite import Group .... pygame.init() pygame.display.set_mode((1200,800)) # ((0,0), pygame.FULLSCREEN) pygame.display.set_caption("pygame") ... ... ... pygame.image.load('image/ship.bmp') ... ... for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: # pygame.KEYUP, pygame.MOUSEBUTTONDOWN, if event.key == pygame.K_RIGHT: # pygame.K_LEFT, pygame.K_q ... pygame.display.flip() # pygame.Rect(0, 0, self.settings.bullet_width, # self.settings.bullet_height) # pygame.draw.rect(self.screen, self.color, self.rect) # pygame.sprite.Group() # pygame.sprite.goupcollide( # self.bullets, self.aliens, True, True) # if pygame.sprite.spritecollideany(slef.ship, self.aliens): # ... # mouse_pos = pygame.mouse.get_pos() # pygame.mouse.set_visible(False) / True # pygame.font.SysFont(None, 48) * helper method; ex) _check_events(), _update_screen() ===== data visualization ===== $ python3 -m pip install --user matplotlib import matplotlib.pyplot as plt squares = [1, 4, 9, 16, 25] plt.style.use('seaborn') # plt.style.available = ['seaborn-dark', 'seaborn-darkgrid', 'seaborn-ticks', 'fivethirtyeight', .... ] fig, ax = plt.subplots() # 그래프 생성 ax.plot(squares) # ax.plot(squares, linewidth=3), ax.plot(input_values, squares, linewidth=3) ax.set_title("Square Numbers", fontsize=24) ax.set_xlabel("Value", fontsize=14) ax.set_ylabel("Square of Value", fontsize=14) ax.tick_params(axis='both', labelsize=14) # 눈금 라벨 크기를 정함 plt.show() * ax.scatter(2, 4) * ax.scatter(2, 4, s=200) * ax.scatter(x_values, y_values, c='red', s=10) * ax.scatter(x_values, y_values, c=(0, 0.8, 0), s=10) * ax.scatter(x_values, y_values, c=y_values, cmap=plt.cm.Blues, s=10) * ax.tick_params(axis='both', which='major', labelsize=14) * ax.axis([0, 1100, 0, 11000000] * https://matplotlib.org * plt.savefig('squares_plot.png', bbox_inches='tight') * ax.get_xaxis().set_visible(False) * ax.get_yaxis().set_visible(False) $ python3 -m pip install --user plotly * https://plot.ly/python from plotly.graph_objs import Bar, Layout from plotly import offline ... ... data = [Bar(x=x_values, y=frequencies)] ... x_axis_config = {'title': 'Result'} y_axis_config = {'title': 'Frequency of Result'} my_layout = Layout(title='Results of rolling one D6 1000 times', xaxis_x_axis_config, yaxis=y_axis_config) offline.plot({'data':data, 'layout': my_layout}, filename='d6.html') import csv filename = 'data/aaa.csv' with open(filename) as f: reader = csv.reader(f) header_row = next(reader) print(header_row) for index, column_header in enumerate(header_row): print(index, column_header) ... import datetime import datetime first_date = datetime.strptime('2021-08-02', '%Y-%m-%d') print(first_date) * [[https://strftime.org/|Python strftime cheatsheet]] * ax.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1) $ python3 -m pip install --user requests import requests # API 호출을 보내고 응답을 저장 url = 'https://api.github.com/search/repositories?q=language:python&sort=stars' headers = {'Accept': 'application/vnd.github.v3+json'} r = requests.get(url, headers=headers) print(f"Status code: {r.status_code}") # API 응답을 변수에 저장 response_dict = r.json() # 결과 처리 print(response_dict.keys()) * 두 개의 그래프 그리기 -> 두 그래프 사이 칠하기 * 에러 체크; except ValueError: * 세계 지도 만들기 -> 지도에 표시 -> 마커 크기 조절 -> 마커 색깔 -> 다른 컬러 스케일 -> 텍스트 추가 * 커스텀 툴팁 추가 * 그래프에 클릭할 수 있는 링크 추가 ===== web application ===== ==== virtual environment ==== $ python3 -m venv ll_env # ll_env란 이름으로 가상 환경 만들기 $ source ll_env/bin/activate # ll_env의 가상 환경 활성화 (ll_env)$ deactivate # ll_env 가상 환경 활성화 상태에서 사용 중지 ==== install django ==== (ll_env)$ pip install django # ll_env 가상 환경에서 장고 설치 (ll_env)$ django-admin startproject learning_log . # learning_log라는 이름으로 프로젝트 생성 마지막에 . 반드시 입력 -> learning_log 디렉토리 안에 settings.py, urls.py, wsgi.py 생성 (ll_env)$ python manage.py migrate # 데이터베이스 생성 -> 기본적으로 db.sqlite3 생성 (ll_env)$ python manage.py startapp learning_logs # learning_logs라는 이름의 앱 생성 -> model.py, admin.py, views.py (ll_env)$ python manage.py runserver # 프로젝트 실행 ==== 모델 정의 ==== from django.db import models class Topic(models.Model): """.....""" ... def __str__(self): ... * settings.py 파일 INSTALLED_APPS = [ # 내 앱 'learning_logs', # 장고 기본 앱 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] ... * model을 수정하면 makemigrations를 먼저 실행하고 -> migrate 실행 (ll_env)$ python manage.py makemigrations learning_logs (ll_env)$ python manage.py migrate * superuser 생성 (ll_env)$ python manage.py createsuperuser * 관리자 사이트에서 모델 등록 * 주제 추가 * 장고 셸; quit to Ctrl-D or Ctrl-Z(on Windows) (ll_env)$ python manage.py shell * urls.py from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), path('', include('learning_logs.urls')), ] * views.py from django.shortcuts import render # view here * decorator; @login_required on views.py * other references; * bootstrap library * heroku; PaaS * Git; (ll_env)$ pip install django-bootstrap4 # bootstrap4 설치 (ll_env)$ pip install psycopg2==2.7.* (ll_env)$ pip install django-heroku (ll_env)$ pip install gunicorn * requirements.txt 파일; 작성한 프로젝트에 필요한 패키지들 모음 (ll_env)$ pip freeze > requirements.txt * runtime.txt python-3.7.2 * Procfile web: gunicorn learning_log.wsgi --log-file - * git (ll_env)$ git --version * .gitignore ll_env/ __pycache__/ *.sqlite3 * 헤로쿠 배포 * 헤로쿠 계정 * 헤로쿠 cli 설치 * 필수 패키지 설치 * requirements.txt 생성 * 파이썬 런타임 명시; runtime.txt * 헤로쿠에서 쓸 수 있도록 settings.py 수정 * Procfile 만들기 * git을 사용해 프로젝트 파일 추적; 깃 설치 -> 설정 -> .gitignore 생성 -> 프로젝트 커밋 * 헤로쿠에 올리기 * 헤로쿠 데이터 베이스 세팅 * 헤로쿠 배포 과정 개선; 헤로쿠에 슈퍼유저 생성 -> 사용하기 쉬운 url 만들기 * 프로젝트 보안; settings.py의 DEBUG 플래그 설정 * 커밋과 푸시 * 헤로쿠에서 환경 변수 세팅하기 * 커스텀 에러 페이지 만들기; 커스텀 템플릿 만들기 -> 로컬에서 에러 페이지 보기 -> 헤로쿠에 변경 내용 올리기 -> get_object_or_404() 메서드 * SECRET_KEY 세팅 * 헤로쿠에서 프로젝트 삭제 ===== Python Keywords and internal functions ===== ==== keywords ==== * False * None * True * and * as * assert * async * await * break * class * continue * def * del * elif * else * except * finally * for * from * global * if * import * in * is * lambda * nonlocal * not * or * pass * raise * return * try * while * with * yield ==== python internal functions ==== * abs() * all() * any() * ascii() * bin() * bool() * breakpoint() * bytearray() * bytes() * callable() * chr() * classmethod() * compile() * complex() * delattr() * dict() * divmod() * enumerate() * eval() * exec() * filter() * float() * format() * frozenset() * getattr() * globals() * hasattr() * hash() * help() * hex() * id() * input() * int() * isinstance() * issubclass() * iter() * len() * list() * locals() * map() * max() * memoryview() * min() * next() * object() * oct() * open() * ord() * pow() * print() * property() * range() * repr() * reversed() * round() * set() * setattr() * slice() * sorted() * staticmethod() * str() * sum() * super() * tuple() * type() * vars() * zip() * __import__() ===== References ===== * [[https://wikidocs.net/131351|098 고유한 식별자를 만들려면? ― uuid]] * import uuid strLongUUID = uuid.uuid1() print(strLongUUID) print(strLongUUID.bytes) print(strLongUUID.hex) print(strLongUUID.int) print(strLongUUID.fields) print(strLongUUID.urn) print('') #pip install shortuuid import shortuuid strShortUUID = shortuuid.uuid() print(strShortUUID) print(len(strShortUUID))