Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Dates and Times in Python (2014) Let's Build a Timed Quiz App Harder Time Machine

Ryan Dyke
seal-mask
.a{fill-rule:evenodd;}techdegree
Ryan Dyke
Full Stack JavaScript Techdegree Student 6,630 Points

Harder Time Machine - can you pass strings to timedelta?

Instead of making 4 if statements, I'd like to pass time_str ("days", "hours", or "minutes") directly into the timedelta method. Is this possible, or are the quotation marks holding me back form doing so?

time_machine.py
import datetime

starter = datetime.datetime(2015, 10, 21, 16, 29)

def time_machine(time_int, time_str):
    if time_str == "years":
        time_int = time_int * 365
        time_str = "days"
        finisher = starter + datetime.timedelta(time_str=time_int)
    else:
        finisher = starter + datetime.timedelta(time_str=time_int)

2 Answers

Steven Parker
Steven Parker
231,236 Points

It looks like you forgot to return the result value!
And the keys in the "key=value" syntax can't be variables, but you can do a little trick with a dictionary literal and the unpacking operator:

def time_machine(time_int, time_str):
    if time_str == "years":
        time_int *= 365
        time_str = "days"
    return starter + datetime.timedelta(**{time_str : time_int})
boi
boi
14,242 Points

Steven, you genius son of a programmer. Hold my upvote. What took me 13 lines of code, you got it in 5.

boi
boi
14,242 Points

Steven, I can't figure out the core building block of your (**{time_str : time_int}), I can't seem to wrap my head around this concept.

def time_machine(time_int, time_str): 👈#Here we're passing a "string" and an "int"
    if time_str == "years":
        time_int *= 365
        time_str = "days"
    return starter + datetime.timedelta(**{time_str : time_int})👈#How'd you change "hours" into hours.

Aren't we passing in "string"?. how did you manage to convert "string" into variable? I still don't quite get that last line of code, could you please break that up for me, so I could see how it works.

return starter + datetime.timedelta(**{time_str : time_int}) #Please explain the working

Would appreciate your help, GREATLY.

Jonathan Gonzalez
Jonathan Gonzalez
8,544 Points

Hey boi,

Chris Freeman explained it really good here: https://teamtreehouse.com/community/why-wont-the-timedelta-function-take-a-variable-as-a-keyword

I think what happens is python takes the variables passed into the function and places them in the dictionary

datetime.timedelta(**{5 : "days"})

then when it runs, it unpacks the dictionary into the key/value pair which timedelta likes

time_machine(5, "days") ------> (datetime.timedelta(day=5)

not 100% so if that's off let me know

boi
boi
14,242 Points

Hey Jonathan,

YES, you're correct, it's the ** that makes it into keyword arguments. I cleared my doubt already by Kenneth's explanation here. Chris Freeman's explanation was more detailed. Thank you for the help, Jonathan 👍🙂