Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2005
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*November
*December
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2005

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: Re: debugging

  • To: mathgroup at smc.vnet.net
  • Subject: [mg56786] Re: [mg56729] Re: [mg56716] Re: [mg56676] debugging
  • From: "E. Martin-Serrano" <EmilioMartin-Serrano at wanadoo.es>
  • Date: Fri, 6 May 2005 02:59:53 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

Sorry, I failed to send an example of how CallingFunction[] works. Here it
is.

First I define the function MinBiPartition[], which accepts several
arguments of different types and includes a "branch" to deal with errors of
the kind treated by CallingFunction[]. MinBiPartition definition includes
calls to other here no defined functions (since they are part of a larger
system)

(* this load the package with Function Call *)

Needs["GeneralServices`CallingFunctionControl`"];
 
Off[General::"spell1",General::"spell"]

(* this defines MinBiPartition[] *)

ClearAll[MinBiPartition];

MinBiPartition::"argument" = "Function call within the context [* `1` *] has
failed because it submitted the improper argument [`2`]. The name of the
function whose body wrapped the faulty call is among those in the list `3`.
Valids arguments for this call must belong to one the following types:
`4`.";

MinBiPartition[side_?SingletonListQ]:= DoNothing

MinBiPartition[side_?VoydQ]:= DoNothing

MinBiPartition[side_?SingletonQ]:= DoNothing

MinBiPartition[side_?CompleteGraphQ]:= DoNothing

MinBiPartition[side_?FakeCliqueQ]:= DoNothing

MinBiPartition[side_?SinglePairListQ]:= DoNothing

MinBiPartition[side_?ProperFlatListQ]:= DoNothing

MinBiPartition[wrong___]:=With[{stack =
Stack[_][[1]]},Message[MinBiPartition::"argument",stack,wrong,CallingFunctio
n[ToString[Hold[stack]]],FunctionDomain[MinBiPartition]];AbortProtect[Abort[
];Print["Computation will be aborted due to improper function call."]]]

(* This is a instrumental function used to test CallingFunction[]*)
 
fff[]:= Module[{},one;two;MinBiPartition["Fake Invalid Argument"];three;
four]

(* This is a another instrumental function used to test CallingFunction[]*)

Otherfff[]:= Module[{},one;two;MinBiPartition["Invalid Argument"];three;
four]

(* This makes a wrong call to fff[]*)

fff[]

(* and the rest is the result rendered by the wrong call to fff[] *)

MinBiPartition::argument: Function call within the context [*
Module[{},one;two;MinBiPartition[Fake Invalid Argument];three;four] *] has
failed because it submitted the improper argument [Fake Invalid Argument].
The name of the function whose body wrapped the faulty call is among those
in the list {fff[]}. Valid arguments for this call must belong to one the
following types:
{MinBiPartition[side_?SingletonListQ],MinBiPartition[side_?VoydQ],MinBiParti
tion[side_?SingletonQ],MinBiPartition[side_?CompleteGraphQ],\[LeftSkeleton]1
4\[RightSkeleton]\[LeftSkeleton]1\[RightSkeleton]\[LeftSkeleton]1\[RightSkel
eton]],MinBiPartition[side_?SinglePairListQ],MinBiPartition[side_?ProperFlat
ListQ],MinBiPartition[wrong___]}.

Computation will be aborted due to improper function call.

$Aborted


-----Original Message-----
From: E. Martin-Serrano [mailto:EmilioMartin-Serrano at wanadoo.es] 
To: mathgroup at smc.vnet.net
Subject: [mg56786] [mg56729] Re: [mg56716] Re: [mg56676] debugging


The lack of debugging tools is, no doubt, an issue in Mathematica.

I wrote the following utility package to deal with semantic/dynamic
debugging; mainly to control calling functions flow.

(* :Context: DFramework`DFrameworkMessage`*)
(* :Title: Design Framework Environment *)
(* :Author: E.Martin-Serrano - In Houston - Texas (USA) *)
(* :Package Version:1.0,0 ,  July 3rd, 2004  *)
(* :Mathematica Version:5.0.1 *)
(* :Copyright: Copyright  2004 *)
(* :History:Original version: July 3rd, 2004 *)
(* :Summary:  CallingFunction[stack] yields a list of functions. The meaning
of this list of functions is that described ahead. Let us have a function
'f', whose body contains a call to another function 'f1'. Let us suppose
that the call to 'f1', inside the body of 'f', fails due to an improper
parameter passing.  This failure may typically happen in situations of
uncertainty: either the system is under construction (debugging) or in
production when the parameters are produced dynamically from inputs
inherited from other functions. To identify and locate the source of the
problem, and the point of the failure, it is necessary to know three things:
1) the piece of code wrapping the point from where 'f1' was called when the
failure came up, 2) The name of the parent function 'f' owning the piece of
code wrapping the calling point to 'f1' where the failure came up, and 3)
the domain of valid parameters for the function 'f1'. The necessity of this
utility comes from the fact that any function may, in principle, be invoked
from many different points or functions in a network-like manner, so there
is not a way to know in advance which function is the culprit of a
particular failure."*)
(* :Keywords: Testing, debugging, messages *)
(* :Contents:*)
(* :Discussion: The present implementation is the first version and is
mainly meant to describe the purpose of the utility itself, yet it seems to
be working properly as far as it is currently used. The implementation
should probably be improved in a more efficient and elegant manner*)
(* :Sources: The function 'Domain' was taken from Ted Ersek's Tricks and
slighted modify to accept arguments of the form ' arg___' *)
(* :Credits: The function 'Domain[]' in its original form is due to Ted
Ersek as mentioned above. David Park has been helping me a lot with his
suggestions about systematic package developing  *)
(* :Warning: I have not performed a systematic thoroughly test *)



