我编写了一个功能,用于检查公司人格的增值税号码。这个功能有效,但很难看(太长太复杂)。
我是Python的新编程,想要改进功能,所以我需要一些反馈和帮助。
增值税号码始终为9位数,第一位是char,其余为数字。
char必须位于letras
字符串中。
最后一个数字是校验位。
使用其他七个数字算法是这样的:
有效增值税号的示例是A58818501
代码
def validarCodigoCIF(entrada):
"""
:param: entrada: str
:rtype: bool
"""
letras = "ABCDEFGHIJKLMNPQRSVW"
if len(entrada) != 9 or entrada[0] not in letras:
return False
numero = entrada[1:10]
pares = int(numero[1]) + int(numero[3]) + int(numero[5])
impares = 0
for i in range(0, 8, 2):
j = int(numero[i]) * 2
if j < 10:
impares += j
else:
impares += j - 9
digito = str(pares+impares)[-1]
if int(digito) == 0:
checkCIF = 0
else:
checkCIF = 10 - int(digito)
# print(checkCIF)
if str(checkCIF) == entrada[-1]:
return True
else:
return False
entradaCodigoCIF = input('Enter the VAT number: ')
print(validarCodigoCIF(entradaCodigoCIF))
答案 0 :(得分:1)
这是缩短版
def check(vat_num):
if len(vat_num) != 9 or vat_num[0] not in "ABCDEFGHIJKLMNPQRSVW":
return False # trivial checks first
nums = list(map(int, vat_num[1:8])) # numbers to check
nums[1::2] = ((i * 2) - (9 if i > 4 else 0) for i in nums[1::2]) # alter odds
return int(vat_num[8]) == (sum(nums) % 10) # compare to check digit
请注意以下有趣的*功能:
[1::2]
从迭代中获取所有其他项目; map(int, ...)
将interable中的所有项目转换为整数;和% 10
(模数)轻松获取数字的数字部分。*可能没什么兴趣
答案 1 :(得分:0)
要解决的第一个问题是你的功能太长了:
def calculate_pares(numero):
return int(numero[1]) + int(numero[3]) + int(numero[5])
def calculate_impares(numero):
result = 0
for i in range(0, 8, 2):
j = int(numero[i]) * 2
if j < 10:
result += j
else:
result += j - 9
return result
def calculate_check_cif(entrada):
numero = entrada[1:10]
pares = calculate_pares(numero)
impares = calculate_impares(numero)
digito = str(pares+impares)[-1]
if int(digito) == 0:
return 0
return 10 - int(digito)
def validarCodigoCIF(entrada):
"""
:param: entrada: str
:rtype: bool
"""
letras = "ABCDEFGHIJKLMNPQRSVW"
if len(entrada) != 9 or entrada[0] not in letras:
return False
checkCIF = calculate_check_cif(entrada)
# print(checkCIF)
return str(checkCIF) == entrada[-1]
这只是第一步,我想你明白了。当你有小功能时,进一步的改进会更容易。
此外,如果您用英语编写代码会更容易 - 那么人们可能会帮助您发现更有意义的功能,而不仅仅是盲目分区/猜测。
答案 2 :(得分:0)
看到增值税号使用Luhn校验和,我提供了我最近在an (unaccepted) answer中发布的有关信用卡号的修改后的版本。
该函数不一定比您的短,但使用另一种方法:它返回有效数字上的None
和失败时的短错误消息。它还确保首字母后的数字有效,并允许空格和一些标点符号。
def invalid_cif_code(s):
""" Returns None if s is a valid CIF code and a string
describing the error otherwise. The string may contain
spaces and punctuation, which is ignored.
"""
# strip punctuation from string
s = [x for x in s if x not in " \t.-"]
if len(s) != 9:
return "Invalid length"
if s[0] not in "ABCDEFGHIJKLMNPQRSVW":
return "Invalid initial letter"
# convert numerical part to list of digits
try:
code = [int(x) for x in s[1:]]
except ValueError:
return "Invalid non-digit in number"
# multiply and cast out nines for every other codeit
for i in range(0, 8, 2):
code[i] *= 2
if code[i] > 9:
code[i] -= 9
# calculate checksum
s = (9 * sum(code)) % 10
if s != 0:
return "Invalid checksum"
return None
Typical Programmer有一个更优雅的Luhn校验和解决方案(虽然用于信用卡号码并用Javascript编写),它使用数组作为奇数。