ATM+購物商城

需求
模擬實現一個ATM + 購物商城程序

額度 15000或自定義
實現購物商城,買東西加入 購物車,調用信用卡接口結賬
支持多賬戶登錄
支持賬戶間轉賬
記錄每月日常消費流水
提供還款接口
ATM記錄操作日誌
提供管理接口,包括添加賬戶、用戶額度,凍結賬戶等。。。
用戶認證用裝飾器


測試信息
ATM.py              主腳本

以下文件需提前創建
db.txt              用戶名密碼認證文件
                    {'admin': '000','lyndon': '123', 'egon': '456', 'alex': '789'}
assest.txt          用戶資產信息  #用戶初始額度爲15000,admin管理員沒有資產記錄
                    {'lyndon': ['15000', '15000'], 'egon': ['15000', '15000'], 'alex': ['15000', '15000']}
frozen_user.txt     凍結賬戶文件
op.log              admin操作記錄(添加用戶、凍結賬戶、調整額度)
flow.log            賬戶流水記錄(商城結算、信用卡還款、轉賬)


wKiom1l6GvageiZ2AAGZT2aZ-5U801.png

import os,time      # 導入所使用的模塊
current_user={'user':None}      # 全局字典控制二次認證免密碼登錄
def auth(func):     # 認證函數
    def wrapper(*args,**kwargs):
        if current_user['user']:        # 判斷是否已認證
            return func(*args,**kwargs)
        print('請輸入你要登錄的賬號')
        name=input('input your name:').strip()
        passwd=input('input your password:').strip()
        with open('frozen_user.txt','r',encoding='utf-8') as f:     # 判斷是否在凍結賬戶文件中
            for i in f.readlines():
                if name in i:
                    print('賬戶已凍結')
                    return op()
        with open('db.txt','r',encoding='utf-8') as f_read:     # 進行用戶名密碼認證
            user_dic=eval(f_read.read())
        if name == 'admin' and passwd == user_dic[name]:        # 判斷是否爲admin用戶登錄
            current_user['user'] = name
            return admin()
        if name in user_dic and passwd == user_dic[name]:
            current_user['user'] = name
            res=func(*args,**kwargs)
            return res
        else:
            print('name or password error!')
            exit()
    return wrapper

@auth
def op():           #主菜單
    print('''
    【1】     購物商城
    【2】     ATM管理
    【3】     切換賬號
    【4】     退出
    ''')
    chooise=input('請輸入你的選擇:').strip()
    if chooise == '1':
        return shop()
    elif chooise == '2':
        return atm(current_user['user'])
    elif chooise == '3':
        current_user['user']=None       # 選擇切換賬號時重置全局變量
        return op()
    elif chooise == '4':
        exit()
    else:
        print('輸入錯誤,請重新輸入')
        return op()

def atm(user):       #ATM管理
    if user == 'admin':
        return admin()
    else:
        print('''
        【1】     還款
        【2】     轉賬
        【3】     返回主菜單
        ''')
        choice=input('請輸入你的選擇:').strip()
        if choice == '1':
            return repayment()
        elif choice == '2':
            return transfer()
        elif choice == '3':
            return op()
        else:
            print('輸入錯誤,重新輸入')
            return atm(user)

def shop():         #購物商城
    goods ={'電腦': 2000,'鼠標': 10,'遊艇': 20,'美女': 998}
    goods_list =[]
    moneys=0
    tag=1
    while tag == 1:
        for key,value in goods.items():
            print(key,value)
        choice=input('請輸入要購買的商品名稱:').strip()
        if choice not in goods:
            print('商品不存在,請重新輸入')
            continue
        count = input('輸入購買數量: ').strip()
        if count.isdigit():
            goods_list.append((choice, goods[choice], int(count)))
            money=int(goods[choice])*int(count)
            moneys=moneys+money
            print('當前購物車:%s' %goods_list)
            while tag == 1:
                choices=input('''
                【1】     繼續購買
                【2】     結算
                【3】     退回主菜單
                請選擇:''').strip()
                if choices == '1':break
                elif choices == '3':
                    op()
                    tag=0
                elif choices == '2':
                    checkout(moneys,goods_list)     #調用結算函數時傳入錢數和購物車商品
                    tag=0
                else:
                    print('輸入錯誤')
                    continue
        else:
            print('輸入錯誤,請重新購買')
            continue

