상세 컨텐츠

본문 제목

[Python 파이썬 독학 8일차]

파이썬 스터디/파이썬-Python 기본편

by 후즈테크 2020. 10. 4. 21:01

본문

반응형

 

1. 예외처리 (except)

 : Error 가 발생하는 경우 처리 하는 방법

 : 배송지 오류(주소는 11층이나, 건물이 10층 건물), 교통 카드 잔액 부족, 계산기 내 문자 입력 등 상황에 따라 미리 예견 되는 Error 가 있고, 홈페이지 서버이상 및 실수 혹은 설계 단계에서 알 수 없는 Error 가 발생할 수 있으며, 해당 경우 처리 방법에 대한 방법

 

 1-1 나누기 전용 계산기

print ("나누기 전용 계산기 입니다.")
num1  = int(input("첫번째 숫자를 입력하세요 : "))
num2  = int(input("두번째 숫자를 입력하세요 : "))
print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))

  - 나누기 전용 계산기, 2개의 변수를 input으로 받고, 받은 변수는 str 형태이므로 int(정수형)으로 변경한다.

  - 일반적인 경우( 6 / 3 ) 에는 정상동작하나, 문자가 들어오거나 기타 다른 변수가 들어올 경우(  6 / 삼 ) 에는 오류가 발생한다.

  - ValueError 이라는 입력 값에 대한 오류라는 구분이 나타남.

반응형

 

 

 

 1-2 나누기 전용 계산기(예외 처리 1)

try:
    print ("나누기 전용 계산기 입니다.")
    num1  = int(input("첫번째 숫자를 입력하세요 : "))
    num2  = int(input("두번째 숫자를 입력하세요 : "))
    print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
except ValueError:
    print("에러! 잘못된 값을 입력하였습니다.")

  - 적용하는 방법은 1-1 에서 실행한 코드를 try 문 안에 넣은 후, 위에서 확인된 바와 같이 ValueError 에 대해 예외 처리를 정의하면, 설정된 출력 값을 출력할 수 있다.

  - 위의 코드를 실행하다 ValueError 가 발생할 경우, except ValueError 실행되며 예외처리를 실행한다.

 - except를 추가하여 경우에 따른 예외처리를 할 수 있으며, 특정 값 출력이 아닌 Error 내용에 대한 출력 값 자체를 표기 할 수도 있다.

 

 - 0 으로 나눌 경우, ZeroDivisionError 가 발생하는데, except 처리 후, as err 로 결과 값을 출력해주면 해당 내용을 확인 할 수 있다.

try:
    print ("나누기 전용 계산기 입니다.")
    num1  = int(input("첫번째 숫자를 입력하세요 : "))
    num2  = int(input("두번째 숫자를 입력하세요 : "))
    print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
except ValueError:
    print("에러! 잘못된 값을 입력하였습니다.")
except   ZeroDivisionError as err:
    print(err)  # ZeroDivisionError 값 출력

  - 1번째 실행 : ZeroDivisionError 예외처리 안하고 실행. 2번째 실행 :  ZeroDivisionError 예외처리 및 Err 출력

 

 1-3 나누기 전용 계산기(예외 처리 1 + 리스트 형태로 변형)

try:
    nums = []
    print ("나누기 전용 계산기 입니다.")
    nums.append(int(input("첫번째 숫자를 입력하세요 : ")))
    nums.append(int(input("두번째 숫자를 입력하세요 : ")))
    nums.append(int(nums[0] / nums[1]))
    print("{0} / {1} = {2}".format(nums[0], nums[1], nums[2]))
except ValueError:
    print("에러! 잘못된 값을 입력하였습니다.")
except   ZeroDivisionError as err:
    print(err)

  - 리스트 형태로 변형하여 입력되는 2개의 변수 및 연산값(나누기)을 저장할 수 있고, 결과 값 출력 또한 정상적으로 처리되는 것을 확인할 수 있다.

 

  - 기존에는 발생되는 Error 에 대한 예외 처리를 진행하였으나, 사용간 발생하는 전체 Error 에 대한 예외처리는 제한되므로, Error 간 구별 없이 except 를 적용하여 처리 할 수 있다.

try:
    nums = []
    print ("나누기 전용 계산기 입니다.")
    nums.append(int(input("첫번째 숫자를 입력하세요 : ")))
    nums.append(int(input("두번째 숫자를 입력하세요 : ")))
    #nums.append(int(nums[0] / nums[1]))    # 임의로 Error 발생
    print("{0} / {1} = {2}".format(nums[0], nums[1], nums[2]))
except ValueError:
    print("에러! 잘못된 값을 입력하였습니다.")
except   ZeroDivisionError as err:
    print(err)
except:
    print("알 수 없는 에러가 발생하였습니다.")

  - 테스트를 위해 "nums.append(int(nums[0] / nums[1]))" 을 주석처리하여 임의로 Error 요소 발생시켜보면 정의되지 않은 모든 경우에 대한 Error 는 except: 문으로 모두 처리할 수 있다.

  - 추가로 1-2에서 진행한 형태와 동일하게 as err 을 이용하여 Error 내용을 표기 할 수 도 있다.

