[부스트캠프 AI Tech 5기] Pre-Course : (4) File / Exception / Log Handling

araseo·2022년 12월 11일
0
post-thumbnail

📖 예상 가능한 예외

  • 발생 여부를 사전에 인지할 수 있는 예외
  • 사용자의 잘못된 입력, 파일 호출 시 파일 없음
  • 개발자가 반드시 명시적으로 정의해야함

📖 예상 가능한 예외

  • 발생 여부를 사전에 인지할 수 있는 예외
  • 사용자의 잘못된 입력, 파일 호출 시 파일 없음
  • 개발자가 반드시 명시적으로 정의 해야함
  • 인터프리터 과정에서 발생하는 예외, 개발자의 실수
  • 리스트의 범위를 넘어가는 값 호출, 정수 0으로 나눔
  • 수행 불가시 인터프리터가 자동 호출
  • 예외가 발생할 경우 후속 조치 등 대처 필요
    1) 없는 파일 호출 → 파일 없음을 알림
    2) 게임 이상 종료 → 게임 정보 저장
  • 프로그램 = 제품, 모든 잘못된 상황에 대처가 필요

📖 파이썬의 예외 처리

  • try ~ except 문법
try:
	예외 발생 가능 코드
except <Exception Type>:
	예외 발생시 대응하는 코드
  • 0으로 숫자를 나눌 때 예외처리 하기
for i in range(10):
  try:
      print(10 / i)
  except ZeroDivisionError:
      print("Not divided by 0")
  • 예외 정보 표시하기
for i in range(10):
	try :
    	print(10 / i)
    except ZeroDivisionError as e:
    	print(e)
        print("Not divided by 0")
  • try ~ except ~ else 문법
try:
	예외 발생 가능 코드
except <Exception Type>:
	예외 발생 시 동작하는 코드
else:
	예외가 발생하지 않을 때 동작하는 코드
  • try ~ except ~ else 문법 예시
for i in range(10):
	try:
		result = 10 / i
    except ZeroDivisionError:
		print("Not divided by 0")
    else:
		print(10 / i)
  • try ~ except ~ finally 구문
try:
	예외 발생 가능 코드
except <Exception Type>:
	예외 발생 시 동작하는 코드
finally:
	예외 발생 여부와 상관없이 실행됨
  • try ~ except ~ finally 구문 예시
try:
for i in range(1, 10):
        result = 10 // i
        print(result)
except ZeroDivisionError:
	print("Not divided by 0")
finally:
	print("종료되었습니다.")
  • raise 구문
    • 필요에 따라 강제로 Exception을 발생
raise <Exception Type>(예외정보)
  • raise 구문 예시
while True:
	value = input("변환할 정수 값을 입력해주세요")
    for digit in value:
		if digit not in "0123456789":
			raise ValueError("숫자값을 입력하지 않으셨습니다")
	print("정수값으로 변환된 숫자 -", int(value))
  • assert 구문
    • 특정 조건에 만족하지 않을 경우 예외 발생
assert 예외조건
  • assert 구문 예시
def get_binary_numbmer(decimal_number):
    assert isinstance(decimal_number, int)
    return bin(decimal_number)
print(get_binary_numbmer(10))

📖 exception의 종류

  • Built-in Exception : 기본적으로 제공하는 예외
Exception 이름내용
IndexErrorList의 Index 범위를 넘어갈 때
NameError존재하지 않은 변수를 호출할 때
ZeroDivisionError0으로 숫자를 나눌 때
ValueError변환할 수 없는 문자/숫자를 변환할 때
FileNotFoundError존재하지 않는 파일을 호출할 때

📖 File Handling Overview

  • File system, 파일 시스템
    - OS에서 파일을 저장하는 트리구조 저장 체계
  • File from wiki
    - 컴퓨터 등의 기기에서 의미 있는 정보를 담는 논리적인 단위
    - 모든 프로그램은 파일로 구성되어 있고, 파일을 사용한다.

📖 파일과 디렉토리

  • 디렉토리(Directory)
    - 폴더 또는 디렉토리로 불림
    - 파일과 다른 디렉토리를 포함할 수 있음
  • 파일(File)
    - 컴퓨터에서 정보를 저장하는 논리적인 단위(wikipedia)
    - 파일은 파일명과 확장자로 식별됨(예 : hello.py)
    - 실행, 쓰기, 읽기 등을 할 수 있음

📖 파일의 종류

  • 기본적인 파일 종류로 text 파일과 binary 파일로 나눔
  • 컴퓨터는 text 파일을 처리하기 위해 binary 파일로 변환시킴(예: pyc 파일)
  • 모든 text 파일도 실제는 binary 파일, ASCII / Unicode 문자열 집합으로 저장되어 사람이 읽을 수 있음
Binary 파일Text 파일
- 컴퓨터만 이해할 수 있는 형태인 이진(법) 형식으로 저장된 파일- 인간도 이해할 수 있는 형태인 문자열 형식으로 저장된 파일
- 일반적으로 메모장으로 열면 내용이 깨져 보임(메모장 해설 불가)- 메모장으로 열면 내용 확인 가능
- 엑셀 파일, 워드 파일 등등- 메모장에 저장된 파일, HTML 파일, 파이썬 코드 파일 등

