作业要求

模拟实现一个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()

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 = [
['','Mac_pro',''] ,
['','iphone',''],
['','Mi_mix','']
] 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

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

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

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':"账户不存在"}

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

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)

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 == '':
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 == '':
conroller() # 进入到ATM操作模式
exit()

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)

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")

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

  

ATM_购物车作业的更多相关文章

  1. 1.3if判断语句+while和for循环语句+购物车作业

    1.if 语句 if userame=_usename and password=_password: print("welcome user {name} login..."). ...

  2. python第八天)——购物车作业优化完成

    发现之前的三级菜单代码有BUG现已经修改过来了 购物车程序:启动程序后,输入用户名密码后,如果是第一次登录,让用户输入工资,然后打印商品列表允许用户根据商品编号购买商品用户选择商品后,检测余额是否够, ...

  3. python购物车作业

    # -*- coding:utf8 -*- # Author:Wang Yao goods = [{"name": "电脑", "price" ...

  4. python作业购物车(第二周)

    一.作业需求: 1.启动程序后,输入用户名密码后,如果是第一次登录,让用户输入工资,然后打印商品列表 2.允许用户根据商品编号购买商品 3.用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒 4 ...

  5. day19 十九、ATM+购物车

    项目:ATM+购物车 作业需求:模拟实现一个ATM + 购物商城程序1.额度 15000或自定义 2.实现购物商城,买东西加入 购物车,调用信用卡接口结账 3.可以提现,手续费5% 4.每月22号出账 ...

  6. Day 11 函数名,闭包,装饰器. +作业

    '''一.函数名.def func(): print(5555)print(func)#输出结果 <function func at 0x026B5E88> 打印函数地址. # 1. 函数 ...

  7. python 作业

    Linux day01 计算机硬件知识整理 作业要求:整理博客,内容如下 编程语言的作用及与操作系统和硬件的关系 应用程序->操作系统->硬件 cpu->内存->磁盘 cpu与 ...

  8. day06_04 购物车讲解02

    1.0 补充知识 a,b = [2,3] print(a) print(b) #>>>2 #>>>3 a,b = (2,3) print(a) print(b) # ...

  9. python数据类型以及模块的含义

    print(sys.path) #打印环境变量 print(sys.argv) #打印相对路径 print(sys.argv[1]) #打印对应的参数 1.在python最上有时候会导入os模块,表示 ...

随机推荐

  1. metroui

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  2. 终端IO(上)

    一.综述 终端IO有两种不同的工作方式: 规范方式输入处理.在这种方式中,终端输入以行为单位进行处理.对于每个读要求,终端驱动程序最多返回一行. 非规范方式输入处理.输入字符不以行为单位进行装配 如果 ...

  3. 【JS加密库】SJCL :斯坦福大学JS加密库

    斯坦福大学Javascript加密库简称SJCL,是一个由斯坦福大学计算机安全实验室创立的项目,旨在创建一个安全.快速.短小精悍.易使用.跨浏览器的JavaScript加密库. 斯坦福大学下载地址:h ...

  4. WEB技术路线图

  5. C#日志记录设计与实现(BenXHLog)

    C#日志记录设计与实现 日志记录: 日志记录在程序设计开发过程中,是非常重要的,可以供调试和记录数据,虽然说有开源的强大日志管理系统,比如apache的Log4Net,功能可谓强悍,但是有时候,不需要 ...

  6. MassTransit入门

    .NET平台ESB框架的中文资料少的可怜,NServiceBus的有几篇,MassTransit的根本找不到,只好硬着头皮看官方的英文文档,顺便翻译出来加深理解. 欢迎拍砖. MassTransit是 ...

  7. 10.12Django form表单

    2018-10-12 15:24:23 From表单参考连接: https://www.cnblogs.com/yuanchenqi/articles/7614921.html 新增了ModelFor ...

  8. day_5.14 py 飞机大战Demo

    飞机未完,继续做 2018-5-14 21:05:45 明天继续       循环里面的坑; 删除列表元素后循环了打印的不一样,主要是比如相邻的删除了,33,44 删除33 循环一次后44跑到33位置 ...

  9. amcharts去除版权标志

    打开amcharts.js, 查找drb, 找到后,将drb:function(){......}程序{}中间内容清空, 或者改成drb:function(){return;}

  10. df

    hdu 1052 Tian Ji -- The Horse Racing (2011-08-26 08:32:51) 转载▼ 标签: 杂谈 分类: acm杂谈 Tian Ji -- The Horse ...