ATM
ATM的架构:
用户功能层:src
注册登录接口层:user_interface
数据处理层:db_landly
公共层:common 登录装饰器需要一个全局变量src.login_name来查询是否登录
管理员功能:
admin 用户功能层显示:
#管理员
def admin():
while True:
username = input('请输入管理员的用户名:').strip()
password = input('请输入管理员密码:').strip()
msg = admin_interface.admin_run(username,password)
print(msg)
break
admin_interface
from db import db_landly
from core import src
#注册
def register_admin():
src.register()
#修改余额
def admin_money():
username = input('请输入要修改余额的用户:').strip()
user_dic = db_landly.find_dic(username)
if user_dic:
money = input('请输入要修改的余额:').strip()
money = int(money) #注意修改金额得转换为int类型
user_dic['balance'] = money
db_landly.save(user_dic)
print('余额修改成功')
else:
print('无此用户')
#冻结用户
def lock_user():
username = input('请输入要冻结的用户名:').strip()
user_dic = db_landly.find_dic(username)
if user_dic:
user_dic['locked'] = True
db_landly.save(user_dic)
print('该用户已成功被冻结')
else:
print('无此用户')
admin_dic = {
'1':register_admin,
'2':admin_money,
'3':lock_user
}
def admin_run(username,password):
while True:
if username == 'zyq' and password == '123':
print('''
1.注册用户
2.修改用户余额
3.冻结用户
''')
choose = input('请输入你的指令:').strip()
if choose == '0':
return '退出管理员系统'
if choose in admin_dic:
admin_dic[choose]()
else:
print('请输入合法的指令')
else:
return '账号密码输入错误,请重新输入'
我认为最难的ATM购物车:
用户功能层:
ATM购物车用户功能层
#购物车
@common.login_dic
def shopping():
shop_list = [
['apple', 100],
['xiaomi', 200],
['huawei', 300],
['meizu', 400],
['balana', 500]
]
shopping_car = {} #初始化当前购物车
while True:
#1)枚举:enumerate(可迭代对象)---> (可迭代对象的索引,索引对应的值)
for index,shop in enumerate(shop_list):
shop_name,shop_price = shop
print(f'商品编号为{index}----'
f'商品名称{shop_name}----'
f'商品单价{shop_price}')
choice = input('请输入商品编号(是否结账y or n):').strip() #2)根据商品编号选择商品
#y的话结算购物车
if choice == 'y': #结算购物车
if not shopping_car:
print('购物车是空的,不能添加,请重新输入')
continue
flag,msg = shop_interface.shopping_interface(login_name,shopping_car)
if flag:
print(msg)
break
else:
print(msg)
#n的话添加购物车
if choice == 'n': #调用购物车接口, 判断用户是否添加购物车
if not shopping_car:
print('购物车是空的,不能添加,请重新输入')
continue
msg = shop_interface.add_shop_interface(login_name,shopping_car)
print(msg)
break
if not choice.isdigit():
continue
choice = int(choice)
if choice not in range(len(shop_list)): #3)判断choice是否存在
print('请输入正确的编号')
continue
shop_name1,shop_price1 = shop_list[choice] #4) 获得商品名称和单价
#5)加入购物车
if shop_name1 in shopping_car:
shopping_car[shop_name1][1]+=1 #如果存在则添加商品数量
else:
#{'商品名称':[‘单价’,‘数量’]}
shopping_car[shop_name1] = [shop_price1,1] #不存在则直接创建一个新的k:v进去
购物车数据接口层:
购物商城接口
#购物商城接口
#支付结算购物车y
def shopping_interface(username,shop_car):
cost = 0
# {'商品名称':[‘单价’,‘数量’]}
for price_num in shop_car.values():
price,num = price_num #['单价','数量']
cost += (price * num)
from interface import bank_interface
flag = bank_interface.shop_pay_interface(username,cost) #转到银行接口结账
if flag:
return True,'支付成功,准备发货'
return False,'支付失败,金额不足'
#购物车添加接口n
def add_shop_interface(login_name,shopping_car):
user_dic = db_landly.find_dic(login_name)
shop_car = user_dic['shop_car'] # 字典里面购物车存在的方式是:{'商品名称':[‘单价’,‘数量’],'商品名称':[‘单价’,‘数量’]---------------}
for shop_name,price_num in shopping_car.items():
num = price_num[1]
if shop_name in shop_car: #如果商品重复,则累加商品数量
user_dic['shop_car'][shop_name][1]+=num
db_landly.save(user_dic)
else:
user_dic['shop_car'].update(
{shop_name:price_num} #如果不重复 则以{'商品名称':[‘单价’,‘数量’]}的形式添加进字典中
)
db_landly.save(user_dic)
return '添加购物车成功'
日志功能:
日志功能的配置文件settings
'''
logging配置
'''
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'
test_format = '%(asctime)s] %(message)s'
path = os.path.dirname(os.path.dirname(__file__))
logfile_dir = os.path.join(path,'logger')
logfile_path = 'atm.log'
if not os.path.exists(logfile_path): #路径文件如果不存在则创建一个
os.mkdir(logfile_dir)
# 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)传递
},
},
}
common:
添加日志功能(日志功能只能在接口层使用)
import logging.config
from conf import settings
#添加日志功能:(日志功能在接口层使用)
def get_logger(log_type):
'''
:param log_type: 比如是user日志,bank日志,购物商城日志
:return:
'''
#1.加载日志配置信息
logging.config.dictConfig(
settings.LOGGING_DIC #LOGGING_DIC是配置字典
)
#获取日志对象
logger = logging.getLogger(log_type)
return logger
使用案例:
user_logger = common.get_logger('user')
#注册
def register_interface(username,password,balance=15000):
# user_dic = db_landly.find_dic(username)
# if not user_dic:
# password_m5 = common.password_m5(password)
# userdic = {
# 'username':username,
# 'password':password_m5,
# 'balance':balance,
# 'flow':[],
# 'shop_car':{},
# 'locked':False
# }
# db_landly.save(userdic)
msg = f'用户{username}注册成功' *******
user_logger.info(msg) *******
return True,msg
#登录
def login_interface(username,password):
user_dic = db_landly.find_dic(username)
if not user_dic:
msg = f'用户{username}不存在,请重新输入'
user_logger.warn(msg) #如果是false的话可以用warn
return False,msg
if user_dic['locked']:
return False,f'该用户已被上锁,请找管理员解锁'
password_m5 = common.password_m5(password)
if password_m5 == user_dic['password']:
msg = f'用户{username}登录成功'
user_logger.info(msg)
return True,msg
else:
msg = f'密码输入错误,请重新登录'
user_logger.warn(msg)
return False,msg
#如果是false的话可以用debug或者warn这些 info是TRUE的时候使用的