作业要求

模拟实现一个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. 16解释器模式Interpreter

    一.什么是解释器模式 Interpreter模式也叫解释器模式,是行为模式之一,它 是一种特殊的设计模式,它建立一个解释器,对于特定 的计算机程序设计语言,用来解释预先定义的文法.简 单地说,Inte ...

  2. 5 -- Hibernate的基本用法 --5 1 持久化类的要求

    1.  提供一个无参数的构造器:所有的持久化类都应该提供一个无参数的构造器,这个构造器可以不采用public访问控制符.只要提供了无参数的构造器,Hibernate就可以使用Constructor.n ...

  3. Spark排序之SortByKey

    sortByKey函数作用于Key-Value形式的RDD,并对Key进行排序. package com.test.spark import org.apache.spark.{SparkConf, ...

  4. Spark RDD Transformation 简单用例(三)

    cache和persist 将RDD数据进行存储,persist(newLevel: StorageLevel)设置了存储级别,cache()和persist()是相同的,存储级别为MEMORY_ON ...

  5. Spark RDD Transformation 简单用例(二)

    aggregateByKey(zeroValue)(seqOp, combOp, [numTasks]) aggregateByKey(zeroValue)(seqOp, combOp, [numTa ...

  6. oracle中如何生成awr报告

    oracle中如何生成awr报告   1.进入数据库 sqlplus / as sysdba 2.查看用户 show parameter db_name 3.开始压测后执行 exec DBMS_WOR ...

  7. IBatisNet不常用到的配置(Dao.config ConnectionTimeout),居然不起作用(前辈留给我们的坑)

    IBattis 默认超时时间好像是30s,可多于这个时间总就会报错:DaoProxy : unable to intercept method name 'ExcuteQuery', cause : ...

  8. Winter-Camp欠债记录

    待完成: 球相交体积模板博客 Day3B题计算几何 Splay和Treap学习 [寒假]整理算法&模板

  9. 2018ACM-ICPC南京区域赛---AJGIDKM

    含[最小球覆盖][最大流isap]模板. 题面pdf https://codeforc.es/gym/101981/attachments/download/7891/20182019-acmicpc ...

  10. int main(int argc,char *argv[])与int main(int argc,char **argv)区别?

    int main(int argc,char *argv[])与int main(int argc,char **argv)区别? 这两种是一个等价的写法 而int main(int argc,cha ...