将参数(x)指定为具有特定列数的多维数组?
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列组成的多维数组,并最终返回一个列表的值表示“有效”或“无效”。将参数(x)指定为具有特定列数的多维数组?
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"
,而不是正常运行,并返回我,指出在各自有效还是无效的列表,以每张卡
您需要检查shape
程序。事情是这样的:
assert len(x.shape) == 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"
除了基本的问题解决在@ JohnZwinck的答案,还有就是你不使用numpy的数组作为numpy的阵列的基本事实。
对于您正在编写的程序,不应该有任何明确的循环或解释来计算总和或其他数量。 Numpy数组是用于向量化代码并简化其外观的优秀工具。
这里有一些改变我除了建议断言数组的大小:
-
断言,所有的数字都在范围0-9:
assert np.all((x >= 0) & (x <= 9))
请注意您是使用行还是使用列。如果您有
n
行,每行16列,checkDig
应该是x[:, 0]
,这是第一列,而不是x[0]
,这是第一行,相当于x[0, :]
。- 无需反转阵列:
checkDig
只是最后一个元素:x[:, -1]
;everySec
变成x[:, 1:-1:2]
。考虑到它的使用方式,没有必要对其进行逆转。 -
功能
double
仅仅是一个烂摊子:- 声明一个未使用的参数
num
。 - 你然后
everySec
运行在封闭命名空间 - 您应用列表理解到numpy的阵列,这是比较慢,很难理解,并不会为二维数组正常工作。
你可以只用
xx = everySec * 2
取代它,甚至摆脱xx
,只是做everySec *= 2
。 - 声明一个未使用的参数
-
getSingle
是矫枉过正。你的数字是九倍以下,所以结果不能超过两位数(总和不能超过九位)。yy = (xx // 10) + (xx % 10)
应该做得很好。通过维护numpy数组而不是列表,您可以使所有操作适用于2D数组,而不必遍历列表中的所有单个元素。 - 您操作的其余都有点不清楚。您似乎正在执行Luhn algorithm,但没有尝试添加非加倍数字。非加倍数字
x[:, :-1:2]
。 - 中调用内建
sum
将阻止你没有一个循环处理多个输入。使用np.sum
,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]
功能可以通过将输入的副本以避免覆盖东西,就地操作进一步简化:
def validation(x):
x = np.array(x, copy=True, subok=True)
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))
y = x[1:-1:2]
x[1:-1:2] = ((2 * y) // 10) + ((2 * y) % 10)
sumDig = np.sum(x, axis=1)
return ['Invalid' if s % 10 else 'Valid' for s in sumDig]
修复您的缩进。这是Python无效的表现。 –
如果您想使用numpy,请使用numpy。不要使用像'len'这样的东西,它按顺序给出了行数,而不是列数和列表解析。 –
当您修复了代码格式时,请对我进行平邮,然后我会给您写回答。 –