Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python Python Collections (2016, retired 2019) Sets Set Math

horus93
horus93
4,333 Points

I feel like I'm not understanding the question right with this set search challenge

So the question at hand is, and I'm a little unclear as to exactly what its asking us to do. Read, and i'll explain below what I get from it step wise on creating said function.

Let's write some functions to explore set math a bit more. We're going to be using this COURSES dict in all of the examples. Don't change it, though!

So, first, write a function named covers that accepts a single parameter, a set of topics. Have the function return a list of courses from COURSES where the supplied set and the course's value (also a set) overlap.

For example, covers({"Python"}) would return ["Python Basics"].

So, given the pretty limited coverage in this section on sets so far (I like how he just said, go read all the documentation first, experiment a bunch, then come try the challenge. Kind of throwing the standard operating procedure so far for lesson structure here out the window, but I'm not here to rant about that even if it is making this a bit more frustrating.)

From my understanding here of the question, we need to make a function named covers, give is a single parameter (single input? or a parameter that accepts multiple inputs, the part that says "a set of topics" makes me wonder about that, since it would make the function better if it could search for courses that shared any number of subtopics like "give me all courses containing functions, booleans, and loops, instead of just searching for a single word in the dict values.

Then have the function take those to compare against each key (course)'s values(subsets, or subdicts? From what I read, the course values are sets, even if to a neophyte like myself they are indistinguishable from dictionaries, or are they always sets if you nest them within a dictionary?). I'd imagine we'd want to use intersection and compare it to the value's that matched our user supplied topics, and return the result of that as a list.

So step wise is where I was getting confused here, because I know this challenge in particular is more about how you get to the result, rather than the actual result. Because it's easy enough to do a for in loop with the dictionary searching for the supplied user input (though, I was having trouble with figuring out how to have it accept more than one topic at a time. Maybe have it look at a tuple with a list inside?

Anyway my breakdown was

1.) Define function (easy enough) - def covers(topic) - (I feel like this input isn't right, maybe I'm misreading it though) 2.) compare the user input against supplied values in each key 3.) return keys who contained the chosen topic/'s value/'s in a list format

Initially after running up against X:Bummer: Try again! multiple times with my initial attempt I found someone else in the last video comments who basically came to a similar conclusion, but was returning the elements to a set instead of a list.

Then I thought, "maybe it wants me to use the set operations for this? I mean, it would make sense" so I modified my original one, though I'm sure there's an easier way, I thought I needed to take the results from searching the COURSES set for the chosen topics that I'd put into a list(which needed to become a tuple, because lists can't be added into sets), and create a new (or, add into an empty set). Then, my control set which was fixed as COURSES, compare against the new one, and return a list of their shared elements (which, from what I understand the intersection operation is for that.

With that however it just wound up returning an empty list, it felt like I was on the right track, but as usual I'm afraid I may have overthought the problem, creating unnecessary new problems for myself, further enshrouding the solution to my gaze.

My original attempt looked like this, with the current state of my code being at the bottom.

def covers(topics):
    list1 = []

    for key in COURSES.keys():
        if topics in COURSES[key]:
            result = key
            list1.append(result)
        else:
            continue
    return list1

print(covers("strings"))
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(topic):
    holding = []
    ctrl_set = frozenset(COURSES)
    hld_set = set()
    tpl_conv = holding,

    for key in COURSES.keys():
        if topic in COURSES[key]:
            result = key
            holding.append(result)
        else:
            continue

    hld_set.add(tpl_conv)
    comparison = ctrl_set.intersection(hld_set)

    return list(comparison)
horus93
horus93
4,333 Points

Ok, so I've gotten it to accept a variable number of strings, for input using *args, this gave me some trouble initially because I felt like that was the direction I needed to go but was implementing it wrong. So now I come to here. It feels wrong for the challenge even if it outputs the desired result as I'm not using any of the new set operations discussed in the videos.

def covers(*topics):

    for topic in topics:
        mylist = list()

        for k, v in COURSES.items():
            if topic in v:
                mylist.append(k)

    return mylist

print(covers('variables', 'input'))

So I output a list after iterating through the COURSES dict, looking at and comparing each keys set contents to one another, and outputting the ones with shared set elements denoted by the function call which can now take a variable number of strings (thanks *args!), and puts each course name into a nice list with other courses that share its topics.

Which seemed like what the challenge is asking for, but with one little bug I noticed, if I try to put elements into the function call in the format listed in the challenge...

For example, covers({"Python"}) would return ["Python Basics"].

It just seem to give me back a blank list output if I tried something like this.

print(covers({'variables'}, {'input'})) 

and or 

```Python
print(covers({'variables', 'input'}))

Both return [], I feel like this issue is the core of why I keep failing the challenge, but I can't seem to find anything in my google searching on functions accepting elements surrounded by {} (which, really probably just means I'm not looking in the right place, or for the right thing.).