[EMAIL PROTECTED] schrieb: > I need to create ranges that can start and end with real numbers. > Searching this newsgroup brought me to a function that I then modified > as follows: > > def myRange(iMin, iMax=None, iStep=1): Just as a sidenote: it is not common to prefix your names with its type. It could change at any time and min, max, step would be clear, too. IMO. > """Extends range to real numbers. Wherever possible, use Python's > range . > In other cases, make the behavior follow the spirit of Python's > range """ If you want to stick to the "normal" range-implementation, myRange should consider an one-argument-call as transmission of iMax. > epsilon = 1.e-8 I can't really say if your attempt using an epsilon-environment is good. I think just increasing a "counter" from iMin to iMax should be fine, achieving more precision by making computations fuzzy -- i don't know, perhaps it's very good. I wouldn't do it. If you like to care about precision, you should have a look at the `decimal module <http://docs.python.org/lib/module-decimal.html>`_. > > if iMax == None and iStep == 1: > return range(int(iMin)) > > elif type(iMin).__name__.lower() in ('int', 'long') and \ > type(iMax).__name__.lower() in ('int', 'long') and \ > type(iStep).__name__.lower() in ('int', 'long') and iStep != > 0: > return range( iMin, iMax, iStep) Ouchie! *That* is a bad one. Checking for a name of an object is neither safe nor good nor common. A better way would be directly comparing type(yourobject) with int/long/float/anytype. See http://docs.python.org/lib/comparisons.html for details on comparisons. Another way of type-checking in python is doing something like ``if isinstance(iMin, (int, long))``. Would work for subclasses, too. > > elif iMin <= iMax and iStep > 0: > return [ iMin+i*iStep for i in range( int(math.ceil((iMax - > iMin - epsilon)/iStep)) )] > > elif iMin >= iMax and iStep < 0: > return [ iMin+i*iStep for i in range(-int(math.ceil((iMin - > iMax + epsilon)/iStep)) )] > Will eat your memory. See below. > else: > raise ValueError, 'Cannot construct a range with steps of size > ' + str(iStep) + ' between ' + str(iMin) + ' and ' + str(iMax) In Python, it is common to use string interpolation instead. Like:: print 'Hello from %d to %d' % (iMin, iMax) Read `String Formatting Operations <http://docs.python.org/lib/typesseq-strings.html>`_ in the manual for details. > > > The one part of my implementation that has me a bit queasy (i.e. > works in my current application, but I can see it misbehaving > elsewhere) is the addition/subtraction of a fixed epsilon to ensure > that my rounding goes the right way. A clean implementation would > modify epsilon based on the achievable level of precision given the > particular values of iMax, iMin and iStep. I suspect this requires a > detailed understanding of the implementation of floating point > arithmetic, I think so, too. That's why it is a bad idea, IMO. > and would appreciate hearing any thoughts you might have > on gilding this lily. > > Sincerely > > Thomas Philips >
I'd recommend you to have a look into `generators <http://docs.python.org/ref/yield.html>`_, it is what `xrange <http://docs.python.org/lib/built-in-funcs.html#l2h-80>`_ uses. You don't put all numbers into your memory ("precompute them") but behave a little bit lazy and compute them whenever the user needs the next one. I expect Google to have lots of example implementations of range as a generator in python for you. :-) HTH, Stargaming -- http://mail.python.org/mailman/listinfo/python-list