1. 程式人生 > >《Python程式設計:從入門到實踐》第10章-檔案和異常 習題

《Python程式設計:從入門到實踐》第10章-檔案和異常 習題

文章目錄

10-1 Python學習筆記

在文字編輯器中新建一個檔案,寫幾句話來總結一下你至此學到的Python知識,其中每一行都以“In Python you can” 打頭。將這個檔案命名為learning_python.txt,並將其儲存到為完成本章練習而編寫的程式所在的目錄中。編寫一個程式,它讀取這個檔案,並將你所寫的內容列印三次:第一次列印時讀取整個檔案;第二次列印時遍歷檔案物件;第三次列印時將各行儲存在一個列表中,再在with程式碼塊列印它們。

(1)列印時讀取整個檔案

file_name = "py_learning.txt"

with open(file_name) as file_object:
	lines = file_object.read()
	print(lines.rstrip())	

小結:

  • 方法read()讀取檔案的全部內容。
  • 方法rstrip()刪除末尾的空格。
  • 方法strip()刪除兩端的空格。

△(2)列印時遍歷檔案物件。

file_name = "learning_python.txt"

with open(file_name) as file_object:
for line in file_object: print(line.strip())

展示一種錯誤寫法
在寫這段的時候寫成:

lines = file_object.read()
for line in lines:
	print(line.strip())

要多加註意。

(3)將各行儲存在一個列表中,再在with程式碼塊外列印它們

file_name = "learning_python.txt"

with open(file_name) as file_object:
	lines = file_object.readlines()

for line in
lines: print(line.strip())

上述輸出結果均為:

In Python you can establish dictionary.
In Python you can establish list.
In Python you can use while, for and if to do logical judgment.
In Python you can use function to solve problems.

10-2 C語言學習筆記

可用方法replace()將字串中的特定單詞都替換為另一個單詞。下面是一個簡單的示例,演示瞭如何將句子中的‘dog’替換為‘cat’:

>>> message = "I really like dogs."
>>> message.replace('dog', 'cat')
'I really like cats.'

讀取你剛建立的檔案learning_python.txt中的每一行,將其中的Python都替換為另一門語言的名稱,如C。將修改後的各行都列印到螢幕上。

file_name = "learning_python.txt"

with open(file_name) as file_objects:
	contents = file_objects.read()
	contents_change = contents.replace('Python', 'C')
	print(contents_change)

build

In C you can establish dictionary.
In C you can establish list.
In C you can use while, for and if to do logical judgment.
In C you can use function to solve problems.

10-3 訪客

編寫一個程式,提示使用者輸入其名字。使用者作出響應後,將其名字寫入到檔案guest.txt中。

filename = "guest.txt"

username = input("Please input your name:")

with open(filename, 'w') as file_object:
	file_object.write(username)

Tools—SublimeREPL—Python—Python-runcurrentfile

Please input your name:

輸入 “Yan Junze”

Please input your name:Yan Junze

***Repl Closed***

開啟與該Python程式同一個資料夾的guest.txt
在這裡插入圖片描述
該字串被寫入檔案。

10-4 訪客名單

編寫一個while迴圈,提示使用者輸入其名字。使用者輸入名字後,在螢幕上列印一條問候語,並將一條訪問記錄新增到檔案guest_book.txt中。確保這個檔案中的每條記錄都獨佔一行。

filename = "guest_book.txt"

print("Enter 'quit' when you are finished.\n")

active = True
while active:
	username = input("What's your name? ")

	if username == "quit":
		active = False

	else:
		with open(filename, 'a') as file_object:
			file_object.write(username.title() + " has visited the website.\n")
			print(username.title() + ", welcome to our website.")

Tools—SublimeREPL—Python—Python-runcurrentfile

Enter 'quit' when you are finished.

What's your name? yan junze
Yan Junze, welcome to our website.
What's your name? liu shiyu
Liu Shiyu, welcome to our website.
What's your name? quit

***Repl Closed***

txt的寫入結果如下圖。
在這裡插入圖片描述
(這道題參考了答案)

原本的寫法也寫得不好。while迴圈使用得很草率,沒有利用邏輯值的賦值。

下面是錯誤示範

filename = "guest_book.txt"

active = True
while active:
	username = input("Please input your name:")
	with open(filename, 'a') as file_object:
		file_object.write(username)
		print("Welcome to the Website, " + username.title())
		username = input("Please input your name:")

但雖然寫得不對,也不明白為什麼不對。

10-5 關於程式設計的調查

編寫一個while迴圈,詢問使用者為何喜歡程式設計。每當使用者輸入一個原因後,都將其新增到一個儲存所有原因的檔案中。
這題的做法基本和10-4沒有區別

filename = "love_programming_reason.txt"

print("Enter 'quit' when you finished.\n")

active = True
while active:
	reason = input("Why do you love programming?\n")

	if reason == 'quit':
		active = False

	else:
		with open(filename, 'a') as file_object:
			file_object.write(reason)
			print("Thank you!")

Tools—SublimeREPL—Python—Python-runcurrentfile

Enter 'quit' when you finished.

Why do you love programming?
it's interesting
Thank you!

