본문 바로가기
Programming Language/Python

[파이썬] DAY9 계좌 알고리즘 문제 코드 리뷰

by 9루트 2022. 1. 27.

전체 코드

import pickle
class 금액부족(Exception):
    def __str__(self):
        return "통장에 잔액이 부족합니다."


# 계좌 정보
class Account:
    account={}
    def __init__(self,ano,owner,balance):
        self.__ano = ano # another
        self.__owner = owner
        self.__balance = balance
        self.__record=f"{'초기금액:'+str(balance):<10s}|{'합계금액:'+str(balance):<10s}|\n"


    def getAno(self): return self.__ano
    def setAno(self,ano): self.__ano = ano
    def getOwner(self):return self.__owner
    def setOwner(self,owner): self.__owner = owner
    def getBalance(self):return self.__balance
    def setBalance(self,balance) :self.__balance = balance
    def getrecord(self) :return self.__record

    def recording(self,changedBalance):
        if(changedBalance >= 0):
            self.__record += (f"{'입금내역:'+str(changedBalance):<10s}|{'합계금액:'+str(self.__balance):<10s}|")
        else:
            self.__record += (f"{'출금내역:'+str(changedBalance*-1):<10s}|{'합계금액:'+str(self.__balance):<10s}|")
        self.__record += "\n"
    def __repr__(self):
      return f"{self.__ano:^10}|{self.__owner:^5}|{self.__balance:^10d}"
      
      
# 계좌 생성  
def createAccount():
    print("--------------")
    print("계좌생성")
    print("--------------")
    while True:
      in_ano =input("계좌번호(8자리를 입력): ")
      if len(in_ano)==8:
        ano=in_ano[:4]+"-"+in_ano[4:]
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    owner =input("계좌주: ")
    balance = int(input("초기입금액: "))
    newAccount = Account(ano, owner, balance)
    
    if ano in Account.account:
        print("이미 있는 계좌 입니다.")
    else:
        Account.account[ano]=newAccount
        print("계좌를 등록했습니다.")
        
        
        
# 계좌 목록 조회        
def accountList():
    print("--------------")
    print("계좌목록")
    print("--------------")
    for key,account in Account.account.items():
        print(f" 계좌번호 | 계좌주 | 예금액 ")
        print(account)
        
        
        
# 예금
def deposit():
    print("--------------")
    print("예금")
    print("--------------")
    while True:
      in_ano =input("계좌번호(8자리 입력): ")
      if len(in_ano)==8:
        ano=in_ano[:4]+"-"+in_ano[4:]
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    money = int(input("예금액: "))
    if ano not in Account.account :
        print("결과: 계좌가 없습니다.")
        return
    account=Account.account.get(ano)
    account.setBalance(account.getBalance() + money)
    account.recording(money)
    print("결과: 예금이 성공되었습니다.")
    
    
    
# 출금
def withdraw():
    print("--------------")
    print("출금")
    print("--------------")
    while True:
      in_ano =input("계좌번호(8자리 입력): ")
      if len(in_ano)==8:
        ano=in_ano[:4]+"-"+in_ano[4:]
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    money =int(input("출금액: "))
    if ano not in Account.account :
        print("결과: 계좌가 없습니다.")
        return
    account=Account.account.get(ano)
    if account.getBalance()<money:
        raise 금액부족()
    account.setBalance(account.getBalance() - money)
    money *=-1
    account.recording(money)
    print("결과: 출금이 성공되었습니다.")
    
    
# 송금       
def remit():
    print("--------------")
    print("송금")
    print("--------------")
    while True:
      in_ano =input("출금계좌번호(8자리 입력): ")
      if len(in_ano)==8:
        ano1=in_ano[:4]+"-"+in_ano[4:]
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    while True:
      in_ano =input("입금계좌번호(8자리 입력): ")
      if len(in_ano)==8:
        ano2=in_ano[:4]+"-"+in_ano[4:]
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    remit_money=int(input("출금액: "))
    if(remit_money > 0):
        if ano1 not in Account.account :
            print("결과: 계좌가 없습니다.")
            return
        if ano2 not in Account.account :
            print("결과: 계좌가 없습니다.")
            return
        account=Account.account.get(ano1)
        if account.getBalance()<remit_money:
            raise 금액부족()
        account.setBalance(account.getBalance() - remit_money)
        remit_money *=-1
        account.recording(remit_money)
        remit_money *=-1
        account=Account.account.get(ano2)
        account.setBalance(account.getBalance() + remit_money)
        account.recording(remit_money)
        print("결과: 송금이 성공되었습니다.")
    else :print("송금액은 양수여야함.")
    
    
# 계좌 내역 확인    
def showRecord() :
    print("--------------")
    print("내역")
    print("--------------")
    while True:
      in_ano =input("조회계좌번호(8자리 입력): ")
      if len(in_ano)==8:
        find_ano=in_ano[:4]+"-"+in_ano[4:].
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    if find_ano not in Account.account :
        print("결과: 조회계좌가 없습니다.")
        return
    account=Account.account.get(find_ano)
    print(f"{'거래내역':^10s}|{'합계금액':^10s}|")
    print(account.getrecord())
    
    
    
# 메인문    
run = True
# 예외처리: 기존 저장된 data가 없을 때
try:open("save_data.p","rb")
except:
    print("기존에 저장된 data가 없습니다.")
else:
    Account.account=pickle.load(open("save_data.p","rb"))
while(run):
    print("----------------------------------------------------------")
    print("1.계좌생성 | 2.계좌목록 | 3.예금 | 4.출금 | 5.종료 | 6.송금 | 7.내역")
    print("----------------------------------------------------------")
    selectNo =int(input("선택>"))
    if(selectNo == 1):
        createAccount()
    elif(selectNo == 2):
        accountList()
    elif(selectNo == 3):
            deposit()
    elif(selectNo == 4):
        try:
             withdraw()
        except 금액부족 as e:
            print(e)
    elif(selectNo == 5):
        run = False
    elif(selectNo == 6):
        try:
            remit()
        except 금액부족 as e:
            print(e)
    elif(selectNo == 7):
        showRecord()      
print("프로그램 종료")
pickle.dump(Account.account,open("save_data.p","wb"))

 

 

예외 처리 클래스 상속

def recording(self,changedBalance):
        if(changedBalance >= 0):
            self.__record += (f"{'입금내역:'+str(changedBalance):<10s}|{'합계금액:'+str(self.__balance):<10s}|")
        else:
            self.__record += (f"{'출금내역:'+str(changedBalance*-1):<10s}|{'합계금액:'+str(self.__balance):<10s}|")
        self.__record += "\n"
    def __repr__(self):
      return f"{self.__ano:^10}|{self.__owner:^5}|{self.__balance:^10d}"

 

 

 

a.__str__(스트링값)

a.__repr__(스트링값)

다이렉트로 넣겠다. 

 

set 메소드는 왜 안했냐

값을 넣는 작업 자체가 초기화이다. 값을 바꾸는 내용을 초기화라고 한다.

recoding() 함수가 set 역할을 한다.

자동차 코드 : 필요하면 만들지만 굳이 안 쓸거면 set 메소드 만들 필요 없다.

 

둘 다 문자열로 보여지지만
  # 예쁘게 보이기 위함(사용자에 포커싱)
class A:
  # 둘 다 문자열로 보여지지만
  # 예쁘게 보이기 위함(사용자에 포커싱)
  def __str__(self): # 각 객체들을 출력했을 때 문자열로 표현
    return "문자열"

  # 객체가 가지고 있는 정보가 뭔지 알려주기 위함(개발자에 포커싱) 
  def __repr__(self): # 객체들이 가지고 있는 리스트(정보, 데이터) 
    return "객체의 의미"

a = A()
print(a)
li = [a] # 리스트 형태로 출력해야한다.
print(li)

 

 

 

 

글자 정렬

class 금액부족(Exception):
    def __str__(self):
        return "통장에 잔액이 부족합니다."

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=huhsamecoding&logNo=221039311539 

 

파이썬 문자열 다루기, 문자열 포매팅 | Python string formating | 왼쪽정렬 가운데정렬 오른쪽정렬

안녕하세요. 허세임 코딩입니다 :) 문자열을 다루는 것은 여러가지로 방법이 다양합니다. 이 게시물에서는 ...

blog.naver.com

:^10 중앙정렬

 

 


1. 함수1: 계좌 생성

string 슬라이싱

      in_ano =input("계좌번호(8자리를 입력): ")
      if len(in_ano)==8:
        ano=in_ano[:4]+"-"+in_ano[4:]
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    owner =input("계좌주: ")
    balance = int(input("초기입금액: "))
    newAccount = Account(ano, owner, balance)

immutable 객체도 슬라이싱 가능하다 -> 새로운 객체 생성

튜플도 가능, string 도 가능

여기서는 string 슬라이싱

 

 

 

계좌가 중복되었을 경우를 고려한다.

if ano in Account.account:
        print("이미 있는 계좌 입니다.")
    else:
        Account.account[ano]=newAccount
        print("계좌를 등록했습니다.")

in : 안에 있는가? True / False 가 나온다.

 

 

2. 함수2: 계좌 목록

for key,account in Account.account.items():
        print(f" 계좌번호 | 계좌주 | 예금액 ")
        print(account)

딕셔너리로 선언 : 계좌번호가 키값

키값만 나와서 비교한다.

리스트는 l = [], l[0] =134 불가능

딕셔너리는 d = {} d[0] = 10 가능  0이라는 키값을 갖는 객체를 만들고 그 값을 10으로 해라

딕셔너리는 for 문에 넣으면 키 값의 집합이 나온다.

int는 객체이지만 출력하면 주솟값이 아닌 숫자값이 나온다.

 

items() : 튜플로 나온다.

 

 

