문제 출처 : 제로베이스 데이터 스쿨
#calculator.py 파일
def add(n1, n2):
try:
n1 = int(n1)
except:
print('첫 번째 피연산자는 숫자가 아닙니다.')
return
try:
n2 = int(n2)
except:
print('두 번째 피연산자는 숫자가 아닙니다.')
return
print(f'{n1} + {n2} = {n1+n2}')
def sub(n1, n2):
try:
n1 = int(n1)
except:
print('첫 번째 피연산자는 숫자가 아닙니다.')
return
try:
n2 = int(n2)
except:
print('두 번째 피연산자는 숫자가 아닙니다.')
return
print(f'{n1} - {n2} = {n1-n2}')
def mul(n1, n2):
try:
n1 = int(n1)
except:
print('첫 번째 피연산자는 숫자가 아닙니다.')
return
try:
n2 = int(n2)
except:
print('두 번째 피연산자는 숫자가 아닙니다.')
return
print(f'{n1} * {n2} = {n1*n2}')
def div(n1, n2):
try:
n1 = int(n1)
except:
print('첫 번째 피연산자는 숫자가 아닙니다.')
return
try:
n2 = int(n2)
except:
print('두 번째 피연산자는 숫자가 아닙니다.')
return
try:
print(f'{n1} / {n2} = {n1/n2}')
except ZeroDivisionError as e:
print(e)
print(f'0으로 나눌 수 없습니다.')
def mod(n1, n2):
try:
n1 = int(n1)
except:
print('첫 번째 피연산자는 숫자가 아닙니다.')
return
try:
n2 = int(n2)
except:
print('두 번째 피연산자는 숫자가 아닙니다.')
return
try:
print(f'{n1} % {n2} = {n1%n2}')
except ZeroDivisionError as e:
print(e)
print(f'0으로 나눌 수 없습니다.')
def flo(n1, n2):
try:
n1 = int(n1)
except:
print('첫 번째 피연산자는 숫자가 아닙니다.')
return
try:
n2 = int(n2)
except:
print('두 번째 피연산자는 숫자가 아닙니다.')
return
try:
print(f'{n1} // {n2} = {n1//n2}')
except ZeroDivisionError as e:
print(e)
print(f'0으로 나눌 수 없습니다.')
def exp(n1, n2):
try:
n1 = int(n1)
except:
print('첫 번째 피연산자는 숫자가 아닙니다.')
return
try:
n2 = int(n2)
except:
print('두 번째 피연산자는 숫자가 아닙니다.')
return
print(f'{n1} ** {n2} = {n1**n2}')
#실행파일
import calculator as cc
inputNum1 = input('첫 번째 피연산자 입력 : ')
inputNum2 = input('두 번째 피연산자 입력 : ')
cc.add(inputNum1, inputNum2)
cc.sub(inputNum1, inputNum2)
cc.mul(inputNum1, inputNum2)
cc.div(inputNum1, inputNum2)
cc.mod(inputNum1, inputNum2)
cc.flo(inputNum1, inputNum2)
cc.exp(inputNum1, inputNum2)
#출력
첫 번째 피연산자 입력 : 10
두 번째 피연산자 입력 : 0
10 + 0 = 10
10 - 0 = 10
10 * 0 = 0
division by zero
0으로 나눌 수 없습니다.
integer modulo by zero
0으로 나눌 수 없습니다.
integer division or modulo by zero
0으로 나눌 수 없습니다.
10 ** 0 = 1
💡except문에서 return으로 끝내주는 것을 잊지말아야겠다.
#prime.py 파일
class NotPrimeException(Exception):
def __init__(self, n):
super().__init__(f'{n}은 소수가 아닙니다.')
class PrimeException(Exception):
def __init__(self, n):
super().__init__(f'{n}은 소수입니다.')
def isPrime(num):
flag = True
for index in range(2, num):
if num % index == 0:
flag = False
break
if flag == False:
raise NotPrimeException(num)
else:
raise PrimeException(num)
#실행파일
import prime as pm
import random as ran
primeNumbers = []
n = 0
while n < 10:
rn = ran.randint(2,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 overlap number')
continue
n += 1
#출력
958은 소수가 아닙니다.
926은 소수가 아닙니다.
881은 소수입니다.
335은 소수가 아닙니다.
862은 소수가 아닙니다.
635은 소수가 아닙니다.
944은 소수가 아닙니다.
664은 소수가 아닙니다.
322은 소수가 아닙니다.
371은 소수가 아닙니다.
323은 소수가 아닙니다.
760은 소수가 아닙니다.
789은 소수가 아닙니다.
517은 소수가 아닙니다.
654은 소수가 아닙니다.
910은 소수가 아닙니다.
351은 소수가 아닙니다.
603은 소수가 아닙니다.
576은 소수가 아닙니다.
746은 소수가 아닙니다.
397은 소수입니다.
313은 소수입니다.
509은 소수입니다.
414은 소수가 아닙니다.
523은 소수입니다.
280은 소수가 아닙니다.
365은 소수가 아닙니다.
830은 소수가 아닙니다.
786은 소수가 아닙니다.
265은 소수가 아닙니다.
976은 소수가 아닙니다.
352은 소수가 아닙니다.
477은 소수가 아닙니다.
271은 소수입니다.
719은 소수입니다.
243은 소수가 아닙니다.
849은 소수가 아닙니다.
647은 소수입니다.
38은 소수가 아닙니다.
639은 소수가 아닙니다.
40은 소수가 아닙니다.
537은 소수가 아닙니다.
773은 소수입니다.
646은 소수가 아닙니다.
629은 소수가 아닙니다.
32은 소수가 아닙니다.
298은 소수가 아닙니다.
313 is overlap number
489은 소수가 아닙니다.
248은 소수가 아닙니다.
407은 소수가 아닙니다.
535은 소수가 아닙니다.
537은 소수가 아닙니다.
16은 소수가 아닙니다.
477은 소수가 아닙니다.
184은 소수가 아닙니다.
261은 소수가 아닙니다.
742은 소수가 아닙니다.
379은 소수입니다.
소수 : [881, 397, 313, 509, 523, 271, 719, 647, 773, 379]
💡요점은 while문 속 if문이었다. break와 continue가 아직 좀 어색한데 적절히 잘 써주어야 겠다고 생각했다.
#calculatorPurchase.py 파일
g1Price = 1200
g2Price = 1000
g3Price = 800
g4Price = 2000
g5Price = 900
def formatted(price):
return format(price, ',')
def calculator(*gcs):
gcsDic = {}
againCntInput = {}
for index, gc in enumerate(gcs):
try:
gcsDic[f'g{index+1}'] = int(gc)
except Exception as e:
againCntInput[f'g{index+1}'] = gc
print(e)
totalPrice = 0
for goodIndex in gcsDic.keys():
totalPrice += globals()[f'{goodIndex}Price'] * gcsDic[goodIndex]
print('-'*30)
print(f'Total Price : {formatted(totalPrice)}원')
print('-'*10 + '미결제 항목' + '-'*10)
for goodIndex in againCntInput.keys():
print(f'상품 : {goodIndex}, \t 구매 개수 : {againCntInput[goodIndex]}')
print('-'*30)
#실행파일
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)
#출력
goods1 구매 개수 : 7
goods2 구매 개수 : 4
goods3 구매 개수 :
goods4 구매 개수 : tka
goods5 구매 개수 : 9
invalid literal for int() with base 10: ' '
invalid literal for int() with base 10: 'tka'
------------------------------
Total Price : 20,500원
----------미결제 항목----------
상품 : g3, 구매 개수 :
상품 : g4, 구매 개수 : tka
------------------------------
💡 첫번째로, globals() 함수로 밖의 값을 가져온다는 것을 알았다. 두번째로는 "gcsDic"에 g1~g5의 가격과 그 인덱스에 맞는 각 상품의 갯수를 짝지어 딕셔너리 형태로 저장하는 것이 어려웠고, 처음보는 문법이었던 것 같다. input을 잘 못 넣었을 경우 처리하는 코드도 한눈에 들어오지 않았다. 이번 예제는 이해하는데에 시간이 많이 소요되었고 복습을 다시 해야할 문제였다..
#mem.py 파일
class MemberEmptyException(Exception):
def __init__(self, what):
super().__init__(f'{what} is empty!!')
def inputDataCheck(n, m, p, a, ph):
if n == '':
raise MemberEmptyException('name')
elif m == '':
raise MemberEmptyException('mail')
elif p == '':
raise MemberEmptyException('password')
elif a == '':
raise MemberEmptyException('address')
elif ph == '':
raise MemberEmptyException('phone_number')
class RegistMember():
def __init__(self, n, m, p, a, ph):
self.name = n
self.mail = m
self.password = p
self.address = a
self.phoneNumber = ph
print('Membership registration completed')
def printMemberInfo(self):
print(f'name : {self.name}')
print(f'mail : {self.mail}')
print(f'password : {self.password}')
print(f'address : {self.address}')
print(f'phoneNumber : {self.phoneNumber}')
#실행파일
import mem as m
memName = input('이름 입력 : ')
memMail = input('메일 입력 : ')
memPassword = input('패스워드 입력 : ')
memAddress = input('주소 입력 : ')
memPhoneNumber = input('폰번호 입력 : ')
try:
m.inputDataCheck(memName, memMail, memPassword, memAddress, memPhoneNumber)
member = m.RegistMember(memName, memMail, memPassword, memAddress, memPhoneNumber)
member.printMemberInfo()
except m.MemberEmptyException as e:
print(e)
#출력1
이름 입력 : kim
메일 입력 : abc@naver.com
패스워드 입력 : 1234
주소 입력 : seoul
폰번호 입력 : 1111-2222
Membership registration completed
name : kim
mail : abc@naver.com
password : 1234
address : seoul
phoneNumber : 1111-2222
#출력2
이름 입력 : kim
메일 입력 :
패스워드 입력 : 1234
주소 입력 : seoul
폰번호 입력 : 111-222
mail is empty!!
💡 "inputCheck함수는 유효성을 체크하여 예외를 발생시키는 역할, 만약 유효하다면 RegistMember 클래스로 인스턴스를 생성." 이 과정에서 첫 번째, RegistMember를 클래스로 인스턴스화 하지 않고 set형식의 함수로 만드려 했음. 두 번째, 그러다보니 printInfo 함수를 '모듈명.printInfo()'로 호출하려 하였음. 객체생성에는 클래스, 예외처리에 함수를 이용하는 것에 대한 개념이 많이 부족했던 것 같다.
#bank.py 파일
import random as ran
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 += m
def doWithdraw(self, ano, m):
pb = self.accounts[ano]
if pb.totalMoney - m < 0:
raise LackException(pb.totalMoney, m)
pb.totalMoney -= m
class PrivateBank:
def __init__(self, bank, account_name):
self.bank = bank
self.account_name = account_name
while True:
newAccountNo = ran.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}')
class LackException(Exception):
def __init__(self, m1, m2):
super().__init__(f'잔고부족! 잔액 : {m1}, 출금액 : {m2}')
#실행파일
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('잘못 입력했습니다. 다시 선택하세요.')
#출력
통장 개설을 위한 예금주 입력 : kim
----------------------------------------
account_name : kim
account_no : 73451
totalMoney : 0
1.입금 2.출금 3.종료 1
입금액 입력 : 50000
----------------------------------------
account_name : kim
account_no : 73451
totalMoney : 50000
1.입금 2.출금 3.종료 2
츨금액 입력 : 20000
----------------------------------------
account_name : kim
account_no : 73451
totalMoney : 30000
1.입금 2.출금 3.종료 2
츨금액 입력 : 50000
잔고부족! 잔액 : 30000, 출금액 : 50000
----------------------------------------
account_name : kim
account_no : 73451
totalMoney : 30000
1.입금 2.출금 3.종료 3
bye~
💡 전체적으로 다시 리뷰를 해봐야 할 것 같다... 꼭 복습하기
import time
def writeDiary(u, f, d):
lt = time.localtime()
timeStr = time.strftime('%Y-%m-%d %I:%M:%S %p', lt)
filePath = u + f
with open(filePath, 'a') as f:
f.write(f'[{timeStr}] {d}\n')
def readDiary(u, f):
filePath = u + f
datas = []
with open(filePath, 'r') as f:
datas = f.readlines()
return datas
import diary
members = {}
uri = 'C:/pythonTxt/'
def printMembers():
for memIndex in members.keys():
print(f' ID : {memIndex} \t PW : {members[memIndex]}')
while True:
selectNum = int(input('1.회원가입 2.한줄일기쓰기 3.일기보기 4.종료'))
if selectNum == 1:
mId = input('enter ID : ')
mPw = input('enter password : ')
members[mId] = mPw
printMembers()
elif selectNum == 2:
mId = input('enter ID : ')
mPw = input('enter password : ')
if mId in members and members[mId] == mPw:
print(f'Log in Success!!')
fileName = 'myDiary_' + mId + '.txt'
data = input('오늘의 일기를 기록하세요.')
diary.writeDiary(uri, fileName, data)
else:
print('Log in Fail!!')
printMembers()
elif selectNum == 3:
mId = input('enter ID : ')
mPw = input('enter PW : ')
if mId in members and members[mId] == mPw :
print('Log in Success!!')
fileName = 'myDiary_' + mId + '.txt'
datas = diary.readDiary(uri, fileName)
for data in datas:
print(data, end='')
else:
print('Log in Fail!!')
printMembers()
elif selectNum == 4:
print('Bye~~~~')
break
#출력
1.회원가입 2.한줄일기쓰기 3.일기보기 4.종료1
enter ID : kim
enter password : 1234
ID : kim PW : 1234
1.회원가입 2.한줄일기쓰기 3.일기보기 4.종료1
enter ID : son
enter password : 0000
ID : kim PW : 1234
ID : son PW : 0000
1.회원가입 2.한줄일기쓰기 3.일기보기 4.종료2
enter ID : kim
enter password : 1234
Log in Success!!
오늘의 일기를 기록하세요.파이썬 공부
1.회원가입 2.한줄일기쓰기 3.일기보기 4.종료2
enter ID : kim
enter password : 1234
Log in Success!!
오늘의 일기를 기록하세요.텍스트 파일 쓰기 문제풀이
1.회원가입 2.한줄일기쓰기 3.일기보기 4.종료3
enter ID : ㅏㅑㅡ
enter PW : 1234
Log in Fail!!
ID : kim PW : 1234
ID : son PW : 0000
1.회원가입 2.한줄일기쓰기 3.일기보기 4.종료3
enter ID : kim
enter PW : 1234
Log in Success!!
[2023-08-21 01:51:21 PM] 파이썬 공부
[2023-08-21 01:51:38 PM] 텍스트 파일 쓰기 문제풀이
1.회원가입 2.한줄일기쓰기 3.일기보기 4.종료4
Bye~~~~

