使用 Mathematica 编写小型或大型代码时如何调试?工作台?mma调试器?或者是其他东西? [英] How to debug when writing small or big codes using Mathematica? workbench? mma debugger? or something else?

查看:35
本文介绍了使用 Mathematica 编写小型或大型代码时如何调试?工作台?mma调试器?或者是其他东西?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 mathkb.com,我发现了一个有趣的帖子Mathematica 调试器的另一篇评论"(by berniethejet)谈论在 wolfram 工作台中的调试.

At mathkb.com, I found a interesting post "Another review of Mathematica's debugger" (by berniethejet) talking about debugging in wolfram workbench.

http://www.mathkb.com/Uwe/Threads/List.aspx/mathematica/20986

我认为这是一个值得讨论的好问题,我想听听使用工作台的一些经验,即使我从未接触过工作台.

I think this is a good question worth discussing and I would like hear some experiences of using workbench, even though I've never touched workbench.

  1. 工作台是一个真正的调试器,但是观察者?它的优势是什么数学?
  2. 你如何调试当你写大或小代码?mabye 工作台用于调试小代码,而 mma 调试器用于大代码?
  3. 对于轻度和重度数学用户的调试有什么建议吗?

推荐答案

当您以有状态的风格(变量、赋值等)编程时,调试器通常更有用——至少我的经验是这样.对于惯用的 Mathematica 编程(基于函数/规则),某些版本的 Print 语句至少同样有效.您可以查看这篇帖子了解一些调试打印实用程序的变体.我将把我的版本从 这个 Mathgroup帖子.

Debuggers are generally more useful when you program in the stateful style (variables, assignments, etc) - at least that has been my experience. For idiomatic Mathematica programming (functional/rule-based), some versions of Print statements are at least as effective. You may look at this post for some variants of debug print utility. I will throw in my version taken from this Mathgroup post.

SetAttributes[ShowIt, HoldAll];
ShowIt[code_] :=
  Module[{y},
    Print[ToString[Unevaluated[code]], " = ", y = code];
    y]; 

这个想法是你可以将这样的函数调用插入到函数调用的管道"中——它打印值,然后将它传递给下一个(周围)函数.举个简单的例子:

The idea is that you can insert such function call into a "pipe" of function calls - it prints the value but then passes it to the next (surrounding) function. As a simple example:

