Python-如何为用户输入创建删除函数



我一直在尝试创建一个程序,允许用户查看文本文件的内容,并删除部分或全部单个条目块。

文本的文件内容示例如下:

Special Type A Sunflower
2016-10-12 18:10:40
Asteraceae
Ingredient in Sunflower Oil
Brought to North America by Europeans
Requires fertile and moist soil
Full sun
Pine Tree
2018-12-15 13:30:45
Pinaceae
Evergreen
Tall and long-lived
Temperate climate
Tropical Sealion
2019-01-20 12:10:05
Otariidae
Found in zoos
Likes fish
Likes balls
Likes zookeepers
Big Honey Badger
2015-06-06 10:10:25
Mustelidae
Eats anything
King of the desert

因此,条目块指的是没有水平空间的所有行。

目前,我的进度是:

import time
import os
global o
global dataset
global database
from datetime import datetime
MyFilePath = os.getcwd() 
ActualFile = "creatures.txt"
FinalFilePath = os.path.join(MyFilePath, ActualFile) 
def get_dataset():
database = []
shown_info = []
with open(FinalFilePath, "r") as textfile:  
sections = textfile.read().split("nn")
for section in sections:                 
lines = section.split("n")      
database.append({                
"Name": lines[0],
"Date": lines[1],              
"Information": lines[2:]          
})
return database
def delete_creature():
dataset = get_dataset()

delete_question = str(input("Would you like to 1) delete a creature or 2) only some of its information from the dataset or 3) return to main page? Enter 1, 2 or 3: "))

if delete_question == "1":
delete_answer = str(input("Enter the name of the creature: "))
for line in textfile:
if delete_answer in line:
line.clear()

elif delete_question == "2":
delete_answer = str(input("Enter the relevant information of the creature: "))
for line in textfile:
if delete_answer in line:
line.clear()

elif delete_question == "3":
break

else:
raise ValueError
except ValueError:
print("nPlease try again! Your entry is invalid!")

while True:
try:
option = str(input("nGood day, This is a program to save and view creature details.n" +
"1) View all creatures.n" +
"2) Delete a creature.n" +
"3) Close the program.n" +
"Please select from the above options: "))

if option == "1":
view_all()

elif option == "2":
delete()

elif option == "3":
break

else:
print("nPlease input one of the options 1, 2 or 3.")

except:
break

delete_function((旨在通过以下方式删除该生物:

  1. 名称,删除与该名称关联的整个文本块
  2. 信息,只删除信息行

然而,我似乎无法让delete_creature((函数工作,而且我不确定如何让它工作。

有人知道如何让它发挥作用吗?

非常感谢!

从节中删除行的问题是,您专门对哪一行表示什么进行了硬编码。在你的情况下,删除一个部分很容易,如果你不改变你的概念,删除一行将涉及到稍后将有问题的行设置为空或表示空字符串的某个字符。这里的另一个问题是,您是否需要您的部分在输入时保持有序,或者您可以将它们按其他顺序重新排序到文件中。

我要做的是将输入文件格式更改为INI文件格式。然后,您可以使用configparser模块以简单的方式解析和编辑它们。INI文件看起来像:

[plant1]
name="Some plant's English name"
species="The plant's Latin species part"
subspecies="The plant's subspecies in Latin ofcourse"
genus="etc."
[animal1]
# Same as above for the animal
# etc. etc. etc.

configparser.ConfigParser()将允许您以字典式的方式加载它,并编辑节和值。节可以命名animal1、plant1,也可以将它们用作其他名称,但我更喜欢将名称保留在值内,通常在name键下,然后使用configparser根据名称创建一个普通字典,其中它的值是另一个包含节中指定的键值对的字典。我在保存结果时颠倒了这个过程。手动或再次使用configparser。

您可能考虑的另一种格式是JSON,使用JSON模块。使用它的函数dumps((并正确设置分隔符和缩进,您将获得非常易读和可编辑的输出格式。好处是,您可以保存正在使用的数据结构,例如dictionary,然后加载它,它会在保存时返回,而且您不需要像使用configparser那样执行一些额外的操作来完成它。问题是,对于不自定义JSON的用户来说,INI文件不那么令人困惑,并且会导致更少的错误,而JSON必须严格格式化,打开和关闭作用域或使用分隔符时的任何错误都会导致整个文件无法工作或输入不正确。当文件很大时,这种情况很容易发生。

这两种格式都允许用户将空行放在任何他们想要的地方,并且他们不会改变文件的加载方式,而您的方法对空行是严格的。

如果你希望你的数据库只由你的程序编辑,那么使用pickle模块来做这件事,并为自己省去麻烦。

否则您可以:

def getdata (stringfromfile):
end = {}
l = [] # lines in a section
for x in stringfromfile.strip().splitlines():
x = x.strip()
if not x: # New section encountered
end[l[0].lower()] = l[1:]
l = []
continue
end.append(x)
end[l[0].lower()] = l[1:] # Add last section
# Connect keys to numbers in the same dict(), so that users can choose by number too
for n, key in enumerate(sorted(end)):
end[n] = key
return end
# You define some constants for which line is what in a dict():
values = {"species": 0, "subspecies": 1, "genus": 2}
# You load the file and parse the data
data = getdata(f.read())
def edit  (name_or_number, edit_what, new_value):
if isinstance(name_or_number, int):
key = data[name_or_number]
else:
key = name_or_number.lower().strip()
if isinstance(edit_what, str):
edit_what = values[edit_what.strip().lower()]
data[key][edit_what] = new_value.strip()
def add (name, list_of_lines):
n = len(data)/2 # Number for new entry for numeric getting
name = name.strip().lower()
data[name] = list_of_lines
data[n] = name
def remove (name):
name = name.lower().strip()
del data[name]
# Well, this part is bad and clumsy
# It would make more sense to keep numeric mappings in separate list
# which will do this automatically, especially if the database file is big-big-big...
# But I started this way, so, keeping it simple and stupid, just remap everything after removing the item (inefficient as hell itself)
for x in data.keys():
if isinstance(x, int):
del data[x]
for n, key in enumerate(sorted(data)):
data[n] = key
def getstring (d):
# Serialize for saving
end = []
for l0, ls in d.items():
if isinstance(l0, int):
continue # Skip numeric mappings
lines = l0+"n"+"n".join(ls)
end.append(lines)
return "nn".join(end)

我没有测试代码。可能有漏洞。

如果你不需要特定的行,你可以很容易地修改我的代码,使用list.index((方法在行中搜索,或者当你需要找到行时,如果行存在,就只使用数字。要使用configparser执行此操作,请在以下部分中使用泛型键:answer0、answer1…,或仅使用0、1、2…,然后忽略它们并将答案加载为列表或。如果要使用configparser处理该文件,则在删除时有时会得到answer0、answer3。

还有一个警告。如果您想保持输入文件给出生物的顺序,请使用ordereddict而不是普通的字典。

此外,在适当的位置编辑打开的文件当然是可能的,但复杂且不可取,所以不要这样做。加载并保存回。想要直接更改文件的情况非常罕见。为此,您可以使用mmap模块。不要!

相关内容

  • 没有找到相关文章

最新更新