이렇게 pythonTxt Uri에 파일이 만들어지고,

열어보면 한줄쓰기로 썼던 내용들이 저장되어있다.
💡코드들이 생각보다 어렵지는 않은데,, 왜 머릿속에서 맴돌기만 하고 바로바로 안쳐지는지 모르겠다. 첫번째로는 딕셔너리를 이용한 값들을 저장하거나 찾는 것이 아직도 익숙하지 않고, 텍스트 파일 쓰기 읽기에 적절하게 들어가야될 변수 설정들이 어렵다. 큰틀에서 어떻게 짜야할까 부터도 생각을 해보아야 겠다.
import time
def getTime():
lt = time.localtime()
st= time.strftime('%Y-%m-%d %H:%M:%S')
return st
while True:
selectNum = int(input('1.입금\t2.출금\t3.종료'))
if selectNum == 1:
money = int(input('입금액 입력 : '))
with open('C:/pythonTxt/bank/money.txt', 'r') as f:
m = f.read()
with open('C:/pythonTxt/bank/money.txt', 'w') as f: #갱신이기때문에 a가 아니라 w
f.write(str(int(m) + money))
memo = input('입금 내역 입력 : ')
with open('C:/pythonTxt/bank/pocketMoneyRegister.txt', 'a') as f:
f.write('-------------------------------------------\n')
f.write(f'{getTime()} \n')
f.write(f'[입금] {memo} : {str(money)}원 \n')
f.write(f'[잔액] : {str(int(m) + money)}원 \n')
print('입금 완료!!')
print(f'기존 잔액 : {m}')
print(f'입금 후 잔액 : {int(m)+money}')
elif selectNum == 2:
money = int(input('출금액 입력 : '))
with open('C:/pythonTxt/bank/money.txt', 'r') as f:
m = f.read()
with open('C:/pythonTxt/bank/money.txt', 'w') as f: #갱신이기때문에 a가 아니라 w
f.write(str(int(m) - money))
memo = input('출금 내역 입력 : ')
with open('C:/pythonTxt/bank/pocketMoneyRegister.txt', 'a') as f:
f.write('-------------------------------------------\n')
f.write(f'{getTime()} \n')
f.write(f'[출금] {memo} : {str(money)}원 \n')
f.write(f'[잔액] : {str(int(m) - money)}원 \n')
print('출금 완료!!')
print(f'기존 잔액 : {m}')
print(f'출금 후 잔액 : {int(m) - money}')
elif selectNum == 3:
print('Bye~~~')
break
else:
print('다시 입력하세요~!')
#출력
1.입금 2.출금 3.종료1
입금액 입력 : 3000000
입금 내역 입력 : 월급
입금 완료!!
기존 잔액 : 0
입금 후 잔액 : 3000000
1.입금 2.출금 3.종료1000000
다시 입력하세요~!
1.입금 2.출금 3.종료2
출금액 입력 : 1000000
출금 내역 입력 : 노트북구매
출금 완료!!
기존 잔액 : 3000000
출금 후 잔액 : 2000000
1.입금 2.출금 3.종료3
Bye~~~
파일이 생성되어 있다.


