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

发布时间:2019-02-28 20:12:09编辑:auto阅读(2149)

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

    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 行.

    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. 文件信息. 提示输入一个文件名, 然后显示这个文本文件的总行数.

    1 filename = input('输入文件名:')
    2 with open(filename) as f:
    3     allline = f.readlines()
    4     print(len(allline))

    9–4. 文件访问. 

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

    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),要求能从多个文件中读入考试成绩。文件的数据格式由你自己决定。

     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. 文件比较. 写一个比较两个文本文件的程序. 如果不同, 给出第一个不同处的行号和列号.

     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 文件的程序. 其它平台用户: 写一个解析特定结构的系统配置文件的程序.

     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() 和其它内建函数提取模块的属性, 显示它们的名字, 类型, 值.

    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)和函数的文档.

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

      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 进行验证.

      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)的更少

      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

     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. 复制文件. 提示输入两个文件名(或者使用命令行参数). 把第一个文件的内容复制到第二个文件中去.

    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 个字符的文本行了.

     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 ) 退出。

     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)和一个文件名. 显示该字符在文件中出现的次数.

    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支持这两个库.

     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 归档文件的功能.

     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() 使用....这由你自己决定.

     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 .

     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) 归档文件间移动文件. 文件可能是已经存在的, 必要时请创建文件.

     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 .

     

     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)

     

关键字