不含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算法加入到其中

相关推荐
观音山保我别报错1 小时前
列表,元组,字典
开发语言·python
小付爱coding1 小时前
Claude Code安装教程【windows版本】
java·git·python
**蓝桉**1 小时前
数组的执行原理,java程序的执行原理
java·开发语言
2301_800256111 小时前
8.2 空间查询基本组件 核心知识点总结
数据库·人工智能·算法
不穿格子的程序员1 小时前
从零开始写算法——矩阵类题:矩阵置零 + 螺旋矩阵
线性代数·算法·矩阵
YDS8291 小时前
MyBatis-Plus精讲 —— 从快速入门到项目实战
java·后端·spring·mybatis·mybatis-plus
高频交易dragon2 小时前
5分钟和30分钟联立进行缠论信号分析
开发语言·python
0思必得02 小时前
[Web自动化] 开发者工具应用(Application)面板
运维·前端·python·自动化·web自动化·开发者工具
BBB努力学习程序设计2 小时前
Java条件判断:程序的"决策大脑"
java