前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《python核心教程2》第九章 练习

《python核心教程2》第九章 练习

作者头像
py3study
发布2020-01-19 09:48:51
6170
发布2020-01-19 09:48:51
举报
文章被收录于专栏:python3python3

9–1. 文件过滤. 显示一个文件的所有行, 忽略以井号( # )开头的行. 这个字符被用做Python , Perl, Tcl, 等大多脚本文件的注释符号.附加题: 处理不是第一个字符开头的注释.

代码语言:javascript
复制
1 filename = input("输入文件名:")
2 with open(filename) as f:
3     for i in f:
4         if i.startswith('#'):
5             continue
6         else:
7             print(i, end='')

9–2. 文件访问. 提示输入数字 N 和文件 F, 然后显示文件 F 的前 N 行.

代码语言:javascript
复制
1 num = int(input("输入数字:"))
2 filename = input("输入文件名:")
3 with open(filename) as f:
4     for i, j in enumerate(f):
5         if i == (num):
6             break
7         else:
8             print(j, end='')

9–3. 文件信息. 提示输入一个文件名, 然后显示这个文本文件的总行数.

代码语言:javascript
复制
1 filename = input('输入文件名:')
2 with open(filename) as f:
3     allline = f.readlines()
4     print(len(allline))

9–4. 文件访问. 

写一个逐页显示文本文件的程序. 提示输入一个文件名, 每次显示文本文件的 25 行, 暂停并向用户提示"按任意键继续.", 按键后继续执行.

代码语言:javascript
复制
1 filename = input("输入文件名:")
2 num = 25
3 with open(filename) as f:
4     for i, j in enumerate(f, 1):
5         if i == num:
6             space = input("输入任意字符回车:")
7             num += 25
8         else:
9             print(j, end='')

9-5 考试成绩,改进你的考试成绩问题(练习5-3和6-4),要求能从多个文件中读入考试成绩。文件的数据格式由你自己决定。

代码语言:javascript
复制
 1 filename = input("输入文件名:")
 2 with open(filename) as f:
 3     for i in f:
 4         i = i.strip()
 5         if int(i) < 60:
 6             print("F")
 7         elif int(i) < 70:
 8             print("D")
 9         elif int(i) < 80:
10             print("C")
11         elif int(i) < 90:
12             print("B")
13         elif int(i) <= 100:
14             print("A")
15         else:
16             print("%s不在范围" % i)

9–6. 文件比较. 写一个比较两个文本文件的程序. 如果不同, 给出第一个不同处的行号和列号.

代码语言:javascript
复制
 1 def file(filename1, filename2):
 2     with open(filename1) as f1:
 3         f1alllines = f1.readlines()
 4 
 5     with open(filename2) as f2:
 6         f2alllines = f2.readlines()
 7 
 8     minlen1 = min(len(f1alllines), len(f2alllines))
 9     for i in range(minlen1):
10         if f1alllines[i] != f2alllines[i]:
11 
12             minlen2 = min(len(f1alllines[i]), len(f2alllines))
13             for j in range(minlen2):
14                 if f1alllines[i][j] != f2alllines[i][j]:
15                     return '不同行号: %s' % (i+1), '不同列号: %s' % (j+1)
16     return '文件相同'
17 
18 if __name__ == '__main__':
19     filename1 = input("输入文件名1:")
20     filename2 = input("输入文件名2:")
21     print(file(filename1, filename2))

9–7. 解析文件. Win32 用户: 创建一个用来解析 Windows .ini 文件的程序. POSIX 用户:创建一个解析 /etc/serves 文件的程序. 其它平台用户: 写一个解析特定结构的系统配置文件的程序.

代码语言:javascript
复制
 1 windows = {}
 2 with open(r'C:\Windows\win.ini') as f:
 3     # print(f.readlines())
 4     for line in f:
 5         if line.startswith(';'):
 6             continue
 7         if line.startswith('['):
 8             iterm = []
 9             name = line[1: line.rfind(']')]
10             windows.setdefault(name, iterm)
11             continue
12         if '=' in line:
13             windows[name].append(line.strip())
14 print(windows)

9–8. 模块研究. 提取模块的属性资料. 提示用户输入一个模块名(或者从命令行接受输入).然后使用 dir() 和其它内建函数提取模块的属性, 显示它们的名字, 类型, 值.

代码语言:javascript
复制
1 m = input('输入模块名: ')
2 module = __import__(m)
3 ml = dir(module)
4 # print(ml)
5 for i in ml:
6     print('name: ', i)
7     print('type: ', type(getattr(module,i)))
8     print('value: ', getattr(module,i))
9     print('')

9–9. Python 文档字符串. 

进入 Python 标准库所在的目录. 检查每个 .py 文件看是否有__doc__ 字符串, 如果有, 对其格式进行适当的整理归类. 你的程序执行完毕后, 应该会生成一个漂亮的清单. 里边列出哪些模块有文档字符串, 以及文档字符串的内容. 清单最后附上那些没有文档字符串模块的名字.附加题: 提取标准库中各模块内全部类(class)和函数的文档.

代码语言:javascript
复制
 1 import os
 2 
 3 pymodules = {}
 4 path = input("输入路径:")
 5 pyfiles = [f for f in os.listdir(os.path.abspath(path)) if f.endswith('.py')]
 6 
 7 for f in pyfiles:
 8     module = f[:-3]
 9     pymodules.setdefault(module, '')
10     pyfile = os.path.join(path, f) 
11     file = open(pyfile)
12     doc = False
13     for line in file:
14         if line.strip().startswith('"""') and line.strip().endswith('"""'):
15             pymodules[module] += line
16             file.close()
17             break
18         elif line.strip().startswith('"""') or line.strip().startswith('r"""') and len(line) > 3:
19             doc = True
20             pymodules[module] += line
21             continue
22         elif doc:
23             if line == '"""':
24                 pymodules[module] += line
25                 file.close()
26                 doc = False
27                 break
28             else:
29                 pymodules[module] += line
30         else:
31             continue
32     file.close()
33 
34 hasdoc = []
35 nodoc = []
36 for module in pymodules:
37     if pymodules[module]:
38         hasdoc.append(module)
39     else:
40         nodoc.append(module)
41 
42 print('没有文档模块:')
43 for key in nodoc:
44     print(key)
45 
46 print("")
47 
48 print("有文档模块:")
49 for key in hasdoc:
50     print("%s:%s" % key, pymodules[key])

9-10.家庭理财。创建一个家庭理财程序。你的程序需要处理储蓄 、支票、金融市场 ,定期存款等多 种账户。为每种账户提供一个菜单操作界面 ,要有存款、取款、借、贷等操作 。另外还要提 一个取消操作选项 。用户退出这个程序时相关数据应该保存到文件里去 (出于备份的目的, 序执行过程中也要备份)。

代码语言:javascript
复制
  1 # 函数思路不够用,只好用上类
  2 import os
  3 import json
  4 import sys
  5 
  6 class Fm:
  7 
  8     def deposit(self):
  9         """存款"""
 10         money = input("存款:")
 11         if money == 'q':
 12             self.saving()
 13         else:
 14             self.user_dict['余额'] += float(money)
 15             with open('%s.json' % self.ID, 'w') as f:
 16                 json.dump(self.user_dict, f)
 17             print("存款成功")
 18             self.saving()
 19 
 20     def withdrawal(self):
 21         """取款"""
 22         while True:
 23             money = input("取款:")
 24             if money == 'q':
 25                 self.saving()
 26             else:
 27                 if float(money) <= self.user_dict['余额']:
 28                     self.user_dict['余额'] -= float(money)
 29                     with open('%s.json' % self.ID, 'w') as f:
 30                         json.dump(self.user_dict, f)
 31                     print("取款成功")
 32                     self.saving()
 33                 else:
 34                     print("取款金额超出余额,重新输入")
 35 
 36     def loan(self):
 37         """借款"""
 38         money = input("存款:")
 39         if money == 'q':
 40             self.saving()
 41         else:
 42             self.user_dict['借款'] += float(money)
 43             with open('%s.json' % self.ID, 'w') as f:
 44                 json.dump(self.user_dict, f)
 45             print("借款成功")
 46             self.saving()
 47 
 48     def credit(self):
 49         """贷款"""
 50         money = input("贷款:")
 51         if money == 'q':
 52             self.saving()
 53         else:
 54             self.user_dict['贷款'] += float(money)
 55             with open('%s.json' % self.ID, 'w') as f:
 56                 json.dump(self.user_dict, f)
 57             print("贷款成功")
 58             self.saving()
 59 
 60     def saving(self):
 61         """储蓄主菜单"""
 62         showmenu = ("""
 63         [1]存款
 64         [2]取款
 65         [3]借款
 66         [4]贷款
 67         [5]返回
 68         [6]退出
 69         
 70         请输入编号:""")
 71         num = input(showmenu)
 72         if num == '6':
 73             sys.exit()
 74         elif num in '12345':
 75             if num == '1': self.deposit()
 76             if num == '2': self.withdrawal()
 77             if num == '3': self.loan()
 78             if num == '4': self.credit()
 79             if num == '5': self.main()
 80         else:
 81             print("输入有误")
 82 
 83     def main(self):
 84         """主菜单"""
 85         showmenu = ("""
 86         [1]储蓄
 87         [2]支票(未写)
 88         [3]金融市场(未写)
 89         [4]定期存款(未写)
 90         [5]退出
 91         
 92         请输入编号:""")
 93         num = input(showmenu)
 94         if num == '5':
 95             sys.exit()
 96         elif num in '1234':
 97             if num == '1': self.saving()
 98         else:
 99             print("输入有误")
100 
101     def registered(self):
102         """注册"""
103         while True:
104             ID = input('ID:')
105             filename = '%s.json' % ID
106             if filename in os.listdir(os.getcwd()):
107                 print("用户已存在")
108             else:
109                 passwd = input('密码:')
110                 name = input('姓名:')
111                 registered_user = {}
112                 registered_user['密码'] = passwd
113                 registered_user['姓名'] = name
114                 registered_user['余额'] = 0
115                 registered_user['借款'] = 0
116                 registered_user['贷款'] = 0
117                 filename = open('%s.json' % ID, 'w')
118                 json.dump(registered_user, filename)
119                 filename.close()
120                 print("注册成功")
121                 self.user()
122 
123     def login(self):
124         """登录"""
125         self.ID = input('ID:')
126         filename = '%s.json' % self.ID
127         if filename in os.listdir(os.getcwd()):
128             with open(filename) as user_file:
129                 self.user_dict = json.load(user_file)
130                 passwd = input("密码:")
131                 if self.user_dict['密码'] == passwd:
132                     print("登录成功")
133                     print("---------------\n"
134                           "姓名:{姓名}\n余额:{余额:.2f}\n借款:{借款:.2f}\n贷款:{贷款:.2f}\n"
135                           "---------------".format(**self.user_dict))
136                     self.main()
137                 else:
138                     print("密码错误")
139         else:
140             print("用户不存在")
141 
142     def user(self):
143         """账号"""
144         showmenu = ("""
145         [1]注册
146         [2]登录
147         [3]退出
148         
149         请输入编号:""")
150         num = input(showmenu)
151         while True:
152             if num == '3':
153                 break
154             elif num in '12':
155                 if num == '1': self.registered()
156                 if num == '2':
157                     if self.login():
158                         self.main()
159             else:
160                 print("输入有误")
161 
162 if __name__ == '__main__':
163     fm = Fm()
164     fm.user()

9–11. Web 站点地址. a) 编写一个 URL 书签管理程序. 使用基于文本的菜单, 用户可以添加, 修改或者删除书签数据项. 书签数据项中包含站点的名称, URL 地址, 以及一行简单说明(可选). 另外提供检索功能,可以根据检索关键字在站点名称和 URL 两部分查找可能的匹配. 程序退出时把数据保存到一个磁盘文件中去; 再次执行时候加载保存的数据. b)改进 a) 的解决方案, 把书签输出到一个合法且语法正确的 HTML 文件(.html 或 htm )中,这样用户就可以使用浏览器查看自己的书签清单. 另外提供创建"文件夹"功能, 对相关的书签进行分组管理. 附加题: 请阅读 Python 的 re 模块了解有关正则表达式的资料, 使用正则表达式对用户输入的 URL 进行验证.

