Python实例—计算ISBN的校验和并返回ISBN号
咳咳,科普一下,ISBN的中文名为国际标准书号,简单来说就是一本书的身份证,经常和条形码在一起使用。
话不多说,我们直接进入正题:
一、题目要求与分析
国际标准书号用10为数字唯一标识一本书(哈哈,莫说我骗你噻,自从2007年1月1日起,实行新版ISBN,即在原来的10位数字前加上3位图书产品代码“978”,称为欧洲商品编号,总之就是方便检索的,这段很尴尬,隐了隐了),最右边的数字为校验和,可由其他9位数字计算出来,且d1 + 2d2 + 3d3 + …+ 10d10 必须是11的倍数。校验和必须是介于0到10中的一个数字,用X标识10。例如:020131452的校验和是5,因为对于下边11倍数的公式,5是唯一的介于0到10之间的数:
要求任意给出前9位数字,需要计算校验和并返回ISBN号。
好吧,不得不说我在构建这个数学公式上耗费了大半元气。
题目分析:上边啰嗦了那么多,终归是一个找数字的问题,只是这个数字比较复杂,既满足在0-10之间,又满足和其他数相加是11的倍数。如果这个数找到了,那么什么输出ISBN号通通不在话下,我们将问题简化可以分解成以下三步:
步骤1: 限定校验和k(就是那个数,我们也专业点儿)的范围为0-10
步骤2: 计算其他数(就是那个 2d2 + 3d3 + …+ 10d10),这里用number_other表示;
步骤3: 限定倍数(就是相加是11的倍数那个倍数),这里用mul表示.
注意:我为什么要限定倍数nul 呢?
这个问题是这道题的核心,这里我不妨谈谈自己的思路,题中提到11的倍数,但又没有说这个倍数具体是多少,所以我只能用一个变量mul来代替,让它从0往后遍历就好了,但是新的问题出现了;这么一直遍历下去也不是办法,毕竟刹不住车不行呀。
所以这里的问题又转化成了找最大倍数的问题,怎么找最大倍数呢?不妨看一下这个公式:
这样就一目了然了,对吧!k增大mul增大,所以很容易求出来mul的最大值是45,如果mul超出这个值,则k就不能落在0-10之间了。
讲到这里,想必后边的代码过程大家都势如破竹了,接下来我们把代码给码列一下……
二、源代码部分
def ISBN(n):
number = str(n)
number_other = 0
j = 2
for i in range(-1,-10,-1):
number_other += eval(number[i]) * j
j += 1
for mul in range(0,45): #找m可能取到的最大值
for k in range(0,11):
if (number_other + k) / 11 == mul: #我滴天,千万不能用整除
if 0 <= k <=9:
d = str(k)
if k == 10:
d = "x"
trueISBN = number + d
return (trueISBN)
for num in [201314525, 488888913, 977889994, 753231846, 701134069]:
trueISBN = ISBN(num)
print(trueISBN)
嗯,中规中矩的代码,不掺任何浮躁华丽……
三、结构分析
(1) 制造一个函数模块
害,这种类型的难题不编写一个函数总觉得对不起自己,一方面是为了养成一个好的习惯,毕竟模块化处理嘛,方便以后干惊天动地的事,另一方面也看起来舒心,简洁整齐,有条不紊,多像正规军。
注意:函数的参数一定要传递正确,要不然浪过头就不好了。
(2) 计算num_other
num_other也不是不好算,只是大家有没有发现那个公式里数字的计算方式是倒着的,比如020131452(图也给你了,快看看),所以你要么倒着让它每个数进行乘法运算,要么就是让他每个数乘以一个倒着增长的数。
我这里选择了前者,这里涉及字符串的索引问题,你要是不懂的话可以看看我的“Python字符串的索引”
于是乎,产生了如下一段代码:
number = str(n)
number_other = 0
j = 2
for i in range(-1,-10,-1):
number_other += eval(number[i]) * j
j += 1
注意:j的值要从2开始,因为乘1被校验和k(文章一开始提到的那个数)占了
(3) 计算核心数字k
通过一开始我们的分析,可以知道要进行两次限定,于是这里就用了两个for循环,第一个循环限定mul的值最大为45(为啥写46就不必说了哈,range函数的特性嘛对不对),第二次限定k的范围为0-10, 所以这个计算核心数字k的过程就悄然跃然纸上:
for mul in range(0,46): #找m可能取到的最大值
for k in range(0,11):
if (number_other + k) / 11 == mul: #我滴天,千万不能用整除
if 0 <= k <=9:
d = str(k)
if k == 10:
d = "x"
trueISBN = number + d
注意:
1 . 因为题中说“用X标识10”,所以记得加一个判断,判定k是不是10,如果是的话就用X代替;
2 . 公式描述的那个部分千万不能用整除,“/”和“//”是有区别的,整除的话在这里会使很大一部分数都满足条件,仔细想想?
3 . 函数的最后要写return,要不前面写的都白搭了。切记切记。
四、本次的运行结果
那就在这里祝你好运咯~
听说,爱学习的人都特帅……