dbader / schedule

Python job scheduling for humans.
https://schedule.readthedocs.io/
MIT License
11.73k stars 959 forks source link

Confusing API names like every().day() & every().days() #299

Open manikanta-kondeti opened 5 years ago

manikanta-kondeti commented 5 years ago

Thanks for the API. It is really simple and easy-to-use.

We were using schedule module to trigger and run our periodic jobs. However, I was confused with the naming convention that every().day() will only once in that day whereas every().days() will run for all days. In general, anything after every() is repetitive and human intuitive. So, it's really confusing in the first place while using this method. Same follows for other dimensions like [(hour, hours), (minute, minutes), (week, weeks), (month, months)]

There was a lack of documentation explaining the clear difference between them. It would be really awesome if we change the names or providing better documentation. I'd love to provide help in this if needed.

Thanks again for the wonderful API.

SijmenHuizenga commented 3 years ago

Hi! Thanks for the love <3

I'm sorry to hear the syntax is a bit confusing. It would be great if we could improve the docs to better explain this. Let me try to explain a bit of the idea behind this syntax and then we can continue brainstorming on how to best improve the docs.

The difference between .day and .days originates from trying to to stay as close as possible to English. Whenever something has to happen more than 1, an s is added because english. For example:

For things that happen every 1 time unit, no s is added:

Writing schedule.every(3).day.do(job) is not allowed (throws an error) because .day conflict with every(3).

Note that writing .every() is the same as .every(1).

Now, you have discovered an edge case! The every().days() should technically throw an error because days implies a number other than 1 is entered in .every().

But we are not throwing that error, for a reason. Many people use variables within days. For example:

nr_of_days = 3

schedule.every(nr_of_days).days.do(job)

If we were to be throwing errors when nr_of_days is 0, people would have to write if-statements to catch these edge cases. That would look something like:

nr_of_days = 3

if nr_of_days == 1:
    schedule.every().day.do(job)
else:
    schedule.every(nr_of_days).days.do(job)

That would defeat the purpose of having a 'simple' library, so we allow schedule.every(1).days.do(job).

How do you think the docs could best be improved to take away any confusion?