📖 Python File I/O

  • 파이썬은 파일 처리를 위해 "open" 키워드를 사용함
f = open("<파일이름>", "접근 모드")
f.close()
파일 열기 모드설명
r읽기 모드 - 파일을 읽기만 할 때 사용
w쓰기 모드 - 파일에 내용을 쓸 때 사용
a추가 모드 - 파일의 마지막에 새로운 내용을 추가 시킬 때 사용

📖 파이썬의 File Read

  • read() : txt 파일 안에 있는 내용을 문자열로 반환
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()
	print (type(contents), contents)

📖 파이썬의 File Read

  • 한 줄씩 읽어 List Type으로 반환함
with open("i_have_a_dream.txt", "r") as my_file:
	content_list = my_file.readlines() #파일 전체를 list로 반환		
    print(type(content_list)) #Type 확인
    print(content_list) #리스트 값 출력
  • 실행 시마다 한 줄씩 읽어오기
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
  • 단어 통계 정보 산출
with open("i_have_a_dream.txt", "r") as my_file:
	contents = my_file.read()
    word_list = contents.split(" ")
    #빈칸 기준으로 단어를 분리 리스트
    line_list = contents.split("\n")
    #한줄 씩 분리하여 리스트
    
print("Total Number of Characters :", len(contents))
print("Total Number of Words:", len(word_list))
print("Total Number of Lines :", len(line_list))

📖 파이썬의 File Write

  • mode는 “w”, encoding=“utf8”
f = open("count_log.txt", 'w', encoding="utf8")
for i in range(1, 11):
	data = "%d번째 줄입니다.\n" % i
    f.write(data)
f.close()
  • mode “a”는 추가 모드
with open("count_log.txt", 'a', encoding="utf8") as f:
	for i in range(1, 11):
		data = "%d번째 줄입니다.\n" % i
        f.write(data)

📖 파이썬의 directory 다루기

  • os 모듈을 사용하여 Directory 다루기
import os
os.mkdir("log")
  • 디렉토리가 있는지 확인하기
if not os.path.isdir("log"):
	os.mkdir("log")
  • 최근에는 pathlib 모듈을 사용하여 path를 객체로 다룸

📖 Log 파일 생성하기
1) 디렉토리가 있는지, 2) 파일이 있는 지 확인 후

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

  • 파이썬의 객체를 영속화(persistence)하는 built-in 객체
  • 데이터, object등 실행중 정보를 저장 → 불러와서 사용
  • 저장해야하는 정보, 계산 결과(모델) 등 활용이 많음
# example 1.
import pickle
f = open("list.pickle", "wb")
test = [1, 2, 3, 4, 5]
pickle.dump(test, f)
f.close()

f = open("list.pickle", "rb")
test_pickle = pickle.load(f)
print(test_pickle)
f.close()

# example 2.
import pickle

class Mutltiply(object):
	def __init__(self, multiplier):
		self.multiplier = multiplier
    def multiply(self, number):
		return number * self.multiplier

muliply = Mutltiply(5)
muliply.multiply(10)

f = open("multiply_object.pickle", "wb")
pickle.dump(muliply, f)
f.close()

f = open("multiply_object.pickle", "rb")
multiply_pickle = pickle.load(f)
multiply_pickle.multiply(5)

📖 로그 남기기 - Logging

  • 프로그램이 실행되는 동안 일어나는 정보를 기록으로 남기기
  • 유저의 접근, 프로그램의 Exception, 특정 함수의 사용
  • Console 화면에 출력, 파일에 남기기, DB에 남기기 등등
  • 기록된 로그를 분석하여 의미있는 결과를 도출할 수 있음
  • 실행시점에서 남겨야 하는 기록, 개발시점에서 남겨야하는 기록

📖 print vs logging

  • 기록을 print로 남기는 것도 가능함
  • 그러나 Console 창에만 남기는 기록은 분석시 사용 불가
  • 때로는 레벨별(개발, 운영)로 기록을 남길 필요도 있음
  • 모듈별로 별도의 logging을 남길 필요도 있음
  • 이러한 기능을 체계적으로 지원하는 모듈이 필요함

📖 logging 모듈

  • Python의 기본 Log 관리 모듈
import logging
logging.debug("틀렸잖아!")
logging.info("확인해")
logging.warning("조심해!")
logging.error("에러났어!!!")
logging.critical ("망했다...")

📖 logging level

  • 프로그램 진행 상황에 따라 다른 Level의 Log를 출력함
  • 개발시점,운영시점 마다 다른 Log가 남을 수 있도록 지원함
  • DEBUG > INFO > WARNING > ERROR > Critical
  • Log 관리 시 가장 기본이 되는 설정 정보

import logging

# Logger 선언
logger = logging.getLogger("main")
# Logger의 output 방법 선언
stream_hander = logging.StreamHandler()
# Logger의 output 등록
logger.addHandler(stream_hander)

