from fractions import Fraction def spread(start, end, count, mode=1): """spread(start, end, count [, mode]) -> generator Yield a sequence of evenly-spaced numbers between start and end. The range start...end is divided into count evenly-spaced (or as close to evenly-spaced as possible) intervals. The end-points of each interval are then yielded, optionally including or excluding start and end themselves. By default, start is included and end is excluded. For example, with start=0, end=2.1 and count=3, the range is divided into three intervals: (0.0)-----(0.7)-----(1.4)-----(2.1) resulting in: >>> list(spread(0.0, 2.1, 3)) [0.0, 0.7, 1.4] Optional argument mode controls whether spread() includes the start and end values. mode must be an int. Bit zero of mode controls whether start is included (on) or excluded (off); bit one does the same for end. Hence: 0 -> open interval (start and end both excluded) 1 -> half-open (start included, end excluded) 2 -> half open (start excluded, end included) 3 -> closed (start and end both included) By default, mode=1 and only start is included in the output. (Note: depending on mode, the number of values returned can be count, count-1 or count+1.) """ if not isinstance(mode, int): raise TypeError('mode must be an int') if count != int(count): raise ValueError('count must be an integer') if count <= 0: raise ValueError('count must be positive') if mode & 1: yield start width = Fraction(end-start) start = Fraction(start) for i in range(1, count): yield float(start + i*width/count) if mode & 2: yield end