<div dir="ltr"><div>Hi Steve,</div><div><br></div><div>I tried this when writing <a href="https://github.com/Code-ReaQtor/DocCron">DocCron </a>but it will not work correctly.</div><div><br></div><div>Suppose we have minutes with range 0-59 and seconds with range 0-59 but starting at, say, 5:</div><div><br></div><div>When the seconds value reaches 59, on the next iteration the minute value should increase by 1 (or back to zero) but it will not work that way since the next rotation will be at 4 transitioning to 5.</div><div><br></div><div>So the correct solution is not modifying any of the arrangements.<br></div><div><br></div><div>Best Regards,</div><div>Ronie<br></div><div><br></div><div><br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Oct 25, 2018 at 7:31 PM Steven D'Aprano <<a href="mailto:steve@pearwood.info">steve@pearwood.info</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Thu, Oct 25, 2018 at 02:31:05PM +0800, Ronie Martinez wrote:<br>
<br>
> def main():<br>
>     datetime_odometer = itertools.product(<br>
>         range(2018, 10_000),  # year<br>
>         range(1, 13),  # month<br>
>         range(1, 31),  # days<br>
>         range(0, 24),  # hours<br>
>         range(0, 60),  # minutes<br>
>         range(0, 60)  # seconds<br>
>     )<br>
<br>
When you talked about datetime, I thought you meant actual datetime <br>
objects. The above is buggy: it ignores the 31st day of January, etc, <br>
but includes February 29 and 30 every year.<br>
<br>
<br>
>     datetime_of_interest = (2050, 6, 15, 10, 5, 0)<br>
> <br>
>     for i in datetime_odometer:<br>
>         if i == datetime_of_interest: # target start time<br>
>             break<br>
<br>
In the most general case, there is no way to jump into the middle of an <br>
arbitrary iterator, except to start at the beginning and compute the <br>
values until you see the one that you want. Arbitrary iterators compute <br>
their values on request, and there is no way to jump ahead except by <br>
inspecting each value in turn, skipping the ones you don't want.<br>
<br>
So unless I have missed something, I think what you are asking for is <br>
impossible except for special cases like lists.<br>
<br>
But in *this* case, modelling an odometer, that special case works:<br>
<br>
def rotate(iterable, position):<br>
    L = list(iterable)<br>
    return L[position:] + L[:position]<br>
<br>
Which gives us this:<br>
<br>
py> months = rotate(range(1, 13), 5)<br>
py> months<br>
[6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5]<br>
<br>
Now pass that to itertools.product.<br>
<br>
In other words, I think that the right solution here is to construct <br>
your iterables to start at the position you want, rather than expect <br>
product() to jump into the middle of the sequence. (Which may not be <br>
possible.)<br>
<br>
<br>
<br>
-- <br>
Steve<br>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</blockquote></div>