不含Luhn算法《python语言程序设计》2018版--第8章14题利用字符串输入作为一个信用卡号之二(识别卡号有效)

一、题面(文字版)

(金融:信用卡号合法性)使用"字符串"输入作为一个信用卡号来改写编程题6.29

二、题面里的函数

python 复制代码
# Return true if the card number is valid
def isValid(number):

# Get the result from Step 2
def sumOfFoubleEvenPlace(number):

# Return this number if it is a single digit, otherwise, return
# the sum of the two digits
def getDigit(number):

# Return sum of odd place digits in number
def sumOfOddPlace(number):

# Return true, if the digit d is a prefix for number
def perfixMatched(number,d):

# Return the number of digits in d
def getSize(d):

# Return the first k number of digits from number. If the
# number of digits in number is less than k, return number.
def getPerfix(number,k)

三 识别卡号有效

信用卡号必须是13位到16位,且数字开头需满足以下

  • 4是指Visa卡 16位
  • 5是指Master卡 16位
  • 37是指American Express卡 15位
  • 6是指Discover卡 16

3.1 输入设计

* 问题1 是先把字符串变成整数,还是一个一个把字符变成整数??

python 复制代码
#先把银行卡直接变成整数
def isValid(number):
    # 用户银行卡号输入模块
    digitNum = int(number)
    print("用户输入的银行卡", digitNum)

    # 对用户输入的银行卡进行甄别模块
    if 13 < digitNum < 16:  # 如果银行卡长度在13到16之间就识别属于什么类银行卡
        if digitNum == 4:
            print(f"银行卡{digitNum}是Visa卡")
        elif digitNum == 5:
            print(f"银行卡{digitNum}是Master卡")
        elif digitNum == 37:
            print(f"银行卡{digitNum}是American Express卡")
        elif digitNum == 6:
            print(f"银行卡{digitNum}是Discover卡")
        else:
            print(f"{digitNum},此卡有问题")
    
    else:
        print("不是合格的银行卡")
        
def main():
    a = isValid("10")
    b = isValid("4388576018402626")
    print(type(a)) #利用type来看看isValid的属性
    print(type(b)) #利用type来看看isValid的属性
main()

这个结果似乎不对。我们来分析一下

我们先把银行卡 4388576018402626转换成了整数,看似很对,可此时的4388576018402626其实是 4,388,576,018,402,626就变成了4千万亿这个超级大的整数。

* 分析

从图2中可以看出这个函数无法进行字符串操作。我们这个函数def isValid(number):看似处理的是整数,但实际上是字符串。所以问题1先把字符串变成整数是不行的。

* 计划

我们应该利用第8章学的切片技术逐一把银行卡号单独提取成数字。当然如果仅仅是识别银行卡属于哪种类型。我的意思也可以不使用转为整数形式。但是逐一切片然后进行字符与字符之间的对比也是可以的。

实施过程中问题

1、if范围是<还是 <=?

13小于lenNum小于16这恰恰将范围限制到了12和15之间,没法进行我们初期的设计即长度在13到16之间,所以我们要加上小于等于<=

2、lenNum[0]还是number[0]?

我们用lenNum来进行

结果TypeError: 'int' object is not subscriptable

我们的目的是利用字符串切片取lenNum中的第一个字符,其实是取银行卡中的第1位
lenNum是利用len后的银行卡长度,而不是银行卡本身

所以我们应该用isValid(number)的numbert

3、if number[0] == 4:还是if number[0] == "4":

我们看一下结果

我处理了lenNum但是这里又忽略了4,应该是字符'4'而不是整数4

3.2 增加全数字验证逻辑

比如"4a88576018402626"会误判为 Visa 卡

