zoukankan      html  css  js  c++  java
  • python练习_module022ATM+购物车

    需求

    • 额度 15000或自定义
    • 实现购物商城,买东西加入 购物车,调用信用卡接口结账
    • 可以提现,手续费5%
    • 支持多账户登录
    • 支持账户间转账
    • 记录每月日常消费流水
    • 提供还款接口
    • ATM记录操作日志 
    • 提供管理接口,包括添加账户、用户额度,冻结账户等。。。
    • 用户认证用装饰器

    目录结构


    module02-2-ATM
        ├── 流程图
        ├── README  
        ├── Atm #ATM主程目录  
        │   ├── __init__.py  
        │   ├── bin     #ATM 执行文件 目录  
        │   │   ├── __init__.py  
        │   │   ├── atm.py      #ATM 执行程序  
        │   │   └── manage.py   #ATM 管理端  
        │   ├── conf    #配置文件  
        │   │   ├── __init__.py  
        │   │   └── settings.py     #初始化数据:清空日志,删除用户信息,生成初始用户数据  
        │   ├── core    #主要程序逻辑都 在这个目录 里  
        │   │   ├── __init__.py  
        │   │   ├── accounts.py     #用于从文件里加载和存储账户数据  
        │   │   ├── auth.py         #用户认证模块  
        │   │   ├── db_handler.py   #记录数据库信息  
        │   │   ├── logger.py       #日志记录模块  
        │   │   ├── main.py         #主逻辑交互程序  
        │   │   └── transaction.py  #执行 记账\还钱\取钱等 所有的与账户金额相关的操作  
        │   ├── db      #用户数据存储的地方  
        │   │   ├── __init__.py  
        │   │   ├── account_sample.py   #生成一个初始的账户数据 ,把这个数据存成一个以这个账户id为文件名的文件,放在accounts目录  
        │   │   └── accounts            #存各个用户的账户数据 ,一个用户一个文件  
        │   │       └── 1 #初始用户tom示例文件  
        │   │       └── 2 #初始用户lily示例文件     
        │   └── log     #日志目录  
        │       ├── __init__.py  
        │       ├── access.log          #用户访问的相关日志  
        │       └── transactions.log    #所有的交易日志  
        └── ShoppingMall #电子商城程序
            └── __init__.py
            └── acc.pkl             #存储商城用户数据,由make_acc.py生成
            └── make_acc.py         #生产初始商城用户数据
            └── shopping_cart.py    #电子商城主程序
    

    代码


     1 #!  /usr/bin/env python3
     2 #   -*- coding:utf-8 -*-
     3 #   Author:Jailly
     4 
     5 import sys,os
     6 
     7 sys.path.append(os.path.dirname(os.getcwd()))
     8 
     9 from core import main
    10 
    11 if __name__ == '__main__':
    12     main.main()
    atm.py
      1 #!  /usr/bin/env python3
      2 #   -*- coding:utf-8 -*-
      3 #   Author:Jailly
      4 #   添加/删除/冻结账户,设定账户额度
      5 
      6 import os,sys,pickle,time
      7 from imp import reload
      8 
      9 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
     10 
     11 from core import db_handler
     12 
     13 # 中英文对齐
     14 def alignment(str1, space, align = 'left'):
     15     length = len(str1.encode('gb2312'))
     16     space = space - length if space >=length else 0
     17     if align == 'left':
     18         str1 = str1 + ' ' * space
     19     elif align == 'right':
     20         str1 = ' '* space +str1
     21     elif align == 'center':
     22         str1 = ' ' * (space //2) +str1 + ' '* (space - space // 2)
     23     return str1
     24 
     25 
     26 # 查看账户[只显示用户名,信用额度,冻结状态]
     27 def show():
     28     import core.accounts
     29     reload(core.accounts)  # 每次获取账号信息都需重载
     30     acc_dict = core.accounts.acc_dict
     31 
     32     print('-'*40)
     33     print('|',alignment('用户名',10),'|',alignment('信用额度',10),'|',alignment('冻结状态',10),'|')
     34     for i in sorted(acc_dict.keys()):
     35         last_frozen_time = acc_dict[i]['last_frozen_time'] if acc_dict[i]['last_frozen_time'] else 0
     36         status = '×' if time.time() - last_frozen_time > 86400 else ''
     37 
     38         print('|',alignment(acc_dict[i]['user'],10),'|',alignment(str(acc_dict[i]['limit']),10),'|',
     39               alignment(status, 10),'|')
     40 
     41     print('-'*40)
     42 
     43     input('\033[1;36m请输入任意键按回车继续...\n\033[0m')
     44 
     45 # 添加账户
     46 def create():
     47     import core.accounts
     48     reload(core.accounts)  # 每次获取账号信息都需重载
     49     acc_dict = core.accounts.acc_dict
     50 
     51     while 1:
     52         # 输入用户名并判断其是否已存在
     53         while 1:
     54             user = input('请输入要添加的用户名:').strip()
     55             if user:
     56                 for i in list(acc_dict.values()):
     57                     if user == i['user']:
     58                         print('\033[1;31m该用户名已存在!\033[0m')
     59                         break
     60                 else:
     61                     break
     62             else:
     63                 print('\033[1;31m用户名不能为空!\033[0m')
     64 
     65         # 两次输入密码并判断输入是否相同
     66         while 1:
     67             pwd = input('请输入密码:')
     68             re_pwd= input('请再次输入密码:')
     69 
     70             if pwd:
     71                 if pwd == re_pwd:
     72                     break
     73                 else:
     74                     print('\033[1;31m两次密码输入不一致!请重新输入\033[0m')
     75             else:
     76                 print('\033[1;31m密码不能为空!\033[0m')
     77 
     78         # 设定额度
     79         while 1:
     80             limit = input('请设定信用额度(默认15000元):').strip()
     81             if limit :
     82                if limit.isdigit():
     83                    limit = int(limit)
     84                    break
     85                else:
     86                    print('\033[1;31m请输入整数!\033[0m')
     87 
     88             else:
     89                 limit = 15000
     90                 break
     91 
     92         print('\n要添加的账户信息为:')
     93         print('-'*25)
     94         print('用户名:%s'%user)
     95         print('密码:%s'%pwd)
     96         print('信用额度:%d'%limit)
     97         print('-' * 25)
     98 
     99         confirm = input('确定吗?(y/n)')
    100 
    101         if confirm.lower() == 'n':
    102             continue
    103         else:
    104             break
    105 
    106     new_id = max(list(acc_dict.keys())) + 1 if acc_dict else 1
    107     new_accfile_path = os.path.join(core.accounts.acc_path,str(new_id))
    108     new_acc = {'user':user,
    109                'pwd':pwd,
    110                'limit':limit,
    111                'available_limit':limit,
    112                'last_login_time':None,
    113                'last_frozen_time':None}
    114 
    115     with open(new_accfile_path,'wb') as f:
    116         pickle.dump(new_acc,f)
    117 
    118     print('用户 \033[1;36m%s\033[0m 已添加,用户文件路径为 \033[1;36m%s\033[0m\n'%(user,new_accfile_path))
    119 
    120 
    121 # 删除用户
    122 def delete():
    123     import core.accounts
    124     reload(core.accounts)  # 每次获取账号信息都需重载
    125     acc_dict = core.accounts.acc_dict
    126 
    127     user = input('请输入您要删除的用户名:').strip()
    128 
    129     for i in acc_dict.keys():
    130         if user == acc_dict[i]['user']:
    131             os.remove(os.path.join(core.accounts.acc_path,str(i)))
    132             print('用户 \033[1;31m%s\033[0m 已删除'%user)
    133             break
    134     else:
    135         print('\033[1;31m用户名不存在!\033[0m')
    136 
    137 
    138 # 冻结用户
    139 def frozen():
    140     import core.accounts
    141     reload(core.accounts)  # 每次获取账号信息都需重载
    142     acc_dict = core.accounts.acc_dict
    143 
    144     user = input('请输入您要冻结的用户名:').strip()
    145     for i in acc_dict:
    146         if acc_dict[i]['user'] == user:
    147             acc_dict[i]['last_frozen_time'] = time.time()
    148 
    149             # 写入数据库
    150             db_handler.write(i,acc_dict[i])
    151 
    152             print('\033[1;31m%s\033[0m 已冻结,将于 \033[1;31m%s\033[0m 解冻\n' % (user,
    153                                                                     time.asctime(time.localtime(time.time() + 86400))))
    154 
    155             break
    156     else:
    157         print('\033[1;31m用户名不存在!\033[0m')
    158 
    159 
    160 # 设置额度
    161 def set_limit():
    162     import core.accounts
    163     reload(core.accounts)  # 每次获取账号信息都需重载
    164     acc_dict = core.accounts.acc_dict
    165 
    166     user = input('请输入用户名:').strip()
    167     limit = input('请设置信用额度:').strip()
    168 
    169     for i in acc_dict:
    170         if user == acc_dict[i]['user']:
    171             if limit.isdigit():
    172                 limit = int(limit)
    173                 acc_dict[i]['limit'] = limit
    174 
    175                 #写入数据库
    176                 db_handler.write(i,acc_dict[i])
    177 
    178                 print('\033[1;31m%s\033[0m 的信用额度已被设置为 \033[1;31m%d\033[0m 元'%(user,limit))
    179 
    180             else:
    181                 print('\033[1;31m额度必须是整数!\033[0m')
    182             break
    183     else:
    184         print('\033[1;31m用户名不存在!\033[0m')
    185 
    186 
    187 # 主程序
    188 def main():
    189 
    190     while 1:
    191         print(' 操作列表 '.center(30, '-'))
    192         print('|', '1.查看用户'.center(25), '|')
    193         print('|', '2.添加用户'.center(25), '|')
    194         print('|', '3.删除用户'.center(25), '|')
    195         print('|', '4.冻结用户'.center(25), '|')
    196         print('|', '5.设置额度'.center(25), '|')
    197         print('|', '6.退出系统'.center(25), '|')
    198         print(''.center(34, '-'))
    199 
    200         choice = input('请输入您要进行的操作编号<1|2|3|4|5|6>:').strip()
    201 
    202         if choice in ['1','2','3','4','5','6']:
    203             if choice == '1':
    204                 show()
    205 
    206             elif choice == '2':
    207                 create()
    208 
    209             elif choice == '3':
    210                 delete()
    211 
    212             elif choice == '4':
    213                 frozen()
    214 
    215             elif choice == '5':
    216                 set_limit()
    217 
    218             elif choice == '6':
    219                 exit()
    220 
    221         else:
    222             print('\033[1;31m请输入正确的操作编号!\033[0m')
    223 
    224 
    225 if __name__ == '__main__':
    226     main()
    manage.py
     1 #!  /usr/bin/env python3
     2 #   -*- coding:utf-8 -*-
     3 #   Author:Jailly
     4 #   用于从文件里加载和存储账户数据
     5 
     6 import os,pickle
     7 
     8 acc_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'db', 'accounts')
     9 acc_filenames_list = os.listdir(acc_path)
    10 acc_dict = {}
    11 
    12 for i in acc_filenames_list:
    13     acc_file_path = os.path.join( acc_path,i )
    14 
    15     with open(acc_file_path,'rb') as f:
    16         acc_dict[int(i)] = pickle.load(f)
    17 
    18 # for i in acc_dict.values():
    19 #     print(i)
    accounts.py
     1 #!  /usr/bin/env python3
     2 #   -*- coding:utf-8 -*-
     3 #   Author:Jailly
     4 #   用户认证
     5 
     6 import os,sys,time
     7 
     8 sys.path.append(os.path.dirname(os.path.dirname(os.getcwd())))
     9 
    10 from Atm.core import accounts,logger,db_handler
    11 
    12 acc_dict = accounts.acc_dict
    13 current_user_id = None
    14 
    15 def auth(func):
    16     def wrapper(*args,**kwargs):
    17         n = 0
    18         flag = 0
    19         while n<3:
    20             user_input = input('请输入用户名:').strip()
    21             pwd_input = input('请输入密码:').strip()
    22 
    23             for i in acc_dict:
    24 
    25                 if user_input == acc_dict[i]['user'] and pwd_input == acc_dict[i]['pwd']:
    26 
    27                     last_frozen_time = acc_dict[i]['last_frozen_time'] if acc_dict[i]['last_frozen_time'] else 0
    28                     # 未冻结
    29                     if time.time() - last_frozen_time > 86400:
    30                         # 将登陆时间写入数据库
    31                         acc_dict[i]['last_login_time'] = time.time()  # 时间戳,用于数据库记录
    32                         db_handler.write(i,acc_dict[i])
    33 
    34                         # 日志记录
    35                         access_time = time.asctime()  # 时间格式化字符串,用于日志记录
    36                         logger.access_record(user_input,access_time)
    37 
    38                         # 传递给core.main,表明当前用户
    39                         global current_user_id
    40                         current_user_id = i
    41 
    42                         flag = 1
    43                         return func(*args,**kwargs)
    44 
    45                     # 已冻结
    46                     else:
    47                         print('\033[1;31m该账户已冻结!\033[0m')
    48                         break
    49             else:
    50                 print('\033[1;31m您输入的用户名或密码不正确,请重新输入\033[0m')
    51 
    52             if flag:
    53                 break
    54 
    55             n += 1
    56 
    57         else:
    58             print('\033[1;31m输入错误次数过多,程序关闭!\033[0m')
    59             exit()
    60 
    61 
    62 
    63     return wrapper
    auth.py
     1 #!  /usr/bin/env python3
     2 #   -*- coding:utf-8 -*-
     3 #   Author:Jailly
     4 #   数据库连接引擎
     5 
     6 import os,pickle
     7 
     8 db_path = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))),'db','accounts' )
     9 
    10 def write(id,user_info):
    11     acc_file_path = os.path.join(db_path, str(id))
    12     with open(acc_file_path, 'wb') as f:
    13         pickle.dump(user_info, f)
    db_hander.py
     1 #!  /usr/bin/env python3
     2 #   -*- coding:utf-8 -*-
     3 #   Author:Jailly
     4 #   日志记录
     5 
     6 import os
     7 
     8 log_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),'log')
     9 access_log_path = os.path.join(log_path,'access.log')
    10 transctions_log_path = os.path.join(log_path,'transactions.log')
    11 
    12 def access_record(user,access_time):
    13 
    14     with open(access_log_path,'a',encoding='utf-8') as f:
    15         record = '{user} accesses at {time}\n'.format(user=user,time=access_time)
    16         f.write(record)
    17 
    18 
    19 def transactions_record(user,type,amount,time,handing_fee=0,to_who=None):
    20     if type == 'withdraw':
    21         with open(transctions_log_path,'a',encoding='utf-8') as f:
    22             record = '{user} {type}s ¥{amount}(handing fee:{handing_fee}) at {time}\n' \
    23                 .format(user=user,type=type,amount=amount,handing_fee=handing_fee,time=time)
    24             f.write(record)
    25 
    26     elif type == 'repay':
    27         with open(transctions_log_path,'a',encoding='utf-8') as f:
    28             record = '{user} {type}s ¥{amount} at {time}\n'.format(user=user,type=type,amount=amount,time=time)
    29             f.write(record)
    30 
    31     elif type == 'transfer':
    32         with open(transctions_log_path,'a',encoding='utf-8') as f:
    33             record = '{user} {type}s ¥{amount} to {to_who} at {time}\n' \
    34                 .format(user=user,type=type,amount=amount,to_who=to_who,time=time)
    35             f.write(record)
    36 
    37     elif type == 'receive':
    38         with open(transctions_log_path,'a',encoding='utf-8') as f:
    39             record = '{user} {type}s ¥{amount} from {to_who} at {time}\n' \
    40                 .format(user=user,type=type,amount=amount,to_who=to_who,time=time)
    41             f.write(record)
    logger.py
     1 #!  /usr/bin/env python3
     2 #   -*- coding:utf-8 -*-
     3 #   Author:Jailly
     4 
     5 import os,sys
     6 
     7 sys.path.append(os.path.dirname(os.getcwd()))
     8 
     9 from core import auth,transaction,accounts
    10 
    11 @auth.auth
    12 def main():
    13     id = auth.current_user_id
    14     print('\033[1;36m%s\033[0m,欢迎进入atm操作系统'%accounts.acc_dict[id]['user'])
    15 
    16     if id:
    17         while 1:
    18             print('操作菜单'.center(30,'-'))
    19             print('| 1. 账户信息'.ljust(28,' '),'|')
    20             print('| 2. 提现'.ljust(30,' '),'|')
    21             print('| 3. 还款'.ljust(30,' '),'|')
    22             print('| 4. 转账'.ljust(30,' '),'|')
    23             print('| 5. 账单'.ljust(30,' '),'|')
    24             print('| 6. 退出'.ljust(30,' '),'|')
    25             print('-'*34)
    26 
    27             operation = input('请输入您想要执行的操作编号(1|2|3|4|5|6):').strip()
    28             if operation == '1' :
    29                 transaction.acc_info(id)
    30 
    31             elif operation == '2' :
    32                 transaction.withdraw(id)
    33 
    34             elif operation == '3' :
    35                 transaction.repay(id)
    36 
    37             elif operation == '4' :
    38                 transaction.transfer(id)
    39 
    40             elif operation == '5':
    41                 transaction.bill(id)
    42 
    43             elif operation == '6':
    44                 break
    45 
    46             else:
    47                 print('\n\033[1;31m输入错误,请重新输入\033[0m')
    48 
    49         print('谢谢您的使用,再见!')
    50 
    51 if __name__ == '__main__':
    52     main()
    main.py
      1 #!  /usr/bin/env python3
      2 #   -*- coding:utf-8 -*-
      3 #   Author:Jailly
      4 
      5 import os,sys,time
      6 from imp import reload
      7 
      8 sys.path.append(os.path.dirname(os.path.dirname(os.getcwd())))
      9 
     10 from Atm.core import auth,db_handler,logger
     11 import Atm.core.accounts
     12 
     13 
     14 # 显示账户信息
     15 def acc_info(id):
     16     reload(Atm.core.accounts)
     17     acc_dict = Atm.core.accounts.acc_dict[id]
     18     user = acc_dict['user']
     19     limit = acc_dict['limit']
     20     available_limit = acc_dict['available_limit']
     21     need_repay = limit - available_limit
     22     last_login_time = time.asctime() if not acc_dict['last_login_time'] else \
     23         time.asctime(time.localtime(acc_dict['last_login_time']))
     24 
     25     print('账户信息'.center(55,'-'))
     26 
     27     print('''
     28 用户名:\t\t%s
     29 信用额度:\t\t%s
     30 可用额度:\t\t%s
     31 待还款:\t\t%s
     32 最近登陆时间:\t%s    
     33     '''%(user,limit,available_limit,need_repay,last_login_time))
     34 
     35     print(''.ljust(58,'-'))
     36 
     37     input('\033[1;36m输入任意键按回车继续...\033[0m\n')
     38 
     39 # 提现
     40 def withdraw(id):
     41     reload(Atm.core.accounts)
     42     acc_dict = Atm.core.accounts.acc_dict[id]
     43     user = acc_dict['user']
     44 
     45     while 1:
     46         available_limit = acc_dict['available_limit']  # 出错则初始化可用额度
     47 
     48         withdraw_amount = input('请输入取现金额([\033[1;36mb\033[0m]:返回上一级;[\033[1;36mq\033[0m]:退出系统):').strip()
     49         if withdraw_amount.isdigit():
     50             withdraw_amount = int(withdraw_amount)
     51             handing_fee = int(withdraw_amount*0.05)
     52             available_limit -= int(withdraw_amount*1.05)
     53 
     54             if not withdraw_amount%100:
     55                 if available_limit >= 0:
     56                     acc_dict['available_limit'] = available_limit
     57                     withdraw_time = time.asctime()
     58                     acc_dict['transaction_record'].append((withdraw_time,'提现',withdraw_amount,handing_fee,''))
     59 
     60                     # 模拟出钞
     61                     print('出钞中',end='')
     62                     for i in range(3):
     63                         sys.stdout.write('.')
     64                         sys.stdout.flush()
     65                         time.sleep(0.5)
     66                     print('\n请从取钞口取出钞票,取钞时请注意安全',end='')
     67                     for i in range(3):
     68                         sys.stdout.write('.')
     69                         sys.stdout.flush()
     70                         time.sleep(0.5)
     71 
     72                     print('\n本次取现 \033[1;31m%d\033[0m 元,手续费 \033[1;31m%d\033[0m 元,您的当前可用额度为 \033[1;31m%d\033[0m 元'% \
     73                           (withdraw_amount,int(withdraw_amount*0.05),available_limit))
     74 
     75                     # 写入账户数据库
     76                     db_handler.write(id,acc_dict)
     77 
     78                     # 记录日志
     79                     logger.transactions_record(user,'withdraw',withdraw_amount,withdraw_time,handing_fee)
     80 
     81                     input('\n\033[1;36m取款结束后请按任意键继续...\033[0m\n')
     82                     break
     83 
     84                 else:
     85                     print('\033[1;31m取款金额超出可用额度,请重试!\033[0m')
     86             else:
     87                 print('\033[1;31m提现金额只能是100的整数倍!\033[0m')
     88 
     89         elif withdraw_amount == 'b':
     90             break
     91 
     92         elif withdraw_amount == 'q':
     93             exit()
     94 
     95         else:
     96             print('\033[1;31m金额必须输入整数!\033[0m')
     97 
     98 
     99 # 还款
    100 def repay(id):
    101     reload(Atm.core.accounts)
    102     acc_dict = Atm.core.accounts.acc_dict[id]
    103     user= acc_dict['user']
    104     available_limit = acc_dict['available_limit']
    105     limit = acc_dict['limit']
    106 
    107     while 1:
    108         repay_amount = input('请输入还款金额:').strip()
    109 
    110         if repay_amount.isdigit():
    111             repay_amount = int(repay_amount)
    112 
    113             if available_limit + repay_amount <= limit:
    114                 acc_dict['available_limit'] = available_limit + repay_amount
    115                 repay_time = time.asctime()
    116                 acc_dict['transaction_record'].append((repay_time,'还款',repay_amount,0,''))
    117 
    118                 # 模拟还款
    119                 print('连接您绑定的银行卡',end='')
    120                 for i in range(3):
    121                     sys.stdout.write('.')
    122                     sys.stdout.flush()
    123                     time.sleep(0.5)
    124 
    125                 print('\n处理还款请求',end='')
    126                 for i in range(3):
    127                     sys.stdout.write('.')
    128                     sys.stdout.flush()
    129                     time.sleep(0.5)
    130 
    131                 print('\n交易完成!\n您已还款 \033[1;31m%d\033[0m 元,您的当前可用额度为 \033[1;31m%d\033[0m 元'% \
    132                       (repay_amount,acc_dict['available_limit']))
    133 
    134                 # 写入账户数据库
    135                 db_handler.write(id, acc_dict)
    136 
    137                 # 记录日志
    138                 logger.transactions_record(user,'repay',repay_amount,repay_time)
    139 
    140                 input('\033[1;36m输入任意键按回车继续...\033[0m\n')
    141                 break
    142             else:
    143                 print('\033[1;31m还款金额已超出信用额度,请重试!\033[0m')
    144 
    145         else:
    146             print('\033[1;31m金额必须输入整数!\033[0m')
    147 
    148 # 转账
    149 def transfer(id):
    150     while 1:
    151         reload(Atm.core.accounts)
    152         accs_dict = Atm.core.accounts.acc_dict
    153         acc_dict = accs_dict[id]
    154 
    155         to_user = input('对方账户:').strip()
    156 
    157         for i in accs_dict:
    158             if to_user == accs_dict[i]['user']:
    159                 to_id = i
    160                 break
    161         else:
    162             print('账户\033[1;31m %s \033[0m不存在!'%to_user)
    163             continue
    164 
    165         transfer_amount = input('转账金额:').strip()
    166 
    167         if transfer_amount.isdigit():
    168             transfer_amount = int(transfer_amount)
    169 
    170 
    171             if transfer_amount <= acc_dict['available_limit']:
    172                 if accs_dict[to_id]['available_limit'] + transfer_amount <= accs_dict[to_id]['limit']:
    173 
    174                     # 本账号记录信息
    175                     acc_dict['available_limit'] -= transfer_amount
    176                     transfer_time = time.asctime()
    177                     acc_dict['transaction_record'].append((transfer_time,'转账',transfer_amount,0,to_user))
    178 
    179                     # 对方账号记录信息
    180                     accs_dict[to_id]['available_limit'] += transfer_amount
    181                     accs_dict[to_id]['transaction_record'].append((transfer_time,'收款',transfer_amount,0,to_user))
    182 
    183                     # 模拟转账
    184                     print('连接对方账户',end='')
    185                     for i in range(3):
    186                         sys.stdout.write('.')
    187                         sys.stdout.flush()
    188                         time.sleep(0.5)
    189 
    190                     print('\n处理转账请求',end='')
    191                     for i in range(3):
    192                         sys.stdout.write('.')
    193                         sys.stdout.flush()
    194                         time.sleep(0.5)
    195 
    196                     print('\n交易完成!\n您向 %s 转账 \033[1;31m%d\033[0m 元,您的当前可用额度为 \033[1;31m%d\033[0m 元'% \
    197                         (to_user,transfer_amount,acc_dict['available_limit']))
    198 
    199                     # 写入账户数据库
    200                     db_handler.write(id,acc_dict)
    201                     db_handler.write(to_id,accs_dict[to_id])
    202 
    203                     # 日志记录
    204                     logger.transactions_record(acc_dict['user'],'transfer',transfer_amount,transfer_time,to_who=to_user)
    205                     logger.transactions_record(to_user,'receive',transfer_amount,transfer_time,to_who=acc_dict['user'])
    206 
    207                     input('\033[1;36m输入任意键按回车继续...\033[0m\n')
    208                     break
    209 
    210                 else:
    211                     print('\033[1;31m转账金额超出对方信用额度\033[0m')
    212             else:
    213                 print('\033[1;31m转账金额超出本账号当前可用额度\033[0m')
    214 
    215         else:
    216             print('\033[1;31m金额必须输入整数!\033[0m')
    217 
    218 
    219 
    220 # 支付
    221 @auth.auth
    222 def pay(payment_amount,to_who):
    223     reload(Atm.core.accounts)
    224     id = auth.current_user_id
    225     acc_dict = Atm.core.accounts.acc_dict[id]
    226     available_limit = acc_dict['available_limit']
    227 
    228     # print(payment_amount,available_limit)
    229 
    230     if payment_amount <= available_limit:
    231         acc_dict['available_limit'] -= payment_amount
    232         pay_time = time.asctime()
    233         acc_dict['transaction_record'].append((pay_time,'支付',payment_amount,0,to_who))
    234 
    235         # 写入账户数据库
    236         db_handler.write(id, acc_dict)
    237 
    238         # 日志记录
    239         logger.transactions_record(acc_dict['user'], 'pay', payment_amount, pay_time, to_who=to_who)
    240 
    241         return 1
    242 
    243     else:
    244         return 0
    245 
    246 # 消费记录
    247 def bill(id):
    248     reload(Atm.core.accounts)
    249     acc_dict = Atm.core.accounts.acc_dict[id]
    250 
    251     print(' 账单 '.center(80,'-'))
    252     print('时间'.ljust(28),'交易类型\t'.ljust(10),'金额\t'.ljust(10),'手续费\t'.ljust(10),'对方账户')
    253     for i in sorted(acc_dict['transaction_record']):
    254         print(i[0].ljust(30),i[1].ljust(12), str(i[2]).ljust(13), str(i[3]).ljust(14),i[4])
    255 
    256     print('-'*84)
    257     print('|',('信用额度: %d'%acc_dict['limit']).center(20),'|',
    258           ('可用额度: %d'%acc_dict['available_limit']).center(20),'|',
    259           ('待还款: %d'%(acc_dict['limit'] - acc_dict['available_limit'])).center(20),'|')
    260     print('-' * 84)
    261 
    262     input('\033[1;36m输入任意键按回车继续...\033[0m\n')
    263 
    264 # if __name__ == '__main__':
    265 #     x = pay(10,'tianmao')
    266 #     print(x)
    transaction.py
     1 #!  /usr/bin/env python3
     2 #   -*- coding:utf-8 -*-
     3 #   Author:Jailly
     4 #   生成初始账户数据
     5 
     6 import pickle,os
     7 
     8 accounts_path = os.path.join((os.path.dirname(__file__)),'accounts')
     9 
    10 acc1 = {'user':'tom',               # 用户名
    11         'pwd':'123',                # 密码
    12         'limit':15000,              # 信用额度
    13         'available_limit':15000,    # 可用额度
    14         'transaction_record':[],    # 交易记录(时间,类型,金额,手续费,对方账户)
    15         'last_login_time':None,     # 最近登录时间
    16         'last_frozen_time':None}    # 最近冻结时间
    17 
    18 acc2 = {'user':'lily',              # 用户名
    19         'pwd':'123',                # 密码
    20         'limit':15000,              # 信用额度
    21         'available_limit':15000,    # 可用额度
    22         'transaction_record':[],    # 交易记录(时间,类型,金额,手续费,对方账户)
    23         'last_login_time':None,     # 最近登录时间
    24         'last_frozen_time':None}    # 最近冻结时间
    25 
    26 def init_account():
    27     with open(os.path.join(accounts_path,'1'),'wb') as f:
    28         pickle.dump(acc1,f)
    29 
    30     with open(os.path.join(accounts_path,'2'),'wb') as f:
    31         pickle.dump(acc2,f)
    32 
    33 if __name__ == '__main__':
    34     init_account()
    account_sample.py
     1 #! /usr/bin/env python3
     2 # -*- encoding:utf-8 -*-
     3 # Author:Jailly
     4 
     5 import  pickle
     6 
     7 acc = {
     8     'tom':
     9         {'pwd':'123',
    10          'shopping cart':[],
    11          'payment amount':0},
    12     'lily':
    13         {'pwd':'123',
    14         'shopping cart':[],
    15          'payment amount': 0}
    16 }
    17 
    18 with open('acc.pkl','wb') as f:
    19     pickle.dump(acc,f)
    20 
    21 print('已生成初始账号(\033[1;36m tom、lily \033[0m)')
    make_acc
      1 #! /usr/bin/env python3
      2 # -*- encoding:utf-8 -*-
      3 # Author:Jailly
      4 
      5 import pickle,os,sys,time
      6 from imp import reload
      7 
      8 sys.path.append(os.path.dirname(os.getcwd()))
      9 
     10 import Atm.core.transaction
     11 
     12 # 用户登陆
     13 def login():
     14     count = 0
     15     while count < 3:
     16         name_input = input('用户名:').strip()
     17         pwd_input = input('密码:')
     18 
     19         if name_input in acc:
     20             if acc[name_input]['pwd'] == pwd_input:
     21                 return name_input
     22             else:
     23                 print('\033[1;31m密码错误\033[0m')
     24                 count += 1
     25         else:
     26             print('\033[1;31m您输入的用户名不存在,请重新输入\033[0m')
     27     else:
     28         print('错误次数太多,程序关闭...')
     29         exit()
     30 
     31 
     32 # 查看购物车
     33 def show_cart(name):
     34 
     35     with open('acc.pkl', 'rb') as f:
     36         acc = pickle.load(f)
     37 
     38     if acc[name]['shopping cart']:
     39         print('-' * 51)
     40         print('|', 'shopping cart'.center(47, ' '), '|')
     41         print('-' * 51)
     42         for i in acc[name]['shopping cart']:
     43             print('|', i[1][0].center(22, ' '), '|', str(i[1][1]).center(22, ' '), '|')
     44             print('-' * 51)
     45         print('|', ('待付款: %d 元'%acc[name]['payment amount']).center(42, ' '), '|')
     46         print('-' * 51)
     47     else:
     48         print('您的购物车为空')
     49     input('\033[1;36m输入任意键按回车继续...\033[0m')
     50 
     51 
     52 # 移出购物车
     53 def remove(name):
     54     # 实时读取用户数据库
     55     with open('acc.pkl', 'rb') as f:
     56         acc = pickle.load(f)
     57 
     58     if acc[name]['shopping cart']:
     59         while 1:
     60             choice = input('请输入您想要移出的商品编号([\033[1;36mb\033[0m]:返回):').strip()
     61 
     62             if choice.isdigit():
     63                 choice = int(choice)
     64                 for i in acc[name]['shopping cart']:
     65                     if choice == i[0]:
     66                         acc[name]['shopping cart'].remove(i)
     67                         acc[name]['payment amount'] -= i[1][1]
     68 
     69                         # 实时写入用户数据库
     70                         with open('acc.pkl','wb') as f:
     71                             pickle.dump(acc,f)
     72 
     73                         print('\033[1;36m%s\033[0m 已移出购物车'%i[1][0])
     74                         break
     75 
     76             elif choice == 'b':
     77                 break
     78 
     79             else:
     80                 print('\033[1;31m请输入正确的商品编号!\033[0m')
     81     else:
     82         print('\033[1;31m您的购物车为空!\033[0m')
     83 
     84 
     85 # 调用支付接口
     86 def pay(name,to_who):
     87 
     88     reload(Atm.core.transaction)
     89 
     90     with open('acc.pkl', 'rb') as f:
     91         acc = pickle.load(f)
     92 
     93     print('连接ATM系统', end='')
     94     for i in range(3):
     95         sys.stdout.write('.')
     96         sys.stdout.flush()
     97         time.sleep(0.5)
     98     print()
     99     # print('\n 待支付 %s'%acc[name]['payment amount'] )
    100 
    101     payment_amount = acc[name]['payment amount']
    102 
    103     flag = Atm.core.transaction.pay(payment_amount, to_who)
    104     # print(flag)
    105 
    106 
    107 
    108     if flag:
    109         acc[name]['shopping cart'] = []
    110         acc[name]['payment amount'] = 0
    111 
    112         # 实时写入用户数据库
    113         with open('acc.pkl', 'wb') as f:
    114             pickle.dump(acc,f)
    115 
    116         print('\n\033[5m支付成功!已付款 %d 元\033[0m' % payment_amount)
    117 
    118     else:
    119         print('\033[1;31m信用卡的可用额度不足,交易取消\033[0m')
    120 
    121 
    122 # 选购商品
    123 def shopping(name_input):
    124 
    125     while 1:
    126         # 显示商品列表
    127         print(' Product List '.center(50,'-'))
    128         for k,v in enumerate(product_list):
    129             print(('| %s\t -> \t%s'%(k,v[0])).ljust(30),str(v[1]).ljust(14),'|')
    130         print('-'*50)
    131 
    132         choice = input('请输入您想要购买的商品编号([\033[1;36ms\033[0m]:查看购物车;[\033[1;36mr\033[0m]:移出购物车;'
    133                        '[\033[1;36mp\033[0m]:付款;[\033[1;36mq\033[0m]:退出):').strip()
    134 
    135         # 选购商品 -> 加入购物车
    136         if choice.isdigit():
    137 
    138             with open('acc.pkl', 'rb') as f:  # 待支付 与 购物车 是中间变量
    139                 acc = pickle.load(f)
    140 
    141             choice = int(choice)
    142             if 0 <= choice < len(product_list):
    143                 acc[name_input]['shopping cart'].append((choice,product_list[choice]))
    144                 acc[name_input]['payment amount'] += product_list[choice][1]
    145 
    146                 print('\033[1;31m%s\033[0m 已加入购物车,待付款 \033[1;31m%d\033[0m 元'% \
    147                       (product_list[choice][0] , acc[name_input]['payment amount']))
    148 
    149                 # 实时写入用户数据库
    150                 with open('acc.pkl', 'wb') as f:
    151                     pickle.dump(acc, f)
    152 
    153             else:
    154                 print('抱歉,没有找到您选择的商品')
    155 
    156         # 查看购物车
    157         elif choice == 's':
    158             show_cart(name_input)
    159 
    160         # 移出购物车
    161         elif choice == 'r':
    162             remove(name_input)
    163 
    164         # 支付
    165         elif choice == 'p':
    166             pay(name_input,'ShoppingMall')
    167 
    168         # 退出
    169         elif choice == 'q':
    170 
    171             with open('acc.pkl', 'rb') as f:  # 待支付 与 购物车 是中间变量
    172                 acc = pickle.load(f)
    173 
    174             if acc[name_input]['shopping cart']:
    175                 empty_confirm = input('购物车中的商品还未支付购买,要现在支付吗?(y/n)')
    176                 if (empty_confirm.strip()).lower() != 'n':
    177                     pay(name_input,'ShoppingMall')
    178                 else:
    179                     print('感谢您的支持,再见!')
    180                     exit()
    181             else:
    182                 print('感谢您的支持,再见!')
    183                 exit()
    184 
    185         else:
    186             print('\033[1;31m请输入正确的商品编号\033[0m')
    187 
    188 
    189 # 主程序
    190 def main():
    191     name_input = login()
    192     shopping(name_input)
    193 
    194 
    195 if __name__ == '__main__':
    196 
    197     product_list = [
    198         ('IPhone', 5000),
    199         ('Mac Pro', 12000),
    200         ('xbox360', 2500),
    201         ('PlayStation3', 2000),
    202         ('bike', 1000),
    203         ('kindle', 150)
    204     ]
    205 
    206     with open('acc.pkl', 'rb') as f:
    207         acc = pickle.load(f)
    208 
    209     main()
    shopping_cart


  • 相关阅读:
    hdu1754线段树入门
    hdu1247 字典树模板
    完全背包 poj 1384
    hdu 1541 树状数入门
    hdu 2665 划分树模板
    winhex分析磁盘目录结构(未完待续)
    取出表单中元素的js代码
    c语言检测cpu大小端模式
    firefox的cookie
    c移位实现求余
  • 原文地址:https://www.cnblogs.com/jailly/p/6895351.html
Copyright © 2011-2022 走看看