第3章 文件操作-函数练习题

时间:2023-02-23 13:51:15
'''
1、编码问题
i请说明python2 与python3中的默认编码是什么?
答:python2默认编码是ascii python3默认编码是:utf-8

ii为什么会出现中文乱码?你能列举出现乱码的情况有哪几种?
如何进行编码转换?
答:编码不符,程序出错。
代码头代加‘#-*-coding:utf-8-*-’进行声明转换

iii#-*-coding:utf-8-*- 的作用是什么?
答:声明代码是以utf-8编码的。

iv解释py2 bytes vs py3 bytes的区别
答:Python 2 将 strings 处理为原生的 bytes 类型,而不是 unicode,
Python 3 所有的 strings 均是 unicode 类型。

2、文件处理

i r和rb的区别是什么?
'r':默认值,表示从文件读取数据,rb表示要读二进制数据

ii解释一下以下三个参数的分别作用
open(f_name,'r',encoding="utf-8")
答:f_name,表示文件,‘r’表示以只读模式,encoding ='utf-8',表示解码为utf-8方式解码
'''
# names= ['Alex','Black Gril','Peiqi']
#
# def change_name():
# del names[2]
# names[1]= "黑姑娘"
# print(names)
#
# change_name()
# print(names)

#写函数,计算传入数字参数的和。(动态传参)
# x = int(input("输入要计算的值a:")) #定义动态输入的x值
# y= int(input("输入要计算的值b:")) #定义动态输入的y值
# def calc(x,y):
# res = x + y
# print("结果是:",res)
#
# calc(x,y)
# calc(233,256)

# 2、写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作
#文件修改占硬盘
# import os #导入工具箱
# f_name = "兼职白领学生空姐模特护士联系方式.txt"
# f_new_name = "%s.new"%f_name
#
# old_str = "完成"
# new_str = "美女"
#
# 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:
# line =line.replace(old_str,new_str)
# f_new.write(line)
# print(line)
#
# f.close()
# f_new.close()
# # os.replace(f_new_name,f_name)
# print("修改完成!")

# 3、写函数,检查用户传入的对象(字符串、列表、元组)的每个个元素是否含有空内容。
# import os, sys
# res_dir = os.listdir("c:/users")
# for res_list in range(len(res_dir)):
# print( res_list,".",res_dir[res_list])
# dir_num = input("Please Input project number:") #raw_input
# def func(x):
# try:
# x=int(x)
# return isinstance(x,int)
# except ValueError:
# print( "input type is error!!!")
# sys.exit()
# func(dir_num)
# if int(dir_num) >= len(res_dir) or int(dir_num) < 0:
# print("input number is error!!!")
# sys.exit()
# dir_path = "/var/www/html/" + res_dir[int(dir_num)]
# file_name_list = []
# file_path_list = []
# for root, dirs, files in os.walk(dir_path):
# for file_list in files:
# if " " in file_list:
# file_name_list.append(os.path.join(root,file_list))
# for dir_list in dirs:
# if " " in dir_list:
# file_path_list.append(os.path.join(root,dir_list))
# if len(file_name_list) == 0:
# pass
# else:
# print( "Warning: These files has a problem!!!")
# for filelists in file_name_list:
# print( filelists)
# if len(file_path_list) == 0:
# pass
# else:
# print ("\nWarning: These directorys has a problem!!!")
# for dislists in file_path_list:
# print (dislists)

# s = " xyz ".strip() # returns "xyz"
# s1 = " 脚 家 "
# s1 = s1.strip()
# s1=s1.rstrip()
# s1=s1.lstrip()
# print(s1)
# print(s1.strip())
# print(s)
# s2 =" a b c".replace(' ','')#.replace(' ','') 前面带空格的' '引号被 ‘’不带空格的引号替换
# print('测试删中间空格:',s2)

# 4、写函数,检查传入字典的每一个value的度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
# def a4(v1):
# ret = {}
# for key,value in v1.items():
# if len(value) > 2:
# ret[key] = value[0:2]
# else:
# ret[key] = value
# return ret
# dic = {"k1": "v1v1", "k2": [11, 22, 33, 44],"k3":"12"}
# r = a4(dic)
# print(r)

