所以我有Python 2.7的代码来计算字频率(欢迎任何优化)。
import Tkinter as tk
def let_freq():
user_input = e.get()
alphabet = {
'a': 0,'b': 1,'c': 2,'d': 3,
'e': 4,'f': 5,'g': 6,'h': 7,
'i': 8,'j': 9,'k': 10,'l': 11,
'm': 12,'n': 13,'o': 14,'p': 15,
'q': 16,'r': 17,'s': 18,'t': 19,
'u': 20,'v': 21,'w': 22,'x': 23,'y': 2,'z': 25}
value_alphabet = {
'a': 0,'b': 0,'c': 0,'d': 0,
'e': 0,'f': 0,'g': 0,'h': 0,
'i': 0,'j': 0,'k': 0,'l': 0,
'm': 0,'n': 0,'o': 0,'p': 0,
'q': 0,'r': 0,'s': 0,'t': 0,
'u': 0,'v': 0,'w': 0,'x': 0,'y': 0,'z': 0}
letters = []
count = 0
for character in user_input:
letters.append(character)
for item in letters:
for key, val in alphabet.items():
if key is item:
value_alphabet[key] += 1
for key in value_alphabet:
if value_alphabet[key] > 0:
count += value_alphabet[key]
for key in sorted(value_alphabet):
if value_alphabet[key] > 0:
print value_alphabet[key], ',', key, '-', float(value_alphabet[key])/count*100, '%'
root = tk.Tk()
e = tk.Entry(root)
assert type(e)
e.grid(ipadx=5,ipady=5)
button = tk.Button(root, text='Letterfrequency',command=let_freq).grid(ipadx=5, ipady=5)
root.mainloop()
现在,问题是显示
print value_alphabet[key], ',', key, '-', float(value_alphabet[key])/count*100, '%'
在Tkinter标签或任何其他适当的Tkinter小部件中,我想知道如何在循环中主动编辑Label,如果user_input
变量发生变化则删除它们,并且(这应该自然而然)显示user_input
(e
'部分之前e.get()
)中新条目的信息。
(即如果你输入'banana',你应该得到-50%,n-33.333333333%,b-16.666666666%......这是字频)
答案 0 :(得分:1)
设置标签时,您可以为其设置tkinter.StringVar
作为文本变量。然后,每当您更新变量时,Label都会自动更新:
from tkinter import *
from time import sleep
root = Tk()
labeltext = StringVar()
labeltext.set('hello')
label = Label(root, textvariable = labeltext)
label.pack()
for i in range(10):
labeltext.set(str(i))
root.update_idletasks()
sleep(1) #slow it down so that the changes are visible
此代码将更新for循环内的标签。现在,您只需要labeltext.set(str(user_input))
,您就会在标签上获得用户输入。
答案 1 :(得分:1)
在回答手头的问题之前,对你的功能做了一些调整。你正在做一些你并不真正需要的东西,并且可以减少这一点。
首先,您的value_alphabet
只是重新实现的collections.Counter
。请改用它。
from collections import Counter
...
value_alphabet = Counter()
你也在做一些时髦的低级别的东西,A)在Python中是不必要的,B)即使有必要,也不是Python中最好的方法。我在谈论
letters = []
for character in user_input:
letters.append(character)
这只是
letters = list(user_input)
但是因为你可以直接在字符串上迭代,所以你不需要letters
AT ALL。去掉它。同样地,count
只是len(user_input)
。你所做的就是遍历每个字母并计算它们。扔了它。现在您的功能如下:
def let_freq():
user_input = e.get()
alphabet = {
'a': 0,'b': 1,'c': 2,'d': 3,
'e': 4,'f': 5,'g': 6,'h': 7,
'i': 8,'j': 9,'k': 10,'l': 11,
'm': 12,'n': 13,'o': 14,'p': 15,
'q': 16,'r': 17,'s': 18,'t': 19,
'u': 20,'v': 21,'w': 22,'x': 23,'y': 2,'z': 25}
value_alphabet = Counter()
for item in user_input:
for key,val in alphabet.items():
if key is item:
value_alphabet[key] += 1
这个循环非常难看。你忽略了字典中最好的部分:O(1)查找!您不需要执行双循环。 if key is item
由于其他原因是不好的,但我不会在这里讨论,因为身份与平等并不是真的在同一个鱼群中(并且它不会影响这里的功能。只要知道' somestring是somestring'并不总是True
。)
for ch in user_input: # changed the loopvar here to sound better
value_alphabet[ch] += alphabet[ch]
# look it up directly.
如果您担心user_input包含无效字符,请使用dict.get
来默认为零。
for ch in user_input:
value_alphabet += alphabet.get(ch, 0)
# if ch isn't in alphabet, do value_alphabet += 0
甜!我们现在几乎整理好了。让我们继续。由于我们已经取消了您的count
变量,因此我们可以跳过下一个for key in value_alphabet
循环,因为它只填充count
。最后一点,您可以通过执行以下操作来缩短代码:
for key,val in sorted(value_alphabet.items()):
if val > 0:
print val, ',', key, '-', float(val * 100 / len(user_input)), '%'
现在关于更改标签的问题?你正在寻找回调。你可能应该把它放到自己的类中,而不是让它在不知名的地方闲逛,但让我们谈谈将回调绑定到用户条目更改。最简单的方法是使用tk.StringVar
及其trace
方法。
root = tk.Tk()
e_stringvar = tk.StringVar()
e = tk.Entry(root, textvariable=e_stringvar)
e_stringvar.trace('w', some_func)
这会将e_stringvar
与您的tk.Entry
窗口小部件绑定在一起,将e
的内容存储在e_stringvar
中。此外,它将一些未知函数some_func
绑定到e_stringvar
,以便每次e_stringvar
都有写入内容(例如e
由于用户输入而发生更改),它会调用{{ 1}}。我们可以将some_func
定义为:
some_func
我已经定义f = tk.Label(root)
f.pack()
e.pack() # whatever, pack everything
def some_func(*args, **kwargs):
text = e_stringvar.get()
f.configure(text=text)
# change the f label so it's displaying the same text as the entry
来接受参数,因为我老实说忘了some_func
回调函数是否通过了触发它们的事件。我们没有使用它们,但如果你不允许它通过,你将获得ArgumentErrors。
我最近写了一些(Py3)代码,它使用这个概念来跟踪tk.StringVar.trace
字段并使用它来过滤文本列表。相关代码位于bitbucket findppw.views.frames(FilterFrame类)和findppw.app(第38行实例化FilterFrame并命名其回调函数)