代码语言:javascript
复制
  1 import sys
  2 import re
  3 
  4 regex = re.compile(r"^(((http|https)://)"  # http、https
  5                        r"?([a-z]{2,}))\." # www
  6                        r"([a-z0-9]+)\." #
  7                        r"([a-z]{3}|([a-z]{3}\.[a-z]{2,4}))$") #com、com.cn
  8 
  9 filename = "bookmark.txt"
 10 def add():
 11     """添加"""
 12     urllist = []
 13     while True:
 14         url = input("输入地址[b:返回]:").strip()
 15         if url == 'b':
 16             main()
 17         if regex.match(url):
 18             urlname = input("输入名称:").strip()
 19             description = input("简要说明:").strip()
 20             urllist.append(urlname)
 21             urllist.append(url)
 22             urllist.append(description)
 23             with open(filename, 'a+') as f:
 24                 f.write(str(urllist) + '\n')
 25                 print('添加成功')
 26         else:
 27             print("地址不规范")
 28 
 29 def modify():
 30     """修改"""
 31     urllist = []
 32     f = open(filename)
 33     for i, j in enumerate(f):
 34         urllist.append(eval(j))
 35         print(i, j, end='')
 36     f.close()
 37 
 38     while True:
 39         num = input("修改编号[b:返回]:")
 40         if num == 'b':
 41             main()
 42         if int(num) <= len(urllist):
 43             url = input("输入地址:").strip()
 44             if regex.match(url):
 45                 urlname = input("输入名称:").strip()
 46                 description = input("简要说明:").strip()
 47                 urllist[int(num)][0] = urlname
 48                 urllist[int(num)][1] = url
 49                 urllist[int(num)][2] = description
 50                 print("修改成功")
 51                 with open(filename, 'w') as urlfile:
 52                     for urlline in urllist:
 53                         urlfile.write(str(urlline) + '\n')
 54             else:
 55                 print("地址不规范")
 56         else:
 57             print('输入有误')
 58 
 59 
 60 def delete():
 61     """删除"""
 62     urllist = []
 63     f = open(filename)
 64     for i, j in enumerate(f):
 65         urllist.append(eval(j))
 66         print(i, j, end='')
 67     f.close()
 68 
 69     while True:
 70         num = input("\n删除编号[b:返回]:")
 71         if num == 'b':
 72             main()
 73         if int(num) <= len(urllist):
 74             del urllist[int(num)]
 75             print('删除成功')
 76             with open(filename, 'w') as urlfile:
 77                 for urlline in urllist:
 78                     urlfile.write(str(urlline) + '\n')
 79         else:
 80             print("输入有误")
 81 
 82 def find():
 83     """查找"""
 84     urllist = []
 85     while True:
 86         name = input("查找内容[b:返回]:")
 87         if name == 'b':
 88             main()
 89         with open(filename) as f:
 90             for urlline in f:
 91                 urllist.append(eval(urlline))
 92         if name in str(urllist):
 93             for urlline in urllist:
 94                 if name in urlline:
 95                     print('%s\n名称:%s\n地址:%s\n说明:%s\n%s' %
 96                           ('-'*20, urlline[0], urlline[1], urlline[2], '-'*20))
 97         else:
 98             print('书签不存在')
 99 
