4

I have been looking at some of the questions regarding error handling but i think my problem is unique.

I am running a Do-loop. I get errors only for certain values of the loop variable due to the nature of the problem.

Example

a = {1, 2, 3, 4, 5};
b = {2, 0, 40, 5, 0};
x = {};
Do[Append[x, a[[i]]/b[[i]]], {i, 1, 5}]

At iterations 2 and 5 the above code gives the error message

Power::infy: Infinite expression 1/0 encountered. >>

I want to know at which index value an error occurs -- any error, not only the particular error given it the example -- and I want to store those values in a variable. I have looked at documentations for Check, Catch, etc., but I couldn't see how to use them. Is there a way to do this?

EDIT

My program is pretty much complex than the above example and has to use loops. So an answer with loops is appreciable.

no-one
  • 1,243
  • 9
  • 14
  • Can't you get an If[] statement in there? Loops are discouraged in Mathematica though... – Feyre Jul 09 '16 at 14:14
  • You certainly meant AppendTo instead of Append. But anyways, as @Feyre said, use Table instead of Do. And read the documentation more thoroughly. – István Zachar Jul 13 '16 at 15:33

5 Answers5

6

Here's one way to do it:

a = {1, 2, 3, 4, 5}; b = {2, 0, 40, 5, 0}; 
x = Quiet[Table[a[[i]]/b[[i]], {i, 1, 5}]];
Position[x, ComplexInfinity]
{{2}, {5}}

Basically, ans contains the values plus the errors, which in this case are ComplexInfinity. You can locate the errors using Position, in this case, at positions 2 and 5. If you want to check for any old error, you can use Check:

a = {1, 2, 3, 4, 5}; b = {2, 0, 40, 5, 0};
x = Quiet[Table[Check[a[[i]]/b[[i]], $Failed], {i, 1, 5}]];
Position[x, $Failed]

Check returns the first argument (in this case a[[i]]/b[[i]] if there is no error and returns the second argument (in this case the symbol error) if there is an error. Thanks to J.M. for suggesting using the already defined symbol $Failed.

bill s
  • 68,936
  • 4
  • 101
  • 191
4

Another way (see How to catch complete error message information, including the message text as it would be printed? for more ways to hack messages): This works because i is effectively Block[]-ed by Do[].

badindices = {};
$MessagePrePrint = (AppendTo[badindices, i]; #) &;

Do[Append[x, a[[i]]/b[[i]]], {i, 1, 5}]

$MessagePrePrint = Automatic;
badindices

(*  {2, 5}  *)

As function for running code: This collects the value of an expression expr at the time a message is generated.

SetAttributes[checkrun, HoldAll]
checkrun[code_, expr_] :=
 Module[{exprlist = {}, res},
  $MessagePrePrint = (AppendTo[exprlist, expr]; #) &;
  res = code;
  $MessagePrePrint = Automatic;
  {res, exprlist}
  ]

Example:

i = 100;  (* to show  i  is  Block[]-ed *)
checkrun[
 Do[Append[x, a[[i]]/b[[i]]], {i, 1, 5}]
 , i]

(*  {Null, {2, 5}}  *)
Michael E2
  • 235,386
  • 17
  • 334
  • 747
3

In case you want to use Quiet and need to know which error messages were generated during the evaluation, you can use $MessageList. Starting from your code:

Module[{errors = Internal`Bag[{}], mess, a, b, x}, 

    a = {1, 2, 3, 4, 5};
    b = {2, 0, 40, 5, 0};
    x = {};

    Block[{$MessageList = {}},
       Do[
          Quiet[
             AppendTo[x, a[[i]] / b[[i]]];
             mess = $MessageList
          ];
          If[mess =!= {},
             Internal`StuffBag[errors, i -> mess];
             mess = $MessageList = {}
          ],
          {i, 1, 5}
       ];
       {x, Internal`BagPart[errors, All]}
    ]

]

This will evaluate to:

(*
{{1/2, ComplexInfinity, 3/40, 4/5, ComplexInfinity}, 
 {2 -> {Power::infy}, 5 -> {Power::infy}}
}
*)

I am using a bag (with Internal`Bag, Internal`StuffBag, Internal`BagPart), but this can be replaced by lists or associations with the appropriate functions for filling them.

2

Check is the function supplied with Mathematica for doing what you request. Here is how it can be used in your situation.

a = {1, 2, 3, 4, 5};
b = {2, 0, 40, 5, 0};
Quiet @ Module[{errs = {}, vals},
  vals =
    Table[Check[a[[i]]/b[[i]], AppendTo[errs, i]; Nothing], {i, 5}];
  {vals, errs}]

{{1/2, 3/40, 4/5}, {2, 5}}

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
  • This seems, as you suggest, a very natural way. For other users, a couple of remarks to show how it can be adapted: (1) It works with Do if one's use-case is not to generate a Table. One can omit Nothing, in this case. (2) One can add res to the Module and use Check[res = a[[i]]/b[[i]], AppendTo[errs, i]; res] to get a table of all results, including the erroneous ones. (Upvoted earlier.) – Michael E2 Jul 11 '16 at 14:53
0

You may use Check and $MessageList.

x = MapThread[Check[#1/#2, Last@$MessageList] &, {a, b}]
(* {1/2, HoldForm[Power::infy], 3/40, 4/5, HoldForm[Power::infy]} *)

Indices of errors can be obtained by:

errs = Position[x, HoldForm[MessageName[__]]]
(* {{2}, {5}} *)

and extracted by:

Extract[x, errs]
(* {HoldForm[Power::infy], HoldForm[Power::infy]} *)

The above is easily converted for loops if you really really need that.

Hope this helps.

Edmund
  • 42,267
  • 3
  • 51
  • 143