第三周作业

作业需求:

模拟实现一个ATM + 购物商城程序

  1. 额度 15000或自定义
  2. 实现购物商城,买东西加入 购物车,调用信用卡接口结账
  3. 可以提现,手续费5%
  4. 每月22号出账单,每月10号为还款日,过期未还,按欠款总额 万分之5 每日计息
  5. 支持多账户登录
  6. 支持账户间转账
  7. 记录每月日常消费流水
  8. 提供还款接口
  9. ATM记录操作日志 
  10. 提供管理接口,包括添加账户、用户额度,冻结账户等。。。
  11. 用户认证用装饰器

源代码:

其他文件格式:

  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()
View Code

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 元
原文地址:https://www.cnblogs.com/msj513/p/9729446.html