100 def main():
101     """主菜单"""
102     showmenu = ("""
103     [1]添加书签
104     [2]修改书签
105     [3]删除书签
106     [4]查找书签
107     [5]退出程序
108     
109     请输入编号:""")
110     num = input(showmenu)
111     if num == '5':
112         sys.exit()
113     elif num in '1234':
114         if num == '1': add()
115         if num == '2': modify()
116         if num == '3': delete()
117         if num == '4': find()
118     else:
119         print("输入有误")
120 
121 if __name__ == '__main__':
122     main()

9-12 用户名和密码。回顾练习7-5,修改代码使之可以支持“上次登录时间”。请参阅time模块中的文档了解如何记录用户上次登录的时间。另外提供一个系统管理员,他可以导出所有用户的用户名,密码(如需要可以加密),以及上次登录时间。 a)数据应保存在磁盘中,使用冒号:分隔,一次写入一行,例如“Joe:boohoo:953176591.145,文件中数据的行数应该等于你系统上的用户数。

b)进一步改进你的程序,不再一次写入一行,而使用pickle模块保存整个数据对象。请参阅pickle模块的文档了解如何序列化/扁平化对象,以及如何读写保存的对象。一般来说,这个解决方案的代码行数要比a)少;

c)使用shelve模块替换pickle模块,由于可以省去一些维护代码,这个解决方案的代码比b)的更少

