Python 为魔方写一份类型合同
我被问到这个问题是为了写这个魔方的代码 二维整数矩阵Python 为魔方写一份类型合同,python,python-3.x,Python,Python 3.x,我被问到这个问题是为了写这个魔方的代码 二维整数矩阵s是一个幻方,如果 s的维数为nxn [1,2,…,n*n]中的每个整数在s中出现一次 s中所有行的和与s中所有列的和相同,与s中对角线元素的和相同 示例:s=[[8,3,4],[1,5,9],[6,7,2]]表示 以下整数矩阵: 8 3 4 1 5 9 6 7 2 请注意,上面的s是一个二维整数数组 s是一个3x3的正方形 [1,2,…,9]中的所有数字在s中正好出现一次 所有行的和与所有列的和与沿两条对角线的和相同 行和:8+3+4==
s
是一个幻方,如果
s=[[8,3,4],[1,5,9],[6,7,2]]
表示
以下整数矩阵:
8 3 4
1 5 9
6 7 2
请注意,上面的s
是一个二维整数数组
- 行和:
8+3+4==1+5+9==6+7+2==15
- 列和:
8+1+6==3+5+7==4+9+2==15
- 诊断和:
8+5+2==6+5+4==15
[[8,1,6],[3,5,7],[4,9,
2] ,[[6,7,2],[1,5,9],[8,3,4].
我了解如何编程和编写这段代码,但我的问题是如何为此编写类型合同。我知道如何编写一个程序来执行它,但是当涉及到任何程序的类型契约时,你如何知道会有多少个参数,你如何知道如何编写你希望它为这样一个程序做什么的示例。在编写类型合同和为程序制作示例时,是否有一个通用的方法可以遵循?如果您的意思是如何通用地解决这个问题,那么就没有解决所有问题的灵丹妙药 然而,在这个特定的问题中,您的输入是一个列表。用户可以给你任何这样的列表,例如
[3]
[3, [2, 5]]
[[5, 6]]
['ac']
只要您能根据一些规则确定它是一个“语法有效”列表,您就可以处理它是否具有魔力
您可以强制用户单独输入数据,以确保数据为nxn和唯一整数[1..9],如下所示:
> Enter n: 3
> Enter [row, column] [1, 1]: 1
> Enter [row, column] [1, 2]: 3
...
这将使以后的魔法检查更容易,因为条件1和2已经满足。
但是,如何实现它实际上取决于您。您可以立即获取整个列表,等等。但这是用户和您商定的决定。关于检查
数组是否是您的docstring所说的,我实际上不会费事。使用;假设这是正确的事情,让调用者去处理任何错误,如果他们没有按照你的要求传递错误
如果输入无效,您的函数将无法继续,因此在该级别处理错误是没有意义的,并且尝试显式使用例如isinstance
只会进一步缩小用户可以传递的内容(例如,如果用户传入的是一组元组,而不是一组列表,为什么您的函数不能继续工作?它们都是序列…)
如果你的问题真的是关于包括例子,正如你的评论所暗示的,我从这里开始:
def is_magic(array):
"""Whether the array is 'magic'.
Arguments:
array (sequence of sequences of integers): The array to test.
Returns:
bool: Whether the array is 'magic'.
Notes:
A 'magic' array is a 3x3 array of integers where each row, column
and diagonal adds up to the same number
Examples:
>>> is_magic([[8, 3, 4], [1, 5, 9], [6, 7, 2]])
True
"""
raise NotImplementedError
if __name__ == '__main__':
import doctest
doctest.testmod()
文档记录了函数,例如IDE和帮助函数可以使用这些函数来告诉用户函数的功能。请注意示例的使用,这些示例都向用户展示了如何调用函数和期望返回的内容,并可作为代码的测试
当然,当你第一次运行它时,它会失败
**********************************************************************
File "C:\Python27\so.py", line 16, in __main__.is_magic
Failed example:
is_magic([[8, 3, 4], [1, 5, 9], [6, 7, 2]])
Exception raised:
Traceback (most recent call last):
File "C:\Python27\lib\doctest.py", line 1315, in __run
compileflags, 1) in test.globs
File "<doctest __main__.is_magic[0]>", line 1, in <module>
is_magic([[8, 3, 4], [1, 5, 9], [6, 7, 2]])
File "C:\Python27\so.py", line 20, in is_magic
raise NotImplementedError
NotImplementedError
**********************************************************************
1 items had failures:
1 of 1 in __main__.is_magic
***Test Failed*** 1 failures.
**********************************************************************
文件“C:\Python27\so.py”,第16行,在\uuuu main\uuuuu.is\u magic中
失败示例:
是魔法([[8,3,4],[1,5,9],[6,7,2])
提出的例外情况:
回溯(最近一次呼叫最后一次):
文件“C:\Python27\lib\doctest.py”,第1315行,正在运行
test.globs中的compileflags,1)
文件“”,第1行,在
是魔法([[8,3,4],[1,5,9],[6,7,2])
文件“C:\Python27\so.py”,第20行,在is\u magic中
引发未实现的错误
未实现错误
**********************************************************************
1个项目出现故障:
1/1在主站是魔术
***测试失败***1次失败。
“类型合同”?这是Python!假设输入是一个序列,如果调用方传入了其他内容,则让调用方处理任何错误。@jornsharpe但我必须输入示例,比如我输入了lets say is_magic(…),然后输入它的输出。如果要显示示例,请将它们作为,然后,您可以确保它们运行并使用它们来测试您的代码。此外,如果您想了解更多,我所指的是“调用”。“只要您可以根据一些规则确定它是一个“语法上有效的”列表”-但最简单的方法是通过duck键入(即,尝试使用它,就好像它是有效的一样)告诉用户不是这样的最好方法是提出一个错误,这会自动发生!您假设“最简单”对程序员来说意味着最简单。用户必须自己找出自己做错了什么。用户是谁?如果OP只是编写一个Python函数,那么“用户”可能是其他一些Python代码,它可以相应地检查TypeError
和try
。对于无效的输入,这个函数无法继续,所以它应该停止,向调用它的人投诉,让他们处理它。这一切都是关于在最合适的位置处理错误,无论是当前函数(我们可以继续)、调用方(他们可以继续)还是直接返回给用户(根本无法继续),每个点的报告级别也不同。