gpt4 book ai didi

wolfram-mathematica - 使用 Mathematica 编写小型或大型代码时如何调试?工作台? mma 调试器?还是别的什么?

转载 作者:行者123 更新时间:2023-12-04 00:10:36 26 4
gpt4 key购买 nike

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

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

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

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

    当您以有状态风格(变量、赋值等)进行编程时,调试器通常更有用 - 至少这是我的经验。对于惯用的 Mathematica 编程(基于函数/规则),某些版本的 Print声明至少同样有效。你可以看看this发布一些调试打印实用程序的变体。我会加入我从 this 中获取的版本数学组帖子。

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

    这个想法是你可以将这样的函数调用插入到函数调用的“管道”中——它打印值,然后将它传递给下一个(周围)函数。作为一个简单的例子:
    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 中非常有效的原因之一是函数式编程导致程序中(几乎)每个部分本身都有意义 - 因为一个函数的结果通常直接传递给封闭函数。

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

    另一个有很大帮助的很棒的设施是内置的 Trace命令。我建议阅读有关它的文档 - 它有许多高级选项,可以自定义以提供很多帮助。我将举一个简单但不平凡的例子:跟踪归并排序算法的执行,使用以下(简单的)实现:
    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]]]]

    我们将采用一个非常小的输入列表,只是为了减少输出的长度:
    In[41]:= testlst = RandomInteger[10, 5]

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

    您可以使用 Trace[mergesort[testlst]]; ,但输出不是很容易阅读,因为它包含所有步骤。通过使用
    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 表达式!):
    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 )。

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

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

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

    关于wolfram-mathematica - 使用 Mathematica 编写小型或大型代码时如何调试?工作台? mma 调试器?还是别的什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6167291/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com