[Python] 중급 문제 풀이 - 예외 처리

박미영·2023년 3월 14일
0

📌예외 처리 연습 문제


📍문제 1 - 산술연산 결과 출력

사용자가 입력한 숫자를 이용해서 산술연산 결과를 출력하는 모듈을 만들되,
예상하는 예외에 대한 예외처리 코드를 작성해 보자

  • calculator.py
def add(n1, n2):
    print('덧셈 연산')
    try:
        n1 = float(n1)
    except:
        print('첫 번째 피연산자는 숫자가 아닙니다.')
        return
    try:
        n2 = float(n2)
    except:
        print('두 번째 피연산자는 숫자가 아닙니다.')
        return

    print(f'{n1} + {n2} = {n1 + n2}')

def sub(n1, n2):
    print('뺄셈 연산')
    try:
        n1 = float(n1)
    except:
        print('첫 번째 피연산자는 숫자가 아닙니다.')
        return
    try:
        n2 = float(n2)
    except:
        print('두 번째 피연산자는 숫자가 아닙니다.')
        return
    print(f'{n1} - {n2} = {n1 - n2}')

def mul(n1, n2):
    print('곱셈 연산')
    try:
        n1 = float(n1)
    except:
        print('첫 번째 피연산자는 숫자가 아닙니다.')
        return
    try:
        n2 = float(n2)
    except:
        print('두 번째 피연산자는 숫자가 아닙니다.')
        return
    print(f'{n1} * {n2} = {n1 * n2}')

def div(n1, n2):
    print('나눗셈 연산')
    try:
        n1 = float(n1)
    except:
        print('첫 번째 피연산자는 숫자가 아닙니다.')
        return
    try:
        n2 = float(n2)
    except:
        print('두 번째 피연산자는 숫자가 아닙니다.')
        return

    # if n2 == 0:
    #     print('0으로 나눌 수 없습니다.')
    #     return
    # print(f'{n1} / {n2} = {n1 / n2}')

    try:
        print(f'{n1} / {n2} = {n1 / n2}')
    except ZeroDivisionError as e:
        print(e)
        print('0으로 나눌 수 없습니다.')

def mod(n1, n2):
    print('나머지 연산')
    try:
        n1 = float(n1)
    except:
        print('첫 번째 피연산자는 숫자가 아닙니다.')
        return
    try:
        n2 = float(n2)
    except:
        print('두 번째 피연산자는 숫자가 아닙니다.')
        return

    if n2 == 0:
        print('0으로 나눌 수 없습니다.')
        return

    print(f'{n1} % {n2} = {n1 % n2}')



def flo(n1, n2):
    print('몫 연산')
    try:
        n1 = float(n1)
    except:
        print('첫 번째 피연산자는 숫자가 아닙니다.')
        return
    try:
        n2 = float(n2)
    except:
        print('두 번째 피연산자는 숫자가 아닙니다.')
        return

    if n2 == 0:
        print('0으로 나눌 수 없습니다.')
        return


    print(f'{n1} // {n2} = {n1 // n2}')


def exp(n1, n2):
    print('거듭제곱 연산')
    try:
        n1 = float(n1)
    except:
        print('첫 번째 피연산자는 숫자가 아닙니다.')
        return
    try:
        n2 = float(n2)
    except:
        print('두 번째 피연산자는 숫자가 아닙니다.')
        return
    print(f'{n1} ** {n2} = {n1 ** n2}')
  • ex.py
import calculator as cc

num1 = input('첫 번째 피연산자 입력: ')
num2 = input('두 번째 피연산자 입력: ')

cc.add(num1, num2)
cc.sub(num1, num2)
cc.mul(num1, num2)
cc.div(num1, num2)
cc.mod(num1, num2)
cc.flo(num1, num2)
cc.exp(num1, num2)
  • 출력결과




📍문제 2 - 소수 난수 5개 생성