# 5、解释闭包的概念
'''关于闭包,即函数定义和函数表达式位于另一个函数体内(嵌套函数)。而且这些函数可以访问它们所在的外部函数中声明
的所有局部变量、参数。当其中一个内部函数在包含它们的外部函数之外被调用时,就会形成闭包。也就是说,内部函数会在
外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其它内部函数。这些
局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。
闭包的意义:返回的函数对象,不仅仅是一个函数的对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处
调用,优先使用自己外层包裹的作用域。'''



# 1、写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组。例如:[(‘红心’,2), (‘草花’,2), …(‘黑桃,‘A’)]
# def cards():
# num =[]
# for v in range(2,11):
# num.append(v)
# num.extend(['J','Q','K','A'])
# type = ['红心','草花','方块','黑桃']
# result = []
# for i in num:
# for j in type:
# result.append((j, i))
# return result
#
# print(cards())


'''# 2、写函数,传入n个数,返回字典:{'max':最大值,'min':'最小值'}。例如:min_max(2,5,7,8,4)返回:
{'max':8,'min':2}'''
# def max_min(*args): # *args代表非固定参数。可以有参数,或都没有参数都可以。 (*args,**kwargs)形参。加多少个参数都可以。
# the_max=args[0]
# the_min=args[0]
# for i in args:
# if i > the_max:
# the_max =i
# if i < the_min:
# the_min=i
# return {'max':the_max,'min':the_min}
# print(max_min(2,4,1,55,-3))


# 3、写函数,专门计算圆形的面积
'''其中嵌套函数,计算圆的面积,正方形的面积和长方形的面积
调用函数area('圆形',圆半径)返回圆的面积
调用函数area(正方形,边长)返回正方形的面积
调用函数area(长方形,长,宽)近回长方形的面积
def area():
def 计算长方形面积():
pass
def 计算正方形面积():
pass
def 计算圆形面积():
pass
'''
#方法一:
# import math
# def area(name,*args):
# def areas_rectangle(x,y):
# return x*y
#
# def area_square(x):
# return x**2
#
# def area_round(r):
# return math.pi*r*r
#
# if name=="圆形":
# return area_round(*args)
# elif name=="正方形":
# return area_square(*args)
# elif name=="长方形":
# return areas_rectangle(*args)
#
# print(area('长方形', 3, 4))
# print(area('圆形', 3))
# print(area('正方形', 3))

# 4、写函数,传入一个参数n,返回n的阶乘
'''例如:cal(7)
计算7*6*5*4*3*2*1 '''

# def cal(n):
# result=1
# for i in range(n,0,-1):
# result=result*i
# print (i)
# return result
#
# print(cal(8))

'''斐波那契数列:[1,1,2,3,5,8,13,...],每个元素为前两个元素之和

  (1)当要求长度小于某个值的时候:'''
# l = [1,1] #声明一个列表,用来存数据
# while len(l)<20: # 当列表长度小于20
# l.append(l[-1]+l[-2]) # l.append(l[-1]+1[-2]) 在最后索引加1代表,表示前两位递加,添加值到最后两位。赋值l列表
# print(l)

'''(2)当要求小于某个数的时候:'''

# l = [1,1]
# while l[-1]<4000000:
# l.append(l[-1]+l[-2])
# del l[-1]
# print(l)

'''
# 正确的整片代码如下所示:
i = j
j = i+j
# 在这里需要注意,“i, j = i, i+j”这条代码不能写成如下所示:
'''

# i, j = 0, 1
# while i < 1000000:
# print(i)
# i, j = j, i+j


'''二、函数装饰器

  在不修改原函数的内容及调用方式的前提下,对原函数进行功能扩展

1、计算函数执行时间实例'''
# import time
# def timmer(func): #装饰器
# def innner(*args,**kwargs):
# start=time.time()
# ret=func(*args,**kwargs)
# end=time.time()
# print(start-end)
# return ret
# return innner
#
# @timmer #语法糖,等价name=timmer(name)
# def name(a,b): #被装饰函数
# print('老板万岁')
# return a+b
#
# name(4,6)

# 2、打印当前正在调用函数名的实例
# def wrapper(func):
# def inner(*args,**kwargs):
# print('你当前调用的函数是:%s' %func.__name__)
# ret=func(*args,**kwargs)
# return ret
#
# return inner
# @wrapper
# def welcome(name):
# print('welcome,%s' %name)
# welcome('zhangli')
# @wrapper
# def home():
# print('欢迎来到home页')
# home()

