# steptools

`steptools.range`

is as a drop-in replacement for `range`

, adding with
support for anything that behaves reasonably like a number, including
floats, `datetime.datetime`

, `datetime.date`

, `fractions.Fraction`

, and
`decimal.Decimal`

.

if `stop is None`

, `start`

will be used as `stop`

and `start`

will be “zero”
created with `type(start)()`

.

Similar to `range`

, generated items are EXCLUSIVE of `stop`

.
`inclusive=True`

allows stop to be returned, assuming it’s a multiple
of step.

`type(step)()`

should construct a “zero” version of `step`

which has no result
if added to `start`

. If this does not work, set `zero_step`

explicitly.

## Examples

`steptools.range`

can act as a drop-in replacement for `range`

to iterate over ints. `range`

is probably faster!

```
>>> list(range(3))
[0, 1, 2]
>>> list(range(3, inclusive=True))
[0, 1, 2, 3]
>>> list(range(5, -3, -2))
[5, 3, 1, -1]
>>> list(range(1.1, 1.5, .2))
[1.1, 1.3]
```

`steptools.range`

can iterate over over `datetime.datetime`

and
`datetime.date`

objects using a `datetime.timedelta`

as the step.

```
>>> from datetime import datetime, timedelta
>>> list(range(datetime(2000, 1, 1), datetime(1999,12,30),
... timedelta(days=-1)))
[datetime.datetime(2000, 1, 1, 0, 0), datetime.datetime(1999, 12, 31, 0, 0)]
```

`steptools.range`

can iterate over over `fractions.Fraction`

```
>>> from fractions import Fraction
>>> list(range(Fraction(1,3), Fraction(2,3), Fraction(1,6)))
[Fraction(1, 3), Fraction(1, 2)]
>>> list(range(Fraction(1,3), Fraction(5,3)))
[Fraction(1, 3), Fraction(4, 3)]
```

`steptools.range`

can iterate over over `decimal.Decimal`

```
>>> from decimal import Decimal
>>> list(range(Decimal("1.33"), Decimal("1.66"), Decimal("0.11")))
[Decimal('1.33'), Decimal('1.44'), Decimal('1.55')]
```

## Requirements

steptools does not depend on any non-core libraries, however the values you pass in for start, stop, step, and zero_step must have certain behavior. The following should all work reasonably without raising exception. The comparisons (< and ==) should return a bool.:

```
if zero_step is None:
type(step)() # must be logically "zero"
step == zero_step
if step < zero_step:
stop < start
stop < (start+step)
else:
start < stop
(start+step) < stop
if inclusive:
start == stop
(start+step) == stop
if stop is none:
type(start)() # must be logically "zero"
```