First time here? Check out the FAQ!

Ask Your Question
1

range, xrange and ellipsis iteration.

asked 9 years ago

Peter Luschny gravatar image

updated 2 years ago

tmonteil gravatar image

Consider the Maple lines

r := n -> (n-(n mod 2))/2:
seq(print(seq(r(n-k) + r(n+k), k = -n..n)), n=0..5);

Output:

               0
            1, 0, 1
         2, 1, 2, 1, 2
      3, 2, 3, 2, 3, 2, 3
   4, 3, 4, 3, 4, 3, 4, 3, 4
5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5

I thought that the Sage equivalent is

r = lambda n: (n-(n%2))//2
for n in range(6):
    [r(n-k) + r(n+k) for k in (-n..n)]

Unfortunately this is not the case. I get

"AttributeError: 'xrange' object has no attribute 'next'".

Is this a bug or a feature?

Preview: (hide)

Comments

A possible workaround (?) is: for n in (0..5): [r(n-k) + r(n+k) for k in (-n..n)] or as tmonteil suggests below: for n in srange(6): [r(n-k) + r(n+k) for k in (-n..n)]

Peter Luschny gravatar imagePeter Luschny ( 9 years ago )

1 Answer

Sort by » oldest newest most voted
1

answered 9 years ago

tmonteil gravatar image

updated 9 years ago

In your example n is a Python int (not a Sage integer) because it is created by the range function,. You can use srange(6) instead of range(6) in your first loop, then the ellipsis should work.

EDIT : since i am a player, i inspected further to decide whether it is a bug or a feature. In the documentation of ellipsis_iter it is claimed that the result is an iterator, and in the official Python documentation, iterators are required to provide a .next() method. With Python integers as "universe" (see below), ellipsis_iter provides an object that does not provide a .next() method:

sage: I = ellipsis_iter(int(-42),Ellipsis,int(42))
sage: I.next()
AttributeError: 'xrange' object has no attribute 'next'

Let us inspect why.

So, if you look at the source code of ellipsis_iter (see ellipsis_iter?? or the file src/sage/misc/misc.py), you will see that it uses xsrange. Now if you look at xsrange, you will see that it does something when the "universe" is ZZ, but just calls xrange Python builtin:

sage: xsrange(42)
<generator object generic_xsrange at 0x7f93417ea230>
sage: xsrange(int(42))
xrange(42)

See in the source code:

if universe is not ZZ:
    return xrange(start, end, step)

Unfortunately, xrange is of type 'xrange' and is not an iterator (though it is an iterable since you can loop over it).

sage: xsrange(42).next()
0
sage: xrange(42).next()
AttributeError: 'xrange' object has no attribute 'next'

So, it is a bug, thanks for reporting, this is now trac ticket 18538, and the fix is ready for review.

Preview: (hide)
link

Comments

Thanks tmonteil! Yes, I know, also range(-n,n+1) works. However I like the form (-n..n) much better and it would be nice if things could also be written that way. By the way, we are talking about (ellipsis_iter(-n,Ellipsis,n)) as the preparser told me.

Peter Luschny gravatar imagePeter Luschny ( 9 years ago )

As i explained, just replace for n in range(6): by for n in srange(6):, then the ellipsis (-n..n) will work as you want. I am not suggesting you to replace (-n..n) with range(-n,n+1).

tmonteil gravatar imagetmonteil ( 9 years ago )

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 9 years ago

Seen: 2,453 times

Last updated: May 29 '15