作业要求

模拟实现一个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. 相比Redis,Memcached真的过时了吗?

    下面内容来自Redis作者在stackoverflow上的一个回答,对应的问题是<Is memcached a dinosaur in comparison to Redis?>(相比Re ...

  2. WPF listbox的分组研究

    1. 初探GroupItem对象 2.ContainerStyle 与 GroupItem的绑定对象 3.Grouping 级联

  3. 跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击

    背景 这个系列有很多题,但是其实考察的相近,类似的就不在多说,我们来看吧.主要分几个点来讲: 反射型 存储型 JSON XM 头部字段相关 分类介绍 反射型 在请求中构造了XSS的Payload,一般 ...

  4. vue编程式路由实现新窗口打开

    一. 标签实现新窗口打开: 官方文档中说 v-link 指令被 组件指令替代,且 不支持 target=”_blank” 属性,如果需要打开一个新窗口必须要用标签,但事实上vue2版本的 是支持 ta ...

  5. python分支语句

    一.if else语句 if 条件表达式: else: a = 3 b = 4 if a >= b: print("a >= b") else: print(" ...

  6. day_6.26 反射

    #utf-8 #2018-6-26 17:58:36 #反射,, 应用:从类里面获取字符串 #在python中万物皆对象 class Teacher: dic = {"查看学生信息" ...

  7. D - Wireless Network

    来源poj2236 An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have s ...

  8. gfs故障恢复

    GlusterFS更换故障Brick tanzhenchao关注0人评论3918人阅读2017-03-21 09:53:18   1 前言 笔者公司内有一套GlusterFS分布式存储,最近数据分区的 ...

  9. 可执行代码(Executable Code)目标代码(object code)

    小结: 1.可执行代码(Executable Code)是指将目标代码(object code)连接后形成的代码,简单来说是机器能够直接执行的代码. https://baike.baidu.com/i ...

  10. xcode工程编译错误:"An instance 0xca90200 of class UITableView was deallocated while key value observers were still registered with it"

    An instance 0xca90200 of class UITableView was deallocated while key value observers were still regi ...