저장된 기록도 출력창에서 기록, 연산된 결과값이 나와있다.
💡갱신하느냐, 이어쓰느냐에 띠라 'w', 'a' 구분이 필요하다. 코드가 어렵진 않았지만 익숙하지 않아서 여러번 보았다.
#약수
inputNumber = int(input('0보다 큰 정수 입력 : '))
divisor = []
for num in range(1, (inputNumber+1)):
if inputNumber % num == 0:
divisor.append(num)
if len(divisor) > 0 :
try:
with open('C:/pythonTxt/divisor.txt', 'a') as f:
f.write(f'{inputNumber}의 약수 : ')
f.write(f'{divisor}\n')
except Exception as e:
print(e)
else:
print('divisor write complete!!')
#소수
inputNumber = int(input('0보다 큰 정수 입력 : '))
prime = []
for num in range(2, (inputNumber + 1)):
flag = True
for n in range(2, num):
if num % n == 0:
flag = False
break
if flag:
prime.append(num)
if len(prime) > 0:
try:
with open('C:/pythonTxt/prime.txt', 'a') as f:
f.write(f'{inputNumber}까지의 소수 : ')
f.write(f'{prime}\n')
except Exception as e:
print(e)
else:
print('prime write complete!!')
#출력
0보다 큰 정수 입력 : 10
divisor write complete!!
0보다 큰 정수 입력 : 25
divisor write complete!!
0보다 큰 정수 입력 : 100
divisor write complete!!
0보다 큰 정수 입력 : 50
prime write complete!!



