作业需求
1. 购物系统,能够注册登录,用户第一次登录后,让用户输入金额,然后打印商品列表
2. 允许用户根据商品编号购买商品
3. 用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒
4. 购买完一件商品后打印购物清单及余额
5. 可随时查看购物清单和退出
6. 如果用户多次购买同一商品,必须合并商品数量和价格信息
7. 用户下次登录时,可查看之前的消费记录
流程图
README
1. 通过分析需求,使用面向过程和函数式编程的方式更好; 2. 文件序列化通过 pickle实现永久存储; 3. 每个用户信息用独立的数据文件来存储; 4. 要求输入数字的地方只能输入正整数; 5. 第二次购买的商品如果同第一次购买的相同,则在第一次商品信息上进行叠加。
程序代码
#!/usr/bin/python3 # -*- coding: utf-8 -*- # Author: hkey import os, pickle def file_oper(file, mode, *args): \'\'\' 通过pickle序列化持久存储数据信息 :param file: 不同的用户生成不同的数据文件,文件名+\'.db\' :param mode: 对数据文件的操作,读取还是写入 :param args: 需要写入的数据信息 :return: 返回读取数据文件的信息 \'\'\' if mode == \'wb\': data = args[0] with open(file, mode) as f: pickle.dump(data, f) elif mode == \'rb\': with open(file, mode) as f: data = pickle.load(f) return data def user(user, pwd, mode): \'\'\' 用户注册及登录 :param user: 用户输入的用户名 :param pwd: 用户输入的密码 :param mode: 注册还是登录 :return: 登录成功,返回用户信息;登录失败,返回 None \'\'\' db_file = user + \'.db\' # 用户注册 if mode == \'regist\': if not os.path.isfile(db_file): user_info = {\'name\': user, \'passwd\': pwd, \'stat\': 0} file_oper(db_file, \'wb\', user_info) print(\'\033[32;1m注册成功.\033[0m\') else: print(\'\033[31;1m错误:该用户已存在.\033[0m\') # 用户登录 elif mode == \'login\': if os.path.isfile(db_file): dict_user = file_oper(db_file, \'rb\') if dict_user[\'name\'] == user and dict_user[\'passwd\'] == pwd: print(\'\033[32;1m登录成功.\033[0m\') return dict_user else: print(\'\033[31;1m错误:用户名密码错误。\033[0m\') else: print(\'\033[31;1m错误:该用户不存在.\033[0m\') def shopping(user_dict, list_goods): \'\'\' 用户购物信息 :param user_dict: 用户信息 :param list_goods: 商品列表 \'\'\' # 判断购物车内是否有商品 if user_dict[\'shopping_car\']: list_shopping = user_dict[\'shopping_car\'] else: list_shopping = [] while True: print(\'\033[32;1m商品列表\033[0m\'.center(50, \'#\')) for i, k in enumerate(list_goods): print(\'序号:%s\t商品名:%s\t\t价格:%s\' % (i, k[\'name\'], k[\'price\'])) choice = input(\'\033[34;1m购买请输入商品序号[t 查看购物清单 q 退出]:\033[0m\').strip() if not choice: continue # 用户输入大小写 \'q\' 都是退出 if choice.upper() == \'Q\': break # 购买商品必须输入商品范围类的数字 if choice.isdigit() and 0 <= int(choice) < len(list_goods): num = input(\'\033[34;1m输入购买的数量:\033[0m\').strip() if num.isdigit(): num = int(num) else: print(\'\033[31;1m错误:数量必须是正整数.\033[0m\') # 获取用户输入的商品信息,并生成商品字典 good = {\'name\': list_goods[int(choice)][\'name\'], \'num\': num, \'total_prices\': list_goods[int(choice)][\'price\'] * num} # 获取用户的余额 money = user_dict[\'money\'] # 用户的余额 - 商品的总价 res_money = money - good[\'total_prices\'] if res_money >= 0: # 这里目前没有想到好的处理办法,只能使用标记来做判断 # 默认 flag 为 True,因为用户一次只能购买一件商品,如果用户购买的是重复的商品,就将购买过的商品信息合并, # 然后将 flag 设置为 False flag = True for i in list_shopping: if good[\'name\'] == i[\'name\']: i[\'num\'] += good[\'num\'] i[\'total_prices\'] += good[\'total_prices\'] flag = False # 当flag = True 说明用户没有购买重复的商品,添加新商品到购物清单;反之则购买了重复的商品 flag = False if flag: list_shopping.append(good) print(\'\033[32;1m购买成功!\033[0m\n\') print(\'\033[32;1m购物清单\033[0m\'.center(50, \'#\')) for i in list_shopping: print(\'商品名:%s\t数量:%s\t总价:%d元\' % (i[\'name\'], i[\'num\'], i[\'total_prices\'])) print(\'\033[33;1m您的余额为:%d元\033[0m\' % res_money) print(\'##########################################\n\') # 修改购物后的用户余额信息 user_dict[\'money\'] = res_money # 修改购物清单信息 user_dict[\'shopping_car\'] = list_shopping # 将修改后的数据写入数据文件 file_oper(user_dict[\'name\'] + \'.db\', \'wb\', user_dict) else: print(\'\033[31;1m错误:商品总价为:%d元,您的余额为:%d元,购物失败.\033[0m\' % (good[\'total_prices\'], money)) elif choice.upper() == \'T\': print(\'\033[32;1m购物清单\033[0m\'.center(50, \'#\')) for i in list_shopping: print(\'商品名:%s\t数量:%s\t总价:%d元\' % (i[\'name\'], i[\'num\'], i[\'total_prices\'])) print(\'\033[33;1m您的余额为:%d元\033[0m\' % user_dict[\'money\']) print(\'##########################################\n\') any = input(\'\033[34;1m任意键返回商品列表\033[0m\').strip() continue else: print(\'\033[31;1m错误:输入商品序号错误。\033[0m\') def start(list_goods): while True: print(\'1. 注册\n\' \'2. 登录\n\' \'3. 退出\') choice = input(\'>>>\').strip() if not choice: continue if choice.isdigit() and 0 < int(choice) < 4: if choice == \'1\': username = input(\'\033[34;1m输入用户名:\033[0m\').strip() password = input(\'\033[34;1m输入密码:\033[0m\').strip() user(username, password, \'regist\') elif choice == \'2\': username = input(\'\033[34;1m输入用户名:\033[0m\').strip() password = input(\'\033[34;1m输入密码:\033[0m\').strip() user_dict = user(username, password, \'login\') # 当 user(username, password, \'login\') 返回 None表示登录失败 if user_dict is None: continue # user_dict[\'stat\'] = 0 表示用户第一次登录,user_dict[\'stat\'] 非零则表示用户多次登录 if user_dict[\'stat\'] == 0: money = input(\'\033[34;1m首次登录,请输入充值金额:\033[0m\').strip() if money.isdigit(): # 这里无法判断小数类型 user_dict[\'money\'] = int(money) # 第一次登录设置成功金额后,将 stat 设置为非零 user_dict[\'stat\'] = 1 user_dict[\'shopping_car\'] = [] print(\'\033[32;1m恭喜:充值成功!\033[0m\') shopping(user_dict, list_goods) else: print(\'\033[31;1m错误:金额只能是正整数!\033[0m\') # user_dict[\'stat\'] = 0 表示用户第一次登录,user_dict[\'stat\'] 非零则表示用户多次登录 else: shopping(user_dict, list_goods) elif choice == \'3\': break else: print(\'\033[31;1m错误:序号输入错误.\033[0m\') if __name__ == \'__main__\': # 商品列表 list_goods = [ {\'name\': \'苹果\', \'price\': 10}, {\'name\': \'鸭梨\', \'price\': 20}, {\'name\': \'芒果\', \'price\': 30}, ] start(list_goods)
部分运行截图:
图1:
图2:
图3:
图4: