Policy regarding the output of a standard Sage function

47 views
Skip to first unread message

Rolandb

unread,
Dec 5, 2014, 9:52:20 AM12/5/14
to sage-s...@googlegroups.com
Hi, please look at the following example.

sage: print two_squares(3437458237428)
Traceback (most recent call last):
...
ValueError: 3437458237428 is not a sum of 2 squares

The ouput is an error message. Thus if I want to test several cases, I have to check each case like:

sage: for k in xrange(10):
...       try:
...           print two_squares(3437458237428-k), 3437458237428-k
...       except:
...           pass
(519651, 1779725) 3437458237426

Why is the output not someting like []? 

This seems (to me) more natural, and as Python skips automatically an empty list, programming is easier, lines are shorter and more readable IMHO. It is also faster.

My question is whether there are good reasons to raise a valueError message as output?

Roland

kcrisman

unread,
Dec 5, 2014, 10:38:57 AM12/5/14
to sage-s...@googlegroups.com
Hmm, this is a fairly old function, if I recall correctly, implemented relatively early on.    There may be some discussion from where it was upgraded at http://trac.sagemath.org/ticket/16308 or http://trac.sagemath.org/ticket/16374 (I cannot find the original ticket, which surprises me).

So if you are interested in doing this, I would recommend opening a ticket and cc:ing the people involved on those tickets.  I feel like your question is good, though one could certainly say this is a ValueError like dividing by zero.

William Stein

unread,
Dec 5, 2014, 10:54:16 AM12/5/14
to sage-support
On Fri, Dec 5, 2014 at 7:38 AM, kcrisman <kcri...@gmail.com> wrote:
> Hmm, this is a fairly old function, if I recall correctly, implemented
> relatively early on. There may be some discussion from where it was
> upgraded at http://trac.sagemath.org/ticket/16308 or
> http://trac.sagemath.org/ticket/16374 (I cannot find the original ticket,
> which surprises me).
>
> So if you are interested in doing this, I would recommend opening a ticket
> and cc:ing the people involved on those tickets. I feel like your question
> is good, though one could certainly say this is a ValueError like dividing
> by zero.

I certainly think the design as it is now is extremely consistent with
the rest of Sage and with standard Python programming practices.

There are certainly other programming languages and libraries where
exceptions are not commonly used, and where it is common for functions
to return arbitrary made-up (hopefully documented) values to indicate
errors. That's just not the convention at all in Python.

Just a technical point. When you say "The output is an error
message." that is not really technically correct (at least if I
replace "output" by "returns"). The function doesn't return
anything; instead it raises an exception during execution.

Here's a function you can use to convert functions in Sage to ones
that have the property you want:

def no_except(f, err):
def g(*args, **kwds):
try:
return f(*args, **kwds)
except:
return err
return g


# Then:

f = no_except(two_squares, [])

for k in xrange(10):
print f(3437458237428-k), 3437458237428-k

# outputs:

[] 3437458237428 [] 3437458237427 (519651, 1779725) 3437458237426 []
3437458237425 [] 3437458237424 [] 3437458237423 [] 3437458237422 []
3437458237421 [] 3437458237420 [] 3437458237419

See [1]

-- William

[1] https://cloud.sagemath.com/projects/4a5f0542-5873-4eed-a85c-a18c706e8bcd/files/support/2014-12-05%20two%20squares.sagews


>
>
> On Friday, December 5, 2014 9:52:20 AM UTC-5, Rolandb wrote:
>>
>> Hi, please look at the following example.
>>
>> sage: print two_squares(3437458237428)
>> Traceback (most recent call last):
>> ...
>> ValueError: 3437458237428 is not a sum of 2 squares
>>
>>
>> The ouput is an error message. Thus if I want to test several cases, I
>> have to check each case like:
>>
>> sage: for k in xrange(10):
>> ... try:
>> ... print two_squares(3437458237428-k), 3437458237428-k
>> ... except:
>> ... pass
>> (519651, 1779725) 3437458237426
>>
>>
>> Why is the output not someting like []?
>>
>> This seems (to me) more natural, and as Python skips automatically an
>> empty list, programming is easier, lines are shorter and more readable IMHO.
>> It is also faster.
>>
>> My question is whether there are good reasons to raise a valueError
>> message as output?
>>
>> Roland
>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-support" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-support...@googlegroups.com.
> To post to this group, send email to sage-s...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sage-support.
> For more options, visit https://groups.google.com/d/optout.



--
William Stein
Professor of Mathematics
University of Washington
http://wstein.org

Rolandb

unread,
Dec 5, 2014, 4:56:54 PM12/5/14
to sage-s...@googlegroups.com
Dear William, 

Thanks for your reply and thoughtful example.

It is not obvious (for non-experts) that this is the elegant and preferred route. It would be nice if this 'solution' was mentioned somewhere. 

As part of the function, or when an ValueError is raised, or on a Quick Reference Card, or no_except becomes a standard function or ...

Roland

Op vrijdag 5 december 2014 16:54:16 UTC+1 schreef William:

kcrisman

unread,
Dec 5, 2014, 11:39:10 PM12/5/14
to sage-s...@googlegroups.com
It is not obvious (for non-experts) that this is the elegant and preferred route. It would be nice if this 'solution' was mentioned somewhere. 


This could be something to put in the Sage developer manual under conventions.
 
As part of the function, or when an ValueError is raised, or on a Quick Reference Card, or no_except becomes a standard function or ...

 
Also, to be fair, we certainly don't always raise an error when a solution to something doesn't exist.  Such as in "solve()".  It's a fine line between deciding that user input error means anything can happen (Pari's usual attitude) and that every single user input error possible must be caught (nice idea but very, very time-consuming to implement).

I think in this case because 

> Write the integer n as a sum of two integer squares if possible;

and it doesn't give a full list of *all* ways to do so, the ValueError is appropriate.  But if it returned a list of all such squares (warning: don't try this at home), then an empty list would make sense.  Does that seem like a reasonable argument?  It's true that Python-based projects sometimes go very far in the "explicit is better than implicit" direction than is healthy ;-)

- kcrisman

Jeroen Demeyer

unread,
Dec 6, 2014, 4:54:10 AM12/6/14
to sage-s...@googlegroups.com
On 2014-12-06 05:39, kcrisman wrote:
> I think in this case because
>
> > Write the integer n as a sum of two integer squares if possible;
>
> and it doesn't give a full list of *all* ways to do so, the ValueError
> is appropriate. But if it returned a list of all such squares (warning:
> don't try this at home), then an empty list would make sense. Does that
> seem like a reasonable argument?
Absolutely, consider the following analogy:

sage: GF(5)(3).sqrt(extend=False)
[...]
ValueError: self must be a square

sage: GF(5)(3).sqrt(extend=False, all=True)
[]

Jeroen Demeyer

unread,
Dec 6, 2014, 4:55:04 AM12/6/14
to sage-s...@googlegroups.com
On 2014-12-05 16:53, William Stein wrote:
> I certainly think the design as it is now is extremely consistent with
> the rest of Sage and with standard Python programming practices.
Yes, see also
https://docs.python.org/2/glossary.html#term-eafp
Reply all
Reply to author
Forward
0 new messages