Python - 자판기 Level 3

닉네임유저·2023년 8월 14일

Python - Vending_machine

목록 보기
3/5
post-thumbnail

📌 class 사용 , 각 분리작업


  • 현금분류 작업
  • 관리자 페이지 작업
  • 클래스를 사용하여 다른 메뉴를 쓸수 있도록 작업
class Vending_machine():

    def __init__(self, cash=0, menus=None, admin_key='admin123'):
        self.cash = cash
        if menus is None:
            self.menus = {
                "coke": {"price": 3000, "quantity": 10},
                "cider": {"price": 1500, "quantity": 10},
                "milk": {"price": 1500, "quantity": 10},
                "coffee": {"price": 2000, "quantity": 10}
            }
        else:
            self.menus = menus
        self.admin_key = admin_key

    def display_menu(self):
        print('--------------메뉴-----------------')
        for index, (item, data) in enumerate(self.menus.items()):
            print(f'{index + 1}. 상품: {item}, 가격: {data["price"]}, 수량: {data["quantity"]}')

    def insert_cash(self):
        try:
            money = int(input('현금을 넣어주세요 : '))
            self.cash += money
        except ValueError:
            print('입력값이 잘못되었습니다.')

    def exchange_cash(self, change):
        # Cash Exchange Variables (현금 교환 변수)
        cev = [50000, 10000, 5000, 1000, 500, 100, 50, 10, 1]  # 원 기준 - list.
        change_dict = {}  # 지폐 , 동전 단위별로 몇장씩 필요한가 딕셔너리로 저장하기 위한 변수 선언 - 계산 후 값을 담기 위해 선언 (초기값 없음)
        result = "" # 공백

        for unit in cev:  # cev list 를 for 문 돌면서 하나씩 가져와서 unit에 넣는다. 리스트에 초기화 해둔 순서대로 하나씩 unit에 들어가고 , 아래문장 실행
            how_much = change // unit  # // <- 몫을 구하는 연산자, 현재 단위로 교환 할 수 있는 최대 개수
            change_dict[unit] = how_much  # 단위별 몇개인지 딕셔너리에 추가한다. change_dict 에 키와 , how_much 에 value 가 들어감
            change = change - (how_much * unit)  # 현재 금액에서 앞서 계산된 (단위 * 개수) 만큼 빼서 나머지 금액을 업데이트 함

        for k, v in change_dict.items(): # 딕셔너리로 저장한 값을 키 - 값으로 반복한다.
            if v != 0:  # 다만 0이 아닐경우에만 보여줌
                result += f'{k}원짜리 {v}개 입니다.\n' # 결과 값 출력 키 - 값

        # print(result)
        print()
        print('-----거스름돈 현금 금액 분류-----')
        return result.strip() # 문자열의 시작과 끝에서 공백을 제거하고 공백없이 동일한 문자열을 반환
        # 리턴값을 반환해주지 않으면 None이 자동으로 반환이 된다.


        # change 의 매개변수가 정수가 아니거나 음수인 경우에 발생할 수있음, 입력이 유효하지 않은 함수는 None 값 반환
        # 함수를 호출할때 , 유효한 양의 정수를 change 매개변수로 전달해야함

    def select_menu(self):
        select_menu = input('메뉴를 선택하세요 , "p" 를 입력하시면 추가로 현금을 투입합니다. "q" 를 입력하시면 잔돈 환불해드려요 : ')
        if select_menu in self.menus.keys():
            if self.cash > self.menus[select_menu]['price']:
                temp = select_menu
                print()
                print(f'"{temp}"를 선택하셨습니다.')
            return select_menu
            # temp = select_menu if self.cash > self.menus[select_menu]['price'] else "사용을 못해"
            # print(f'{temp}를 선택하셨습니다.')
            # 사용을 이거 잘 못하겠어서 다시 삼항연산자 -> if else로 만듬
        elif select_menu.lower() == 'p':
            return 'p'
        elif select_menu.lower() == 'q':
            return 'q'
        elif select_menu.lower() == self.admin_key:
            return 'admin'
        else:
            print('선택된 메뉴가 존재하지 않습니다.')
            return None

    def calculation(self, choice): # choice 는 사용자가 선택한 메뉴
        if choice in self.menus.keys(): # 메뉴 안에 선택한 메뉴가 있으면
            price = self.menus[choice]['price'] # 가격은 선택한 메뉴의 가격 value를 나타낸다.
            if self.menus[choice]['quantity'] <= 0: # 만약 선택한 메뉴의 수량이 0보다 작거나 같다면
                print(f'{choice}는 재고가 없습니다. 다른 메뉴를 선택해주세요.') # 재고가 없다고 다른 메뉴를 선택해 달라고 나온다.
                return True
            elif self.cash >= price: # 잔금이 가격보다 많거나 같다면
                self.cash = self.cash - price # 잔금 - 가격 으로 계산
                self.menus[choice]['quantity'] -= 1 # 그리고 수량을 하나 뺸다.
                print(
                    f'{self.exchange_cash(self.cash)}')
                print()
                print(f'총 거스름돈은 {self.cash}원 이고 선택된 메뉴는 {choice} 입니다. 남은 수량은 : {self.menus[choice]["quantity"]}개 입니다.')
                return False  # 리턴값이 false 로 들어가서 None이 나오나?
            else:
                # print(f'현금이 부족합니다. 거스름돈 : {self.cash} ')
                return True
        else:
            return False

    def run(self):
        print('자판기를 시작합니다.')
        while True:
            self.display_menu()
            selected = self.select_menu()
            if selected == "p":
                self.insert_cash()
                continue
            if selected == "q":
                print(f'{self.exchange_cash(self.cash)}') # 현금 교환
                print(f'총 거스름돈 : {self.cash}원 입니다. 이용해주셔서 감사합니다.')
                self.cash = 0
                continue
            if selected == "admin":
                self.admin_mode()
            if self.calculation(selected):
                if self.cash <= 0:
                    cash = input('현금이 부족합니다. 현금을 더 넣으시겠습니까? (넣으려면 "Y", 아니면 아무키나 눌러주십시오): ')
                    if cash.lower() == 'y':
                        self.insert_cash()
                        continue
                    else:
                        print(f'총 거스름돈 : {self.cash}입니다. 수량을 최대로 맞춥니다.')
                        continue

    def admin_mode(self):
        print('------------관리자 모드----------')
        print('---------반갑습니다 관리자님--------')
        while True:
            print()
            print('1. 메뉴 추가, 2.메뉴 수정, 3.메뉴 삭제,4.아이템 조회, 0.종료')

            admin_choice = input('사용하실 부분을 선택해주십시오 : ')

            try:
                if admin_choice == "1":
                    new_item = input('새로 추가하실 아이템 이름 : ')
                    new_price = int(input('새로 추가하실 아이템의 가격 : '))
                    new_quantity = int(input('새로 추가하실 아이템의 수량 : '))
                    self.menus[new_item] = {"price": new_price, "quantity": new_quantity}
                    continue
            except ValueError:
                print('아이템의 가격이나 수량은 정수로 입력하셔야 합니다, 다시 입력해주세요?')
                continue

            try:
                if admin_choice == "2":
                    modify_item = input('수정하실 아이템의 이름 : ')
                    modify_price = int(input('수정하실 아이템의 가격 : '))
                    modify_quantity = int(input('수정하실 아이템의 수량 : '))
                    if modify_item in self.menus.keys():
                        self.menus[modify_item] = {"price": modify_price, "quantity": modify_quantity}
                        continue
                    else:
                        print('선택하신 아이템이 없습니다.')
                        continue
            except ValueError:
                print('아이템의 가격이나 수량은 정수로 입력하셔야 합니다, 다시 입력해주세요?')
                continue

            if admin_choice == "3":
                delete = input('삭제하실 아이템의 이름 : ')
                if delete in self.menus.keys():
                    temp = self.menus.pop(delete)
                    print(f'메뉴 : {delete} : {temp}가 삭제되었습니다.')
                    continue
                else:
                    print('삭제를 하실 아이템이 없습니다. 확인하시고 다시 입력해 주십시오')
                    continue

            if admin_choice == "4":
                print('현재의 상품을 조회합니다.')
                # 일단 enumerate 내장함수는 index 를 쓰기위해 인터넷 검색함
                # '열거하다' 라는 뜻인데 순서가 있는 자료형을 첫번째 인자로 받아서 각각의 인덱스 값과 Value을 enumerate 객체로 리턴한다고 함
                for index, (item, data) in enumerate(self.menus.items()):
                    print(f'{index + 1}. 상품: {item}, 가격: {data["price"]}, 수량: {data["quantity"]}')
                continue

            if admin_choice == "0":
                print('관리자 모드를 종료합니다.')
                break
            break


vending_machine = Vending_machine()
vending_machine.run()

# Material = {"egg": {"price": 10000, "quantity": 10}, "ham": {"price": 12000, "quantity": 5}}
# sandwichs = Vending_machine(cash=0,menus=Material)
# sandwichs.run()
profile
이것저것 다해보는 개발자

0개의 댓글