模拟实现一个ATM + 购物商城程序
- 额度 15000或自定义
- 实现购物商城,买东西加入 购物车,调用信用卡接口结账
- 可以提现,手续费5%
- 每月22号出账单,每月10号为还款日,过期未还,按欠款总额 万分之5 每日计息
- 支持多账户登录
- 支持账户间转账
- 记录每月日常消费流水
- 提供还款接口
- ATM记录操作日志
- 提供管理接口,包括添加账户、用户额度,冻结账户等。。。
- 用户认证用装饰器
import os BASE_DIR = os.path.dirname(os.path.dirname(__file__)) DB_PATH = os.path.join(BASE_DIR, 'db') BASE_LOG =os.path.join(BASE_DIR,'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' # 定义日志输出格式 结束 # 如果不存在定义的日志目录就创建一个 if not os.path.isdir(BASE_LOG): os.mkdir(BASE_LOG) # log文件的全路径 logfile_path = os.path.join(BASE_LOG, 'log.log') # 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 * 1024 * 5, # 日志大小 5M 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, 'loggers': { # logging.getLogger(__name__)拿到的logger配置 '': { 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'level': 'INFO', 'propagate': True, # 向上(更高level的logger)传递 }, }, }
from interface import user from lib import common from interface import bank from interface import shop user_data = {'name':None} def login(): if user_data['name']: print('登录状态') return print('登录') count = 0 while True: name = input('用户名:').strip() if name == 'q': break user_dic = user.get_userinfo_interface(name) if user_dic: if not user_dic['locked']: pwd = input('密码:').strip() if pwd == user_dic['pwd']: print('登录成功') user_data['name'] = name break else: print('密码错误') count += 1 if count == 3: msg = user.lock_user_interface(name) print(msg) break else: print('用户锁定状态') break else: print('用户名不存在') def register(): if user_data['name']: print('登录状态') return print('注册') while True: name = input('用户名(q to quit):').strip() if name == 'q':break if user.get_userinfo_interface(name): print('用户名已被注册') continue else: pwd = input('密码:').strip() conf_pwd = input('核对密码:').strip() if pwd == conf_pwd: msg = user.register_interface(name,pwd) print(msg) break else: print('两次密码不一致') @common.auth def check_balance(): print('查看余额') msg = bank.check_balance_interface(user_data['name']) print(msg) @common.auth def transfer(): print('转账') to_user = input('转入账户:').strip() transfer_account = input('转账金额:').strip() flag,msg = bank.transfer_interface(user_data['name'],to_user,transfer_account) if flag: print(msg) else: print(msg) @common.auth def repay(): print('还款') account = input('输入还款金额:').strip() flag,msg = bank.repay_interface(user_data['name'],account) if flag: print(msg) else: print(msg) @common.auth def withdraw(): print('取款') account = input('取款金额:').strip() flag,msg = bank.withdraw_interface(user_data['name'],account) if flag: print(msg) else: print(msg) @common.auth def check_records(): res = bank.check_records_interface(user_data['name']) for i in res: print(i) @common.auth def shopping(): product_list = [['Iphone7', 5800], ['Coffee', 30], ['疙瘩汤', 10], ['Python Book', 99], ['Bike', 199], ['ViVo X9', 2499], ] shopping_cart = {} while True: for k,v in enumerate(product_list): info = '编号:%s 商品:%s 价格:%s' %(k,product_list[k][0],product_list[k][1]) print(info) choice = input('输入商品编号:').strip() if choice.isdigit(): choice = int(choice) if 0 <= choice < len(product_list): product_name = product_list[choice][0] product_price = product_list[choice][1] else: print('超出编号范围') continue else: print('输入非法') continue product_count = input('输入购买数量:').strip() if product_count.isdigit(): product_count = int(product_count) else: print('输入非法') for name in shopping_cart: if name == product_name: shopping_cart[product_name]['count'] += product_count break else: shopping_cart[product_name] = {'price':product_price,'count':product_count} cmd = input('结账:Y/y 任意键继续>>: ').strip() if cmd == 'y' or cmd == 'Y': # name shopping_cart print(shopping_cart) flag,msg = shop.shop_interface(user_data['name'],shopping_cart) if flag: print(msg) break else: print(msg) break else: print(shopping_cart) @common.auth def check_shopping_cart(): res = shop.check_cart_interface(user_data['name']) for i in res: print(i) def logout(): user_data['name'] = None func_dic = { '1':login, '2':register, '3':check_balance, '4':transfer, '5':repay, '6':withdraw, '7':check_records, '8':shopping, '9':check_shopping_cart, '0':logout } msg = ''' 1 登录 2 注册 3 查看余额 4 转账 5 还款 6 提现 7 查看流水 8 购物 9 查看购买商品 0 退出当前用户 ''' def run(): while True: print(msg) choice = input('选择功能>>: ').strip() if choice in func_dic: func_dic[choice]()
import os import json from conf import setting def select(name): user_path = os.path.join(setting.DB_PATH, '%s.json' % name) if os.path.exists(user_path): with open(user_path,encoding='utf-8') as f: user_dic = json.load(f) return user_dic else: return False def update(user_dic): user_path = os.path.join(setting.DB_PATH, '%s.json' %user_dic['name']) with open(user_path,'wt',encoding='utf-8') as f: json.dump(user_dic,f) f.flush()
from db import db_handler from lib import common logger_bank = common.get_logger('bank') def check_balance_interface(name): user_dic = db_handler.select(name) return '%s 余额为:%s' %(name,user_dic['account']) def transfer_interface(from_user,to_user,account): to_user_dic = db_handler.select(to_user) from_user_dic = db_handler.select(from_user) if from_user != to_user: if to_user_dic: if account.isdigit(): account = int(account) if from_user_dic['account'] >= account: from_user_dic['account'] -= account to_user_dic['account'] += account from_user_dic['bankflow'].append('%s 转给 %s %s元' % (from_user, to_user, account)) to_user_dic['bankflow'].append('%s 收到 %s %s元' % (to_user, from_user, account)) db_handler.update(from_user_dic) db_handler.update(to_user_dic) logger_bank.info('转账成功:%s 转给 %s %s元' % (from_user, to_user, account)) return True,'转账成功' else: return False,'余额不足' else: return False,'金额必须是整数' else: return False,'转入账户不存在' else: return False,'不能转给自己' def repay_interface(name,account): user_dic = db_handler.select(name) if account.isdigit(): account = int(account) user_dic['account'] += account user_dic['bankflow'].append('%s 还款 %s' %(name,account)) db_handler.update(user_dic) logger_bank.info('%s 还款 %s' %(name,account)) return True,'还款成功' else: return False,'还款金额必须是整数' def withdraw_interface(name,account): user_dic = db_handler.select(name) if account.isdigit(): account = int(account) if user_dic['account'] >= account: user_dic['account'] -= account user_dic['bankflow'].append('%s 取款 %s元' %(name,account)) logger_bank.info('%s 取款 %s元' %(name,account)) return True,'取款成功' else: return False,'余额不足' else: return False,'取款金额必须是整数' def check_records_interface(name): user_dic = db_handler.select(name) return user_dic['bankflow']
from db import db_handler from lib import common logger_shop = common.get_logger('shop') def shop_interface(name,cart): cost = 0 user_dic = db_handler.select(name) for v in cart.values(): cost += v['price'] * v['count'] if user_dic['account'] >= cost: user_dic['account'] -= cost user_dic['shopping_cart'].append('%s 购物信息 %s' %(name,cart)) db_handler.update(user_dic) logger_shop.info('%s 购物信息 %s' %(name,cart)) return True,'购物完成' else: return False,'余额不足' def check_cart_interface(name): user_dic = db_handler.select(name) return user_dic['shopping_cart']
import os from conf import setting from db import db_handler from lib import common from core import src logger_user = common.get_logger('user') def get_userinfo_interface(name): user_dic = db_handler.select(name) return user_dic def register_interface(name,pwd,account=15000): user_dic = {'name': name, 'pwd': pwd, 'locked': False, 'account': account, 'creidt': account, 'bankflow': [], 'shopping_cart': []} db_handler.update(user_dic) logger_user.info('%s 注册成功' %name) return '注册成功' def lock_user_interface(name): user_dic = db_handler.select(name) user_dic['locked'] = True db_handler.update(user_dic) logger_user.info('%s 被锁定' %name) return '错误3次,锁定用户'
import os from conf import setting from db import db_handler from lib import common from core import src logger_user = common.get_logger('user') def get_userinfo_interface(name): user_dic = db_handler.select(name) return user_dic def register_interface(name,pwd,account=15000): user_dic = {'name': name, 'pwd': pwd, 'locked': False, 'account': account, 'creidt': account, 'bankflow': [], 'shopping_cart': []} db_handler.update(user_dic) logger_user.info('%s 注册成功' %name) return '注册成功' def lock_user_interface(name): user_dic = db_handler.select(name) user_dic['locked'] = True db_handler.update(user_dic) logger_user.info('%s 被锁定' %name) return '错误3次,锁定用户'
def login(): pass def register(): pass def check_balance(): pass def transfer(): pass def repay(): pass def withdraw(): pass def check_records(): pass def shopping(): pass def check_shopping_cart(): pass func_dic = { '1':login, '2':register, '3':check_balance, '4':transfer, '5':repay, '6':withdraw, '7':check_records, '8':shopping, '9':check_shopping_cart } msg = ''' 1 登录 2 注册 3 查看余额 4 转账 5 还款 6 提现 7 查看流水 8 购物 9 查看购买商品 0 退出 ''' product_list = [['Iphone7', 5800], ['Coffee', 30], ['疙瘩汤', 10], ['Python Book', 99], ['Bike', 199], ['ViVo X9', 2499], ] 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 每月22号出账单,每月10号为还款日,过期未还,按欠款总额 万分之5 每日计息 支持多账户登录 支持账户间转账 记录每月日常消费流水 提供还款接口 ATM记录操作日志 提供管理接口,包括添加账户、用户额度,冻结账户等。。。 用户认证用装饰器 import os BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # 得到上一层的上一层目录也就是根目录 # BASE_DB_LOCAL = os.path.join(BASE_DIR, 'db') # 把根目录 和 db 目录拼接起来 BASE_LOG_LOCAL=os.path.join(BASE_DIR, 'log') logfile_name = 'log.log' # log文件名 # 如果不存在定义的日志目录就创建一个 if not os.path.isdir(BASE_LOG_LOCAL): os.mkdir(BASE_LOG_LOCAL) # log文件的全路径 logfile_path = os.path.join(BASE_LOG_LOCAL, logfile_name) 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*1024*5, # 日志大小 5M 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, 'loggers': { #logging.getLogger(__name__)拿到的logger配置 '': { 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'level': 'DEBUG', 'propagate': True, # 向上(更高level的logger)传递 }, }, }
import os import sys # BASE_DIR = os.path.normpath(os.path.join(os.path.abspath(__file__),'..')) BASE_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.append(BASE_DIR) from core import src if __name__ == '__main__': src.run()