代码语言:javascript
复制
  1 from datetime import datetime
  2 import hashlib, time, sys
  3 import pickle as p
  4 import shelve as s
  5 
  6 db = {}
  7 
  8 def newuser():
  9     """注册"""
 10     value = []
 11     prompt = 'login desired: '
 12     while True:
 13         name = input(prompt).lower()
 14         if not name.isalnum() and '' in name:
 15             print('name format error')
 16             continue
 17         else:
 18             if name in db:
 19                 prompt = 'name taken, try another: '
 20                 continue
 21             else:
 22                 break
 23     pwd = input('login password desired:')
 24     m = hashlib.md5()
 25     m.update(pwd.encode(encoding='utf-8'))
 26     value.append(m.hexdigest())
 27     value.append(datetime.now())
 28     value.append(time.time())
 29     db[name] = value
 30     print('new user is %s, register time is %s' % (name, db[name][1]))
 31 
 32 def olduser():
 33     """登录"""
 34     name = input('Username:').lower()
 35     pwd = input('Password:')
 36     m = hashlib.md5()
 37     m.update(pwd.encode(encoding='utf-8'))
 38     passwd = db.get(name)
 39     if passwd[0] == m.hexdigest():
 40         newtimestamp = time.time()
 41         newtime = datetime.now()
 42         if newtimestamp - db[name][2] < 14400:
 43             print('You already logged in at %s:' % db[name][1])
 44         else:
 45             passwd[1] = newtime
 46             print('Welcome back %s, login time is %s' % (name, passwd[1]))
 47     else:
 48         print('Login incorrect')
 49 
 50 def removeuser():
 51     """删除"""
 52     print(db)
 53     name = input('Input a user name to remove:').lower()
 54     if name in db:
 55         db.pop(name)
 56         print("Done")
 57     else:
 58         print('Input error')
 59 
 60 def getuser():
 61     """查询"""
 62     while True:
 63         name = input('login name desired:').lower()
 64         if not name.isalnum() and '' in name:
 65             print('name format error')
 66             continue
 67         else:
 68             if name not in db:
 69                 print('User name is not in db')
 70                 answer = input('register a new user? y/n').lower()
 71                 if 'y' == answer:
 72                     newuser()
 73                     break
 74                 elif 'n' == answer:
 75                     break
 76             else:
 77                 print('user name is already in db')
 78                 olduser()
 79                 break
 80 
 81 def textfile():
 82     """text"""
 83     print(db)
 84     f = open('account.txt', 'w')
 85     f.write(str(db))
 86     f.close()
 87 
 88 def picklefile():
 89     """pickle"""
 90     accountfile = 'pickle.data'
 91     f = open(accountfile, 'wb')
 92     p.dump(db, f)
 93     f.close()
 94 
 95     f = open(accountfile, 'rb')
 96     accountdb = p.load(f)
 97     print(accountdb)
 98 
 99 def shelvefile():
