当满足某些条件时,如何让这个 for 循环正常工作以替换文件中的一行?
How can I get this for loop to work correctly to replace a line in a file when certain conditions are met?
我正在寻找一个图书馆类型的程序,允许您从一个小的 "database" 文本文件中取出一本书,然后修改文件中的行以包含之前输入的用户 ID表明它已被拍摄。
输入的用户 ID 必须是一个整数和 4 位数字,我已经让程序用 try/except 来解决这个问题,除了现在要继续实际编写文件,它似乎不再 运行 过去要求 book_id 尽管在我放入所有检查 ID 的正确长度之前它是可用的。
此外,这一切都意味着在一个 "def checkout()" 函数中(这样我以后可以正确地创建一个主程序,包括我编写的搜索功能和一个允许你 'return' 书籍的程序)但是如果我试图把它放在里面,我得到的都是缩进错误,每当我试图使用 break 来阻止程序为每本书或每本书重复 "Sorry, either the book ID was not found or the book is unavailable" 时,整个事情都会死掉。在这一点上,我只是在寻找基本的功能,即使它不能完美地工作,所以主要的优先事项是实际获得它 运行ning.
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(或 space“ ”,表示该书可用)是右边的数字。
这可能是我遗漏的一些非常简单的事情,并且已经做了使其无法工作,因为我是初学者,但我感谢任何输入,干杯。
您的代码中有几个问题:
不要在 while 循环之前打开文件(并适当添加错误检查)
while True:
txt = open("book_list.txt", "r+")
如果您写入 r+
文件,您会将 txt.write
写入的所有行追加到文件末尾。
不要覆盖它们!这意味着在签出一本书后,您将有一个新行
在文件的末尾,这本书被签出。在文件中覆盖更复杂!
基本上有两种解决方案,要么读入整个文件并将其保存在字典中,要么……。然后用 w
重写整个文件。
或者,这有点难看,你在每本书后面放了四个空格,然后使用 txt.seek
.
用用户数覆盖这些空格
比较book_id == line[0]
基本上就是检查line
的第一个字符是否等于书的编号,这与检查是否相同该行的第一个数字与您的图书 ID 相同
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
处理文件,因此您不必跟踪关闭它。
另外,在 "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."
首先,您可以在不使用异常的情况下轻松验证 ID:
def id_valid(id):
return len(id) == 4 and id.isdigit()
如果字符串中的所有字符都是数字,isdigit() 方法return为真。
然后可以这样读取正确的 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)
"Sorry, either the book ID was not found or the book is unavailable." 消息显示了很多次,因为您在每次迭代中打印它,其中 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。它将 return 一个列表,其中 [0] 元素是图书 ID,[3] 是用户 ID(如果存在)。如果没有用户 ID,列表将只有 3 个元素。
至于更新文件,最简单的策略是在处理原始文件时保存修改后的副本,如果要在最后保存修改,则覆盖它。
我正在寻找一个图书馆类型的程序,允许您从一个小的 "database" 文本文件中取出一本书,然后修改文件中的行以包含之前输入的用户 ID表明它已被拍摄。
输入的用户 ID 必须是一个整数和 4 位数字,我已经让程序用 try/except 来解决这个问题,除了现在要继续实际编写文件,它似乎不再 运行 过去要求 book_id 尽管在我放入所有检查 ID 的正确长度之前它是可用的。
此外,这一切都意味着在一个 "def checkout()" 函数中(这样我以后可以正确地创建一个主程序,包括我编写的搜索功能和一个允许你 'return' 书籍的程序)但是如果我试图把它放在里面,我得到的都是缩进错误,每当我试图使用 break 来阻止程序为每本书或每本书重复 "Sorry, either the book ID was not found or the book is unavailable" 时,整个事情都会死掉。在这一点上,我只是在寻找基本的功能,即使它不能完美地工作,所以主要的优先事项是实际获得它 运行ning.
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(或 space“ ”,表示该书可用)是右边的数字。
这可能是我遗漏的一些非常简单的事情,并且已经做了使其无法工作,因为我是初学者,但我感谢任何输入,干杯。
您的代码中有几个问题:
不要在 while 循环之前打开文件(并适当添加错误检查)
while True: txt = open("book_list.txt", "r+")
如果您写入
r+
文件,您会将txt.write
写入的所有行追加到文件末尾。 不要覆盖它们!这意味着在签出一本书后,您将有一个新行 在文件的末尾,这本书被签出。在文件中覆盖更复杂! 基本上有两种解决方案,要么读入整个文件并将其保存在字典中,要么……。然后用w
重写整个文件。 或者,这有点难看,你在每本书后面放了四个空格,然后使用txt.seek
. 用用户数覆盖这些空格
比较
book_id == line[0]
基本上就是检查line
的第一个字符是否等于书的编号,这与检查是否相同该行的第一个数字与您的图书 ID 相同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
处理文件,因此您不必跟踪关闭它。
另外,在 "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."
首先,您可以在不使用异常的情况下轻松验证 ID:
def id_valid(id):
return len(id) == 4 and id.isdigit()
如果字符串中的所有字符都是数字,isdigit() 方法return为真。
然后可以这样读取正确的 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)
"Sorry, either the book ID was not found or the book is unavailable." 消息显示了很多次,因为您在每次迭代中打印它,其中 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。它将 return 一个列表,其中 [0] 元素是图书 ID,[3] 是用户 ID(如果存在)。如果没有用户 ID,列表将只有 3 个元素。
至于更新文件,最简单的策略是在处理原始文件时保存修改后的副本,如果要在最后保存修改,则覆盖它。