파이썬의 예외 처리 문법을 활용한 문제 풀이
EX 1. 사용자가 입력한 숫자를 이용해서 산술연산 결과를 출력하는 모듈을 만들되, 예상하는 예외에 대한 예외처리 코드를 작성해보자.
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}')
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}')
import calculator as cc
n1 = int(input('첫번째 피연산자 입력: '))
n2 = int(input('두번째 피연산자 입력: '))
cc.add(n1,n2)
cc.sub(n1,n2)
cc.mul(n1,n2)
cc.div(n1,n2)
cc.mod(n1,n2)
cc.flo(n1,n2)
cc.exp(n1,n2)
✅ 또는 0이 들어왔을 때 예외 처리를 다음과 같이 Exception 클래스
를 사용할 수 도 있다.
try:
print(f'{n1} / {n2} = {n1 / n2}')
except ZeroDivisionError as e:
print(e) # 어떤 방식으로 에러가 나는지 확인하고
print('0으로 나눌 수 없습니다.')
# 결과는 다음과 같이 나올 것이다 #
# float division by zero
# 0으로 나눌 수 없습니다.
EX 2. 1부터 1000까지의 소수인 난수 10개를 생성하되, 소수가 아니면 사용자 예외가 발생하도록 프로그램을 만들자.
# prime.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 i in range(2,number): # 2와 number -1 한 값들만 확인해주면 된다.
if number % i == 0:
flag = False
break
if flag == False: # 소수가 아니라면
raise NotPrimeException(number)
else:
raise PrimeException(number)
# 난수이면서, 소수인 숫자를 출력해야 한다.
# 소수가 아니면 예외를 발생시키자
import prime as pm
import random
primeNumbers = []
n = 0
while n < 10:
rn = random.randint(2,1000) # 소수에는 일단 1이 포함 안됨.
if rn not in primeNumbers: # 일단, 난수가 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} 은 이미 존재합니다.')
continue
n += 1
print(f'소수인 난수 결과 : {primeNumbers}')
EX 3. 상품 구매에 따른 ‘총 구매 금액’을 출력하되 개수가 잘 못 입력된 경우 별도로 출력하도록 프로그램을 만들자.
# calculatorPrice.py
g1 = 1000; g2 = 1200; g3 = 800;
g4 = 2000; g5 = 900
def formatedNumber(n):
retur n format(n, ',')
def calculator(*gcs): # 상품을 몇개를 구매할지 확정되지 않았기 때문에 -> 반복가능한 객체로 사용할 수 있다
gdDic = {} # 제대로 된 상품 목록을 저장할 딕셔너리 초기화
againCntInput = {} # 미결제된 상품 목록을 저장할 딕셔너리 초기화
for idx, gc in enumerate(gcs):
try:
gdDic[f'g{idx + 1}'] = int(gc)
except Exception as e: # int() 를 해줬을 때, 오류가 발생하면 againCntInput 딕셔너리에 담기
againCntInput[f'g{idx + 1}'] = gc
print(e)
# 총금액 계산해주기
tot_price = 0
for g in gdDic.keys():
tot_price += globals()[f'{g}'] * gdDic[g] # globals() 는 전역변수를 담고 있는 리스트다
print('-'*32)
print(f'총 구매 금액: {formatedNumber(tot_price)}원')
print('-'*16, '미결제 항목', '-'*16)
for a in againCntInput.keys():
print(f'상품 이름: {a},\t 구매 개수: {againCntInput[a]}')
print('-' * 32)
import calculatorPrice as cp
# 구매할 상품 개수를 입력받자
gd1 = input('goods1 구매 개수: ')
gd2 = input('goods2 구매 개수: ')
gd3 = input('goods3 구매 개수: ')
gd4 = input('goods4 구매 개수: ')
gd5 = input('goods5 구매 개수: ')
acp.calculator(gd1,gd2,gd3,gd4,gd5)
🔥 globals() 🔥 : 저장된 전역변수들을 리스트로 불러온다.
EX 4. 회원가입 프로그램을 만들되, 입력하지 않은 항목이 있는 경우, 에러 메세지를 출력하는 프로그램을 만들자.
# signinCheck
class EmptyDataException(Exception):
def __init__(self,i): # 어떤 값이 없는지를 받아야되니까
super().__init__(f'{i} is empty!!')
def checkInfo(n,m,p,a,c): # 실행파일에서 회원의 정보를 입력받으면
if n == '': # 이름이 비어있다면 error 발생
raise EmptyDataException('name')
elif m == '':
raise EmptyDataException('mail')
elif p == '':
raise EmptyDataException('passsword')
elif a == '':
raise EmptyDataException('address')
elif c == '':
raise EmptyDataException('phone number')
class RegistMember():
def __init__(self, n,m,p,a,c): # 회원 정보를 입력받는 함수
self.name = n
self.mail = m
self.pw = p
self.address = a
self.contact = c
print('Membership registered!!')
def printUserInfo(self):
print(f'name : {self.name}')
print(f'mail : {self.mail}')
print(f'password: {self.pw}')
print( f'address : {self.address}')
print(f'contact : {self.contact}')
# 실행파일에서 input을 받는다.
import signinCheck as sc
name = input('이름 입력: ')
mail = input('메일 주소 입력: ')
pw = input('비밀번호 입력: ')
address = input('주소 입력: ')
contact = input('연락처 입력: ')
# 함수 실행 시 예외 발생 처리
try:
sc.checkInfo(name,mail,pw,address,contact)
newMember = sc.RegistMember(name,mail,pw,address,contact)
newMember.printUserInfo()
except sc.EmptyDataException as e:
print(e)
# 결과 출력
EX 5. 예외처리를 이용해서 은행 계좌 개설 및 입/출금 프로그램을 만들자.
# bank.py
# 1. 은행에 대한 클래스
class Bank:
def __init__(self):
self.accounts = {}
def addAccount(self,privateBank): # 계좌에 추가해주는 함수
self.accounts[privateBank.account_no] = privateBank
def isAccount(self, accountNo):# 계좌를 추가할 때, 기존에 있는 계좌인지 확인해주는 함수
return accountNo in self.accounts
def doDeposit(self,accountNo, m): # 입금하는 함수
pb = self.accounts[accountNo] # 입력한 계좌에 해당하는 정보를 가져오고
pb.totalMoney = pb.totalMoney + m # 계좌 정보에 들어있는 잔고에서 더해주기
def doWithdraw(self,accountNo, m): # 출금하는 함수
pb = self.accounts[accountNo] # 입력한 계좌에 해당하는 정보를 가져오고
# 그 잔고와 출금하려는 금액에 따라 출금이 가능한지 아닌지를 확인해주기
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}')
# 2. 개인통장을 만들어내는 클래스
# 은행, 계좌 번호, 잔고 등에 대한 정보를 갖고 있어야 한다.
# 계좌 번호를 랜덤하게 생성하기 위해 random 모듈을 가져오자
import random
class PrivateBank:
def __init__(self, bank, account_name):
self.bank = bank # 은행 이름
self.account_name = account_name # 계좌 이름
while True:
newAccount = random.randint(10000,99999) # 임의의 계좌 번호를 발생시키고
if bank.isAccount(newAccount): # 이미 계좌 번호가 존재한다면
continue # 중복되지 않는 계좌 번호가 나올때까지 반복 실행
else:
self.account_no = newAccount # 중복되지 않은 계좌번호가 만들어지면
break # 반복문 탈출
self.totalMoney = 0 # 계좌 잔고 초기화
bank.addAccount(self) # 내 계좌 정보를 추가해주기
# 내 계좌정보 출력하는 함수
def printAccount(self):
print('-'*40)
print(f'account name: {self.account_name}')
print(f'account number: {self.account_no}')
print(f'account total money: {self.totalMoney}')
print('-'*40)
import bank
# 가상의 은행 먼저 만들기
koreaBank = bank.Bank()
new_account_name = input('통장 개설을 위한 예금주 입력: ')
# 새로운 계좌 등록후, 정보 출력
myAccount = bank.PrivateBank(koreaBank, new_account_name)
myAccount.printAccount()
# 입출금 활동 시작
while True:
selectNumber = int(input('1.입금 \t 2.출금 \t 3.종료'))
if selectNumber == 1: # 입금
m = int(input('입금액 입력: '))
koreaBank.doDeposit(myAccount.account_no, m)
myAccount.printAccount()
elif selectNumber == 2: # 출금
m = int(input('출금액 입력: '))
try:
koreaBank.doWithdraw(myAccount.account_no, m)
except bank.LackException as e:
print(e)
# 예외가 발생하던, 발생하지 않던 계좌정보는 한번 더 출력해주기
finally:
myAccount.printAccount()
elif selectNumber == 3: # 종료를 누르면
print('Bye ~')
break
else: # 1,2,3이 아닌 다른 번호를 입력했을 때
print('잘못 입력했습니다. 다시 선택하세요')
다음 스터디 노트에는 텍스트 파일 다루기
와 관련된 연습 문제 풀이를 정리한다.