Python 输入验证函数保留旧变量
Python Input validation function keeping old variables
我目前正在编写一个税收计算器,我注意到如果我输入了一个无效的税码,一开始它看起来会被拒绝,但随后程序似乎会保留初始输入并反向循环它们订单(像这样):
[User Input] Gross Income: £32,000
[User Input] Tax Code: 32,000
Tax Code after input: 32,000
Failed letter check
Invalid input. Please enter your tax code.
[User Input] Tax Code: y
Tax Code after input: y
Passed letter check
Tax Code after letter check: y
Tax Code during dictionary match check (false): y
Failed dictionary match check
Invalid input. Please enter your tax code.
[User Input] Tax Code: 1257L
Tax Code after input: 1257L
Passed letter check
Tax Code after letter check: 1257L
Tax Code during dictionary match check (true): 1257L
Passed dictionary match check
Tax Code after dictionary match check: 1257L
Personal Allowance: 12570
Tax Letter: L
Tax Code after dictionary match check: y
Personal Allowance: 0
Tax Letter: Y
Tax Code after letter check: 32,000
Traceback (most recent call last):
File "C:\Users\Joshua.Riberio\Git\taxcalc\taxcalc.py", line 336, in <module>
salarycalc()
File "C:\Users\Joshua.Riberio\Git\taxcalc\taxcalc.py", line 243, in salarycalc
personal_allowance, tax_letter = get_tax_code()
File "C:\Users\Joshua.Riberio\Git\taxcalc\taxcalc.py", line 78, in get_tax_code
tax_letter = tax_code[tax_letter_index:].upper()
TypeError: slice indices must be integers or None or have an __index__ method
这是我的代码:
def get_tax_code():
tax_code = input('Tax Code: ')
print('Tax Code after input:', tax_code)
tax_letter_index = ''
# Checking input contains a letter
for char in tax_code:
if char.upper() in alpha:
tax_letter_index = tax_code.index(char)
print('Passed letter check')
break
if tax_letter_index == '':
print('Failed letter check')
print('Invalid input. Please enter your tax code.')
get_tax_code()
print('Tax Code after letter check:', tax_code)
tax_letter = tax_code[tax_letter_index:].upper()
# Checking input has a key match in the tax_letters dictionary
if tax_letter not in tax_letters.keys():
print('Tax Code during dictionary match check (false):', tax_code)
print('Failed dictionary match check')
print('Invalid input. Please enter your tax code.')
get_tax_code()
elif tax_letter in tax_letters.keys():
print('Tax Code during dictionary match check (true):', tax_code)
print('Passed dictionary match check')
print('Tax Code after dictionary match check:', tax_code)
# Getting personal allowance from Tax Code
personal_allowance = tax_code[:tax_letter_index]
if personal_allowance == '':
personal_allowance = 0
else:
personal_allowance = int(personal_allowance) * 10
# Setting personal allowance exceptions for gross income over £100,000
if gross_income > 100000:
personal_allowance = set_personal_allowance - ((gross_income - 100000) / 2)
if personal_allowance < 0:
personal_allowance = 0
print('Personal Allowance:', personal_allowance)
print('Tax Letter:', tax_letter)
return personal_allowance, tax_letter
过多的打印只是为了让我可以看到输入被更改的地方。似乎在 运行 成功通过后,代码使用先前的无效输入循环回到顶部,导致代码无法 运行.
有人能看出我错在哪里吗?
备注
tax_letters
是定义的字典,将更新它以从选定的 CSV 中提取:
tax_letters = {
"L": "You’re entitled to the standard tax-free Personal Allowance",
"M": "Marriage Allowance: you’ve received a transfer of 10% of your partner’s Personal Allowance",
"N": "Marriage Allowance: you’ve transferred 10% of your Personal Allowance to your partner",
"T": "Your tax code includes other calculations to work out your Personal Allowance",
"0T": "Your Personal Allowance has been used up, or you’ve started a new job and your employer does not have the details they need to give you a tax code",
"BR": "All your income from this job or pension is taxed at the basic rate (usually used if you’ve got more than one job or pension)",
"D0": "All your income from this job or pension is taxed at the higher rate (usually used if you’ve got more than one job or pension)",
"D1": "All your income from this job or pension is taxed at the additional rate (usually used if you’ve got more than one job or pension)",
"NT": "You’re not paying any tax on this income",
"S": "Your income or pension is taxed using the rates in Scotland",
"S0T": "Your Personal Allowance (Scotland) has been used up, or you’ve started a new job and your employer does not have the details they need to give you a tax code",
"SBR": "All your income from this job or pension is taxed at the basic rate in Scotland (usually used if you’ve got more than one job or pension)",
"SD0": "All your income from this job or pension is taxed at the intermediate rate in Scotland (usually used if you’ve got more than one job or pension)",
"SD1": "All your income from this job or pension is taxed at the higher rate in Scotland (usually used if you’ve got more than one job or pension)",
"SD2": "All your income from this job or pension is taxed at the top rate in Scotland (usually used if you’ve got more than one job or pension)",
"C": "Your income or pension is taxed using the rates in Wales",
"C0T": "Your Personal Allowance (Wales) has been used up, or you’ve started a new job and your employer does not have the details they need to give you a tax code",
"CBR": "All your income from this job or pension is taxed at the basic rate in Wales (usually used if you’ve got more than one job or pension)",
"CD0": "All your income from this job or pension is taxed at the higher rate in Wales (usually used if you’ve got more than one job or pension)",
"CD1": "All your income from this job or pension is taxed at the additional rate in Wales (usually used if you’ve got more than one job or pension)"
}
gross_income
定义在main函数中:
def salarycalc():
screen_clear()
global gross_income
gross_income = input('Gross Income: £')
if ',' in gross_income:
gross_income = gross_income.replace(',', '')
if '£' in gross_income:
gross_income = gross_income.replace('£', '')
gross_income = float(gross_income)
set_personal_allowance
是由 'tax_brackets' 字典中的值定义的变量,稍后将再次更新它以从 CSV 的选择中提取:
tax_brackets = {
'Personal Allowance': 12570,
'Basic': [0, 0.2],
'Higher': [50270, 0.4],
'Additional': [150000, 0.45]
}
set_personal_allowance = tax_brackets['Personal Allowance']
因此,您的代码可能不起作用的主要原因是重复的递归调用。为了使方法更简单,我将所需的功能分解为 2 个验证检查。请注意,我已经包含了一些示例数据来检查程序,您可以相应地忽略它。
只要两个检查为真,驱动程序函数 get_tax_code
就会运行,这意味着它只会在税码通过字母检查和字典匹配验证后才停止要求输入。
def get_tax_code(tax_letters):
gross_income = 32000
set_personal_allowance = 12570
check1 = True
check2 = True
while check1 or check2:
tax_code = input('Tax Code: ')
print('Tax Code after input:', tax_code)
tax_letter_index = verify1(tax_code)
if tax_letter_index != -1:
check1 = False
tax_letter = tax_code[tax_letter_index:].upper()
print('Tax Code after letter check:', tax_code)
x = verify2(tax_letter, tax_letters)
if x:
print('Tax Code during dictionary match check (true):', tax_code)
print('Passed dictionary match check')
print('Tax Code after dictionary match check:', tax_code)
check2 = False
else:
print('Tax Code during dictionary match check (false):', tax_code)
print('Failed dictionary match check')
print('Invalid input. Please enter your tax code.')
else:
print('Failed letter check')
print('Invalid input. Please enter your tax code.')
# Getting personal allowance from Tax Code
personal_allowance = tax_code[:tax_letter_index]
if personal_allowance == '':
personal_allowance = 0
else:
personal_allowance = int(personal_allowance) * 10
# Setting personal allowance exceptions for gross income over £100,000
if gross_income > 100000:
personal_allowance = set_personal_allowance - ((gross_income - 100000) / 2)
if personal_allowance < 0:
personal_allowance = 0
print('Personal Allowance:', personal_allowance)
print('Tax Letter:', tax_letter)
这些是之前包含在 get_tax_code
中的两个辅助函数。
第一个函数 verify1()
负责字母检查,而第二个 verify2()
处理字典匹配。从这两个函数返回的值决定了检查值是否更新,进而决定用户是否必须再次提供 tax_code
输入。
def verify1(tax_code):
tax_letter_index = ''
# Checking input contains a letter
for char in tax_code:
if char.upper().isalpha():
tax_letter_index = tax_code.index(char)
print('Passed letter check')
break
if tax_letter_index == '':
return -1
else:
return tax_letter_index
def verify2(tax_letter, tax_letters):
if tax_letter not in tax_letters.keys():
return False
elif tax_letter in tax_letters.keys():
return True
输出
Tax Code: 3200
Tax Code after input: 3200
Failed letter check
Invalid input. Please enter your tax code.
Tax Code: y
Tax Code after input: y
Passed letter check
Tax Code during dictionary match check (false): y
Failed dictionary match check
Invalid input. Please enter your tax code.
Tax Code: 1257L
Tax Code after input: 1257L
Passed letter check
Tax Code during dictionary match check (true): 1257L
Passed dictionary match check
Tax Code after dictionary match check: 1257L
Personal Allowance: 12570
Tax Letter: L
我目前正在编写一个税收计算器,我注意到如果我输入了一个无效的税码,一开始它看起来会被拒绝,但随后程序似乎会保留初始输入并反向循环它们订单(像这样):
[User Input] Gross Income: £32,000 [User Input] Tax Code: 32,000 Tax Code after input: 32,000 Failed letter check Invalid input. Please enter your tax code. [User Input] Tax Code: y Tax Code after input: y Passed letter check Tax Code after letter check: y Tax Code during dictionary match check (false): y Failed dictionary match check Invalid input. Please enter your tax code. [User Input] Tax Code: 1257L Tax Code after input: 1257L Passed letter check Tax Code after letter check: 1257L Tax Code during dictionary match check (true): 1257L Passed dictionary match check Tax Code after dictionary match check: 1257L Personal Allowance: 12570 Tax Letter: L Tax Code after dictionary match check: y Personal Allowance: 0 Tax Letter: Y Tax Code after letter check: 32,000 Traceback (most recent call last): File "C:\Users\Joshua.Riberio\Git\taxcalc\taxcalc.py", line 336, in <module> salarycalc() File "C:\Users\Joshua.Riberio\Git\taxcalc\taxcalc.py", line 243, in salarycalc personal_allowance, tax_letter = get_tax_code() File "C:\Users\Joshua.Riberio\Git\taxcalc\taxcalc.py", line 78, in get_tax_code tax_letter = tax_code[tax_letter_index:].upper() TypeError: slice indices must be integers or None or have an __index__ method
这是我的代码:
def get_tax_code(): tax_code = input('Tax Code: ') print('Tax Code after input:', tax_code) tax_letter_index = '' # Checking input contains a letter for char in tax_code: if char.upper() in alpha: tax_letter_index = tax_code.index(char) print('Passed letter check') break if tax_letter_index == '': print('Failed letter check') print('Invalid input. Please enter your tax code.') get_tax_code() print('Tax Code after letter check:', tax_code) tax_letter = tax_code[tax_letter_index:].upper() # Checking input has a key match in the tax_letters dictionary if tax_letter not in tax_letters.keys(): print('Tax Code during dictionary match check (false):', tax_code) print('Failed dictionary match check') print('Invalid input. Please enter your tax code.') get_tax_code() elif tax_letter in tax_letters.keys(): print('Tax Code during dictionary match check (true):', tax_code) print('Passed dictionary match check') print('Tax Code after dictionary match check:', tax_code) # Getting personal allowance from Tax Code personal_allowance = tax_code[:tax_letter_index] if personal_allowance == '': personal_allowance = 0 else: personal_allowance = int(personal_allowance) * 10 # Setting personal allowance exceptions for gross income over £100,000 if gross_income > 100000: personal_allowance = set_personal_allowance - ((gross_income - 100000) / 2) if personal_allowance < 0: personal_allowance = 0 print('Personal Allowance:', personal_allowance) print('Tax Letter:', tax_letter) return personal_allowance, tax_letter
过多的打印只是为了让我可以看到输入被更改的地方。似乎在 运行 成功通过后,代码使用先前的无效输入循环回到顶部,导致代码无法 运行.
有人能看出我错在哪里吗?
备注
tax_letters
是定义的字典,将更新它以从选定的 CSV 中提取:
tax_letters = {
"L": "You’re entitled to the standard tax-free Personal Allowance",
"M": "Marriage Allowance: you’ve received a transfer of 10% of your partner’s Personal Allowance",
"N": "Marriage Allowance: you’ve transferred 10% of your Personal Allowance to your partner",
"T": "Your tax code includes other calculations to work out your Personal Allowance",
"0T": "Your Personal Allowance has been used up, or you’ve started a new job and your employer does not have the details they need to give you a tax code",
"BR": "All your income from this job or pension is taxed at the basic rate (usually used if you’ve got more than one job or pension)",
"D0": "All your income from this job or pension is taxed at the higher rate (usually used if you’ve got more than one job or pension)",
"D1": "All your income from this job or pension is taxed at the additional rate (usually used if you’ve got more than one job or pension)",
"NT": "You’re not paying any tax on this income",
"S": "Your income or pension is taxed using the rates in Scotland",
"S0T": "Your Personal Allowance (Scotland) has been used up, or you’ve started a new job and your employer does not have the details they need to give you a tax code",
"SBR": "All your income from this job or pension is taxed at the basic rate in Scotland (usually used if you’ve got more than one job or pension)",
"SD0": "All your income from this job or pension is taxed at the intermediate rate in Scotland (usually used if you’ve got more than one job or pension)",
"SD1": "All your income from this job or pension is taxed at the higher rate in Scotland (usually used if you’ve got more than one job or pension)",
"SD2": "All your income from this job or pension is taxed at the top rate in Scotland (usually used if you’ve got more than one job or pension)",
"C": "Your income or pension is taxed using the rates in Wales",
"C0T": "Your Personal Allowance (Wales) has been used up, or you’ve started a new job and your employer does not have the details they need to give you a tax code",
"CBR": "All your income from this job or pension is taxed at the basic rate in Wales (usually used if you’ve got more than one job or pension)",
"CD0": "All your income from this job or pension is taxed at the higher rate in Wales (usually used if you’ve got more than one job or pension)",
"CD1": "All your income from this job or pension is taxed at the additional rate in Wales (usually used if you’ve got more than one job or pension)"
}
gross_income
定义在main函数中:
def salarycalc():
screen_clear()
global gross_income
gross_income = input('Gross Income: £')
if ',' in gross_income:
gross_income = gross_income.replace(',', '')
if '£' in gross_income:
gross_income = gross_income.replace('£', '')
gross_income = float(gross_income)
set_personal_allowance
是由 'tax_brackets' 字典中的值定义的变量,稍后将再次更新它以从 CSV 的选择中提取:
tax_brackets = {
'Personal Allowance': 12570,
'Basic': [0, 0.2],
'Higher': [50270, 0.4],
'Additional': [150000, 0.45]
}
set_personal_allowance = tax_brackets['Personal Allowance']
因此,您的代码可能不起作用的主要原因是重复的递归调用。为了使方法更简单,我将所需的功能分解为 2 个验证检查。请注意,我已经包含了一些示例数据来检查程序,您可以相应地忽略它。
只要两个检查为真,驱动程序函数 get_tax_code
就会运行,这意味着它只会在税码通过字母检查和字典匹配验证后才停止要求输入。
def get_tax_code(tax_letters):
gross_income = 32000
set_personal_allowance = 12570
check1 = True
check2 = True
while check1 or check2:
tax_code = input('Tax Code: ')
print('Tax Code after input:', tax_code)
tax_letter_index = verify1(tax_code)
if tax_letter_index != -1:
check1 = False
tax_letter = tax_code[tax_letter_index:].upper()
print('Tax Code after letter check:', tax_code)
x = verify2(tax_letter, tax_letters)
if x:
print('Tax Code during dictionary match check (true):', tax_code)
print('Passed dictionary match check')
print('Tax Code after dictionary match check:', tax_code)
check2 = False
else:
print('Tax Code during dictionary match check (false):', tax_code)
print('Failed dictionary match check')
print('Invalid input. Please enter your tax code.')
else:
print('Failed letter check')
print('Invalid input. Please enter your tax code.')
# Getting personal allowance from Tax Code
personal_allowance = tax_code[:tax_letter_index]
if personal_allowance == '':
personal_allowance = 0
else:
personal_allowance = int(personal_allowance) * 10
# Setting personal allowance exceptions for gross income over £100,000
if gross_income > 100000:
personal_allowance = set_personal_allowance - ((gross_income - 100000) / 2)
if personal_allowance < 0:
personal_allowance = 0
print('Personal Allowance:', personal_allowance)
print('Tax Letter:', tax_letter)
这些是之前包含在 get_tax_code
中的两个辅助函数。
第一个函数 verify1()
负责字母检查,而第二个 verify2()
处理字典匹配。从这两个函数返回的值决定了检查值是否更新,进而决定用户是否必须再次提供 tax_code
输入。
def verify1(tax_code):
tax_letter_index = ''
# Checking input contains a letter
for char in tax_code:
if char.upper().isalpha():
tax_letter_index = tax_code.index(char)
print('Passed letter check')
break
if tax_letter_index == '':
return -1
else:
return tax_letter_index
def verify2(tax_letter, tax_letters):
if tax_letter not in tax_letters.keys():
return False
elif tax_letter in tax_letters.keys():
return True
输出
Tax Code: 3200
Tax Code after input: 3200
Failed letter check
Invalid input. Please enter your tax code.
Tax Code: y
Tax Code after input: y
Passed letter check
Tax Code during dictionary match check (false): y
Failed dictionary match check
Invalid input. Please enter your tax code.
Tax Code: 1257L
Tax Code after input: 1257L
Passed letter check
Tax Code during dictionary match check (true): 1257L
Passed dictionary match check
Tax Code after dictionary match check: 1257L
Personal Allowance: 12570
Tax Letter: L