# 5、编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名
#和密码
'''
f=open('db.txt','r',encoding='utf-8')
access =f.readlines() #逐行读取数据
while True: #循环
for line in access:
line=line.split()
for i in range(3):
print(i)
u = input("请输入用户名:")
p = input("请输入密码:")
if u == line[0] and p == line[1]:
print("登陆成功!")
exit()
else:
print("用户名或密码错误,请重试!")
if i==2:
exit()
'''
# user_status = False #用户登录了 就把这个改成True
# def login(auth_type): #qq
# def outer(func): #henan
# def inner(*args,**kwargs): #3p
# _username = 'alex' #假装这是DB里存在的用户信息
# _password = 'abc!23' # 假装这是DB里存在的用户信息
# global user_status
#
# if user_status == False:
# username =input("user:")
# password =input("password:")
#
# if username == _username and password ==_password:
# print("welcome login...")
# user_status = True
# else:
# print("wrong username or password!")
# else:
# print("用户已登录,验证通过。。。")
# if user_status:
# func(*args,*kwargs) #3p
# return inner
# return outer
# def home():
# print(" ----首页----")
# def america():
# print("----欧美专区----")
#
# def japan():
# print("----日韩专区----")
# @login('qq')
# def henan(style):
# print("----河南专区----",style)
#
# henan('3p')

# 生成器和迭代器
#1、生成器和迭代器的区别?
'''对于list、string、tuple、dict等这些容器对象,使用for循环遍历是很方便的。
在后台for语句对容器对象调用iter()函数。iter()是python内置函数。
iter()函数会返回一个定义了 next()方法的迭代器对象,它在容器中逐个访问容器内的
元素。next()也是python内置函数。在没有后续元素时,next()会抛出
一个StopIteration异常,通知for语句循环结束。
迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的
时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()函数
的时候,调用的就是迭代器对象的_next_方法(Python3中是对象的_next_方法,
Python2中是对象的next()方法)。所以,我们要想构造一个迭代器,
就要实现它的_next_方法。但这还不够,python要求迭代器本身也是可迭代的,
所以我们还要为迭代器实现_iter_方法,而_iter_方法要返回一个迭代器,
迭代器自身正是一个迭代器,所以迭代器的_iter_方法返回自身self即可。'''

# l=[1,5,6,879,9]
# iterl=iter(l)
# print(iterl.__next__()) #迭代器



# 2、生成器有几种方式获取value?
# 两种方式: for 循环获取 next 获取

#3、通过生成器写一个日志调用方法,支持以下功能
# 根据指令向屏幕输出日志
#根据指令向文件输出日志
import logging
class IgnoreBackupLogFilter(logging.Filter):
"""忽略带db backup 的日志"""
def filter(self, record): #固定写法
return "db backup" not in record.getMessage()

#console handler
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
#file handler
fh = logging.FileHandler('mysql.log')
#fh.setLevel(logging.WARNING)


#formatter
'''
# logging.basicConfig(format='%(asctime)s', datefmt='%m/%d/%Y %I:%M:%S %p')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#bind formatter to ch
ch.setFormatter(formatter)
fh.setFormatter(formatter)

logger = logging.getLogger("Mysql")
logger.setLevel(logging.DEBUG) #logger 优先级高于其它输出途径的

#add handler to logger instance
logger.addHandler(ch)
logger.addHandler(fh)
#add filter
logger.addFilter(IgnoreBackupLogFilter())

logger.debug("test ....")
logger.info("test info ....")
logger.warning("start to run db backup job ....")
logger.error("test error ....")
'''
# 内置函数
# 1、用map 来处理字符串列表,把列表中所有人都变成sb,比方alex_sb
# name = ['alex','wupeiqi','yuanhao','zezha']
'''map()函数
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把
函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

例如,对于list [1, 2, 3, 4, 5, 6, 7, 8, 9]

如果希望把list的每个元素都作平方,就可以用map()函数:
因此,我们只需要传入函数f(x)=x*x,就可以利用map()函数完成这个计算:

def f(x):
return x*x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
输出结果:

[1, 4, 9, 10, 25, 36, 49, 64, 81]
注意:map()函数不改变原有的 list,而是返回一个新的 list。'''

# name = ['alex', 'wupeiqi', 'yuanhao', 'zezha']
# def s1(x):
# return x+'_sb'
# a = map(s1,['alex', 'wupeiqi', 'yuanhao', 'zezha'])
#
# print("函数:",list(a))

# def s1(x):
# return x+'_sb'
# a= map(s1,['alex', 'wupeiqi', 'yuanhao', 'zezha'])
# print('name=',list(a))
# 用filter函数处理数字列表,将列表中所有的偶数筛选出来
##num = [1,3,5,6,7,80.]

# num = [1,3,5,6,7,8]
# def func(x):
# if x%2 == 0:
# return True
# ret = filter(func,num) #ret是迭代器
# print(list(ret))
#
# ret = filter(lambda x:x%2 == 0,num)
# ret = filter(lambda x:True if x%2 == 0 else False,num)
# print(list(ret))

'''自己写的例子'''
# num = [1,3,5,6,7,8]
# def func(x):
# if x%2 ==0:
# return True
# ret =filter(func,num) #ret是迭代器
# print(list(ret))
# ret1 = filter(lambda x:x%2==0,num)
# print("lambda",list(ret1))
# ret2 = filter(lambda x:True if x%2==0 else False,num)
# print("ret2",list(ret2))
'''
3.用map来处理字符串列表,把列表中所有人都变成sb,比方alex_sb
name = [‘alex‘,‘wupeiqi‘,‘yuanhao‘,‘nezha‘]
def ad(l):
return l[:len(l)]+‘_sb‘
print(list(map(ad, name)))
'''
# 3、 如下,每个小字典对应股票名字,shares对应多少股,price对应股票的价格
'''portlio= [
{'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}
]
计算购买每支股票的总价
用filter过滤出,单价大于100的股票有些'''

'''
2'用filter函数处理数字列表,将列表中所有的偶数筛选出来
num = [1,2,3,4,5,6,7,8]
def ou(num1):
return num1 % 2 == 0
print(list(filter(ou,num)))
'''

'''
3.如下,每个小字典的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}
]
计算购买每支股票的总价

用filter过滤出,单价大于100的股票有哪些


'''
# 1、map来得出一个包含数字的迭代器,数字指的是:购买每支股票的总价格

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}
]
# m = map(lambda y:y["shares"]*y["price"],portfolio)
# print(list(m))
# --------------输出结果---------------
# [9110.0, 27161.0, 4218.0, 1111.25, 735.7500000000001, 8673.75]

#  3、用filter过滤出,单价大于100的股票有哪些

# f =filter(lambda d:d['price']>=100,portfolio)
# print(list(f))
# -----------------------输出结果-----------------------------
# [{‘name‘: ‘AAPL‘, ‘shares‘: 50, ‘price‘: 543.22}, {‘name‘: ‘ACME‘, ‘shares‘: 75, ‘price‘: 115.65}]
'''
1、请分别介绍文件操作中不同的打开方式之间的区别:

模式 含义
r 文本只读模式
rb 二进制模式  #这种方法,是用来传输或存储,不给人看的。
r+ r+ 是读写模式,只要沾上r,文件必须存在
rb+ 二进制读写模式
w w 写模式,它是不能读的,如果用w模式打开一个已经存在的文件,会清空以前的文件内容,重新写
wb 和wb 两种模式
w+ w+ 是读写内容,只要沾上w,肯定会清空原来的文件
wb+ 二进制写读模式
a a 追加模式,也能写,在文件的末尾添加内容
ab 二进制追 加模式
a+
ab+
'''
# 2、有列表 li = ['alex', 'egon', 'smith', 'pizza', 'alen'], 请将以字母“a”开头的元素的首字母改为大写字母

