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 Python Collections (2016, retired 2019) Sets Set Math

Alejandro Byrne
Alejandro Byrne
2,562 Points

Function loop doesn't work. I think

Hi, sorry, another question. I'm getting an error saying it can't fin 'covers' - even though that was the first step (which I already did). Anyway, I think my second function doesn't work either. I'm trying to get it to see if all the content in topics is in a course. And if it is, then add the course name to the result.

sets.py
COURSES = {
    "Python Basics": {"Python", "functions", "variables",
                      "booleans", "integers", "floats",
                      "arrays", "strings", "exceptions",
                      "conditions", "input", "loops"},
    "Java Basics": {"Java", "strings", "variables",
                    "input", "exceptions", "integers",
                    "booleans", "loops"},
    "PHP Basics": {"PHP", "variables", "conditions",
                   "integers", "floats", "strings",
                   "booleans", "HTML"},
    "Ruby Basics": {"Ruby", "strings", "floats",
                    "integers", "conditions",
                    "functions", "input"}
}

def covers(topics):
    result = []
    for topic in topics:
        for course_key, course in COURSES.items():
            if topic in course:
                result.append(course_key)
    return result

def cover_all(topics):
    result = []
    for course in COURSE.items():
        if topics in course:
            result.append(course)
    return result
Nathan Tallack
Nathan Tallack
22,159 Points

The trick with this is to make use of the built-in type methods for sets rather than iterating over it with for loops.

Consider the functions issubset and difference for the tasks in this challenge. They will be the path to your solution.

Sets are VERY powerful when you use their builtin methods, and as you will see from your resulting code when comparing against the complexity of these for loops you were trying to work with, you will agree.

BTW, don't be disheartened. We all make this mistake you are making. That's one of the reasons these courses on treehouse are so fantastic. :)

3 Answers

Claudio Longato Jr
Claudio Longato Jr
4,318 Points

Hi Alejandro,

When I first tried to answer your question I haven't gone through the code challenge. We can make a single loop to have the values we're looking for. Remember that when comparing two sets the return value is a set too. In the first case I checked if the set was empty (an empty set is evaluated as boolean False). In the second function we have to check if the set created by the intersection (not the union, as in your code) is equal to the topics set, that is, if the course covers all topics.

Here's what I came up with:

def covers(topics):

new_list = []

for key, values in COURSES.items():
    if topics.intersection(values):
        new_list.append(key)

return new_list

def covers_all(topics):

new_list = []

for key, values in COURSES.items():
    if topics.intersection(values) == topics:
        new_list.append(key)

return new_list
Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,423 Points

As Nathan Tallack mentioned, using sets is the goal of this challenge. But it can be solved without. There are a few errors in the code that are causing syntax errors. The syntax errors cause the checker to fail so it can't run the checks on task one. Hence, the error message "cannot find covers".

The current errors in the "covers_all" code:

  • Function should be named "covers_all" not "cover_all"
  • COURSE.items() should be named COURSES.items()
  • COURSES.items() returns two items. The for statement has only course to unpack the two items into.
  • The argument topics may be a set of multiple items. The in operator cannot compare two sets. If not using set comparisons, then you need to loop through each item in topics and check if each topic was in the course topics for each course. Then add to result only if all topics were found.

I encourage you to finish both a set and a non-set version of the challenge.

Post back if you need more guidance. Good Luck!!!

Alejandro Byrne
Alejandro Byrne
2,562 Points
def covers_all(topics):
    result = []
    for item in COURSES.items():
        if topics == topics.union(item)
            result.append(item)
    return result

That is my new code, what is wrong with it. Didn't really understand the 3rd bullet you said.

[MOD: added ```python formatting -cf]

Chris Freeman
Chris Freeman
Treehouse Moderator 68,423 Points

Look at the following code example to see how COURSES.items() returns two items.

COURSES = {
    "Python Basics": {"Python", "functions", "variables",
                      "booleans", "integers", "floats",
                      "arrays", "strings", "exceptions",
                      "conditions", "input", "loops"},
    "Java Basics": {"Java", "strings", "variables",
                    "input", "exceptions", "integers",
                    "booleans", "loops"},
    "PHP Basics": {"PHP", "variables", "conditions",
                   "integers", "floats", "strings",
                   "booleans", "HTML"},
    "Ruby Basics": {"Ruby", "strings", "floats",
                    "integers", "conditions",
                    "functions", "input"}
}
print("Three ways to inspect a dict container")
print("\n1a: Using the default to see the dict keys: 'in COURSES'")
for course_name in COURSES:
    print(course_name)

print("\n1b: Same as above. Explicitly view the dict keys: 'in COURSES.keys()'")
for course_name in COURSES.keys():
    print(course_name)

print("\n2: Explicitly view the dict values: 'in COURSES.values()'")
for course_topic in COURSES.values():
    print(course_topic)

print("\n3: Explicitly view both dict key and value: 'in COURSES.items()'")
for course_name, course_topic in COURSES.items():
    print("Name: ", course_name, "Topics: ", course_topic)

This results in:

Three ways to inspect a dict container

1a: Using the default to see the dict keys: 'in COURSES'
Ruby Basics
Java Basics
PHP Basics
Python Basics

1b: Same as above. Explicitly view the dict keys: 'in COURSES.keys()'
Ruby Basics
Java Basics
PHP Basics
Python Basics

2: Explicitly view the dict values: 'in COURSES.values()'
{'Ruby', 'integers', 'functions', 'strings', 'conditions', 'input', 'floats'}
{'loops', 'Java', 'integers', 'strings', 'exceptions', 'booleans', 'input', 'variables'}
{'integers', 'strings', 'HTML', 'conditions', 'booleans', 'variables', 'floats', 'PHP'}
{'loops', 'integers', 'functions', 'exceptions', 'arrays', 'strings', 'conditions', 'booleans', 'Python', 'input', 'variables', 'floats'}

3: Explicitly view both dict key and value: 'in COURSES.items()'
Name:  Ruby Basics Topics:  {'Ruby', 'integers', 'functions', 'strings', 'conditions', 'input', 'floats'}
Name:  Java Basics Topics:  {'loops', 'Java', 'integers', 'strings', 'exceptions', 'booleans', 'input', 'variables'}
Name:  PHP Basics Topics:  {'integers', 'strings', 'HTML', 'conditions', 'booleans', 'variables', 'floats', 'PHP'}
Name:  Python Basics Topics:  {'loops', 'integers', 'functions', 'exceptions', 'arrays', 'strings', 'conditions', 'booleans', 'Python', 'input', 'variables', 'floats'}

Notice how using items() returns both the key and value for each key/value pair in the dict

Alejandro Byrne
Alejandro Byrne
2,562 Points

Thanks, all the responses helped. Completed the challenge! Used a mix of both suggestions. Thanks for the help in the types of ways to get things out of a dict!