Just sorting the list in Sage does not work, as the object in question
has a state maintained by an external program (e.g. GAP), and messing
up this order is no fun at all.
(well, yes, one can think of maintaining the permutation used for the
sorting, etc etc, but this looks like an unnecessary kludge)
It seems to me that the right way to deal with this is to extend the
capabilities of the testing scheme so that it is able to handle sets,
not only lists.
Maybe you can write doctests in one of these forms
sage: set([output from function...]) == set([what the output is
supposed to be])
True
(or use Set instead of set?)
sage: (some known element) in [output from function]
True
sage: convert output to string and do some string comparisons on it
--
John
+1 to John's suggestion to rewrite your tests so that the lists are
sorted in a sensible way. There are many ways to do so as he pointed
out. If we can avoid it, we shouldn't change the Python doctest
framework any more than we already have (which is very minimal).
We could add a function to Sage for testing purposes, such as:
sage: strsort(v)
which would takes it input (any iterable), convert all entries to
strings, then sort, then output the result as a list. Then your
doctests would display that output.
It's good to keep in mind that doctests are meant to be viewed by
people, so tests like the above that maybe aren't so human readable
should go in the
TESTS::
section instead of the EXAMPLES:: section.
-- William
The testing scheme (the doctests part at least) is text-based. What
about
sage: tested_function() # random order
set([1, 5, 7, -3, 2, 6])
sage: tested_function() == set([1, 5, 7, -3, 2, 6])
True
- Robert
-1
> The testing scheme (the doctests part at least) is text-based. What
> about
>
> sage: tested_function() # random order
> set([1, 5, 7, -3, 2, 6])
> sage: tested_function() == set([1, 5, 7, -3, 2, 6])
> True
+1
Nick
Indeed, without this it is impossible to really test, say, a function
that
produces a matrix that is only known up to (unknown) permutations of
rows and columns.
An example of a test that is basically not possible to make
consistently, is
values()
sage/groups/class_function.py
(this function basically returns such a matrix, namely a character
table of a group, for which the
order of conj. classes etc is a priori not known)
Dima
> William,
> I think TESTS:: would be a good idea!
> Having an optional part TESTS:: where one can put more or less any
> Sage code; if TESTS:: is present,
> EXAMPLES:: is ignored, and otherwise EXAMPLES:: play the role of
> TESTS::
We already use TESTS blocks. Both should be tested if both exist.
> Indeed, without this it is impossible to really test, say, a function
> that
> produces a matrix that is only known up to (unknown) permutations of
> rows and columns.
> An example of a test that is basically not possible to make
> consistently, is
> values()
> sage/groups/class_function.py
> (this function basically returns such a matrix, namely a character
> table of a group, for which the
> order of conj. classes etc is a priori not known)
The thing to do here is something like
sage: M = x.values(); M # random permutation
[your matrix here]
then demonstrate that M has the right properties (not sure what they
are in your case, but there should be something you can do that tests
correct matrices from incorrect ones, and as well as making good tests
this kind of thing is mathematically instructive as well).
- Robert
On Jan 30, 1:46 pm, Robert Bradshaw <rober...@math.washington.edu>
wrote:
> On Jan 29, 2010, at 9:27 PM, Dima Pasechnik wrote:
>
> > William,
> > I think TESTS:: would be a good idea!
> > Having an optional part TESTS:: where one can put more or less any
> > Sage code; if TESTS:: is present,
> > EXAMPLES:: is ignored, and otherwise EXAMPLES:: play the role of
> > TESTS::
>
> We already use TESTS blocks. Both should be tested if both exist.
Is there a docstrings-like option to use in order to tell the system
not to test things in EXAMPLES:: ?
Dima
Put "# not tested" as a comment.
That said, unless there is a very, very, very good reason, everything
in EXAMPLES should get tested. It's absolutely terrible to have
examples that don't work precisely the way we say they do in the
documentation. I would definitely not positively review any code
that makes frivolous use of "# not tested".
There is also a "# random" marker that one can put on doctests. It
also should be avoided...
William
On Jan 31, 1:15 pm, William Stein <wst...@gmail.com> wrote:
> On Sat, Jan 30, 2010 at 9:10 PM, Dima Pasechnik <dimp...@gmail.com> wrote:
>
> > On Jan 30, 1:46 pm, Robert Bradshaw <rober...@math.washington.edu>
> > wrote:
> >> On Jan 29, 2010, at 9:27 PM, Dima Pasechnik wrote:
>
> >> > William,
> >> > I think TESTS:: would be a good idea!
> >> > Having an optional part TESTS:: where one can put more or less any
> >> > Sage code; if TESTS:: is present,
> >> > EXAMPLES:: is ignored, and otherwise EXAMPLES:: play the role of
> >> > TESTS::
>
> >> We already use TESTS blocks. Both should be tested if both exist.
>
> > Is there a docstrings-like option to use in order to tell the system
> > not to test things in EXAMPLES:: ?
>
> > Dima
>
> Put "# not tested" as a comment.
>
> That said, unless there is a very, very, very good reason, everything
> in EXAMPLES should get tested. It's absolutely terrible to have
> examples that don't work precisely the way we say they do in the
> documentation. I would definitely not positively review any code
> that makes frivolous use of "# not tested".
>
well, I just test what is in EXAMPLES in TESTS (as string comparison
fails here, I have to write a bit of code to test properly)
It's a bit ugly, but it's a limitation of docstinsg that is impossible
to overcome.
(Please see http://trac.sagemath.org/sage_trac/ticket/8150 for the
corresponding patch)
Dmitrii
sage: A.<a,b,c,d,e> = AbelianGroup(5,[4, 5, 5, 7, 8])
sage: b1 = a^3*b*c*d^2*e^5
sage: b2 = a^2*b*c^2*d^3*e^3
sage: b3 = a^7*b^3*c^5*d^4*e^4
sage: b4 = a^3*b^2*c^2*d^3*e^5
sage: b5 = a^2*b^4*c^2*d^4*e^5
sage: word_problem([b1,b2,b3,b4,b5],e) #random order
[[a^3*b*c*d^2*e^5, 1], [a^2*b*c^2*d^3*e^3, 1], [a^3*b^3*d^4*e^4, 3],
[a^2*b^4*c^2*d^4*e^5, 1]]
sage: ans_dict = {a^3*b*c*d^2*e^5: 1, a^2*b*c^2*d^3*e^3: 1,
a^3*b^3*d^4*e^4: 3, a^2*b^4*c^2*d^4*e^5: 1}
sage: dict( word_problem([b1,b2,b3,b4,b5],e) ) == ans_dict # we use
dict to avoid ordering problems
True
(remark: It would make sense for the function word_problem to return a
dict. This would allow:
sage: w = word_problem([b1,b2,b3,b4,b5],e)
sage: w[b3]
3
end of the remark)
On Feb 2, 8:54 pm, YannLC <yannlaiglecha...@gmail.com> wrote:
> Why don't you use something like this e.g.:
>
> sage: A.<a,b,c,d,e> = AbelianGroup(5,[4, 5, 5, 7, 8])
> sage: b1 = a^3*b*c*d^2*e^5
> sage: b2 = a^2*b*c^2*d^3*e^3
> sage: b3 = a^7*b^3*c^5*d^4*e^4
> sage: b4 = a^3*b^2*c^2*d^3*e^5
> sage: b5 = a^2*b^4*c^2*d^4*e^5
> sage: word_problem([b1,b2,b3,b4,b5],e) #random order
> [[a^3*b*c*d^2*e^5, 1], [a^2*b*c^2*d^3*e^3, 1], [a^3*b^3*d^4*e^4, 3],
> [a^2*b^4*c^2*d^4*e^5, 1]]
> sage: ans_dict = {a^3*b*c*d^2*e^5: 1, a^2*b*c^2*d^3*e^3: 1,
> a^3*b^3*d^4*e^4: 3, a^2*b^4*c^2*d^4*e^5: 1}
> sage: dict( word_problem([b1,b2,b3,b4,b5],e) ) == ans_dict # we use
> dict to avoid ordering problems
> True
>
As always, a better working solution only comes after at least one
working solution has been already presented :-)
Yes, indeed, it makes perfect sense to use dictionaries here.
Unfortunately for irreducible characters (see groups/
class_function.py patch)
reduce seems to be the only way so far :-(
> (remark: It would make sense for the function word_problem to return a
> dict. This would allow:
> sage: w = word_problem([b1,b2,b3,b4,b5],e)
> sage: w[b3]
> 3
> end of the remark)
>
yes, this is a good idea.
sage: G = GL(2,3)
sage: k.<zeta8> = CyclotomicField(8)
sage: expected = set([(3, 0, 3, 0, -1, 1, 1, -1), (1, 1, 1, 1, 1, 1,
1, 1), (1, 1, 1, 1, 1, -1, -1, -1), (2, -1, 2, -1, 2, 0, 0, 0), (4,
-1, -4, 1, 0, 0, 0, 0), (2, 1, -2, -1, 0, zeta8^3 + zeta8, -zeta8^3 -
zeta8, 0), (2, 1, -2, -1, 0, -zeta8^3 - zeta8, zeta8^3 + zeta8, 0),
(3, 0, 3, 0, -1, -1, -1, 1)])
sage: set([tuple(x.values()) for x in G.irreducible_characters()]) ==
expected
True
sage: set([tuple(x.values()) for x in G.irreducible_characters()]) ==
expected
you need tuple... just add it!
> G.irreducible_characters() is a list of lists, not a list of tuples,
> so one cannot just take set() of them.
On another note, for both this and word problem, you might want to
consider whether a list of tuples would be better to return than a
list of lists... do they need to be mutable?
- Robert
>
> On Feb 2, 10:01 pm, YannLC <yannlaiglecha...@gmail.com> wrote:
>> Maybe just using sets:
>>
>> sage: G = GL(2,3)
>> sage: k.<zeta8> = CyclotomicField(8)
>> sage: expected = set([(3, 0, 3, 0, -1, 1, 1, -1), (1, 1, 1, 1, 1, 1,
>> 1, 1), (1, 1, 1, 1, 1, -1, -1, -1), (2, -1, 2, -1, 2, 0, 0, 0), (4,
>> -1, -4, 1, 0, 0, 0, 0), (2, 1, -2, -1, 0, zeta8^3 + zeta8, -zeta8^3 -
>> zeta8, 0), (2, 1, -2, -1, 0, -zeta8^3 - zeta8, zeta8^3 + zeta8, 0),
>> (3, 0, 3, 0, -1, -1, -1, 1)])
>> sage: set([tuple(x.values()) for x in G.irreducible_characters()]) ==
>> expected
>> True
>>
>> On Feb 2, 2:25 pm, Dima Pasechnik <dimp...@gmail.com> wrote:
>>
>>
>>
>>> On Feb 2, 8:54 pm, YannLC <yannlaiglecha...@gmail.com> wrote:
>>> Unfortunately for irreducible characters (see groups/
>>> class_function.py patch)
>>> reduce seems to be the only way so far :-(
>
> --
> To post to this group, send an email to sage-...@googlegroups.com
> To unsubscribe from this group, send an email to sage-devel+...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/sage-devel
> URL: http://www.sagemath.org