我有一个加密代码,由26个字母组成,还有一个选项,允许用户根据需要进行更改。在多次尝试我的程序后,我遇到了一个错误,一个合乎逻辑的错误。用户可以更改代码,但是,他们可以输入相同的字符26次或至少1个字符不止一次,这可能会破坏我的整个程序。有没有办法只允许用户输入每个字母一次?这是我到目前为止所做的:
import tkinter
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
encryption_code = 'LFWOAYUISVKMNXPBDCRJTQEGHZ'
letters += letters.lower()
encryption_code += encryption_code.lower()
window = tkinter.Tk()
encrypt_entry = tkinter.Entry(window)
encrypt_entry.pack()
def code_change(event):
global encrypt_entry
global encryption_code
encryptget = encrypt_entry.get()
if len(encryptget) == 26:
print("You have changed the encryption code")
encryption_code = encryptget
encryption_code += encryption_code.lower()
enc = dict(zip(letters, encryption_code))
dec = dict(zip(encryption_code, letters))
elif len(encryptget) < 26 or len(encryptget) > 26:
print("Please enter 26 characters")
encrypt_entry.delete(0, tkinter.END)
window.bind('<Return>', code_change)
修改
我尝试了以下但是现在如果我尝试输入字母或encryption_code
elif
语句什么都不做。
import tkinter
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
encryption_code = 'LFWOAYUISVKMNXPBDCRJTQEGHZ'
letters += letters.lower()
encryption_code += encryption_code.lower()
window = tkinter.Tk()
encrypt_entry = tkinter.Entry(window)
encrypt_entry.pack()
def code_change(event):
global encrypt_entry
global encryption_code
encryptget = encrypt_entry.get()
if len(set(encryptget)) == 26 and encryptget != encryption_code and encryptget != letters:
print("You have changed the encryption code")
encryption_code = encryptget
encryption_code += encryption_code.lower()
enc = dict(zip(letters, encryption_code))
dec = dict(zip(encryption_code, letters))
elif len(set(encryptget)) != 26 and encryptget == encryption_code and encryptget == letters:
print("Please enter each character exactly once")
encrypt_entry.delete(0, tkinter.END)
window.bind('<Return>', code_change)
答案 0 :(得分:1)
Tkinter具有专门用于此类验证的功能。您可以让它为每次插入调用一个函数,并且此函数可以根据您想要的任何条件接受或拒绝该插入。
在您的情况下,标准是&#34;没有重复的字符&#34;。确定这一点的简单方法是将字符串转换为集合(根据定义,集合没有重复),然后将集合的长度与字符串的长度进行比较。
要在每次用户按下某个键时调用此函数,请设置条目小部件的validate
和validatecommand
选项。还有一个额外的步骤,你必须注册命令,告诉tkinter你希望命令接收几个特殊参数。
解决方案看起来像这样:
# Define a command to be run whenever the user edits the entry
# N.B. d will be "1" for an insert, "0" for delete, and "-1"
# for anything else. P will be the value of the entry if this
# edit is allowed.
#
# Note: this function must always return either True or False
def encryption_validation(d, P):
if d == "1": # ie: an insert
unique_chars = set(P)
if len(P) > len(unique_chars):
return False
return True
# register the command with tkinter
vcmd = (window.register(encryption_validation), '%d', '%P')
# configure the entry widget to use this command
encrypt_entry.configure(validate="key", validatecommand=vcmd)
如上所述,用户不可能两次输入任何字符。请注意,此解决方案还可以防止用户粘贴具有重复字符的字符串。
有关条目验证的详尽解释,请参阅stackoverflow上的以下答案:https://stackoverflow.com/a/4140988/7432
答案 1 :(得分:-1)
如果我弄错了,请纠正我,但听起来你只是想确保用户为代码输入的字符串不包含任何副本?
我个人并不了解验证命令,但我认为这可以达到您的目标:
def IsCodeValid(encryption_code):
c = [0]*26
pos = 0
for i in range(len(encryption_code)):
pos = ord(encryption_code[i])-ord('A') #find placement relative to A in unicode
c[pos] = c[pos] + 1 #increment counter for that letter
j = 0
ValidCode = True
while j<26 and ValidCode:
if c[j]>1: #check to see if any letter occurred more than once
ValidCode = False
else:
j += 1
return ValidCode
请注意,这也预计所有字母都会输入大写字母。但是你可以通过在接受数据之前规范化数据来解决这个问题。或者,您可以使逻辑复杂化以检查上限和下限。小写。
编辑:假设您不希望在encryption_code无效的情况下运行代码,您可以使用此标志在运行程序的其余部分之前从用户请求新的encryption_code。