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("\033[32;1mq:退出进入结账模式\033[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("\033[31;1m-----支付成功-----\033[0m")
            logger1.debug("用户%s支付成功"%username)
            user_file(f,username)
            exit()
        else:
            print("\033[31;1m输入的用户名和密码错误\033[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("您购买的\033[32;1m%s\033[0m已加入到购物车"%shopping_list[user_choise-1][1])
        else:
            print("\033[31;1m请输入正确的商品编号\033[0m")
    elif user_choise == 'q':
        print("\033[31;1m------Shopping cart list-----\033[0m")
        print(tabulate(shopping_cart, headers=k, tablefmt="grid"))
        print("\033[31;1m------用户登陆-----\033[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("\033[31;1m您输入用户或密码错误\033[0m")
            elif user_file["state"] == 1:
                if user_file:  # 如果用户存在
                    user_entrance["user_status"] = True  # 可以让认证后的用户,在user_entrance中体现出来
                    user_entrance['data'] = user_file  # 将用户文件,添加到'data'当中
                    print("\033[31;1m--------------welcome--------------\033[0m")
                    logger1.debug("用户%s登陆" % account)

            elif user_file["state"] == 0: #判断用户是否是锁定状态
                print("\033[31;1m----用户被冻结----\033[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_1\ATM_project
    # print(user_path) #E:\Moudule_1\ATM_project\account
    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("\033[31;1m-----1:进入管理员模式-----\033[0m")
print("\033[31;1m-----2:ATM机操作模式------\033[0m")
print("\033[32;1m管理员账号:manage,密码:1234\033[0m")
def user_exchange():
    """对管理员用户进行认证"""
    user_choise = input(">>:")
    while True:
        if user_choise == '1':
            print("\033[31;1m-----管理员模式-----\033[0m")
            username = input("\033[31;1mUsername:\033[0m")
            password = input("\033[31;1mPassword:\033[0m")
            manage_file = userjudge(username, password)  # 获取到管理员文件中的内容
            if manage_file:
                # print(manage_file)
                print("\033[32;1m-----欢迎登陆-----\033[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("\033[32;1m----添加成功----\033[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("\033[32;1m----用户额度更改成功----\033[0m")
        user_file(f,username)
    else:
        print("\033[32;1m用户名错误\033[0m")

def user_lock():
    """锁定用户,将用户状态 state:1 修改为 state:0"""
    print("\033[31;1m----输入想要冻结的用户----\033[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("\033[31;1m----用户冻结成功----\033[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("\033[32;1m用户余额:\033[0m",user_data["balance"])
    print("\033[32;1m用户密码:\033[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("\033[31;1m-------取现成功-------\033[0m")
        logger1.debug("用户%s取现金额%s"%(account,cash_money))
        user_file(user_data,account) #通过user_file函数来 将用户信息写到文件当中
    else:
        print("\033[32;1m提现金额超出信用额度!\033[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("\033[31;1m-------还款成功-------\033[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("\033[31;1m-------转账成功-------\033[0m")
            logger1.debug("用户%s给用户%s转账金额%s"%(account,transfer_user,transfer_money))
        else:
            print("\033[31;1m输入的用户错误,请重新输入\033[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

  

 

posted @ 2018-03-14 20:53  Mr。yang  阅读(325)  评论(1编辑  收藏  举报