# li = ['alex', 'egon', 'smith', 'pizza', 'alen']
# for i in range(5):
# if "a" == li[i][0]:
# li[i] =li[i].capitalize()
# print("大写后",li[i][0])
# else:
# continue
#
# print(li)
'''
5、有名为poetry.txt的文件,其内容如下,请删除第三行;

昔人已乘黄鹤去,此地空余黄鹤楼。

黄鹤一去不复返,白云千载空悠悠。

晴川历历汉阳树,芳草萋萋鹦鹉洲。

日暮乡关何处是?烟波江上使人愁。
'''
# import os
# p='poetry.txt'
# poetry =open(p,'r',encoding='utf-8')
# poetry_new= '%s.new'%p
# p_new=open(poetry_new,'w',encoding='utf-8')
# str1='晴川历历汉阳树,芳草萋萋鹦鹉洲。'
# for line in poetry:
# if str1 in line:
# line= ''
# p_new.write(line)
# print(str1)
# else:
# p_new.write(line)
# poetry.close()
# p_new.close()
# os.replace(poetry_new,p)

#方法二 逐行读取文件,
# import os
# f1=open('poetry.txt', 'r',encoding='utf-8')
#
# str='晴川历历汉阳树,芳草萋萋鹦鹉洲。'
# with open('poetry1.txt', 'w', encoding='utf-8') as f2:
# ff1='poetry.txt'
# ff2='poetry1.txt'
# for line in f1:
# if str in line:
# line=''
# f2.write(line)
#
# else:
# f2.write(line)
# f1.close()
# f2.close()
# os.replace(ff2,ff1)
'''
6、有名为username.txt的文件,其内容格式如下,写一个程序,判断该文件中是否存在"alex", 如果没有,则将字符串"alex"添加到该文件末尾,否则提示用户该用户已存在;

pizza
alex
egon '''
# usr=open('username.txt','r+',encoding='utf-8')
# str="alex"
# for line in usr:
# if str in line:
# print('该用户已存在,程序退出!')
# exit()
# usr.close()
# usr=open('username.txt','a',encoding='utf-8')
# usr.write('\nalex')
# usr.close()
# print("用户添加成功!")
'''
7、有名为user_info.txt的文件,其内容格式如下,写一个程序,删除id为100003的行;

pizza,100001
alex, 100002
egon, 100003 '''

# import os
# u1='user_info.txt'
# u2='%s.new'%u1
# with open('user_info.txt','r+',encoding='utf-8') as f1:
# with open("%s.new"%u1,'w',encoding='utf-8')as f2:
# for line in f1:
# if "100003" in line:
# line =""
# f2.write(line)
# else:
# f2.write(line)
# os.replace(u2,u1)

'''
8、有名为user_info.txt的文件,其内容格式如下,写一个程序,将id为100002的用户名修改为alex li;

pizza,100001
alex, 100002
egon, 100003 '''

# file='user_info.txt'
# oldstr='100002'
# newstr='alex, 100002'
# file_data=''
# with open(file,'r',encoding='utf-8') as f1:
#
# for line in f1:
# if oldstr in line:
# line =newstr
# file_data +=line
#
# with open(file,'w',encoding='utf-8') as f1:
# f1.write(file_data)


# 9、写一个计算每个程序执行时间的装饰器;
#-*-coding:utf-8 -*-
#-*- coding: utf-8 -*-


import time

"""
定义简单的装饰器,用来输出程序运行的所用时间
"""
'''
def timer(func):
def decor(*args):

start_time = time.time();
func(*args);
end_time = time.time();
d_time = end_time - start_time
print("run the func use : ", d_time)


return decor;

@timer #printSth = timer(printSth) -> printSth = decor
def printSth(str, count):
for i in range(count):
print("%d hello,%s!"%(i,str))
printSth("world", 100)
'''


# 10、lambda是什么?请说说你曾在什么场景下使用lambda?
'''
lambda函数就是可以接受任意多个参数(包括可选参数)并且返回单个表达式值得函数
好处:
1.lambda函数比较轻便,即用即扔,适合完成只在一处使用的简单功能
2.匿名函数,一般用来给filter,map这样的函数式编程服务
3.作为回调函数,传递给某些应用,比如消息处理'''
'''
什么是装饰器?写一个装饰器,可以打印输出方法执行时长的信息。
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。
import time

def timer(func):
def decor(*args):

start_time = time.time()
func(*args)
end_time = time.time()
d_time = end_time - start_time
print("run the func use : ", d_time)
return decor

@timer #printSth = timer(printSth) -> printSth = decor
def printSth(str, count):
for i in range(count):
print("%d hello,%s!"%(i,str))

printSth("world", 1000000)#run the func use : 4.414000034332275

'''
''''''