練手小程序用了pandas模塊和json模塊以及time模塊

6.16自我總結

功能介紹

程序功能介紹:
    商品信息再讀取修改買賣均已xlsx格式
    且生成購物記錄也按/用戶名/購買時間.xlsx格式生成
    帳號密碼輸入錯誤三次按照時間進行凍結
    用戶信息已json格式保存
 程序寫的過程
先生成功能模塊和運行模塊
再寫功能模塊中用到的固定的文件目錄全放在setting.py文件中
與商品交互全放在shop.py中
與用戶交互全放在user.py中
一些返回界面延遲動畫全放在輔助模塊中

1.程序設計目錄

2.run.py

from core.src import run
if __name__ == '__main__':
    run()

3.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()

3.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'))

4.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')

5.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)

6.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'])

7.goods_info.xlsx/goods_info_patch.xlsx

蘋果 香蕉 西瓜 荔枝
價格 2 3 10 5 5
數量 200 215 34 32 523
相關文章
相關標籤/搜索