100     """shelve"""
101     accountfile = 'shelve.data'
102     accountdb = s.open(accountfile, 'c')
103     accountdb['data'] = db
104     accountdb.close()
105 
106     accountdb = s.open(accountfile, 'r')
107     print(accountdb['data'])
108 
109 def adminlogin():
110     """管理员"""
111     while True:
112         name = input('Username:').lower()
113         if not name.isalnum() and '' in name:
114             print('name format error')
115             continue
116         else:
117             pwd = input('Password:')
118             if name == 'root' and pwd == 'root':
119                 print('Welcom admin')
120                 if len(db) == 0:
121                     print('There is nothing you can do')
122                     showmenu()
123                 else:
124                     while True:
125                         answer = input('Output all account? y/n').lower()
126                         if 'y' == answer:
127                             prompt = "(T)ext\n(P)ickle\n(S)helve\n\nEnter choice:"
128                             choice = input(prompt).lower()
129                             if choice in 'tps':
130                                 if choice == 't': textfile()
131                                 if choice == 'p': picklefile()
132                                 if choice == 's': shelvefile()
133                         elif 'n' == answer:
134                             print('Bye')
135                             showmenu()
136                             sys.exit()
137             else:
138                 print('User name or password is wrong, input again')
139 
140 
141 def showmenu():
142     """功能"""
143     prompt = """
144     (N)ew User Login
145     (E)xisting User Login
146     (G)et user
147     (R)emove a existing user
148     (A)dmin Login
149     (Q)uit
150     
151     Enter choice: """
152 
153     done = False
154     while not done:
155         chosen = False
156         while not chosen:
157             try:
158                 choice = input(prompt).strip()[0].lower()
159             except (EOFError, KeyboardInterrupt):
160                 choice = 'q'
161             print('\nYou picked: [%s]' % choice)
162             if choice not in 'negraq':
163                 print('Invalid option, try again')
164             else:
165                 chosen = True
166 
167             if choice == 'q': done = True
168             if choice == 'n': newuser()
169             if choice == 'e': olduser()
170             if choice == 'g': getuser()
171             if choice == 'r': removeuser()
172             if choice == 'a': adminlogin()
173 
174 if __name__ == '__main__':
175     showmenu()

9-14 记录结果。修改你的计算器程序(练习5-6)使之接受命令行参数。例如$ calc.py 1 + 2 只输出计算结果。另外,把每个表达式和它的结果写入到一个磁盘文件中,当使用下面的命令时 $ calc.py print 会把记录的内容显示到屏幕上,然后重置文件。这里是样例展示: $ calc.py 1 + 2

3

$ calc.py 3 ^ 3

27

$ calc.py print

1 + 2

3

3 ^ 3

27

$ calc.py print

代码语言:javascript
复制
 1 import sys, os
 2 
 3 if sys.argv[1] == 'print':
 4     if os.path.exists(r'test.txt'):
 5         f = open(r'test.txt', 'r')
 6         for line in f:
 7             print(line)
 8         f.close()
 9     else:
10         print('No file yet')
11     f = open(r'text.txt', 'w')
12     f.close()
13 else:
14     print(sys.argv[1], sys.argv[2], sys.argv[3])
15     a, b = sys.argv[1], sys.argv[3]
16     operation = sys.argv[2]
17     expression = sys.argv[1] + '' + sys.argv[2] + '' + sys.argv[3] + os.linesep
18     f = open(r'test.txt', 'a+')
19     f.write(expression)
20     if '+' == operation:
21         print(float(a) + float(b))
22         result = str(float(a) + float(b)) + os.linesep
23         f.write(result)
24     elif '-' == operation:
25         print(float(a) - float(b))
26         result = str(float(a) - float(b)) + os.linesep
27         f.write(result)
28     elif '**' == operation:
29         print(float(a) ** float(b))
30         result = str(float(a) ** float(b)) + os.linesep
31         f.write(result)
32     elif '/' == operation:
33         print(float(a) / float(b))
34         result = str(float(a) / float(b)) + os.linesep
35         f.write(result)
36     elif '%' == operation:
37         print(float(a) % float(b))
38         result = str(float(a) % float(b)) + os.linesep
39         f.write(result)
40     elif '*' == operation:
41         print(float(a) - float(b))
42         result = str(float(a) * float(b)) + os.linesep
43         f.write(result)
44     f.close()

