作业需求:
模拟实现一个ATM + 购物商城程序
- 额度 15000或自定义
- 实现购物商城,买东西加入 购物车,调用信用卡接口结账
- 可以提现,手续费5%
- 每月22号出账单,每月10号为还款日,过期未还,按欠款总额 万分之5 每日计息
- 支持多账户登录
- 支持账户间转账
- 记录每月日常消费流水
- 提供还款接口
- ATM记录操作日志
- 提供管理接口,包括添加账户、用户额度,冻结账户等。。。
- 用户认证用装饰器
源代码:
其他文件格式:
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 import time 4 import os 5 import re 6 ab_info ={'shop_user':None,'bank_user':'msj'} 7 8 def t_stamp(): 9 """返回一个时间戳""" 10 return time.strftime('%Y-%m-%d %X') 11 12 def add_user(name,pwd,type): 13 """ 14 添加账户 15 :param name: 16 :param pwd: 17 :param type: 账户种类 两种 account 和 bank 18 :return: 19 """ 20 if type =='account': 21 file = 'account_info.txt' 22 user_info ='%s|%s '%(name,pwd) 23 elif type =='bank': 24 file = 'bank_info.txt' 25 user_info ='%s|%s|0|15000 '%(name,pwd) 26 else: 27 print('非法操作2') 28 return 29 with open(r'%s'%file,mode='a',encoding='utf-8') as f: 30 f.write(user_info) 31 32 def acc_info(): 33 """ 34 :return: 返回account_info.txt中以字典形式{ 35 'msj': '123', 'scg': '123', 'lhy': '123', 'egon': '1234', 'flower': '123', 'fgh': '123', 'hua': '123'} 36 """ 37 account_info = {} 38 with open(r'account_info.txt',mode='r',encoding='utf-8') as f: 39 for line in f: 40 line = line.strip(' ') 41 if line != '': 42 u,v = line.split('|') 43 account_info[u] = v 44 return account_info 45 46 def bk_info(): 47 ''' 48 钱和信用额度都是浮点数类型 49 :return: {'msj': {'pwd': '123', 'money': 4600.0, 'credit': 15000.0}} 50 ''' 51 bank_user ={} 52 with open(r'bank_info.txt',mode='r',encoding='utf-8') as f: 53 for line in f: 54 line = line.strip(' ') 55 if line != '': 56 u,p,m,c = line.split('|') 57 bank_user[u]={'pwd':p,'money':float(m),'credit':float(c)} 58 return bank_user 59 60 def alter_money(name,money): 61 ''' 62 改变账号中的余额 63 :param name: 用户名 64 :param money: int 钱 65 :return: 66 ''' 67 user_info = bk_info() 68 user_info[name]['money']=user_info[name]['money']+money 69 # print(user_info[name]['money']) 70 with open(r'bank_info.txt',mode='w',encoding='utf-8') as f: 71 for k,v in user_info.items(): 72 msg = '{}|{}|{}|{} '.format(k,v['pwd'],v['money'],v['credit']) 73 f.write(msg) 74 75 def alter_credit(name,money): 76 ''' 77 改变账号中的信用额 78 :param name: 用户名 79 :param money: int 钱 80 :return: 81 ''' 82 user_info = bk_info() 83 user_info[name]['credit']=user_info[name]['credit']+money 84 # print(user_info[name]['money']) 85 with open(r'bank_info.txt',mode='w',encoding='utf-8') as f: 86 for k,v in user_info.items(): 87 msg = '{}|{}|{}|{} '.format(k,v['pwd'],v['money'],v['credit']) 88 f.write(msg) 89 90 def auth(kind): 91 def auth1(func): 92 def wrapper(*args,**kwargs): 93 if kind == 'shop': 94 account =ab_info['shop_user'] 95 elif kind =='bank': 96 account =ab_info['bank_user'] 97 if account is None: 98 print('please log in first') 99 else: 100 res = func(*args, **kwargs) 101 return res 102 return wrapper 103 return auth1 104 105 def is_number(num): 106 ''' 107 判断字符串是否为数字,包含整形和浮点型。 108 :param num: 109 :return: 110 ''' 111 pattern = re.compile(r'^[-+]?[-0-9]d*.d*|[-+]?.?[0-9]d*$') 112 result = pattern.match(num) 113 if result: 114 return True 115 else: 116 return False 117 118 @auth('bank') 119 def check_balance(): 120 '''查看余额''' 121 username = ab_info['bank_user'] 122 user_info= bk_info() 123 res = user_info[username]['money'] 124 print('当前账户余额:%s'%res) 125 return res 126 127 @auth('bank') 128 def check_credit(): 129 '''查看信用''' 130 username = ab_info['bank_user'] 131 user_info= bk_info() 132 res = user_info[username]['credit'] 133 print('当前账户信用额度:%s'%res) 134 return res 135 136 def log(type,msg): 137 """ 138 type 选项account用户日志文件、选项bank 银行日志文件、shopping 购物车文件、buy 写入shopping.log.txt 139 :param type: 选择写入的文件 140 :param msg: 写入的内容 141 :return: 142 """ 143 if type == 'account': 144 file = 'info_account.log.txt' 145 elif type == 'bank': 146 file = 'info_bank.log.txt' 147 elif type == 'buy': 148 file = 'shopping.log.txt' 149 elif type == 'shopping': 150 file = 'shoppingcart.txt' 151 else: 152 print('不符合要求操作') 153 return 154 with open(r'%s'%file,mode='a',encoding='utf-8') as f: 155 f.write(msg) 156 157 def read_hmd(type): 158 if type == 'shop': 159 file = 'shop_hmd.txt' 160 else: 161 file = 'bank_hmd.txt' 162 hmd = [] 163 with open('%s'%file,mode='r',encoding='utf-8') as f: 164 for i in f: 165 i = i.strip(' ') 166 if i != '': 167 hmd.append(i) 168 return hmd 169 170 @auth('bank') 171 def recharge(): 172 '''余额充值''' 173 current_user= ab_info['bank_user'] 174 check_balance() 175 while True: 176 choice = input('是否充值 Y/N>>:').strip() 177 if choice == 'Y' or choice =='y': 178 break 179 elif choice == 'N' or choice =='n': 180 print('exit') 181 return 182 else: 183 print('非法操作') 184 continue 185 while True: 186 money = input('请输入充值金额>>:').strip() 187 if is_number(money): 188 money = float(money) 189 if money<=0: 190 print('充值金额需要大于0') 191 continue 192 else: 193 t =t_stamp() 194 msg = '[INFO] [{}] [bank] {} 充值了 {} 元 '.format(t,current_user,money) 195 alter_money(current_user,money) 196 log('bank',msg) 197 print('recharge success') 198 return 199 else: 200 print('非法输入') 201 continue 202 203 def regist(): 204 ''' 205 注册功能 206 :return: 207 ''' 208 choice = input('请问你想要注册的账户:1、商城,2、银行。>>').strip() 209 if choice == '1': 210 users = acc_info() 211 elif choice == '2': 212 users = bk_info() 213 else: 214 print('非法操作1') 215 return 216 tag = True 217 while tag: 218 username = input('please input username>>').strip() 219 if username in users: 220 print('user is exist') 221 continue 222 break 223 while tag: 224 pwd1 = input('please input password>>').strip() 225 pwd2 = input('please config password>>').strip() 226 if pwd1 == pwd2: 227 if choice == '1': 228 add_user(username,pwd1,type='account')#添加account添加用户 229 t = t_stamp() 230 msg = '[INFO] [{}] [user] {} 注册了 '.format(t,username)#添加日志 231 log('account',msg) 232 print(msg) 233 return 234 else: 235 add_user(username, pwd1, type='bank')#添加bank添加用户 236 t = t_stamp() 237 msg = '[INFO] [{}] [bank] {} 注册了 '.format(t, username)#添加日志 238 log('bank', msg) 239 print(msg) 240 return 241 242 else: 243 print('password is difference') 244 245 def login(): 246 '''登录''' 247 choice = input('请问你想要登录的账户:1、商城,2、银行。>>').strip() 248 if choice == '1': 249 user_inf = acc_info() 250 t = 'shop_user' 251 type = 'shop' 252 elif choice == '2': 253 user_inf = bk_info() 254 t='bank_user' 255 type = 'bank' 256 else: 257 print('非法操作') 258 return 259 if ab_info[t] is None: 260 name = input('please input username>>:').strip() 261 pwd = input('please input password>>:').strip() 262 hmd = read_hmd(type) 263 if name in hmd: 264 print('该账户在黑名单') 265 return 266 if name in user_inf : 267 if choice == '1' and pwd == user_inf[name]: 268 print('login success') 269 ab_info[t] = name 270 elif pwd == user_inf[name]['pwd']: 271 print('login success') 272 ab_info[t] = name 273 else: 274 print('user or password is error') 275 else: 276 print('user or password is error') 277 else: 278 print('Please logoff and log in.') 279 280 @auth('bank') 281 def transfer(): 282 '''转账''' 283 user_info = bk_info() 284 while True: 285 name = input('please input transfer user(q to exit)>>:').strip() 286 if name == ab_info['bank_user']: 287 print('cannot transfer to yourself') 288 continue 289 elif name == 'q': 290 print('exit') 291 return 292 elif name in bk_info(): 293 money = input('please input transfer money>>: ').strip() 294 if is_number(money): 295 money = float(money) 296 else: 297 print('输入金额不正确') 298 return 299 if money > user_info[ab_info['bank_user']]['money']: 300 print('余额不足,无法转账') 301 return 302 t= t_stamp() 303 msg = '[INFO] [{}][bank] {} 向 {} 转账 {} '.format(t,ab_info['bank_user'],name,money) 304 alter_money(ab_info['bank_user'],-money) 305 alter_money(name,money) 306 log('bank',msg) 307 print(msg) 308 return 309 else: 310 print('user do not exist') 311 312 @auth('bank') 313 def repay(): 314 '''还款''' 315 user_info= bk_info() 316 current_user=ab_info['bank_user'] 317 credit_money = user_info[current_user]['credit'] 318 if credit_money>=15000: 319 print('没有使用信用额度') 320 return 321 print('需要还款额度:%s'%(15000-credit_money)) 322 while True: 323 repay_money = input('please input repay money(q to exit)>>:').strip() 324 if repay_money == 'q': 325 print('exit') 326 return 327 elif is_number(repay_money): 328 repay_money = float(repay_money) 329 if repay_money<=0: 330 print('please input number') 331 continue 332 elif repay_money>(15000-credit_money): 333 print('超过最大还款额度,请重新输入金额') 334 continue 335 else: 336 t= t_stamp() 337 msg = '[INFO][{}] [bank] {} 还款了 {} 元 '.format(t,current_user,repay_money) 338 alter_credit(current_user,repay_money) 339 log('bank',msg) 340 return 341 else: 342 print('非法操作') 343 continue 344 345 @auth('bank') 346 def withdraw(): 347 '''取款''' 348 user_info = bk_info() 349 current_user = ab_info['bank_user'] 350 while True: 351 draw_money = input('please input withdraw(q to exit)>>:').strip() 352 if draw_money == 'q': 353 print('exit') 354 return 355 elif is_number(draw_money): 356 draw_money = float(draw_money) 357 if draw_money > user_info[current_user]['money']: 358 print('money not enough') 359 continue 360 else: 361 print('withdraw %s yuan success' % draw_money) 362 t = t_stamp() 363 draw_money = draw_money * 1.05 364 msg = '[INFO] [{}] [bank] {} 取款 {} 元 '.format(t, current_user, draw_money) 365 alter_money(current_user, -draw_money) 366 log('bank', msg) 367 print(msg) 368 369 else: 370 print('非法操作') 371 372 @auth('bank') 373 def turnover(): 374 '''查看流水''' 375 current_user = ab_info['bank_user'] 376 with open(r'info_bank.log.txt',mode='r',encoding='utf-8') as f: 377 for line in f: 378 line=line.strip(' ') 379 if line != '': 380 l=line.rsplit(']',1) 381 if current_user in l[1]: 382 print(l[1]) 383 384 385 def add_shoppingcart(name,good,price,count): 386 '''添加购物车''' 387 log_msg = "%s|{'%s':{'price':%s,'count':%s}} "%(name,good,price,count) 388 log('shopping',log_msg) 389 390 @auth('shop') 391 def check_shoppingcart(): 392 ''' 393 检查当前用户购物车中的商品,并将商品信息返回 394 :return: 返回,为字典内包含列表形式 395 ''' 396 current_user = ab_info['shop_user'] 397 shopping_list = [] 398 with open(r'shoppingcart.txt',mode='r',encoding='utf-8') as f: 399 for line in f: 400 line = line.strip(' ') 401 if line != '': 402 l = line.split('|') 403 if l[0] == current_user: 404 shopping_list.append(eval(l[1])) 405 return shopping_list 406 407 def sum_money(shopping_list): 408 '''根据check_shoppingcart 返回的列表计算需要支付的钱款的总和''' 409 sum_m = 0 410 for item in shopping_list: 411 for i in item.values(): 412 sum_m = sum_m + i['price']*i['count'] 413 return sum_m 414 415 def clear_cart(name): 416 ''' 417 清空购物车 418 :param name: 419 :return: 420 ''' 421 with open(r'shoppingcart.txt',mode='r',encoding='utf-8') as rf, 422 open(r'shoppingcart.txt.swap',mode='w',encoding='utf-8') as wf: 423 for line in rf: 424 line = line.strip(' ') 425 if line != '': 426 if name in line: 427 line = '' 428 else: 429 line = line +' ' 430 wf.write(line) 431 os.remove('shoppingcart.txt') 432 os.rename('shoppingcart.txt.swap','shoppingcart.txt') 433 434 @auth('shop') 435 @auth('bank') 436 def buy(): 437 shop_user= ab_info['shop_user'] 438 bank_user = ab_info['bank_user'] 439 shopping_list = check_shoppingcart() 440 if shopping_list is []: 441 print('购物车中没有商品') 442 return 443 print('%s 购物车中 %s'%(shop_user,shopping_list)) 444 money = sum_money(shopping_list) 445 print('需支付 %s'%money) 446 while True: 447 choice = input('是否支付 Y/N>>:') 448 if choice == 'Y' or choice =='y': 449 break 450 elif choice == 'N' or choice =='n': 451 print('退出支付') 452 return 453 else: 454 print('非法操作') 455 continue 456 while True: 457 pay_wey = input('请选择支付方式:1.余额 2.信用额度(q to exit)>>:') 458 if pay_wey == '1': 459 paymoney = check_balance() 460 elif pay_wey =='2': 461 paymoney = check_credit() 462 elif pay_wey == 'q': 463 print('exit') 464 return 465 else: 466 print('非法操作') 467 continue 468 if paymoney <money: 469 print('账户中金额无法支付,请重新选择支付方式。') 470 continue 471 else: 472 if pay_wey == '1': 473 alter_money(bank_user,-money) 474 else: 475 alter_credit(bank_user,-money) 476 t = t_stamp() 477 bank_info = '[INFO] [{}] [bank] {} 消费 {} 元 '.format(t,bank_user,money) 478 log('bank',bank_info) 479 shop_info = '[INFO] [{}] [shop] {} 花费 {} 元购买了{} '.format(t,shop_user,money,shopping_list) 480 log('buy',shop_info) 481 clear_cart(shop_user) 482 print('buy success') 483 return 484 485 @auth('shop') 486 def shoppingcart(): 487 current_user=ab_info['shop_user'] 488 good_msg = [['coffee',30],['chicken',20],['iphone',8000],['macbook',12000],['car',100000]] 489 print('购物') 490 while True: 491 i = 0 492 for i in range(len(good_msg)): 493 print(i,good_msg[i]) 494 choice = input('please choice goods or exit(q)>>:').strip() 495 if choice == 'q': 496 print('exit') 497 # 显示购物车信息,提示是否购买 498 shopping_list = check_shoppingcart() 499 buy() 500 return 501 elif choice.isdigit(): 502 choice = int(choice) 503 else: 504 print('非法操作') 505 continue 506 if choice < len(good_msg): 507 while True: 508 count = input('please input goods number>>:').strip() 509 if count.isdigit(): 510 count = int(count) 511 if count <= 0: 512 print('数量必须大于0') 513 else: 514 show_msg = '{} {} add to shopping cart'.format(count,good_msg[choice][0]) 515 print(show_msg) 516 add_shoppingcart(current_user,good_msg[choice][0],good_msg[choice][1],count) 517 break 518 519 else: 520 print('非法操作') 521 continue 522 523 else: 524 print('没有对应的商品') 525 continue 526 527 @auth('shop') 528 def check_shoppinglog(): 529 current_user = ab_info['shop_user'] 530 with open(r'shopping.log.txt',mode = 'r',encoding='utf-8') as f: 531 for line in f: 532 line= line.strip(' ') 533 if line != '': 534 if current_user in line: 535 l=line.split(']',3) 536 print(l[3]) 537 538 def log_off(): 539 if ab_info['shop_user'] and ab_info['bank_user']: 540 while True: 541 choice = input('log off 1.shop 2.bank').strip(' ') 542 if choice =='1': 543 ab_info['shop_user'] = None 544 elif choice =='2': 545 ab_info['bank_user'] = None 546 else: 547 print('非法操作') 548 continue 549 return 550 elif ab_info['shop_user']: 551 ab_info['shop_user'] = None 552 elif ab_info['bank_user']: 553 ab_info['bank_user'] = None 554 else: 555 print('no account is login') 556 557 init_msg = """ 558 1.登录 559 2、注册 560 3、查看余额 561 4、购物 562 5、充值 563 6、转账 564 7、还款 565 8、取款 566 9、查看流水 567 10、查看购物车 568 11、查看信用额度 569 12、查看购买信息 570 13、支付 571 14、注销 572 0、退出 573 """ 574 575 init_dic={ 576 '1':login, 577 '2':regist, 578 '3':check_balance, 579 '4':shoppingcart, 580 '5':recharge, 581 '6':transfer, 582 '7':repay, 583 '8':withdraw, 584 '9':turnover, 585 '10':check_shoppingcart, 586 '11':check_credit, 587 '12':check_shoppinglog, 588 '13':buy, 589 '14':log_off 590 } 591 592 def chief(): 593 while True: 594 print(init_msg) 595 choice = input('请输入你想要的操作').strip() 596 if choice in init_dic: 597 init_dic[choice]() 598 elif choice == '0': 599 print('exit shopping') 600 return 601 else: 602 print('非法操作,请重新输入操作') 603 604 chief()
info_account.log.txt
[INFO] [2018-09-30 13:06:33] [user] lll 注册了 [INFO] [2018-09-30 13:09:46] [user] lhy 注册了 [INFO] [2018-09-30 14:22:43] [user] we 注册了
shopping.log.txt
[INFO] [2018-09-30 11:08:19] [shop] msj 花费 100 元购买了[{'chicken': {'price': 20, 'count': 2}}, {'coffee': {'price': 30, 'count': 2}}] [INFO] [2018-09-30 13:49:02] [shop] scg 花费 100 元购买了[{'coffee': {'price': 30, 'count': 2}}, {'chicken': {'price': 20, 'count': 2}}] [INFO] [2018-09-30 13:59:14] [shop] scg 花费 90 元购买了[{'coffee': {'price': 30, 'count': 1}}, {'chicken': {'price': 20, 'count': 3}}]
shoppingcart.txt
msj|{'coffee':{'price':30,'count':2}}
msj|{'car':{'price':100000,'count':1}}
scg|{'iphone':{'price':8000,'count':1}}
account_info.txt
msj|123
scg|321
lll|123456
lhy|123
we|123
bank_info.txt
msj|123|4600|15000
scg|123|6700|15000
swb|123456|200|15000
cxm|123|0|15000
lhy|321|0|15000
mwl|123|0|15000
info_bank.log.txt
[INFO] [2018-09-30 13:45:54] [bank] scg 充值了 2000 元
[INFO] [2018-09-30 13:46:31] [bank] scg 充值了 100 元
[INFO] [2018-09-30 13:47:17][bank] scg 向 msj 转账 500
[INFO] [2018-09-30 13:49:02] [bank] scg 消费 100 元
[INFO] [2018-09-30 13:59:14] [bank] scg 消费 90 元
[INFO][2018-09-30 14:01:10] [bank] scg 还款了 90 元
[INFO] [2018-09-30 14:02:38] [bank] scg 充值了 5000 元