Since I was the last person to touch the digits method, I'll state my case.
Note that digits was (I think) inconsistent in this regard before my
modifications -- I believe binary was different than other bases, but I don't
recall which way.
I intentionally made 0.digits() return [] because that seems to me the most
consistent mathematical thing to do. To make 0.digits() return [0] seems
inconsistent to me because we don't pad any other number with 0's to the
left. I'm sure that one could imagine use cases where you would really want
either implementation for 0.digits().
Here's a feature I would like that you might like as well:
sage: #hypothetical code ahead
sage: 1.digits(padto=3)
[1, 0, 0]
sage: 0.digits(padto=1)
[0]
sage: 123456.digits(padto=5) # padto is only a minimum
[6, 5, 4, 3, 2, 1]
In short, the 'padto' parameter would state the minimal length of the returned
list and we would put sufficient zeros to make the list that length. This
would enable things like this (I suspect there's better ways to do this, but
this is what I always think of when I want listings of power-set-like
things):
sage: for i in srange(8): i.digits(base=2,padto=3)
[0, 0, 0]
[1, 0, 0]
[0, 1, 0]
[1, 1, 0]
[0, 0, 1]
[1, 0, 1]
[0, 1, 1]
[1, 1, 1]
So, the current returns are what occurs with padto=0.
--
Joel
> I intentionally made 0.digits() return [] because that seems to me
> the most
> consistent mathematical thing to do.
+1
david
Joel B. Mohler wrote:
|
| Since I was the last person to touch the digits method, I'll state my
case.
| Note that digits was (I think) inconsistent in this regard before my
| modifications -- I believe binary was different than other bases, but
I don't
| recall which way.
|
| I intentionally made 0.digits() return [] because that seems to me the
most
| consistent mathematical thing to do. To make 0.digits() return [0] seems
| inconsistent to me because we don't pad any other number with 0's to the
| left. I'm sure that one could imagine use cases where you would
really want
| either implementation for 0.digits().
|
I guess this is a question of convention, and depends on how you think
of "digit":
(1) a digit is a symbol used to construct representations of numbers,
and so the base 10 digits are: "0", "1", ..., "9". In this case,
0.ndigits() should return 1 and 0.digits() should return [0]
(2) when writing an integer n in base b, you compute a b-adic expansion
n = d_0 + d_1*b^1 + d_2*b^2 + ... + d_k b^k
with d_k nonzero; you call the d_i the "digits" of a. Then 0 *has no
such expansion*, therefore 0.digits() should return [] and 0.ndigits()
should return 0.
I used to be very much in favor of option (1), but now that I actually
thought about it for 30 seconds, it doesn't really matter to me as long
as we document the chosen convention properly, and we are consistent.
Note that at the moment 0.digits() does (2) and 0.ndigits() does (1),
which is really bad.
Alex
- --
Alexandru Ghitza
Assistant Professor
Department of Mathematics
Colby College
Waterville, ME 04901
http://bayes.colby.edu/~ghitza/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFH9Ou6dZTaNFFPILgRAlgJAJ4hBj/GR1NdxgkXxIXEtoeT12ry4gCgjgYq
3DDU6zKocIuQTlNHoiCL3s0=
=g8+f
-----END PGP SIGNATURE-----
Yes, this is very bad. I was not aware of the ndigits convention until after
the digits patch I wrote was included. On this topic, we also need a vote
about digits/ndigits disagreement about the defaulted base. One defaults to
base 2 and the other to base 10.
I vote that they both default to base 10.
Somewhat related: The 'bits' and 'ndigits(base=2)' are redundant. This
violates the python mantra (but, I personally am not entirely fond of the
one-way-to-do-things mantra). I think that 'bits' should be 'nbits'.
Sorry, this is a bit of thread-jacking.
I'd be happy to write a patch tweaking a few of these things if there were
consensus about the tweaking.
--
Joel
I went to see what the degree of the 0 polynomial is in Sage,
expecting one of : -Infinity, Undefined, and found it is -1. Well ok,
that is one convention, but please do not try to convince me that it
is anything other than a convention. (I prefer -Infinity but am not
fussy).
John
Certainly, 0 is a special case (and the example of string is crystal clear).
However, the question is which way more users of 'digits' want the results.
Not having a list of uses (and future uses!) of 'digits' on hand at the
moment, it's a bit of a shot in the dark which special casing might be
preferred. I think that the most likely correct answer for general cases is
the empty list (after all, we'd like to not pass on the special case to the
end-user more than we have to.)
--
Joel
Of course we could restrict the ndigits() function to positive integers only...
John
I'll try anyways to at least convince you that there was a
good reason at the time when I chose that convention.
I defined degree that way specifically for consistency
with Magma:
> R<x> := PolynomialRing(RationalField());
> Degree(R!0);
-1
I implemented the first version of polynomials in Sage in the very
early days of Sage, and for quite a long time consistency with
Magma was a guiding design constraint for Sage (i.e., if a lot
more people hadn't got involved, Sage/Magma could very well
have been somewhat like Octave/Matlab).
Also, Sage didn't have any notion of infinity when I first
implemented polynomials...
--William
John