[英]How can I get this for loop to work correctly to replace a line in a file when certain conditions are met?
我正在尋找一個圖書館類型的程序,該程序允許您從一個小的“數據庫”文本文件中取出一本書,然后修改文件中的行,以包括先前輸入的用戶ID以表明它已被使用。
輸入的用戶ID必須是一個整數,且必須為4位數字,這使我可以使用try / except程序來進行處理,但現在開始實際寫入文件時,似乎不再跑過去詢問book_id,盡管它在我檢查ID正確長度的所有內容之前都起作用。
同樣,所有這些都應該放在“ def checkout()”函數中(這樣我以后就可以對一個主程序進行修改,包括我編寫的搜索功能和一個允許您“退還”書的程序),但是如果我嘗試放下它在其中,我得到的都是縮進錯誤,每當我嘗試使用中斷以阻止程序重復“對不起,找不到書ID或書不可用”時,每本書或每本書都會死。 在這一點上,我只是在尋找基本功能,即使它不能完美運行,所以主要的優先任務是使其真正運行。
while True:
txt = open("book_list.txt", "r+")
try:
user_id = int((raw_input("Please enter your ID: ")))
if len(str(user_id)) != 4:
print "Sorry, that was an invalid ID. Please try again."
continue
break
except:
print "Sorry, that was an invalid ID. Please try again."
book_id = (raw_input("Please enter the book ID no. you would like to take out: "))
for line in txt:
if book_id == line[0] and line[-1] == " ":
txt.write(line.replace(line,user_id))
print "You have successfully taken out the book."
else:
print "Sorry, either the book ID was not found or the book is unavailable."
txt.close()
有問題的文本文件是:
1 Book_1 Author_1 1234
2 Book_1 Author_1
3 Book_2 Author_2
4 Book_3 Author_3 2000
5 Book_4 Author_3
書籍ID是左側的數字,而用戶ID(或空格“”表示該書籍可用)是右側的數字。
我可能很簡單,因為我是一個初學者,所以我很想念它並使其無法工作,但我感謝任何投入,歡呼。
首先,您可以輕松地驗證ID,而無需使用異常:
def id_valid(id):
return len(id) == 4 and id.isdigit()
如果字符串中的所有字符都是數字,則isdigit()方法將返回true。
然后可以這樣讀取正確的ID:
PROMPT = "Please enter your ID: "
user_id = raw_input(PROMPT)
while not id_valid(user_id):
print "Sorry, that was an invalid ID. Please try again."
user_id = raw_input(PROMPT)
“很抱歉,找不到書ID或書不可用。” 該消息被顯示了很多次,因為您在ID不匹配或書籍不可用的每次迭代中打印該消息。 您可以使用布爾值標記來記住是否找到了這本書,並在最后打印該消息一次:
book_found = False
with open("book_list.txt", "r") as txt:
for line in txt:
data = line.split();
if book_id == data[0] and len(data) == 3:
# modify the file here
print "You have successfully taken out the book."
book_found = True
if not book_found:
print "Sorry, either the book ID was not found or the book is unavailable."
假設每一行中的數據條目都由空格分隔,則可以使用split來分隔ID。 它將返回一個列表,其中[0]元素是書籍ID,[3]是用戶ID(如果存在)。 如果沒有用戶ID,則列表將僅包含3個元素。
至於更新文件,最簡單的策略是在處理原始文件時保存修改后的副本,如果要在最后保存修改,則將其覆蓋。
您的代碼中有兩個問題:
不要在while循環中但在循環之前打開文件(並適當地添加錯誤檢查)
while True: txt = open("book_list.txt", "r+")
如果寫入r+
文件,則將txt.write
寫入的所有行附加到文件末尾。 不要覆蓋它們! 這意味着簽出一本書后,您將在該書簽出文件的末尾有一個新行。 覆蓋文件更加復雜! 基本上有兩種解決方案,您可以讀取整個文件,也可以將其保存在字典或其他文件中。 然后使用w
重寫整個文件。 或者,這有點丑陋,您需要在每本書后面精確地放置四個空格,然后使用txt.seek
用用戶數覆蓋這些txt.seek
。
比較book_id == line[0]
基本上意味着您檢查line
的第一個字符是否等於書號,這與檢查行的第一個數字是否與您的書號相同是不同的book_id == int(line[0:line.index(" ")])
您得到的縮進錯誤很難檢查,但是基本上您必須檢查您是IDE還是texteditor,如果它正確處理了空格和制表符,或者您是否某種程度上不關心縮進。
首先從while
循環中刪除open語句,它會不必要地打開文件。
while True:
try:
user_id = int((raw_input("Please enter your ID: ")))
if len(str(user_id)) != 4:
print "Sorry, that was an invalid ID. Please try again."
continue
break
except:
print "Sorry, that was an invalid ID. Please try again."
book_id = (raw_input("Please enter the book ID no. you would like to take out: "))
其次with
while
處理文件時使用with
語句while
因此您不必跟蹤關閉它。 另外,在"r+"
模式下打開文件會使問題變得更加復雜,因為最終將要添加數據,您可以利用seek
和tell
但是這樣做不會使事情變得容易,也可能會覆蓋數據,因此我建議您使用一個臨時文件
out_txt = open("temp.txt","w")
found = False
with open("book_list.txt", "r") as txt:
for line in txt:
if book_id == line[0] and line[-1] == " ": # are you sure that every line that does not have an user_id associated to it is going to have a " "(space) at the end of it, if not think of some other condition to do this
line = line.strip() + " " + str(user_id) + "\n"
print "You have successfully taken out the book."
found = True
out_txt.write(line)
out_txt.close()
if found:
import os
os.remove("book_list.txt")
os.rename(out_txt.name, "book_list.txt")
else:
print "Sorry, either the book ID was not found or the book is unavailable."
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.