python闯关_Day012

day012 用python实现信息卡管理及购物商城的项目

 

需求

#需求:
1 这是一个信用卡管理程序
2 用户手持信用卡购物,使用函数,按照软件开发规范
3 用户名密码存放于文件中,支持多用户登陆,使用json
4 程序启动,先登录或者注册,保存信息到文件中,记录日志
5 用户的登陆,密码输错三次,锁定,不能再登录
6 用户可以取现,消费,还款,提额
7 允许用户根据商品编号购买商品,用户选择商品,检测余额,够用扣款,不够用提示,用户行为都要记录日志
8 用户可以随时退出,退出时,打印已购买商品和余额

借鉴了老师在day011中的代码框架,添加了部分代码。

 

项目的结构如下。

 

项目的目录结构如下。

 

项目的运行结果展示

 

待改进的地方

1.  未做到单点登录
2.  日志的信息不够详细
3.  项目的健壮性,输入校验等等,有待提高

代码如下。

#/bin/start.py
import sys,os
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

from core import src

if __name__ == '__main__':
    src.run()

  

#/conf/setting.py

import os

BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DB_PATH=os.path.join(BASE_DIR,'db','db.json')
LOG_PATH=os.path.join(BASE_DIR,'log','access.log')
LOGIN_TIMEOUT=3

"""
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'
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': LOG_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)传递
        },
    },
}

  

#/core/src.py

from conf import settings
from lib import common
import time

logger=common.get_logger(__name__)

current_user={'user':None,'login_time':None,'timeout':int(settings.LOGIN_TIMEOUT)}


def auth(func):
    def wrapper(*args,**kwargs):
        if current_user['user']:
            interval=time.time()-current_user['login_time']
            if interval < current_user['timeout']:
                return func(*args,**kwargs)
        name = input('name>>: ')
        db=common.conn_db()
        if db.get(name):   #已注册用户的登录流程
            if db.get(name).get('locked'):
                logger.warning('该用户已被锁定')
                print ('该用户已被锁定')
            else:
                logging_error_times = 0

                while True:
                    if logging_error_times >= 3:
                        logger.warning('密码输入错误3次,该用户已被')
                        db[name]['locked'] = 1
                        common.save_db(db)
                        break
                    password = input('password>>:')
                    if password == db.get(name).get('password'):
                        logger.info('登录成功')
                        print('登录成功')
                        current_user['user'] = name
                        current_user['login_time'] = time.time()
                        return func(*args, **kwargs)
                    else:
                        logger.warning('密码错误')
                        logging_error_times += 1

        else:           #注册
            is_register = input('是否注册? (Y/N)')
            if is_register in ['Y','y']:
                password = input('password>>')
                db[name] = {"password":password, "money":0, "locked":0}
                logger.info("登录成功")
                print('登录成功')
                current_user['user'] = name
                current_user['login_time'] = time.time()
                common.save_db(db)
                return func(*args, **kwargs)
            else:
                logger.info('用户不注册')
    return wrapper


@auth
def buy():
    db = common.conn_db()
    money = db.get(current_user['user']).get('money')
    print ('目前账户有%d元' %money)
    items_dict = {'item1':1, 'item2':2}
    print (items_dict.keys())
    items_bought_dic = {}
    while True:
        item_buy = input('buy which(Q退出)?>>').strip()
        item_buy_split = item_buy.split(' ')
        #print (item_buy_split[0], item_buy_split[1])
        if item_buy_split[0] in ['q', 'Q']:
            db[current_user['user']]['money'] = money
            common.save_db(db)
            print('你买了:',items_bought_dic)
            print('账户余额:',money)
            break
        elif item_buy_split[0] in items_dict:
            item, item_num = item_buy_split[0], item_buy_split[1]
            item_price = items_dict[item] * int(item_num)
            print(item,':',item_num,'共花了%d'%item_price)
            if item_price <= money:
                money -= item_price
                print ('购买成功,还有%d元'%money)
                if item in items_bought_dic:
                    items_bought_dic[item] += item_num
                else:
                    items_bought_dic[item] = item_num
            else:
                print ('余额不足')
        else:
            print ('请输入:【商量名称】 【商品数量】')


@auth
def withdraw():
    db = common.conn_db()
    money = db.get(current_user['user']).get('money')
    print ('账户余额%d元' %money)
    withdraw_num = int(input('取多少钱?'))
    if withdraw_num <= money:
        money -= withdraw_num
        db[current_user['user']]['money'] = money
        common.save_db(db)
        print ('取现成功,账户余额%d' % money)
    else:
        print ('账户余额不足')

@auth
def repay():
    db = common.conn_db()
    money = db.get(current_user['user']).get('money')
    print('账户余额%d元' % money)
    repay_num = int(input('还款数量? '))
    money += repay_num
    db[current_user['user']]['money'] = money
    common.save_db(db)
    print('还款成功,你还有%d' % (money))


@auth
def run():

    print('''
1. 取现
2. 还款
3. 消费
Q. 退出
    ''')
    while True:
        choice = input('>>: ').strip()
        if not choice:continue
        if choice == '1':
            withdraw()
        if choice == '2':
            repay()
        if choice == '3':
            buy()
        if choice in ['Q','q']:
            quit()

  

#/db/db.json
{"user1": {"password": "111", "money": 2705, "locked": 0}, "user2": {"password": "111", "money": 30000, "locked": 0}, "user3": {"password": "111", "money": 20000, "locked": 0}, "zjl": {"password": "111", "money": 0, "locked": 0}}

  

#/lib/common.py

from conf import settings
import logging
import logging.config
import json

def get_logger(name):
    logging.config.dictConfig(settings.LOGGING_DIC)  # 导入上面定义的logging配置
    logger = logging.getLogger(name)  # 生成一个log实例
    return logger

def conn_db():
    db_path=settings.DB_PATH
    dic=json.load(open(db_path,'r',encoding='utf-8'))
    return dic

def save_db(dic):
    db_path = settings.DB_PATH
    json.dump(dic, open(db_path, 'w', encoding='utf-8'))

  

日志的截图

 

posted on 2019-01-15 18:51  NetDevOps  阅读(269)  评论(0编辑  收藏  举报

导航