如何改进python中的结构这样的数据?

时间:2017-11-14 04:10:16

标签: tkinter python-3.6

对于我在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>

1 个答案:

答案 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中的值进行比较,看看我们是否得到匹配,如果我们这样做,那么程序必须评估是否有任何其他记录与此匹配(例如,如果我们注册了RonRonald我们不希望它自动填充,直到我们确定用户想要RonRonald)。为此,我们在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}}(例如,如果我们有RonRonald并输入"Ro"这将返回2),然后检查该计数是否等于{ {1}}。如果是,那么我们返回1,因为我们的数据中可能不存在任何其他匹配项。下半部分检查True中的值是否与我们数据中的任何内容完全匹配,如果我们没有这样做,那么Entry将永远不会返回RonRon Ronald因为Ron将始终返回前一个语句的2计数。

最后,如果您愿意,可以将数据移到另一个文件中,例如.json.csv(使用.json文件会比.csv主观上更容易})这样它就不会弄乱你的程序。然后,您需要导入要在程序中使用的数据。这已在SO上进行了很多解释,因此您应该能够找到一个可以帮助您的问题。