对于我在python中创建的学生来说,这是一个类似数据库的结构,我很想知道你们是否可以看一下这段代码,并给我一些关于如何更好地编写好代码的建议(意思是看起来很好而且那个很容易理解,我刚开始编码大约2-3周前)你们建议我会考虑的任何事情,我只是想提高:)
#Our Gui TOOls
from tkinter import *
from tkinter import ttk
#Window
root = Tk()
#Not allowing the window to be resized
root.resizable(height = False , width = False)
#title of window when we get more things in the window
root.title(string = 'Ronald')
#The object /class
class Students:
def __init__(self, root):
self.root = root
self.data = [{"Student Info": "Ronald Colyar", "Gpa": "4.0", "GradeLVL": "10", "NumOfClasses": "6" , 'Parents number': '773-567-2791'},
{"Student Info": "Beta", "Gpa": "1", "GradeLVL": "5", "NumOfClasses": "9", 'Parents number': '773-867-2791'},
{"Student Info": "Charlie", "Gpa": "2", "GradeLVL": "6", "NumOfClasses": "6", 'Parents number': '773-566-2791'}
]
#Container (very vaguly speaking )
self.var = StringVar()
#track what is being put inside entry
self.var.trace("w", self.callback)
#The entry across 2 columns in row 0
self.entry = ttk.Entry(self.root, textvariable=self.var)
self.entry.grid(row=0, column=0, columnspan=2)
#All of the labels that correspond the the information in self.data
self.labels = [(ttk.Label(self.root, text="Student Info"),ttk.Label(self.root)),(ttk.Label(self.root, text="Gpa"),ttk.Label(self.root)),(ttk.Label(self.root, text="GradeLVL"),ttk.Label(self.root)),(ttk.Label(self.root, text="NumOfClasses"),ttk.Label(self.root)),(ttk.Label(self.root, text="Parents number"),ttk.Label(self.root))]
#spacing the labels out in the window by the amount of them
for i in range(len(self.labels)):
self.labels[i][0].grid(row = i+1, column=0)
self.labels[i][1].grid(row = i+1, column=1)
#if the entry matches the data , display the data.
def callback(self, *args):
for i in self.data:
#if the data matches evaluates to true
if i["Student Info"] == self.var.get():
#execute if data matches
for c in self.labels:
c[1].configure(text=i[c[0].cget("text")])
#Calling our object inside of root
Students(root)
#Constant loop of our window
root.mainloop()
第3周编程你们怎么认为即时学习,我已经落后了3个星期,或者我有望成为一名优秀的软件开发人员,也是我16岁,所以我有几年时间掌握这些技能。< / p>
答案 0 :(得分:0)
在可读性和Pythonic最佳实践方面,此代码(if I do say so myself)布局合理。
可以做出一些主观改进。
第一个是在这里使用enumerate()
:
for i in range(len(self.labels)):
self.labels[i][0].grid(row = i+1, column=0)
self.labels[i][1].grid(row = i+1, column=1)
除了上述内容,我们可以使用类似下面的内容:
for c, i in enumerate(self.labels, 1):
i[0].grid(row = c+1, column=0)
i[1].grid(row = c+1, column=1)
enumerate()
获取一个列表并返回一个元组,其索引号与列表中的值相关联,因此在这种情况下,我们声明第一个索引值应为1
,我们得到一个数据结构返回如下:
[(1, (ttk.Label(self.root, text="Student Info"),ttk.Label(self.root))),(2, (ttk.Label(self.root, text="Gpa"),ttk.Label(self.root))), . . . ]
这意味着我们可以放弃使用单独的计数变量以及由此产生的混淆。
我们还可以实施一个系统,通过我们可以通过搜索获得&#34;自动完成&#34; 功能,我们可以通过修改以下行来实现:
if i["Student Info"] == self.var.get():
要:
if i["Student Info"][:len(self.var.get())] == self.var.get() and ([x["Student Info"][:len(self.var.get())] for x in self.data].count(self.var.get()) == 1 or i["Student Info"] == self.var.get()):
这看起来很可怕,并且很多都在发生,但让我们仔细看看它。
我们使用字符串拼接将名称字符串的第一部分拉回到Entry
字段中字符串的长度,并将其与Entry
中的值进行比较,看看我们是否得到匹配,如果我们这样做,那么程序必须评估是否有任何其他记录与此匹配(例如,如果我们注册了Ron
和Ronald
我们不希望它自动填充,直到我们确定用户想要Ron
或Ronald
)。为此,我们在or
语句中使用if
子句:
([x["Student Info"][:len(self.var.get())] for x in self.data].count(self.var.get()) == 1 or i["Student Info"] == self.var.get()):
这意味着如果两个条件中的任何一个返回True
,我们将继续执行语句下面的代码块。 or
语句的前半部分使用列表推导来返回名称字符串列表,直到Entry
中值的长度,然后计算其中有多少与Entry
中的值匹配。 1}}(例如,如果我们有Ron
和Ronald
并输入"Ro"
这将返回2
),然后检查该计数是否等于{ {1}}。如果是,那么我们返回1
,因为我们的数据中可能不存在任何其他匹配项。下半部分检查True
中的值是否与我们数据中的任何内容完全匹配,如果我们没有这样做,那么Entry
将永远不会返回Ron
和Ron
Ronald
因为Ron
将始终返回前一个语句的2
计数。
最后,如果您愿意,可以将数据移到另一个文件中,例如.json
或.csv
(使用.json
文件会比.csv
主观上更容易})这样它就不会弄乱你的程序。然后,您需要导入要在程序中使用的数据。这已在SO上进行了很多解释,因此您应该能够找到一个可以帮助您的问题。