1부터 1000까지의 소수인 난수 5개를 생성하되, 소수가 아니면 사용자 예외가 발생하도록 프로그램을 만들어보자.

  • prime_module.py
class NotPrimeException(Exception):

    def __init__(self, n):
        super().__init__(f'{n} is not prime number.')   # 소수가 아닌 경우 발생하는 예외


class PrimeException(Exception):

    def __init__(self, n):
        super().__init__(f'{n} is prime number.')  # 소수인 경우 발생하는 예외


def isPrime(number):
    flag = True
    for n in range(2, number):
        if number % n ==0:
            flag = False
            break

    if flag == False:
        raise NotPrimeException(number)
    else:
        raise PrimeException(number)
  • ex.py
import prime_module as pm
import random

primeNumbers = []

n = 0

while n < 5:
    rn = random.randint(1, 1000)
    if rn not in primeNumbers:
        try:
            pm.isPrime(rn)
        except pm.NotPrimeException as e:
            print(e)
            continue
        except pm.PrimeException as e:
            print(e)
            primeNumbers.append(rn)

    else:
        print(f'{rn} is overap number.')
        continue
    n += 1

print(f'primeNumbers: {primeNumbers}')
  • 출력결과




📍문제 3 - 영수증 출력

상품 구매에 따른 ‘총 구매 금액’을 출력하되, 다음과 같이 개수가 잘 못 입력된 경우 별도로 출력하도록 프로그램을 만들어보자

  • calculatorPurchase.py
g1Price, g2Price, g3Price, g4Price, g5Price = 1200, 1000, 800, 2000, 900

def formatedNumber(n):
    return format(n, ',')

def calculator(*gcs):   # *gcs: 몇 개 변수가 들어올지 모를 때 *

    gcsDic = {}
    againCntInput = {}

    for idx, gc in enumerate(gcs):
        try:
            gcsDic[f'g{idx+1}'] = int(gc)
        except Exception as e:
            againCntInput[f'g{idx + 1}'] = gc
            print(e)

    totalPrice = 0
    for g in gcsDic.keys():
        totalPrice += globals()[f'{g}Price'] * gcsDic[g]    # 변수명 바로 찾아서 값 저장

    print('---------------------------------------')
    print(f'총 구매 금액: {formatedNumber(totalPrice)}원')
    print('---------------미결제 항목---------------')
    for g in againCntInput.keys():
        print(f'상품: {g}, \t 구매 개수: {againCntInput[g]}')
    print('---------------------------------------')
    print()
  • ex.py
import calculatorPurchase as cp

g1Cnt = input('goods1 구매 개수: ')
g2Cnt = input('goods2 구매 개수: ')
g3Cnt = input('goods3 구매 개수: ')
g4Cnt = input('goods4 구매 개수: ')
g5Cnt = input('goods5 구매 개수: ')

cp.calculator(g1Cnt, g2Cnt, g3Cnt, g4Cnt, g5Cnt)
  • 출력결과



💡globals() - 변수명 자동 지정 할 때 사용

totalPrice += globals()[f'{g}Price'] * gcsDic[g]

변수명 자동 지정




📍문제 4 - 회원가입

회원가입 프로그램을 만들되 입력하지 않은 항목이 있는 경우 에러 메시지를 출력하는 프로그램을 만들어보자.

  • mem.py
class EmptyDataException(Exception):
    def __init__(self, i):
        super().__init__(f'{i} is empty!')

def checkInputData(n, m, p, a, ph):
    if n == '':
        raise EmptyDataException('name')
    elif m == '':
        raise EmptyDataException('mail')
    elif p == '':
        raise EmptyDataException('password')
    elif a == '':
        raise EmptyDataException('address')
    elif ph == '':
        raise EmptyDataException('phone')

