• ATM_购物车作业


    作业要求

    模拟实现一个ATM + 购物商城程序

    1. 额度 15000或自定义
    2. 实现购物商城,买东西加入 购物车,调用信用卡接口结账
    3. 可以提现,手续费5%
    4. 支持多账户登录
    5. 支持账户间转账
    6. 记录每月日常消费流水
    7. 提供还款接口
    8. ATM记录操作日志
    9. 提供管理接口,包括添加账户、用户额度,冻结账户等。。。
    10. 用户认证用装饰器

    作业流程图

     ATM_购物车程序目录

    ——————————————————————————————

    作业中应注意的问题和解决方法

    1.在创建用户文件的时候,要用json类型,这样可以避免用户信息修改的时候覆盖文件,导致其他的用户信息丢失。

    2.程序的主入口py文件,在主目录的下一级,这样可以方面调用每一个模块之中的函数。

    3.日志中的Formatter格式不要写死,可以在创建一个py文件,来进行调用。

    4.用户名和密码进行判断的时候,可以通过用户名等同于文件名,进行判断。

    5.创建setting文件的时候一定要不能随便更改其中的参数。

    6.在对文件进行读取的时候,要利用os.path.dirname返回到前两级的目录,以及os.path.abspath获取到绝对路径,这样才可以打开用户文件。

    7.在main.py的文件当中要尽量使用函数,这样可以减少代码的数量,增加可读性。

    ————————————————————————————————

    manage.json

    {"account":"manage","password":"1234","user":"manage"}
    

    atm_start.py

    #程序入口
    if __name__ == '__main__':
        from atm import exchange
        exchange.user_exchange()
    View Code

    shopping.py

    import json,os
    from tabulate import tabulate
    from atm.auth import userjudge
    from atm.logger import logger1
    from conf.settings import user_path
    from atm.conroller_class import user_file
    
    
    shopping_list = [
       ['1','Mac_pro','12000'] ,
       ['2','iphone','8000'],
       ['3','Mi_mix','5000']
    ]
    
    
    k = ["sum","goods","price"]
    print(tabulate(shopping_list, headers=k, tablefmt="grid"))
    print("33[32;1mq:退出进入结账模式33[0m")
    shopping_cart = [] #用户的购物列表
    
    def payment():
        """对结账用户进行认证, 成功后对用户的余额进行处理"""
        while True:
            username = input("Username:")
            password = input("Password:")
            f = userjudge(username,password)
            if f:
                money = []
                for i in shopping_cart:
                    i[2] = int(i[2])
                    money.append(i[2]) # 将商品价格 添加到列表当中
                money_add = sum(money)  # 商品总额
                # print(f)
                f["balance"] = f["balance"] - money_add
                print("33[31;1m-----支付成功-----33[0m")
                logger1.debug("用户%s支付成功"%username)
                user_file(f,username)
                exit()
            else:
                print("33[31;1m输入的用户名和密码错误33[0m")
    
    
    while True:
        user_choise = input(">>:")
        if user_choise.isdigit():
            user_choise = int(user_choise)
            if user_choise < len(shopping_list)+1 and user_choise >0:
                shopping_cart.append(shopping_list[user_choise-1])  # 将用户选择的商品 加入到proct中
                # print(shopping_cart)
                print("您购买的33[32;1m%s33[0m已加入到购物车"%shopping_list[user_choise-1][1])
            else:
                print("33[31;1m请输入正确的商品编号33[0m")
        elif user_choise == 'q':
            print("33[31;1m------Shopping cart list-----33[0m")
            print(tabulate(shopping_cart, headers=k, tablefmt="grid"))
            print("33[31;1m------用户登陆-----33[0m")
            payment() #调用结账函数 来进行支付
            break
    View Code

    main.py

    from conf.settings import main_path,user_path
    from .logger import logger,logger1
    from .auth import userjudge
    from .conroller_class import *
    
    
    info = """
    1.查看用户信息 view_account_info
    2.取现 with_draw
    3.还款 pay_back
    4.转账transfer
    """
    
    
    def login(conroller):
        def entrance():
            """ATM的交互入口"""
            user_entrance = {  # 存储账户的认证状态,和账户信息
                "user_status": False,
                'data': None
            }
            while user_entrance["user_status"] is not True:  # 如果用户没有认证则输入密码
                account = input("Username:")
                password = input("Password:")
                user_file = userjudge(account, password)# 通过userjudge函数 来判断用户和密码是否正确
                if user_file == None:
                    print("33[31;1m您输入用户或密码错误33[0m")
                elif user_file["state"] == 1:
                    if user_file:  # 如果用户存在
                        user_entrance["user_status"] = True  # 可以让认证后的用户,在user_entrance中体现出来
                        user_entrance['data'] = user_file  # 将用户文件,添加到'data'当中
                        print("33[31;1m--------------welcome--------------33[0m")
                        logger1.debug("用户%s登陆" % account)
    
                elif user_file["state"] == 0: #判断用户是否是锁定状态
                    print("33[31;1m----用户被冻结----33[0m")
                    exit()
            else:
                 conroller(account) #执行conroller函数
        return entrance
    
    @login
    def conroller(account):
        """功能分发器"""
        print(info) #打印功能列表
        while True:
            user_choise = input(">>(q退出):").strip()
            if user_choise.isdigit():
                user_choise = int(user_choise)
            if user_choise == 1:  # 信息查询
               view_account_info(user_path,account)
            elif user_choise == 2:# 取现
                with_draw(user_path,logger1,account)
            elif user_choise == 3:# 还款
                pay_back(user_path,logger1,account)
            elif user_choise == 4:# 转账
                transfer(user_path,logger1,account)
            elif user_choise == 'q':
                exit()
    View Code

    auth.py

    from .db_handler import user_file_manage
    
    def userjudge(account,password):
        """对用户信息进行验证"""
        account_data = user_file_manage(account) # 通过user_file_manage来获取到账户账户信息
        if account_data['status'] == 0:
            account_data = account_data['data']
            if password == account_data['password']:
                return account_data
            else:
                return None
        else:
            return None
    View Code

    db_handler.py

    import json,os
    import logging
    from conf.settings import main_path,user_path# 导入用户信息的上级目录 和绝对路径
    
    
    def user_file_manage(account):
        """根据account 取处理用户文件"""
        # print(main_path) #E:Moudule_1ATM_project
        # print(user_path) #E:Moudule_1ATM_projectaccount
        f = os.path.join(user_path,"%s.json"%account)# 读取用户全部信息
        if os.path.isfile(f):
            account_file = open(f)
            data = json.load(account_file)
           # print(data)
            account_file.close()
            return {'status':0,'data':data}
        else:
            return {'status':-1,'error':"账户不存在"}
    View Code

    setting.py

    import os,sys
    import logging
    from logging import handlers
    
    main_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 获取程序的绝对路径
    
    user_path = os.path.join(main_path,"account")# 指定目录和文件名
    
    ATM_formatter  = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %I:%M:%S')
    USER_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %I:%M:%S')
    View Code

    logger.py

    import os
    import logging
    from logging import handlers
    from conf.settings import user_path,main_path,ATM_formatter,USER_formatter
    
    logger = logging.getLogger("atm")
    logger.setLevel(logging.DEBUG)
    fh_atm = logging.handlers.TimedRotatingFileHandler(filename=os.path.join(main_path,"log/atm.log"),encoding="utf-8")
    logger.addHandler(fh_atm)
    atm_formatter = ATM_formatter
    fh_atm.setFormatter(atm_formatter)
    
    logger1 = logging.getLogger("user")
    logger1.setLevel(logging.DEBUG)
    fh_user = logging.handlers.TimedRotatingFileHandler(filename=os.path.join(main_path,"log/user.log"),encoding="utf-8")
    logger1.addHandler(fh_user)
    user_formatter = USER_formatter
    fh_user.setFormatter(user_formatter)
    View Code

    exchange.py

    from .auth import userjudge
    from .main import conroller
    from .atm_manage import manage_interface
    
    print("33[31;1m-----1:进入管理员模式-----33[0m")
    print("33[31;1m-----2:ATM机操作模式------33[0m")
    print("33[32;1m管理员账号:manage,密码:123433[0m")
    def user_exchange():
        """对管理员用户进行认证"""
        user_choise = input(">>:")
        while True:
            if user_choise == '1':
                print("33[31;1m-----管理员模式-----33[0m")
                username = input("33[31;1mUsername:33[0m")
                password = input("33[31;1mPassword:33[0m")
                manage_file = userjudge(username, password)  # 获取到管理员文件中的内容
                if manage_file:
                    # print(manage_file)
                    print("33[32;1m-----欢迎登陆-----33[0m")
                    manage_interface()
                else:
                    print("输入的用户名或者密码错误")
            elif user_choise == '2':
                conroller()  # 进入到ATM操作模式
                exit()
    View Code

    atm_manage.py

    import os,json
    
    
    
    from conf.settings import user_path
    from atm.logger import logger
    from .db_handler import user_file_manage
    from .conroller_class import user_file
    
    
    info = """
    1.添加账户
    2.用户额度
    3.冻结账户
    q(退出程序)
    """
    
    def manage_interface():
        """用于实现管理用户的接口"""
        while True:
            print(info)
            user_choise = input(">>:")
            if user_choise.isdigit():
                user_choise = int(user_choise)
            if user_choise == 1:
                add_user()
            elif user_choise == 2:
                user_lines()
            elif user_choise == 3:
                user_lock()
            elif user_choise == 'q':
                exit()
    
    def add_user():
        """添加用户"""
        username = input("username:") #用户名 == 文件名
        password = input("password:") #密码
        balance  = input("balance:")  #余额
        lines    = input("lines:")    #额度
        f = open(os.path.join(user_path, "%s.json"%username), 'w', encoding='utf-8')
        user_format ={"password":password,"balance":balance,"lines":lines,"state":1}
        json.dump(user_format,f)
        logger.debug("添加用户%s成功"%username)
        print("33[32;1m----添加成功----33[0m")
    
    def user_lines():
        """改变用户额度"""
        username  = input("username:") #文件名
        userfile = user_file_manage(username) # 获取到文件内容
        # print(user_file)
        if userfile['status'] == 0: #用户存在的话
            new_lines = input("new_lines:")#额度
            f = json.load(open(os.path.join(user_path, "%s.json"%username), 'r+', encoding='utf-8')) #读取用户信息
            f['lines'] = new_lines
            logger.debug("更改用户%s额度成功" % username)
            print("33[32;1m----用户额度更改成功----33[0m")
            user_file(f,username)
        else:
            print("33[32;1m用户名错误33[0m")
    
    def user_lock():
        """锁定用户,将用户状态 state:1 修改为 state:0"""
        print("33[31;1m----输入想要冻结的用户----33[0m")
        username = input("user:")
        f = json.load(open(os.path.join(user_path, "%s.json" % username), 'r+', encoding='utf-8'))  # 读取用户信息
        f['state'] = 0
        logger.debug("冻结用户%s成功" % username)
        print("33[31;1m----用户冻结成功----33[0m")
        user_file(f,username)
    View Code

    conroller_class.py

    import json,os
    from conf.settings import user_path
    
    info = """
    1.查看用户信息 view_account_info
    2.取现 with_draw
    3.还款 pay_back
    4.转账transfer
    """
    
    def user_file(user_data,account):
        """将修改后的用户信息 写入到对应文件当中
        """
        f = open(os.path.join(user_path, '%s.json'%account), 'w', encoding='utf-8') #
        f.seek(0)
        f.truncate()
        json.dump(user_data, f)
        f.close()
    
    def view_account_info(user_path,account):
        """查看用户信息"""
        user_data = json.load(open(os.path.join(user_path,"%s.json"%account),'r',encoding="utf-8"))#获取到用户信息
        print("33[32;1m用户余额:33[0m",user_data["balance"])
        print("33[32;1m用户密码:33[0m",user_data["password"])
    
    def with_draw(user_path,logger1,account):
        """取现"""
        cash_money = int(input("Input your cash money:"))
        user_data = json.load(open(os.path.join(user_path,"%s.json"%account),'r',encoding="utf-8"))#获取到用户信息
        if cash_money < int(user_data['lines']):
            user_data['balance'] = int(user_data['balance']) - cash_money * (1 - 0.05)
            print("33[31;1m-------取现成功-------33[0m")
            logger1.debug("用户%s取现金额%s"%(account,cash_money))
            user_file(user_data,account) #通过user_file函数来 将用户信息写到文件当中
        else:
            print("33[32;1m提现金额超出信用额度!33[0m")
    
    def pay_back(user_path,logger1,account):
        """还款"""
        refund_money = input("Input your refund money:")
        user_data = json.load(open(os.path.join(user_path,"%s.json"%account),'r',encoding="utf-8"))
        user_data['balance'] = int(user_data['balance']) + int(refund_money)
        print("33[31;1m-------还款成功-------33[0m")
        logger1.debug("用户%s还款金额%s"%(account,refund_money))
        user_file(user_data,account)
    
    def transfer(user_path,logger1,account):
        """转账"""
        while True:
            transfer_user = input("Input accout(q退出):") #转账的用户
            f = os.path.join(user_path,"%s.json"%transfer_user)
            if transfer_user == 'q':
                exit()
            if os.path.isfile(f): #判断文件是否存在
                transfer_money = input("Input your transfer money:")
                user_data = json.load(open(os.path.join(user_path,"%s.json"%account),'r',encoding="utf-8")) #当前账户
                transfer_user_file = json.load(open(f)) #取出转账用户的信息
                transfer_user_file['balance'] =  int(transfer_user_file['balance']) + int(transfer_money)
                user_file(transfer_user_file,transfer_user) #通过user_file函数来 将转账用户信息写到文件当中
                print("33[31;1m-------转账成功-------33[0m")
                logger1.debug("用户%s给用户%s转账金额%s"%(account,transfer_user,transfer_money))
            else:
                print("33[31;1m输入的用户错误,请重新输入33[0m")
    View Code

    atm.log

    2018-03-14 10:34:02 - atm - DEBUG - 添加用户1成功
    2018-03-14 10:34:11 - atm - DEBUG - 更改用户1额度成功
    2018-03-14 10:34:16 - atm - DEBUG - 冻结用户1成功
    2018-03-14 10:35:34 - atm - DEBUG - 更改用户1额度成功
    

    user.log

    2018-03-14 10:34:53 - user - DEBUG - 用户1234登陆
    2018-03-14 10:34:59 - user - DEBUG - 用户1234取现金额100
    2018-03-14 10:35:01 - user - DEBUG - 用户1234还款金额100
    2018-03-14 10:35:07 - user - DEBUG - 用户1234给用户1转账金额10
    

      

  • 相关阅读:
    【林】Ubuntu下安装和设置 OpenSSH Server
    吐吐槽
    【不定时推荐】这些年读过的书第一本--《一个人的朝圣》
    source insight 和keil 编辑对齐
    WeifenLuo DockContent停靠窗口的大小设置
    指针无法保存值
    php 练习基础
    php 写日志
    数据库设计——字段类型设计
    .net用TreeView实现CheckBoxes全选 反选 子节选中 传值
  • 原文地址:https://www.cnblogs.com/Mryang123/p/8570055.html
Copyright © 2020-2023  润新知