3. 함수3: 예금(입금)

def deposit():
    print("--------------")
    print("예금")
    print("--------------")
    while True:
      in_ano =input("계좌번호(8자리 입력): ")
      if len(in_ano)==8:
        ano=in_ano[:4]+"-"+in_ano[4:]
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    money = int(input("예금액: "))
    if ano not in Account.account :
        print("결과: 계좌가 없습니다.")
        return
    account=Account.account.get(ano)
    account.setBalance(account.getBalance() + money)
    account.recording(money)
    print("결과: 예금이 성공되었습니다.")

get으로 딕셔너리의 값을 가져온다.

 

 

4. 함수4: 출금

def withdraw():
    print("--------------")
    print("출금")
    print("--------------")
    while True:
      in_ano =input("계좌번호(8자리 입력): ")
      if len(in_ano)==8:
        ano=in_ano[:4]+"-"+in_ano[4:]
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    money =int(input("출금액: "))
    if ano not in Account.account :
        print("결과: 계좌가 없습니다.")
        return
    account=Account.account.get(ano)
    if account.getBalance()<money:
        raise 금액부족()
    account.setBalance(account.getBalance() - money)
    money *=-1
    account.recording(money)
    print("결과: 출금이 성공되었습니다.")

 

 

5. 함수5: 송금

def remit():
    print("--------------")
    print("송금")
    print("--------------")
    while True:
      in_ano =input("출금계좌번호(8자리 입력): ")
      if len(in_ano)==8:
        ano1=in_ano[:4]+"-"+in_ano[4:]
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    while True:
      in_ano =input("입금계좌번호(8자리 입력): ")
      if len(in_ano)==8:
        ano2=in_ano[:4]+"-"+in_ano[4:]
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    remit_money=int(input("출금액: "))
    if(remit_money > 0):
        if ano1 not in Account.account :
            print("결과: 계좌가 없습니다.")
            return
        if ano2 not in Account.account :
            print("결과: 계좌가 없습니다.")
            return
        account=Account.account.get(ano1)
        if account.getBalance()<remit_money:
            raise 금액부족()
        account.setBalance(account.getBalance() - remit_money)
        remit_money *=-1
        account.recording(remit_money)
        remit_money *=-1
        account=Account.account.get(ano2)
        account.setBalance(account.getBalance() + remit_money)
        account.recording(remit_money)
        print("결과: 송금이 성공되었습니다.")
    else :print("송금액은 양수여야함.")

 

 

6. 함수6: 내역조회

def showRecord() :
    print("--------------")
    print("내역")
    print("--------------")
    while True:
      in_ano =input("조회계좌번호(8자리 입력): ")
      if len(in_ano)==8:
        find_ano=in_ano[:4]+"-"+in_ano[4:].
        break
      print("계좌번호는 -없이 8자리를 입력하시오.")
    if find_ano not in Account.account :
        print("결과: 조회계좌가 없습니다.")
        return
    account=Account.account.get(find_ano)
    print(f"{'거래내역':^10s}|{'합계금액':^10s}|")
    print(account.getrecord())

 

 

6. 메인 영역

try:open("save_data.p","rb")
except:
    print("기존에 저장된 data가 없습니다.")
else:
    Account.account=pickle.load(open("save_data.p","rb"))
while(run):
    print("----------------------------------------------------------")
    print("1.계좌생성 | 2.계좌목록 | 3.예금 | 4.출금 | 5.종료 | 6.송금 | 7.내역")
    print("----------------------------------------------------------")
    selectNo =int(input("선택>"))
    if(selectNo == 1):
        createAccount()
    elif(selectNo == 2):
        accountList()
    elif(selectNo == 3):
            deposit()
    elif(selectNo == 4):
        try:
             withdraw()
        except 금액부족 as e:
            print(e)
    elif(selectNo == 5):
        run = False
    elif(selectNo == 6):
        try:
            remit()
        except 금액부족 as e:
            print(e)
    elif(selectNo == 7):
        showRecord()      
print("프로그램 종료")
pickle.dump(Account.account,open("save_data.p","wb"))

 as라는 키워드

NUMPY = np

1) 랜덤 배울 때는 닉네임 부여하는 역할로 쓴다.

2) 클래스가 아닌 객체(인스턴스)의 정보를 가져온다. 즉, 객체의 셋팅한 출력 정보가 나오게 된다.

입력 값을 객체의 출력값으로 결정짓는다.

 

 

 

raise : 예외를 전달한다. (상단으로 보낸다.)

 

 

출금 계좌 입금 계좌 따로 따지기

 

 

함수 내에서

return: 받는 값 설정해야함

raise: 받는 값 없어도 됨

 

 

global 안 쓰는 이유 : 클래스 필드는 인스턴스에 다 공유된다.

 

 

메소드 안에 예외 처리 안 한 이유

입금 출금  각각 예외 처리 만들 바에는 메인에 하나만 둬서 중복성을 없애기 위함이다.