[파이썬 Projects]/<파이썬 기초>

[파이썬] 파이썬 기초 - 예외 처리 보완

기록자_Recordian 2025. 1. 21. 21:15
728x90
반응형
예외 처리 이전 내용
 

[파이썬] 파이썬기초: 예외 처리(Exception Handling)

시작에 앞서해당 내용은 ' 박응용 지음. 이지스 퍼블리싱' 을 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.예외 처리(Exception Handl

puppy-foot-it.tistory.com


예외 처리 보완

 

  • 파이썬은 try-except를 사용하여 오류 발생 시 프로그램이 종료되지 않고 예외적으로 오류를 처리할 수 있도록 한다.
  • try 블록 수행 중 오류가 발생하면 except 블록이 수행되며, 오류가 발생하지 않는다면 except 블록은 건너뛴다.
  • finally 절을 사용하면 try 문 수행 도중 예외 발생 여부와 관계없이 항상 수행된다. (오류가 발생 여부와 관계없이)
  • 오류를 일부러 발생시키려면 raise 명령어 + 에러명을 입력해주면 해당 상황이 발생하였을 경우, 지정한 에러가 발생한다.
  • 사용자가 정의하는 사용자 정의 에러를 만들기 위해서는 파이썬 내장 클래스인 Exception 클래스를 상속하여 만들 수 있다.
  • __str__ 메서드는 오류 메시지를 print문으로 출력할 경우에 호출되는 메서드이다.

아래의 코드는 한 자리 숫자 두 개를 받아 두 번째 숫자로 첫 번째 숫자를 나누는 프로그램을 실행한다.

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 ValueError:
    print("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")
except BigNumberError as err:
    print("에러가 발생하였습니다. 한 자리 숫자만 입력하세요.")
    print(err)
    
# finally는 코드의 정상 작동 여부와 관계없이 무조건 작동
finally:
    print("계산기를 이용해 주셔서 감사합니다.")

▶ 한 자리 숫자를 입력할 경우, 제대로 잘 작동한다.
 

▶ 그러나, 두 자리 숫자인 10을 입력할 경우 사용자가 정의한 BigNumberError를 발생하도록 하여
"에러가 발생하였습니다. 한 자리 숫자만 입력하세요." 라는 문자가 출력되고,
BigNumberError 발생 시 표시되도록 입력한 입력값이 표시된다.
(해당 입력값을 표시하기 위해 BigNumberError 클래스에__str__ 메서드 정의)
마지막으로 예외 발생 여부와 관계 없이 finally 절이 수행된다.


예제2. 치킨집 자동 주문 시스템

 
아래 두 가지 조건을 만족하는 치킨집의 자동 주문 시스템을 구현해 본다.
조건1. 1보다 작거나 숫자가 아닌 입력값이 들어올 때는 ValueError 처리
- 출력 메시지: "잘못된 값을 입력하였습니다."
조건2. 대기 손님이 주문할 수 있는 총 치킨량은 10마리이며, 치킨 소진 시 사용자 정의 에러 [SoldOutError]를 발생시키고 프로그램 종료
- 출력 메시지: "재고가 소진되어 더 이상 주문을 받지 않습니다."
 
[코드]

class SoldOutError(Exception): # 사용자 정의 에러
    pass

chicken = 10
waiting = 1 # 홀 안에는 현재 만석. 대기번호 1부터 시작
while(True):
    try:
        print(f"남은 치킨: {chicken}")
        order = int(input("치킨 몇 마리를 주문하시겠습니까? "))
        if order > chicken: # 남은 치킨보다 주문량이 많을 때
            print("재료가 부족합니다.")
        elif order <= 0: # 주문량이 0보다 작거나 같으면
            raise ValueError       
        else: # 주문량보다 치킨이 많거나 같을 때
            print(f"[대기번호{waiting}] {order} 마리 주문이 완료되었습니다.")
            waiting += 1
            chicken -= order

        if chicken == 0: # 치킨이 0마리 남으면
            raise SoldOutError
        
    except ValueError:
        print("잘못된 값을 입력하였습니다.")
    except SoldOutError:
        print("재고가 소진되어 더 이상 주문을 받지 않습니다.")
        break # 재고 소진되어 프로그램 종료


예제3. 패스트푸드점 자동 주문 시스템

 

아래의 조건을 만족하는 (포장 전문) 패스트푸드점 자동 판매 시스템을 구현해본다. 

  • 메뉴 및 남은 수량: 햄버거(10), 감자튀김(10)
  • 모든 메뉴가 소진되면 [SoldOutError] 발생 시키고 프로그램 종료
  • 단, 세트 메뉴 중 하나만 소진되면 [SoldSetError] 발생
  • 두 메뉴의 총 수량이 1미만이거나, 수량이 숫자가 아닐 경우 ValueError 발생
class SoldOutError(Exception):
    pass

class SoldSetError(Exception):
    pass

hamburger = 10 # 햄버거
french_fries = 10 # 감자튀김
waiting = 0 # 대기번호

def display_menu():
    print("어서오세요.")
    print("1. 햄버거")
    print("2. 감자튀김")
    print("3. 햄버거세트")
    print("4. 종료")
    menu = int(input("메뉴를 선택해 주세요.: "))
    # print(type(menu))
    return menu

def main():
    while True:
        try:
            menu = display_menu()       
            if menu == 1:
                get_burger_ord()
                
            elif menu == 2:
                get_french_ord()
                 
            elif menu == 3:
                get_set_ord()
                
            elif menu == 4:
                print("프로그램을 종료합니다.")
                break

        except ValueError:
            print("잘못된 수량을 입력하였습니다.")

        except SoldSetError:
            print("준비된 세트 메뉴 수량이 전량 소진되었습니다.")
            print("단품 메뉴를 선택해 주십시오.")
            main()
        
        except SoldOutError:
            print("재고가 모두 소진되었습니다. 영업을 종료합니다.")
            break

        finally:
            print("이용해 주셔서 감사합니다.")

def get_burger_ord():
    global hamburger
    global waiting
    print(f"남은 햄버거: {hamburger}")
    ham_ord = int(input("햄버거 수량을 입력해 주세요: "))
    if ham_ord > hamburger:
        print("수량이 모자랍니다.")
    elif ham_ord <= 0:
        raise ValueError
    else:
        hamburger -= ham_ord
        waiting += 1
        print(f"주문이 완료되었습니다. [대기번호: {waiting}]")
        print(f"햄버거 남은 수량: {hamburger}")

    if hamburger == 0:
        raise SoldOutError

def get_french_ord():
    global french_fries
    global waiting
    print(f"남은 감자튀김: {french_fries}")
    fre_ord = int(input("감자튀김 수량을 입력해 주세요: "))
    if fre_ord > french_fries:
        print("수량이 모자랍니다.")
    elif fre_ord <= 0:
        raise ValueError
    else:
        french_fries -= fre_ord
        waiting += 1
        print(f"주문이 완료되었습니다. [대기번호: {waiting}]")
        print(f"감자튀김 남은 수량: {french_fries}")

    if french_fries == 0:
        raise SoldOutError

def get_set_ord():
    global hamburger
    global french_fries
    global waiting
    set_ord = int(input("세트 수량을 입력해 주세요: "))
    if set_ord > french_fries or set_ord > hamburger :
        print("수량이 모자랍니다.")
    elif set_ord <= 0:
        raise ValueError
    else:
        french_fries -= set_ord
        hamburger -= set_ord
        waiting += 1
        print(f"주문이 완료되었습니다. [대기번호: {waiting}]")
        print(f"햄버거 남은 수량: {hamburger}")
        print(f"감자튀김 남은 수량: {french_fries}")

    if hamburger == 0 and french_fries == 0:
        raise SoldOutError
    elif hamburger == 0 and french_fries > 0:
        raise SoldSetError
    elif hamburger > 0 and french_fries == 0:
        raise SoldSetError

main()

 


다음 내용


[참고]
나도코딩 유튜브: 파이썬 코딩 무료 강의 (기본편) 

728x90
반응형