0
1

More than 3 years have passed since last update.

Python boot camp by Dr.Angela day15

Last updated at Posted at 2021-05-15

Mission>> Virtual Starbucks Machine

かの有名なスタバの自動販売機を作成してみよう!
機能
・3つの味があり、レシピがそれぞれ異なる
☑Latte(450円):200ml water, 24g coffee, 100ml milk
★Coffee(300円):100ml water, 18g coffee →こいつだけmilkのkeyがないのでどうするか
☑Mocha(400円):200ml water, 24g coffee, 150ml milk
・小銭とお札で販売する
☑使用できるのは 50 / 100 / 500円玉 と1000円札
☑それぞれの枚数を聞いてくる
☑入金合計が注文した料金に足らなければ商品は渡さず、全額返金
☑入金合計が注文した料金に足りるのであれば、お釣りを計算して返してくれる
・自動ディスペンサー
☑タンクに water500ml, coffee100mg, milk300ml備蓄してある
☑注文来ても材料(備蓄量)がなければつくれないため、"Sorry..."と返金および材料を減らさない。
☑スタッフを呼んで補充してもらいたいか聞く
→ Yesですべてリセットされて再度注文可能
→ Noでプログラム自体終了
・報告機能
☑"report"をタイプしたら、その時点での残り備蓄量および売上金を出力してくれる
↑一番最後の機能については1日文をメールで報告し、1週間分のデータにしてサーバに格納というような拡張ができそうだな~。スキル上がったらまたやってみよう。
→item == "report"だと、keyにreportがないからkey Errorになる。どうするか
・終了
☑注文受付時に"end"をタイプすると終了する

まとめると以下。
1. Print report
2. Check resources sufficient?
3. Process coins
4. Check transaction successful?
5. Make Coffee

starbucks_machine_menu.py
MENU = {
    "latte": {
        "ingredients": {
            "water": 200,
            "coffee": 24,
            "milk": 100,
        },
        "cost": 450,
    },
    "coffee": {
        "ingredients": {
            "water": 100,
            "coffee": 18,
        },
        "cost": 300,
    },
    "mocha": {
        "ingredients": {
            "water": 200,
            "milk": 150,
            "coffee": 24,
        },
        "cost": 400,
    }
}

resources = {
    "water": 500,
    "milk": 100,
    "coffee": 300,
}

上記restoreのwater,milk,coffeeを随時変更してrunさせることでテストケース実行に使用。

starbucks_machine_2.py

※starbucks_machine_1.pyは試作段階のものなので割愛

starbucks_machine_2.py
from starbucks_machine_menu import MENU,resources

def status(item,stock_water,stock_coffee,stock_milk):
    """注文後の販売した状態を返す"""
    if item != "coffee":
        stock_water -= MENU[item]['ingredients']['water']
        stock_coffee -= MENU[item]['ingredients']['coffee']
        stock_milk -= MENU[item]['ingredients']['milk']
        return stock_water,stock_coffee,stock_milk
    else:
        stock_water -=  MENU[item]['ingredients']['water']
        stock_coffee -= MENU[item]['ingredients']['coffee']
        return stock_water,stock_coffee,stock_milk


def refund_status(item,stock_water,stock_coffee,stock_milk):
    """注文後の販売しなかった状態を返す"""
    if item != "coffee":
        stock_water += MENU[item]['ingredients']['water']
        stock_coffee += MENU[item]['ingredients']['coffee']
        stock_milk += MENU[item]['ingredients']['milk']
        return stock_water,stock_coffee,stock_milk
    else:
        stock_water +=  MENU[item]['ingredients']['water']
        stock_coffee += MENU[item]['ingredients']['coffee']
        return stock_water,stock_coffee,stock_milk


def calculate_result(item_price,total_insert):
    """入金が足りているかTrue or Falseで返し、お釣りor合計金額を返す"""
    substraction = total_insert - item_price
    if substraction >= 0:
        return True,substraction
    else:
        return False,total_insert