try:
    nums = []
    print ("나누기 전용 계산기 입니다.")
    nums.append(int(input("첫번째 숫자를 입력하세요 : ")))
    nums.append(int(input("두번째 숫자를 입력하세요 : ")))
    #nums.append(int(nums[0] / nums[1])) # 임의로 오류 발생
    print("{0} / {1} = {2}".format(nums[0], nums[1], nums[2]))
except ValueError:
    print("에러! 잘못된 값을 입력하였습니다.")
except   ZeroDivisionError as err:
    print(err)
except Exception as err: # as err로 해당값 print(err)을 통해 출력
    print("알 수 없는 에러가 발생하였습니다.")
    print(err)

  - 처음 실행된 "알 수 없는 에러가 발생하였습니다." 외 추가로 "list index out of range" 라는 error 내용을 확인 할 수 있다.

 

1-4. 1 자릿수 전용 계산기

try:
    print("한 자리 숫자 나누기 전용 계산기입니다.")
    num1 = int(input("첫번째 숫자를 입력하세요 : "))
    num2 = int(input("두번째 숫자를 입력하세요 : "))
    if num1 >= 10 or num2 >= 10:
        raise ValueError
    print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))
except ValueError:
    print("잘못된 값을 입력하였습니다. 한자리 숫자만 입력하세요.")

  - try 문 안에 if 를 이용하여 조건을 줄 수 있고, 해당 조건에서 raise를 통해 ValueError 로 예외처리 할 수 있다.

 

1-5. 자릿수 전용 계산기(사용자 정의 예외 처리 class 추가)

class BigNumberError(Exception):
    pass

try:
    print("한 자리 숫자 나누기 전용 계산기입니다.")
    num1 = int(input("첫번째 숫자를 입력하세요 : "))
    num2 = int(input("두번째 숫자를 입력하세요 : "))
    if num1 >= 10 or num2 >= 10:
        raise BigNumberError   # BigNumberError 로 변경
    print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))
except ValueError:
    print("잘못된 값을 입력하였습니다. 한자리 숫자만 입력하세요.")
except BigNumberError:
    print("에러가 발생하였습니다. 한자리 숫자만 입력하세요.")

   - Exception class를 상속하는 BigNumberError class 를 생성한다.

      * 특정 기능이 없으므로, 작성하지 않고 동작을 확인 할 수 있다.

   - if 문을 통해 입력받은 2개의 변수 중, 하나 이상이 2자릿수 일 경우,  raise BigNumberError 을 통해 예외 처리된다.

   - 예외 처리된 사항은 출력되는 결과 값을 통해 확인 할 수있다.

1-6. 자릿수 전용 계산기(사용자 정의 예외 처리 message 추가)

class BigNumberError(Exception):
    def __init__(self, msg):
        self.msg = msg
    
    def __str__(self):
        return self.msg

try:
    print("한 자리 숫자 나누기 전용 계산기입니다.")
    num1 = int(input("첫번째 숫자를 입력하세요 : "))
    num2 = int(input("두번째 숫자를 입력하세요 : "))
    if num1 >= 10 or num2 >= 10:
        raise BigNumberError("입력 값 : {0}, {1}" .format(num1, num2))   # BigNumberError 가 발생했을 때, msg-"입력 값 : {0}, {1}" .format(num1, num2) 를 전달하고 반환
    print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))
except ValueError:
    print("잘못된 값을 입력하였습니다. 한자리 숫자만 입력하세요.")
except BigNumberError as err:  # err 반환
    print("에러가 발생하였습니다. 한자리 숫자만 입력하세요.")
    print(err)

 1) BigNumberError(Exception) class 생성 

 2) if 문에 해당 하는(10보다 큰 변수 입력 되는) 경우, raise BigNumberError 을 실행

 3) BigNumberError 실행 시, msg 로 class 내 입력하고, 

 4) print(err) 출력 시, 입력된 msg 값을 return 하여 출력하여 준다.

  * return 시 __str__ 을 사용하는데, 해당 함수는 객체를 문자열로 표현한 것을 반환하는 함수이다.

  * __init__ 함수에 return 값을 적용해 보았으나, TypeError:__init__() should return None, not 'str' 라는 메세지가 발생하며, 문자열 값을 반환할 수 없다고 나타났다.

 

 

2. finally

  : try 문 사용 시, 정상, 비정상 구분 없이 모두 출력하는 기능.

  : 없는 파일 처리, 접근 등의 경우 등 예상치 못한 오류로 인해 강제 종료되는 것을 막을 수 있어 완성도가 높아짐

class BigNumberError(Exception):
    def __init__(self, msg):
        self.msg = msg
    
    def __str__(self):
        return self.msg