python 复制代码
def isValid(number):
    # 新增:验证是否全为数字
    if not number.isdigit():
        print(f"{number}含非数字字符,不是合法银行卡号")
        return 
    lenNum =len(number) #识别银行卡字符串长度
    if 13 <= lenNum <= 16 : # Visa/Master/Discover:13/16位;American Express:15位
        if number[0] == '4':# 如果头一个字符是4则是visa卡
            print(f"银行卡{number}是Visa卡")
            return True #返回True表示验证成功
        elif number[0] == '5':
            print(f"银行卡{number}是Master卡")
            return True #返回True表示验证成功
        elif number[0:2] == '37':
            print(f"银行卡{number}是American Express卡")
            return True #返回True表示验证成功
        elif number[0] == '6':
            print(f"银行卡{number}是Discover卡")
            return True #返回True表示验证成功
        else: #如果不符合则显示磁卡
            print(f"{number},此卡无法识别,请您提供该卡类型给管理员")
            return False
    else:
        print(f"{number}不是银行卡,请您重新输入,或联系管理员")
        return False
        
def main():
    a = isValid("10") # 故意输入的非法数
    b = isValid("4388576018402626") #visa卡
    c = isValid("5388576018402626") #Master卡
    d = isValid("3788576018402626") #American Express卡
    e = isValid("6388576018402626") #Discover卡
main()

最终结果

3.3 细化代码

python 复制代码
#识别银行卡
def isValid(number):
    # 新增:验证是否全为数字
    if not number.isdigit():
        print(f"{number}含非数字字符,不是合法银行卡号")
        return
    lenNum =len(number) #识别银行卡字符串长度
    if 13 <= lenNum <= 16 : # Visa/Master/Discover 16位;American Express:15位
        if number[0] == '4' and lenNum == 16:# 如果头一个字符是4则是visa卡
            print(f"银行卡{number}是Visa卡")
            return True #返回True表示验证成功
        elif number[0] == '5' and lenNum == 16:
            print(f"银行卡{number}是Master卡")
            return True #返回True表示验证成功
        elif number[0:2] == '37' and lenNum == 15:
            print(f"银行卡{number}是American Express卡")
            return True #返回True表示验证成功
        elif number[0:4] == '6011' and lenNum == 16:
            print(f"银行卡{number}是Discover卡")
            return True #返回True表示验证成功
            
        else: #如果不符合则显示磁卡
            print(f"{number},此卡无法识别,请您提供该卡类型给管理员")
            return False
    else:
        print(f"{number}不是银行卡,请您重新输入,或联系管理员")
        return False
        
def main():
    a = isValid("10") # 故意输入的非法数
    b = isValid("4388576018402626") #visa卡
    c = isValid("5388576018402626") #Master卡
    d = isValid("3788576018402626") #American Express卡
    e = isValid("6388576018402626") #非Discover卡
    d = isValid("6011576018402626") #Discover卡

main()

下一章我们将把Luhn算法加入到其中

相关推荐
WJX_KOI3 小时前
Open Notebook 一个开源的结合AI的记笔记软件
python
0思必得04 小时前
[Web自动化] 反爬虫
前端·爬虫·python·selenium·自动化
嘴贱欠吻!4 小时前
Flutter鸿蒙开发指南(七):轮播图搜索框和导航栏
算法·flutter·图搜索算法
徐徐同学4 小时前
cpolar为IT-Tools 解锁公网访问,远程开发再也不卡壳
java·开发语言·分布式
2301_822382764 小时前
Python上下文管理器(with语句)的原理与实践
jvm·数据库·python
张祥6422889044 小时前
误差理论与测量平差基础笔记十
笔记·算法·机器学习
喵手5 小时前
Python爬虫实战:从零搭建字体库爬虫 - requests+lxml 实战采集字体网字体信息数据(附 CSV 导出)!
爬虫·python·爬虫实战·零基础python爬虫教学·csv导出·采集字体库数据·字体库字体信息采集
qq_192779875 小时前
C++模块化编程指南
开发语言·c++·算法
Mr.朱鹏5 小时前
Nginx路由转发案例实战
java·运维·spring boot·nginx·spring·intellij-idea·jetty
2301_790300965 小时前
Python深度学习入门:TensorFlow 2.0/Keras实战
jvm·数据库·python