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的维数为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==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
    。对于无效的输入,这个函数无法继续,所以它应该停止,向调用它的人投诉,让他们处理它。这一切都是关于在最合适的位置处理错误,无论是当前函数(我们可以继续)、调用方(他们可以继续)还是直接返回给用户(根本无法继续),每个点的报告级别也不同。