def checkout(nums,goods):         # 購物商城下結算
    with open('assets.txt','r',encoding='utf-8') as f_read:
        with open('assets.swap.txt','w+',encoding='utf-8') as f_write:
            money_dic=eval(f_read.read())
            money=money_dic[current_user['user']][0]        # 判斷錢數與額度的大小,用戶資產使用字典嵌套
            if int(nums) > int(money):
                print('餘額不足,請重新購買')
                goods=[]
                shop()
            money_dic[current_user['user']][0]=str(int(money) - int(nums))
            s=str(money_dic)
            f_write.writelines(s)
    os.remove('assets.txt')
    os.rename('assets.swap.txt', 'assets.txt')
    print('購買成功,當前餘額爲:%s' %money_dic[current_user['user']][0])
    start=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
    with open('flow.log','a',encoding='utf-8') as f:        # 寫入流水日誌
        f.write('%s %s 購買物品 %s 支出%s,餘額%s\n' %(start,current_user['user'],goods,nums,money_dic[current_user['user']][0]))
    return shop()

def repayment():        #信用卡管理下還款
    with open ('assets.txt','r',encoding='utf-8') as f_read:
        money_dic = eval(f_read.read())
        money=money_dic[current_user['user']][0]
        quot=money_dic[current_user['user']][1]
        owe=(int(quot) - int(money))
    if owe <= 0:
        print('當前餘額爲 %s 不需要還款。' %money)
    else:
        print('當前賬單爲:%s' %owe)
        re=input('輸入還款金額:').strip()
        if re.isdigit() and len(money) != 0 :
            with open('assets.swap.txt', 'w+', encoding='utf-8') as f_write:
                money_dic[current_user['user']][0] = str(int(money) + int(re))
                s = str(money_dic)
                f_write.writelines(s)
            print('還款成功,當前餘額爲:%s' %money_dic[current_user['user']][0])
            start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
            with open('flow.log', 'a', encoding='utf-8') as f:
                f.write('%s %s 主動還款%s 餘額%s\n' % (start, current_user['user'], re, money_dic[current_user['user']][0]))
        else:
            print('輸入金額錯誤,請重新輸入')
            repayment()
    os.remove('assets.txt')
    os.rename('assets.swap.txt', 'assets.txt')

def transfer():         #ATM管理下轉賬
    with open ('assets.txt','r',encoding='utf-8') as f_read:
        money_dic = eval(f_read.read())
        money=money_dic[current_user['user']][0]
        print('當前賬戶餘額爲:%s' %money)
    other=input('轉入賬戶:').strip()
    tran_money=input('轉入金額:').strip()
    if other in money_dic and tran_money.isdigit() and len(tran_money) != 0:
        with open('assets.swap.txt', 'w+', encoding='utf-8') as f_write:
            money_dic[current_user['user']][0] = str(int(money) - int(tran_money))
            other_money = money_dic[other][0]
            money_dic[other][0] = str(int(other_money) + int(tran_money))
            s = str(money_dic)
            f_write.writelines(s)
        os.remove('assets.txt')
        os.rename('assets.swap.txt', 'assets.txt')
        print('轉賬成功,當前餘額爲:%s' % money_dic[current_user['user']][0])
        start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        with open('flow.log', 'a', encoding='utf-8') as f:
            f.write('%s %s 向 %s 轉賬%s 餘額%s\n' % (start,current_user['user'],other,tran_money,money_dic[current_user['user']][0]))
    else:
        print('帳戶不存在、已凍結或輸入金額有誤')
        transfer()

