将参数(x)指定为具有一定列数的多维数组?

时间:2017-11-11 02:31:13

标签: python numpy multidimensional-array

import numpy as np

def validation(x):
    x = np.asarray(x)
    if len(x) != 16:
        return("Card doesn't have exactly 16 digits. Try again")
    values = []
    rwhat = x[::-1]    # reverse the order of the credit card numbers
    rwhat

    checkDig = rwhat[0] # the leftmost [originally rightmost] digit which is the checkDigit ... I'm just doing this because it's easier for me to work with
    checkDig
    withCheck = [] # to append later when we add all single digits

    everySec = rwhat[1:16:2] # we don't want to double the checkDigit, but we're extracting every second digit starting from the first, leftmost digit [tho we omit this checkDigit
    everySec

    def double(num): # to double the extracted second digit values
        return [j * 2 for j in everySec] 
    xx = double(everySec)
    xx

    def getSingle(y): # to add the sum of the digits of any of the new doubled numbers which happen to be greater than 9
        u = 0
        while y:
            u += y % 10
            y //= 10
        return u
    yy=list(map(getSingle,xx))
    yy
    withCheck.append(checkDig)
    withCheck
    new_vv = withCheck + yy
    new_vv # now we include the omitted checkDigit into this new list which should all be single digits

    sumDig = sum(new_vv)
    sumDig # now have the sum of the the new_vv list.

    def final(f):
        if sumDig % 10 == 0: # if the calculated sum is divisible by 10, then the card is valid.
            return("Valid")
        else:
            return("Invalid")
    go = final(sumDig)
    values.append(go) # basically just appending into values[] for the sake of the validation(x) function, and so we can return something for this function. in this case we'd return values as seen below.
    return values

所以我创建了这个程序,我需要弄清楚如何定义第一个(最外面的)函数的参数将卡号作为一个由16列组成的多维数组,最终应该返回一个值列表说明“有效”或“无效”。

def validation(x)内部的东西,我在实际制作上述函数之前测试了它,但我只是不知道如何指定这个函数[这个程序基本上是什么]接受了16列的多维数组。

我很确定关于if len(x) != 16的代码行是问题的一部分,但是如果我们只想运行一张卡[也就是一组16位数]

例如,如果我想尝试validation(([[0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5],[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6]])我受到输出的困扰:"Card doesn't have exactly 16 digits. Try again"而不是正确运行的程序,并返回一个列表,表明每张卡各有效或无效

2 个答案:

答案 0 :(得分:2)

除了@ JohnZwinck的答案中提到的基本问题之外,还有一个基本的事实,即你没有将numpy数组用作numpy数组。

对于您正在编写的程序,不应该有任何明确的循环或理解来计算总和或其他数量。 Numpy数组是用于矢量化代码和简化其外观的出色工具。

除了声明数组的大小之外,我还建议进行一些更改:

  • 断言所有数字都在0-9范围内:

    assert np.all((x >= 0) & (x <= 9))
    
  • 请注意您是使用行还是列。如果您有n行,每行16列,checkDig应为x[:, 0],这是第一列,而不是x[0],这是第一行,相当于{{ 1}}。

  • 无需反转数组:x[0, :]只是最后一个元素:checkDig; x[:, -1]变为everySec。考虑到如何使用它,没有必要对它进行反转。
  • 函数x[:, 1:-1:2]只是一团糟:

    1. 您声明了一个未使用的参数double
    2. 然后,您将在封闭名称空间
    3. 中对num进行操作
    4. 您将列表推导应用于numpy数组,该数组较慢,难以理解且无法正确处理2D数组。
    5. 您可以仅使用everySec替换它,甚至可以删除xx = everySec * 2,然后执行xx

    6. everySec *= 2有点矫枉过正。你将数字加倍九,所以结果不能超过2位数(其总和不能超过9)。 getSingle应该做得很好。通过维护numpy数组而不是列表,可以使所有操作都适用于2D数组,而不必遍历列表中的所有单个元素。
    7. 您的其余操作有点不清楚。您似乎正在实施Luhn algorithm,但没有尝试添加非加倍数字。非加倍数字yy = (xx // 10) + (xx % 10)
    8. 调用内置x[:, :-1:2]将阻止您在没有循环的情况下处理多个输入。使用np.sumsum对每行中的列进行求和。
    9. axis=1只被调用一次。如果你想处理多个数字,你必须编写某种循环。将values.append(go)作为布尔数组而不是单个布尔值会更容易。

结合所有这些建议会产生类似的结果:

go

通过复制输入以避免覆盖事物并就地操作,可以进一步简化该功能:

def validation(x):
    x = np.asanyarray(x)
    assert x.ndim == 2, "input must be 2D"
    assert x.shape[1] == 16, "input must have 16 columns"
    assert np.issubdtype(x.dtype, np.integer), "input must be integers"
    assert np.all((x >= 0) & (x <= 9))
    checkDig = x[:, -1]
    xx = x[:, 1:-1:2] * 2
    yy = x[:, :-1:2]
    sumDig = np.sum(xx, axis=1) + np.sum(yy, axis=1) + checkDig
    return ['Invalid' if s % 10 else 'Valid' for s in sumDig]

答案 1 :(得分:0)

您需要检查dnf install php56-php-mbstring。像这样:

shape