See the recipe here for a description of the problem.
This variant allows the user to choose between two APIs, either by supplying the count, start value and end value:
>>> list(spread(5, 1.0, end=2.0))
[1.0, 1.2, 1.4, 1.6, 1.8]
or the count, start value and step size:
>>> list(spread(5, 1.0, step=-0.25))
[1.0, 0.75, 0.5, 0.25, 0.0]
As before, the count argument specifies how many subdivisions are made. The optional argument mode
selects whether the start and end values are included. By default, start is included and end is not, and exactly count values are returned.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | from fractions import Fraction
def spread(count, start, end=None, step=None, mode=1):
if end is step is None:
raise TypeError('one of end or step must be given')
if not isinstance(mode, int):
raise TypeError('mode must be an int')
if count != int(count):
raise ValueError('count must be an integer')
elif count <= 0:
raise ValueError('count must be positive')
if mode & 1:
yield start
if end is None:
step = Fraction(step)
end = start + count*step
else:
step = Fraction(end-start)/count
start = Fraction(start)
for i in range(1, count):
yield float(start + i*step)
if mode & 2:
yield float(end)
|