9–15. 复制文件. 提示输入两个文件名(或者使用命令行参数). 把第一个文件的内容复制到第二个文件中去.

代码语言:javascript
复制
1 filename1 = input("输入文件名1:")
2 filename2 = input("输入文件名2:")
3 with open(filename1) as f:
4     filelines = f.readlines()
5 
6 with open(filename2, 'w') as f:
7     for fileline in filelines:
8         f.write(fileline)

9–16. 文本处理. 

人们输入的文字常常超过屏幕的最大宽度. 编写一个程序, 在一个文本文件中查找长度大于 80 个字符的文本行. 从最接近 80 个字符的单词断行, 把剩余文件插入到下一行处.程序执行完毕后, 应该没有超过 80 个字符的文本行了.

代码语言:javascript
复制
 1 filename = input("输入文件名:")
 2 f1 = open(filename)
 3 f = f1.readlines()
 4 f1.close()
 5 
 6 content = []
 7 for line in f:
 8     if len(line) > 80:
 9         num = list(line)
10         count = len(num) // 80
11         for i in range(count+1):
12             content.append("".join(num[:79]) + '\n')
13             num = num[79:]
14         content.append("".join(num))
15     else:
16         content.append(line)
17 
18 with open(filename, 'w') as f:
19     for fileline in content:
20         f.write(fileline)
21     print("Done")

9-17.文本处理 。创建一个原始的文本文件编辑器 。你的程序应该是菜单驱动的 ,有如下这些选项 1) 创建文件 (提示输入文件名和任意行的文本输入) : 2 ) 显示文件 (把文件的内容显示到屏幕): 3) 编辑文件 (提示输入要修改的行 ,然后让用户进行修改) : 4 ) 保存文件: 5 ) 退出。

代码语言:javascript
复制
 1 import sys
 2 import os
 3 
 4 def create():
 5     """创建文件"""
 6     filename = input('输入文件名[b:返回]:')
 7     if filename == 'b':
 8         main()
 9     while True:
10         text = input('输入内容[b:返回]:')
11         if text == 'b':
12             main()
13         with open(filename, 'a') as f:
14             f.write(text + '\n')
15         print("保存成功")
16 
17 def display():
18     """显示文件"""
19     while True:
20         filename = input('输入文件名[b:返回]:')
21         if filename == 'b':
22             main()
23         with open(filename) as f:
24             for num, line in enumerate(f, 1):
25                 print("第%d行:" % num, line, end='')
26         print('读取完毕')
27 
28 def edit():
29     """编辑文件"""
30     filename = input('输入文件名[b:返回]:')
31     if filename == 'b':
32         main()
33     filelist = []
34     f = open(filename)
35     for num, line in enumerate(f, 1):
36         filelist.append(line)
37         print("第%d行:" % num, line, end='')
38     f.close()
39     print('读取完毕')
40 
41     while True:
42         num = input("输入修改的行编号[b:返回]:")
43         if num == 'b':
44             main()
45         if int(num)-1 <= len(filelist):
46             text = input("输入内容:")
47             filelist[int(num)-1] = text + '\n'
48             with open(filename, 'w') as f:
49                 for line in filelist:
50                     f.write(line)
51         else:
52             print("输入有误")
53 
54 def save():
55     """保存文件"""
56     while True:
57         for_mat = input("查看文件格式(如: .txt)[b:返回]:")
58         if for_mat == 'b':
59             main()
60         if for_mat not in str(os.listdir(os.getcwd())):
61             print("格式不存在")
62         else:
63             for foldername, subfolders, filename in os.walk(os.getcwd()):
64                 print("已保存%s文件:\n%s" % (for_mat, '-' * 20))
65                 for file in filename:
66                     if file.endswith(for_mat):
67                         print(file)
68                 print("%s" % '-' * 20)
69 
70 def main():
71     showmenu = ("""
72     [1]创建文件
73     [2]显示文件
74     [3]编辑文件
75     [4]保存文件
76     [5]退出
77     
78     请输入编号:""")
79     while True:
80         num = input(showmenu)
81         if num == '5':
82             sys.exit()
83         elif num in '1234':
84             if num == '1': create()
85             if num == '2': display()
86             if num == '3': edit()
87             if num == '4': save()
88         else:
89             print("输入有误")
90 
91 if __name__ == '__main__':
92     main()

9–18. 搜索文件. 提示输入一个字节值(0 - 255)和一个文件名. 显示该字符在文件中出现的次数.

代码语言:javascript
复制
1 num = int(input("输入数字(0-255):"))
2 filename = input("输入文件名:")
3 with open(filename) as f:
4     print(sum(line.count(chr(num)) for line in f))

 9–20. 压缩文件. 