BeginPackage["GeneralServices`CallingFunctionControl`"]

Unprotect[Evaluate[$Context<>"*"]]

FunctionDomain::usage=
  "FunctionDomain[function] computes the valid domain of the arguments
accepted by 'function[]'."

CallingFunction::usage=
  "CallingFunction[stack] yields a list of functions. The meaning of this
list of functions is that described ahead. Let us have a function 'f', whose
body contains a call to another function 'f1'. Let us suppose that the call
to 'f1', inside the body of 'f', fails due to an improper parameter passing.
This failure may typically happen in situations of uncertainty: either the
system is under construction (debugging) or in production when the
parameters are produced dynamically from inputs inherited from other
functions. To identify and locate the source of the problem, and the point
of the failure, it is necessary to know three things: 1) the piece of code
wrapping the point from where 'f1' was called when the failure came up; 2)
The name of the parent function, 'f', owning the piece of code that wraps
the calling point to 'f1' where the failure came up; and 3) the domain of
valid parameters for the function 'f1'. The necessity of this utility comes
from the fact that any function may, in principle, be invoked from many
different points or functions in a network-like manner, so that there is not
an easy way to know in advance which function is the culprit of a particular
failure."

Begin["`Private`"]

FunctionDomain[f_]:=Module[{result},
    result=HoldForm@@{First/@DownValues[f]};
    result=result/.Verbatim[HoldPattern][e_]\[RuleDelayed]e
    ]

CallingFunction[stack_]:=
  Module[{downvalues,callingcontext,stp,index,functions},
    downvalues=
 
DownValues[#]&/@Cases[Map[ToExpression,Names[Context[]<>"*"]],_Symbol]//
        Flatten;
    callingcontext = StringDrop[stack,5];
    callingcontext  = StringDrop[callingcontext,-1];
    stp =StringPosition[#,callingcontext]&/@(ToString[#]&/@downvalues);
    index =
Table[If[stp[[i]]\[NotEqual]{},{i},{}],{i,Length[stp]}]//Flatten;
    functions =StringDrop[ ToString[First[downvalues[[#]]]],12]&/@index;
    StringDrop[#,-1]&/@functions
    ]

End[]

Protect[Evaluate[$Context<>"*"]]

EndPackage[] 

-----Original Message-----
From: Chris Chiasson [mailto:chris.chiasson at gmail.com] 
To: mathgroup at smc.vnet.net
Subject: [mg56786] [mg56729] [mg56716] Re: [mg56676] debugging

Do you mean it wasn't an error that referenced a line number? Some
errors in Mathematica do come with line numbers; I thought you had one
of those kind and were just looking for a way to display line numbers.

You could add your own type checking/debugging code that will produce
its own warning messages. That would help you locate the problem.

I usually start from the name of the function that produces an error
and tear my function apart, call by call, until I find the step
between which the output went from good to bad.

You may find ctrl+shift+b useful for this. You may also wish to make
use of the Interrupt[] , Abort[] and Throw/Catch calls.

On 5/3/05, Daniel Roy <droy at mit.edu> wrote:
> There are no line numbers in the reported bugs, of course.
> 
> On Tue, 2005-05-03 at 13:10 -0400, Chris Chiasson wrote:
> > You could load the code into the vi editor (or your favorite text
> > editor) and turn on the line numbers.
> >
> > On 5/3/05, Daniel Roy <droy at mit.edu> wrote:
> > >
> > > My question concerns debugging.  I've done googling to find a quick
> > > answer but have failed.  I'm developming large functions and without
> > > line numbers telling me where the errors occurred, its becoming very
> > > difficult to develop code quickly.  Can anyone point me in the right
> > > direction in terms of debugging multi line  (at least 50+ lines)
> > > functions?
> > >
> > > thanks,
> > > dan
> > >
> > >
> >
> >
> 
> 


-- 
Chris Chiasson
http://chrischiasson.com/
1 (810) 265-3161






  • Prev by Date: Re: Re: Re: debugging
  • Next by Date: Re: Re: letrec/named let
  • Previous by thread: Re: Re: Re: debugging
  • Next by thread: Debugging