需求
- 额度 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
时间: 2024-10-05 08:00:46