Reputation: 251
So I am doing a course on Python and was on a chapter quiz. The first time I answered the question, I was wrong, then I saw the actual answer. The two unknown's were (bday-today).days
. Additionally, I also want to know how "Birthday in %d days" % (diff+365)
works.
Here's the code:
from datetime import *
def main():
today=date.today()
bday=date(today.year,12,13)
diff=(bday-today).days
if diff>0:
print("Birthday in %d days" % diff)
else:
print("Birthday in %d days" % (diff+365))
main()
Upvotes: 1
Views: 94
Reputation: 1901
As for (bday-today).days
, it often surprises people when they see a method called on an expression like (a + b)
. It doesn't make sense that (a + b).method()
could ever work.
However, you're not calling .method()
on the parentheses; you're calling it on the result of a + b
, which should be an object that supports calling .method()
.
Consider this code:
a = "Hello, "
b = "World!"
What if you want to find the length of the combined string? Well, you could do this:
c = a + b
print( len(c) )
But you can save a step with:
print( len(a + b) )
This probably doesn't surprise you too much, but let's change the question a little bit:
What if you wanted the upper-case equivalent of the combined string? Well, you could write:
c = a + b
print( c.upper() )
Or, you could save a step and do:
print( (a + b).upper() )
Because you may have never seen a parenthesized expression having a method called on it, this may look bizarre to you. But all that's happening is that (a + b) is creating a new object (which is a str
object), which then gets its .upper()
method called.
You may (or may not) have even seen code like this:
some_function().some_action()
That looks wrong, but is it? It looks like we're calling a method of a function!
But we're not. What's really going on is that some_function()
is returning an object, and this object has a .some_action()
method that can be called. Basically, the above code is really no different than:
var = some_function()
var.some_action()
(except that the returned value of some_function()
is not stored off in a variable).
And this isn't a Python quirk; this behavior is found in C++, Java, and pretty much every other Obejct-Oriented language there is.
(Don't feel bad if you didn't know about this. I worked with a professional C++ programmer (with over a decade of experience) who didn't know that that was possible in C++. When I explained to him that it worked, he thought it was best to "play it safe" and not use that construct -- because, you know, "the compiler might not support it!" However, this must be supported by Object-Oriented languages -- otherwise, a fundamental property of OO is broken -- namely, that objects (even returned objects) can have their methods called.)
As for "Birthday in %d days" % (diff+365)
, it's an old way of formatting text that's been replaced by f-strings
and the str.format()
. Basically, these lines are equivalent:
"Birthday in %d days" % (diff+365) # Usually found in Python 2.X
"Birthday in {} days".format(diff+365) # Usually found in Python 3.X
f"Birthday in {diff+365} days" # Usually found in Python 3.X
If you're used to programming in Python 3.X, it's no surprise that it looks unfamiliar to you. I recommend reading up a little on it (so you can recognize if for what it is), but using the other format methods when writing your own code.
Upvotes: 4
Reputation: 82899
The line diff = (bday - today).days
gets the difference between bday
and today
, which is an instance of datetime.timedelta
, and then gets the days
attribute from that timedelta
, and thus the number of days until (or since) the birthday. The parens are necessary, since without, bday - today.days
would be evaluated as bday - (today.days)
, which would not make sense.
Similarly, "Birthday in %d days" % (diff+365)
is basically just the same as two lines above, but adding 356
to the number of days before putting them where the %d
is in the string. Again, the parens are necessary since %
is technically still a "multiplication/division" type operation, even though it is used differently here, and thus stronger binding than addition, i.e. without it would be evaluated as ("Birthday in %d days" % diff) + 365
, which, again, would not make sense.
Upvotes: 1