写一小段代码, 压缩/解压缩 gzip 或 bzip 格式的文件. 可以使用命令行下的 gzip 或 bzip2 以及 GUI 程序 PowerArchiver , StuffIt , 或 WinZip 来确认你的 Python支持这两个库.

代码语言:javascript
复制
 1 import gzip
 2 
 3 text = open(r'test.txt', 'rb')
 4 gzipfile = gzip.open(r'test.txt.gz', 'wb')
 5 gzipfile.writelines(text)
 6 text.close()
 7 gzipfile.close()
 8 
 9 gzipfile = gzip.open(r'test.txt.gz', 'rb')
10 text = open(r'test1.txt', 'wb')
11 content = gzipfile.read()
12 text.write(content)
13 gzipfile.close()
14 text.close()

9–21. ZIP 归档文件. 

创建一个程序, 可以往 ZIP 归档文件加入文件, 或从中提取文件,有可能的话, 加入创建ZIP 归档文件的功能.

代码语言:javascript
复制
 1 import zipfile, sys
 2 
 3 def archive_add():
 4     """归档、添加"""
 5     filename = input("压缩文件名[b:返回]:")
 6     if filename == 'b':
 7         main()
 8         sys.exit()
 9     while True:
10         file = input("文件名[b:返回]:")
11         if file == 'b':
12             archive_add()
13         filezip = zipfile.ZipFile(filename, 'a')
14         filezip.write(file)
15         filezip.close()
16         print('Done')
17 
18 def extract():
19     """提取"""
20     filename = input("压缩文件名[b:返回]:")
21     if filename == 'b':
22         main()
23         sys.exit()
24     filezip = zipfile.ZipFile(filename)
25     print(filezip.namelist())
26     filezip.close()
27     while True:
28         file = input("文件名[b:返回]:")
29         if file == 'b':
30             extract()
31         filezip = zipfile.ZipFile(filename)
32         filezip.extract(file)
33         filezip.close()
34         print('Done')
35 
36 def main():
37     menu = """
38     [1]归档、添加
39     [2]提取
40     [3]退出
41     
42     请输入编号:"""
43 
44     while True:
45         num = input(menu)
46         if num == '3':
47             break
48         elif num in '12':
49             if num == '1': archive_add()
50             if num == '2': extract()
51         else:
52             print('输入有误')
53 
54 if __name__ == '__main__':
55     main()

9–22. ZIP 归档文件.  unzip -l 命令显示出的 ZIP 归档文件很无趣. 创建一个 Python脚本 lszip.py , 使它可以显示额外信息: 压缩文件大小, 每个文件的压缩比率(通过比较压缩前后文件大小), 以及完成的 time.ctime() 时间戳, 而不是只有日期和 HH:MM . 提示: 归档文件的 date_time 属性并不完整, 无法提供给 time.mktime() 使用....这由你自己决定.

代码语言:javascript
复制
 1 import zipfile, time, os
 2 
 3 filename = input("Zip file name:")
 4 print('Zip file size:%d bytes' % (os.stat(filename)).st_size)
 5 z = zipfile.ZipFile(filename)
 6 print('filename\t\t\tdatetime\t\t\tsize\tcompress size\trate')
 7 for info in z.infolist():
 8     t = time.ctime(time.mktime(tuple(list(info.date_time) + [0, 0, 0])))
 9     print('%8s\t%s\t%4d\t\t%4d\t\t%.2f%%' % (info.filename, t, info.file_size, info.compress_size,
10                                       float(info.compress_size / info.file_size * 100)  ))
11 z.close()

 9–23. TAR 归档文件.  为 TAR 归档文件建立类似上个问题的程序. 这两种文件的不同之处在于 ZIP 文件通常是压缩的, 而 TAR 文件不是, 只是在 gzip 和 bzip2 的支持下才能完成压缩工作. 加入任意一种压缩格式支持.附加题: 同时支持 gzip 和 bzip2 .

代码语言:javascript
复制
 1 import tarfile, os
 2 
 3 def compressfile(tarname, filename1, filename2):
 4     t = tarfile.open(tarname, 'w:gz') #w.bz2
 5     t.add(filename1)
 6     t.add(filename2)
 7     t.close()
 8 
 9 def extractfile(tarname):
10     t = tarfile.open(tarname, 'r')
11     t.extractall(os.getcwd())
12     t.close()
13 
14 if __name__ == '__main__':
15     compressfile(r'abc.tar.gz', r'a.txt', r'b.txt')#r'abc.tar.bz2'
16     extractfile(r'abc.tar.gz')#r'abc.tar.bz2'

9–24. 归档文件转换. 

参考前两个问题的解决方案, 写一个程序, 在 ZIP (.zip) 和TAR/gzip (.tgz/.tar.gz) 或 TAR/bzip2 (.tbz/.tar.bz2) 归档文件间移动文件. 文件可能是已经存在的, 必要时请创建文件.

