From d878659d193c56fa1736606f67773edb73952ae2 Mon Sep 17 00:00:00 2001 From: Elex Date: Thu, 23 Jan 2025 11:02:27 +0900 Subject: [PATCH] 2025-01-23T11:02:27 --- doc/08_03_serialization.md | 39 ++++ doc/08_04_json.md | 37 ++++ doc/08_05_csv.md | 35 ++++ doc/11_iterator.md | 45 +++++ doc/12_decorator.md | 49 +++++ doc/18_threading.md | 32 +++ doc/19_subprocess.md | 50 +++++ doc/19_thread.md | 1 - doc/20_01_html_parser.md | 42 +++- doc/22_regexp.md | 71 +++++++ doc/23_asyncio.md | 29 +++ doc/23_xml.md | 0 doc/24_json.md | 0 doc/25_serialization.md | 0 doc/{26_sys_module.md => 26_sys.md} | 0 doc/{27_argparse_module.md => 27_argparse.md} | 0 doc/28_00_database.md | 68 +++++++ doc/28_01_sqlite3.md | 49 +++++ doc/28_02_pymysql.md | 51 +++++ doc/28_04_sqlqlchemy.md | 154 +++++++++++++++ doc/29_database.md | 0 doc/29_numpy.md | 46 +++++ doc/30_pandas.md | 55 ++++++ doc/39_00_flask.md | 39 ++++ doc/39_01_controller.md | 171 ++++++++++++++++ doc/39_02_view.md | 105 ++++++++++ doc/39_03_model.md | 73 +++++++ doc/40_gui.md | 0 doc/40_tkinter.md | 186 ++++++++++++++++++ doc/41_logging.md | 47 ++++- doc/42_unittest.md | 75 ++++++- doc/49_collections.md | 60 ++++++ 32 files changed, 1605 insertions(+), 4 deletions(-) create mode 100644 doc/08_03_serialization.md create mode 100644 doc/08_04_json.md create mode 100644 doc/08_05_csv.md create mode 100644 doc/11_iterator.md create mode 100644 doc/12_decorator.md create mode 100644 doc/18_threading.md create mode 100644 doc/19_subprocess.md delete mode 100644 doc/19_thread.md create mode 100644 doc/23_asyncio.md delete mode 100644 doc/23_xml.md delete mode 100644 doc/24_json.md delete mode 100644 doc/25_serialization.md rename doc/{26_sys_module.md => 26_sys.md} (100%) rename doc/{27_argparse_module.md => 27_argparse.md} (100%) create mode 100644 doc/28_00_database.md create mode 100644 doc/28_01_sqlite3.md create mode 100644 doc/28_02_pymysql.md create mode 100644 doc/28_04_sqlqlchemy.md delete mode 100644 doc/29_database.md create mode 100644 doc/29_numpy.md create mode 100644 doc/30_pandas.md create mode 100644 doc/39_00_flask.md create mode 100644 doc/39_01_controller.md create mode 100644 doc/39_02_view.md create mode 100644 doc/39_03_model.md delete mode 100644 doc/40_gui.md create mode 100644 doc/40_tkinter.md create mode 100644 doc/49_collections.md diff --git a/doc/08_03_serialization.md b/doc/08_03_serialization.md new file mode 100644 index 0000000..d637c20 --- /dev/null +++ b/doc/08_03_serialization.md @@ -0,0 +1,39 @@ +# 직렬화(Serialization) +직렬화란 파이썬 객체를 바이트 스트림으로 변환하는 과정을 의미합니다. 이렇게 변환된 데이터는 파일로 저장하거나 네트워크를 통해 전송할 수 있으며, 필요할 때 다시 원래의 객체로 복원할 수 있습니다. 마치 객체를 압축하여 박스에 담아 옮기는 것과 비슷합니다. + +## 직렬화 과정 +* 객체 생성: 파이썬에서 사용할 객체를 생성합니다. +* 직렬화: pickle 모듈 등을 사용하여 객체를 바이트 스트림으로 변환합니다. +* 저장 또는 전송: 변환된 바이트 스트림을 파일로 저장하거나 네트워크를 통해 전송합니다. +* 역직렬화: 저장된 바이트 스트림을 다시 원래의 객체로 복원합니다. + +## 직렬화에 사용되는 모듈 +* pickle: 파이썬 객체를 바이너리 형태로 직렬화하는 가장 일반적인 모듈입니다. 간단하고 사용하기 쉽지만, 보안 문제가 있을 수 있습니다. +* json: JSON 형식으로 직렬화합니다. 사람이 읽을 수 있는 형식이며, 다양한 언어에서 지원됩니다. +* marshal: 파이썬 객체를 바이트 스트림으로 변환하는 간단한 모듈입니다. +* shelve: 파이썬 객체를 파일에 저장하고 불러오는 데 특화된 모듈입니다. + +## pickle + +```python +import pickle + +class Person: + def __init__(self, name, age): + self.name = name + self.age = age + +# 객체 생성 +person = Person("Alice", 30) + +# 직렬화 (파일 저장) +with open('person.pkl', 'wb') as f: + pickle.dump(person, f) + +# 역직렬화 (파일 읽기) +with open('person.pkl', 'rb') as f: + loaded_person = pickle.load(f) + +print(loaded_person.name) # 출력: Alice +print(loaded_person.age) # 출력: 30 +``` \ No newline at end of file diff --git a/doc/08_04_json.md b/doc/08_04_json.md new file mode 100644 index 0000000..14c24bc --- /dev/null +++ b/doc/08_04_json.md @@ -0,0 +1,37 @@ +# JSON + +**JSON(JavaScript Object Notation)**은 데이터를 간단하고 가볍게 교환하기 위한 표준 형식입니다. 사람이 읽기 쉽고, 다양한 프로그래밍 언어에서 지원하기 때문에 웹 서비스나 데이터베이스와의 통신에서 널리 사용됩니다. 파이썬에서 JSON 데이터를 처리하기 위해 json 모듈을 사용합니다. + +* JSON 문자열을 파이썬 객체로 변환: json.loads() 메서드를 사용하여 JSON 문자열을 파이썬의 딕셔너리나 리스트 등의 객체로 변환할 수 있습니다. +* 파이썬 객체를 JSON 문자열로 변환: json.dumps() 메서드를 사용하여 파이썬 객체를 JSON 문자열로 변환할 수 있습니다. +* JSON 파일 읽기/쓰기: json.load()와 json.dump() 메서드를 사용하여 JSON 파일을 읽고 쓸 수 있습니다. + +```python +import json + +# Python 객체 생성 +data = {'name': 'Alice', 'age': 30, 'city': 'Seoul'} + +# Python 객체를 JSON 문자열로 변환 +json_string = json.dumps(data) +print(json_string) # 출력: {"name": "Alice", "age": 30, "city": "Seoul"} + +# JSON 문자열을 Python 객체로 변환 +python_object = json.loads(json_string) +print(python_object['name']) # 출력: Alice + +# JSON 파일 저장 +with open('data.json', 'w') as f: + json.dump(data, f) + +# JSON 파일 읽기 +with open('data.json', 'r') as f: + loaded_data = json.load(f) + print(loaded_data) +``` + +## json 모듈의 주요 메소드 +* loads(s): JSON 문자열 s를 파이썬 객체로 변환합니다. +* dumps(obj): 파이썬 객체 obj를 JSON 문자열로 변환합니다. +* load(fp): JSON 파일 fp에서 데이터를 읽어 파이썬 객체로 변환합니다. +* dump(obj, fp): 파이썬 객체 obj를 JSON 파일 fp에 저장합니다. \ No newline at end of file diff --git a/doc/08_05_csv.md b/doc/08_05_csv.md new file mode 100644 index 0000000..05d6ae4 --- /dev/null +++ b/doc/08_05_csv.md @@ -0,0 +1,35 @@ +# CSV + +csv 모듈은 파이썬에서 CSV (Comma-Separated Values) 파일을 읽고 쓰는 데 사용되는 표준 라이브러리입니다. CSV 파일은 쉼표(,)나 다른 구분 기호로 값을 구분하여 텍스트 형식으로 데이터를 저장하는 간단하고 효율적인 방법입니다. + +* CSV 파일 읽기: csv.reader 객체를 사용하여 CSV 파일을 읽고, 각 행을 리스트 형태로 반환합니다. +* CSV 파일 쓰기: csv.writer 객체를 사용하여 파이썬의 리스트나 딕셔너리를 CSV 파일로 저장합니다. +* 구분 기호 설정: 쉼표 외에도 다른 구분 기호를 사용할 수 있습니다. +* 인코딩 설정: 다양한 인코딩 방식을 지원합니다. + +```python +import csv + +# CSV 파일 읽기 +with open('data.csv', 'r') as csvfile: + reader = csv.reader(csvfile) + for row in reader: + print(row) + +# CSV 파일 쓰기 +with open('new_data.csv', 'w', newline='') as csvfile: + fieldnames = ['name', 'age', 'city'] + writer = csv.writer(csvfile) + writer.writerow(fieldnames) + writer.writerows([['Alice', 30, 'Seoul'], ['Bob', 25, 'Busan']]) +``` +* csv.reader: CSV 파일을 읽어 각 행을 리스트로 반환합니다. +* csv.writer: 파이썬의 리스트나 딕셔너리를 CSV 파일로 저장합니다. + +## csv 모듈의 주요 매개변수 +* delimiter: 구분 기호 (기본값: ',') +* quotechar: 문자열을 감싸는 따옴표 (기본값: '"') +* quoting: 따옴표 사용 방식 (QUOTE_ALL, QUOTE_MINIMAL 등) +* lineterminator: 줄 바꿈 문자 (기본값: '\n') + +대규모 데이터나 복잡한 구조의 데이터를 처리할 때는 pandas와 같은 더 강력한 라이브러리를 사용하는 것이 좋습니다. \ No newline at end of file diff --git a/doc/11_iterator.md b/doc/11_iterator.md new file mode 100644 index 0000000..f4410ce --- /dev/null +++ b/doc/11_iterator.md @@ -0,0 +1,45 @@ +# 이터레이터와 제너레이터 +파이썬에서 이터레이터(iterator)와 제너레이터(generator)는 시퀀스(sequence) 데이터를 순차적으로 처리하는 데 사용되는 중요한 개념입니다. 이 둘은 서로 밀접한 관련이 있지만, 각각 다른 특징과 용도를 가지고 있습니다. + +## 이터레이터(Iterator) + +**이터레이터(Iterator)**는 순서대로 다음 값을 반환할 수 있는 객체를 의미합니다. 이터레이터는 `__next__()` 메서드를 가지는 객체로, 이 메서드를 호출할 때마다 다음 값을 순차적으로 반환합니다. 파이썬에서 리스트, 튜플, 문자열 등 많은 자료형들이 이터레이터를 지원하여 for 문과 같은 반복문에서 사용될 수 있습니다. + + +* 순차적 접근: 다음 값을 요청할 때마다 현재 위치에서 한 칸씩 이동하며 값을 반환합니다. +* 상태 유지: 이전에 반환한 값을 기억하여 다음 값을 반환할 때 사용합니다. +* `__next__()` 메서드: 다음 값을 반환하는 메서드입니다. 모든 값을 반환하고 더 이상 값이 없을 때 StopIteration 예외를 발생시킵니다. +* `iter()` 함수: 이터러블 객체를 이터레이터로 변환합니다. + +```python +my_list = [1, 2, 3] +my_iter = iter(my_list) + +print(next(my_iter)) # 1 +print(next(my_iter)) # 2 +print(next(my_iter)) # 3 +print(next(my_iter)) # StopIteration 예외 발생 +``` + +### 이터러블(Iterable) +for 문에서 사용될 수 있는 객체를 의미합니다. 리스트, 튜플, 문자열 등이 대표적인 예입니다. + +모든 이터러블은 이터레이터로 변환될 수 있습니다. + +## 제너레이터(Generator) +제너레이터는 이터레이터를 생성하는 함수입니다. yield 키워드를 사용하여 값을 반환하고, 함수의 실행을 일시 중단합니다. 다음 번에 함수를 호출하면 이전에 중단된 지점부터 다시 실행됩니다. + +* 메모리 효율적: 필요한 값만 메모리에 로드하기 때문에 대용량 데이터 처리에 유용합니다. +* 간결한 코드: yield 키워드를 사용하여 간결하게 이터레이터를 구현할 수 있습니다. +* 코루틴과 연동: 비동기 프로그래밍에서 코루틴과 함께 사용될 수 있습니다. + +```python +def my_generator(): + for i in range(5): + yield i + +for num in my_generator(): + print(num) +``` + +이터레이터는 이미 존재하는 데이터를 순회하는 도구이고, 제너레이터는 데이터를 생성하는 도구라고 할 수 있습니다. diff --git a/doc/12_decorator.md b/doc/12_decorator.md new file mode 100644 index 0000000..0bd9a9d --- /dev/null +++ b/doc/12_decorator.md @@ -0,0 +1,49 @@ +# 데코레이터 + +데코레이터는 파이썬에서 함수나 클래스에 추가적인 기능을 부여하는 강력한 도구입니다. 마치 함수나 클래스를 장식하듯이, 기존의 기능을 변경하거나 확장할 수 있죠. + +데코레이터는 실제로 함수를 인자로 받아 새로운 함수를 반환하는, 고차 함수(higher-order function)입니다. 이렇게 반환된 새로운 함수는 원래 함수를 감싸면서 추가적인 작업을 수행할 수 있습니다. + +```python +def my_decorator(func): + def wrapper(*args, **kwargs): + print("함수 실행 전") + result = func(*args, **kwargs) + print("함수 실행 후") + return result + return wrapper + +@my_decorator +def greet(name): + print(f"Hello, {name}!") + +greet("Alice") +``` +위 예시에서 @my_decorator 부분이 greet 함수에 데코레이터를 적용하는 부분입니다. my_decorator 함수는 greet 함수를 인자로 받아 새로운 함수 wrapper를 반환합니다. 이 wrapper 함수는 greet 함수를 호출하기 전후에 추가적인 작업을 수행합니다. + +## 활용 +* 로깅: 함수의 실행 시간, 입력값, 출력값 등을 로그에 기록합니다. +* 캐싱: 함수의 결과를 캐시하여 동일한 입력에 대해 반복적인 계산을 방지합니다. +* 인증: 함수 호출 권한을 검사합니다. +* 예외 처리: 예외 발생 시 특정 작업을 수행합니다. +* 프로파일링: 함수의 성능을 측정합니다. + +## 데코레이터의 구현 +```python +def my_decorator(func): + def wrapper(*args, **kwargs): + # 데코레이터가 수행할 작업 + # ... + result = func(*args, **kwargs) + # 데코레이터가 수행할 작업 + return result + return wrapper +``` +* @decorator_name 문법: 함수 위에 붙여 데코레이터를 적용합니다. +* wrapper 함수: 실제로 호출되는 함수입니다. +* *args, **kwargs: 가변 인자를 사용하여 다양한 형태의 함수에 적용할 수 있도록 합니다. + +## 더 알아보기 +* 클래스 데코레이터: 클래스에도 데코레이터를 적용할 수 있습니다. +* 매개변수가 있는 데코레이터: 데코레이터 함수에 인자를 전달하여 기능을 커스터마이징할 수 있습니다. +* 함수 데코레이터: 함수를 반환하는 함수를 사용하여 더 복잡한 기능을 구현할 수 있습니다. diff --git a/doc/18_threading.md b/doc/18_threading.md new file mode 100644 index 0000000..2abe218 --- /dev/null +++ b/doc/18_threading.md @@ -0,0 +1,32 @@ +# threading 모듈: 동시 작업의 시작 +threading 모듈은 파이썬에서 여러 작업을 동시에 실행하기 위한 도구입니다. 마치 여러 사람이 동시에 다른 일을 하는 것처럼, 파이썬 프로그램 내에서도 여러 작업을 동시에 처리할 수 있도록 해줍니다. 이를 통해 프로그램의 실행 속도를 향상시키고, I/O 작업과 같은 블로킹 작업을 효율적으로 처리할 수 있습니다. + +* 스레드 생성: Thread 클래스를 사용하여 새로운 스레드를 생성합니다. +* 스레드 실행: start() 메서드를 호출하여 스레드를 실행합니다. +* 스레드 동기화: Lock, RLock, Condition, Event 등의 클래스를 사용하여 스레드 간의 동기화를 수행합니다. +* 데몬 스레드: 메인 스레드가 종료되면 자동으로 종료되는 스레드를 생성할 수 있습니다. + +```python +import threading +import time + +def worker(num): + print(f"Worker {num} starting...") + time.sleep(2) + print(f"Worker {num} finished.") + +threads = [] +for i in range(5): + t = threading.Thread(target=worker, args=(i,)) + threads.append(t) + t.start() + +for t in threads: + t.join() +``` +위 예시는 5개의 스레드를 생성하여 각 스레드에서 worker 함수를 실행하는 코드입니다. 각 스레드는 2초 동안 실행되며, 모든 스레드가 종료될 때까지 메인 스레드가 기다립니다. + +## 주의 사항 +* Global Interpreter Lock (GIL): 파이썬의 GIL은 한 번에 하나의 스레드만 실행되도록 제한합니다. 따라서 CPU-bound 작업(연산 집약적인 작업)의 경우 스레드를 사용해도 성능 향상이 제한적일 수 있습니다. +* 동기화 문제: 여러 스레드가 공유하는 데이터에 접근할 때는 동기화 문제가 발생할 수 있습니다. Lock이나 RLock 등을 사용하여 데이터 접근을 제어해야 합니다. +* 데몬 스레드: 데몬 스레드는 메인 스레드가 종료될 때 강제로 종료될 수 있으므로 주의해야 합니다. \ No newline at end of file diff --git a/doc/19_subprocess.md b/doc/19_subprocess.md new file mode 100644 index 0000000..0a3d93e --- /dev/null +++ b/doc/19_subprocess.md @@ -0,0 +1,50 @@ +# subprocess 모듈: 외부 프로세스 실행하기 + +subprocess 모듈은 파이썬 프로그램 내에서 다른 프로그램이나 셸 명령어를 실행하고, 그 실행 결과를 제어할 수 있도록 해주는 강력한 도구입니다. 즉, 파이썬 스크립트 내에서 외부 프로그램을 호출하여 마치 하나의 프로그램처럼 사용할 수 있게 해줍니다. + +* 시스템 명령 실행: ls, cd, grep 등과 같은 시스템 명령을 파이썬 코드에서 직접 실행할 수 있습니다. +* 외부 프로그램 실행: 다른 언어로 작성된 프로그램을 파이썬에서 호출하여 결과를 얻을 수 있습니다. +* 파이프라인 구축: 여러 프로그램의 표준 입력과 출력을 연결하여 복잡한 작업을 수행할 수 있습니다. +* 자동화: 반복적인 작업을 자동화하기 위해 스크립트를 작성할 때 유용합니다. + +## 주요 함수 +* `subprocess.run()`: 가장 일반적으로 사용되는 함수로, 명령을 실행하고 결과를 반환합니다. +* `subprocess.Popen()`: 프로세스를 생성하고 더 세밀하게 제어할 수 있는 클래스입니다. + +```python +import subprocess + +# 명령 실행 +result = subprocess.run(['ls', '-la'], capture_output=True, text=True) + +# 실행 결과 출력 +print(result.stdout) +print(result.stderr) +``` +위 예시에서는 ls -la 명령을 실행하고, 그 결과를 stdout과 stderr 속성을 통해 얻을 수 있습니다. + +```python +import subprocess + +# 프로세스 생성 +process = subprocess.Popen(['ping', 'google.com'], stdout=subprocess.PIPE) + +# 출력 읽기 +for line in process.stdout: + print(line.decode('utf-8').strip()) + +# 프로세스 종료 +process.wait() +``` +### 주요 옵션 +* args: 실행할 명령어 또는 명령어 리스트 +* cwd: 작업 디렉토리 +* env: 환경 변수 +* stdin, stdout, stderr: 표준 입출력 스트림 +* shell: True로 설정하면 셸을 통해 명령을 실행합니다. + +## 주의 사항 +* 보안: 사용자 입력을 직접 명령어에 포함시키는 것은 보안 문제를 야기할 수 있습니다. +* 에러 처리: `subprocess.run()`은 CompletedProcess 객체를 반환하며, 이를 통해 프로세스의 종료 상태를 확인하고 에러를 처리할 수 있습니다. +* 비동기 처리: asyncio 모듈과 함께 사용하여 비동기 방식으로 프로세스를 실행할 수 있습니다. + diff --git a/doc/19_thread.md b/doc/19_thread.md deleted file mode 100644 index 71f73e3..0000000 --- a/doc/19_thread.md +++ /dev/null @@ -1 +0,0 @@ -# 멀티스레드 diff --git a/doc/20_01_html_parser.md b/doc/20_01_html_parser.md index da4dfac..980eb61 100644 --- a/doc/20_01_html_parser.md +++ b/doc/20_01_html_parser.md @@ -22,4 +22,44 @@ - Parsel - * CSS 선택자 기반의 HTML/XML 파싱 라이브러리: Beautiful Soup과 유사하지만 더욱 강력한 기능을 제공합니다. \ No newline at end of file + * CSS 선택자 기반의 HTML/XML 파싱 라이브러리: Beautiful Soup과 유사하지만 더욱 강력한 기능을 제공합니다. + +## Beautiful Soup +Beautiful Soup은 파이썬에서 HTML 및 XML 문서를 파싱하고 처리하기 위한 파서 라이브러리입니다. 웹 크롤링, 데이터 추출 등 다양한 작업에 활용되며, 복잡한 웹 페이지 구조를 쉽게 분석하고 원하는 정보를 추출할 수 있도록 도와줍니다. + +```bash +pip install beautifulsoup4 +``` + +```python +from bs4 import BeautifulSoup +import requests + +# 웹 페이지 가져오기 +response = requests.get("https://www.example.com") +html = response.text + +# BeautifulSoup 객체 생성 +soup = BeautifulSoup(html, 'html.parser') + +# 특정 태그 찾기 +title = soup.title +print(title.string) + +# 모든 링크 찾기 +links = soup.find_all('a') +for link in links: + print(link.get('href')) +``` +### 주요 메서드 +* find(): 특정 태그를 하나 찾습니다. +* find_all(): 특정 태그를 모두 찾아 리스트로 반환합니다. +* select(): CSS 선택자를 사용하여 요소를 찾습니다. +* get_text(): 태그 내부의 텍스트를 추출합니다. +* get(): 태그의 속성 값을 가져옵니다. + +### 팁 +* CSS 선택자 활용: CSS 선택자를 이용하면 복잡한 구조의 HTML 문서에서도 원하는 요소를 정확하게 찾을 수 있습니다. +* 파서 선택: html.parser 외에도 lxml 등 다른 파서를 사용할 수 있습니다. lxml은 성능이 더 빠르지만 설치가 필요합니다. +* 예외 처리: 네트워크 오류나 HTML 구조 변경 등 예상치 못한 상황에 대비하여 예외 처리를 해야 합니다. +* XPath 사용: XPath를 사용하여 더욱 복잡한 XPath 표현식으로 요소를 선택할 수 있습니다. \ No newline at end of file diff --git a/doc/22_regexp.md b/doc/22_regexp.md index 5f8b721..88d84fa 100644 --- a/doc/22_regexp.md +++ b/doc/22_regexp.md @@ -1,2 +1,73 @@ # 정규표현식 +정규 표현식은 특정한 규칙(패턴)을 가진 문자열을 찾아내기 위한 표현 방식입니다. 텍스트 데이터를 처리할 때 특정 문자열을 검색하거나, 문자열을 추출하거나, 문자열을 변환하는 등 다양한 작업에 활용됩니다. 예를 들어, 이메일 주소, 전화번호, 특정 형식의 로그 데이터 등을 찾아내는 데 사용됩니다. + +## 정규 표현식의 구성 요소 +* 메타 문자: 일반 문자가 아닌 특별한 의미를 가지는 문자입니다. 예를 들어, `.`은 임의의 한 문자를 의미하고, `*`은 앞의 문자가 0번 이상 반복되는 것을 의미합니다. +* 특수 시퀀스: `\d` (숫자), `\s` (공백), `\w` (단어 문자) 등 특정 문자 집합을 나타내는 시퀀스입니다. +* 문자 클래스: `[abc]` 와 같이 대괄호 안에 포함된 문자 중 하나를 의미합니다. + +### 메타 문자 +* `.`: 임의의 한 문자 +* `^`: 문자열의 시작 +* `$`: 문자열의 끝 +* `*`: 앞의 문자가 0번 이상 반복 +* `+`: 앞의 문자가 1번 이상 반복 +* `?`: 앞의 문자가 0번 또는 1번 반복 +* `{m,n}`: 앞의 문자가 최소 m번, 최대 n번 반복 +* `[abc]`: a, b, c 중 하나의 문자 +* `[^abc]`: a, b, c를 제외한 문자 + +## 정규 표현식 예시 +* `\d{3}-\d{4}-\d{4}`: 전화번호 형식 (예: 010-1234-5678) +* `\w+@\w+\.\w+`: 이메일 주소 형식 (예: [이메일 주소 삭제됨]) +* `<[^>]+>`: HTML 태그 추출 +* `^http://`: http://으로 시작하는 문자열 + +## re 모듈 + +re 모듈은 파이썬에서 정규 표현식을 사용하여 문자열을 검색, 치환, 분할하는 등 다양한 작업을 수행할 수 있도록 지원하는 표준 라이브러리입니다. + +* 패턴 매칭: 주어진 문자열에서 정규 표현식과 일치하는 부분을 찾습니다. +* 문자열 치환: 일치하는 부분을 다른 문자열로 바꿉니다. +* 문자열 분할: 정규 표현식을 기준으로 문자열을 분할합니다. + +```python +import re + +text = "The phone number is 415-555-1212." +pattern = "\d{3}-\d{3}-\d{4}" + +# 검색 +match = re.search(pattern, text) +if match: + print(match.group()) # 출력: 415-555-1212 + +# 모든 일치하는 부분 찾기 +all_matches = re.findall(pattern, text) +print(all_matches) # 출력: ['415-555-1212'] + +# 치환 +new_text = re.sub(pattern, "XXX-XXX-XXXX", text) +print(new_text) # 출력: The phone number is XXX-XXX-XXXX. +``` + +### 주요 함수 +* `re.search(pattern, string)`: 문자열 전체에서 패턴을 찾아 첫 번째 매칭 객체를 반환합니다. +* `re.findall(pattern, string)`: 문자열에서 패턴과 일치하는 모든 부분을 리스트로 반환합니다. +* `re.sub(pattern, repl, string)`: 문자열에서 패턴과 일치하는 부분을 다른 문자열로 치환합니다. +* `re.compile(pattern)`: 정규 표현식을 컴파일하여 패턴 객체를 생성합니다. + +```python +import re + +# 정규 표현식 컴파일 +pattern = re.compile(r'\d+') # 숫자만 추출하는 패턴 + +# 문자열 검색 +text = "The price is $19.99" +match = pattern.search(text) +if match: + print(match.group()) # 출력: 19.99 +``` + diff --git a/doc/23_asyncio.md b/doc/23_asyncio.md new file mode 100644 index 0000000..24183b7 --- /dev/null +++ b/doc/23_asyncio.md @@ -0,0 +1,29 @@ +# asyncio 모듈: 비동기 프로그래밍 + +asyncio 모듈은 파이썬에서 비동기 프로그래밍을 지원하는 강력한 도구입니다. 특히, I/O 작업이 많은 네트워킹 프로그램이나 웹 서버 개발에 널리 사용됩니다. + +* 비동기 처리: 여러 작업을 동시에 처리하여 프로그램의 응답성을 높일 수 있습니다. +* I/O 바운드 작업 최적화: 네트워크 통신, 파일 입출력과 같은 I/O 작업을 효율적으로 처리하여 프로그램의 성능을 향상시킬 수 있습니다. +* 코루틴 기반: 코루틴을 사용하여 비동기 코드를 직관적으로 작성할 수 있습니다. + +```python +import asyncio + +async def hello(): + print("Hello, world!") + await asyncio.sleep(1) + print("Hello again!") + +async def main(): + task1 = asyncio.create_task(hello()) + task2 = asyncio.create_task(hello()) + await asyncio.gather(task1, task2) + +asyncio.run(main()) +``` +위 예시에서 async 키워드로 코루틴 함수 hello()를 정의하고, asyncio.run()을 통해 이벤트 루프를 시작하여 코루틴을 실행합니다. asyncio.sleep()은 비동기적으로 1초 동안 일시 정지하는 함수입니다. + +## asyncio의 핵심 개념 +* 이벤트 루프: 비동기 작업을 관리하고 스케줄링하는 중심 엔진입니다. +* 코루틴: 비동기 함수를 정의하는 데 사용되는 키워드 `async`와 `await`를 사용하여 작성됩니다. 코루틴은 실행 중에 일시 중단될 수 있으며, 다른 코루틴이 실행될 수 있는 기회를 제공합니다. +* 태스크: 코루틴을 실행하는 객체입니다. 이벤트 루프는 태스크를 관리하고 실행합니다. diff --git a/doc/23_xml.md b/doc/23_xml.md deleted file mode 100644 index e69de29..0000000 diff --git a/doc/24_json.md b/doc/24_json.md deleted file mode 100644 index e69de29..0000000 diff --git a/doc/25_serialization.md b/doc/25_serialization.md deleted file mode 100644 index e69de29..0000000 diff --git a/doc/26_sys_module.md b/doc/26_sys.md similarity index 100% rename from doc/26_sys_module.md rename to doc/26_sys.md diff --git a/doc/27_argparse_module.md b/doc/27_argparse.md similarity index 100% rename from doc/27_argparse_module.md rename to doc/27_argparse.md diff --git a/doc/28_00_database.md b/doc/28_00_database.md new file mode 100644 index 0000000..e450830 --- /dev/null +++ b/doc/28_00_database.md @@ -0,0 +1,68 @@ +# 데이터베이스 +파이썬은 다양한 데이터베이스와 상호 작용할 수 있는 풍부한 모듈을 제공합니다. 이러한 모듈들은 데이터 저장, 검색, 수정, 삭제 등 데이터베이스 관련 작업을 쉽고 효율적으로 수행할 수 있도록 도와줍니다. + +- sqlite3 + + 파이썬 표준 라이브러리에 포함되어 있어 별도 설치가 필요 없습니다. + 단일 파일 데이터베이스로 간단한 애플리케이션에 적합합니다. + 트랜잭션을 지원하며, ACID 특성을 만족합니다. + + * 작은 규모의 데이터 저장, 캐싱, 설정 파일 등 + * 웹 애플리케이션의 로컬 데이터 저장 + +- MySQLdb/PyMySQL + + MySQL 데이터베이스와 연결하기 위한 모듈입니다. + MySQL의 강력한 기능을 활용할 수 있습니다. + + * 대규모 웹 애플리케이션, 데이터 분석, 데이터베이스 기반 서비스 등 + +- psycopg2 + + PostgreSQL 데이터베이스와 연결하기 위한 모듈입니다. + PostgreSQL의 고급 기능을 활용할 수 있습니다. + * 대규모 데이터베이스, 데이터 웨어하우스 등 + +- SQLAlchemy + + 다양한 데이터베이스(MySQL, PostgreSQL, SQLite 등)를 통일된 인터페이스로 사용할 수 있는 ORM(Object-Relational Mapper)입니다. + 객체 지향적인 방식으로 데이터베이스를 모델링할 수 있습니다. + * 복잡한 데이터 모델링, 데이터베이스 마이그레이션 + +- MongoDB(NoSQL) + + 문서 형태로 데이터를 저장하는 NoSQL 데이터베이스입니다. + 유연한 데이터 모델링과 확장성이 뛰어납니다. + * 대규모 비정형 데이터 저장, 실시간 분석, 콘텐츠 관리 시스템 + +```python +import sqlite3 + +# 데이터베이스 연결 +conn = sqlite3.connect('mydatabase.db') + +# 커서 생성 +cursor = conn.cursor() + +# 테이블 생성 +cursor.execute('''CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT, + email TEXT +)''') + +# 데이터 삽입 +cursor.execute("INSERT INTO users (name, email) VALUES (?, ?)", ('Alice', 'alice@example.com')) + +# 데이터 조회 +cursor.execute("SELECT * FROM users") +results = cursor.fetchall() +for row in results: + print(row) + +# 변경 사항 저장 +conn.commit() + +# 연결 종료 +conn.close() +``` diff --git a/doc/28_01_sqlite3.md b/doc/28_01_sqlite3.md new file mode 100644 index 0000000..adb33a5 --- /dev/null +++ b/doc/28_01_sqlite3.md @@ -0,0 +1,49 @@ +# sqlite3 모듈: 간편한 데이터베이스 관리 도구 + +sqlite3는 파이썬의 표준 라이브러리로, 별도의 설치 없이 바로 사용할 수 있는 경량형 데이터베이스 모듈입니다. 간단한 웹 애플리케이션, 데이터 분석, 설정 파일 저장 등 다양한 용도로 활용됩니다. + +* 간편성: 파이썬 코드 내에서 직관적인 API를 통해 데이터베이스를 관리할 수 있습니다. +* 경량성: 별도의 서버 없이 단일 파일로 데이터베이스를 관리하며, 작은 용량의 데이터를 저장하는 데 적합합니다. +* 내장형: 애플리케이션에 내장하여 독립적으로 실행할 수 있습니다. +* ACID 특성: 원자성(Atomicity), 일관성(Consistency), 고립성(Isolation), 내구성(Durability)을 보장하여 데이터 무결성을 유지합니다. + +```python +import sqlite3 + +# 데이터베이스 연결 +conn = sqlite3.connect('mydatabase.db') + +# 커서 생성 +cursor = conn.cursor() + +# 테이블 생성 +cursor.execute('''CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT, + email TEXT +)''') + +# 데이터 삽입 +cursor.execute("INSERT INTO users (name, email) VALUES (?, ?)", ('Alice', 'alice@example.com')) + +# 데이터 조회 +cursor.execute("SELECT * FROM users") +results = cursor.fetchall() +for row in results: + print(row) + +# 변경 사항 저장 +conn.commit() + +# 연결 종료 +conn.close() +``` + +## 주요 기능 +* 데이터베이스 연결: sqlite3.connect() 함수를 사용하여 데이터베이스에 연결합니다. +* 커서 생성: cursor() 메서드를 사용하여 커서를 생성하고 SQL 문을 실행합니다. +* SQL 실행: execute() 메서드를 사용하여 SQL 문을 실행합니다. +* 데이터 조회: fetchall() 메서드를 사용하여 조회 결과를 가져옵니다. +* 데이터 변경: execute() 메서드를 사용하여 INSERT, UPDATE, DELETE 등의 SQL 문을 실행합니다. +* 트랜잭션: commit() 메서드로 변경 사항을 저장하고, rollback() 메서드로 변경 사항을 취소합니다. + diff --git a/doc/28_02_pymysql.md b/doc/28_02_pymysql.md new file mode 100644 index 0000000..217ad03 --- /dev/null +++ b/doc/28_02_pymysql.md @@ -0,0 +1,51 @@ +# PyMySQL 모듈 +MariaDB는 높은 호환성과 성능으로 많은 사랑을 받는 오픈 소스 데이터베이스입니다. 파이썬에서 MariaDB를 사용하려면 PyMySQL과 같은 별도의 드라이버를 설치해야 합니다. + +```bash +pip install PyMySQL +``` + +```python +import pymysql + +# 데이터베이스 연결 정보 +host = 'your_host' +user = 'your_user' +password = 'your_password' +database = 'your_database' + +# 데이터베이스 연결 +try: + conn = pymysql.connect( + host=host, + user=user, + password=password, + database=database + ) + print("데이터베이스에 연결되었습니다.") +except pymysql.Error as e: + print(f"Error: {e}") + +# 커서 생성 +cursor = conn.cursor() + +# SQL 쿼리 실행 (예시: 모든 데이터 조회) +cursor.execute("SELECT * FROM your_table") +result = cursor.fetchall() +for row in result: + print(row) + +# 변경 사항 커밋 +conn.commit() + +# 연결 종료 +conn.close() +``` + +* 데이터베이스 연결 정보: 호스트, 사용자, 비밀번호, 데이터베이스 이름을 정확하게 입력해야 합니다. +* 연결 시도: pymysql.connect() 함수를 사용하여 데이터베이스에 연결합니다. +* 커서 생성: cursor() 메서드를 사용하여 커서를 생성합니다. 커서는 데이터베이스와 상호 작용하는 데 사용되는 객체입니다. +* SQL 쿼리 실행: execute() 메서드를 사용하여 SQL 쿼리를 실행합니다. +* 데이터 조회: fetchall() 메서드를 사용하여 모든 결과를 가져옵니다. +* 변경 사항 커밋: commit() 메서드를 사용하여 데이터베이스에 변경 사항을 반영합니다. +* 연결 종료: close() 메서드를 사용하여 데이터베이스 연결을 종료합니다. diff --git a/doc/28_04_sqlqlchemy.md b/doc/28_04_sqlqlchemy.md new file mode 100644 index 0000000..41070b1 --- /dev/null +++ b/doc/28_04_sqlqlchemy.md @@ -0,0 +1,154 @@ +# SQLAlchemy: 파이썬에서 객체 지향적으로 데이터베이스를 다루는 강력한 도구 + +SQLAlchemy는 파이썬에서 데이터베이스를 다루기 위한 강력한 ORM(Object-Relational Mapper) 라이브러리입니다. ORM은 객체 지향 언어의 개념을 사용하여 관계형 데이터베이스를 다루는 방식으로, 개발자들이 SQL 문법을 직접 작성하지 않고도 데이터베이스와 상호 작용할 수 있도록 해줍니다. + +* 다양한 데이터베이스 지원: MySQL, PostgreSQL, SQLite 등 다양한 관계형 데이터베이스를 지원합니다. +* 객체-관계 매핑: 파이썬 클래스를 데이터베이스 테이블에 매핑하여 객체 지향적인 방식으로 데이터를 관리합니다. +* SQLAlchemy ORM: SQL을 직접 작성하지 않고, 파이썬 객체를 통해 데이터베이스를 조작할 수 있습니다. +* SQLAlchemy Core: 저수준 API를 제공하여 복잡한 SQL 쿼리를 직접 작성할 수 있습니다. +* 데이터베이스 마이그레이션: 데이터베이스 스키마를 관리하고 변경하는 기능을 제공합니다. + +```python +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy import Column, Integer, String + +# 데이터베이스 연결 +engine = create_engine('sqlite:///mydatabase.db') +Base = declarative_base() + +# User 모델 정의 +class User(Base): + __tablename__ = 'users' + + id = Column(Integer, primary_key=True) + name = Column(String(50), nullable=False) + email = Column(String(120), unique=True, nullable=False) + +# 데이터베이스 생성 +Base.metadata.create_all(engine) + +# Session 생성 (데이터베이스와의 상호작용을 위한 세션) +from sqlalchemy.orm import sessionmaker +Session = sessionmaker(bind=engine) +session = Session() + +# 데이터 추가 +new_user = User(name='Alice', email='alice@example.com') +session.add(new_user) +session.commit() + +# 데이터 조회 +users = session.query(User).all() +for user in users: + print(user.name, user.email) +``` + +## 주요 개념 +* Engine: 데이터베이스에 대한 연결 정보를 담고 있는 객체입니다. +* Session: 데이터베이스와의 상호 작용을 위한 세션 객체입니다. +* Model: 데이터베이스 테이블에 해당하는 파이썬 클래스입니다. +* Query: 데이터베이스에서 데이터를 조회하기 위한 쿼리 객체입니다. + +## 모델 +### 모델 정의 기본 구조 +```python +from sqlalchemy import Column, Integer, String +from sqlalchemy.ext.declarative import declarative_base + +Base = declarative_base() + +class User(Base): + __tablename__ = 'users' + + id = Column(Integer, primary_key=True) + name = Column(String(50), nullable=False) + email = Column(String(120), unique=True, nullable=False) +``` +* Base: 모든 모델 클래스가 상속받는 기본 클래스입니다. +* tablename: 데이터베이스 테이블 이름을 지정합니다. +* Column: 테이블의 각 열을 정의합니다. + * type: 데이터 타입 (Integer, String, Float, DateTime 등) + - Integer: 정수형 데이터 + - String(길이): 문자열 데이터 + * primary_key: 기본키 설정 + * nullable: null 허용 여부 + * unique: 중복 값 허용 여부 + * index: 인덱스 생성 + * foreign_key: 외래 키 설정 + * 그 외 다양한 속성 지원 + +### 관계 설정 +- one-to-one +```python +user = relationship("User", back_populates="address") +``` +- one-to-many +```python +orders = relationship("Order", back_populates="user") +``` +- many-to-many +```python +tags = relationship("Tag", secondary=association_table, back_populates="posts") +``` +### 모델 메타데이터 +* metadata: 모든 모델에 대한 정보를 담고 있는 객체입니다. create_all() 메서드를 사용하여 데이터베이스에 테이블을 생성합니다. + +```python +class Post(Base): + __tablename__ = 'posts' + + id = Column(Integer, primary_key=True) + title = Column(String(100), nullable=False) + content = Column(Text) + created_at = Column(DateTime, default=func.now()) + user_id = Column(Integer, ForeignKey('users.id')) + + user = relationship("User", back_populates="posts") +``` + +## 쿼리 +* session.query(모델명): 해당 모델에 대한 쿼리 객체를 생성합니다. + +### 쿼리 수행 +- 모든 데이터 조회 +```python +results = query.all() +``` +- 첫 번째 데이터 조회 +```python +first_result = query.first() +``` +- 조건에 맞는 데이터 조회 +```python +users = session.query(User).filter(User.name == 'Alice') +``` +- 데이터 정렬 +```python +users = session.query(User).order_by(User.id.desc()) +``` +- 데이터 그룹화 +```python +groups = session.query(func.count(User.id), User.city).group_by(User.city) +``` +### 쿼리 메서드 +* filter(): 조건에 맞는 데이터를 필터링합니다. +* order_by(): 데이터를 정렬합니다. +* group_by(): 데이터를 그룹화합니다. +* limit(): 조회 결과를 제한합니다. +* offset(): 조회 시작 위치를 설정합니다. +* all(): 모든 결과를 리스트로 반환합니다. +* first(): 첫 번째 결과를 반환합니다. +* one(): 정확히 하나의 결과를 반환하고, 없거나 여러 개일 경우 예외를 발생시킵니다. + +### 복잡한 쿼리 +* 조인: 여러 테이블을 연결하여 데이터를 조회합니다. +* 서브쿼리: 쿼리 안에 또 다른 쿼리를 포함하여 복잡한 조건을 설정합니다. +* 함수: func를 사용하여 SQL 함수를 호출합니다. + +```python +from sqlalchemy import func + +# 특정 도시에 거주하는 사용자의 평균 나이 +result = session.query(func.avg(User.age)).filter(User.city == 'Seoul').scalar() +``` diff --git a/doc/29_database.md b/doc/29_database.md deleted file mode 100644 index e69de29..0000000 diff --git a/doc/29_numpy.md b/doc/29_numpy.md new file mode 100644 index 0000000..5fd8318 --- /dev/null +++ b/doc/29_numpy.md @@ -0,0 +1,46 @@ +# Numpy : 파이썬의 강력한 수치 계산 도구 + +NumPy는 Numerical Python의 줄임말로, 파이썬에서 과학 계산, 수치 분석 등을 효율적으로 수행하기 위한 필수적인 라이브러리입니다. 특히, **다차원 배열(ndarray)**을 효과적으로 다루고 벡터화 연산을 지원하여 빠르고 효율적인 수치 계산을 가능하게 합니다. + +* 빠른 속도: C 언어로 작성된 내부 코드를 사용하여 파이썬 리스트보다 훨씬 빠른 연산을 수행합니다. +* 편리한 사용법: 다양한 함수와 메서드를 제공하여 복잡한 수치 계산을 간단하게 수행할 수 있습니다. +* 대규모 데이터 처리: 대용량 데이터를 효율적으로 처리할 수 있는 기능을 제공합니다. +* 다양한 라이브러리와의 호환성: SciPy, Pandas, Matplotlib 등 다양한 과학 계산 라이브러리와 호환됩니다. + +## NumPy의 주요 특징 +* 다차원 배열(ndarray): NumPy의 핵심 데이터 구조입니다. 행렬, 벡터, 텐서 등 다양한 형태의 데이터를 효율적으로 저장하고 연산할 수 있습니다. +* 벡터화 연산: 반복문 없이 배열 전체에 대한 연산을 한 번에 수행하여 속도를 크게 향상시킵니다. +* 선형대수 연산: 행렬 곱셈, 역행렬, 고유값 분해 등 선형대수 연산을 위한 다양한 함수를 제공합니다. +* 난수 생성: 다양한 분포의 난수를 생성할 수 있는 기능을 제공합니다. +* 브로드캐스팅: shape이 다른 배열 간의 연산을 자동으로 처리하는 기능입니다. + +## 주요 함수 +* ndarray 생성: `np.array()`, `np.zeros()`, `np.ones()`, `np.arange()` 등 +* 배열 연산: `+`, `-`, `*`, `/`, `**` 등의 산술 연산자, `dot` 함수를 이용한 행렬 곱셈 등 +* 배열 조작: `reshape()`, `transpose()`, `flatten()`, `concatenate()` 등 +* 선형대수: linalg 모듈을 이용한 행렬 분해, 역행렬 계산 등 +* 통계: `mean()`, `std()`, `sum()`, `max()`, `min()` 등 + +```python +import numpy as np + +# 1차원 배열 생성 +arr = np.array([1, 2, 3, 4, 5]) + +# 2차원 배열 생성 +arr2d = np.array([[1, 2, 3], [4, 5, 6]]) + +# 배열 연산 +result = arr + 2 +print(result) # [3 4 5 6 7] + +# 행렬 곱셈 +result = np.dot(arr2d, arr2d.T) +print(result) + +# 난수 생성 +random_numbers = np.random.rand(3, 3) +print(random_numbers) +``` + + diff --git a/doc/30_pandas.md b/doc/30_pandas.md new file mode 100644 index 0000000..ac5b3a0 --- /dev/null +++ b/doc/30_pandas.md @@ -0,0 +1,55 @@ +# Pandas 모듈: 데이터 분석의 핵심 도구 + +Pandas는 파이썬에서 데이터 분석을 위한 가장 강력하고 인기 있는 라이브러리 중 하나입니다. 특히, **데이터프레임(DataFrame)**이라는 2차원 표 형태의 데이터 구조를 제공하여 데이터를 효율적으로 관리하고 분석할 수 있도록 돕습니다. + +* 데이터 구조: Series와 DataFrame이라는 직관적인 자료 구조를 제공하여 데이터를 쉽게 다룰 수 있습니다. +* 데이터 처리: 데이터 읽기, 쓰기, 선택, 필터링, 변형, 집계 등 다양한 데이터 처리 기능을 제공합니다. +* 데이터 분석: 그룹화, 병합, 시각화 등 데이터 분석에 필요한 기능을 제공합니다. +* 다양한 데이터 형식 지원: CSV, Excel, SQL 데이터베이스 등 다양한 형식의 데이터를 읽고 쓸 수 있습니다. +* NumPy와의 연동: NumPy와의 연동을 통해 고성능 수치 계산을 수행할 수 있습니다. +* Matplotlib와의 연동: Matplotlib과의 연동을 통해 데이터 시각화를 쉽게 수행할 수 있습니다. + +```python +import pandas as pd + +# 데이터 생성 +data = {'이름': ['홍길동', '김철수', '박영희'], + '나이': [30, 25, 28], + '성별': ['남', '남', '여']} +df = pd.DataFrame(data) + +# 데이터 출력 +print(df) + +# 특정 열 선택 +print(df['이름']) + +# 조건에 맞는 데이터 추출 +print(df[df['나이'] > 25]) + +# 그룹화 +grouped = df.groupby('성별') +print(grouped.mean()) + +# 시각화 (Matplotlib과 함께 사용) +import matplotlib.pyplot as plt +df.plot(kind='bar') +plt.show() +``` + +## 기본 개념 +* Series: 1차원 배열과 유사하며, 각 요소에 인덱스가 부여된 자료 구조입니다. +* DataFrame: 표 형태의 2차원 데이터를 나타내는 자료 구조입니다. 행과 열로 구성되어 있으며, 각 열은 Series로 구성됩니다. + +## 주요 기능 +* 데이터 읽기/쓰기: 다양한 형식의 파일(CSV, Excel, SQL 등)을 읽고 쓸 수 있습니다. +* 데이터 선택: 행, 열, 조건에 맞는 데이터를 선택할 수 있습니다. +* 데이터 변형: 데이터를 정렬, 필터링, 그룹화, 합계, 평균 등 다양한 방식으로 변형할 수 있습니다. +* 결측치 처리: 결측치를 찾아내고 처리하는 기능을 제공합니다. +* 데이터 병합: 여러 데이터프레임을 합칠 수 있습니다. + +## 활용 분야 +* 데이터 분석: 대용량 데이터를 분석하고 시각화하여 인사이트를 도출합니다. +* 데이터 전처리: 머신 러닝 모델에 사용하기 위한 데이터를 정제하고 가공합니다. +* 금융 데이터 분석: 주식 시장 데이터, 금융 데이터 분석에 활용됩니다. +* 과학 데이터 분석: 과학 실험 데이터 분석에 활용됩니다. \ No newline at end of file diff --git a/doc/39_00_flask.md b/doc/39_00_flask.md new file mode 100644 index 0000000..7b68230 --- /dev/null +++ b/doc/39_00_flask.md @@ -0,0 +1,39 @@ +# Flask 모듈: 간편하고 유연한 마이크로 웹 프레임워크 + +Flask는 파이썬으로 웹 애플리케이션을 개발하기 위한 경량급 웹 프레임워크입니다. Django와 같은 대형 프레임워크에 비해 학습 곡선이 낮고, 필요한 기능만 골라 사용할 수 있어 빠르게 프로토타입을 만들거나 작은 규모의 웹 애플리케이션을 개발하는 데 적합합니다. + +```bash +pip install Flask +``` + +* 간결함: 최소한의 기능만 제공하여 빠르게 시작할 수 있습니다. +* 유연성: 필요에 따라 다양한 확장 모듈을 추가하여 기능을 확장할 수 있습니다. +* Jinja2 템플릿 엔진: 동적인 웹 페이지를 생성하기 위한 강력한 템플릿 엔진을 제공합니다. +* WSGI 1.0 호환: 다양한 웹 서버와 호환됩니다. +* 확장성: 다양한 확장 모듈을 통해 기능을 추가할 수 있습니다. + +## 기본 사용법 +```python +from flask import Flask + +app = Flask(__name__) + +@app.route('/') +def hello(): + return 'Hello, World!' + +if __name__ == '__main__': + app.run() +``` +* Flask 객체 생성: `Flask(__name__)`으로 Flask 애플리케이션을 생성합니다. +* 라우팅: `@app.route('/')` 데코레이터를 사용하여 URL과 함수를 연결합니다. +* 함수: 요청을 받았을 때 실행될 함수를 정의합니다. +* 서버 실행: `app.run()`으로 개발 서버를 실행합니다. + +## 주요 기능 +* 라우팅: URL과 함수를 연결하여 요청을 처리합니다. +* 템플릿: Jinja2 템플릿 엔진을 사용하여 동적인 HTML 페이지를 생성합니다. +* 요청 처리: HTTP 요청 메서드(GET, POST 등)에 따라 다른 함수를 실행할 수 있습니다. +* 세션: 사용자 세션을 관리하여 상태를 유지할 수 있습니다. +* 쿠키: 쿠키를 사용하여 사용자 정보를 저장하고 관리할 수 있습니다. +* 데이터베이스: SQLAlchemy 등의 ORM을 사용하여 데이터베이스를 연결할 수 있습니다. diff --git a/doc/39_01_controller.md b/doc/39_01_controller.md new file mode 100644 index 0000000..1067941 --- /dev/null +++ b/doc/39_01_controller.md @@ -0,0 +1,171 @@ +# Flask에서 라우팅하는 방법 +Flask에서 라우팅은 특정 URL에 어떤 함수를 연결하여 요청을 처리하는 것을 의미합니다. 즉, 사용자가 어떤 URL로 접속하면 그에 해당하는 함수가 실행되어 동적인 웹 페이지를 생성하게 됩니다. + +## @app.route 데코레이터 +Flask에서 라우팅은 @app.route 데코레이터를 사용하여 간단하게 정의할 수 있습니다. 이 데코레이터는 함수 위에 붙여서 해당 함수가 처리할 URL을 지정합니다. + +```python +from flask import Flask + +app = Flask(__name__) + +@app.route('/') +def index(): + return 'Hello, World!' + +if __name__ == '__main__': + app.run() +``` +위 코드에서 @app.route('/')는 루트 경로('/')에 대한 요청이 들어오면 index() 함수를 실행하도록 설정합니다. + +## 다양한 라우팅 방법 +### 정적 라우팅 +특정 URL에 하나의 함수를 연결하는 방식입니다. +```python +@app.route('/about') +``` + +### 동적 라우팅 +URL에 변수를 포함하여 다양한 요청을 처리할 수 있습니다. +```python +@app.route('/user/') +``` +```python +from flask import Flask + +app = Flask(__name__) + +@app.route('/user/') +def show_user_profile(username): + # 사용자 정보를 조회하여 반환 + return f'User {username}' + +if __name__ == '__main__': + app.run() +``` +위 코드에서 /user/ 라우트는 username이라는 변수를 포함하고 있습니다. 이를 통해 /user/john과 같은 URL에 접속하면 username 변수에 'john'이 할당되고, show_user_profile 함수에서 이 값을 사용하여 사용자 정보를 조회할 수 있습니다. + +### HTTP 메서드 +methods 인자를 사용하여 GET, POST, PUT 등 다양한 HTTP 메서드를 지원할 수 있습니다. +```python +@app.route('/login', methods=['GET', 'POST']) +``` + + +## 다양한 변수 형식 +Flask는 다양한 URL 변환기를 제공하여 URL에서 값을 추출하고 검증하는 기능을 제공합니다. + +* `int:변수명`: 정수 값 +* `float:변수명`: 부동소수점 값 +* `path:변수명`: 슬래시(/)를 포함한 경로 +* `uuid:변수명`: UUID 값 + +```python +@app.route('/post/') +def show_post(post_id): + # post_id는 정수형으로 변환되어 사용됩니다. + return f'Post {post_id}' +``` + +* 변환기 사용자 정의: `Converter`를 상속하여 사용자 정의 변환기를 만들 수 있습니다. +* 기본값 설정: `default` 인자를 사용하여 변수에 기본값을 설정할 수 있습니다. +* 필수 파라미터: `required` 인자를 사용하여 필수 파라미터를 지정할 수 있습니다. + +## URL 파라미터 값 가져오기 +URL에 ?를 붙여 쿼리 파라미터를 전달할 수 있습니다. 예를 들어, /search?q=python과 같이 사용합니다. 이러한 쿼리 파라미터는 `request.args`를 통해 접근할 수 있습니다. +```python +from flask import Flask, request + +app = Flask(__name__) + +@app.route('/search') +def search(): + query = request.args.get('q') + return f'You searched for: {query}' +``` + +## 응답 코드 지정 + +```python +from flask import Flask, make_response + +app = Flask(__name__) + +@app.route('/') +def index(): + # 404 Not Found 응답 + return make_response('Not Found', 404) +``` +* make_response() 함수: 직접 응답 객체를 생성하여 응답 코드를 지정할 수 있습니다. 첫 번째 인자는 응답 내용, 두 번째 인자는 상태 코드입니다. + +### Flask의 내장 함수 활용 +* abort(code): 특정 상태 코드와 함께 예외를 발생시켜 응답을 중단합니다. +* redirect(location, code=302): 다른 URL로 리다이렉트합니다. +```python +from flask import abort, redirect, url_for + +@app.route('/admin') +def admin_page(): + if not is_admin: + abort(403) # 403 Forbidden + return 'Welcome, admin!' +``` + +### Jinja2 템플릿과 함께 사용 +```python +from flask import render_template + +@app.route('/error') +def error_page(): + return render_template('error.html'), 404 +``` + +### Response 객체 +더 복잡한 응답을 생성하려면 Response 객체를 직접 사용할 수 있습니다. +```python +from flask import Response + +@app.route('/custom_response') +def custom_response(): + response = Response('Custom response', status=201, mimetype='text/plain') + response.headers['X-Custom-Header'] = 'custom value' + return response +``` + +## 파일 업로드 +```python +from flask import Flask, request, render_template + +app = Flask(__name__) +UPLOAD_FOLDER = 'static/uploads' # 업로드 파일 저장 경로 + +@app.route('/', methods=['GET', 'POST']) +def upload_file(): + if request.method == 'POST': + if 'file' not in request.files: + flash('No file part') + return redirect(request.url) + file = request.files['file'] + if file.filename == '': + flash('No selected file') + return redirect(request.url) + if file: + filename = secure_filename(file.filename) + file.save(os.path.join(UPLOAD_FOLDER, filename)) + return 'Uploaded file successfully' + return render_template('upload.html') + +if __name__ == '__main__': + app.run(debug=True) +``` +* UPLOAD_FOLDER: 업로드된 파일을 저장할 폴더 경로를 설정합니다. +* request.files: enctype="multipart/form-data"로 설정된 폼에서 전송된 파일을 담고 있는 딕셔너리입니다. +* secure_filename: Flask에서 제공하는 함수로, 업로드 파일 이름을 안전하게 처리하여 디렉토리 트래버설 공격을 방지합니다. +* file.save(): 파일을 지정된 경로에 저장합니다. + +## 추가적인 기능 +* URL for: url_for 함수를 사용하여 URL을 생성할 수 있습니다. +* HTTP 메서드: GET, POST, PUT, DELETE 등 다양한 HTTP 메서드를 지원합니다. +* HTTP 상태 코드: return 문에서 상태 코드를 지정하여 응답할 수 있습니다. +* 템플릿 엔진: Jinja2를 사용하여 동적인 HTML 페이지를 생성할 수 있습니다. + diff --git a/doc/39_02_view.md b/doc/39_02_view.md new file mode 100644 index 0000000..e900720 --- /dev/null +++ b/doc/39_02_view.md @@ -0,0 +1,105 @@ +# Jinja2: 템플릿 엔진 + +Jinja2는 파이썬에서 사용되는 강력하고 유연한 템플릿 엔진입니다. 특히 Flask와 같은 웹 프레임워크에서 HTML 페이지를 동적으로 생성하는 데 널리 사용됩니다. Jinja2를 사용하면 복잡한 웹 페이지를 효율적으로 관리하고, 데이터를 동적으로 렌더링할 수 있습니다. + +* 간결한 문법: 파이썬과 유사한 문법을 사용하여 쉽게 학습하고 사용할 수 있습니다. +* 강력한 기능: 조건문, 반복문, 상속, 필터 등 다양한 기능을 제공하여 복잡한 템플릿을 구현할 수 있습니다. +* 안전성: 자동으로 HTML 엔티티를 이스케이프하여 XSS 공격을 방지합니다. +* 확장성: 커스텀 필터, 테스트, 글로벌 변수 등을 정의하여 기능을 확장할 수 있습니다. + +## Jinja2의 기본 구조 +Jinja2 템플릿은 .html 확장자를 가지는 파일로, HTML 코드와 Jinja2 특정 문법이 혼재되어 있습니다. + +* 변수 출력: {{ 변수명 }} +* 조건문: {% if 조건 %} ... {% endif %} +* 반복문: {% for item in list %} ... {% endfor %} +* 주석: {# 주석 내용 #} + +```jinja + + + + Jinja2 예제 + + +

