zoukankan      html  css  js  c++  java
  • 2.2

    要求:
    模拟实现一个ATM + 购物商城程序
    1.额度 15000或自定义
    2.实现购物商城,买东西加入 购物车,调用信用卡接口结账
    3.可以提现,手续费5%
    4.支持多账户登录
    5.支持账户间转账
    6.记录每月日常消费流水
    7.提供还款接口
    8.ATM记录操作日志
    9.提供管理接口,包括添加账户、用户额度,冻结账户等。。。
    10.用户认证用装饰器

    示例代码 https://github.com/triaquae/py3_training/tree/master/atm
    简易流程图:https://www.processon.com/view/link/589eb841e4b0999184934329

    ---------------------------------------------------------------
    做项目的步骤:
    1.分析功能,需求
    账户数据的增删改查 ,提现 转账 还款 --> 加钱 减钱
    日志
    模块间的互相调用
    功能的重用
    2.画流程图 https://www.processon.com/
    https://www.processon.com/view/link/589eb841e4b0999184934329
    3.搭框架

    ---------------------------------------------------------------
    注意事项:
    1.一个账户一个文件(.json),防止多个用户同时读数据,修改文件后,会覆盖别人已经修改好的文件!
    2.num_func = {'1': view_account, '2': withdraw, '3': pay_back, '4': transfer, '5': quit}
    choice_num = input('num>>>:').strip()
    num_func[choice_num](choice_num)
    字典 value 的值可以放 (地址)
    3.settings文件要重视,防止以后修改需求,可自定义配置
    4. json.dump(account_info['account_data'], f)
    f.close()
    os.replace(path_tmp, path)
    防止断电 .json 数据修改后,还未保存到硬盘上,所以一般写到 新文件中 再替换
    5.注意写的 模块公用,模块内的参数 一定不能写成死的!
    6.注意写的 函数公用,函数内的参数 一定要注意公用!
    7.公共的 函数,不要涉及到与用户交互!
    8.imoprt ***.py 引入模块时,引入模块得顺序:内置模块,第三方模块,自定义模块
    引入模块,一般到函数级别from *** import (***,***),为了可维护,程序可读性。无论加载一个模块还是加载一个函数,函数所在得模块都会被加载到内存中!
    9.load(open('**.py','r')) 和 with open('**.py','r') as f: 建议用后者 不需要关闭文件 python会自动关 但是f.close()是个好习惯 f.close()
    f.flush() 会触发磁盘写操作 增加io压力 增加系统负载 但是 特殊情况下 可以这么做
    10.变量在哪里使用就在哪里定义,因为函数传参是有一定代价的!
    11.密码md5加盐salt

    用户注册时:
    用户输入【账号】和【密码】(以及其他用户信息);
    系统为用户生成【Salt值】;
    系统将【Salt值】和【用户密码】连接到一起;
    对连接后的值进行散列,得到【Hash值】;
    将【Hash值1】和【Salt值】分别放到数据库中。

    用户登录时:
    用户输入【账号】和【密码】;
    系统通过用户名找到与之对应的【Hash值】和【Salt值】;
    系统将【Salt值】和【用户输入的密码】连接到一起;
    对连接后的值进行散列,得到【Hash值2】(注意是即时运算出来的值);
    比较【Hash值1】和【Hash值2】是否相等,相等则表示密码正确,否则表示密码错误。
    ----------------------------------------------------------------------------

    README:

    1.管理员的账号:999    密码:123
    2.普通账号:1000 / 1001 / 1002   密码:123

    atm.py

     1 # -*- coding:utf-8 -*-
     2 import os
     3 import sys
     4 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
     5 
     6 from core import(
     7     main, manager, shopper
     8 )
     9 
    10 
    11 def main_run():
    12     main.run()
    13 
    14 
    15 def manager_run():
    16     manager.run()
    17 
    18 
    19 def shopper_run():
    20     shopper.run()
    21 
    22 
    23 def quit_func():
    24     exit('bye bye ...')
    25 
    26 
    27 def choice():
    28     choice_msg = '''
    29     -----start-----
    30     1.普通账户
    31     2.管理员
    32     3.购物者
    33     4.退出
    34     ------end------
    35     '''
    36     dict_choice = {'1': main_run, '2': manager_run, '3': shopper_run, '4': quit_func}
    37     while True:
    38         print(choice_msg)
    39         choice_num = input('num>>>:').strip()
    40         if choice_num in dict_choice:
    41             dict_choice[choice_num]()
    42         else:
    43             print('请输入正确的序号!')
    44 
    45 
    46 if __name__ == '__main__':
    47     choice()
    atm

    settings.py

     1 # -*- coding:utf-8 -*-
     2 import os
     3 import logging
     4 import time
     5 import datetime
     6 
     7 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
     8 
     9 DATABASE = {
    10     'engine:': 'file_storage',
    11     'path': os.path.join(BASE_DIR, 'db/accounts')
    12 }
    13 
    14 LOG_LEVEL = logging.INFO
    15 LOG_FORMATTER = logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %I:%M:%S %p')
    16 
    17 TRANSACTION_TYPE = {
    18     'withdraw': {'action': 'minus', 'interest': 0.05},
    19     'pay_back': {'action': 'plus', 'interest': 0},
    20     'transfer': {'action': 'minus', 'interest': 0.05},
    21     'consume': {'action': 'minus', 'interest': 0}
    22 }
    23 
    24 GOODS = [
    25     {"name": "电脑", "price": 1999},
    26     {"name": "鼠标", "price": 10},
    27     {"name": "游艇", "price": 20},
    28     {"name": "美女", "price": 998}
    29 ]
    30 
    31 MANAGER_ID = '999'
    32 
    33 datetime_tmp = datetime.datetime.now().replace(year=2050, month=1, day=1)
    34 DEFAULT_ACCOUNT = {
    35     'id': 0,
    36     'password': '',
    37     'salt': '',
    38     'balance': 15000,
    39     'credit': 15000,
    40     'enroll_date': time.strftime('%Y-%m-%d', time.localtime()),
    41     'expire_date': '%s-%s-%s' % (datetime_tmp.year, datetime_tmp.month, datetime_tmp.day),
    42     'pay_day': 22,
    43     'status': 0
    44 }
    settings

    auth.py

     1 # -*- coding:utf-8 -*-
     2 import os
     3 import json
     4 from hashlib import md5
     5 
     6 from conf.settings import DATABASE
     7 
     8 
     9 def auth_login(func):
    10     # 装饰器
    11     def inner(*args, **kwargs):
    12         if args[0]['is_auth']:
    13             return func(*args, **kwargs)
    14         else:
    15             exit('您还未登录!')
    16     return inner
    17 
    18 
    19 def hash_password(password, salt):
    20     # 用户输入的密码 + salt 得到hash值
    21     hash_value = md5()
    22     hash_value.update((password+salt).encode('utf-8'))
    23     return hash_value.hexdigest()
    24 
    25 
    26 def judge_account(account):
    27     # 判断用户是否存在 存在返回json数据
    28     path_json = DATABASE['path']
    29     file_path = os.path.join(path_json, account+'.json')
    30     if os.path.isfile(file_path):
    31         with open(file_path, 'r', encoding='utf-8') as f:
    32             account_data = json.load(f)
    33             f.close()
    34             return account_data
    35 
    36 
    37 def login(logger, *args):
    38     # 判断账号密码是否正确
    39     account_info = {
    40         'is_auth': False,
    41         'account': None,
    42         'account_data': None
    43     }
    44     login_count = 0
    45     while login_count < 3:
    46         account = input('33[1;32maccount>>>:33[0m').strip()
    47         password = input('33[1;32mpassword>>>:33[0m').strip()
    48         account_data = judge_account(account)
    49         if account_data:
    50             if account_data.get('password') == hash_password(password, account_data['salt']):
    51                 # print('33[1;33m登录成功!33[0m'.center(25, '-'))
    52                 account_info['is_auth'] = True
    53                 account_info['account'] = account
    54                 account_info['account_data'] = account_data
    55                 if account_data['status'] == 1:  # 表示账号 被冻结
    56                     print('33[1;31m账号:%s 被冻结!33[0m'.center(30, '-') % account)
    57                 else:
    58                     if len(args) != 0:  # 管理员
    59                         if args[0] == account:
    60                             logger.info('管理员account: %s - 登录成功' % account)
    61                             return account_info
    62                         else:
    63                             print('33[1;31m您不是管理员!33[0m'.center(25, '-'))
    64                     else:  # 普通账号
    65                         logger.info('account: %s - 登录成功' % account)
    66                         return account_info
    67             else:
    68                 print('33[1;31m密码错误!33[0m'.center(25, '-'))
    69         else:
    70             print('33[1;31m账号:%s 不存在33[0m' % account)
    71         login_count += 1
    72     else:
    73         logger.critical('account: %s - 登录失败次数超过3次' % account)
    74         exit()
    auth

    db_handler.py

     1 # -*- coding:utf-8 -*-
     2 import os
     3 import json
     4 
     5 from .logger import set_logger
     6 from .auth import judge_account
     7 from conf.settings import(
     8     DATABASE, TRANSACTION_TYPE
     9 )
    10 
    11 trans_logger = set_logger('transactions')
    12 
    13 
    14 def account_data_save(account, account_data):
    15     # 修改文件的 公共方法
    16     path = os.path.join(DATABASE['path'], account + '.json')
    17     path_tmp = os.path.join(DATABASE['path'], account + '_tmp' + '.json')
    18     if os.path.isfile(path):
    19         with open(path_tmp, 'w', encoding='utf-8') as f:
    20             json.dump(account_data, f)
    21         os.replace(path_tmp, path)
    22         return account_data
    23 
    24 
    25 def save_json_common(account, new_balance, account_data):
    26     # 内存中 替换余额
    27     account_data['balance'] = round(new_balance, 2)
    28     return account_data_save(account, account_data)
    29 
    30 
    31 def transaction_logger(account, new_balance, account_data, arguments):
    32     # 记录 日志的 公共方法
    33     account_data_new = save_json_common(account, new_balance, account_data)
    34     if account_data_new:
    35         trans_logger.info('account: %s - account_type: %s - action: %s - interest: %s' % (account, arguments[0], arguments[1]['action'], arguments[1]['interest']))
    36         return account_data_new
    37 
    38 
    39 def split_account(new_balance, account_info, *args, **kwargs):
    40     # 区分开 是两个账号间的操作 还是一个账号
    41     account = account_info['account']
    42     if len(kwargs) != 0:  # 转账 两个账号 间的操作
    43         transfer_data = save_json_common(kwargs['transfer_account'], kwargs['transfer_new_balance'], kwargs['transfer_data'])
    44         if transfer_data:
    45             return transaction_logger(account, new_balance, account_info['account_data'], args)
    46     else:  # 一个 账号 的操作
    47         return transaction_logger(account, new_balance, account_info['account_data'], args)
    48 
    49 
    50 def make_transaction(money, account_info, account_type, *args):
    51     # 提现 还款 转账 公共方法
    52     if account_type in TRANSACTION_TYPE:
    53         transaction_type = TRANSACTION_TYPE[account_type]
    54         interest = money * transaction_type['interest']
    55         old_balance = account_info['account_data']['balance']
    56         # 减钱的 操作
    57         if transaction_type['action'] == 'minus':
    58             if len(args) == 0:  # 提现 或者 消费 没有附加的参数
    59                 new_balance = old_balance - money - interest
    60                 if new_balance < 0:
    61                     print('33[1;31m交易失败,余额不足33[0m')
    62                 else:
    63                     return split_account(new_balance, account_info, account_type, transaction_type)
    64             else:  # 转账
    65                 if args[0] == account_info['account']:
    66                     print('33[1;31m注:同一账号,不允许转账33[0m')
    67                 else:
    68                     transfer_data = judge_account(args[0])
    69                     if transfer_data:
    70                         if transfer_data['status'] == 1:
    71                             print('33[1;31m账号:%s 被冻结!33[0m'.center(30, '-') % args[0])
    72                         else:
    73                             new_balance = old_balance - money - interest
    74                             if new_balance < 0:
    75                                 print('33[1;31m交易失败,余额不足33[0m')
    76                             else:
    77                                 transfer_new_balance = transfer_data['balance'] + money
    78                                 return split_account(new_balance, account_info, account_type, transaction_type, transfer_account = args[0], transfer_new_balance = transfer_new_balance, transfer_data = transfer_data)
    79                     else:
    80                         print('33[1;31m账号:%s 不存在33[0m' % args[0])
    81         # 加钱的 操作
    82         elif transaction_type['action'] == 'plus':
    83             new_balance = old_balance + money + interest
    84             return split_account(new_balance, account_info, account_type, transaction_type)
    85 
    86     else:
    87         print('33[1;31m%s 交易类型不存在!33[0m' % account_type)
    db_handler

    logger.py

     1 # -*- coding:utf-8 -*-
     2 import os
     3 import logging
     4 from logging import handlers
     5 
     6 from conf.settings import(
     7     LOG_LEVEL, BASE_DIR, LOG_FORMATTER
     8 )
     9 
    10 
    11 def set_logger(name):
    12     # 配置logger对象
    13     logger = logging.getLogger(name)
    14     logger.setLevel(LOG_LEVEL)
    15 
    16     # fh = logging.FileHandler(os.path.join(BASE_DIR, 'log/'+name+'.log'), encoding='utf-8')
    17     # fh = handlers.RotatingFileHandler(filename = os.path.join(BASE_DIR, 'log/'+name+'.log'), maxBytes=10, backupCount=2, encoding='utf-8')
    18     fh = handlers.TimedRotatingFileHandler(filename = os.path.join(BASE_DIR, 'log/'+name+'.log'), when='S', interval=2, backupCount=2, encoding='utf-8')
    19     logger.addHandler(fh)
    20 
    21     fh_formatter = LOG_FORMATTER
    22     fh.setFormatter(fh_formatter)
    23 
    24     return logger
    logger

    main.py

      1 # -*- coding:utf-8 -*-
      2 import re
      3 
      4 from .logger import set_logger
      5 from .db_handler import make_transaction
      6 from .auth import (
      7     login, auth_login
      8 )
      9 
     10 access_logger = set_logger('access')
     11 
     12 
     13 @auth_login
     14 def checkout(account_info, money):
     15     # 购买商品之后 结账
     16     account_data = make_transaction(money, account_info, 'consume')
     17     if account_data:
     18         print('账户:%s ->> 消费 33[1;34m%s33[0m -> 余额 33[1;31m%s33[0m' % (account_info['account'], money, account_data['balance']))
     19         exit()
     20     else:
     21         print('33[1;31m结账失败!33[0m')
     22 
     23 
     24 def judge_num(num):
     25     # 判断 int float
     26     str_num = re.sub('.', '', num, count=1)
     27     if str_num.isdigit():
     28         return float(num)
     29 
     30 
     31 @auth_login
     32 def view_account(account_info):
     33     # 查看账户信息
     34     msg_info = '''33[1;34m
     35     -----账户:%s 的信息:-----
     36     balance: %10s
     37     credit:  %10s
     38     pay_day: %10s33[0m
     39     ''' % (account_info.get('account'), account_info['account_data']['balance'], account_info['account_data']['credit'], account_info['account_data']['pay_day'])
     40     print(msg_info)
     41 
     42 
     43 @auth_login
     44 def withdraw(account_info):
     45     # 提现
     46     while True:
     47         money = input('withdraw_money(q表示退出)>>>:').strip()
     48         if not money:
     49             continue
     50         if money == 'q':
     51             break
     52         float_money = judge_num(money)
     53         if float_money:
     54             account_data = make_transaction(float_money, account_info, 'withdraw')
     55             if account_data:
     56                 print('账户:%s -> 提现成功 -> 提现 33[1;34m%s33[0m -> 余额 33[1;31m%s33[0m' % (account_info['account'], money, account_data['balance']))
     57             else:
     58                 print('33[1;31m提现失败!33[0m')
     59         else:
     60             print('请输入33[1;34m正确的33[0m并33[1;31m大于033[0m的金额'.center(45, '-'))
     61 
     62 
     63 @auth_login
     64 def pay_back(account_info):
     65     # 还款
     66     while True:
     67         money = input('pay_back_money(q表示退出)>>>:').strip()
     68         if not money:
     69             continue
     70         if money == 'q':
     71             break
     72         float_money = judge_num(money)
     73         if float_money:
     74             account_data = make_transaction(float_money, account_info, 'pay_back')
     75             if account_data:
     76                 print('账户:%s -> 还款成功 -> 还款 33[1;34m%s33[0m -> 余额 33[1;31m%s33[0m' % (account_info['account'], money, account_data['balance']))
     77             else:
     78                 print('33[1;31m还款失败!33[0m')
     79         else:
     80             print('请输入33[1;34m正确的33[0m并33[1;31m大于033[0m的金额'.center(45, '-'))
     81 
     82 
     83 @auth_login
     84 def transfer(account_info):
     85     # 转账
     86     while True:
     87         transfer_account = input('transfer_account(q表示退出)>>>:').strip()
     88         if not transfer_account:
     89             continue
     90         if transfer_account == 'q':
     91             break
     92         while True:
     93             money = input('transfer_money(q表示退出)>>>:').strip()
     94             if not money:
     95                 continue
     96             if money == 'q':
     97                 return
     98             float_money = judge_num(money)
     99             if float_money:
    100                 account_data = make_transaction(float_money, account_info, 'transfer', transfer_account)
    101                 if account_data:
    102                     print('账户:%s -> 转账成功 -> 转账 33[1;34m%s33[0m -> 余额 33[1;31m%s33[0m' % (account_info['account'], money, account_data['balance']))
    103                 else:  # 交易失败余额不足的 或者 账号不存在的 或者 同一账号的 会直接退出
    104                     print('33[1;31m转账失败!33[0m')
    105                     return
    106             else:
    107                 print('请输入33[1;34m正确的33[0m并33[1;31m大于033[0m的金额'.center(45, '-'))
    108 
    109 
    110 def quit_func(account_info):
    111     # 退出
    112     exit('bye bye ...')
    113 
    114 
    115 def controller(account_info):
    116     # 功能分发器
    117     print('账户33[0;34m%s33[0m登录成功'.center(35, '*') % account_info.get('account'))
    118     msg_num = '''33[1;33m
    119     --------start--------
    120     1. 账户信息
    121     2. 提现
    122     3. 还款
    123     4. 转账
    124     5. 退出
    125     ---------end---------
    126     33[0m
    127     '''
    128     num_func = {'1': view_account, '2': withdraw, '3': pay_back, '4': transfer, '5': quit_func}  # 字典的值可存放 地址
    129     while True:
    130         print(msg_num)
    131         choice_num = input('num>>>:').strip()
    132         if not choice_num:
    133             continue
    134         if choice_num in num_func:
    135             num_func[choice_num](account_info)
    136         else:
    137             print('33[1;31m请输入正确的序号33[0m')
    138 
    139 
    140 def run():
    141     account_info = login(access_logger)
    142     if access_logger:
    143         controller(account_info)
    main

    manager.py

      1 # -*- coding:utf-8 -*-
      2 import os
      3 import json
      4 import string
      5 import random
      6 from hashlib import md5
      7 
      8 from .logger import set_logger
      9 from .main import judge_num
     10 from .db_handler import account_data_save
     11 from .auth import(
     12     login, judge_account, auth_login
     13 )
     14 from conf.settings import(
     15     MANAGER_ID, DATABASE, DEFAULT_ACCOUNT
     16 )
     17 
     18 manager_logger = set_logger('manager')
     19 
     20 
     21 def set_salt():
     22     # 每个用户的salt值不一样 库中的password就不一样
     23     salt = ''.join(random.sample(string.digits + string.ascii_letters + string.punctuation, 8))  # 随机的8位盐 使得相同的密码 也有不同md5()值
     24     md5_value = md5()
     25     md5_value.update(b'123' + salt.encode('utf-8'))
     26     return salt, md5_value.hexdigest()
     27 
     28 
     29 def get_account():
     30     # 输入 id 得到账户信息
     31     while True:
     32         id_account = input('id>>>:').strip()
     33         if id_account.isdigit():
     34             account_date = judge_account(id_account)
     35             if account_date:
     36                 return account_date, id_account
     37             else:
     38                 print('33[1;31m账号:%s 不存在33[0m' % id_account)
     39         else:
     40             print('33[1;31m请输入整数的 id 账户33[0m')
     41 
     42 
     43 @auth_login
     44 def add_acount(m_account_info):
     45     # 添加账户
     46     print('33[1;34m管理员 %s 开始添加账户33[0m'.center(30, '-') % m_account_info['account'])
     47     while True:
     48         id_account = input('id>>>:').strip()
     49         if id_account.isdigit():
     50             account_date = judge_account(id_account)
     51             if account_date:
     52                 print('33[1;31m账号:%s 已存在33[0m' % id_account)
     53             else:
     54                 salt_pass = set_salt()
     55                 DEFAULT_ACCOUNT['id'] = int(id_account)
     56                 DEFAULT_ACCOUNT['password'] = salt_pass[1]
     57                 DEFAULT_ACCOUNT['salt'] = salt_pass[0]
     58                 with open(os.path.join(DATABASE['path'], id_account + '.json'), 'w', encoding='utf-8') as f:
     59                     json.dump(DEFAULT_ACCOUNT, f)
     60                 print('33[1;32m账号:%s 添加成功33[0m' % id_account)
     61                 manager_logger.info('管理员account:%s - 添加账户account:%s' % (m_account_info['account'], id_account))
     62                 break
     63         else:
     64             print('33[1;31m请输入整数的 id 账户33[0m')
     65 
     66 
     67 @auth_login
     68 def credit_account(m_account_info):
     69     # 设定用户 额度
     70     account_tuple = get_account()
     71     if account_tuple:
     72         credit = input('new_credit>>>:').strip()
     73         float_credit = judge_num(credit)
     74         if float_credit:
     75             account_tuple[0]['credit'] = round(float_credit, 2)
     76             account_data = account_data_save(account_tuple[1], account_tuple[0])
     77             if account_data:
     78                 print('修改账号: 33[1;33m%s33[0m 额度成功,现在额度为:33[1;34m%s33[0m' % (account_tuple[1], account_data['credit']))
     79                 manager_logger.info('管理员account:%s - 修改账号account:%s - 修改额度credit:%s' % (m_account_info['account'], account_tuple[1], float_credit))
     80             else:
     81                 print('账号:%s 文件修改失败!' % account_tuple[1])
     82         else:
     83             print('33[1;31m注意:用户额度须为整数或小数33[0m')
     84 
     85 
     86 @auth_login
     87 def freeze_account(m_account_info):
     88     # 冻结账户
     89     account_tuple = get_account()
     90     if account_tuple:
     91         if account_tuple[1] == m_account_info['account']:  # 是管理员 本人
     92             print('33[1;31m您是管理员,不能冻结自己!33[0m')
     93         else:
     94             if account_tuple[0]['status'] == 1:
     95                 print('账号是 33[1;32m冻结33[0m 状态,将 33[1;34m解冻33[0m')
     96                 account_tuple[0]['status'] = 0
     97             else:
     98                 print('账号是 33[1;32m解冻33[0m 状态,将 33[1;34m冻结33[0m')
     99                 account_tuple[0]['status'] = 1
    100             account_data = account_data_save(account_tuple[1], account_tuple[0])
    101             if account_data:
    102                 print('33[1;33m修改账号的 冻结状态:%s 成功!33[0m' % (account_tuple[1]))
    103                 manager_logger.info('管理员account:%s - 修改账号account:%s - 修改冻结状态成功' % (m_account_info['account'], account_tuple[1]))
    104             else:
    105                 print('账号:%s 文件修改失败!' % account_tuple[1])
    106 
    107 
    108 def quit_func(m_account_info):
    109     # 退出
    110     exit('bye bye ...')
    111 
    112 
    113 def controller(m_account_info):
    114     # 功能分发器
    115     print('33[1;33m欢迎管理员 %s 登录33[0m'.center(35, '-') % m_account_info.get('account'))
    116     manager_choice = '''
    117     ------start------
    118     1. 添加账户
    119     2. 用户额度
    120     3. 冻结账户
    121     4. 退出
    122     ------end------
    123     '''
    124     dict_manager_info = {'1': add_acount, '2': credit_account, '3': freeze_account, '4': quit_func}
    125     while True:
    126         print(manager_choice)
    127         num = input('num>>>:').strip()
    128         if not num:
    129             continue
    130         if num in dict_manager_info:
    131             dict_manager_info[num](m_account_info)
    132         else:
    133             print('33[1;31m请重新选择33[0m')
    134 
    135 
    136 def run():
    137     manager_account_info = login(manager_logger, MANAGER_ID)
    138     if manager_account_info:
    139         controller(manager_account_info)
    manager

    shopper.py

     1 # -*- coding:utf-8 -*-
     2 from conf.settings import GOODS
     3 from .auth import login
     4 from .main import (
     5     access_logger, checkout
     6 )
     7 
     8 
     9 def show_buy_goods(goods_buyed):
    10     # 展示购买的商品
    11     all_money = 0
    12     if len(goods_buyed) == 0:
    13         return all_money
    14     else:
    15         print('您已购买以下商品:'.center(20, '-'))
    16         for index, i in enumerate(goods_buyed, 1):
    17             print('%s. %s  %s' % (index, i['name'], i['price']))
    18             all_money += int(i['price'])
    19         return all_money
    20 
    21 
    22 def buy_goods(dict_goods):
    23     # 购买商品
    24     goods_buyed = []
    25     while True:
    26         choice = input('num(q退出并结算)>>>:').strip()
    27         if not choice:
    28             continue
    29         if choice == 'q':
    30             return show_buy_goods(goods_buyed)
    31         if choice in dict_goods:
    32             goods_buyed.append(dict_goods[choice])
    33             print('33[1;34m%s33[0m 加入购物车' % dict_goods[choice]['name'])
    34         else:
    35             print('33[1;31m重新选择33[0m')
    36 
    37 
    38 def show_goods():
    39     # 展示商品列表
    40     dict_goods = {}
    41     print('展示商品列表'.center(20,'-'))
    42     for index, i in enumerate(GOODS):
    43         dict_goods[str(index)] = i
    44         print('%d. %s   %d' % (index, i['name'], i['price']))
    45     return dict_goods
    46 
    47 
    48 def run():
    49     account_info = login(access_logger)
    50     if account_info['is_auth'] is True:
    51         all_money = buy_goods(show_goods())
    52         checkout(account_info, all_money)
    shopper

    ***.json

    1 {"id": 999, "password": "4940e231b912f39abd7d98c81bed7053", "salt": "}fH>@&0o", "balance": 15000, "credit": 15000, "enroll_date": "2016-01-01", "expire_date": "2021-01-01", "pay_day": 22, "status": 0}
    ***.json

    account_sample.py

     1 # -*- coding:utf-8 -*-
     2 import json
     3 import random
     4 import string
     5 from hashlib import md5
     6 
     7 salt = ''.join(random.sample(string.digits + string.ascii_letters + string.punctuation, 8))
     8 md5_value = md5()
     9 md5_value.update(b'123'+salt.encode('utf-8'))
    10 
    11 account_dic = {
    12     'id': 999,
    13     'password': md5_value.hexdigest(),
    14     'salt': salt,
    15     'balance': 15000,  # 账户余额
    16     'credit': 15000,  # 信用额度
    17     'enroll_date': '2016-01-01',
    18     'expire_date': '2021-01-01',
    19     'pay_day': 22,
    20     'status': 0  # 0 = normal, 1 = locked, 2 = disabled
    21 }
    22 
    23 print(json.dumps(account_dic))
    24 # json.dump(account_dic, open('./accounts/999.json', 'w', encoding='utf-8'))
    account_sample

    access.log

     1 2018-03-04 11:33:52 AM - access - CRITICAL - account:  - 登录失败次数超过3次
     2 2018-03-04 11:34:03 AM - access - INFO - account: 1000 - 登录成功
     3 2018-03-04 11:34:50 AM - access - INFO - account: 999 - 登录成功
     4 2018-03-04 11:35:57 AM - access - INFO - account: 1000 - 登录成功
     5 2018-03-04 11:38:23 AM - access - INFO - account: 1008 - 登录成功
     6 2018-03-04 11:39:29 AM - access - INFO - account: 1008 - 登录成功
     7 2018-03-04 11:40:17 AM - access - INFO - account: 1008 - 登录成功
     8 2018-03-04 11:41:40 AM - access - INFO - account: 1008 - 登录成功
     9 2018-03-04 11:43:41 AM - access - INFO - account: 1008 - 登录成功
    10 2018-03-04 11:46:12 AM - access - CRITICAL - account:  - 登录失败次数超过3次
    11 2018-03-04 11:46:19 AM - access - INFO - account: 1000 - 登录成功
    12 2018-03-04 11:50:57 AM - access - CRITICAL - account: 1010 - 登录失败次数超过3次
    13 2018-03-04 11:51:03 AM - access - INFO - account: 999 - 登录成功
    14 2018-03-04 11:51:08 AM - access - INFO - account: 1010 - 登录成功
    15 2018-03-04 11:51:49 AM - access - INFO - account: 999 - 登录成功
    16 2018-03-04 11:52:00 AM - access - INFO - account: 1010 - 登录成功
    17 2018-03-04 11:54:02 AM - access - INFO - account: 1000 - 登录成功
    18 2018-03-04 11:54:56 AM - access - INFO - account: 1000 - 登录成功
    19 2018-03-04 11:55:38 AM - access - INFO - account: 1000 - 登录成功
    20 2018-03-04 11:57:30 AM - access - INFO - account: 1000 - 登录成功
    21 2018-03-04 12:02:44 PM - access - INFO - account: 999 - 登录成功
    22 2018-03-04 12:02:57 PM - access - CRITICAL - account: 1000 - 登录失败次数超过3次
    23 2018-03-04 12:03:04 PM - access - INFO - account: 1000 - 登录成功
    24 2018-03-04 12:03:14 PM - access - INFO - account: 999 - 登录成功
    25 2018-03-04 12:05:04 PM - access - INFO - account: 999 - 登录成功
    access

    manager.log

     1 2018-03-04 11:34:18 AM - manager - CRITICAL - account: 123 - 登录失败次数超过3次
     2 2018-03-04 11:34:24 AM - manager - INFO - 管理员account: 999 - 登录成功
     3 2018-03-04 11:34:37 AM - manager - INFO - 管理员account:999 - 修改账号account:1000 - 修改冻结状态成功
     4 2018-03-04 11:35:25 AM - manager - INFO - 管理员account:999 - 添加账户account:900
     5 2018-03-04 11:35:38 AM - manager - INFO - 管理员account: 999 - 登录成功
     6 2018-03-04 11:35:52 AM - manager - INFO - 管理员account:999 - 修改账号account:1000 - 修改冻结状态成功
     7 2018-03-04 11:37:39 AM - manager - INFO - 管理员account:999 - 添加账户account:1008
     8 2018-03-04 11:38:03 AM - manager - INFO - 管理员account:999 - 修改账号account:1008 - 修改额度credit:1200.0
     9 2018-03-04 11:38:37 AM - manager - INFO - 管理员account:999 - 修改账号account:1008 - 修改冻结状态成功
    10 2018-03-04 11:41:48 AM - manager - INFO - 管理员account: 999 - 登录成功
    11 2018-03-04 11:41:52 AM - manager - INFO - 管理员account:999 - 修改账号account:1008 - 修改冻结状态成功
    12 2018-03-04 11:43:50 AM - manager - INFO - 管理员account:999 - 修改账号account:1008 - 修改冻结状态成功
    13 2018-03-04 11:48:13 AM - manager - CRITICAL - account: 1000 - 登录失败次数超过3次
    14 2018-03-04 11:48:19 AM - manager - INFO - 管理员account: 999 - 登录成功
    15 2018-03-04 11:48:26 AM - manager - INFO - 管理员account:999 - 添加账户account:1009
    16 2018-03-04 11:48:32 AM - manager - INFO - 管理员account:999 - 添加账户account:23
    17 2018-03-04 11:48:45 AM - manager - INFO - 管理员account:999 - 添加账户account:1010
    18 2018-03-04 11:49:36 AM - manager - INFO - 管理员account:999 - 修改账号account:1009 - 修改额度credit:1000.0
    19 2018-03-04 11:49:52 AM - manager - INFO - 管理员account:999 - 修改账号account:1009 - 修改冻结状态成功
    20 2018-03-04 11:50:31 AM - manager - INFO - 管理员account: 999 - 登录成功
    21 2018-03-04 11:50:38 AM - manager - INFO - 管理员account:999 - 添加账户account:123
    22 2018-03-04 11:56:32 AM - manager - INFO - 管理员account: 999 - 登录成功
    23 2018-03-04 11:56:38 AM - manager - INFO - 管理员account:999 - 修改账号account:1003 - 修改冻结状态成功
    24 2018-03-04 11:56:53 AM - manager - INFO - 管理员account:999 - 修改账号account:1003 - 修改冻结状态成功
    25 2018-03-04 12:03:37 PM - manager - INFO - 管理员account: 999 - 登录成功
    26 2018-03-04 12:03:45 PM - manager - INFO - 管理员account:999 - 修改账号account:999 - 修改额度credit:123.0
    27 2018-03-04 12:04:48 PM - manager - INFO - 管理员account:999 - 修改账号account:999 - 修改额度credit:15000.0
    manager

    transactions.log

     1 2018-03-04 11:36:10 AM - transactions - INFO - account: 1000 - account_type: withdraw - action: minus - interest: 0.05
     2 2018-03-04 11:36:31 AM - transactions - INFO - account: 1000 - account_type: pay_back - action: plus - interest: 0
     3 2018-03-04 11:36:34 AM - transactions - INFO - account: 1000 - account_type: pay_back - action: plus - interest: 0
     4 2018-03-04 11:37:02 AM - transactions - INFO - account: 1000 - account_type: transfer - action: minus - interest: 0.05
     5 2018-03-04 11:38:58 AM - transactions - INFO - account: 1008 - account_type: pay_back - action: plus - interest: 0
     6 2018-03-04 11:42:17 AM - transactions - INFO - account: 1008 - account_type: withdraw - action: minus - interest: 0.05
     7 2018-03-04 11:46:34 AM - transactions - INFO - account: 1000 - account_type: withdraw - action: minus - interest: 0.05
     8 2018-03-04 11:46:42 AM - transactions - INFO - account: 1000 - account_type: pay_back - action: plus - interest: 0
     9 2018-03-04 11:46:45 AM - transactions - INFO - account: 1000 - account_type: pay_back - action: plus - interest: 0
    10 2018-03-04 11:47:48 AM - transactions - INFO - account: 1000 - account_type: transfer - action: minus - interest: 0.05
    11 2018-03-04 11:51:15 AM - transactions - INFO - account: 1010 - account_type: consume - action: minus - interest: 0
    12 2018-03-04 11:52:08 AM - transactions - INFO - account: 1010 - account_type: withdraw - action: minus - interest: 0.05
    13 2018-03-04 11:55:22 AM - transactions - INFO - account: 1000 - account_type: pay_back - action: plus - interest: 0
    14 2018-03-04 11:55:41 AM - transactions - INFO - account: 1000 - account_type: withdraw - action: minus - interest: 0.05
    15 2018-03-04 11:55:47 AM - transactions - INFO - account: 1000 - account_type: pay_back - action: plus - interest: 0
    16 2018-03-04 11:56:04 AM - transactions - INFO - account: 1000 - account_type: pay_back - action: plus - interest: 0
    17 2018-03-04 11:56:06 AM - transactions - INFO - account: 1000 - account_type: pay_back - action: plus - interest: 0
    18 2018-03-04 11:57:35 AM - transactions - INFO - account: 1000 - account_type: consume - action: minus - interest: 0
    transactions

    github:https://github.com/alice-bj/atm


  • 相关阅读:
    Eclipse配置C++环境
    C++/C中的struct和typedef struct用法和区别
    推荐系统实践(项亮)— 第2章 利用用户行为数据
    推荐系统实践(项亮)— 第1章 好的推荐系统
    语录摘抄(二)
    语录摘抄(一)
    深度学习—BN的理解(一)
    代码题(63)— 字符串拷贝
    代码题(62)— 滑动窗口最大值
    目标检测 — NMS
  • 原文地址:https://www.cnblogs.com/alice-bj/p/8504381.html
Copyright © 2011-2022 走看看