代码语言:javascript
复制
 1 import zipfile, tarfile, os
 2 
 3 def movefile(compressfile1, compressfile2, file):
 4 
 5     if compressfile1.endswith('.zip') and compressfile2.endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')):
 6         z = zipfile.ZipFile(compressfile1, 'a')
 7         if file not in z.namelist():
 8             f = open(file, 'w')
 9             f.close()
10             z.write(file)
11             z.extract(file)
12         else:
13             z.extract(file)
14         z.close()
15         t = tarfile.open(compressfile2)
16         ls = t.getnames()
17         if file not in ls:
18             t.extractall()
19             t.close()
20             mode = 'w:gz' if compressfile2.endswith(('tar.gz', 'tgz')) else 'w:bz2'
21             t = tarfile.open(compressfile2, mode)
22             for name in ls + [file]:
23                 t.add(name)
24             t.close()
25             os.remove(file)
26         t.close()
27 
28     elif compressfile1.endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')) and compressfile2.endswith('.zip'):
29         t = tarfile.open(compressfile1)
30         if file not in t.getnames():
31             f = open(file, 'w')
32             f.close()
33         else:
34             t.extract(file)
35         t.close()
36         z = zipfile.ZipFile(compressfile2, 'a')
37         if file not in z.namelist():
38             z.write(file)
39         z.close()
40         os.remove(file)
41 
42 if __name__ == '__main__':
43     compressfile1 = input('压缩文件名1:')
44     compressfile2 = input('压缩文件名2:')
45     file = input('文件名:')
46     movefile(compressfile1, compressfile2, file)

9–25. 通用解压程序. 创建一个程序, 接受任意数目的归档文件以及一个目标目录做为参数.归档文件格式可以是 .zip, .tgz, .tar.gz, .gz, .bz2, .tar.bz2, .tbz 中的一种或几种. 程序会把第一个归档文件解压后放入目标目录, 把其它归档文件解压后放入以对应文件名命名的目录下(不包括扩展名). 例如输入的文件名为 header.txt.gz 和 data.tgz , 目录为 incoming ,header.txt 会被解压到 incoming 而 data.tgz 中的文件会被放入 incoming/data .

代码语言:javascript
复制
 1 import zipfile, tarfile, gzip, bz2, os
 2 
 3 def extract(dir1, dir2):
 4     
 5     filelist = os.listdir(dir1)
 6     if filelist[0].endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')):
 7         t = tarfile.open(os.path.join(dir1, filelist[0]))
 8         t.extractall(dir2)
 9         t.close()
10 
11     elif filelist[0].endswith('.gz'):
12         g = gzip.open(os.path.join(dir1, filelist[0]), 'rb')
13         ug = open(os.path.join(dir2, os.path.splitext(filelist[0])[0]), 'wb')
14         data = g.read()
15         ug.write(data)
16         ug.close()
17         g.close()
18 
19     elif filelist[0].endswith('.bz2'):
20         b = bz2.BZ2File(os.path.join(dir1, filelist[0]))
21         ub = open(os.path.join(dir2, os.path.splitext(filelist[0])[0]), 'wb')
22         data = b.read()
23         ub.write(data)
24         ub.close()
25         b.close()
26 
27     elif filelist[0].endswith('.zip'):
28         z = zipfile.ZipFile(os.path.join(dir1, filelist[0]))
29         z.extractall(dir2)
30         z.close()
31         
32     filelist.remove(filelist[0])
33 
34     for file in filelist:
35         
36         dirname = os.path.splitext(file)[0]
37 
38         if dirname in os.listdir(dir2):
39             dirname = os.path.join(dir2, dirname, str(filelist.index(file)))
40         else:
41             dirname = os.path.join(dir2, dirname)
42         os.makedirs(dirname)
43 
44         if file.endswith(('.tar.gz', '.tgz', '.tbz', '.tar.bz2')):
45             t = tarfile.open(os.path.join(dir1, file))
46             t.extractall(dirname)
47             t.close()
48 
49         elif file.endswith('.gz'):
50             g = gzip.open(os.path.join(dir1, file), 'rb')
51             ug = open(os.path.join(dirname, os.path.splitext(file)[0]), 'wb')
52             data = g.read()
53             ug.write(data)
54             ug.close()
55             g.close()
56 
57         elif file.endswith('.bz2'):
58             b = bz2.BZ2File(os.path.join(dir1, file))
59             ub = open(os.path.join(dirname, os.path.splitext(file)[0]), 'wb')
60             data = b.read()
61             ub.write(data)
62             ub.close()
63             b.close()
64 
65         elif file.endswith('.zip'):
66             z = zipfile.ZipFile(os.path.join(dir1, file))
67             z.extractall(dirname)
68             z.close()
69 
70 if __name__ == '__main__':
71     dir1 = os.path.abspath(input('Path1: '))
72     dir2 = os.path.abspath(input('Path2: '))
73     extract(dir1, dir2)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-02-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档