Why do you love programming?
it's cool
Thank you!

Why do you love programming?
I enjoy it
Thank you!

Why do you love programming?
quit

***Repl Closed***

儲存原因的檔案:
在這裡插入圖片描述

10-6 加法運算

提示使用者提供數值輸入時,常出現的一個問題是,使用者提供的是文字而不是數字。在這種情況下,當你嘗試將輸入轉換為整數時,將引發ValueError異常。編寫一個程式,提示使用者輸入兩個數字,再將它們相加並列印結果。在使用者輸入的任何一個值不是數字時都捕獲ValueError異常,並列印一條友好的錯誤訊息。對你編寫的程式進行測試:先輸入兩個數字,再輸入一些文字而不是數字。

num2 = input("Please input the second number:")

try:
	num3 = int(num1) + int(num2)
except ValueError:
	print("Sorry, you need to input number instead of words.")
else:
	print("The sum of these two numbers is " + str(num3))

Build—Tools—SublimeREPL—Python—Python-runcurrentfile
輸入數字:

Please input the first number:5
Please input the second number:7
The sum of these two numbers is 12

***Repl Closed***

輸入文字:

Please input the first number:5
Please input the second number:hello
Sorry, you need to input number instead of words.

***Repl Closed***

10-7 加法計算器

將你為完成練習10-6而編寫的程式碼放在一個while迴圈中,讓使用者犯錯(輸入的是文字而不是數字)後能繼續輸入數字。

active = True
print("Enter 'q' when you want to quit.\n")

while active:
	num1 = input("Please input the first number:")
	if num1 == 'q':
		active = False #False要大寫
	else:
		num2 = input("Please input the second number:")

		if num2 =='q':
			active = False
		else:
			try:
				num3 = int(num1) + int(num2)
			except ValueError:
				print("Sorry, you need to input number instead of words.\n")
			else:
				print("The sum of these two numbers is " + str(num3) + ".\n")

Tools—SublimeREPL—Python—Python-runcurrentfile

Enter 'q' when you want to quit.

Please input the first number:hello
Please input the second number:3
Sorry, you need to input number instead of words.

Please input the first number:byebye
Please input the second number:5
Sorry, you need to input number instead of words.

Please input the first number:5
Please input the second number:6
The sum of these two numbers is 11.

Please input the first number:q

***Repl Closed***

10-8 貓和狗

建立兩個檔案cats.txt和dogs.txt,在第一個檔案中至少儲存三隻貓的名字,在第二個檔案中至少儲存三條狗的名字。編寫一個程式,嘗試讀取這些檔案,並將其內容列印到螢幕上。將這些程式碼放在一個try-except程式碼塊中,以便在檔案不存在時捕獲FileNotFound錯誤,並列印一條友好的訊息。將其中一個檔案遷移到另一個地方,並確認except程式碼塊中的程式碼將正確地執行。

def print_out(filename):
	"""定義一個列印檔案內容的函式"""

	try:
		with open(filename) as objects:
			contents = objects.read()
	except FileNotFoundError:
		print("Sorry," + filename + "does not exist.")
	else:
		print(contents + "\n")

filenames = ['cats.txt', 'dogs.txt']
for filename1 in filenames:
	print_out(filename1)

build

shagou
jiaozi
watermelon
lingling

Sorry,dogs.txtdoes not exist.

10-9 沉默的貓和狗

修改你在練習10-8中編寫的except程式碼塊,讓程式在檔案不存在時一言不發。

pass語句的使用和作用

def print_out(filename):
	"""定義一個列印檔案內容的函式"""

	try:
		with open(filename) as objects:
			contents = objects.read()
	except FileNotFoundError:
		pass
	else:
		print(contents + "\n")

filenames = ['cats.txt', 'dogs.txt']
for filename1 in filenames:
	print_out(filename1)

build

shagou
jiaozi
watermelon
lingling

10-10 常見單詞

訪問專案Gutenberg,並找一些你想分析的圖書。下載這些作品的文字檔案或將瀏覽器中的原始文字複製到文字檔案中。
你可以使用方法count()來確定特定的單詞或短語在字串中出現了多少次。例如,下面的程式碼計算‘row’在一個字串中出現了多少次:

>>> line = "Row, row, row your boat"
>>> line.count('row')
2
>>> line.lower().count('row')
3

請注意,通過使用lower()將字串轉換為小寫,可捕捉要查詢的單詞出現的所有次數,而不管其大小寫格式如何。
編寫一個程式,它讀取你在專案Gutenberg中獲取的檔案,並計算單詞‘the’在每個檔案中分別出現了多少次。

def count_words(filename, word_to_count):
	"""計算文件中任意單詞的數目"""
	try:
		with open(filename) as objects:
			contents = objects.read()
	except FileNotFoundError:
		print("Sorry," + filename + " cannot be found.")
	else:
		contents1 = contents.lower()
		number=contents.lower().count(word_to_count)
		print("The number of the word '" + word_to_count + "' in" + filename
			+ " is " + str(number))

filenames = ['grania.txt', 'Colored Troops in the French Army.txt']
for filename1 in filenames:
	count_words(filename1, 'the')

