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

Code Challenge: Teacher stats

I did it this way,but I'm getting error as 'Didn't get the right teacher name!' can you help me out in where I did wrong in the code please...

teachers={'Andrew Chalkley': ['jQuery Basics', 'Node.js Basics','Big Data','c++'],'Kenneth Love': ['Python Basics', 'Python Collections','c','c++','data structures']}

def num_teachers(x): return len(x) def num_courses(x): count=0 for i in x.values(): #print(i) count+=len(i) return count def courses(x): courses=[] for i in x.values(): for j in i: #print(j) courses.append(j) return courses def most_courses(x): most_dict={} for i,j in x.items(): for k in x.values(): if len(j)>len(k): most_dict[i]=j print(most_dict.keys()) return most_dict.keys()

most_courses(teachers)
num_teachers(teachers) num_courses(teachers) courses(teachers)

Eric M
Eric M
11,545 Points

Hi Vinay,

Your code is almost unreadable like that sorry, especially for Python where the level of indentation can change the behavior of the program.

Consider:

results = []
for can in shelf:
        results.append(can)
        print(results[-1])

############################

results = []
for can in shelf:
        results.append(can)
print(results[-1])

The first loop prints each can after it has been added. The second loop adds all cans then prints only the last one that was added.

I think your code indentation is supposed to be as per the below, but please let me know and if it's not the same post it with your indentation by using three backticks followed by Python, then your code, then three backticks, like this:

```Python

Your code here

```

Here's my guess as to your layout:

teachers={'Andrew Chalkley': ['jQuery Basics', 'Node.js Basics','Big Data','c++'],'Kenneth Love': ['Python Basics', 'Python Collections','c','c++','data structures']}

def num_teachers(x): 
        return len(x) 

def num_courses(x):
        count=0 
        for i in x.values():
                #print(i)
                count+=len(i)
        return count

def courses(x): 
        courses=[] 
        for i in x.values(): 
                for j in i: 
                        #print(j) 
                        courses.append(j) 
        return courses 

def most_courses(x): 
        most_dict={} 
        for i,j in x.items():
                for k in x.values():
                        if len(j)>len(k):
                                most_dict[i]=j 
                                print(most_dict.keys()) 
        return most_dict.keys()

most_courses(teachers)

num_teachers(teachers) 

num_courses(teachers) 

courses(teachers)

5 Answers

yes...this is my exact code

Eric M
Eric M
11,545 Points

Okay great. Let's focus on the function that's giving you trouble, most_courses, good work with the rest of them!

def most_courses(x): 
        most_dict={} 
        for i,j in x.items():
                for k in x.values():
                        if len(j)>len(k):
                                most_dict[i]=j 
                                print(most_dict.keys()) 
        return most_dict.keys()

You started with the right idea here, but you might be overthinking it. Our dictionary has key value pairs, where the key is a teacher's name and the value is a list of their courses. The number of courses will be the length of that list, or a length of that value. So what we need to do is establish a counter, check if the length is greater than the counter, if it is, we update the name of the teacher with the most courses. Once we've iterated through the entire list we can return that name.

Here's an edit to your function with minimal changes

def most_courses(x): 
        most_courses = 0
        most_name = ""
        for i, j in x.items():
                if len(j) > most_courses:
                    most_name = i
        return most_name

And again with some variable names that might make things clearer (they do for me :) ):

def most_courses(course_dictionary): 
        most_courses = 0
        most_name = ""
        for teacher_name, course_list in course_dictionary.items():
                if len(course_list) > most_courses:
                        most_name = teacher_name
        return most_name

Yes....You are right.But at last my code also returning same value right?

Eric M
Eric M
11,545 Points

Unfortunately not. There's a few things going on.

Firstly, your code returns a dict_keys object. For the example (which are not the same as the test cases, they're just examples) your code will have a single key and you're right that the key it contains is the same as the string that the code I provided returns. However, we want a string "Kenneth Love", not a dict_keys object dict_keys(['Kenneth Love']).

The bigger issue though is that when provided with a larger data set your code does not just return a single key.

Say for example we add a third teacher called "Footeach" that has 10 courses in their list. Kenneth has 5 and Andrew has 4.

Your outer loop runs its first iteration setting i to Kenneth and j to his list of 5.

Your inner loop runs through Kenneth's list and we get len(j) > len(k) or 5 > 5 because we're comparing Kenneth to Kenneth, this evaluates to false.

Next inner loop sets k to Andrew's list and we get len(j) > len(k) or 5 > 4 because we're comparing Kenneth to Andrew. This evaluates to True and most_dict[i]=j runs, adding an entry key of Kenneth and a value of his entire list to most_dict.

Next inner loop sets k to Footeach, our new entry, and we get len(j) > len(k) or 5 > 10 because we're comparing Kenneth to Footeach. This is false so that's the end of the first inner loop, back to outer.

Your outer loop runs its second iteration setting i to Andrew and j to his list of 4.

Your inner loop runs through Kenneth's list and we get len(j) > len(k) or 4 > 5, false

Your inner loop runs through Andrew's list and we get len(j) > len(k) or 4 > 4, false

Your inner loop runs through Footech's list and we get len(j) > len(k) or 4 > 10, false

Nothing is changed in most_dict. If these were the only two teachers and you displayed the key instead of a dict_keys object you'd be right if there were only 2 teachers in the dict. The test case has more though, so we continue.

Your outer loop runs its third iteration setting i to Footeach and j to their list of 10

Your inner loop runs through Kenneth's list and we get len(j) > len(k) or 10 > 5, True. most_dict[i]=j runs, adding an entry key of Footeach and a value of their entire list to most_dict.

Your inner loop runs through Andrew's list and we get len(j) > len(k) or 10 > 4, True. most_dict[i]=j runs, updating the Footeach entry with their list (not changing anything).

Your inner loop runs through Footech's list and we get len(j) > len(k) or 10 > 10, false

Your code then returns dict_keys(['Kenneth Love', 'Footeach']) when for this dataset it should have returned "Footeach"

Thank you I got it

This is a helpful discussion.

Eric M
Eric M
11,545 Points

Thanks B G, glad you got something out of it!