pythonwhile-loopnumber-sequence

Print numbers that are multiples of certain number uniformly


Maybe a silly question, I am trying to print numbers in a loop in such a way that they are multiples of 10. This is very easy as long as the timestep in the loop is multiple of 10. This is how I do it:

time = 0.
timestep = 2.
while time <= 100.:
    if int(round(time)) % 10 == 0:
        print time
    time += timestep

which gives me an output of:

0.0
10.0
20.0
30.0
40.0
50.0
60.0
70.0
80.0
90.0
100.0

And if I use a timestep = 1, I get a similar output. My problem is that now my timestep is given as a function of another variable, and is a float with many decimals. For one case, for instance, the timestep turns out to be 1.31784024239, and if I try to do a similar loop, the numbers I get are not that uniform anymore. For example, I get:

0.0 
19.7676036358 
30.310325575 
39.5352072717
50.0779292108
69.8455328467
80.3882547858
89.6131364825

My question is if there is any trick so that my output is printed uniformly - every, let's say, 10 days? it doesn't have to be exactly ten, but I would like to have a point, for example, between 0 and 19 (around 10) and another one around 60, since theres a jump from 50.07 to 69.84.

I don't know if it is possible, but any ideas will really be helpful as many of my timesteps are floats with many decimals.


Solution

  • Here's a simple solution that finds the steps that are nearest to a given series of multiples:

    def stepper(timestep, limit=100.0, multiple=10.0):
        current = multiples = 0.0
        while current <= limit:
            step = current + timestep
            if step >= multiples:
                if multiples - current > step - multiples:
                    yield step
                else:
                    yield current
                multiples += multiple
            current = step
    
    for step in stepper(1.31784024239):
        print step
    

    Output:

    0.0
    10.5427219391
    19.7676036358
    30.310325575
    39.5352072717
    50.0779292108
    60.6206511499
    69.8455328467
    80.3882547858
    89.6131364825
    100.155858422