class RegistMember():
    def __init__(self, n, m, p, a, ph):
        self.m_name = n
        self.m_mail = m
        self.m_pw = p
        self.m_addr = a
        self.m_phone = ph
        print('Membership complete')

    def printMemberInfo(self):
        print(f'm_name: {self.m_name}')
        print(f'm_mail: {self.m_mail}')
        print(f'm_pw: {self.m_name}')
        print(f'm_addr: {self.m_addr}')
        print(f'm_phone: {self.m_phone}')
  • ex.py
import mem

m_name = input('이름 입력: ')
m_mail = input('메일 주소 입력: ')
m_pw = input('비밀번호 입력: ')
m_addr = input('주소 입력: ')
m_phone = input('연락처 입력: ')

try:
    mem.checkInputData(m_name, m_mail, m_pw, m_addr, m_phone)
    newMember = mem.RegistMember(m_name, m_mail, m_pw, m_addr, m_phone)
    newMember.printMemberInfo()
except mem.EmptyDataException as e:
    print(e)
  • 출력결과




📍문제 5 - 은행 계좌 개설 및 입/출금 프로그램

은행 계좌 계설 및 입/출금 프로그램을 만들어 보자.

  • back.py
import random

class PrivateBank:
    def __init__(self, bank, account_name):
        self.bank = bank
        self.account_name = account_name

        while True:
            newAccountNo = random.randint(10000, 99999)
            if bank.isAccount(newAccountNo):
                continue
            else:
                self.account_no = newAccountNo
                break

        self.totalMoney = 0
        bank.addAccount(self)

    def printBankInfo(self):
        print('-' * 40)
        print(f'account_name: {self.account_name}')
        print(f'account_no: {self.account_no}')
        print(f'totalMoney: {self.totalMoney}')
        print('-' * 40)



class Bank:

    def __init__(self):
        self.accounts = {}

    def addAccount(self, privateBank):
        self.accounts[privateBank.account_no] = privateBank

    def isAccount(self, ano):
        return ano in self.accounts

    def doDeposit(self, ano, m):
        pb = self.accounts[ano]
        pb.totalMoney = pb.totalMoney + m

    def doWithdraw(self, ano, m):
        pb = self.accounts[ano]
        if pb.totalMoney - m < 0:
            raise LackException(pb.totalMoney, m)
        pb.totalMoney = pb.totalMoney - m

class LackException(Exception):
    def __init__(self, m1, m2):
        super().__init__(f'잔고 부족!! 잔액: {m1}, 출금액: {m2}')
  • ex.py
import bank

koreaBank = bank.Bank()

new_account_name = input('통장 개설을 위한 예금주 입력: ')
myAccount = bank.PrivateBank(koreaBank, new_account_name)
myAccount.printBankInfo()

while True:

    selectNumber = int(input('1.입금, \t 2.출금, \t 3.종료: '))
    if selectNumber == 1:
        m = int(input('입금액 입력: '))
        koreaBank.doDeposit(myAccount.account_no, m)
        myAccount.printBankInfo()

    elif selectNumber == 2:
        m = int(input('출금액 입력: '))
        try:
            koreaBank.doWithdraw(myAccount.account_no, m)
        except bank.LackException as e:
            print(e)
        finally:
            myAccount.printBankInfo()

    elif selectNumber == 3:
        print('Bye~~')
        break

    else:
        print('잘못 입력했습니다. 다시 선택하세요.')
  • 출력결과




느낀 점😊

예외 처리... 아직 익숙하지 않아 스스로 구현하기가 쉽지 않다. 언젠가는 잘 할 수 있겠지? 오늘은 globals() 사용법을 알게 돼서 너무 반가웠다.
정말 저거 몰라서 문제를 쉽게 풀지 못하고 돌아갔던 적이 몇 번인지ㅠㅠ
나도 이제 자동으로 변수명 지정할 수 있다!!! 변수명 자동으로 불러올 수도 있다!!!


"이 글은 제로베이스 데이터 취업 스쿨 강의 자료 일부를 발췌한 내용이 포함되어 있습니다."

0개의 댓글