- 프로그램을 제대로 만들기 위해 알아야 하는 예외 처리와 파일 다루기에 대해서 배운다.
- 대부분의 경우 우리가 만드는 프로그램에는 우리가 예상치 못한 오류가 생기곤 한다.
- 이를 해결하기 위해서 사전에 모든 경우를 다 지정해서 대비하는 경우도 있지만, 특정 상황에서 발생할 수 있는 예외를 포괄적으로 지정해서 대비하는 경우도 있다.
- 또, 실제 프로그램을 작성할 때는 파일에 존재하는 데이터를 사용하는 경우가 많다.
- 추가적으로 여러가지 프로그램을 진행하면서 기록을 남기는 로깅에 대해서도 배운다.
- 로그 데이터를 남기는 건 오늘날 데이터 기반의 애플리케이션 개발에서 매우 중요한 이슈가 되고 있다.
- 로그 데이터를 설계하는 것이 하나의 분야로 자리잡고 있을 만큼 매우 관심을 받고 있다.
1) 예상 가능 한 예외
2) 예상이 불가능 한 예외
try:
예외 발생 가능 코드
except <Exception Type>: # 완전히 다른 exception type가 들어가 있으면 exception을 발견하지 못한다.
예외 발생시 대응하는 코드
for i in range(10):
try:
print(10 / i)
except ZeroDivisionError:
print("Not divided by 0")
Built-in Exception: 기본적으로 제공하는 예외
Exception 이름 | 내용 |
---|---|
IndexError | List의 Index 범위를 넘어갈 때 |
NameError | 존재하지 않은 변수를 호출 할 때 |
ZeroDivisionError | 0으로 숫자를 나눌 때 |
ValueError | 변환할 수 없는 문자/숫자를 변환할 떄 |
FileNotFoundError | 존재하지 않는 파일을 호출할 때 |
try ~ except ~ else
try:
예외 발생 가능 코드
except <Exception Type>:
예외 발생시 동작하는 코드
else:
예외가 발생하지 않을 때 동작하는 코드
try:
예외 발생 가능 코드
except <Exception Type>:
예외 발생시 동작하는 코드
finally:
예외 발생 여부와 상관없이 실행됨
raise <Exception Type>(예외정보)
while True:
value = input("변환할 정수 값을 입력해주세요")
for digit in value:
if digit not in "0123456789":
raise ValueError("숫자값을 입력하지 않으셨습니다")
print("정수값으로 변환된 숫자 -", int(value))
assert 예외조건
def get_binary_number(decimal_number):
assert isinstance(decimal_number, int) # True 혹은 False, False는 AssertionError를 발생. True는
return bin(decimal_number)
print(get_binary_number(10.0))
File System, 파일 시스템
file from wiki
파일의 종류
Binary 파일 | Text 파일 |
---|---|
컴퓨터만 이해할 수 있는 형태인 이진(법)형식으로 저장된 파일 | 인간도 이해할 수 있는 형태인 문자열 형식으로 저장된 파일 |
일반적으로 메모장으로 열면 내용이 깨져 보임(메모장 해설 부락) | 메모장으로 열면 내용 확인 가능 |
엑셀파일, 워드 파일 등등 | 메모장에 저장된 파일, HTML 파일, 파이썬 코드 파일 등 |
f = open('<파일이름>', '접근모드')
f.close()
파일 열기 모드 | 설명 |
---|---|
r | 읽기모드 - 파일을 읽기만 할 때 사용 |
w | 쓰기모드 - 파일에 내용을 쓸 때 사용 |
a | 추가모드 - 파일의 마지막에 새로운 내용을 추가 시킬 때 사용 |
f = open('i_have_a_dream.txt', 'r') # 대상파일이 같은 폴더에 있을 경우
contents = f.read()
print(contents)
f.close()
# with 구문과 함께 사용하기
with open('i_have_a_dream.txt', 'r') as my_file:
contents = my_file.read() # 파일 전체를 list로 반환
print(type(contents), contents) # Type 확인
print(contents) # 리스트 값 출력
# 실행 시 마다 한 줄 씩 읽어 오기
# 파일 용량이 커서 한번에 메모리에 올릴 수 없을 경우 한 줄씩 읽어오는 방법을 사용해야한다.
with open("i_have_a_dream.txt", "r") as my_file:
i = 0
while True:
line = my_file.readline()
if not line:
break
print (str(i) + " === " + line.replace("\n","")) #한줄씩 값 출력
i = i + 1
# mode는 'w', encoding = 'utf8'
f = open("count_log.txt",'w' , encoding="utf8") # 한글 = utf8
for i in range(1, 11):
data = "%d번째 줄입니다.\n" % i
f.write(data)
f.close()
# mode는 'a'는 추가 모드
# a = append, 기존 파일에 덮어쓰기
with open("count_log.txt",'a', encoding="utf8") as f:
for i in range(1, 11):
data = "%d번째 줄입니다.\n" % i
f.write(data)
# os 모듈을 사용하여 Directory 다루기
import os
os.mkdir('log')
# 디렉토리가 있는지 확인하기
if not os.path.isdir('log'):
os.mkdir('log')
# 디렉토리가 있는지 확인하기 2
try :
os.mkdir('abc')
except FileExistsError as e:
print('already created')
# 디렉토리가 있는지 확인하기 3
os.path.exists('abc') # True/False
# 파일을 옮길때 사용하는 모듈 shutil
import shutil
source = 'i_have_a_dream.txt'
dest = os.path.join('abc', 'andrew.txt') # join = abc\\andrew.txt
shutil.copy(source, dest) # shutil.copy = 파일 복사 함수
import pathlib
cwd = pathlib.Path.cwd()
cwd # WindowsPath('D:/workspace')
cwd.parent # WindowsPath('D:/')
import os
if not os.path.isdir("log"):
os.mkdir("log")
if not os.path.exists("log/count_log.txt"):
f = open("log/count_log.txt", 'w', encoding="utf8")
f.write("기록이 시작됩니다\n")
f.close()
with open("log/count_log.txt", 'a', encoding="utf8") as f:
import random, datetime
for i in range(1, 11):
stamp = str(datetime.datetime.now())
value = random.random() * 1000000
log_line = stamp + "\t" + str(value) +"값이 생성되었습니다" + "\n"
f.write(log_line)
# pickle모듈로 객체를 저장
import pickle
f = open("list.pickle", "wb") # writebinary
test = [1, 2, 3, 4, 5] # 리스트 객체
pickle.dump(test, f) # dump = 리스트 객체를 f변수에 할당되어 있는 정보에 저장
f.close()
# 객체 불러오기
f = open("list.pickle", "rb") # readbinary
test_pickle = pickle.load(f)
print(test_pickle) # [1, 2, 3, 4, 5]
f.close()
- 게임을 만들었는데 Hack쓰는 유저들 때문에 망할 수 있다
- 어떻게 잡을 수 있을까?
- 일단 상황을 기록하는것 부터 해야한다 (로그 남기기)
로그 남기기 - Logging
print vs logging
logging 모듈
import logging
logging.debug("틀렸잖아!")
logging.info("확인해")
logging.warning("조심해!")
logging.error("에러났어!!!")
logging.critical("망했다...")
import logging
logger = logging.getLogger("main") # Logger 선언
stream_hander = logging.StreamHandler() # Logger의 output 방법 선언
logger.addHandler(stream_hander) # Logger의 output 등록
import configparser
config = configparser.ConfigParser()
config.sections()
config.read('example.cfg')
config.sections()
for key in config['SectionOne']:
print(key)
config['SectionOne']["status"]
- 파이썬에서 다룰 수 있는 CSV, 웹, XML, JSON 네 가지 데이터 타입에 대해서 배운다
- CSV 파일 포맷은 어떠한 프로그래밍 언어든 데이터를 다루는 분야에서 가장 기본이 되는 타입형태이다
- 우리가 계속 써온 데이터 저장형태인 엑셀의 텍스트 데이터 형태로 이해하면 된다
- 매우 중요한 데이터 타입으로 파이썬으로 핸들링하는 것에 익숙해지는 것이 필요하다
- 다음으로 웹이다. 우리가 모두 알고 있듯이 이미 웹은 우리가 세상에서 가장 많은 정보를 제공하고 가장 많은 시간을 사용하고 있는 공간이다
- 이 정보를 어떻게 자동으로 확보할 것인지에 대해서 배운다
- 먼저 기본적인 웹을 표현하는 가장 기본적인 언어인 HTML에 대해서 배운다
- HTML은 웹에서 나타나는 정보의 표현 방법 중 가장 대표적인 방법 으로 거의 모든 정보를 HTML 분석으로 얻을 수가 있다
- 다음으로 그 HTML을 분석하기 위해 대표적인 방법인 정규표현식(regex) 에 대해서 배우게 된다
- 정규표현식은 텍스트 데이터 분석에 있어 가장 대표적인 분석 방법으로, HTML외에도 다양한 유형의 텍스트에서 특정 정보를 뽑아내는데 사용 한다
- 마지막으로 데이터를 저장하는 다양한 포멧중 하나인 XML(eXtensible Markup Languages) 과 JSON(JavaScript Object Notation) 에 대해서 다룬다
- XML 프로그래밍 언어에서 데이터를 저장하고 불러오는 전통적인 파일포맷은 흔히 레거시 시스템 (오래전에 구축된 시스템) 에서 raw파일을 저장하는 대표적인 포맷 이다.
- JSON은 이와 달리 모바일이 활발히 사용되면서 사용되기 시작하는 저장 포맷으로 웹에서 많이 사용되는 JavaScript의 문법을 활용하여 저장하는 포맷 이다
line_counter = 0 #파일의 총 줄수를 세는 변수
data_header = [] #data의 필드값을 저장하는 list
customer_list = [] #cutomer 개별 List를 저장하는 List
with open ("customers.csv") as customer_data: #customer.csv 파일을 customer_data 객체에 저장
while True:
data = customer_data.readline() #customer.csv에 한줄씩 data 변수에 저장
if not data: break #데이터가 없을 때, Loop 종료
if line_counter==0: #첫번째 데이터는 데이터의 필드
data_header = data.split(",") #데이터의 필드는 data_header List에 저장, 데이터 저장시 “,”로 분리
else:
customer_list.append(data.split(",")) #일반 데이터는 customer_list 객체에 저장, 데이터 저장시 “,”로 분리
line_counter += 1
print("Header :\t", data_header) #데이터 필드 값 출력
for i in range(0,10): #데이터 출력 (샘플 10개만)
print ("Data",i,":\t\t",customer_list[i])
print (len(customer_list)) #전체 데이터 크기 출력
csv 객체로 csv처리
csv 객체 활용
reader = csv.reader(f, delimiter = ',', quatechar = '"', quoting = csv.QUOTE_ALL)
Attribute | Default | Meaning |
---|---|---|
delimiter | , | 글자를 나누는 기준 |
lineterminator | ₩r₩n | 줄 바꿈 기준 |
quotechar | " | 문자열을 둘러싸는 신호 문자 |
quoting | QUOTE_MINIMAL | 데이터 나누는 기준이 quotechar에 의해 둘러싸인 레빌 |
import csv
seoung_nam_data = []
header = []
rownum = 0
with open("korea_floating_population_data.csv","r", encoding="cp949") as p_file: # 맥은 encoding = 'utf8'
csv_data = csv.reader(p_file) #csv 객체를 이용해서 csv_data 읽기
for row in csv_data: #읽어온 데이터를 한 줄씩 처리
if rownum == 0:
header = row #첫 번째 줄은 데이터 필드로 따로 저장
location = row[7]
#“행정구역”필드 데이터 추출, 한글 처리로 유니코드 데이터를 cp949로 변환
if location.find(u"성남시") != -1:
seoung_nam_data.append(row)
#”행정구역” 데이터에 성남시가 들어가 있으면 seoung_nam_data List에 추가
rownum +=1
with open("seoung_nam_floating_population_data.csv","w", encoding="utf8") as s_p_file:
writer = csv.writer(s_p_file, delimiter='\t', quotechar="'", quoting=csv.QUOTE_ALL)
# csv.writer를 사용해서 csv 파일 만들기 delimiter 필드 구분자
# quotechar는 필드 각 데이터는 묶는 문자, quoting는 묶는 범위
writer.writerow(header) #제목 필드 파일에 쓰기
for row in seoung_nam_data:
writer.writerow(row) #seoung_nam_data에 있는 정보 list에 쓰기
우리가 늘 쓰는 그 것
Web은 어떻게 동작하는가?
1) 서버에 요청
2) 서버에서 처리
3) 처리된 결과를 HTML파일에 사용자에게 보내준다.
4) 사용자는 HTML을 다운로드 받고 사용되는 browser가 렌더링해서 사용자에게 보여준다
정규식 연습장 활용하기
1) 정규식 연습장 연습장 으로 이동
2) 테스트하고 싶은 문서를 Text란에 삽입
3) 정규식을 사용해서 찾아보기. 이 페이지를 보세요 페이지
정규식 기본 문법 # 1
정규식 기본 문법 - 메타 문자
정규식 in 파이썬
데이터의 구조와 의미를 설명하는 TAG(MarkUp)를 사용하여 표시하는 언어
TAG 와 TAG사이에 값이 표시되고, 구조적인 정보를 표현할 수 있음
HTML과 문법이 비슷, 대표적인 데이터 저장 방식
정보의 구조에 대한 정보인 스키마와 DTD 등으로 정보에 대한 정보(메타정보)가 표현되며, 용도에 따라 다양한 형태로 변경가능
XML은 컴퓨터(예: PC <-> 스마트폰) 간에 정보를 주고받기 매우 유용한 저장 방식으로 쓰이고 있음
XML 예제
json 모듈을 사용하여 손 쉽게 파싱 및 저장 가능
데이터 저장 및 읽기는 dict type 과 상호 호환 가능
웹에서 제공하는 API는 대부분 정보 교환 시 JSON 활용
페이스북, 트위터, Github 등 거의 모든 사이트
각 사이트 마다 Developer API의 활용법을 찾아 사용
JSON Read