I have created a program which works out days, hours, minutes, seconds and milliseconds until a date which the user inputs. Is it possible to shorten/make the output a little clearer?
from datetime import datetime
while True:
inp = input("Enter date in format yyyy/mm/dd hh:mm:ss")
try:
then = datetime.strptime(inp, "%Y/%m/%d %H:%M:%S")
break
except ValueError:
print("Invalid input")
now = datetime.now()
diff = then - now
print(diff, "until", inp)
print(diff.total_seconds(),"seconds")
-
\$\begingroup\$ Welcome to Code Review. It's actually unclear what you're asking for. What do you think should be improved in your program code? \$\endgroup\$πάντα ῥεῖ– πάντα ῥεῖ2015年12月16日 21:47:38 +00:00Commented Dec 16, 2015 at 21:47
-
\$\begingroup\$ Good point, I'll edit \$\endgroup\$Beastly Gerbil– Beastly Gerbil2015年12月16日 21:48:04 +00:00Commented Dec 16, 2015 at 21:48
-
\$\begingroup\$ Probably you should show what your actual output looks like, and what you want to make clearer. Your edit didn't improve very much I'm afraid. My downvote still stays until you make your question clear. \$\endgroup\$πάντα ῥεῖ– πάντα ῥεῖ2015年12月16日 22:30:11 +00:00Commented Dec 16, 2015 at 22:30
2 Answers 2
Here you going to get two different answers in one for your question. One on the output issue, and one your coding. Let's start with the coding part.
I do like that keep trying until you get a proper input, however there is no way to exit this loop besides providing a legal date. This shouldn't be a problem as you suggest the valid format, but yet again it could be bad.
Even for small scripts I would get into the habit of using functions, and avoid code at the top level. Not only can that focus your coding, but it could also for you function to be called as part of a module, and allow for testing using modules like doctest. One common idiom to use is the if __name__ == '__main__':
which then can call your function.
Using it as function could also allow for looping your script if you want to check multiple days, or allow dates to input from the command line using argument parsing.
Your names are not terrible, but they are not entirely good either. The now
also kind of hides the datetime.now()
. It's legal, and your code does work, but having variables the same as functions is a little unfortunate.
Regarding simplifying output
I expect that you would want output similar to "2 years, 4 months, 7 days, 8 hours, 40 minutes and 4 seconds". This however is harder than you think, as get the correct amount of months and years is tricky. I.e. How many days and months are there between 2015年02月03日 and 2015年03月04日? Is it "1 month and 1 day" or is it "29 days"? The latter would be correct if the month always have 30 days, and the first is the more conventional answer based on human logic.
The same kind of logic applies to years, where you'll possibly get the output wrong according to human logic. And with leap years the equation gets even worse. Both for months and days difference calculation.
As such you might want to evaluate what you actually want to output, and how to achieve this. One road could be to do it the hard way, and that is compare the dates part by part, but this will expand your code quite a bit.
I.e. when comparing the 2015年11月16日 with 2016年03月14日, you could try with "1 year" but as the to month is lower than from month, you have to subtract one and add 12 months to the difference. For months you'll then get "3 - 11 + 12" making 4 months. But yet again you'll have an issue since the 14th is before the 16th...
And this time you have to take into account the days of the previous month, February of 2016, which has 29 days, making the correct number of days: "14 -ひく 16 +たす 29 =わ 27", and correct the month number to 3 months.
So the final difference is to be: 3 months and 27 days. (That is if I'm not mistaken, and done something wrong in my calculations.)
-
\$\begingroup\$ Thx for the help, and good point about the output \$\endgroup\$Beastly Gerbil– Beastly Gerbil2015年12月17日 18:40:44 +00:00Commented Dec 17, 2015 at 18:40
Your error message can't be much more specific without parsing the string to try determine the error, but users don't read well, so it's worth reminding them why they're getting an error.
print("Invalid input. Please match the format *exactly*.")
print("Also non existent dates like month 13 are not valid.")
holroy's right that now
isn't a great name, but you don't even need it. You could just evaluate the result of now()
in place:
diff = then - datetime.now()
print(diff, "until", inp)
print(diff.total_seconds(),"seconds")
There's nothing wrong with this, I personally find it cleaner since it's more obvious you only need that result once and it's easier to see how diff
is being calculated.
-
\$\begingroup\$ Thx, always like to have my code as short as possible and that has helped \$\endgroup\$Beastly Gerbil– Beastly Gerbil2015年12月17日 18:41:37 +00:00Commented Dec 17, 2015 at 18:41
Explore related questions
See similar questions with these tags.