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 trialIdris Abdulwahab
Courses Plus Student 2,961 PointsPacking and Unpacking
Code Challenge problem:
Let's test unpacking dictionaries in keyword arguments. You've used the string .format() method before to fill in blank placeholders. If you give the placeholder a name, though, like in template below, you fill it in through keyword arguments to .format(), like this: template.format(name="Kenneth", food="tacos") Write a function named string_factory that accepts a list of dictionaries as an argument. Return a new list of strings made by using ** for each dictionary in the list and the template string provided.
Error message was: positional argument follow keyword argument (string_factory.py, line 12)
With my understanding, to unpack, I will use the double asterisks to introduce the values I want to unpack inside the call function.
Please if you are helping out with this, I will appreciate some explanation on what I did wrong and what I should have done instead. In that way I will learn better and understand your own solution to the problem.
My code is attached.
Thank you so much for your help.
# Example:
# values = [{"name": "Michelangelo", "food": "PIZZA"}, {"name": "Garfield", "food": "lasagna"}]
# string_factory(values)
# ["Hi, I'm Michelangelo and I love to eat PIZZA!", "Hi, I'm Garfield and I love to eat lasagna!"]
#template = "Hi, I'm {name} and I love to eat {food}!"
def string_factory(template = "Hi, I'm {name} and I love to eat {food}!"):
if template:
return (template.format(name = "name", food = "food"))
string_factory(**{"name": "Michelangelo", "food": "PIZZA"}, {"name": "Garfield", "food": "lasagna"})
5 Answers
Steven Parker
231,269 PointsHere's a few hints:
- don't modify the provided code, "template" is defined as a global you can use in the function
- your function "accepts a list of dictionaries as an argument", give this a name other than "template"
- you will need a loop to handle multiple items in the argument list
- you will use "format" in the loop with "template" to build up a list of strings to return
- the format call will provide an opportunity to use unpacking to create named arguments
- only after the loop is finished, you will return the newly-created list of strings
Idris Abdulwahab
Courses Plus Student 2,961 PointsI think i'm lost. It's still not panning out.
template = "Hi, I'm {name} and I love to eat {food}!"
def string_factory(steak):
values = [{"name": "Michelangelo", "food": "PIZZA"}, {"name": "Garfield", "food": "lasagna"}]
new = []
for item in values:
good = [(template.format(name = "name", food = "food"))]
new += good
return new
Steven Parker
231,269 PointsYou're pretty close, but:
- the dictionary list comes in as the argument, you do not want any literals
- the literal values in the comments are just sample models, they will not be used
- the format argument doesn't need explicit names if the unpacking operator is used
Idris Abdulwahab
Courses Plus Student 2,961 PointsStill finding the exit. If I understand what you are saying, the dictionary will be used with double asterisk to call function while unpacking and the unpacking will not come inside of the function. I tried with the lines below but no success.
template = "Hi, I'm {name} and I love to eat {food}!"
def string_factory(list):
new = []
for item in list:
good = [(template.format(name, food))]
new += good
return (new)
Steven Parker
231,269 PointsYou're almost there. Here's what I was hinting about regarding the unpacking operator:
good = [ template.format(**item) ]
Idris Abdulwahab
Courses Plus Student 2,961 PointsSigh of relief at last! Thanks a million for helping out with those hints. And I do appreciate your patience.
Bryan Park
13,481 PointsYou can also save yourself a line of code with not using the "good" variable. Just add the combined template directly into the new list.
new += [template.format(**item)]
Idris Abdulwahab
Courses Plus Student 2,961 PointsIdris Abdulwahab
Courses Plus Student 2,961 PointsFollowing your hints, I tried this but I'm not yet there.
Steven Parker
231,269 PointsSteven Parker
231,269 PointsOK, here's another round of hints:
for item in value:
")