Hello, {{ name }}!

+
    + {% for item in items %} +
  • {{ item }}
  • + {% endfor %} +
+ + +``` +위 템플릿에서 name과 items 변수는 파이썬 코드에서 전달된 값으로 대체됩니다. + +## 주요 기능 +* 상속: 기본 템플릿을 상속하여 하위 템플릿에서 재사용 가능 +* 필터: 변수를 다양한 형식으로 변환하거나 필터링 +* 매크로: 자주 사용하는 코드 블록을 함수처럼 정의하여 재사용 +* 자동 에스케이핑: XSS 공격을 방지하기 위해 HTML 특수 문자를 자동으로 이스케이프 + +## Flask와 함께 사용하기 +```python +from flask import Flask, render_template + +app = Flask(__name__) + +@app.route('/') +def index(): + name = 'World' + items = ['apple', 'banana', 'orange'] + return render_template('index.html', name=name, items=items) +``` + +## 상속 + +* 기본 템플릿: 모든 페이지에 공통적으로 사용되는 요소(헤더, 푸터, 네비게이션 등)를 포함하는 템플릿입니다. +* 자식 템플릿: 기본 템플릿을 상속받아 특정 페이지에 필요한 내용을 추가하거나 수정하는 템플릿입니다. + +```jinja + + + + {% block title %}{% endblock %} + + +
+
+
+ {% block content %}{% endblock %} +
+
+
+ + + +{% extends "base.html" %} + +{% block title %}About Us{% endblock %} + +{% block content %} +

