Thanks to everyone who responded to my comments about one-offset arrays in Python. I understand much better now why zero-offset arrays are a good choice for Python. For the reasons already discussed (mostly ease of translating one-offset algorithms), one-offset arrays would nevertheless be useful in certain situations, so I went ahead and wrote a class for a one-offset array. It ended up being a somewhat bigger job than I expected, and since it is rather too much material for a mailing-list submission I created a web site for it. Anyone who is interested in this topic please have a look: http://www.physics.ubc.ca/~mbelab/python/arrayone/index.html I'd love some feedback along the following lines: 1. There are 4 outstanding problems/bugs which I could identify but was unable to fix. Most of these seem to be due to limitations of the UserArray class, but they could also be due to limitations of the programmer. None of these problems make the class unusable. One of them is the issue which Travis identified about functions taking UserArrays but returning standard arrays. It would be nice if the resulting discussion led to something be done... Any suggestions for fixing the other 3 issues would be most welcome. 2. I would like this module to be as accessible as possible to others, particularly those who are just getting started with Python and may therefore be especially encumbered with one-offset baggage. How can I do this? Submit it to a Python resource such as the Vaults of Parnassus? Get people to link to my web page? Does someone with a more prominant website want to volunteer to host it? Is there any possibility of having it included eventually with Numerical Python or Scientific Python? Probably some people will consider it too trivial to include, but I found it less trivial than I expected once all the cases were covered - and there are still the 4 outstanding issues. (Yes the code sucks! Suggestions for improvement are most welcome!) Why make people reinvent the wheel? People coming from MatLab for example might be inclined to give up and go back to MatLab. Eric P.S. In case anyone is interested in the outstanding problems but for some reason doesn't want to or can't visit the web site, here are the summaries: Problem 1 --------- Description for loops don't work with variables of type arrayone Example X=arrayone((1,2,3)) for item in X: print item This just generates an error. Reason In Python, a for loop works by starting at x(0) and incrementing until an out-of-bounds error occurs. arrayone types have no 0 element. Work-around: Cast to type array in for loops. For example X=arrayone((1,2,3)) for item in array(X): print item Possible solutions: Is it possible to "overload" "for" so that it behaves differently for arrayone type? Problem 2 --------- Description Slicing an arrayone from 0 doesn't generate an error but it should. Example: X=arrayone((1,2,3)) X[0:3] This returns ArrayOne.arrayone([1, 2, 3]) instead of an error. Reason X[:3] results in a call to __getslice__ with low=0. This cannot be distinguished from X[0:3]. Therefore in order to deal correctly with the X[:] case, we have to assume that low=0 means an unspecified low. Work-around If you don't trust your code, you have to implement specific checking for this condition before slicing. Possible solution If it was possible to get access to the unparsed input (literally '0:3' for example), this could be fixed. Problem 3 --------- Description Negative subscripts return a slice offset by -1 from the expected result. Example X=arrayone((1,2,3,4)) X[-3:-2] This returns ArrayOne.arrayone([1, 2]) instead of ArrayOne.arrayone([2, 3]). Reason X[-3:-2] in the above example results in a call to __getslice__ with low=1, high=2, which cannot be distinguished from X[1:2]. Work-around Don't use negative index slicing with arrayone types. Possible solution: If had access to unparsed input, could fix this. Problem 4 --------- Description Functions which take arrayone arguments return type array. Work-around Have to cast back into arrayone, for example: Y=arrayone(somefunc(X)) Possible solution See http://www.geocrawler.com/lists/3/SourceForge/1329/0/6505926
Hi Eric, Here are some comments on the problems you identify.
Problem 1 ---------
Description for loops don't work with variables of type arrayone
Soon (Python 2.2?) you will be able to use the new iterator protocol to do this correctly. So target the iterator protocol and this will begin to work as people begin to upgrade.
Problem 2 ---------
Description Slicing an arrayone from 0 doesn't generate an error but it should.
I was going to suggest removing __getslice__, and only using __getitem__. However, the slices recieved by __getitem__ *sometimes* gets their first value filled in with zero (in the same cases that __getslice__ is called) instead of None. I regard this as a bug/misfeature and I just reported it on sourceforge.
Problem 3 ---------
Description Negative subscripts return a slice offset by -1 from the expected result.
This one _should_ be fixable just by removing __getslice__ and working with __getitem__ only. (getitem is called instead of getslice). However it fails for the same reason that this fix fails for problem 2. Mumble. Note that both fixes work fine if you always include the second colon. One approach would be to do all [] operations in getitem and have getslice raise an error. This would force your users to always use a[-3:-2:] instead of a[-2:-2]. The former can be made to work since it calls getitem with the raw values [slice(-3,-2,None)] as opposed to munging them like the latter does. -tim
This is just a followup to my earlier message. The getitem issues I identify there are fixed in Python 2.2, if you use new style class (inherit from object). So, problems 1-3 can be fixed in Python 2.2. It seems that problem 4 could be fixed fairly easily in the python layer by writing wrapper functions in Numeric.py. For example: def cos(a): r = umath.cos(a) if isinstance(a, UserArray): r = a.__class__(r) return r This would be potentially a bit tedious, but straightforward. -tim
participants (2)
-
Eric Nodwell
-
Tim Hochberg