In[29]:= Map[#^2&,ShowIt@Select[Range[10],EvenQ]]
During evaluation of In[29]:= Select[Range[10], EvenQ] = {2,4,6,8,10}

Out[29]= {4,16,36,64,100}

这在大多数情况下应该可以正常工作(可能除了那些周围函数保存其参数并对其进行非平凡操作的情况).这种方法在 Mathematica 中非常有效的原因之一是函数式编程导致程序中(几乎)每个部分本身都有意义 - 因为一个函数的结果通常直接传递给封闭函数.

This should work fine in most cases (except possibly those where the surrounding function holds its arguments and acts on them non-trivially). One of the reasons that this approach is very effective in Mathematica is that functional programming leads to programs in which (almost) every piece makes sense by itself - since the result of one function is typically passed directly to the enclosing function.

也就是说,您当然可以在交互式会话中和 WorkBench 中使用调试器,使用Debug As Mathematica"机制.虽然我自己经常使用 WorkBench,但我从来没有觉得这是必要的,但是 YMMV.

That said, you can certainly use the debugger, both within interactive session and in the WorkBench, using "Debug As Mathematica" regime. While I use WorkBench a lot myself, I never found this necessary, but YMMV.

另一个非常有用的工具是内置的跟踪命令.我建议阅读有关它的文档 - 它有许多高级选项,可以自定义以提供很多帮助.我将举一个简单但不平凡的例子:跟踪归并排序算法的执行,使用以下(简单的)实现:

Another great facility that helps a lot is a built-in Trace command. I recommend reading the documentation on it - it has a number of advanced options and can be customized to help a great deal. I will give one simple but non-trivial example: tracing the execution of the mergesort algorithm, with the following (simplistic) implementation:

Clear[merge];
merge[{}, {x__}] := {x};
merge[{x__}, {}] := {x}
merge[{x__?NumericQ}, {y__?NumericQ}] /; First[{x}] <= First[{y}] := 
  Flatten[{First[{x}], merge[Rest[{x}], {y}]}];
merge[{x__?NumericQ}, {y__?NumericQ}] := merge[{y}, {x}];

Clear[mergesort];
mergesort[x : {} | {_}] := x;
mergesort[x : {__?NumericQ}] := 
 With[{splitlen = IntegerPart[Length[x]/2]}, 
   merge[mergesort[Take[x, splitlen]], mergesort[Drop[x, splitlen]]]]

我们将采用一个非常小的输入列表,只是为了减少输出的长度:

We will take a very small input list, just to reduce the length of the output:

In[41]:= testlst = RandomInteger[10, 5]

Out[41]= {0, 6, 9, 8, 8}

您可以只使用 Trace[mergesort[testlst]];,但输出不是很容易阅读,因为它包含所有步骤.通过使用

You could just use Trace[mergesort[testlst]];, but the output is not very easy to read, since it contains all the steps. By using

In[42]:= Trace[mergesort[testlst],_mergesort]

Out[42]= {mergesort[{0,6,9,8,8}],{mergesort[{0,6}],{mergesort[{0}]},
{mergesort[{6}]}},{mergesort[{9,8,8}],{mergesort[{9}]},{mergesort[{8,8}],
{mergesort[{8}]},{mergesort[{8}]}}}}

您可以非常清楚地了解递归函数调用.您可以更深入地跟踪 merge 函数的动态.为此,您必须处理 Trace 的结果(这也是一个 Mathematica 表达式!):

You get a very clear picture of recursive function calls. You can go deeper and trace the dynamics of merge function. For that, you have to process the result of Trace (which is also a Mathematica expression!):

In[43]:= 
Cases[Trace[mergesort[testlst],_merge],merge[x__List]/;FreeQ[{x},mergesort]:> 
 HoldForm[merge[x]],Infinity]

Out[43]= {merge[{0},{6}],merge[{},{6}],merge[{8},{8}],merge[{},{8}],
merge[{9},{8,8}],merge[{8,8},{9}],merge[{8},{9}],merge[{},{9}],merge[{0,6},
{8,8,9}],merge[{6},{8,8,9}],merge[{},{8,8,9}]}

最后一个示例说明,即使很难直接配置 Trace 以过滤掉不需要的执行步骤,也可以简单地使用以下方法对 Trace 的结果进行后处理标准意味着 Mathematica 提供表达式解构(例如 Cases).

This last example illustrates that, even when it is hard to configure Trace directly to filter out unwanted execution steps, one can simply post-process the results of Trace using standard means that Mathematica provides for expression destructuring (such as Cases).

我还要提到 Mathematica 的专家用户和顾问 David Bailey 编写了一个包 DebugTrace,它应该是一个替代调试器.我还没有机会尝试它,但我相信它值得一试.

Let me also mention that an expert Mathematica user and consultant David Bailey wrote a package DebugTrace, which is supposed to be an alternative debugger. I did not have a chance yet to try it, but I am sure it is worth the try.

最后,虽然这与调试没有直接关系,但 WorkBench 有一个集成的单元测试框架 MUnit,我发现它非常有用.它在精神上类似于其他语言中众所周知的单元测试框架,例如 Java 的 JUnit.对于大规模开发,这可能是一个真正的帮助.

Finally, while this is not directly related to debugging, WorkBench has an integrated unit testing framework MUnit, which I found very useful. It is similar in spirit to well-known unit-testing frameworks in other languages, such as JUnit for Java. For large-scale development, this can be a real help.

关于 WorkBench 的使用,我想说,除了最小的项目(甚至是它们)之外,将它用于任何事情确实是值得的.它基于 Eclipse,您将获得相同的好东西,例如带有代码突出显示的编辑器、转到函数定义"功能、导航、搜索、CVS/SVN 集成等.同时,您没有在交互性方面几乎失去了任何东西 - 当在作为 Mathematica 运行"机制下工作时,您仍然可以在链接到 WorkBench 的交互式 Mathematica 会话中开发新功能.对于涉及许多包的大型项目,我认为没有任何理由不使用它.

Regarding the uses of WorkBench, I'd say that it really pays off to use it for anything except the smallest projects (or even for them). It is based on Eclipse, and you get the same nice things, such as the editor with code highlighting, "go to function definition" capability, navigation, search, CVS/SVN integration, etc. At the same time, you don't lose almost anything in terms of interactivity - you can still develop the new functionality in the interactive Mathematica session linked to WorkBench when working in the "Run as Mathematica" regime. For larger projects involving many packages, I just don't see any reason not to use it.

这篇关于使用 Mathematica 编写小型或大型代码时如何调试?工作台?mma调试器?或者是其他东西?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