생성된 파일과 그 내용들.
💡약수와 소수 구하는 코드는 여러번 봐서 쉬웠다. 조건문에서 len() 함수로 내용이 있는지 없는지를 확인하는 방법이 있었다.
# 두 수의 공약수
num1 = int(input('1보다 큰 정수 입력 : '))
num2 = int(input('1보다 큰 정수 입력 : '))
common = []
for index in range(1, (num1 + 1)):
if num1 % index == 0 and num2 % index == 0:
common.append(index)
if len(common) > 0:
try:
with open('C:/pythonTxt/common.txt', 'a') as f:
f.write(f'{num1}과 {num2}의 공약수 : ')
f.write(f'{common}\n')
except Exception as e:
print(e)
else:
print('common factor write complete!!')
# 두 수의 최대 공약수
num1 = int(input('1보다 큰 정수 입력 : '))
num2 = int(input('1보다 큰 정수 입력 : '))
maxComNum = 0
for index in range(1, (num1 + 1)):
if num1 % index == 0 and num2 % index == 0:
maxComNum = index
try:
with open('C:/pythonTxt/maxComNum.txt', 'a') as f:
f.write(f'{num1}과 {num2}의 최대 공약수 {maxComNum}\n')
except Exception as e:
print(e)
else:
print('Max common factor write complete!!')
#출력
1보다 큰 정수 입력 : 10
1보다 큰 정수 입력 : 15
common factor write complete!!
1보다 큰 정수 입력 : 50
1보다 큰 정수 입력 : 60
common factor write complete!!
1보다 큰 정수 입력 : 112
1보다 큰 정수 입력 : 200
common factor write complete!!
1보다 큰 정수 입력 : 10
1보다 큰 정수 입력 : 15
Max common factor write complete!!
1보다 큰 정수 입력 : 20
1보다 큰 정수 입력 : 30
Max common factor write complete!!

