6.16自我總結
功能介紹程式功能介紹:
商品資訊再讀取修改買賣均已xlsx格式
且生成購物記錄也按/使用者名/購買時間.xlsx格式生成
賬号密碼輸入錯誤三次按照時間進行當機
使用者資訊已json格式儲存
程式寫的過程
先生成功能子產品和運作子產品
再寫功能子產品中用到的固定的檔案目錄全放在setting.py檔案中
與商品互動全放在shop.py中
與使用者互動全放在user.py中
一些傳回界面延遲動畫全放在輔助子產品中
1.程式設計目錄
思路生成xlsx文檔就要導入pands子產品
使用者資訊用josn儲存導入json子產品
把路徑什麼通用不變的丢入setting中
把所有檔案存取丢入接口層中api中
其他增減根據功能來
一些通用的方法可以全部放入common中
2.run.pyfrom core.src import run
if __name__ == '__main__':
run()
3.src.pyfrom 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)
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()
3.common.pyfrom 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'))
4.setting.pyimport 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')
5.shop.py
(商品資訊存儲檔案與功能子產品的互動)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)
6.user.py
(使用者資訊存儲檔案與功能子產品的互動)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'])
7.goods_info.xlsx/goods_info_patch.xlsx
蘋果香蕉西瓜荔枝梨價格231055
數量2002153432523