python isbn 13 位验证
python isbn 13 digit validate
我需要编写一个函数来验证 13 位 ISBN。它需要以 978 或 979 开头,以一位数字结尾,其余部分的长度至少需要一位数字。我需要一些帮助才能完成这项工作,我不明白为什么它从来没有 returns true
def validate(s)
lst = s.split("-")
isbn= False
if lst[0] == "978" or lst[0] == "979":
if len(lst[1])>=1 and len(lst[2])>=1:
if len(lst[3])==1:
isbn= True
return isbn
您应该使用正则表达式,这正是它用于以下用途的原因:
>>> import re
>>> def validate(isbn):
isbn_regex = re.compile('^(978|979)-\d+-\d+-\d$')
return isbn_regex.search(isbn) is not None
>>> print validate('978-12-12-2')
True
注意:这按照您在上面代码中的逻辑工作(除了您没有检查它是否是数字)。
ISBN-13 由五组数字组成,最后一位是校验位。这是一个函数,用于确保有五个组,正好是 13 个数字,并验证校验位。它适用于您的样本:
import re
def validate(s):
d = re.findall(r'\d',s)
if len(d) != 13:
return False
if not re.match(r'97[89](?:-\d+){3}-\d$',s):
return False
# The ISBN-13 check digit, which is the last digit of the ISBN, must range from 0 to 9
# and must be such that the sum of all the thirteen digits, each multiplied by its
# (integer) weight, alternating between 1 and 3, is a multiple of 10.
odd = [int(x) for x in d[::2]]
even = [int(x)*3 for x in d[1::2]]
return (sum(odd)+sum(even)) % 10 == 0
trials = '''\
978-3-16-148410-0
978-3-16-148410
978-0-306-40615-7
978-0306-40615-7
979-11111-11-11-2
978-7654-321-12-4
977-7654-321-12-4
978-7654-321-1-41
978-7654-321-1-4
978-7654-321-122-4
'''.splitlines()
for trial in trials:
print(validate(trial),trial)
输出:
True 978-3-16-148410-0
False 978-3-16-148410 # too few numbers and groups
True 978-0-306-40615-7
False 978-0306-40615-7 # too few groups
True 979-11111-11-11-2
False 978-7654-321-12-4 # wrong check digit
False 977-7654-321-12-4 # didn't start with 978 or 979
False 978-7654-321-1-41 # didn't end in one digit.
False 978-7654-321-1-4 # too few digits
False 978-7654-321-122-4 # too many digits
ISBN-13 需要 13 位数字才有效。您的代码不检查所有字符都是数字(不包括 -
分隔符),也不检查实际长度。另外,需要五个部分,你可能正在验证校验位。
具体来说,您的代码从未 return True
因为第四段 (lst[3]
) 检查 正好 一个字符 (if len(lst[3])==1:
),但是,该元素通常会超过 1 个数字。
有 python 库可通过 PyPI 验证 ISBN 代码。这是一个使用 isbnlib
:
的例子
>>> import isbnlib
>>> isbnlib.is_isbn13('978-3-16-148410-0')
True
>>> isbnlib.is_isbn13('978-3-16-148410-5')
False
>>> isbnlib.is_isbn13('978-3-16-148410-A')
False
>>> isbnlib.is_isbn13('979-3-16-148410-9')
True
另一个更轻量级的库是 pyisbn
:
>>> import pysisbn
>>> pyisbn.validate('979-3-16-148410-9')
True
>>> pyisbn.validate('979-3-16-148410-0')
False
使用这些库的好处,除了让您免去自己解析 ISBN 字符串的麻烦之外,还在于它们提供了额外的功能,例如从 ISBN-13 转换为 ISBN-10。
错误 1:'def' 语句末尾缺少一个冒号。
错误2:'return isbn'语句没有缩进;它在函数之外,但应该在函数内部。
错误3:当lst中的元素多于四个时,检查lst[3]长度的行不检查isbn字符串的最后一个元素。
split 命令在 lst 中为您的第一个字符串 978-3-16-148410-0 创建五个元素;但是lst[3]有6位,长度测试失败
split 命令在 lst 中为您的第二个字符串 978-3-16-148410 创建四个元素;但是lst[3]有6位,长度测试失败
考虑使用 lst[-1] 来指定 lst 的最后一个元素,而不管它包含多少个元素。如果您的 i/p 格式正确,那么 o/p 应该是正确的。
我需要编写一个函数来验证 13 位 ISBN。它需要以 978 或 979 开头,以一位数字结尾,其余部分的长度至少需要一位数字。我需要一些帮助才能完成这项工作,我不明白为什么它从来没有 returns true
def validate(s)
lst = s.split("-")
isbn= False
if lst[0] == "978" or lst[0] == "979":
if len(lst[1])>=1 and len(lst[2])>=1:
if len(lst[3])==1:
isbn= True
return isbn
您应该使用正则表达式,这正是它用于以下用途的原因:
>>> import re
>>> def validate(isbn):
isbn_regex = re.compile('^(978|979)-\d+-\d+-\d$')
return isbn_regex.search(isbn) is not None
>>> print validate('978-12-12-2')
True
注意:这按照您在上面代码中的逻辑工作(除了您没有检查它是否是数字)。
ISBN-13 由五组数字组成,最后一位是校验位。这是一个函数,用于确保有五个组,正好是 13 个数字,并验证校验位。它适用于您的样本:
import re
def validate(s):
d = re.findall(r'\d',s)
if len(d) != 13:
return False
if not re.match(r'97[89](?:-\d+){3}-\d$',s):
return False
# The ISBN-13 check digit, which is the last digit of the ISBN, must range from 0 to 9
# and must be such that the sum of all the thirteen digits, each multiplied by its
# (integer) weight, alternating between 1 and 3, is a multiple of 10.
odd = [int(x) for x in d[::2]]
even = [int(x)*3 for x in d[1::2]]
return (sum(odd)+sum(even)) % 10 == 0
trials = '''\
978-3-16-148410-0
978-3-16-148410
978-0-306-40615-7
978-0306-40615-7
979-11111-11-11-2
978-7654-321-12-4
977-7654-321-12-4
978-7654-321-1-41
978-7654-321-1-4
978-7654-321-122-4
'''.splitlines()
for trial in trials:
print(validate(trial),trial)
输出:
True 978-3-16-148410-0
False 978-3-16-148410 # too few numbers and groups
True 978-0-306-40615-7
False 978-0306-40615-7 # too few groups
True 979-11111-11-11-2
False 978-7654-321-12-4 # wrong check digit
False 977-7654-321-12-4 # didn't start with 978 or 979
False 978-7654-321-1-41 # didn't end in one digit.
False 978-7654-321-1-4 # too few digits
False 978-7654-321-122-4 # too many digits
ISBN-13 需要 13 位数字才有效。您的代码不检查所有字符都是数字(不包括 -
分隔符),也不检查实际长度。另外,需要五个部分,你可能正在验证校验位。
具体来说,您的代码从未 return True
因为第四段 (lst[3]
) 检查 正好 一个字符 (if len(lst[3])==1:
),但是,该元素通常会超过 1 个数字。
有 python 库可通过 PyPI 验证 ISBN 代码。这是一个使用 isbnlib
:
>>> import isbnlib
>>> isbnlib.is_isbn13('978-3-16-148410-0')
True
>>> isbnlib.is_isbn13('978-3-16-148410-5')
False
>>> isbnlib.is_isbn13('978-3-16-148410-A')
False
>>> isbnlib.is_isbn13('979-3-16-148410-9')
True
另一个更轻量级的库是 pyisbn
:
>>> import pysisbn
>>> pyisbn.validate('979-3-16-148410-9')
True
>>> pyisbn.validate('979-3-16-148410-0')
False
使用这些库的好处,除了让您免去自己解析 ISBN 字符串的麻烦之外,还在于它们提供了额外的功能,例如从 ISBN-13 转换为 ISBN-10。
错误 1:'def' 语句末尾缺少一个冒号。
错误2:'return isbn'语句没有缩进;它在函数之外,但应该在函数内部。
错误3:当lst中的元素多于四个时,检查lst[3]长度的行不检查isbn字符串的最后一个元素。
split 命令在 lst 中为您的第一个字符串 978-3-16-148410-0 创建五个元素;但是lst[3]有6位,长度测试失败
split 命令在 lst 中为您的第二个字符串 978-3-16-148410 创建四个元素;但是lst[3]有6位,长度测试失败
考虑使用 lst[-1] 来指定 lst 的最后一个元素,而不管它包含多少个元素。如果您的 i/p 格式正确,那么 o/p 应该是正确的。