# def calculate(item_price,total_insert):
#     """おつりor返金合計額を返す"""
#     substraction = total_insert - item_price
#     if substraction >= 0:
#         return substraction
#     else:
#         return total_insert


vending_machine = True   
while vending_machine:
    stock_water = resources['water']
    stock_coffee = resources['coffee']
    stock_milk = resources['milk']
    money = 0
    line1 = "---------------------------------------------"
    line2 = "------------------"

    while stock_water >= 100 or stock_coffee >= 18:
        print(f"{line1}\n ☕ Welcome to Starbucks vending machine ☕ \n{line1}")
        item = input("\nWhat would you like? [Latte/Coffee/Mocha] ")
        if item == "end":
            vending_machine = False
            break
        elif item != "report":
            stock_water,stock_coffee,stock_milk = status(item,stock_water,stock_coffee,stock_milk)
            if stock_water >= 0 and stock_coffee >= 0 and stock_milk >= 0: 
                item_price = MENU[item]['cost']
                print(f"It's {item_price} yen.")
                print("\nPlease insert coins.")
                coin1 = int(input("50 yen: "))
                coin2 = int(input("100 yen: "))
                coin3 = int(input("500 yen: "))
                coin4 = int(input("1000 yen: "))
                total_insert = coin1*50 + coin2*100 + coin3*500 + coin4*1000

                TorF, in_charge = calculate_result(item_price,total_insert)
                while TorF:
                    print(f"\nHere {in_charge} yen in charge\n")
                    money += item_price
                    break
                else:
                    print(f"\n>> Sorry that's not enough money.\n>> {in_charge} yen refunded.\n")
                    stock_water,stock_coffee,stock_milk = refund_status(item,stock_water,stock_coffee,stock_milk)
            else:
                print(f"\n>> Sorry...\n>> {item} is sold out.")
                if input("\n>> Do you call a staff and restore?? [y/n]:" ) == "n":
                    vending_machine = False
                    break
                else:
                    break
        elif item == "report":
            print(f"\n~~~~~ report ~~~~~\nstock water:{stock_water}\nstock coffee:{stock_coffee}\nstock milk:{stock_milk}\n------------------\nstored money:{money}\n\n") 

独力1回目で完成させたので、着実に力はついているのかなーという感じ。
今までは「while True: 」がうまく使えていなかったので、関数のネストをつくったりしてたけど、今回から徐々に使えるようになってきたのでスムーズに作れるようになった。

なお、先生の解答はこのような感じで、メイン関数がとてもシンプルで読みやすい。自分のは、メイン関数がやたら長くて読む気が失せる。

coffee_machine_answer.py

coffee_machine_answer.py
#以下コーヒー作成だけ抜粋
def make_coffee(drink_name, order_ingredients):
    """Deduct the required ingredients from the resources."""
    for item in order_ingredients:      #いちいちdictの中身を定義せず、for文で回している。
        resources[item] -= order_ingredients[item]
    print(f"Here is your {drink_name} ☕️. Enjoy!")


#以下メイン関数だけ抜粋
is_on = True

while is_on:
    choice = input("​What would you like? (espresso/latte/cappuccino): ")
    if choice == "off":
        is_on = False
    elif choice == "report":
        print(f"Water: {resources['water']}ml")
        print(f"Milk: {resources['milk']}ml")
        print(f"Coffee: {resources['coffee']}g")
        print(f"Money: ${profit}")
    else:
        drink = MENU[choice]
        if is_resource_sufficient(drink["ingredients"]):   #材料が足りているならば
            payment = process_coins()                      #支払い額=process_coinsからreturnされる
            if is_transaction_successful(payment, drink["cost"]):  #トランザクションが成功したら
                make_coffee(choice, drink["ingredients"])          #コーヒーを作る

メイン関数をもっと上手に作れるようになりたいなぁ...。

for item in order_ingredients:
    resources[item] -= order_ingredients[item]

あと、今後この書き方真似したい。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1