About Us

+

This is the about page.

+{% endblock %} +``` +* `{% extends "base.html" %}`: base.html 템플릿을 상속합니다. +* `{% block title %}{% endblock %}`: title 블록을 정의하여 자식 템플릿에서 내용을 채울 수 있도록 합니다. +* `{% block content %}{% endblock %}`: content 블록을 정의하여 각 페이지의 주요 내용을 채울 수 있도록 합니다. + + +## include +include는 다른 템플릿 파일을 현재 템플릿에 포함시키는 지시자입니다. 마치 함수 호출처럼 다른 템플릿을 호출하여 그 내용을 현재 위치에 삽입하는 효과를 냅니다. + +```jinja +{% include 'header.html' %} +``` + +## macro +macro는 템플릿 내에서 함수처럼 사용할 수 있는 코드 블록입니다. 특정 기능을 수행하는 코드를 한 번 정의해놓고, 필요한 곳에서 호출하여 사용할 수 있습니다. + +```jinja +{% macro input(name, value='', type='text') %} + +{% endmacro %} +``` diff --git a/doc/39_03_model.md b/doc/39_03_model.md new file mode 100644 index 0000000..0e3a7aa --- /dev/null +++ b/doc/39_03_model.md @@ -0,0 +1,73 @@ +# SQLAlchemy :Flask에서 데이터베이스 연결하기 + +Flask는 자체적으로 데이터베이스를 관리하는 기능은 제공하지 않지만, SQLAlchemy와 같은 ORM(Object-Relational Mapper) 라이브러리를 사용하여 다양한 데이터베이스를 쉽게 연결하고 관리할 수 있습니다. SQLAlchemy는 파이썬 객체를 데이터베이스 테이블에 매핑하여 데이터베이스와 상호 작용하는 것을 더욱 직관적으로 만들어줍니다. + +```bash +pip install Flask SQLAlchemy +``` + +## 주요 개념 +* SQLAlchemy: 파이썬 ORM으로, 객체와 관계형 데이터베이스 테이블을 매핑하는 역할을 합니다. +* Model: 데이터베이스 테이블과 대응되는 파이썬 클래스입니다. +* Session: 데이터베이스와의 상호 작용을 위한 세션 객체입니다. + +## 1. Flask 애플리케이션 생성 및 설정 + +```python +from flask import Flask +from flask_sqlalchemy import SQLAlchemy + +app = Flask(__name__) + +# 데이터베이스 설정 +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db' # SQLite 사용 예시 +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 추적 비활성화 + +db = SQLAlchemy(app) +``` +* SQLALCHEMY_DATABASE_URI: 데이터베이스 연결 문자열을 설정합니다. +* SQLALCHEMY_TRACK_MODIFICATIONS: 모델 변경 사항을 자동으로 추적하는 기능을 비활성화합니다. + +## 2. 모델 정의 +```python +class User(db.Model): + id = db.Column(db.Integer, primary_key=True) + username = db.Column(db.String(80), unique=True, nullable=False) + email = db.Column(db.String(120), unique=True, nullable=False) + + def __repr__(self): + return '' % self.username +``` +* db.Model: SQLAlchemy 모델을 상속받아 테이블과 매핑할 클래스를 정의합니다. +* db.Column: 테이블의 각 열을 정의합니다. + +## 3. 데이터베이스 생성 및 모델 초기화 +```python +with app.app_context(): + db.create_all() +``` +위 코드를 실행하면 app.db라는 SQLite 데이터베이스가 생성되고, User 모델에 해당하는 테이블이 생성됩니다. + +## 4. 데이터베이스 CRUD 작업 +```python +# 데이터 추가 +user = User(username='admin', email='admin@example.com') +db.session.add(user) +db.session.commit() + +# 데이터 조회 +users = User.query.all() +for user in users: + print(user.username) + +# 데이터 수정 +user = User.query.filter_by(username='admin').first() +user.email = 'new_email@example.com' +db.session.commit() + +# 데이터 삭제 +db.session.delete(user) +db.session.commit() +``` + + diff --git a/doc/40_gui.md b/doc/40_gui.md deleted file mode 100644 index e69de29..0000000 diff --git a/doc/40_tkinter.md b/doc/40_tkinter.md new file mode 100644 index 0000000..45a08ee --- /dev/null +++ b/doc/40_tkinter.md @@ -0,0 +1,186 @@ +# Tkinter 모듈: 간단한 GUI 프로그램 만들기 + +Tkinter는 파이썬에서 GUI(Graphical User Interface, 그래픽 사용자 인터페이스) 프로그램을 만들기 위한 표준 라이브러리입니다. 즉, 파이썬 코드를 사용하여 창, 버튼, 라벨 등 다양한 UI 요소를 만들고 사용자와 상호 작용하는 프로그램을 개발할 수 있도록 도와줍니다. + +```python +import tkinter as tk + +# 메인 창 생성 +window = tk.Tk() +window.title("첫 번째 Tkinter 프로그램") + +# 라벨 생성 +label = tk.Label(window, text="Hello, Tkinter!") +label.pack() + +# 버튼 생성 +button = tk.Button(window, text="클릭", command=lambda: print("버튼 클릭")) +button.pack() + +# 창 실행 +window.mainloop() +``` +위 코드는 간단한 창을 만들고, 그 안에 "Hello, Tkinter!" 라는 라벨과 "클릭" 버튼을 배치하는 예시입니다. 버튼을 클릭하면 콘솔에 "버튼 클릭"이 출력됩니다. + +## 위젯 +Tkinter는 다양한 종류의 위젯을 제공하여 풍부한 사용자 인터페이스를 구축할 수 있도록 지원합니다. 각 위젯은 특정한 기능을 수행하며, 이들을 조합하여 복잡한 GUI 애플리케이션을 만들 수 있습니다. + +### 컨테이너 위젯 +* Frame: 다른 위젯들을 그룹화하여 관리하는 컨테이너입니다. 레이아웃 관리자를 사용하여 프레임 내부에 위젯을 배치합니다. +* LabelFrame: 프레임과 유사하지만, 라벨을 포함하여 그룹을 구분합니다. +* PanedWindow: 두 개 이상의 창을 가로 또는 세로로 나누어 관리하는 컨테이너입니다. + +### 기본 위젯 +* Label: 텍스트를 표시하는 위젯입니다. +* Button: 버튼을 생성하여 사용자의 클릭 이벤트를 처리합니다. +* Entry: 한 줄의 텍스트를 입력받는 위젯입니다. +* Text: 여러 줄의 텍스트를 입력하고 편집할 수 있는 위젯입니다. +* Checkbutton: 체크박스를 생성하여 선택 여부를 확인합니다. +* Radiobutton: 라디오 버튼을 생성하여 여러 옵션 중 하나를 선택하도록 합니다. +* Listbox: 여러 항목을 리스트 형태로 보여주고, 사용자가 항목을 선택할 수 있도록 합니다. +* Scrollbar: 스크롤바를 생성하여 내용이 많은 위젯을 스크롤하여 볼 수 있도록 합니다. +* Message: 텍스트를 여러 줄로 표시하며, 자동 줄 바꿈 기능을 제공합니다. + +### 메뉴 위젯 +* Menu: 메뉴바를 생성합니다. +* Menubutton: 메뉴 버튼을 생성합니다. +* MenuButton: 메뉴 버튼을 생성합니다. (Menubutton과 동일) + +### 다이얼로그 위젯 +* Messagebox: 간단한 메시지 박스를 생성합니다. +* filedialog: 파일 선택 대화상자를 생성합니다. +* colorchooser: 색상 선택 대화상자를 생성합니다. + +### 기타 위젯 +* Canvas: 그림을 그리거나 사용자 정의 위젯을 만들 때 사용합니다. +* Scale: 슬라이더를 생성하여 값을 조절할 수 있도록 합니다. +* Spinbox: 숫자를 입력하는 스핀 박스를 생성합니다. +* OptionMenu: 드롭다운 메뉴를 생성합니다. + +### 위젯의 속성과 메서드 +각 위젯은 다양한 속성과 메서드를 가지고 있어 외형과 기능을 커스터마이징할 수 있습니다. 예를 들어, font, fg, bg 속성을 사용하여 폰트, 전경색, 배경색을 설정할 수 있습니다. + +## 레이아웃 관리자 +Tkinter에서 다양한 위젯을 생성하고 창에 배치하려면 레이아웃 관리자가 필요합니다. 레이아웃 관리자는 위젯들의 위치와 크기를 자동으로 조절하여 보기 좋은 화면을 구성하는 역할을 합니다. Tkinter는 주로 다음과 같은 세 가지 레이아웃 관리자를 제공합니다. + +### pack() 레이아웃 관리자 +위젯을 순서대로 창에 채워 넣습니다. 마치 박스를 쌓아 올리듯이 위젯을 배치합니다. +* 장점: 간단하고 사용하기 쉽습니다. +* 단점: 복잡한 레이아웃을 구현하기 어려울 수 있습니다. + +```python +import tkinter as tk + +root = tk.Tk() + +label1 = tk.Label(root, text="첫 번째 라벨") +label1.pack() + +label2 = tk.Label(root, text="두 번째 라벨") +label2.pack(side="bottom") # 아래쪽에 배치 + +root.mainloop() +``` + +### grid() 레이아웃 관리자 + +위젯을 행과 열 형태의 격자에 배치합니다. 엑셀 시트처럼 생각하면 쉽습니다. + +* 장점: 복잡한 레이아웃을 정교하게 구성할 수 있습니다. +* 단점: 초기 설정이 다소 복잡할 수 있습니다. + +```python +import tkinter as tk + +root = tk.Tk() + +label1 = tk.Label(root, text="첫 번째 라벨") +label1.grid(row=0, column=0) + +label2 = tk.Label(root, text="두 번째 라벨") +label2.grid(row=1, column=0) + +root.mainloop() +``` +### place() 레이아웃 관리자 +위젯을 정확한 위치에 배치합니다. 좌표를 직접 지정하여 절대적인 위치를 설정합니다. + +* 장점: 매우 정확한 배치가 가능합니다. +* 단점: 창 크기가 변경될 때 위젯의 위치가 고정되어 불편할 수 있습니다. + +```python +import tkinter as tk + +root = tk.Tk() + +label1 = tk.Label(root, text="첫 번째 라벨") +label1.place(x=50, y=50) + +root.mainloop() +``` + +## 이벤트 처리 +Tkinter는 사용자의 입력이나 창의 크기 변경 등 다양한 이벤트를 감지하고, 이에 대한 적절한 동작을 수행할 수 있도록 이벤트 처리 기능을 제공합니다. 이를 통해 사용자와 상호 작용하는 동적인 GUI 프로그램을 만들 수 있습니다. + +### 이벤트 종류 +* 마우스 이벤트: 클릭, 더블 클릭, 드래그 등 +* 키보드 이벤트: 키 입력, 키 누르고 있기 등 +* 위젯 이벤트: 위젯의 크기 변경, 포커스 변경 등 + +### 이벤트 처리 방법 +#### command 옵션을 이용한 이벤트 처리 +가장 간단한 방법으로, 버튼 클릭과 같이 특정 이벤트에 대한 처리 함수를 직접 지정할 수 있습니다. +```python +import tkinter as tk + +def button_click(): + print("버튼이 클릭되었습니다.") + +window = tk.Tk() +button = tk.Button(window, text="클릭", command=button_click) +button.pack() +window.mainloop() +``` +위 코드에서 command 옵션에 button_click 함수를 지정하여 버튼이 클릭될 때 해당 함수가 실행되도록 합니다. + +#### bind 메서드를 이용한 이벤트 처리 +더욱 다양한 이벤트를 처리하고, 이벤트 발생 시에 추가적인 정보를 얻고 싶을 때 bind 메서드를 사용합니다. +```python +import tkinter as tk + +def on_click(event): + print("클릭한 위치:", event.x, event.y) + +window = tk.Tk() +label = tk.Label(window, text="여기에 클릭하세요") +label.bind("", on_click) +label.pack() +window.mainloop() +``` +위 코드에서 은 마우스 왼쪽 버튼 클릭 이벤트를 의미하며, on_click 함수가 호출될 때 이벤트 정보를 담은 event 객체가 전달됩니다. event.x와 event.y를 통해 클릭한 위치의 좌표를 얻을 수 있습니다. + +### 이벤트 객체 +이벤트 객체는 이벤트 발생 시에 전달되는 객체로, 이벤트에 대한 다양한 정보를 포함하고 있습니다. 예를 들어, 이벤트 발생 위치, 키 코드, 마우스 버튼 등을 확인할 수 있습니다. + +### 주요 이벤트 종류 +* ``: 마우스 왼쪽 버튼 클릭 +* ``: 마우스 가운데 버튼 클릭 +* ``: 마우스 오른쪽 버튼 클릭 +* ``: 키 입력 +* ``: 마우스 이동 +* ``: 위젯 크기 변경 + +### 이벤트 처리 시 주의할 점 +* 이벤트 순서: 여러 이벤트가 동시에 발생할 경우 처리 순서가 달라질 수 있습니다. +* 이벤트 전파: 이벤트는 부모 위젯으로 전파될 수 있습니다. +* 람다 함수: bind 메서드에 직접 함수를 전달할 때 람다 함수를 사용하면 유용합니다. + +## Tkinter의 장단점 +### 장점 +* 간단하고 배우기 쉽습니다. +* 파이썬 표준 라이브러리로 별도 설치가 필요 없습니다. +* 다양한 플랫폼에서 동작합니다. +### 단점 +* 복잡한 GUI를 만들기에는 부족한 기능이 있을 수 있습니다. +* 디자인 자유도가 낮을 수 있습니다. + diff --git a/doc/41_logging.md b/doc/41_logging.md index 52ea27f..1962637 100644 --- a/doc/41_logging.md +++ b/doc/41_logging.md @@ -1,2 +1,47 @@ -# 로깅 +# logging 모듈: 프로그램 실행 기록 관리 +logging 모듈은 파이썬 프로그램 실행 중 발생하는 다양한 이벤트를 기록하고 관리하는 데 사용되는 표준 라이브러리입니다. 디버깅, 모니터링, 문제 해결 등 프로그램 개발 및 운영에 있어 필수적인 역할을 합니다. + +* 디버깅: 프로그램의 특정 부분에서 문제가 발생할 때, 로그를 통해 문제 발생 지점과 원인을 파악할 수 있습니다. +* 모니터링: 프로그램의 실행 상태를 실시간으로 확인하여 성능 저하나 오류 발생 여부를 감지할 수 있습니다. +* 로그 분석: 수집된 로그 데이터를 분석하여 프로그램의 성능을 개선하고, 사용자 행태를 파악할 수 있습니다. + +```python +import logging + +# 로거 생성 +logger = logging.getLogger(__name__) +logger.setLevel(logging.DEBUG) + +# 콘솔 출력 설정 +stream_handler = logging.StreamHandler() +logger.addHandler(stream_handler) + +# 로그 메시지 출력 +logger.debug("디버그 메시지") +logger.info("정보 메시지") +logger.warning("경고 메시지") +logger.error("오류 메시지") +``` +## 주요 구성 요소 +* Logger: 로그를 생성하고 관리하는 객체입니다. +* Handler: 로그 메시지를 어디로 보낼지를 결정합니다. (예: 콘솔, 파일, 네트워크) +* Formatter: 로그 메시지의 형식을 지정합니다. +* Filter: 로그 메시지를 필터링하여 특정 조건에 맞는 메시지만 출력합니다. + +## 로그 레벨 +* DEBUG: 디버깅에 유용한 상세한 정보 +* INFO: 일반적인 정보 +* WARNING: 경고 메시지 +* ERROR: 오류 발생 시 출력되는 메시지 +* CRITICAL: 심각한 오류 발생 시 출력되는 메시지 + +## 포맷터 +```python +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +logger.setFormatter(formatter) +``` +## 로그 출력 설정 +* 콘솔 출력: StreamHandler를 사용하여 콘솔에 로그를 출력합니다. +* 파일 출력: FileHandler를 사용하여 로그를 파일에 저장합니다. +* 네트워크 전송: SocketHandler를 사용하여 네트워크를 통해 로그를 전송합니다. diff --git a/doc/42_unittest.md b/doc/42_unittest.md index aa47ab4..73e5934 100644 --- a/doc/42_unittest.md +++ b/doc/42_unittest.md @@ -1 +1,74 @@ -# 단위 테스트 +# unittest 모듈: 코드의 신뢰성을 높이는 단위 테스트 + +unittest 모듈은 파이썬에서 단위 테스트를 작성하고 실행하기 위한 표준 라이브러리입니다. 단위 테스트는 코드의 각 기능이 의도한 대로 작동하는지 검증하는 과정으로, 소프트웨어 개발 과정에서 매우 중요한 역할을 합니다. unittest는 이러한 단위 테스트를 체계적으로 관리하고 실행할 수 있도록 도와줍니다. + +* 테스트 케이스 작성: 테스트 케이스를 정의하고 실행합니다. +* 테스트 실행: 모든 테스트 케이스를 자동으로 실행하고 결과를 보고합니다. +* 테스트 결과 확인: 테스트 성공 여부를 확인하고, 실패한 테스트에 대한 상세한 정보를 제공합니다. +* 테스트 조직: 테스트 케이스를 클래스와 메서드로 구성하여 테스트 코드를 체계적으로 관리합니다. + +```python +import unittest + +def add(x, y): + return x + y + +class TestAdd(unittest.TestCase): + def test_add_positive(self): + self.assertEqual(add(2, 3), 5) + + def test_add_negative(self): + self.assertEqual(add(-1, 1), 0) + +if __name__ == '__main__': + unittest.main() +``` +위 예시에서, +* unittest.TestCase 클래스를 상속받아 TestAdd 클래스를 정의합니다. +* test_add_positive, test_add_negative와 같이 test_로 시작하는 메서드를 테스트 케이스로 정의합니다. +* self.assertEqual() 메서드를 사용하여 실제 결과와 예상 결과를 비교합니다. + +## unittest 모듈의 주요 개념 +* TestCase: 단일 테스트 케이스를 나타내는 클래스입니다. +* TestSuite: 여러 개의 테스트 케이스를 모아 실행할 수 있는 클래스입니다. +* TestLoader: 테스트 케이스를 자동으로 찾아 TestSuite에 추가하는 클래스입니다. +* TextTestRunner: 테스트 결과를 콘솔에 출력하는 러너입니다. + +## 테스트하는 방법 +unittest 모듈을 활용하여 모듈 전체를 테스트하는 방법은 여러 가지가 있습니다. 각 방법마다 장단점이 있으므로, 프로젝트의 규모와 복잡도에 따라 적절한 방법을 선택해야 합니다. + +### 테스트 디렉토리 구조 설정 +* 모듈별 테스트 파일: 각 모듈에 해당하는 테스트 파일을 생성하여 관리합니다. 이는 모듈과 테스트 코드 간의 관계를 명확하게 하고, 테스트 코드를 효율적으로 관리하는 데 도움이 됩니다. +* 테스트 디렉토리: 모든 테스트 파일을 별도의 테스트 디렉토리에 모아 관리합니다. 이는 프로젝트 구조를 명확하게 하고, 테스트 코드를 쉽게 찾을 수 있도록 합니다. + +### 테스트 실행 +* unittest.main(): 테스트 모듈의 최하단에 unittest.main() 함수를 호출하여 해당 모듈 내의 모든 테스트 케이스를 실행합니다. +* 명령줄: python -m unittest 명령을 사용하여 특정 모듈 또는 디렉토리 내의 모든 테스트를 실행할 수 있습니다. +* 테스트 러너: IDE(Integrated Development Environment)에서 제공하는 테스트 러너를 사용하여 테스트를 실행하고 결과를 시각적으로 확인할 수 있습니다. + +### 테스트 발견 (Test Discovery) +* unittest.defaultTestLoader: discover() 메서드를 사용하여 특정 디렉토리에서 테스트 케이스를 자동으로 찾아 TestSuite을 생성할 수 있습니다. + +```python +# my_module.py +def add(a, b): + return a + b + +# test_my_module.py +import unittest +from my_module import add + +class TestAdd(unittest.TestCase): + def test_add_positive(self): + self.assertEqual(add(2, 3), 5) + +if __name__ == '__main__': + unittest.main() +``` +위 예시에서 test_my_module.py 파일을 실행하면 my_module 모듈의 add 함수에 대한 테스트가 실행됩니다. + +## 추가적인 고려 사항 +* 테스트 커버리지: coverage와 같은 도구를 사용하여 테스트가 얼마나 많은 코드를 커버하는지 측정할 수 있습니다. +* 테스트 데이터: 다양한 입력값을 사용하여 테스트를 수행하여 코드의 견고성을 높여야 합니다. +* 테스트 더블: 모듈의 의존성을 모킹하여 테스트를 독립적으로 수행할 수 있습니다. +* 테스트 주도 개발(TDD): 테스트를 먼저 작성하고, 그에 맞춰 코드를 구현하는 방식으로 개발 생산성을 높일 수 있습니다. diff --git a/doc/49_collections.md b/doc/49_collections.md new file mode 100644 index 0000000..cf39a21 --- /dev/null +++ b/doc/49_collections.md @@ -0,0 +1,60 @@ +# collections 모듈: 다양한 컨테이너 자료형 + +collections 모듈은 파이썬의 기본 컨테이너 자료형인 리스트, 딕셔너리, 튜플 등을 확장하여 다양한 기능을 제공하는 모듈입니다. 특정한 목적에 맞는 자료형을 제공하여 코드의 가독성을 높이고, 개발 생산성을 향상시키는 데 도움을 줍니다. + +- Counter + + 해시 가능한 객체(숫자, 문자열 등)의 개수를 세는 데 특화된 딕셔너리 서브클래스입니다. + 단어 빈도수 계산, 투표 결과 집계 등에 유용하게 사용됩니다. + +- defaultdict + + 키가 존재하지 않을 때 기본값을 설정하여 반환하는 딕셔너리 서브클래스입니다. + 데이터 구조를 초기화할 때 편리하며, 특히 중첩된 데이터 구조를 만들 때 유용합니다. + +- OrderedDict + + 항목이 추가된 순서를 기억하는 딕셔너리 서브클래스입니다. + 딕셔너리의 순서를 유지해야 할 때 사용합니다. + +- deque + + 양쪽 끝에서 효율적으로 요소를 추가하거나 삭제할 수 있는 리스트와 유사한 자료형입니다. + 큐, 스택 등을 구현하는 데 사용됩니다. + +- namedtuple + + 이름이 있는 필드를 가진 튜플을 생성하는 팩토리 함수입니다. + 객체의 속성에 접근할 때 더 명확하고 안전하게 사용할 수 있습니다. + +```python +from collections import Counter, defaultdict, OrderedDict, deque, namedtuple + +# Counter +words = ['apple', 'banana', 'apple', 'orange'] +word_counts = Counter(words) +print(word_counts) # Counter({'apple': 2, 'banana': 1, 'orange': 1}) + +# defaultdict +default_dict = defaultdict(list) +default_dict['colors'].append('red') +default_dict['colors'].append('blue') +print(default_dict) # defaultdict(, {'colors': ['red', 'blue']}) + +# OrderedDict +ordered_dict = OrderedDict() +ordered_dict['a'] = 1 +ordered_dict['b'] = 2 +print(ordered_dict) # OrderedDict([('a', 1), ('b', 2)]) + +# deque +queue = deque(['a', 'b', 'c']) +queue.append('d') +queue.popleft() +print(queue) # deque(['b', 'c', 'd']) + +# namedtuple +Point = namedtuple('Point', ['x', 'y']) +pt = Point(10, 20) +print(pt.x, pt.y) # 10 20 +```