• python-学习 初级atm小脚本、函数嵌套、装饰器、生成器、迭代器、三元表达式


    一、作业需求:

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

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




    要求1、2、3、6、8、9、11以实现 要求4、5、7、10、未实现

    登录ID:1234 密码:abc123

      1 import  time
      2 current_user={'id':None}
      3 wenjian=open('db.txt','r+',encoding='utf-8')
      4 duqu=eval(wenjian.readline())
      5 shijian=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))  #定义日志操作时间
      6 def log(rizhi):
      7     with open('log.txt','a',encoding='utf-8') as l:
      8         l.write(rizhi)
      9         return rizhi
     10 def renzheng(zhanghu):
     11     def auth():
     12         while True:
     13            if current_user['id']:
     14                return zhanghu()
     15            name_id=input('请输入银行卡ID: ').strip()
     16            password=input('请输入密码: ') .strip()
     17            if len(password)== 0 and  len(name_id) ==0 :
     18                print('错误❌')
     19            if name_id == duqu['id'] and password == duqu['password'] :
     20                print('登录成功')
     21                current_user['id']=name_id
     22                log('%s   账户[%s]登录成功
    ' % (shijian, name_id))  #记录登录日志
     23                return zhanghu()
     24            else:
     25                print('登录失败,请检查账户名或密码')
     26                log('%s   账户[%s]登录失败
    '%(shijian,name_id))
     27     return  auth
     28 @renzheng
     29 def  chaxun():
     30     edu = duqu['money']
     31     xiaofei = duqu['shengyu']
     32     if xiaofei > edu:
     33         huankuan = 0
     34     else:
     35         huankuan = edu - xiaofei
     36     print('''
     37             总信用额度:%s
     38             剩余可消费:%s
     39             本月应还款:%s        
     40     ''' % (edu, xiaofei, huankuan))
     41     time.sleep(3)
     42 @renzheng
     43 def huankuan():
     44     huankuan = input('请输入还款金额:').strip()
     45     if huankuan.isdigit():
     46         xiaofei = duqu['shengyu']
     47         xiaofei += int(huankuan)
     48         duqu['shengyu'] = xiaofei
     49         print('还款中,请稍后..........')
     50         time.sleep(2)
     51         print('还款成功,账户可消费金额:%s' % xiaofei)
     52         time.sleep(3)
     53         wenjian = open('db.txt', 'w', encoding='utf-8')
     54         wenjian.write(str(duqu))
     55         wenjian.close()
     56 @renzheng
     57 def gouwuche():         #以前的作业拿来改吧改吧就用上了
     58     goods = [
     59         {"name": "电脑", "price": 1999},
     60         {"name": "鼠标", "price": 10},
     61         {"name": "游艇", "price": 20},
     62         {"name": "娃娃", "price": 3998},
     63         {"name": "气筒", "price": 99},
     64     ]
     65     kong = []
     66     qian = []
     67     while True:
     68         for k, v in enumerate(goods):
     69             print(k, '商品: {name}  价格: {price} RMB'.format(price=v['price'], name=v['name']))
     70         sp = input('请输入购买的商品编号[输入j结账][输入r删除购物车商品][输入q退出]: ').strip()
     71         if sp == 'q' and len(sp) != 0:
     72             break
     73         elif sp == 'r':
     74             while True:
     75                 if kong == []:
     76                     print('======================》没有商品可删了《=====================')
     77                     break
     78                 print('您以购买的商品: ')
     79                 for k, v in enumerate(kong):  # for循环显示已购买的商品
     80                     print(k, '商品: {name}  价格: {price} RMB'.format(price=v[1], name=v[0]))
     81                 sc = input('请输入删除的商品编号[输入q返回]: ').strip()
     82                 if sc == 'q' and len(sc) != 0:
     83                     break
     84                 if sc.isdigit():
     85                     if int(sc) < len(kong) and int(sc) >= 0:  # 判断输入的数字不能大于列表的下标数字和小于0
     86                         kong.remove(kong[int(sc)])  # 删除购物车商品
     87                     else:
     88                         print('!!!!!!!!!!!!!!!!无效的输入!!!!!!!!!!!!!!!!!!!')
     89                 else:
     90                     print('33[42m请输入要删除的商品编号哦~33[0m')
     91         elif sp.isdigit():
     92             if int(sp) < len(goods) and int(sp) >= 0:
     93                 jiaqian = goods[int(sp)]['price']
     94                 mingzi = goods[int(sp)]['name']
     95                 kong.append((mingzi, jiaqian))
     96                 qian.append(jiaqian, )
     97                 print('33[42m您以购买的商品:[ %s ] 价钱RMB:[ %s ]33[0m' % (mingzi, jiaqian))
     98             else:
     99                 print('>>>>>>>>>>>>>>>>>不要瞎搞!!!按提示操作!!!不要瞎搞!!!<<<<<<<<<<<<<<<<<<<<<')
    100         elif sp == 'j':
    101             while True:
    102                 res = sum(i for i in qian)
    103                 print('您总共消费了:%s' % res)
    104                 m = input('是否跳转到ATM结账y或n: ').strip()
    105                 if len(m)==0:
    106                     print('按提示操作!!')
    107                     continue
    108                 elif m == 'y':
    109                     jiezhang=duqu['shengyu']
    110                     print('     正在跳转请稍后.........')
    111                     time.sleep(3)
    112                     if jiezhang <= 0:
    113                         print('您的余额不足!!!!!')
    114                     jiezhang-=res
    115                     time.sleep(1)
    116                     print('支付成功,卡内剩余可消费金额:%s。'%jiezhang)
    117                     duqu['shengyu']=jiezhang
    118                     wenjian=open('db.txt','w',encoding='utf-8')
    119                     wenjian.write(str(duqu))    #将剩余金额写进文件里
    120                     wenjian.close()
    121                     print('正在返回商品页面,请稍后..........')
    122                     time.sleep(3)
    123                     break
    124                 elif m =='n':
    125                     break
    126                 else:continue
    127         else:
    128             print('>>>>>>>>>>>>>>>>>不要瞎搞!!!按提示操作!!!不要瞎搞!!!<<<<<<<<<<<<<<<<<<<<<')
    129 @renzheng
    130 def zhiqian():
    131     while True:
    132         quxian = input('请输入取现金额(输入b返回): ').strip()
    133         shengyu = duqu['shengyu']
    134         if len(quxian) == 0:
    135             print('!!!!!非法字符!!!!!')
    136             continue
    137         elif quxian == 'b':
    138             break
    139         elif quxian.isalpha():
    140             print('!!!!!非法字符!!!!')
    141             continue
    142         elif shengyu <= 0 or int(quxian) > shengyu:
    143             print('您的余额不足!!!!!')
    144             continue
    145         elif quxian is float:
    146             print('请输入整数')
    147         elif quxian.isdigit():
    148             quxian=int(quxian)
    149             shouxufei=quxian*0.05
    150             shengyu=shengyu-quxian-shouxufei
    151             print('%s  成功取现:%s   账户剩余:%s   手续费:%s' % (shijian, quxian, shengyu,shouxufei))
    152             log('%s   成功取现:%s   账户剩余:%s    手续费:%s
    ' % (shijian, quxian, shengyu,shouxufei))  #记录取钱日志
    153             duqu['shengyu'] = shengyu
    154             wenjian = open('db.txt', 'w', encoding='utf-8')
    155             wenjian.write(str(duqu))
    156             wenjian.close()
    157             continue
    158         else:
    159             print('输入错误!!!!!')
    160             continue
    161 
    162 
    163 
    164 @renzheng
    165 def caidan():
    166     while True:
    167         print('======================================================================================')
    168         print('''
    169                                                       1.查询余额
    170                                                       2.  转账
    171                                                       3.  取现
    172                                                       4.  购物
    173                                                       5.  还款
    174                                                       6.操作日志
    175                                                       7.退   出
    176               ''')
    177         print('======================================================================================')
    178         xuanze=input('请输入您要操作的选项:').strip()
    179         if xuanze == '1':chaxun()
    180         elif xuanze == '2':print('-------------------该功能未实现---------------------')
    181         elif xuanze == '3':zhiqian()
    182         elif xuanze == '4':gouwuche()
    183         elif xuanze == '5':
    184            chaxun()
    185            huankuan()
    186         elif xuanze == '6':
    187             with open('log.txt',encoding='utf-8') as log_f:
    188                 for i in log_f:
    189                     print(i)
    190                 time.sleep(3)
    191         elif xuanze == '7':break
    192         else:
    193             print('按提示操作!!')
    194             time.sleep(2)
    195             continue
    196 
    197 caidan()
    ATM

    二、笔记

      1.函数嵌套

    函数的嵌套定义:在一个函数的内部,又定义另外一个函数
    函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数
    1 def bar():
    2     print('from nbar')
    3 
    4 def foo():
    5     print('from foo')
    6     bar()
    7 
    8 foo()
    例子

      2.装饰器

    1 开放封闭原则:对扩展是开放的,对修改是封闭
    2 装饰器:装饰它人的工具,装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象
      2.1 装饰器的遵循的原则:1 不修改被装饰对象的源代码 2 不修改被调用对象的调用方式
      2.2 装饰器的目的是:在遵循1和2原则的前提,为其他新功能函数添加
    3 @装饰器名,必须写在被装饰对象的正上方,并且是单独一行
    4 一个函数头顶上可以多个装饰器(最先执行的是第一个)
     1 import time
     2 
     3 def timmer(func):
     4     # func=index
     5     def wrapper():
     6         start=time.time()
     7         func()
     8         stop=time.time()
     9         print('run time is %s' %(stop-start))
    10     return wrapper
    11 
    12 
    13 @timmer # index=timmer(index)
    14 def index():
    15     time.sleep(3)
    16     print('welcome to index')
    17 @timmer # home=timmer(home)
    18 def home():
    19     time.sleep(2)
    20     print('welcome to home page')
    21 
    22 index()
    23 home()
    例子

      2.1   无参装饰器版本

     1 current_user={'user':None}
     2 def auth(func):
     3     def wrapper(*args,**kwargs):
     4         if current_user['user']:
     5             return func(*args,**kwargs)
     6 
     7         name=input('name: ').strip()
     8         password=input('password: ').strip()
     9 
    10         with open('db.txt', encoding='utf-8') as f:
    11             user_dic = eval(f.read())
    12         if name in user_dic and password == user_dic[name]:
    13             res=func(*args,**kwargs)
    14             current_user['user']=name
    15             return res
    16         else:
    17             print('user or password error')
    18     return wrapper
    19 
    20 @auth #index=auth(index) index=wrapper
    21 def index():
    22     print('from index')
    23 index()
    24 
    25 @auth
    26 def home(name):
    27     print('welcome %s' %name)
    28 
    29 index() #wrapper()
    30 home('egon')
    例子

      2.2.  有参装饰器版本

     1 current_user={'user':None}
     2 def auth(auth_type='file'):
     3     def deco(func):
     4         def wrapper(*args, **kwargs):
     5             if auth_type == 'file':
     6                 if current_user['user']:
     7                     return func(*args, **kwargs)
     8                 name = input('name: ').strip()
     9                 password = input('password: ').strip()
    10 
    11                 with open('db.txt', encoding='utf-8') as f:
    12                     user_dic = eval(f.read())
    13                 if name in user_dic and password == user_dic[name]:
    14                     res = func(*args, **kwargs)
    15                     current_user['user'] = name
    16                     return res
    17                 else:
    18                     print('user or password error')
    19             elif auth_type == 'mysql':
    20                 print('mysql')
    21 
    22             elif auth_type == 'ldap':
    23                 print('ldap')
    24             else:
    25                 print('not valid auth_type')
    26         return wrapper
    27     return deco
    28 
    29 
    30 
    31 
    32 
    33 
    34 @auth(auth_type='mysql') #@deco  #index=deco(index)
    35 def index():
    36     print('from index')
    37 @auth(auth_type='file')
    38 def home(name):
    39     print('welcome %s' %name)
    40 index() #wrapper()
    41 home('egon')
    例子

      3.列表解析

     1 l=[]
     2 for i in range(10):
     3     if i >=5:
     4         l.append('egg%s' %i)
     5 
     6 print(l)
     7 
     8 列表解析
     9 for i0 in ...:
    10     if 条件1:
    11         for i1 in ...:
    12             if 条件2:
    13                 for i2 in ...:
    14                     if 条件3:
    15                         。。。
    16 
    17 l=['egg%s' %i for i in range(10)  if i >=5]
    18 print(l)
    19 
    20 nums=[1,2,3,4,5,6]
    21 nums_new=[item**2 for item in nums if item > 3]
    22 print(nums_new)
    23 
    24 
    25 nums_new=[]
    26 for item in nums:
    27     nums_new.append(item**2)
    28 
    29 print(nums_new)
    30 
    31 
    32 names=['alex_sb','wupeiqi_sb','egon','yuanhao_sb']
    33 
    34 names_new=[name for name in names if name.endswith('sb')]
    35 print(names_new)
    例子

      4.生成器

        1.生成器表达式

     1 # g=('egg%s' %i for i in range(1000))
     2 # print(g)
     3 # print(next(g))
     4 # print(next(g))
     5 # print(next(g))
     6 
     7 
     8 
     9 # with open('a.txt',encoding='utf-8') as f:
    10 #     # res=max((len(line) for line in f))
    11 #     res=max(len(line) for line in f)
    12 #     print(res)
    13 
    14 # print(max([1,2,3,4,5,6]))
    15 
    16 
    17 # with open('a.txt',encoding='utf-8') as f:
    18 #     g=(len(line) for line in f)
    19 #     print(max(g))
    20 #     print(max(g))
    21 #     print(max(g))
    例子
    1.生成器:在函数内部包含yield关键,那么该函数执行的结果是生成器
    2.生成器就是迭代器
    3.yield的功能:
    4. 把函数的结果做生迭代器(以一种优雅的方式封装好__iter__,__next__)
    5. 函数暂停与再继续运行的状态是由yield
     1 # def func():
     2 #     print('first')
     3 #     yield 11111111
     4 #     print('second')
     5 #     yield 2222222
     6 #     print('third')
     7 #     yield 33333333
     8 #     print('fourth')
     9 #
    10 #
    11 # g=func()
    12 # print(g)
    13 # from collections import Iterator
    14 # print(isinstance(g,Iterator))
    15 
    16 # print(next(g))
    17 # print('======>')
    18 # print(next(g))
    19 # print('======>')
    20 # print(next(g))
    21 # print('======>')
    22 # print(next(g))
    23 
    24 # for i in g: #i=iter(g)
    25 #     print(i)
    26 
    27 
    28 
    29 
    30 # def func(n):
    31 #     print('我开动啦')
    32 #     while True:
    33 #         yield n
    34 #         n+=1
    35 #
    36 # g=func(0)
    37 #
    38 # print(next(g))
    39 # print(next(g))
    40 # print(next(g))
    41 # for i in g:
    42 #     print(i)
    43 
    44 
    45 
    46 
    47 
    48 #
    49 # for i in range(10000):
    50 #     print(i)
    51 
    52 # def my_range(start,stop):
    53 #     while True:
    54 #         if start == stop:
    55 #             raise StopIteration
    56 #         yield start #2
    57 #         start+=1 #3
    58 #
    59 # g=my_range(1,3)
    60 # 
    61 # print(next(g))
    62 # print(next(g))
    63 # print(next(g))
    64 #
    65 
    66 #
    67 # for i in my_range(1,3):
    68 #     print(i)
    例子
    yield与return的比较?
    相同:都有返回值的功能
    不同:return只能返回一次值,而yield可以返回多次值
     1 # python3 tail.py -f access.log | grep 'error'
     2 import time
     3 
     4 def tail(filepath):
     5     with open(filepath, 'r') as f:
     6         f.seek(0, 2)
     7         while True:
     8             line = f.readline()
     9             if line:
    10                 yield line
    11             else:
    12                 time.sleep(0.2)
    13 
    14 
    15 def grep(pattern,lines):
    16     for line in lines:
    17         if pattern in line:
    18             print(line,end='')
    19 
    20 grep('error',tail('access.log'))
    例子

      5.三元表达式

     1 # def foo(x):
     2 #     if x > 3:
     3 #         return 'ok'
     4 #     else:
     5 #         return 'no'
     6 #
     7 # x=10
     8 # res=x if x > 3 else 'no'
     9 # print(res)
    10 
    11 
    12 # def max2(x,y):
    13 #     return x if x > y else y
    14 # print(max2(1,3))
    15 
    16 
    17 # name='egon'
    18 # print('SB' if name == 'alex' else 'shuai')
    例子

      6.迭代器

      1 #迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来
      2 # while True: #单纯的重复
      3 #     print('你瞅啥')
      4 
      5 # l=['a','b','c','d']
      6 # count=0
      7 # while count < len(l):
      8 #     print(l[count])
      9 #     count+=1
     10 
     11 dic={'name':'egon','sex':'m',"age":18} #上述按照索引的取值方式,不适于没有索引的数据类型
     12 
     13 #迭代器:
     14 #可迭代对象iterable:凡是对象下有__iter__方法:对象.__iter__,该对象就是可迭代对象
     15 # s='hello'
     16 # l=['a','b','c','d']
     17 # t=('a','b','c','d')
     18 # dic={'name':'egon','sex':'m',"age":18}
     19 # set1={1,2,3}
     20 # f=open('db.txt')
     21 
     22 # s.__iter__()
     23 # l.__iter__()
     24 # t.__iter__()
     25 # dic.__iter__()
     26 # set1.__iter__()
     27 # f.__iter__()
     28 
     29 
     30 #迭代器对象:可迭代对象执行内置的__iter__方法,得到的结果就是迭代器对象
     31 
     32 # dic={'name':'egon','sex':'m',"age":18}
     33 #
     34 # i=dic.__iter__()
     35 # # print(i) #iterator迭代器
     36 #
     37 # # i.__next__() #next(i)
     38 # print(next(i))
     39 # print(next(i))
     40 # print(next(i))
     41 # print(next(i)) #StopIteration
     42 #
     43 # l=['a','b','c','d']
     44 #
     45 # i=l.__iter__()
     46 # print(next(i))
     47 # print(next(i))
     48 # print(next(i))
     49 # print(next(i))
     50 # print(next(i)) #StopIteration
     51 
     52 
     53 
     54 
     55 #不依赖于索引的取值方式
     56 # l=['a','b','c','d']
     57 # dic={'name':'egon','sex':'m',"age":18}
     58 # iter_l=iter(l)
     59 # iter_dic=iter(dic)
     60 # while True:
     61 #     try:
     62 #         # print(next(iter_l))
     63 #         k=next(iter_dic)
     64 #         print(k,dic[k])
     65 #     except StopIteration:
     66 #         break
     67 
     68 
     69 #什么是迭代器对象:
     70 #1 有__iter__,执行得到仍然是迭代本身
     71 #2 有__next__
     72 
     73 
     74 #迭代器对象的优点
     75 #1:提供了一种统一的(不依赖于索引的)迭代方式
     76 #2:迭代器本身,比起其他数据类型更省内存
     77 # l=['a','b','c','d']
     78 # i=iter(l)
     79 
     80 # dic={'a':1,'b':2}
     81 # x=dic.keys()
     82 # print(x)
     83 # i=x.__iter__()
     84 #
     85 # with open('a.txt') as f:
     86 #     # print(next(f))
     87 #     # print(next(f))
     88 #     # print(next(f))
     89 #     f.read()
     90 
     91 
     92 #迭代器对象的缺点
     93 #1:一次性,只能往后走,不能回退,不如索引取值灵活
     94 #2:无法预知什么时候取值结束,即无法预知长度
     95 # l=['a','b','c','d']
     96 # i=iter(l)
     97 # print(next(i))
     98 # print(next(i))
     99 # print(next(i))
    100 
    101 
    102 #for循环原理
    103 
    104 #
    105 # l=['a','b','c','d']
    106 # for item in l: #iter_l=l.__iter__()
    107 #     print(item)
    108 
    109 
    110 # for item in {1,2,3,4}:
    111 #     print(item)
    112 
    113 
    114 # with open('a.txt') as f:
    115 #     # for line in f: #i=f.__iter__()
    116 #     #     print(line)
    117 #     print(f is f.__iter__())
    118 
    119 
    120 
    121 
    122 
    123 #补充:判断可迭代对象与迭代器对象(了解)
    124 
    125 from collections import Iterable,Iterator
    126 s='hello'
    127 l=['a','b','c','d']
    128 t=('a','b','c','d')
    129 dic={'name':'egon','sex':'m',"age":18}
    130 set1={1,2,3}
    131 f=open('a.txt')
    132 
    133 
    134 # print(isinstance(s,Iterable))
    135 # print(isinstance(l,Iterable))
    136 # print(isinstance(t,Iterable))
    137 # print(isinstance(dic,Iterable))
    138 # print(isinstance(set1,Iterable))
    139 # print(isinstance(f,Iterable))
    140 
    141 print(isinstance(s,Iterator))
    142 print(isinstance(l,Iterator))
    143 print(isinstance(t,Iterator))
    144 print(isinstance(dic,Iterator))
    145 print(isinstance(set1,Iterator))
    146 print(isinstance(f,Iterator))
    例子



  • 相关阅读:
    Java实现 LeetCode 382 链表随机节点
    Java实现 LeetCode 382 链表随机节点
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
    Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
    Linux下的iwpriv(iwlist、iwconfig)的简单应用
    OCX控件的注册卸载,以及判断是否注册
    .OCX、.dll文件注册命令Regsvr32的使用
  • 原文地址:https://www.cnblogs.com/ikere/p/7242311.html
Copyright © 2020-2023  润新知