try:
    print("한 자리 숫자 나누기 전용 계산기입니다.")
    num1 = int(input("첫번째 숫자를 입력하세요 : "))
    num2 = int(input("두번째 숫자를 입력하세요 : "))
    if num1 >= 10 or num2 >= 10:
        raise BigNumberError("입력 값 : {0}, {1}" .format(num1, num2))   # BigNumberError 가 발생했을 때, msg-"입력 값 : {0}, {1}" .format(num1, num2) 를 전달하고 반환
    print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))
except ValueError:
    print("잘못된 값을 입력하였습니다. 한자리 숫자만 입력하세요.")
except BigNumberError as err:  # err 반환
    print("에러가 발생하였습니다. 한자리 숫자만 입력하세요.")
    print(err)
finally:
    print("계산기를 이용해 주셔서 감사합니다.")

 - 정상, 예외처리 모두 finally 값을 출력 하는 것을 확인 할 수 있다.

 

--------------------------------------------------------------------------------------------------

Quiz 9. 

동네에 항상 대기 손님이 있는 맛있는 치킨집이 있습니다.

대기 손님의 치킨 요리 시간을 줄이고자 자동 주문 시스템을 제작하였습니다.

시스템 코드를 확인하고 적절한 예외처리 구문을 넣으시오.

 

조건1 : 1보다 작거나 숫자가 아닌 입력값이 들어올 때는 ValueError 로 처리

        출력메세지 : "잘못된 값을 입력하였습니다."

조건2 : 대기 손님이 주문할 수 있는 총 치킨량은 10 마리로 한정

        치킨 소진 시 사용자 정의 에러 [SoldOutErr]를 발생시키고, 프로그램 종료

        출력메세지 : "재고가 소진되어 더 이상 주문을 받지 않습니다."

--------------------------------------------------------------------------------------------------

[코드]

chicken = 10

waiting = 1 # 홀 안에는 현재 만석. 대기번호 1부터 시작

 

while(True):

    print("[남은 치킨 : {0}]".format(chicken))

    order = int(input("치킨 몇 마리 주문하시겠습니까?"))

    if order > chicken: # 남은 치킨보다 주문량이 많을 때

        print("재료가 부족합니다.")

    else :

        print("[대기번호 {0}] {1} 마리 주문이 완료되었습니다. " .format(waiting, order))

 

        waiting += 1

        chicken -= order 

 

 

--------------------------------------------------------------------------------------------------

Ans 1. 내가 작성한 코드(90% 성공, 실패)

class SoldOutErr(Exception):
    pass

chicken = 10
waiting = 1 # 홀 안에는 현재 만석. 대기번호 1부터 시작

while(True):
    try : 
        print("[남은 치킨 : {0}]".format(chicken))
        order = int(input("치킨 몇 마리 주문하시겠습니까?"))
        if order < 1 :
            raise ValueError
        elif chicken == 0 :    # 문제가 된 if 문의 위치
                raise SoldOutErr

        elif order > chicken: # 남은 치킨보다 주문량이 많을 때
                print("재료가 부족합니다.")
        
        else :
            print("[대기번호 {0}] {1} 마리 주문이 완료되었습니다. " .format(waiting, order))

            waiting += 1
            chicken -= order 
    except ValueError:
        print("잘못된 값을 입력하였습니다.")
    except SoldOutErr:
        print("재고가 소진되어 더 이상 주문을 받지 않습니다.")
        break

 - 음수 입력 및 문자 입력에 대한 ValueError 정상 처리.

 - [남은 치킨 : 0 ] 일 경우, 프로그램이 바로 종료 되지 않고, 한번 더 주문을 받아야 종료됨.

 

--------------------------------------------------------------------------------------------------

Ans 2. 나도코딩님 답안

class SoldOutErr(Exception):
    pass

chicken = 10
waiting = 1 # 홀 안에는 현재 만석. 대기번호 1부터 시작

while(True):
    try : 
        print("[남은 치킨 : {0}]".format(chicken))
        order = int(input("치킨 몇 마리 주문하시겠습니까?"))
        if order > chicken: # 남은 치킨보다 주문량이 많을 때
            print("재료가 부족합니다.")

		elif order <= 0 :
            raise ValueError
        
        else :
            print("[대기번호 {0}] {1} 마리 주문이 완료되었습니다. " .format(waiting, order))

            waiting += 1
            chicken -= order 
        
        if chicken ==0:  # 해당 위치가 정상적인 처리 위치
            raise SoldOutErr
            
    except ValueError:
        print("잘못된 값을 입력하였습니다.")
    except SoldOutErr:
        print("재고가 소진되어 더 이상 주문을 받지 않습니다.")
        break

--------------------------------------------------------------------------------------------------

FeedBack

 

지난 번 들여쓰기에 이어, 이번엔 if 문의 위치에 따른 결과 값 출력 오류....

바깥으로 꺼내기만 하면 되는거였는데...... 몇 시간을 보고도 찾지 못했던 오류.

 

들여쓰기.. python에서는 정말 중요하고 실력이 쌓일 수록 실수를 적게 할 수 있을 것 같다.

 

 

 

유튜버 '나도코딩' 님의 영상을 보며 공부 및 노트 작성합니다.

반응형

관련글 더보기

댓글 영역