Python - Kiosk

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

Python - Vending_machine

목록 보기
4/5
post-thumbnail
class Kiosk:
    def __init__(self, mac_list=None, admin_key=9712):
        if mac_list is None:  # 이거 하면 안됨 , 메뉴가 정해져 있어서 변경이 안됨 , 할꺼면 실행 부분을 원하는 방식으로 변경을 하고나서 작업을 해야함
            self.mac_list = [
                {'menu': '불고기 버거', 'price': 3000, 'quantity': 100},
                {'menu': '유로피언 버거', 'price': 4000, 'quantity': 100},
                {'menu': '더블 더블 버거', 'price': 4500, 'quantity': 100},
                {'menu': '유채 샐러드', 'price': 2500, 'quantity': 100},
                {'menu': '감자 샐러드', 'price': 2000, 'quantity': 100},
                {'menu': '양파 샐러드', 'price': 2000, 'quantity': 100},
                {'menu': '콜라', 'price': 2000, 'quantity': 200},
                {'menu': '쉐이크', 'price': 2500, 'quantity': 200},
                {'menu': '사이다', 'price': 2000, 'quantity': 200}
            ]
        else:
            self.mac_list = mac_list
        self.balance = 0  # 잔금 변수
        self.select_dict = {}  # 메뉴를 담을 변수 { 메뉴 : 갯수 } 형식으로 구성되어있다.
        self.admin_key = admin_key  # 관리자 키 번호 저장 변수
        self.revenue = 0  # 매출 저장 변수

    # 주요 기능을 하는 메서드
    def run(self):
        while True:
            print('                버거집 키오스크')
            print()
            self.show_menu('햄버거 코너', '불고기 버거', '더블 더블 버거')
            self.show_menu('샐러드 코너', '유채 샐러드', '양파 샐러드')
            self.show_menu('음료 코너', '콜라', '사이다')
            print()
            continue_order = True  # 결제 부분이 참이다
            while continue_order:  # 반복문 시작
                self.select_item()  # 메뉴를 선택하는 메서드 시작
                continue_order = self.payment_procedure()  # 메뉴 부분을 선택하면 결제 부분이 참으로 인식 , 메서드 선언

    def show_menu(self, title, start_item, end_item):  # 메뉴를 보여주는 메서드
        print(f'                 {title}')  # 메뉴 제목
        flag = False  # 플래그는 false 값 선언
        for i, item in enumerate(self.mac_list):  # mac_list 에서 인덱스 값을 찾는다.
            if item["menu"] == start_item:  # 리스트에서 메뉴를 찾고 , 그것이 첫번째 시작하는 아이템과 같을경우
                flag = True  # 반복문은 참이되고 실행된다.
            if flag:
                print(f'{i + 1}. {item["menu"]} : {item["price"]}원 ', end=' ')  # 반복문이 참값이면 , 이런방식으로 출력한다.
            if item["menu"] == end_item:  # 리스트에서 메뉴를 찾고 , 그것이 마지막 아이템과 같을경우
                flag = False  # 찾았으니 false 값 선언
                break  # 더이상 찾을 필요없으니 종료
        print()

    def show_select_menu_items(self):  # 선택된 아이템을 보여주는 메서드
        # 제너레이터 표현식 : menu_idx = next((i for i, item in enumerate(self.mac_list) if item['menu'] == menu), None)
        for menu, quantity in self.select_dict.items():  # 딕셔너리 값 가져온다.
            menu_idx = None  # 메뉴의 인덱스값 변수 지정
            for i, item in enumerate(self.mac_list):  # self.mac_list에서 해당 메뉴의 인덱스를 찾는다.
                if item['menu'] == menu:  # mac_list 에 있는 'menu' 의 값이 일치할 경우
                    menu_idx = i  # 인덱스 값 찾기
                    break  # 일치하는 메뉴를 찾았다면 더 이상 찾을 필요가 없으므로 loop 종료

            if menu_idx is not None:  # 인덱스를 찾았으면
                print(f'메뉴 번호 : {menu_idx + 1}번 , {menu} : {quantity} 개')  # 출력

    def update_balance_and_inventory(self, menu_index, qty):  # 메뉴를 찾고 딕셔너리에 선택된 메뉴를 추가를 하는 메서드
        # 매개변수 값은 , 메뉴 인덱스 값과 , 갯수(수량)
        select_price = self.mac_list[menu_index - 1]['price']
        self.balance += select_price * qty  # 잔금 수량 업데이트 (추가)
        self.revenue += select_price * qty  # 매출을 업데이트 (추가)
        self.mac_list[menu_index - 1]['quantity'] -= qty  # 선택된 수량만큼 원래 mac_list 에서 갯수(수량) 제거
        if self.mac_list[menu_index - 1]['menu'] in self.select_dict:  # 만약 mac_list 의 메뉴 안에 선택된 딕셔너리가 있을 경우
            self.select_dict[self.mac_list[menu_index - 1]['menu']] += qty  # 선택된 딕셔너리의 해당 메뉴에 갯수 (수량)이 추가
        else:  # 그렇지 않다면
            self.select_dict[self.mac_list[menu_index - 1]['menu']] = qty  # 선택된 메뉴의 수량은 동일하다.
        selected_item = self.mac_list[menu_index - 1]['menu']  # 해당 메뉴의 변수 선언
        print(f'{selected_item} {qty}개를 선택하셨습니다.')  # 선택된 메뉴와 , 갯수 선언
        print()


    def select_item(self):  # 메뉴를 선택하는 메서드
        while True:
            try:
                select_menu = int(
                    input('메뉴 번호를 입력 해주세요 , "0" 을 입력하시면 결제를 진행합니다. "10" 을 입력하시면 선택한 메뉴를 보여드립니다. : '))  # 차감하는 입력 변수 선언
                print()

                if select_menu == self.admin_key:  # 입력 변수에 9712 를 입력하였을 경우
                    self.admin_page()  # 관리자 페이지로 입장
                    continue

                if select_menu == 0:  # 0을 입력할시 결제를 진행할 수 있도록 해야함
                    if not self.select_dict:  # 만약 선택된 딕셔너리가 없을경우?
                        print('선택하신 메뉴가 없습니다, 다시 입력해주세요')  # 선택된 메뉴가 없다고 출력
                        continue  # 다시돌아가기
                    else:
                        break  # while 탈출, 계산

                if select_menu == 10:  # 10을 입력할 경우
                    if self.select_dict:  # 선택된 딕셔너리에 있는 메뉴를 전부 보여줌
                        print(f'현재 선택한 물품')
                        self.show_select_menu_items()  # 선택된 딕셔너리를 보여주는 메서드를 선언하여 보여줌

                        change_menu = int(input('수량을 변경할 메뉴의 번호를 선택하세요 , 0 을 입력하시면 이전화면으로 되돌아갑니다. : '))

                        if change_menu == 0:
                            print()
                            self.show_menu('햄버거 코너', '불고기 버거', '더블 더블 버거')
                            self.show_menu('샐러드 코너', '유채 샐러드', '양파 샐러드')
                            self.show_menu('음료 코너', '콜라', '사이다')
                            print()
                            continue

                        if change_menu <= 0 or change_menu > len(self.mac_list):
                            print('올바른 번호를 입력하십시오')
                            continue

                        menu_name = self.mac_list[change_menu - 1]['menu']  # 메뉴 이름 확인

                        if menu_name not in self.select_dict:  # 선택된 딕셔너리에 해당 메뉴가 없다면
                            print('해당 메뉴가 구매선택에 있지 않습니다. 다시 선택해주세요')
                            continue

                        new_quantity = int(
                            input(f'변경할 수량을 입력하세요 (현재 수량: {self.select_dict[menu_name]}개): '))  # 새로운 수량 입력 받기

                        if new_quantity < 0:
                            print('올바른 수량을 입력해주세요.')
                            continue

                        # 선택된 딕셔너리에 해당 메뉴의 수량을 새로 입력한 수량으로 변경
                        self.select_dict[menu_name] = new_quantity
                        print(f"{menu_name}의 수량이 {new_quantity}개로 변경되었습니다.")
                        continue

                    else:
                        print('현재 선택된 물품이 없습니다.')
                        continue  # 반복문 처음으로 돌아가기

                if select_menu <= 0 or select_menu > len(self.mac_list):
                    print('올바른 번호를 입력하십시오')
                    continue

                select_quantity = int(input('몇 개를 구매하시겠습니까? 0을 입력하시면 구매를 취소합니다. : '))  # 몇개를 구매하겠냐는 입력 변수를 선언

                if select_quantity == 0:  # 0을 입력하였을경우
                    print('구매가 취소되었습니다.')  # 선택을 취소하고 처음으로 돌아가기
                    continue

                if self.mac_list[select_menu - 1]['quantity'] < select_quantity:  # 리스트의 수량 갯수가 선택된 수량갯수보다 적을경우
                    print('해당 메뉴의 재고가 부족합니다. 다른 메뉴로 다시 선택해주세요.')  # 재고가 부족하다고 출력
                    continue  # 반복문 처음으로 돌아가기

                self.update_balance_and_inventory(select_menu,select_quantity)  # menu - menu_index, quantity - qty 매개변수로 삽입 , 잔금 수량과 매출을 업데이트하고 , 수량을 선택된 딕셔너리에 넣는 메서드를 선언

            except ValueError:  # 잘못 입력하였을때의 에러처리문
                print('입력이 잘못되셨습니다. 다시 입력해주세요')
                continue  # 반복문 처음으로 돌아가기

    def reset_balance_and_cart(self):  # 계산을 초기화 시키는 메서드
        self.balance = 0  # 계산이 끝나고 모든 잔금을 초기화 시키는 변수
        self.select_dict = {}  # 계산이 끝나고 모든 메뉴를 초기화 시키는 변수

    def payment_procedure(self):  # 결제를 진행하는 메서드
        while True:  # 반복문 시작
            payment = input(
                f'총 구매 내역은 : {", ".join([f"{menu} {count}개" for menu, count in self.select_dict.items()])} 입니다.\n'
                f'총 가격은 {self.balance}원 입니다. 결제 진행 하시겠습니까? '
                f'결제하려면 "x" 입력 , 추가로 결제하려면 "c"를 입력해주십시오. : ')  # 입력변수 선언
            print()
            if payment == 'c':  # c를 입력하면 True 로 돌아가게 되어 , 추가로 결제를 진행할수 있도록 함
                return True  # 반복문의 처음으로 돌아감
            elif payment == 'x':  # x를 입력하면
                while True:  # 다시 반복문을 시작
                    try:
                        money = int(input('현금을 넣어주세요 : '))  # 현금을 입력하는 변수를 선언
                        break  # 반복문 탈출
                    except ValueError:  # 잘못된 금액을 입력하였을때의 에러처리문
                        print('잘못된 금액을 입력하셨습니다. 정수 형태로 다시 입력해주세요.')
                if money < self.balance:  # 현금변수가 잔금 변수 보다 작다면 , self.balance : (select_price) * qty 라서 잔금 변수는 해당 리스트의 인덱스값 + 가격변수 * 수량을 더한 값이다.
                    print('현금이 부족합니다, 다시 넣어주세요')  # 현금이 부족하다면 출력하고 반복문 처음으로 돌아가기
                    continue
                else:
                    change = money - self.balance  # 결제 완료 대금은 현금변수 - 잔금 변수
                    print(
                        f'구매 내역은 : {", ".join([f"{menu} {count}개" for menu, count in self.select_dict.items()])} 입니다. \n'
                        f'결제 완료되었습니다. 잔금 : {change} 입니다. \n'
                        f'이용해주셔서 감사합니다.')  # "," join으로 묶고 , for문으로 선택된 딕셔너리의 아이템 (메뉴, 수량)을 보여준다.
                    print()
                    self.reset_balance_and_cart()  # 잔금 , 메뉴 초기화
                    return False  # 리턴값을 false로 주어서 반복문 탈출
            else:
                print('입력이 잘못되었습니다.')
                continue

    def admin_page(self):  # 관리자 페이지 접속
        print('관리자 페이지에 접속하였습니다.')
        while True:
            print('1. 재고 확인')
            print('2. 재고 추가')
            print('3. 매출 확인')  # 매출 확인 메뉴 추가
            print('4. 나가기')
            choice = int(input('원하는 메뉴 번호를 입력하세요: '))  # 입력변수를 선언
            if choice == 1:
                self.check_inventory()  # 재고 확인
            elif choice == 2:
                self.add_inventory()  # 재고 추가
            elif choice == 3:
                self.check_revenue()  # 매출 확인 기능 호출
            elif choice == 4:
                print()
                self.show_menu('햄버거 코너', '불고기 버거', '더블 더블 버거')
                self.show_menu('샐러드 코너', '유채 샐러드', '양파 샐러드')
                self.show_menu('음료 코너', '콜라', '사이다')
                print()
                break
            else:
                print('올바른 번호를 입력하세요.')

    def check_inventory(self):  # 재고 확인
        for i, item in enumerate(self.mac_list):  # 리스트에 있는값을 겨와서 메뉴와 해당 재고를 보여준다.
            print(f"{i + 1}. {item['menu']} - 재고: {item['quantity']}개")
        print()

    def add_inventory(self):  # 재고 추가 할 부분
        for i, item in enumerate(self.mac_list):
            print(f"{i + 1}. {item['menu']}")
        item_number = int(input('재고를 추가할 메뉴의 번호를 선택하세요: '))
        add_quantity = int(input('추가할 재고의 양을 입력하세요: '))
        self.mac_list[item_number - 1]['quantity'] += add_quantity  # 해당 재고 추가
        print(f"{self.mac_list[item_number - 1]['menu']}의 재고가 {add_quantity}개 추가되었습니다.")  # 추가된 내용 표시
    print()

    def check_revenue(self):  # 매출 확인 부분
        print(f'현재 매출은 {self.revenue}원 입니다.')
        print()


if __name__ == '__main__':  # 프로그램의 시작점일때만 아래 코드를 실행한다.
    kiosk = Kiosk()  # 객체를 인스턴스화
    kiosk.run()  # run 메서드를 실행하라
profile
이것저것 다해보는 개발자

0개의 댓글