생성된 파일, 저장된 내용.
💡if문만 조금 신꼉쓰면 구할 수 있는 공약수, 최대 공약수 코드였다.
ship1 = 3
ship2 = 4
ship3 = 5
maxDay = 0
for index in range(1, (ship1+1)):
if ship1 % index == 0 and ship2 % index == 0:
maxDay = index
minDay = (ship1 * ship2) // maxDay
newDay = minDay
for index in range(1, (newDay+1)):
if newDay % index == 0 and ship3 % index == 0:
maxDay = index
minDay = (newDay * ship3) // maxDay
print(f'minDay : {minDay}')
print(f'maxDay : {maxDay}')
from datetime import datetime
from datetime import timedelta
n = 1
baseTime = datetime(2023, 1, 1, 10, 0, 0) # 2021년 1월 1일 10시 0분 0초
with open('C:/pythonTxt/arrrive.txt', 'a') as f:
f.write(f'2023년 모든 선박 입항일\n')
f.write(f'{baseTime}\n')
nextTime = baseTime + timedelta(days=minDay)
while True:
with open('C:/pythonTxt/arrrive.txt', 'a') as f:
f.write(f'{nextTime}\n')
nextTime = nextTime + timedelta(days=minDay)
if nextTime.year > 2023 :
break
#출력
minDay : 60
maxDay : 1

💡timedelta(days=) 함수로 원하는 일수 뒤의 날짜를 출력해주는 함수이다. datetime모듈로 날짜 지정하는 법도 알게 되었다. 세 선박의 최소공배수를 구해서 세 선박이 도착하는 날짜의 코드였다. 날짜 구하는 변수설정만 잘해두면 크게 어려울 것 없었다.
글 잘 봤습니다.