<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Jan 8, 2015 at 8:01 AM, Todd <span dir="ltr"><<a href="mailto:toddrjen@gmail.com" target="_blank">toddrjen@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><p dir="ltr">Currently, the range class is limited to integers.  However, in many applications, especially science and mathematics, ranges of float values are the norm. </p></div></div></div></div></div></div></blockquote><div>almost -- see below.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><p dir="ltr"> </p>
<p dir="ltr"> So it would be nice to have a float equivalent of the existing range class.<br></p></div></div></div></div></div></div></blockquote><div>+1 </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><p dir="ltr"></p><p dir="ltr"></p></div></div></div>The second approach is to create a new class that handles floating-point ranges </div></div></div></blockquote><div><br></div><div>I think this is the way to go, but not for the same reasons you gave.</div><div><br></div><div>from numpy experience: numpy provides an arange() ("array range", so names back in the days of import *) with integer inputs is is essentially the same as the py2 range() function -- i.e. creates a 1-d numpy array of integers using start, stop, step.</div><div><br></div><div>Called with floating point arguments, it does much the same thing, but with floats, and, of course, start, stop and step need not be integers -- but here's the rub:</div><div><br></div><div>it does  this in the naive way: starting with start, continuing to add step, until the value is >= stop, at which point it terminates without including that last value. This is fine and dandy for integers, but is a mess with floats, due to rounding and binary storage under the hood (i.e floats can not precisely represent common base-10 steps). This is particularly a problem when you ant a particular end point to be included, you then need to increase stop to a bit more than you want, so as to make sure it gets included, but then you can accidentally get one too many.</div><div><br></div><div>This is almost never what people really want, though it does work as expected most of the time -- that most of the time is the catch -- future bugs lurking.</div><div><br></div><div>So: the accepted practice in numpy (and often espoused to newbies on the mailing list) is to not use arange() for floats. Instead, the "linspace()" function is recommended. This function returns evenly spaced numbers over a specified interval, guaranteeing that you get the start an end points you want included. It has optional arguments that let you define the spacing in various ways, but the key is that the algorithms are designed to give the user what is expected,  regardless of floating point nuance.</div><div><br></div><div>Anyway, if such an object were to be added to the pyton standard libary, it should be more like the numpy linspace(), rather than range.</div><div><br></div><div>-Chris</div><div><br></div><div><br></div><div>linspace docstring::</div><div>---------------------------</div><div><div>Return evenly spaced numbers over a specified interval.</div><div><br></div><div>Returns `num` evenly spaced samples, calculated over the</div><div>interval [`start`, `stop` ].</div><div><br></div><div>The endpoint of the interval can optionally be excluded.</div><div><br></div><div>Parameters</div><div>----------</div><div>start : scalar</div><div>    The starting value of the sequence.</div><div>stop : scalar</div><div>    The end value of the sequence, unless `endpoint` is set to False.</div><div>    In that case, the sequence consists of all but the last of ``num + 1``</div><div>    evenly spaced samples, so that `stop` is excluded.  Note that the step</div><div>    size changes when `endpoint` is False.</div><div>num : int, optional</div><div>    Number of samples to generate. Default is 50.</div></div><div><div>endpoint : bool, optional</div><div>    If True, `stop` is the last sample. Otherwise, it is not included.</div><div>    Default is True.</div><div>retstep : bool, optional</div><div>    If True, return (`samples`, `step`), where `step` is the spacing</div><div>    between samples.</div><div>dtype : dtype</div><div>    The type of the output array.  If `dtype` is not given, infer the data</div><div>    type from the other input arguments.</div><div><br></div><div>    .. versionadded:: 1.9.0</div><div><br></div><div>Returns</div><div>-------</div><div>samples : ndarray</div><div>    There are `num` equally spaced samples in the closed interval</div><div>    ``[start, stop]`` or the half-open interval ``[start, stop)``</div><div>    (depending on whether `endpoint` is True or False).</div><div>step : float (only if `retstep` is True)</div><div>    Size of spacing between samples.</div></div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div>(perhaps called "frange") and/or a new class that handles duck-typed ranges (perhaps called "drange").  However, there isn't really a good place right now to put these as far as I can see.<br></div></div></div></blockquote><div><br></div><div><br></div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><br></div>The third approach is to create a new module for various range classes.  For example there could be a float range, a datetime range, a decimal range, a duck-typed range, an abstract base class for making new range classes, etc.  However, this is a lot more work (although it wouldn't need to all be done at one time).<br></div><br></div>
<br>_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/codeofconduct/</a><br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><br>Christopher Barker, Ph.D.<br>Oceanographer<br><br>Emergency Response Division<br>NOAA/NOS/OR&R            (206) 526-6959   voice<br>7600 Sand Point Way NE   (206) 526-6329   fax<br>Seattle, WA  98115       (206) 526-6317   main reception<br><br><a href="mailto:Chris.Barker@noaa.gov" target="_blank">Chris.Barker@noaa.gov</a></div>
</div></div>