Message Boards Message Boards

1
|
3556 Views
|
1 Reply
|
2 Total Likes
View groups...
Share
Share this post:

Method for limiting message output

Posted 11 years ago
I have a general question about how to limit the number of messages issued by a function, using an intermediate function (or if there is a better method that will work too). The situation is probably easiest to explain with an example:
In[58]:= isValidInputPair[x_, y_] :=   
  If[TrueQ@OddQ[x + y], True, Message[f::invld, x, y]; False]
In[59]:= f::invld = "`1` and `2` are invalid arguments";
  f[arg1_, args__] := And @@ (isValidInputPair[arg1, #] & /@ {args}) 

In some cases there will be no messages:
In[61]:= f[1, 2] 
Out[61]= True 

In other cases there will be one message:
In[62]:= f[1, 2, 3] 
During evaluation of In[62]:= f::invld: 1 and 3 are invalid arguments 
Out[62]= False 

but with larger inputs there can be a whole slew of messages:
In[65]:= f[Sequence @@ Range[10]] 
During evaluation of In[65]:= f::invld: 1 and 3 are invalid arguments 
During evaluation of In[65]:= f::invld: 1 and 5 are invalid arguments 
During evaluation of In[65]:= f::invld: 1 and 7 are invalid arguments 
During evaluation of In[65]:= General::stop: Further output of f::invld will be suppressed during this calculation. >> 
Out[65]= False 

Rather than waiting for General::stop to kick in I'd like to just collect the first message and issue it with the result, though it's important to keep track of the input values for Messages[]. I could re-work f[] so that when a message is issued the evaluation is aborted, but since I'm having this issue in a number of functions I thought there might be a better method to collect the messages.
POSTED BY: Nick Lariviere
Posted 11 years ago
One way is to Throw and Catch False values for an early exit
In[1]:= isValidInputPair[x_, y_] := If[TrueQ@OddQ[x + y], True, Message[f::invld, x, y]; False]

In[2]:= f::invld = "`1` and `2` are invalid arguments"; 
  f[arg1_, args__] := Catch[And @@ ((If[# === False, Throw[False], #] &[isValidInputPair[arg1, #]]) & /@ {args})]

In[4]:= f[Sequence @@ Range[10]]
During evaluation of In[4]:= f::invld: 1 and 3 are invalid arguments
Out[4]= False 

When I do this type of thing I usually use a Table instead to avoid nested pure functions.
In[5]:= Clear[f] 
In[6]:= f[arg1_, args__] := And@@Catch[Table[(If[# === False, Throw[False], #] &[isValidInputPair[arg1, i]]), {i, {args}}]] 

In[7]:= f[Sequence @@ Range[10]]
During evaluation of In[7]:= f::invld: 1 and 3 are invalid arguments
Out[7]= False 
POSTED BY: Nick Gaskill
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract