程序功能介紹: 商品信息再讀取修改買賣均已xlsx格式 且生成購物記錄也按/用戶名/購買時間.xlsx格式生成 帳號密碼輸入錯誤三次按照時間進行凍結 用戶信息已json格式保存 程序寫的過程 先生成功能模塊和運行模塊 再寫功能模塊中用到的固定的文件目錄全放在setting.py文件中 與商品交互全放在shop.py中 與用戶交互全放在user.py中 一些返回界面延遲動畫全放在輔助模塊中
run.py
from core.src import run if __name__ == '__main__': run()
src.py
from conf.setting import * from lib.common import * from api.user import * from api.shop import * import re import numpy as np goods_count = [1] #註冊 def register(): print('\033[47;;m\t\t歡迎使用註冊功能\t\t\033[0m') count = 0 while count == 0: register_name = input('請輸入名字按Q退出程序\n' '\033[31;;m帳號由漢字,字母,數字,下劃線組成\033[0m' '\n請輸入:') if register_name == 'Q': go_to_run() return False if decide_user_name(register_name): print('\033[31;;m帳號存在\033[0m') continue register_name_1 = re.findall('\w+',register_name) if len(register_name) == 0: print('\033[31;;m請好好輸入\033[0m') continue elif register_name_1[0] != register_name: print('\033[31;;m帳號由漢字,字母,數字,下劃線組成\033[0m') continue else: count =1 while True: register_pwd = input('請輸入密碼按Q退出程序\n' '\033[31;;m密碼由漢字,字母,數字,下劃線組成\033[0m\n' '請輸入') if register_pwd == 'Q': go_to_run() return False register_pwd_1 = re.findall('\w+', register_pwd) if len(register_pwd) == 0: print('\033[31;;m請好好輸入\033[0m') continue elif register_pwd_1[0] != register_pwd: print('\033[31;;m密碼由漢字,字母,數字,下劃線組成\033[0m') continue else: save_info(register_name, register_pwd) print('\033[32;;m註冊成功\033[0m') go_to_run() return True #登入 def login(): print('\033[47;;m\t\t歡迎使用登入功能\t\t\033[0m') if not LOGIN_NAME[0]: pwd_count =0 login_count = 0 while login_count==0: login_name = input('請輸入名字按Q退出程序\n請輸入:') if login_name == 'Q': go_to_run() return False if not decide_user_name(login_name): print('\033[31;;m帳號不存在\033[0m') continue if not load_freeze_user(login_name): go_to_run() return False else: login_count = 1 while pwd_count<3: login_pwd = input('\033[41;;m請輸入密碼輸錯三次會被凍結五分鐘\033[0m\n請輸入:') if not load_info(login_name,login_pwd): pwd_count +=1 print(f'\033[31;;m還有{3-pwd_count}次機會\033[0m') continue else: print('\033[32;;m登入成功\033[0m') LOGIN_NAME[0] = login_name go_to_run() return True if pwd_count == 3: freeze_user(login_name) print(f'\033[31;;m帳號{login_name}因爲密碼輸入太屢次暫時被凍結\033[0m') go_to_run() return False else: print(f'\033[32;;m帳號{LOGIN_NAME[0]}以及登入') login_chiose = input('輸入0爲退出當前程序\n' '輸入1爲退出當前帳號從新登入\n' '輸入2爲退出當前帳號並退出程序\n' '請選擇:') if login_chiose not in ['0','1','2']: print('\033[31;;m請好好輸入\033[0m') elif login_chiose == '0': go_to_run() return False elif login_chiose == '1': df = load_goods_pach() dump_goods(df) LOGIN_NAME[0] = None login() elif login_chiose == '2': df = load_goods_pach() dump_goods(df) LOGIN_NAME[0] = None print('\033[41;;m帳號以退出\033[0m') go_to_run() return False #充值 @login_deco def top_up(): print('\033[47;;m\t\t歡迎使用充值功能\t\t\033[0m') while True: chiose = input('請輸入充值金額\n輸入Q退出功能\n請輸入') if chiose == 'Q': go_to_run() return False elif not chiose.isdigit(): print('\033[31;;m請輸入阿拉伯數字\033[0m') continue else: info = load_login_info(LOGIN_NAME[0]) info["balance"] += int(chiose) dump_login_info(LOGIN_NAME[0],info) print(f'\033[42;;m帳號{LOGIN_NAME[0]}充值成功\n當前餘額{info["balance"]}元\033[0m') go_to_run() return True #餘額查詢 @login_deco def balance(): print('\033[47;;m\t\t歡迎使用餘額查詢功能\t\t\033[0m') info = load_login_info(LOGIN_NAME[0]) print(f'\033[42;;m帳號{LOGIN_NAME[0]}\n當前餘額{info["balance"]}\033[0m') go_to_run() return True #提現 @login_deco def withdraw(): print('\033[47;;m\t\t歡迎使用提現功能\t\t\033[0m') while True: chiose = input('\033[32;;m請輸入提現金額\n輸入Q退出功能\n請輸入') if chiose == 'Q': go_to_run() return False elif not chiose.isdigit(): print('\033[31;;m請輸入阿拉伯數字\033[0m') continue else: info = load_login_info(LOGIN_NAME[0]) if info["balance"] < int(chiose): print('\033[31;;m餘額不足\033[0m') continue info["balance"] -= int(chiose) dump_login_info(LOGIN_NAME[0],info) print(f'\033[41;;m帳號{LOGIN_NAME[0]}提現成功\n當前餘額{info["balance"]}元\033[0m') go_to_run() return True #轉帳 @login_deco def transfer(): print('\033[47;;m\t\t歡迎使用轉帳功能\t\t\033[0m') count = 0 while count ==0: chiose = input('\033[32;;m請輸入轉帳金額\n輸入Q退出功能\n請輸入') if chiose == 'Q': go_to_run() return False elif not chiose.isdigit(): print('\033[31;;m[請輸入阿拉伯數字\033[0m') continue else: info = load_login_info(LOGIN_NAME[0]) if info["balance"] < int(chiose): print('\033[31;;m餘額不足\033[0m') continue info["balance"] -= int(chiose) while True: count =1 transfer_name = input('\033[32;;m轉帳的名字\n輸入Q退出') if transfer_name == 'Q': go_to_run() return False if not decide_user_name(transfer_name): print('\033[31;;m轉帳帳號不存在\033[0m') continue if LOGIN_NAME[0] == transfer_name: print('\033[31;;m不能轉給本身\033[0m') continue transfer_name_info = load_login_info(transfer_name) transfer_name_info["balance"] += int(chiose) dump_login_info(transfer_name, transfer_name_info) dump_login_info(LOGIN_NAME[0], info) print(f'\033[42;;m帳號{LOGIN_NAME[0]}轉帳成功\n當前餘額{info["balance"]}元\033[0m') go_to_run() return True #流水 @login_deco def user_history(): print('\033[47;;m\t\t歡迎使用流水功能\t\t\033[0m') if not history(LOGIN_NAME[0]): print('\033[31;;m沒有購買記錄\033[0m') go_to_run() return False while True: date_lis = show_history(LOGIN_NAME[0]) chiose = input('\033[32;;m請輸入你要查看的日期\n' '輸入Q退出') if chiose not in date_lis: print('\033[31;;m沒有日期\033[0m') continue print(f'{chiose}') print(load_goods_history(LOGIN_NAME[0],chiose)) history_count = 0 while history_count == 0: next_chiose = input('\033[32;;m請輸入Y繼續查看的日期\n' '輸入Q退出\n' '請輸入') if next_chiose not in ('Y','Q'): print('\033[31;;m請好好輸入\033[0m') elif next_chiose == 'Y': history_count =1 elif next_chiose =='Q': go_to_run() return False #購物 @login_deco def shopping(): count = 0 chiose_count =0 print('\033[47;;m\t\t歡迎使用購物功能\t\t\033[0m') global goods_count while count == 0: if not goods_count[0]: df = load_goods() print('\t\t\t商品目錄') print(f'\033[35;36;m{df}\033[0m') else: df = load_goods_pach() print('\t\t\t商品目錄') print(f'\033[35;36;m{df}\033[0m') goods = input('\033[32;;m請選擇你的商品\n' '輸入Q退出\n' '請選擇') goods_list = df.columns if goods == 'Q': go_to_run() return False elif goods not in goods_list: print('\033[31;;m無此商品\033[0m') continue else: chiose_count =0 while chiose_count == 0: num = input('\033[32;;m請選擇你的商品數量\n' '輸入Q退出\n' '請選擇') goods_num = df[goods]['數量'] if goods == 'Q': go_to_run() return False elif not num.isdigit(): print('\033[31;;m請輸入數字\033[0m') continue elif int(goods_num)<int(num): print('\033[31;;m庫存不足\033[0m') else: df[goods]['數量'] -= int(num) goods_num = int(num) dump_goods_pach(df) print(f'\033[42;;m你把{goods}{num}個加入購物車\033[0m') while chiose_count == 0: chiose =input('\033[32;;m是否繼續購物\n' 'Y是繼續,N是退出\n' '請選擇') if chiose not in ['Y','N']: print('\033[31;;m請好好輸入\033[0m') continue if chiose == 'N': goods_count[0] = 1 go_to_run() return True if chiose == 'Y': chiose_count = 1 goods_count[0] = 1 pass #購物車 @login_deco def shopping_car(): print('\033[47;;m\t\t歡迎使用購物車功能\t\t\033[0m') global goods_count if not goods_count[0]: print('\033[31;;m購物車無商品\033[0m') else: df_1 = load_goods() df_2 = load_goods_pach() df = df_1 - df_2 print('-'*50) print('\t\t\t購物車目錄') print(f'\033[35;36;m{df}\033[0m') df_mun = df.values[1,:] df_pice = df_1.values[0,:] df_add = df_mun*df_pice money = sum(df_add) print(f'合計{money}元') print('-' * 50) while True: chiose = input('\033[32;;m輸入Q退出程序\n' '輸入0清空購物車並退出程序\n' '輸入1結算\n' '請選擇') if chiose not in ['Q','0','1']: print('\033[31;;m請好好輸入\033[0m') continue elif chiose == 'Q': go_to_run() return False elif chiose == '0': goods_count[0] = None df_new = load_goods() dump_goods_pach(df_new) go_to_run() return False elif chiose == '1': info = load_login_info(LOGIN_NAME[0]) if int(money) > info['balance']: print('\033[31;;m餘額不足\033[0m') continue else: print('\033[41;;m支付成功\033[0m') info['balance'] -= int(money) dump_login_info(LOGIN_NAME[0],info) df_new = load_goods_pach() dump_goods(df_new) df_mun = df[1:2] df_pice = df_1[0:1] df = df.columns new_df = df_pice.append(df_mun) print(new_df) time =time_strftime() dump_goods_history(LOGIN_NAME[0],time,new_df) go_to_run() return True #運行模塊 def run(): action_dict={ '0':register, '1':login, '2':top_up, '3':balance, '4':withdraw, '5':transfer, '6':user_history, '7':shopping, '8':shopping_car, } while True: if LOGIN_NAME[0]: print(f'你好{LOGIN_NAME[0]}') for action_num,action in ACTION_INFO.items(): print(f'\033[35;;m\t\t輸入{action_num}功能爲{action}\033[0m') action_chiose = input('\033[32;;m請輸入你要選擇的功能:') if action_chiose == 'Q': print('退出程序') return if action_chiose not in action_dict: print('\033[31;;m輸入錯誤\033[0m') continue action_dict[action_chiose]() if __name__ == '__main__': run()
common.py
from conf.setting import * import time def login_deco(func): def wrapper(*args,**kwargs): if not LOGIN_NAME[0]: print('請先登入') go_to_run() return False func() return True return wrapper def go_to_run(): for a in range(20): time.sleep(0.1) txt = '\t\t返回主界面中' txt += '.'*int(a%4) print('\r',f'\033[32;;m{txt}\033[0m',end='') print('') def time_now(): return time.time() def time_strftime(): return str(time.strftime('%Y-%m-%d-%H-%M-%S'))
setting.py
import os import time ACTION_INFO={ '0':'註冊', '1':'登入', '2':'充值', '3':'餘額查詢', '4':'提現', '5':'轉帳', '6':'購物歷史記錄', '7':'購物', '8':'購物車', 'Q' :'退出' } LOGIN_NAME = [None] ATM_PATH = os.path.dirname(os.path.dirname(__file__)) USER_PATH = os.path.join(ATM_PATH,'db') GOODS_PATH = os.path.join(ATM_PATH,'db','goods_info.xlsx') GOODS_PATCH = os.path.join(ATM_PATH,'db','goods_info_patch.xlsx')
shop.py
(商品信息存儲文件與功能模塊的交互)python
import pandas as pd from conf.setting import GOODS_PATH,GOODS_PATCH import os def dump_goods(df): df.to_excel(GOODS_PATH) def dump_goods_pach(df): df.to_excel(GOODS_PATCH) def load_goods(): df = pd.read_excel(GOODS_PATH,index_col=0,header=0) return df def load_goods_pach(): df = pd.read_excel(GOODS_PATCH,index_col=0,header=0) return df def dump_goods_history(name,time,df): path_1 = os.path.join(r'E:\ATM\db', name) path = os.path.join(r'E:\ATM\db',name,f'{time}.xlsx') if not os.path.exists(path_1): os.mkdir(path_1) df.to_excel(path) def load_goods_history(name,time): path = os.path.join(r'E:\ATM\db', name, f'{time}.xlsx') df = pd.read_excel(path,index_col=0,header=0) return df def show_history(name): new_list =[] path_1 = os.path.join(r'E:\ATM\db', name) lis = os.listdir(path_1) print('\033[46;;m提示:年-月-日-時-分-秒\033[0m') for info in lis: info = info[0:-5] print(info) new_list.append(info) return new_list def history(name): path_1 = os.path.join(r'E:\ATM\db', name) if os.path.exists(path_1): return True return False if __name__ == '__main__': df = load_goods_pach() print(df)
user.py
(用戶信息存儲文件與功能模塊的交互)ios
from conf.setting import * import json import hashlib from lib.common import time_now def save_info(user_name,pwd): m = hashlib.md5() m.update(pwd.encode('utf8')) pwd =m.hexdigest() user_path = os.path.join(USER_PATH, f'{user_name}.json') with open(user_path,'w',encoding='utf8') as fw: info_dict = {'name':user_name,'pwd':pwd,'freeze':time_now(),'balance':0,'freeze_count':0} json.dump(info_dict,fw) def load_info(user_name,pwd): user_path = os.path.join(USER_PATH, f'{user_name}.json') if not LOGIN_NAME[0]: if not os.path.exists(user_path): print('\033[31;;m用戶不存在\033[0m') return False m = hashlib.md5() m.update(pwd.encode('utf8')) pwd =m.hexdigest() with open(user_path, 'r', encoding='utf8') as fr: info_dict = json.load(fr) if info_dict.get('pwd') != pwd: print('\033[31;;m密碼錯誤\033[0m') return False with open(user_path, 'r', encoding='utf8') as fr: info_dict = json.load(fr) info_dict['freeze_count'] = 0 with open(user_path, 'w', encoding='utf8') as fw: json.dump(info_dict,fw) return info_dict def decide_user_name(user_name): user_path = os.path.join(USER_PATH, f'{user_name}.json') if os.path.exists(user_path): return True return False def freeze_user(user_name): user_path = os.path.join(USER_PATH, f'{user_name}.json') with open(user_path, 'r', encoding='utf8') as fr: info_dict = json.load(fr) info_dict['freeze_count'] += 1 info_dict['freeze'] = time_now() + 300*info_dict['freeze_count'] with open(user_path,'w',encoding='utf8') as fw: json.dump(info_dict,fw) def load_freeze_user(user_name): user_path = os.path.join(USER_PATH, f'{user_name}.json') with open(user_path, 'r', encoding='utf8') as fr: dict = json.load(fr) if time_now() >= dict['freeze'] : print('\033[32;;m帳號登入成功\033[0m') return True else: min = int(divmod(-time_now() + dict['freeze'], 60)[0]) s = int(divmod(-time_now() + dict['freeze'], 60)[1]) print(f'\033[31;;m帳號{user_name}已被凍結,還須要{min}分{s}秒\033[0m') return False def load_login_info(name): login_user_path = os.path.join(USER_PATH, f'{name}.json') with open(login_user_path, 'r', encoding='utf8') as fr: info_dict = json.load(fr) return info_dict def dump_login_info(name,dict): login_user_path = os.path.join(USER_PATH, f'{name}.json') with open(login_user_path, 'w', encoding='utf8') as fw: json.dump(dict,fw) return True if __name__ == '__main__': save_info('楊文益','12312') dict = load_info('楊文益','12312') print(dict['name'])
蘋果 | 香蕉 | 西瓜 | 荔枝 | 梨 | |
---|---|---|---|---|---|
價格 | 2 | 3 | 10 | 5 | 5 |
數量 | 200 | 215 | 34 | 32 | 523 |