python练习day01-20
难点 第20天的匿名函数 lambda和max的结合
day21 ATM
day_08
# 1.1 for循环嵌套之打印99乘法表
for i in range(1, 10): for j in range(1, i + 1): print("{}*{}={}".format(j, i, j * i), end=" ") # 这个end是不换行 print() # 每计算完一列,然后换行
# 1.2 for循环嵌套之打印金字塔
提示分析如下
'''
#max_level=5
* #current_level=1,空格数=4,*号数=1
*** #current_level=2,空格数=3,*号数=3
***** #current_level=3,空格数=2,*号数=5
******* #current_level=4,空格数=1,*号数=7
********* #current_level=5,空格数=0,*号数=9
#数学表达式
空格数=max_level-current_level
*号数=2*current_level-1
n=100 for i in range(n): print(("*"*(2*i-1)).center(2*(n-1)-1, ))
for i in range(1,6): #1,3,5
print("{}".format((2*i-1)*"*").center(2*5-1))
day09
考试15分钟(两道题): 1、请按照昨日所讲,用for循环改写以下代码 # count = 0 # while count < 3: # inp_name = input('请输入您的账号:') # inp_pwd = input('请输入您的密码:') # # if inp_name == username and inp_pwd == password: # print('登录成功') # while True: # cmd = input("输入命令>: ") # if cmd == 'q': # 整个程序结束,退出所有while循环 # break # else: # print('命令{x}正在运行'.format(x=cmd)) # break # else: # print('账号名或密码错误') # count += 1 # else: # print('输错3次,退出') 2、编写代码实现,for循环打印金字塔
day10
1、用列表模拟队列的入队与出队操作,FIFO 先进先出 append 和 pop(0) 2、用列表模拟堆栈的入队与出队操作,LIFO 后进先出 append 和 pop() 3、有列表l=['egon','alex_sb','lxx']从列表中取走/剪切走傻逼,并赋值给新变量 pop可以返回值 res=l.pop(1) 4、什么是元组?它用在何处 取值 ;不可变的列表,取值和列表一样 5、元组不可变指的是元组内的什么不可改变 内存地址不可变,但是元祖包含列表时,列表中的元素某个值是可变的 6、t=(1,2,['AA']) # 针对改元组能够把'aa'改成'AA',这与元组不可变是否冲突 7、在我无法确定key是否存在的情况下,如何从字典中取值才能保持程序不会出错 >>> res=d.get('name',None) >>> print(res) None 8、列表能否通过不存在索引增加元素,字典能否通过不存在key增加元素, 字典可以,列表不可以;IndexError: list assignment index out of range 9、简述python3中dict.keys()、dict.values()、dict.items()包含的内容及 与python2的区别 ,生成器,和可迭代对象的区别
可迭代想的区别
https://blog.csdn.net/sfakh/article/details/107178371
dict.items 类似 key和value组成的元祖的列表 10、用代码分别示范:for循环遍历我们所学过的所有可遍历的类型
凡是实现了__iter__方法的对象都称之为 可迭代对象
判断是否是可迭代对象
from collections.abc import Iterable def isiterable(iter): if isinstance(iter,Iterable): #判断q4是不是可迭代对象 print("yes" ) else: print("no") #再去调用它 isiterable([1,2,3,4]) isiterable(1)
迭代器
概念
任何实现了__iter__()和__next()__方法的都是迭代器,其中__iter()__是用来返回迭代器本身;__next()__是用来返回迭代对象中的下一个值
注意事项如下:
1.迭代器有具体的迭代器类型,可用type查看,一般有list_iterator,set_iterator等类型
2.迭代器是有状态的,可以被 next() 调用,并且不断返回迭代对象的下一个值,如果到了迭代器的最后一个元素,继续调用next(),则会抛出stopIteration异常
————————————————
from collections.abc import Iterable,Iterator def ifiter(ran): #判断是不是可迭代对象 if isinstance(ran,Iterable): print(f"{ran}是可迭代的对象") else: print(f"{ran}不是可迭代的对象") #判断是不是迭代器 if isinstance(ran,Iterator): print(f"{ran}是迭代器") else: print(f"{ran}不是迭代器") ran=range(3) ifiter(ran)
生成器
概念
生成器是一种特殊的迭代器,不需要手动的编写__iter()__和__next()__方法,因为yeild关键字已经包含了这两种方法。
注意事项:
1.因为生成器(generator)一定是迭代器,所以生成器也是一种懒加载的模式生成值(即需要用的时候才会生成数据,不需要的时候不会生成)
2 生成器可以是生成器表达式也可以是生成器函数
其中生成式表达式,使用()表示,将列表推导式的 [] 改成()即可得到生成器
生成器函数则调用yield关键字即可
yield关键字
了解一个东西,首先要知道它的原因,yield关键字产生的原因:
因为yeild自动实现了__iter__和__next__方法,起到简化代码的作用,一般用于大数据,大文件逐个生成的时候,可以大大减少内存的开销。
使用yield时的注意事项:
1.yeild被调用时,返回一个迭代器,调用时可以使用next或send(msg)
2.只要函数内部有yield关键字,就认为该函数是生成器函数
3.一个生成器中可以有多个yield,一旦遇到yield,就会保存当前状态,然后返回yield后面的值
4.当生成器遇到yield时,会暂停运行生成器,返回yield后面的值,当再次调用生成器的时候,会从刚才暂停的地方继续执行,直到下一个yield
5.yield关键字,会保留中间算法,下次继续执行
day11
#一:今日作业: #1、编写文件copy工具 ;读一行写一行 #2、编写登录程序,账号密码来自于文件 ; 读文件,一行,一行的读,然后split,然后获取到账号和密码 #3、编写注册程序,账号密码来存入文件 1 注册时,先检查文件中账号是否存在,存在则提示,不存在,则 检查账号和密码是否符合规则,符合规则则 a写入文件 #二:周末综合作业: # 2.1:编写用户登录接口 #1、输入账号密码完成验证,验证通过后输出"登录成功" #2、可以登录不同的用户 #3、同一账号输错三次锁定,(提示:锁定的用户存入文件中,这样才能保证程序关闭后,该用户仍然被锁定) # 2.2:编写程序实现用户注册后(注册到文件中),可以登录(登录信息来自于文件) 提示: while True: msg = """ 0 退出 1 登录 2 注册 """ print(msg) cmd = input('请输入命令编号>>: ').strip() if not cmd.isdigit(): print('必须输入命令编号的数字,傻叉') continue if cmd == '0': break elif cmd == '1': # 登录功能代码(附加:可以把之前的循环嵌套,三次输错退出引入过来) pass elif cmd == '2': # 注册功能代码 pass else: print('输入的命令不存在') # 思考:上述这个if分支的功能否使用其他更为优美地方式实现
day12
#1、通用文件copy工具实现 #2、基于seek控制指针移动,测试 r+、 w+ 、a+ 模式下的读写内容 #3、tail -f access.log 程序实现
with open('access.log', mode='rb') as f: ,也可以用a+ 模式 到文件尾部,并读
# 1、将指针跳到文件末尾
# f.read() # 错误
f.seek(0, 2)
while True:
line = f.readline() + b'\n' # 读一行
if line == b'\n':
time.sleep(0.3)
else:
print(line.decode('utf-8'), end='')
#4、周末作业参考在老师讲解完毕后(下午17:30开始讲解),练习熟练,明早日考就靠他俩 # 4.1:编写用户登录接口 # 4.2:编写程序实现用户注册后(注册到文件中),可以登录(登录信息来自于文件)
day13
# 1、编写文件修改功能,调用函数时,传入三个参数(修改的文件路径,要修改的内容,修改后的内容)既可完成文件的修改 # 2、编写tail工具 # 3、编写登录功能 # 4、编写注册功能 # 5、编写用户认证功能
# 选做题:编写 ATM 程序实现下述功能,数据来源于文件db.txt ----账号,和密码
# 1、充值功能:用户输入充值钱数,db.txt中该账号钱数完成修改 1 充值,则增加价格,修改文件中对应账号对应的值
# 2、转账功能:用户A向用户B转账1000元,db.txt中完成用户A账号减钱,用户B账号加钱 转账两方,一 加, 一减
# 3、提现功能:用户输入提现金额,db.txt中该账号钱数减少 1 体现,则减少价格,修改文件中对应账号对应的值
# 4、查询余额功能:输入账号查询余额 2 每次查询一行,然后根据 账号,返回对应的金额
# 选做题中的选做题:登录功能
# 用户登录成功后,内存中记录下该状态,上述功能以当前登录状态为准,必须先登录才能操作; 登录后,数据库中修改登录状态 为success 退出后,修改状态为退出
day14
1、写函数,,用户传入修改的文件名,与要修改的内容,执行函数,完成批了修改操作 2、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数
# "".isdigit() "".isspace() "".isalpha()
3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。
4、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
5、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
if i % 2 == 1: % 余数
6、写函数,检查字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。 dic = {"k1": "v1v1", "k2": [11,22,33,44]} PS:字典中的value只能是字符串或列表 # 选做作业:同昨天
用一个新字典保存
day15
# 作业要求:下述所有代码画图以及分析代码执行流程
# 1、以定义阶段为准,先画出名称空间的嵌套关系图
# 2、然后找到调用函数的位置,写出函数调用时代码的执行过程,涉及到名字的查找时,参照1中画好
# 的嵌套图,标明查找顺序,一层一层直到找到位置
# ===================题目一===================
input=333
def func():
input=444
func()
print(input)
# ===================题目二===================
def func():
print(x)
x=111
func()
# ===================题目三===================
x=1
def func():
print(x)
def foo():
x=222
func()
foo()
# ===================题目四===================
input=111
def f1():
def f2():
# input=333
print(input)
input=222
f2()
f1()
# ===================题目五===================
x=111
def func():
print(x) #
x=222
func()
# ===================题目六===================
x=111
def foo():
print(x,)
def bar():
print(x)
foo()
bar()
# ===================题目七===================
x=1
def func2():
func1()
x=2
def func1():
print(x)
x=3
func2()
# ===================题目八===================
1、如下全局变量记录了当前登录用户,编写登录功能,一旦用户登录成功,则将全局变量赋值为当前登录的用户名
login_user=None
2、针对之前编写的查询余额的功能,添加额外的逻辑:如果用户没有登录,则先执行登录功能
day16
今日作业:
1、函数对象优化多分支 if 的代码练熟
2、编写计数器功能,要求调用一次在原有的基础上加一
温馨提示:
I:需要用到的知识点:闭包函数+ nonlocal
II:核心功能如下:
def counter():
x+=1
return x
要求最终效果类似
print(couter()) # 1
print(couter()) # 2
print(couter()) # 3
print(couter()) # 4
print(couter()) # 5
def func(): x = 0 def count(): nonlocal x x += 1 return x return count count=func() print(count()) print(count()) print(count())
# ====================周末作业==================== # 编写ATM程序实现下述功能,数据来源于文件db.txt # 0、注册功能:用户输入账号名、密码、金额,按照固定的格式存入文件db.txt # 1、登录功能:用户名不存在,要求必须先注册,用户名存在&输错三次锁定,登录成功后记录下登录状态(提示:可以使用全局变量来记录) 下述操作,要求登录后才能操作 # 1、充值功能:用户输入充值钱数,db.txt中该账号钱数完成修改 # 2、转账功能:用户A向用户B转账1000元,db.txt中完成用户A账号减钱,用户B账号加钱 # 3、提现功能:用户输入提现金额,db.txt中该账号钱数减少 # 4、查询余额功能:输入账号查询余额
day17
一:编写函数,(函数执行的时间用time.sleep(n)模拟)
二:编写装饰器,为函数加上统计时间的功能
三:编写装饰器,为函数加上认证的功能
四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式
五:编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录
六:选做题
# 思考题(选做),叠加多个装饰器,加载顺序与运行顺序,可以将上述实现的装饰器叠加起来自己验证一下
# @deco1 # index=deco1(deco2.wrapper的内存地址)
# @deco2 # deco2.wrapper的内存地址=deco2(deco3.wrapper的内存地址)
# @deco3 # deco3.wrapper的内存地址=deco3(index)
# def index():
# pass
day18
作业:
1、编写课上讲解的有参装饰器准备明天默写
2:还记得我们用函数对象的概念,制作一个函数字典的操作吗,来来来,我们有更高大上的做法,在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作
3、 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到日志文件中,日志文件路径可以指定
注意:时间格式的获取
import time
time.strftime('%Y-%m-%d %X')
4、基于迭代器的方式,用while循环迭代取值字符串、列表、元组、字典、集合、文件对象
5、自定义迭代器实现range功能
====================本周选做作业如下====================
编写小说阅读程序实现下属功能
# 一:程序运行开始时显示
0 账号注册
1 充值功能
2 阅读小说
# 二: 针对文件db.txt,内容格式为:"用户名:密码:金额",完成下述功能
2.1、账号注册
2.2、充值功能
# 三:文件story_class.txt存放类别与小说文件路径,如下,读出来后可用eval反解出字典
{"0":{"0":["倚天屠狗记.txt",3],"1":["沙雕英雄转.txt",10]},"1":{"0":["令人羞耻的爱.txt",6],"1":["二狗的妻子与大草原的故事.txt",5]},}
3.1、用户登录�
day19
1、文件内容如下,标题为:姓名,性别,年纪,薪资
egon male 18 3000
alex male 38 30000
wupeiqi female 28 20000
yuanhao female 28 10000
要求:
从文件中取出每一条记录放入列表中,
列表的每个元素都是{'name':'egon','sex':'male','age':18,'salary':3000}的形式
2 根据1得到的列表,取出所有人的薪资之和
3 根据1得到的列表,取出所有的男人的名字
4 根据1得到的列表,将每个人的信息中的名字映射成首字母大写的形式
5 根据1得到的列表,过滤掉名字以a开头的人的信息
6 使用递归打印斐波那契数列(前两个数的和得到第三个数,如:0 1 1 2 3 4 7...)
7 一个嵌套很多层的列表,如l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]],用递归取出所有的值
# 选做作业:同昨天
day20
作业:
1、文件内容如下,标题为:姓名,性别,年纪,薪资
egon male 18 3000
alex male 38 30000
wupeiqi female 28 20000
yuanhao female 28 10000
要求:
从文件中取出每一条记录放入列表中,
列表的每个元素都是{'name':'egon','sex':'male','age':18,'salary':3000}的形式
2 根据1得到的列表,取出薪资最高的人的信息
3 根据1得到的列表,取出最年轻的人的信息
4、将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写
5、将names=['egon','alex_sb','wupeiqi','yuanhao']中以sb结尾的名字过滤掉,然后保存剩下的名字长度
6、求文件a.txt中最长的行的长度(长度按字符个数算,需要使用max函数)
7、求文件a.txt中总共包含的字符个数?思考为何在第一次之后的n次sum求和得到的结果为0?(需要使用sum函数)
8、思考题
with open('a.txt') as f:
g=(len(line) for line in f)
print(sum(g)) #为何报错?
9、文件shopping.txt内容如下
mac,20000,3
lenovo,3000,10
tesla,1000000,10
chicken,200,1
求总共花了多少钱?
打印出所有商品的信息,格式为[{'name':'xxx','price':333,'count':3},...]
求单价大于10000的商品信息,格式同上
10、思考:判断下述说法是否正确
题目1:
1、应该将程序所有功能都扔到一个模块中,然后通过导入模块的方式引用它们
2、应该只将程序各部分组件共享的那一部分功能扔到一个模块中,然后通过导入模块的方式引用它们
题目2:
运行python文件与导入python文件的区别是什么?
运行的python文件产生的名称空间何时回收,为什么?
导入的python文件产生的名称空间何时回收,为什么?