def admin():            #ATM管理下管理員操作
    print('''
    【1】     添加賬戶
    【2】     調整額度
    【3】     凍結賬戶
    【4】     退出管理
    ''')
    choice=input('請輸入你的選擇:').strip()
    if choice == '1':
        user_add()
    elif choice == '2':
        adjustment()
    elif choice == '3':
        frozen()
    elif choice == '4':
        current_user['user']=None
        op()
    else:
        print('輸入錯誤,重新輸入:')
        admin()

def user_add():         #admin管理接口下添加用戶
    with open('db.txt', 'r', encoding='utf-8') as f_read:
        user_dic = eval(f_read.read())
    user_name=input('創建用戶名:').strip()
    user_passwd=input('設置密碼:').strip()
    passwd_ag=input('確認密碼:').strip()
    if user_name not in user_dic and user_passwd == passwd_ag:
        user_dic[user_name]=user_passwd
        user_list=str(user_dic)
        with open('db.txt','w',encoding='utf-8') as f:
            f.write(user_list)
        with open('assets.txt','r',encoding='utf-8') as f1:
            with open('assets.swap.txt','w',encoding='utf-8') as f2:
                money_dic = eval(f1.read())
                money_dic[user_name]=['15000','15000']      #添加用戶時,設置初始額度爲15000
                s=str(money_dic)
                f2.write(s)
                print('%s 用戶已添加' %user_name)
                start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                with open('op.log', 'a', encoding='utf-8') as f3:
                    f3.write('%s %s 添加賬戶:%s 密碼:%s\n' % (start, current_user['user'], user_name,user_passwd))
    else:
        print('用戶名已存在或兩次輸入密碼不一致')
        admin()
    os.remove('assets.txt')
    os.rename('assets.swap.txt', 'assets.txt')
    admin()

def adjustment():       #admin管理接口下調整額度
    with open ('assets.txt','r',encoding='utf-8') as f_read:
        money_dic = eval(f_read.read())
        adjust_user = input('請輸入需要調整的賬戶:').strip()
        quot=money_dic[adjust_user][1]
        if adjust_user not in money_dic:
            print('用戶不存在')
            return admin()
        else:
            print('%s 當前額度爲 %s' %(adjust_user,quot))
            adjust_quot=input('調整爲:').strip()
            if adjust_quot.isdigit() and len(adjust_user) != 0:
                with open('assets.swap.txt', 'w+', encoding='utf-8') as f_write:
                    money_dic[adjust_user][0]=str(int(money_dic[adjust_user][0]) + int(adjust_quot) - int(quot))
                    money_dic[adjust_user][1] = adjust_quot
                    s=str(money_dic)
                    f_write.writelines(s)
                    print('%s 調整額度成功,當前額度爲:%s' %(adjust_user,money_dic[adjust_user][1]))
                    start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                    with open('op.log', 'a', encoding='utf-8') as f:
                        f.write('%s %s 調整 %s 額度由%s ---> %s\n' % (start, current_user['user'], adjust_user,quot,money_dic[adjust_user][1]))
            else:
                print('輸入金額錯誤')
                admin()
    os.remove('assets.txt')
    os.rename('assets.swap.txt', 'assets.txt')
    admin()

def frozen():           # admin管理接口下凍結賬戶(已知bug爲如果輸入爲已凍結賬號會重新凍結)
    frozen_name=input('請輸入你要凍結的賬戶名(admin無法凍結):').strip()
    with open('db.txt','r',encoding='utf-8') as f_read:
        user_dic = eval(f_read.read())
    if frozen_name in user_dic and frozen_name != 'admin':
        with open('frozen_user.txt','a',encoding='utf-8') as f_write:
            print('%s 賬號已凍結' % frozen_name)
            f_write.write('%s\n' % frozen_name)
        start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        with open('op.log', 'a', encoding='utf-8') as f:
            f.write('%s %s 凍結賬戶 %s\n' % (start,current_user['user'],frozen_name))
        admin()
    else:
        print('賬戶不存在')
        return frozen()

op()


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章