build

The number of the word 'the' ingrania.txt is 3775
Sorry,Colored Troops in the French Army.txt cannot be found.

兩個問題

問題1

UnicodeDecodeError: 'gbk' codec can't decode byte 0x99 in position 1524: illegal multibyte sequence

使用notepad.exe小程式改變編碼型別。
==①當txt檔案編碼為ANSI時,如上述可順利執行 ==
②當txt檔案編碼為UTF-8時,第四行改為

with open(filename, 'r', encoding='UTF-8') as objects:

Unicode和Unicode big endian的情況有待探究

問題2
當第四行改為:

with open(filename, 'rb') as objects:

出現

TypeError: argument should be integer or bytes-like object, not 'str'

‘rb’表示讀寫二進位制資料(存疑?)
需要補充一下編碼知識

10-11 喜歡的數字

編寫一個程式,提示使用者輸入他喜歡的數字,並使用json.dump()將這個數字儲存到檔案中。再編寫一個程式,從檔案中讀取這個值,並列印訊息“I know your favorite number! It’s___. ”

(1)用json.dump()將數字儲存到檔案中。

import json

filename = "favorite_number.json"
number = input("What's your favorite number?")

with open(filename, 'w') as f_obj:
	json.dump(number, f_obj)
	print("We'll remember your favorite number.")

Build—Tools—SublimeREPL—Python—Python-runcurrentfile

What's your favorite number?15
We'll remember your favorite number.

(2)從檔案中讀取這個值

import json

filename = "favorite_number.json"

with open(filename) as f_obj:
	number = json.load(f_obj)
	print("Your favorite number is " + number + ".")

build

Your favorite number is 15.

10-12 記住喜歡的數字

將練習10-11中的兩個程式合而為一。如果儲存了使用者喜歡的數字,就向用戶顯示它,否則提示使用者輸入他喜歡的數字並將其儲存到檔案中。執行這個程式兩次,看看它是否像預期的那樣工作。

import json

filename = "favorite_number.json"

try:
	with open(filename) as f_obj:
		number = json.load(f_obj)
			
except FileNotFoundError:
	number = input("What's your favorite number?")
	with open(filename, 'w') as f_obj:
		json.dump(number, f_obj)
		print("We'll remember your favorite number.\n")
else:	
	print("Your favorite number is " + number + ".")

第一次:
Build—Tools—SublimeREPL—Python—Python-runcurrentfile

What's your favorite number? 15
We'll remember your favorite number.


***Repl Closed***

第二次:在已經輸入favorite number的情況下。build。

Your favorite number is  15.

程式能夠在兩種情況下順利執行。

10-13 驗證使用者

最後一個remember_me.py版本假設使用者要麼已輸入其使用者名稱,要麼是首次執行該程式。我們應修改這個程式,以應對這樣的情形:當前和最後一次執行該程式的使用者並非同一個人。
為此,在greet_user()中列印歡迎使用者回來的訊息前,先詢問他使用者名稱是否是對的。如果不對,就呼叫get_new_username()讓使用者輸入正確的使用者名稱。

import json

def get_stored_username():
	"""如果儲存了使用者名稱,就獲取它"""
	filename = 'username.json'
	try:
		with open(filename) as f_obj:
			username = json.load(f_obj)
	except FileNotFoundError:
		return None
	else:
		return username

def get_new_username():
	"""提示使用者輸入使用者名稱"""
	username = input("What is your name? ")
	filename = 'username.json'
	with open(filename, 'w') as f_obj:
		json.dump(username, f_obj)
	return username

def greet_new_user():
	username = get_new_username()
	print("We'll remember when you come back " + username + "!")

def greet_user():
	"""問候使用者,並指出其名字"""
	username = get_stored_username()
	if username:
		correct = input("Is '" + username + "' your name? Input 'N' if it is not your name.\n"+ 
			"And input anything else if it is your name.\n" )
		correct1 = correct.upper()
		if correct1 == 'N':
			greet_new_user()
		else:
			print("Welcome back, " + username + "!")
	else:
		greet_new_user()

greet_user()

Build—Tools—SublimeREPL—Python—Python-runcurrentfile

①事先沒有該file的情況。

What is your name? Wang
We'll remember when you come back Wang!

***Repl Closed***

②存在該file的情況:
(a)當用戶變更,使用者名稱不正確時。

Is 'Wang' your name? Input 'N' if it is not your name.
And input anything else if it is your name.
N
What is your name? Eric
We'll remember when you come back Eric!

***Repl Closed***

(b)當用戶未變,使用者名稱正確時。

Is 'Eric' your name? Input 'N' if it is not your name.
And input anything else if it is your name.
your
Welcome back, Eric!

***Repl Closed***

注意
Advantage: 對greet_new_user()部分進行了重構,建立一個新的函式。使無論是第一次執行程式還是更換使用者,輸入名字時均能收到問候。
Disadvantage: greet_user()函式中,if語句的巢狀問題;‘N’對應否,而任意其他鍵對應‘Yes’,是否不合理?需要思考。

總結

  • 例題&習題
  • 幕布
  • 筆記
  • 二刷