很多时候,当我继承或遇到其他人编写的科学代码(或偶而甚至是我自己的工作)时,我注意到文档稀疏或不存在。如果幸运的话,我会看到翔实的评论。如果我很幸运,甚至还有Doxygen注释和Doxyfile,这样我就可以使用函数接口和一些格式化的HTML进行查阅。如果我非常幸运,除了Doxygen和源文件注释之外,还有PDF手册和示例,我很欣喜,因为它使我的生活变得非常轻松。
哪些信息和工具可用于记录源代码?因此,对于科学软件,哪些信息和工具可用于记录与该源代码一起的数据和结果?
很多时候,当我继承或遇到其他人编写的科学代码(或偶而甚至是我自己的工作)时,我注意到文档稀疏或不存在。如果幸运的话,我会看到翔实的评论。如果我很幸运,甚至还有Doxygen注释和Doxyfile,这样我就可以使用函数接口和一些格式化的HTML进行查阅。如果我非常幸运,除了Doxygen和源文件注释之外,还有PDF手册和示例,我很欣喜,因为它使我的生活变得非常轻松。
哪些信息和工具可用于记录源代码?因此,对于科学软件,哪些信息和工具可用于记录与该源代码一起的数据和结果?
Answers:
我认为科学软件的文档可以分为三类,所有这些对于充分理解都是必要的。最简单,最常见的是单个方法文档。为此有许多系统。您提到了doxygen,Python有pydoc,在PETSc中,我们有自己的包播种,它会生成以下内容。
但是,对于超出简单实用程序范围的任何软件,都需要手册。这提供了软件包目的的高级视图,以及如何集成其不同功能来实现此目的。它通常通过使用示例来帮助新用户构建其代码。在PETSc中,我们仅使用LaTeX作为手册,但是PyClaw包使用的Sphinx框架让我印象深刻。我发现播种包中实现的一件事非常有用,就是示例代码和函数文档之间的链接。例如这个例子解决布拉图方程。请注意,如何跟踪任何自定义类型或函数调用的链接并转到低级文档,以及这些页面如何链接回使用它们的示例。这就是我了解项目中其他人贡献的新功能的方式。
我认为,文档中经常被忽略的部分是开发人员文档。发布编码样式的文档以及与存储库进行交互的说明并不罕见。但是,很少解释在实现之前做出的设计决策。这些决定总是涉及折衷,并且有关硬件和算法的情况将随着时间而改变。无需讨论所权衡的问题和特定设计决策的原理,以后的程序员可以自己重新创建整个过程。我认为,当原始开发人员不再负责时,这是成功维护和改进旧代码的主要障碍。
最重要的是在您选择的开发环境中使用文档工具,这意味着python的pydoc,java中的javadoc或C#中的xml注释。这些使得在编写代码的同时易于编写文档。
如果您依赖于以后再回来记录文档,则可能无法解决问题,但是如果在编写代码时就这样做了,那么需要记录的内容将是新鲜的。如果XML文档不完整或与实际代码不一致,C#甚至可以选择发出编译警告。
另一个重要方面是具有良好的集成和单元测试。
文档通常集中于类和方法独立进行的工作,而跳过如何一起使用它们来解决您的问题。测试通常通过显示它们如何交互来将它们置于上下文中。
同样,单元测试通常会明确指出外部依赖关系,需要通过这些外部关系来模拟事物。
我还发现,使用测试驱动的开发可以编写易于使用的软件,因为我一开始就在使用它。有了良好的测试框架,使代码更易于测试和易于使用通常是一回事。
最后,还有关于系统级别和体系结构文档的操作。许多人主张使用Wiki或使用Word或其他文字处理器编写此类文档,但是对我而言,此类文档的最佳位置是代码,并采用纯文本格式,这是版本控制系统友好的。
就像代码中的文档一样,如果将更高级别的文档存储在代码存储库中,则很有可能使它保持最新。您还可以获得以下好处:拔出代码的XY版本时,还将获得文档的XY版本。另外,如果使用VCS友好格式,则意味着可以像代码一样轻松地对文档进行分支,区分和合并。
我非常喜欢reStructuredText(rst),因为使用sphinx可以很容易地从中生成html页面和pdf文档,并且比LaTeX友好得多,但仍可以在需要时包含LaTeX数学表达式。
rst
是我可以在普通的文本编辑器中编写它(使用与编写代码相同的IDE),并且仍然可以确定最终文档的外观喜欢。另外,格式约定使它对VCS非常友好,这对我来说很重要。
我将对Faheem提出的几乎所有观点表示反对。特别:
1 /“我认为期望科学开发人员花费大量时间来记录其软件是不现实的”。这是一个失败项目的处方,该项目很快将使没有权限的人无法使用主要开发人员。大型科学计算库(例如PETSc或deal.II)具有广泛的文档,可以运行到数千页或更多页面,这是有充分的理由。如果您没有大量的文档,那么您将没有一个庞大的用户社区。但是,我会同意,示例代码必须简单并且只关注单个概念。
2 /“如果适当,作者应考虑撰写论文供出版”。在实践中这通常是不可能的。可以写有关概念和算法的论文,但不能写关于接口和其他设计决策的论文。此类论文的读者将了解实现的方式。实现的用户将需要知道要调用的函数,参数的含义等。作为用户,大多数时候可以不使用前者而只是将库视为黑匣子,但是如果没有,则不能做不到接口信息。
这是一个很好的问题。首先,代码应尝试进行自我记录。因此,举例来说,如果软件是命令行,你应该能够做到executable --help
或者executable -h
甚至executable
(如果可执行文件不执行任何不带任何参数),并且有一个简短的用法消息回报。
其次,我认为期望科学开发人员花费大量时间来记录其软件是不现实的,因此我建议保持简单。简短的文本手册,其中包含基本方法和选项以及带注释的工作和测试从简单到更复杂的用法示例(用法示例非常重要,经常被忽略)比没有好得多,而且比大多数科学软件所提供的要好得多。我还想对用法示例添加一点生气。简单意味着简单。这意味着,如果您试图说明一种方法,则不会添加十个无关的概念或方法来使读者感到困惑。保持简单和注释,以使读者知道该示例应该执行的操作。我还建议以某种方式将手动用法示例绑定到测试套件中,以便在更改代码后它们可以继续工作。我实际上不知道如何以一种很好的方式来做到这一点,所以请随时教育我。如果开发人员想花更多的时间,请确保他们可以使用不错的标记语言等,并添加手册页等。
第三,作者应酌情考虑撰写论文发表。这通常可以解决设计决策,并且比手册可以提供或可以预期提供对软件的更高层次的了解。这将解决@Matt在谈论的设计决策文档。
当然,最重要的文档是代码本身,应在必要时对其进行注释。假设代码是免费软件。如果不是这样,那么它作为科学软件就没有那么多用了(您是否真的想在无法看到方法实现方式的地方使用黑匣子?),并且我不会使用它。
为了解决有关如何记录数据和结果的问题,我建议您使用Python的doctest模块之类的东西。这使您可以以可以自动验证的方式编写教程或测试。
如果您对识字编程感兴趣,请参阅org-babel。它是Emacs中组织模式的一部分,因此为您提供了广泛的文档导出选项(LaTeX,PDF,HTML,ODT)。Emacs可以在缓冲区内显示图像,并允许您使用LaTeX语法编写数学方程式,因此您不必局限于纯文本文档。
在Python中,有pep8和pep257工具会报告缺少或格式错误的文档。用于Emacs的elpy也将抱怨缺少文档。带有reStructuredText 的Numpy docstring约定很好遵循。可以使用py.test和tox自动运行来设置使用pep8,pep257和doctest进行测试。