购物车+ATM项目小结及代码分享
购物车+ATM
文件目录:
Bin
Conf setting 配置文件 :配置环境
Core src.py 主程序
Lib common.py 公用模块 修饰器
Db db_hander.py 数据相关 保存 查询函数
Log 日志相关Interface
user.py 用户接口
注册接口
登录接口
shopping.py 购物接口
购物
查看商品
bank.py 银行接口
查询余额
转账
还款
取现
查看流水
Readme :程序简介
Start.py :程序入口
流程:
1、先配置环境,到setting中配置用DB 接收db的环境变量2、到入口start写入口程序需要配置环境变量用sys 将如口的环境变量加入系统中导入src,调用run方法
3、再回src中写主函数run和各个空函数
1、注册功能
接收输入 简单判断到user中编写注册接口(参数:name, password, balance=15000) 查询用户是否存在(到db中编写查询函数(参数为name),先path接收db中文件路径,如果存在就返回Flase,若果不存在接调用存储函数(再db中编写存储函数(参数为接收的字典user_dic),先用path结束存的路径和文件名,再以写的模式打开使用dump方法写入文件)将内容以json方式存入db)调用注册接口复制给flag,msg 如果flag是Ture 打印msg 结束不存在则直接打印msg
2、登陆功能:
接收用户名和密码用flag和msg接收登陆接口的返回值(在user中编写登陆接口(参数为name,password)用字典接收通过用户名查询到的信息,如果用户存在再判断密码是否正确和是否锁定,正确未锁定返回Ture和登陆成功,否则打印密码错误或被锁定,如果不存在直接返回Flase,账户不存在)如果Flag=Ture 打印msg 并将name存入到开头定义的空字典中 并结束程序如果Flag=Flase 直接打印返回的msg
3、查询余额
直接用balance接收调用余额查询接口的返回值,再打印出来(在bank中编写查询接口(参数为name),用字典接收通过名字查询到的信息,返回字典中的余额)
取款:
4、接收取款的金额
判断是否为isdigit 再int强制转换 同样用flag,msg接收取现接口的返回值(在bank中编写取现接口(参数为name,balance),用字典接收通过姓名查询到的信息,判断余额是否充足,充足就余额减去取款金额的1.05倍,调用save函数存储更新后的字典,并返回Ture和取现成功,否则显示余额不足)
5、存款功能
接收存入金额判断金额是否为整数 强制转换 用两个变量接收还款接口的参数(到bank中写还款接口,字典接收通过名字查询到的信息,取余额加存入的金额并保存到文件中)
6、转账功能
接收输入的目标账户判断是否与自己姓名相同,相同则不能转账,接收转账金额,金额是否为整数 并转换 用两个变量接收转账接口的返回值(转账接口,查询目标账户是否存在,判断金额是否足够,足够就自己减去金额,目标账户加上金额,成功就返回Ture 成功)
7、查看流水
用列表接收其流水接口的值后循环打印(接收查询到的信息,返回流水列表)
8、购物功能
查询账户余额并赋值购物车以字典形式存,商品用列表Enumerate打印索引和内容选择商品判断choice是数字转换后判断长度 如果大于就跳出,取商品名和价格余额大于价格则可购买 如果购物车内有这件商品只用数量加一否则直接加所有信息加入后余额减去价格,花费加上价格余额小于价格显示不足Choice==Q输入Q再判断,如果cost==0显示未购买,退出打印购物车输入是否购买 是的话调用购物接口(接收bank中结账接口(接收查询的信息,取余额判断余额是否大于需要付的金额大于就减去金额存入字典返回True付款成功,小于则返回Flase,余额不足)的的返回值,判断返回值字典接收查询内容,购物车赋值进去,存入文件返回购物成功 )判断返回值正误,正确的话打印msg结束,未购买Choice 乱输 非法输入查看商品接收查看接口的返回值并打印(字典接收查询内容,返回购物车信息)
9、日志
复制日志字典,日志格式配置日志的环境变量和文件名在接口中添加日志,
def get_logger(name):
logging.config.dictConfig(setting.LOGGING_DIC)
my_logger=logging.getLogger(name)
return my_logger
每个接口函数值调用,在银行接口中添加流水程序注销账户将存储信息列表赋值为空
文件 Conf setting 中的代码:
import os DIR_PATH = os.path.dirname(os.path.dirname(__file__)) DIR_DB = os.path.join(DIR_PATH, 'db') BASE_LOG= os.path.join(DIR_PATH,'log') # 如果不存在定义的日志目录就创建一个 if not os.path.isdir(BASE_LOG): os.mkdir(BASE_LOG) # log文件的全路径 logfile_path = os.path.join(BASE_LOG, 'log.log') standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \ '[%(levelname)s][%(message)s]' # 其中name为getlogger指定的名字 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s' # log配置字典 LOGGING_DIC = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': standard_format }, 'simple': { 'format': simple_format }, }, 'filters': {}, 'handlers': { # 打印到终端的日志 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', # 打印到屏幕 'formatter': 'simple' }, # 打印到文件的日志,收集info及以上的日志 'default': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'standard', 'filename': logfile_path, # 日志文件 'maxBytes': 1024*5*1024, # 日志大小 5M 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, 'loggers': { # logging.getLogger(__name__)拿到的logger配置 '': { 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'level': 'INFO', 'propagate': True, # 向上(更高level的logger)传递 }, }, }
文件core src中的代码
from interface import user, bank, shopping from lib import common user_info = { 'name': None } def login(): print('登录') if user_info['name']: print('您已经登录过了') return count = 0 while True: name = input('请输入用户名').strip() if name == 'q': break password = input('请输入密码:').strip() flag, msg = user.login_interface(name, password) if flag: print(msg) user_info['name'] = name break else: count += 1 if count >= 3: user.lock_user(name) print('账号被锁定') break print(msg) def register(): print('注册') if user_info['name']: print('您已经登录过了,不能注册') return while True: name = input('请输入用户名:').strip() if name == 'q': break password = input('请输入密码:').strip() conf_password = input('请确认密码:').strip() if password == conf_password: flag, msg = user.register_interface(name, password) if flag: print(msg) break else: print(msg) else: print('两次密码不一致') @common.auth def check_balance(): print('查看余额') balance = bank.check_balance_interface(user_info['name']) print('您的余额为:%s' % balance) @common.auth def transfer(): print('转账') while True: to_user = input('请输入要转账的账户:').strip() if to_user == user_info['name']: print('不能给自己转账') continue balance = input('请输入转账金额:').strip() if balance.isdigit(): balance = int(balance) flag, msg = bank.transfer_interface(user_info['name'], to_user, balance) if flag: print(msg) break else: print(msg) @common.auth def repay(): print('还款') balance = input('请输入还款金额:').strip() if balance.isdigit(): balance = int(balance) _, msg = bank.repay_interface(user_info['name'], balance) print(msg) @common.auth def withdraw(): print('取款') while True: balance = input('请输入取款金额:').strip() if balance.isdigit(): balance = int(balance) flag, msg = bank.withdraw_interface(user_info['name'], balance) if flag: print(msg) break else: print(msg) @common.auth def check_record(): print('查看流水') records = bank.check_record_interface(user_info['name']) for record in records: print(record) @common.auth def shop(): ''' 1 先循环打印出商品 2 用户输入数字选择商品(判断是否是数字,判断输入的数字是否在范围内) 3 取出商品名,商品价格 4 判断用户余额是否大于商品价格 5 余额大于商品价格时,判断此商品是否在购物车里 5.1 在购物车里,个数加1 5.1 不在购物车里,拼出字典放入({‘car’:{‘price’:1000,‘count’:2},‘iphone’:{‘price’:10,‘count’:1}}) 6 用户余额减掉商品价格 7 花费加上商品价格 8 当输入 q时,购买商品 8.1 消费为0 ,直接退出 8.2 打印购物车 8.3 接受用户输入,是否购买 当输入y,直接调购物接口实现购物 :return: ''' print('购物') user_balance = bank.check_balance_interface(user_info['name']) cost = 0 shopping_cart = {} goods_list = [ ['coffee', 10], ['chicken', 20], ['iphone', 8000], ['macPro', 15000], ['car', 100000] ] while True: for i, good in enumerate(goods_list): print('%s:%s' % (i, good)) choice = input('请输入要购买的商品:').strip() if choice.isdigit(): choice = int(choice) if choice > len(goods_list)-1: continue good_name = goods_list[choice][0] good_price = goods_list[choice][1] if user_balance >= good_price: if good_name in shopping_cart: shopping_cart[good_name]['count'] += 1 else: shopping_cart[good_name] = {'price': good_price, 'count': 1} print('成功把%s加入了购物车'%good_name) user_balance -= good_price cost += good_price else: print('您的余额不足') elif choice == 'q': if cost == 0: print('您什么都没选择') break print(shopping_cart) config=input('您确定购买吗?(y/n):').strip() if config =='y': flag,msg=shopping.shooping_interface(user_info['name'],cost,shopping_cart) if flag: print(msg) break else: print(msg) break else: print('您什么都没买') break else: print('输入非法') @common.auth def check_shoppingcart(): print('查看购买商品') shopping_cart=shopping.check_shoppingcart_interface(user_info['name']) print(shopping_cart) def logout(): user_info['name'] = None func_dic = { '1': login, '2': register, '3': check_balance, '4': transfer, '5': repay, '6': withdraw, '7': check_record, '8': shop, '9': check_shoppingcart, '10': logout } def run(): while True: print(''' 1、登录 2、注册 3、查看余额 4、转账 5、还款 6、取款 7、查看流水 8、购物 9、查看购买商品 10、注销 ''') choice = input('请选择:').strip() if choice not in func_dic: continue func_dic[choice]()
文件db db_hoster中的代码
import json import os from conf import settings def save(user_dic): path = os.path.join(settings.DIR_DB, '%s.json' % user_dic['name']) with open(path, 'w', encoding='utf-8') as f: json.dump(user_dic, f) def select(name): path = os.path.join(settings.DIR_DB, '%s.json' % name) if os.path.exists(path): with open(path, 'r', encoding='utf-8') as f: user_dic = json.load(f) return user_dic else: return False
文件interface中 user、shopping 、bank中的方法
bank
from db import db_handler from lib import common bank_logger=common.get_logger('bank') def check_balance_interface(name): user_dic=db_handler.select(name) return user_dic['balance'] def withdraw_interface(name,balance): user_dic=db_handler.select(name) if user_dic['balance'] >=balance*1.05: user_dic['balance']-=balance*1.05 user_dic['bankflow'].append('%s 取款 %s'%(name,balance)) db_handler.save(user_dic) bank_logger.info('%s 取款 %s'%(name,balance)) return True,'取款成功' else: return False,'余额不足' def repay_interface(name,balance): user_dic=db_handler.select(name) user_dic['balance']+=balance user_dic['bankflow'].append('%s 还款 %s' % (name, balance)) db_handler.save(user_dic) bank_logger.info('%s 还款 %s' % (name, balance)) return True,'还款成功' def transfer_interface(from_user,to_user,balance): to_user_dic=db_handler.select(to_user) if to_user_dic: from_user_dic=db_handler.select(from_user) if from_user_dic['balance']>=balance: from_user_dic['balance']-=balance to_user_dic['balance']+=balance from_user_dic['bankflow'].append('您给%s转账 %s' % (to_user, balance)) to_user_dic['bankflow'].append('%s给您转账 %s' % (from_user, balance)) db_handler.save(to_user_dic) db_handler.save(from_user_dic) bank_logger.info('%s 给 %s 转账 %s' % (from_user,to_user, balance)) return True,'转账成功' else: return False,'余额不足' else: return False,'对方账户不存在' def check_record_interface(name): user_dic=db_handler.select(name) return user_dic['bankflow'] def consume_interface(name, account): user_dic = db_handler.select(name) if user_dic['balance'] >= account: user_dic['balance'] -= account user_dic['bankflow'].append('您消费%s' % account) db_handler.save(user_dic) bank_logger.info('消费 %s' % account) return True, '付款成功' else: return False, '余额不足,不能付款'
shopping
from db import db_handler from interface import bank from lib import common shop_logger=common.get_logger('shopping') def shooping_interface(name,cost,shoppingcart): flag,msg=bank.consume_interface(name,cost) if flag: user_dic=db_handler.select(name) user_dic['shoppingcart']=shoppingcart db_handler.save(user_dic) shop_logger.info('购买商品成功') return True,'购买成功' else: return False,msg def check_shoppingcart_interface(name): user_dic=db_handler.select(name) return user_dic['shoppingcart']
user
from db import db_handler from lib import common user_log=common.get_logger('user') def register_interface(name, password, balance=15000): user = db_handler.select(name) if user: return False, '用户已经存在' user_dic = {'name': name, 'password': password, 'balance': balance, 'credit': balance, 'locked': False, 'bankflow': [], 'shoppingcart': {}} db_handler.save(user_dic) user_log.info('%s 注册成功'%name) return True, '注册成功' def login_interface(name, password): user_dic = db_handler.select(name) if user_dic: if user_dic['password'] == password and not user_dic['locked']: return True, '登录成功' else: return False, '密码错误或账户被锁定' else: return False, '用户不存在' def lock_user(name): user_dic = db_handler.select(name) if user_dic: user_dic['locked'] = True db_handler.save(user_dic) user_log.info('%s 被锁定' % name) def unlock_user(name): user_dic = db_handler.select(name) if user_dic: user_dic['locked'] = False db_handler.save(user_dic) user_log.info('%s 被解锁' % name) return True,'解锁成功' else: return False,'用户不存在'
文件lib 中common的方式
from core import src from conf import settings import logging.config def auth(func): def inner(*args, **kwargs): if src.user_info['name']: res = func(*args, **kwargs) return res else: src.login() return inner def get_logger(name): logging.config.dictConfig(settings.LOGGING_DIC) my_logger = logging.getLogger(name) return my_logger
开始文件的代码
import sys,os path= os.path.dirname(__file__) sys.path.append(path) from core import src if __name__ == '__main__': src.run()
readme
1 需求分析 项目需求: 模拟实现一个ATM + 购物商城程序 额度 15000或自定义---->注册功能 实现购物商城,买东西加入 购物车,调用信用卡接口结账----->购物车,支付 可以提现,手续费5%----->提现 支持多账户登录----->登录 支持账户间转账----->转账 记录日常消费流水----->记录流水 提供还款接口---->还款 ATM记录操作日志---->日志 提供管理接口,包括添加账户、冻结账户等。。。---->管理接口,添加,冻结账户 用户认证用装饰器------>装饰器 1、登录 2、注册 3、查看余额 4、转账 5、还款 6、取款 7、查看流水 8、购物 9、查看购买商品 2 设计程序以及程序的架构 3 分任务开发程序 4 测试程序 5 上线运行