[Python学习日记-44] 函数编程的练习
简介
本篇是函数编程的练习题,主要用于巩固前面学习的函数内容,建议先自己做一遍,最后再对答案,这样会比较稳固。
题目
1、写函数,计算传入数字参数的和。(动态传参)
2、写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作
3、写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容。
4、写函数,检查传入字典的每一个 value 的长度,如果大于2,那么仅保留前两个长度的内容(对 value 的值进行截断),并将新内容返回给调用者,注意传入的数据可以是字符串、列表、字典
5、解释闭包的概念
6、写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组
例如:[('红心’,2),('梅花',2),('方块',2),...('黑桃A')]
7、写函数,传入 n 个数,返回字典 {'max':最大值,'min':最小值}
例如:min_max(2,5,7,8,4)
返回:{'max':8,'min':2}
8、 写函数,专门计算图形的面积
- 其中嵌套函数,计算圆的面积,正方形的面积和长方形的面积
- 调用函数 area('圆形',圆半径) 返回圆的面积
- 调用函数 area('正方形',边长) 返回正方形的面积
- 调用函数 area('长方形',长,宽) 返回长方形的面积
- 代码模板
def area():
def 计算长方形面积():
pass
def 计算正方形面积():
pass
def 计算圆形面积():
pass
9、 写函数,传入一个参数 n,返回 n 的阶乘
例如:cal(7)
计算 7*6*5*4*3*2*1
10、编写装饰器,为多个的数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
11、生成器和迭代器的区别?
12、生成器有几种方式获取 value?
13、通过生成器写一个日志调用方法,支持以下功能
- 根据指令向屏幕输出日志
- 根据指令向文件输出日志
- 根据指令同时向文件和屏幕输出日志
- 以上日志格式如下
2017-10-19 22:07:38 [1] test log db backup 3
2017-10-19 22:07:40 [2] user jove login success
注意:其中 [1],[2] 是指日志方法第几次调用,每调用一次输出一条日志
- 代码结构如下
def logger(filename,channel='file'):
"""日志方法
:param filename:log filename:param channel:输出的目的地,屏幕(terminal),文件(file),屏幕+文件(both)
:return:"""
...your code...
# 调用log_obj = logger(filename="web.log",channel="both")
log_obj.__next__()
log_obj.send('user jove login success')
14、用 map 来处理字符串列表,把列表中所有人都变成 hanson,比方 jove_hanson
name=['jove','kerry','amy','lucy']
15、用 filter 函数处理数字列表,将列表中所有的偶数筛选出来
num = [1,3,5,6,7,8]
16、如下,每个小字典的 name 对回股票名字,shares 对应多少股,price 对应股票的价格
portfolio = [
{"name":"IBM","shares":100,"price":91.1},
{"name":"AAPL","shares":50,"price":543.22},{"name":"FB","shares":200,"price":21.09},
{"name":"HPQ","shares":35,"price":31.75},
{"name":"YHOQ","shares":45,"price":16.35},
{"name":"ACME","shares":75,"price":115.65},
]
- 通过明个内置函数可以计算购买每支股票的总价
- 用 filter 过滤出,单价大于100的股票有哪些
17、有列表 i = ['jove','kerry','amy','lucy','aizza'],请将以字母“a”开头的元素的首字母改为大写字母
18、有列表 i = ['jove','kerry','amy','lucy','aizza'],请以列表中每个元素的第二个字母倒序排序
19、有名为 poetry.txt 的文件,其内容如下,请删除第三行
昔人已乘黄鹤去,此地空余黄鹤楼,
黄鹤一去不复返,白云千载空悠悠,
晴川历历汉阳树,芳草萋萋鹦鹉洲,
日暮乡关何处是?烟波江上使人愁。
20、有名为 username.txt 的文件,其内容格式如下,写一个程序,判断该文件中是否存在“jove”,如果没有,则将字符串“jove”添加到该文件未尾,否则提示用户该用户已存在
jove
kerry
amy
21、有名为 user_info.txt 的文件,其内容格式如下,写一个程序,删除 id 为100003的行
jove,100001
kerry,100002
amy,100003
22、有名为 user_info.txt 的文件,其内容格式如下,写一个程序,将 id 为100002的用户名修改为kerry zou
jove,100001
kerry,100002
amy,100003
23、写一个计算每个程序执行时间的装饰器
24、lambda 是什么?请说说你曾在什么场景下使用 lambda?
25、写一个摇塞子游戏,要求用户压大小,赔率一赔一。
要求:三个股子,每个般子的值从1-6,摇大小,每次打印摇出来3个股子的值。
答案
1、写函数,计算传入数字参数的和。(动态传参)
def sum_numbers(*args):
return sum(args)
print(sum_numbers(1,2,3,4,5,6,7,8,9,10))
2、写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作
原文件 test1.txt 内容为(编码格式为UTF8):
Hello,Wold!
import os
def modify_file(f_name, old_str, new_str):
f_new_name = "%s.new" % f_name
# 读取原文件
f = open(f_name, 'r', encoding='utf-8')
# 写入新文件
f_new = open(f_new_name, 'w', encoding='utf-8')
for line in f:
if old_str in line:
new_line = line.replace(old_str, new_str)
else:
new_line = line
f_new.write(new_line)
f.close()
f_new.close()
# 新文件替换旧文件
os.replace(f_new_name, f_name) # mac 使用 rename
modify_file("test1.txt", "Hello", "World")
3、写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容。
def check_empty(obj):
if isinstance(obj, str):
if obj == '':
return True
else:
return False
elif isinstance(obj, list) or isinstance(obj, tuple):
if len(obj) == 0:
return True
else:
for i in obj:
if i == '':
return True
return False
else:
return False
print(check_empty(""))
print(check_empty(["jove",123,"","kerry"]))
print(check_empty("jove"))
print(check_empty([123,123,123]))
print(check_empty([]))
4、写函数,检查传入字典的每一个 value 的长度,如果大于2,那么仅保留前两个长度的内容(对 value 的值进行截断),并将新内容返回给调用者,注意传入的数据可以是字符串、列表、字典
dict_i = {
"key":"vl",
"key2":"vl",
"key3":"vl"
}
str_j = "kamslmlac"
list_k = ["123",456,"","a,nca"]
def check_len():
dict_test = {}
count = 0
while True:
v = yield
if len(v) > 2:
if isinstance(v,str) or isinstance(v,list):
v = v[:2]
elif isinstance(v,dict):
dict_list = []
for k in v:
dict_info = "'%s':'%s'" % (k, v[k])
dict_list.append(dict_info)
v = "{" + ",".join(dict_list[:2]) + "}"
dict_test[count] = v
count += 1
print(dict_test)
c = check_len()
c.__next__()
c.send(dict_i)
c.send(str_j)
c.send(list_k)
5、解释闭包的概念
闭包就是在一个嵌套函数当中,内函数调用了外函数的参数或者变量和外函数返回了内函数的内存地址。
当在全局调用该返回的内存地址时,导致原本已经运行结束的外函数无法释放原本的内存空间的现像就叫做闭包。
6、写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组
def poker():
poker_list = []
poker_flower = ["红心","草花","方块","黑桃"]
poker_num = [2,3,4,5,6,7,8,9,10,"J","Q","K","A"]
for i in poker_num:
for j in poker_flower:
if isinstance(i,int):
poker_list.append((j,i))
else:
poker_list.append((j+i))
return poker_list
print(poker())
7、写函数,传入 n 个数,返回字典 {'max':最大值,'min':最小值}
def min_max(*args):
dict_num = {
'max': args[0],
'min': args[0]
}
for i in args:
if i > dict_num['max']:
dict_num['max'] = i
if i < dict_num['min']:
dict_num['min'] = i
return dict_num
print(min_max(-1,2,5,7,8,4,9))
8、写函数,专门计算图形的面积
import math
def area(*args):
def rect():
result = args[1] * args[1]
return result
def squ():
if len(args) != 3 or args[1] == args[2]:
return "参数输入错误"
result = args[1] * args[2]
return result
def circle():
result = math.pi * math.pow(args[1], 2)
return result
if args[0] == '正方形':
return rect()
elif args[0] == '长方形':
return squ()
elif args[0] == '圆形':
return circle()
else:
print("无你需要计算的形状")
print(area("长方形", 2, 3))
9、写函数,传入一个参数 n,返回 n 的阶乘
def cal(n):
result = n
while n > 1:
n -= 1
result = result * n
return result
print(cal(7))
10、编写装饰器,为多个的数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
user_npw:用于存储用户名和密码
jove,abc123
account = {
"is_authenticated":False, # 用户登录了就把这个改成True
}
def login(area):
def inner(*args,**kwargs):
if account["is_authenticated"] is False:
f = open('user_npw','r')
user = input("user:")
passwd = input("passwd:")
user_list = f.readline().split(',')
if user_list[0] == user and user_list[1] == passwd:
print("welcome login....")
account["is_authenticated"] = True
area(*args,**kwargs)
else:
print("wrong username or password!")
else:
print("用户已登录,验证通过...")
return inner
def home():
print("---首页----")
@login
def america():
print("----欧美专区----")
@login
def japan():
print("----日韩专区----")
@login
def henan():
print("----河南专区----")
home()
america()
japan()
henan()
11、生成器和迭代器的区别?
生成器:生成器有两种形式,一种是以()括起来的for,例如(x**x for x in range(10)),这一类简单可循环的生成器; 另一种则是相对来说比较复杂的函数生成器,通常会在循环的函数中加入yield来暂停函数,有两种写法,一种是yield n(使用next()来返回n然后停止函数,并返回n),另一种是n = yield(使用send()来对n赋值)。 以上两种生成器都有同一个特点,那就是都是运算一次计算一次。
迭代器:迭代器是包含生成器的,要了解迭代器前就需要先了解什么是可迭代对象,简单来说就是可以循环出来的就是可迭代对象,可以使用from collections import Iterable 与 print(isinstance(数据类型/函数,Iterable))来判断是不是可迭代对象。 迭代器则是可以被next()的函数,并且不断返回下一个值的对象。在这里要说明的是,可迭代对象不一定是迭代器,但是可以通过iter()来把可迭代对象进行转换(非可迭代对象进行转换会报错),并且可以通过from collections import Iterator 与 print(isinstance(数据类型/函数,Iterator))。
区别:生成器和迭代器的主要区别就是迭代器是包含生成器的,有的迭代器不是生成器。
12、生成器有几种方式获取 value?
有三种方法:
1.把生成器的地址赋值给 g = (x * x for x in range(10)) 然后 for i in g,i 就是生成器每一次生成的值。
2.使用 next(),每使用一次就获取到一次计算的值。
3.使用 g.__next__(),与 next() 相同。
13、通过生成器写一个日志调用方法
# 代码结构如下
import time
def logger(filename, channel='file'):
"""
日志方法
:param filename: log filename
:param channel: 输出的目的地,屏幕(terminal),文件(file),屏幕+文件(both)
:return:
"""
count = 0
while True:
count += 1
staff_table = yield
now_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
log = "%s [%d] %s" % (now_time, count, staff_table)
if count == 1:
f = open(filename, 'w')
else:
f = open(filename, 'a')
if channel == 'terminal':
print(log)
elif channel == 'file':
f.write(log + "\n")
elif channel == 'both':
print(log)
f.write(log + "\n")
else:
print("参数输入错误")
f.close()
# 调用
log_obj = logger(filename="web.log", channel='both')
log_obj.__next__()
log_obj.send('test log db backup 3')
log_obj.send('user jove login success')
14、用 map 来处理字符串列表,把列表中所有人都变成 hanson,比方 jove_hanson
name = ['jove','lucy','kerry','jack']
name = list(map(lambda x:x+"_hanson",name))
print(name)
15、用 filter 函数处理数字列表,将列表中所有的偶数筛选出来
num = [1,3,5,6,7,8]
num = list(filter(lambda x:not x%2,num))
print(num)
16、 每个小字典的 name 对回股票名字,shares 对应多少股,price 对应股票的价格
portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
print(sum(portfolio[i]['price']*portfolio[i]['shares'] for i in range(len(portfolio))))
big_100 = [portfolio[i]['shares'] for i in range(len(portfolio))]
more_100 = list(filter(lambda x: x > 100, big_100))
print(more_100)
17、有列表 i = ['jove','kerry','amy','lucy','aizza'],请将以字母“a”开头的元素的首字母改为大写字母
li = ['jove','kerry','amy','lucy','aizza']
for i in range(len(li)):
if li[i].startswith('a'):
li[i]=li[i].upper()
print(li)
18、有列表 i = ['jove','kerry','amy','lucy','aizza'],请以列表中每个元素的第二个字母倒序排序
li = ['jove','kerry','amy','lucy','aizza']
li_str_2 = [i[1] for i in li]
li.sort(key=lambda x: x[1], reverse=True)
print(li)
19、有名为 poetry.txt 的文件,其内容如下,请删除第三行
f = open('poetry.txt','w')
f.write('昔人已乘黄鹤去,此地空余黄鹤楼。\n')
f.write('黄鹤一去不复返,白云千载空悠悠。\n')
f.write('晴川历历汉阳树,芳草萋萋鹦鹉洲。\n')
f.write('日暮乡关何处是?烟波江上使人愁。\n')
f.close()
import os
f = open('poetry.txt', 'r')
f_new = open('poetry.txt.new', 'w')
count = 0
for line in f:
count += 1
if count == 3:
continue
f_new.write(line)
f.close()
f_new.close()
os.replace('poetry.txt.new', 'poetry.txt')
20、有名为 username.txt 的文件,其内容格式如下,写一个程序,判断该文件中是否存在“jove”,如果没有,则将字符串“jove”添加到该文件未尾,否则提示用户该用户已存在
username.txt
jove
kerry
amy
f = open('username.txt','w')
f.write('jove\n')
f.write('kerry\n')
f.write('amy\n')
f.close()
f = open('username.txt','r')
f_add = open('username.txt','a')
for line in f:
if line.strip() == 'alex':
print('该用户已存在')
break
else:
f_add.write('alex\n')
21、有名为 user_info.txt 的文件,其内容格式如下,写一个程序,删除 id 为100003的行
user_info.txt
jove,100001
kerry,100002
amy,100003
f = open('user_info.txt','w')
f.write('jove,100001\n')
f.write('kerry, 100002\n')
f.write('amy, 100003\n')
f.close()
import os
f = open('user_info.txt', 'r')
f_new = open('user_info.txt.new', 'w')
for line in f:
if '100003' in line:
continue
f_new.write(line)
f.close()
f_new.close()
os.replace('user_info.txt.new', 'user_info.txt')
22、有名为 user_info.txt 的文件,其内容格式如下,写一个程序,将 id 为100002的用户名修改为kerry zou
user_info.txt
jove,100001
kerry,100002
amy,100003
import os
f = open('user_info.txt', 'r')
f_new = open('user_info.txt.new', 'w')
for line in f:
if '100002' in line:
lst = line.split(",")
lst[0] = "alex li"
line = ",".join(lst)
f_new.write(line)
f.close()
f_new.close()
os.replace('user_info.txt.new', 'user_info.txt')
23、写一个计算每个程序执行时间的装饰器
import time
def def_time(func):
def inner(*args,**kwargs):
start = time.time()
func(*args,**kwargs)
end = time.time() - start
result = time.strftime("%M:%S",time.localtime(end))
print('run time is %s.' % result)
return inner
def sleep_test(s):
print(s)
time.sleep(5)
s = "开始沉睡了"
sleep_test = def_time(sleep_test)
sleep_test(s)
24、lambda 是什么?请说说你曾在什么场景下使用 lambda?
lambda是匿名函数,它没有函数名,只可以执行简单的运算,test = lambda x:x**x ,就相当于 def test(x):return x**x,lambda的使用场景通常可以结合内置函数map()和filter()来使用 map(lambda x:x+1,[1,2,3,4]) --> 列表[1,2,3,4]的每一个元素放入匿名函数当中运算,最终每个元素加一,输出[2,3,4,5],对列表内的每个元素进行简单的运算,然后返回一个列表。 filter(lambda x:x>3,[1,2,3,4]) --> 列表[1,2,3,4]的每一个元素放入匿名函数当中运算,如果结果为True的则返回,输出[4],对列表内的每个元素进行过滤,然后返回一个包含所有符合元素的列表。
25、写一个摇塞子游戏,要求用户压大小,赔率一赔一。
import random
def play_dice():
while True:
yield random.randrange(1, 6)
count = 0
c = play_dice()
while True:
count += 1
user_choice = input("Please choice(big or small)>>:")
print("------ 第%d轮摇骰 ------" % count)
c1 = c.__next__()
c2 = c.__next__()
c3 = c.__next__()
all_num = c1 + c2 + c3
if all_num > 9:
play_result = "big"
print("%d %d %d %s" % (c1, c2, c3, play_result))
if user_choice.lower() == "big":
print("Congratulation,you are bingo!!!")
else:
print("Sorry,try again has luck!!!")
elif all_num <= 9:
play_result = "small"
print("%d %d %d %s" % (c1, c2, c3, play_result))
if user_choice.lower() == "small":
print("Congratulation,you are bingo!!!")
else:
print("Sorry,try again has luck!!!")