#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"をタイプすると終了する
まとめると以下。
- Print report
- Check resources sufficient?
- Process coins
- Check transaction successful?
- Make Coffee
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は試作段階のものなので割愛
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
#以下コーヒー作成だけ抜粋
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]
あと、今後この書き方真似したい。