logger.setLevel(logging.DEBUG)
logger.debug("틀렸잖아!")
logger.info("확인해")
logger.warning("조심해!")
logger.error("에러났어!!!")
logger.critical("망했다...")

logger.setLevel(logging.CRITICAL)
logger.debug("틀렸잖아!")
logger.info("확인해")
logger.warning("조심해!")
logger.error("에러났어!!!")
logger.critical("망했다...")

📖 configparser

  • 프로그램의 실행 설정을 file에 저장함
  • Section, Key, Value 값의 형태로 설정된 설정 파일을 사용
  • 설정 파일을 Dict Type으로 호출 후 사용

📖 config file

Status: Single
Name: Derek
Value: Yes
Age: 30
Single: True

[SectionTwo]
FavoriteColor = Green

[SectionThree]
FamilyName: Johnson

📖 configparser file

import configparser
config = configparser.ConfigParser()
config.sections()

config.read('example.cfg')
config.sections()

for key in config['SectionOne']:
	print(key)
    
config['SectionOne']["status"]

📖 argparser

  • Console 창에서 프로그램 실행시 Setting 정보를 저장함
  • 거의 모든 Console 기반 Python 프로그램 기본으로 제공
  • 특수 모듈도 많이 존재하지만(TF), 일반적으로 argparse를 사용
  • Command-Line Option 이라고 부름
import argparse
parser = argparse.ArgumentParser(description='Sum two integers.') 

# 짧은 이름, 긴 이름, 표시명, Help 설명, Argument Type 순
parser.add_argument('-a', "--a_value", dest=”A_value", help="A integers", type=int)
parser.add_argument('-b', "--b_value", dest=”B_value", help="B integers", type=int)

args = parser.parse_args()
print(args)
print(args.a)
print(args.b)
print(args.a + args.b)

# example
# 출처 : https://ddiri01.tistory.com/302
def main():
    parser = argparse.ArgumentParser(description='PyTorch MNIST Example')
    parser.add_argument('--batch-size', type=int, default=64, metavar='N', help='input batch size for training (default: 64)')
    parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N', help='input batch size for testing (default: 1000)')
	parser.add_argument('--epochs', type=int, default=10, metavar='N', help='number of epochs to train (default: 10)')
	parser.add_argument('--lr', type=float, default=0.01, metavar='LR', help='learning rate (default: 0.01)')
    parser.add_argument('--momentum', type=float, default=0.5, metavar='M', help='SGD momentum (default: 0.5)') 		parser.add_argument('--no-cuda', action='store_true', default=False, help='disables CUDA training') parser.add_argument('--seed', type=int, default=1, metavar='S', help='random seed (default: 1)’) parser.add_argument('--save-model', action='store_true', default=False, help='For Saving the current Model')
    args = parser.parse_args()
    
if __name__ == '__main__':
    main()

📖 Logging formmater

  • Log의 결과값의 format을 지정해줄 수 있음
formatter = logging.Formatter('%(asctime)s %(levelname)s %(process)d %(message)s')
 2018-01-18 22:47:04,385 ERROR 4410 ERROR occurred
 2018-01-18 22:47:22,458 ERROR 4439 ERROR occurred
 2018-01-18 22:47:22,458 INFO 4439 HERE WE ARE
 2018-01-18 22:47:24,680 ERROR 4443 ERROR occurred
 2018-01-18 22:47:24,681 INFO 4443 HERE WE ARE
 2018-01-18 22:47:24,970 ERROR 4445 ERROR occurred
 2018-01-18 22:47:24,970 INFO 4445 HERE WE ARE
logging.config.fileConfig('logging.conf')
logger = logging.getLogger()
  [loggers]
  keys=rooy

  [handlers]
  keys=consoleHandler

  [formatters]
  keys=simpleFormatter

  [logger_root]
  level=DEBUG
  handlers=consoleHandler

  [handler_consoleHandler]
  class=StreamHandler
  level=DEBUG
  formatter=simpleFormatter
  args=(sys.stdout,)

📖 Logging examples

logger.info('Open file {0}'.format("customers.csv",))
try:
	with open("customers.csv", "r") as customer_data:
    	customer_reader = csv.reader(customer_data, delimiter=',', quotechar='"')
        for customer in customer_reader:
        	if customer[10].upper() == "USA": #customer 데이터의 offset 10번째 값
            	logger.info('ID {0} added'.format(customer[0],))
                customer_USA_only_list.append(customer) #즉 country 필드가 “USA” 것만
except FileNotFoundError as e:
	logger.error('File NOT found {0}'.format(e,))

<이 게시물은 최성철 교수님의 Exception/File/Log Handling 강의 자료를 참고하여 작성되었습니다.>

본 포스트의 학습 내용은 [부스트캠프 AI Tech 5기] Pre-Course 강의 내용을 바탕으로 작성되었습니다.
부스트캠프 AI Tech 5기 Pre-Course는 일정 기간 동안에만 운영되는 강의이며,
AI 관련 강의를 학습하고자 하시는 분들은 부스트코스 AI 강좌에서 기간 제한 없이 학습하실 수 있습니다.
(https://www.boostcourse.org/)

profile
AI를 공부하고 있는 학생입니다:)

0개의 댓글