第五章 中期实战 项目练习 一
题目
情景介绍
假设有一个水果摊摊主,
摊位的水果价格信息保存在fruits.txt
中,具体内容如下
apple,10
banana,5
cherry,20
lemon,15
orange,8
注:
- 这个价格定的比较随意,大家可以理解为一份(一盒)的价格吧。。。
- 假设水果的数量充足。不会因客户买掉而消失
现在希望实现一个简易的买水果系统(控制台版本的),
帮助顾客购买水果。
具体要求如下
具体需要以下几个页面(菜单)
以下也提供了中文版的和英文版的,
挑选一个自己习惯的就好。
输入不符合规范都提醒Invalid Input.
或输入无效
主界面
展示主要的介绍信息后,读取用户输入。
英文版本
---------------
Welcome!
Your balance left: 20
You can enter `b`, `l`, `r` or `e`.
The meaning is as follows:
- b: buy fruit
- l: list fruits you have bought
- r: recharge
- e: exit
Enter your command:
为了简化问题,这里假设每位顾客的初始余额都为20。
中文版本:
---------------
欢迎!
你的余额: 20
你可以输入`b`、`l`、`r` 或`e`.
意义如下:
- b: 购买水果
- l: 罗列已购买的
- r: 充值
- e: 退出
请输入命令:
购买界面
Prices are as follows:
apple : 10
banana : 5
cherry : 20
lemon : 15
orange : 8
Please enter the fruit name or first letter:
可以输入水果全名或首字母来购买
购买水果会立刻扣除费用,费用不足会显示购买失败(不扣费)。
购买成功提醒
Successfully.
购买失败提醒
Failed: insufficient balance
中文版本
价格如下:
apple : 10
banana : 5
cherry : 20
lemon : 15
orange : 8
请输入水果名或者首字母:
成功
失败: 余额不足
罗列购买过的
You have bought:
apple, cherry,
逗号分隔,不用去重
中文版本
你已购买:
apple, cherry,
充值界面
Enter recharge num:
成功后,返回主界面即可
中文版本
输入充值金额:
退出
退出时,展示余额,已购买的水果,如下
Your balance left: 90
You have bought:
apple, cherry,
Bye
中文版本
你的余额: 90
你已购买:
apple, cherry,
再见
实现效果-英文版
---------------
Welcome!
Your balance left: 20
You can enter `b`, `l`, `r` or `e`.
The meaning is as follows:
- b: buy fruit
- l: list fruits you have bought
- r: recharge
- e: exit
Enter your command: b
Prices are as follows:
apple : 10
banana : 5
cherry : 20
lemon : 15
orange : 8
Please enter the fruit name or first letter: a
Successfully.
---------------
Welcome!
Your balance left: 10
You can enter `b`, `l`, `r` or `e`.
The meaning is as follows:
- b: buy fruit
- l: list fruits you have bought
- r: recharge
- e: exit
Enter your command: l
You have bought:
apple,
---------------
Welcome!
Your balance left: 10
You can enter `b`, `l`, `r` or `e`.
The meaning is as follows:
- b: buy fruit
- l: list fruits you have bought
- r: recharge
- e: exit
Enter your command: b
Prices are as follows:
apple : 10
banana : 5
cherry : 20
lemon : 15
orange : 8
Please enter the fruit name or first letter: l
Failed: insufficient balance
---------------
Welcome!
Your balance left: 10
You can enter `b`, `l`, `r` or `e`.
The meaning is as follows:
- b: buy fruit
- l: list fruits you have bought
- r: recharge
- e: exit
Enter your command: r
Enter recharge num: 100
---------------
Welcome!
Your balance left: 110
You can enter `b`, `l`, `r` or `e`.
The meaning is as follows:
- b: buy fruit
- l: list fruits you have bought
- r: recharge
- e: exit
Enter your command: b
Prices are as follows:
apple : 10
banana : 5
cherry : 20
lemon : 15
orange : 8
Please enter the fruit name or first letter: c
Successfully.
---------------
Welcome!
Your balance left: 90
You can enter `b`, `l`, `r` or `e`.
The meaning is as follows:
- b: buy fruit
- l: list fruits you have bought
- r: recharge
- e: exit
Enter your command: l
You have bought:
apple, cherry,
---------------
Welcome!
Your balance left: 90
You can enter `b`, `l`, `r` or `e`.
The meaning is as follows:
- b: buy fruit
- l: list fruits you have bought
- r: recharge
- e: exit
Enter your command: e
Your balance left: 90
You have bought:
apple, cherry,
Bye
实现效果-中文版
---------------
欢迎!
你的余额: 20
你可以输入`b`、`l`、`r` 或`e`.
意义如下:
- b: 购买水果
- l: 罗列已购买的
- r: 充值
- e: 退出
请输入命令: b
价格如下:
apple : 10
banana : 5
cherry : 20
lemon : 15
orange : 8
请输入水果名或者首字母: a
成功.
---------------
欢迎!
你的余额: 10
你可以输入`b`、`l`、`r` 或`e`.
意义如下:
- b: 购买水果
- l: 罗列已购买的
- r: 充值
- e: 退出
请输入命令: l
你已购买:
apple,
---------------
欢迎!
你的余额: 10
你可以输入`b`、`l`、`r` 或`e`.
意义如下:
- b: 购买水果
- l: 罗列已购买的
- r: 充值
- e: 退出
请输入命令: b
价格如下:
apple : 10
banana : 5
cherry : 20
lemon : 15
orange : 8
请输入水果名或者首字母: l
失败: 余额不足
---------------
欢迎!
你的余额: 10
你可以输入`b`、`l`、`r` 或`e`.
意义如下:
- b: 购买水果
- l: 罗列已购买的
- r: 充值
- e: 退出
请输入命令: r
输入充值金额: 100
---------------
欢迎!
你的余额: 110
你可以输入`b`、`l`、`r` 或`e`.
意义如下:
- b: 购买水果
- l: 罗列已购买的
- r: 充值
- e: 退出
请输入命令: b
价格如下:
apple : 10
banana : 5
cherry : 20
lemon : 15
orange : 8
请输入水果名或者首字母: c
成功.
---------------
欢迎!
你的余额: 90
你可以输入`b`、`l`、`r` 或`e`.
意义如下:
- b: 购买水果
- l: 罗列已购买的
- r: 充值
- e: 退出
请输入命令: l
你已购买:
apple, cherry,
---------------
欢迎!
你的余额: 90
你可以输入`b`、`l`、`r` 或`e`.
意义如下:
- b: 购买水果
- l: 罗列已购买的
- r: 充值
- e: 退出
请输入命令: e
你的余额: 90
你已购买:
apple, cherry,
再见
分割线
本小段没有实际意义,
仅用于分隔题目和答案。
防止学生无意中直接看到答案,
影响思路。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
答案
框架分析
核心函数如下
def read_fruit_price(fruit_file):
# 读取文本文件,得到价格信息
return {}
def buy_fruit(fruit_prices, balance, bought):
# 尝试购买水果,购买成功则扣费,不成功不扣费
# 返回新的余额
return balance
def list_bought(bought):
# 罗列已购买的水果信息
pass
def recharge(balance):
# 充值,返回新的余额
return balance
def main(fruit_file, balance):
# 主函数,展示主菜单与处理主要命令
pass
主流程与常量分析
INITIAL_BALANCE = 20
FRUIT_FILE = "fruits.txt"
MAIN_MENU1 = """---------------
Welcome!"""
MAIN_MENU2 = """You can enter `b`, `l`, `r` or `e`.
The meaning is as follows:
- b: buy fruit
- l: list fruits you have bought
- r: recharge
- e: exit
Enter your command: """
BALANCE_MENU = "Your balance left:"
BUY_MENU1 = "Prices are as follows:"
BUY_MENU2 = "Please enter the fruit name or first letter: "
BUY_MENU3 = "Successfully."
BUY_MENU4 = "Failed: insufficient balance"
LIST_MENU1 = "You have bought: "
RECHARGE_MENU1 = "Enter recharge num: "
EXIT_MENU2 = "Bye"
INVALID = "Invalid Input."
def read_fruit_price(fruit_file):
# 读取文本文件,得到价格信息
return {}
def buy_fruit(fruit_prices, balance, bought):
# 尝试购买水果,购买成功则扣费,不成功不扣费
# 返回新的余额
return balance
def list_bought(bought):
# 罗列已购买的水果信息
pass
def recharge(balance):
# 充值,返回新的余额
return balance
def main(fruit_file, balance):
# 主函数,展示主菜单与处理主要命令
fruit_price = read_fruit_price(fruit_file)
bought = []
balance = balance
while True:
print(MAIN_MENU1)
print(BALANCE_MENU, balance)
cmd = input(MAIN_MENU2)
if cmd == "b":
balance = buy_fruit(fruit_price, balance, bought)
elif cmd == "l":
list_bought(bought)
elif cmd == "r":
balance = recharge(balance)
elif cmd == "e":
print(BALANCE_MENU, balance)
list_bought(bought)
print(EXIT_MENU2)
break
else:
print(INVALID)
main(FRUIT_FILE, INITIAL_BALANCE)
总代码(英文版)
INITIAL_BALANCE = 20
FRUIT_FILE = "fruits.txt"
MAIN_MENU1 = """---------------
Welcome!"""
MAIN_MENU2 = """You can enter `b`, `l`, `r` or `e`.
The meaning is as follows:
- b: buy fruit
- l: list fruits you have bought
- r: recharge
- e: exit
Enter your command: """
BALANCE_MENU = "Your balance left:"
BUY_MENU1 = "Prices are as follows:"
BUY_MENU2 = "Please enter the fruit name or first letter: "
BUY_MENU3 = "Successfully."
BUY_MENU4 = "Failed: insufficient balance"
LIST_MENU1 = "You have bought: "
RECHARGE_MENU1 = "Enter recharge num: "
EXIT_MENU2 = "Bye"
INVALID = "Invalid Input."
def read_fruit_price(fruit_file):
fruit_price = {}
with open(fruit_file, 'r') as f:
fr = f.read()
lines = fr.split("\n")
for line in lines:
line = line.strip()
if line:
fruit, price = line.split(",")
price = int(price)
fruit_price[fruit] = price
return fruit_price
def buy_fruit(fruit_prices, balance, bought):
while True:
print(BUY_MENU1)
for fruit in fruit_prices:
print("{:<10s}: {}".format(fruit, fruit_prices[fruit]))
choice = input(BUY_MENU2)
if len(choice) == 1:
for fruit in fruit_prices:
if fruit.startswith(choice):
choice = fruit
break
if choice in fruit_prices:
price = fruit_prices[choice]
if balance >= price:
bought.append(choice)
balance -= price
print(BUY_MENU3)
else:
print(BUY_MENU4)
return balance
print(INVALID)
def list_bought(bought):
print(LIST_MENU1)
print(" ", end="")
for fruit in bought:
print(fruit, end=", ")
print()
def recharge(balance):
while True:
num = input(RECHARGE_MENU1)
if num.isdigit():
num = int(num)
return balance + num
else:
print(INVALID)
def main(fruit_file, balance):
fruit_price = read_fruit_price(fruit_file)
bought = []
balance = balance
while True:
print(MAIN_MENU1)
print(BALANCE_MENU, balance)
cmd = input(MAIN_MENU2)
if cmd == "b":
balance = buy_fruit(fruit_price, balance, bought)
elif cmd == "l":
list_bought(bought)
elif cmd == "r":
balance = recharge(balance)
elif cmd == "e":
print(BALANCE_MENU, balance)
list_bought(bought)
print(EXIT_MENU2)
break
else:
print(INVALID)
main(FRUIT_FILE, INITIAL_BALANCE)
中文版
将前面的文本常量改掉就行,如下
INITIAL_BALANCE = 20
FRUIT_FILE = "fruits.txt"
MAIN_MENU1 = """---------------
欢迎!"""
MAIN_MENU2 = """你可以输入`b`、`l`、`r` 或`e`.
意义如下:
- b: 购买水果
- l: 罗列已购买的
- r: 充值
- e: 退出
请输入命令: """
BALANCE_MENU = "你的余额:"
BUY_MENU1 = "价格如下:"
BUY_MENU2 = "请输入水果名或者首字母: "
BUY_MENU3 = "成功."
BUY_MENU4 = "失败: 余额不足"
LIST_MENU1 = "你已购买: "
RECHARGE_MENU1 = "输入充值金额: "
EXIT_MENU2 = "再见"
INVALID = "输入无效"
后面的逻辑代码是一样的,不用改。