파이썬 예외처리 (Quiz: 치킨 장사)

2star_·2024년 10월 7일
0

Python

목록 보기
9/13

예외처리 (Exception Handling)

이번에는 파이썬에서의 예외처리를 학습하면서 실제로 다양한 예외처리 구문을 작성해 보았습니다. 코드가 비정상적으로 중단되지 않고, 예상하지 못한 오류에 대해 대처할 수 있는 방법을 알아 보았습니다.

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("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")

여기서 ValueErrorZeroDivisionError 같은 예외들을 처리할 수 있도록 하였습니다. 예를 들어 숫자가 아닌 값을 입력하거나, 0으로 나누기를 시도했을 때 적절한 예외 메시지를 출력합니다.


에러 적용하기

특정 조건에서 에러를 직접 발생시킬 수도 있습니다. 예를 들어, 한 자리 숫자만 입력할 수 있는 계산기를 만들 때, 두 자리 이상의 숫자가 입력되면 (ex : 10) 의도적으로 ValueError를 발생시킬 수 있습니다.

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("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")

이 코드를 통해 두 자리 이상의 숫자가 입력되면 ValueError가 발생하며, 사용자에게 입력이 잘못 되었다는 것을 알립니다.


사용자 정의 예외처리

파이썬에서는 사용자 정의 예외를 만들 수 있습니다. 이를 통해 특정 상황에서 발생할 수 있는 예외를 더 명확하게 처리할 수 있습니다.BigNumberError라는 예외를 정의하고, 두 자리 숫자가 입력되었을 때 이 예외를 발생시키도록 했습니다.


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))
    print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))
except BigNumberError as err:
    print("에러가 발생하였습니다. 한 자리 숫자만 입력하세요.")
    print(err)
finally:
    print("계산기를 이용해 주셔서 감사합니다.")

이 코드는 사용자 정의 예외를 발생시킬 뿐만 아니라, finally 구문을 통해 예외가 발생하든 발생하지 않든 항상 마지막에 특정 동작을 수행할 수 있게 해줍니다.

사용 예시)

  1. 한 자리 숫자 입력 시

첫 번째 숫자를 입력하세요 : 5
두 번째 숫자를 입력하세요 : 2
5 / 2 = 2
계산기를 이용해 주셔서 감사합니다.

  1. 두 자리 숫자 입력 시

첫 번째 숫자를 입력하세요 : 10
두 번째 숫자를 입력하세요 : 2
에러가 발생하였습니다. 한 자리 숫자만 입력하세요.
입력값 : 10, 2
계산기를 이용해 주셔서 감사합니다.

  1. 잘못된 값 입력 시 (예: 문자)

첫 번째 숫자를 입력하세요 : "열개"
잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.
계산기를 이용해 주셔서 감사합니다.


🍗 예외처리 퀴즈 (치킨 주문 시스템)

주어진 코드에서 적절한 예외처리 구문을 추가하여, 치킨 주문 시스템을 만들었습니다. 예외 처리 없이 시스템이 작동하면 비정상적인 값이 입력되었을 때 오류가 발생하여 프로그램이 중단될 수 있기 때문에, 다양한 예외를 처리할 수 있도록 구현했습니다.

퀴즈 조건

  1. 1보다 작거나 숫자가 아닌 입력값이 들어오면 ValueError로 처리.
  2. 치킨이 모두 소진되면 SoldOutError를 발생시켜 프로그램 종료.

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

이 코드는 문제에 주어진 기본적인 주문 시스템입니다.


내 답안

퀴즈 문제에 대한 답안 코드를 통해, 사용자 정의 예외인 SoldOutError를 추가하고 예외처리 를 넣었습니다.


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

class SoldOutError(Exception):
    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return self.msg
try:
    while(True):
        if chicken == 0:
            raise SoldOutError("재고가 소진되어 더 이상 주문을 받지 않습니다.")

        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
except ValueError:  #조건 1 try, except 구문 추가.
    print("잘못된 값을 입력하였습니다.")

except SoldOutError as err:
    print(err)

모범 답안


class SoldOutError(Exception):
    pass

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 SoldOutError
        except ValueError:  #조건 1 try, except 구문 추가.
            print("잘못된 값을 입력하였습니다.")

        except SoldOutError:
            print("재고가 소진되어 더 이상 주문을 받지 않습니다.")
            break   

답안 비교 및 피드백...

먼저 나는 SoldOutError를 정의하면서 메시지(msg)를 받아서, 예외가 발생할 때 이 메시지를 출력할 수 있도록 하고 싶었다. 예외가 발생했을 때 __str__ 메서드가 호출되어 메시지를 출력하게 된다.

그러나

모범 답안(강의中)은 SoldOutError 클래스에 추가적인 메서드나 메시지가 없으며, 단순히 예외를 발생시키고, 메시지는 예외 처리 블록에서 처리하고 있었다.

내 답안에서는 치킨이 0이 되면 예외를 발생시키고, 예외 처리 블록에서 오류 메시지를 출력한 후에도 프로그램이 계속 실행된다 ㅠㅠ...
모범 답안에서는 치킨이 0이 되어 SoldOutError가 발생하면 break를 통해 반복문을 종료하도록 되어 있습니다.
아직 반복문의 break에 숙달되지 않은 것 같다.

또한 예외 구문 처리에서도 내 코드는 예외 클래스에서 받은 메시지를 출력하는 방식으로 처리하고 있지만, 이로 인해 코드가 복잡해졌다. 특히, 메시지가 고정되어 있는 경우에는 모범 답안처럼 except 블록에서 직접 메시지를 출력하는 것이 더 간단하고 효율적으로 보인다.


profile
안녕하세요.

0개의 댓글

관련 채용 정보