如何让每个字符输入一次?
How to allow each character to be entered once?
我有一个加密代码,它由 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)
如果我弄错了请纠正我,但听起来您只是想确保用户为代码输入的字符串不包含任何重复项?
我个人不知道验证命令,但我认为这可以实现您的目标:
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 无效,您可以使用此标志从用户在 运行 完成程序的其余部分之前。
Tkinter 具有专门用于此类验证的功能。您可以让它为每次插入调用一个函数,并且此函数可以根据您想要的任何条件接受或拒绝该插入。
在您的情况下,标准是 "no duplicate characters"。一个简单的确定方法是将字符串转换为一个集合(根据定义,一个集合没有重复项),然后将集合的长度与字符串的长度进行比较。
要在用户每次按键时调用此函数,请设置条目小部件的 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)
有了以上,用户将不可能输入任何字符两次。请注意,此解决方案还可以防止用户粘贴包含重复字符的字符串。
有关条目验证的更详尽解释,请参阅 Whosebug 上的此答案:
我有一个加密代码,它由 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)
如果我弄错了请纠正我,但听起来您只是想确保用户为代码输入的字符串不包含任何重复项?
我个人不知道验证命令,但我认为这可以实现您的目标:
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 无效,您可以使用此标志从用户在 运行 完成程序的其余部分之前。
Tkinter 具有专门用于此类验证的功能。您可以让它为每次插入调用一个函数,并且此函数可以根据您想要的任何条件接受或拒绝该插入。
在您的情况下,标准是 "no duplicate characters"。一个简单的确定方法是将字符串转换为一个集合(根据定义,一个集合没有重复项),然后将集合的长度与字符串的长度进行比较。
要在用户每次按键时调用此函数,请设置条目小部件的 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)
有了以上,用户将不可能输入任何字符两次。请注意,此解决方案还可以防止用户粘贴包含重复字符的字符串。
有关条目验证的更详尽解释,请参阅 Whosebug 上的此答案: