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) Dictionaries Word Count

Kevin Ryu
Kevin Ryu
1,286 Points

This works on my atom editor, why won't it work on the workspace?

I ran this code on my atom editor, and it worked fine.

With the command word_count('I do do not not like it Sam I Am')

I get {'do': 2, 'not': 2, 'like': 1, 'it': 1, 'sam': 1, 'i': 2, 'am': 1}. What changed when I copy/pasted onto treehouse editor?

wordcount.py
# E.g. word_count("I do not like it Sam I Am") gets back a dictionary like:
# {'i': 2, 'do': 1, 'it': 1, 'sam': 1, 'like': 1, 'not': 1, 'am': 1}
# Lowercase the string to make it easier.
def string_into_list(first_SA):
    first_SA = first_SA.lower()
    string_copy = first_SA[:]
    empty_list = []
    left_index = 0
    for i in [i for i,x in enumerate(first_SA) if x == ' ']:
        empty_list.append(string_copy[left_index:i])
        left_index = i+1

    empty_list.append(string_copy[left_index:])
    return(empty_list)

def num_list(word_list: list, word):
    num_time_words = 0
    for i in [i for i, x in enumerate(word_list) if x == word]:
        num_time_words +=1
    return num_time_words

def word_count(string_argument):
    main_dict = {}
    word_list = string_into_list(string_argument)
    main_string_copy = word_list[:]
    y=0
    x=0
    for words in word_list:
        if num_list(word_list, word_list[y]) > 1:
            word_list.remove(words)
        y+=1
    for words in word_list:
        main_dict.update({words: num_list(main_string_copy, words)})
        x+=1
    return main_dict

1 Answer

andren
andren
28,558 Points

The challenge wants you to split on all whitespace, your code splits on spaces which is a type of whitespace, but there are lots of other characters considered whitespaces. Like line breaks, tabs, and other things like that. The code works on the example input since that only uses spaces, but the example input the challenges shows you is often different from the value they actually pass to the function. They often differ in order to make it harder to cheat the challenge checker by hardcoding your return to the right values.

Also while list comprehensions can be fun to write they are not always the right tool for the job, to be honest your code is extremely complex compared to the task it is trying to solve. For one implementing a custom string-to-list splitting method instead of using the build-in split method.

If you use the split method then by default (with no arguments passed) it will split the string on all whitespace. So if you replace your string_into_list function with split like this:

def num_list(word_list: list, word):
    num_time_words = 0
    for i in [i for i, x in enumerate(word_list) if x == word]:
        num_time_words +=1
    return num_time_words

def word_count(string_argument):
    main_dict = {}
    word_list = string_argument.lower().split()
    main_string_copy = word_list[:]
    y=0
    x=0
    for words in word_list:
        if num_list(word_list, word_list[y]) > 1:
            word_list.remove(words)
        y+=1
    for words in word_list:
        main_dict.update({words: num_list(main_string_copy, words)})
        x+=1
    return main_dict

Then your code will work, though it will still be quite heavy for the task. A simple way of solving this task is to check if the word currently exists in the dictionary. If it does update the dictionary with its current value + 1, if it does not then set it to 1.

Like this for example:

def word_count(string_argument):
    main_dict = {}
    word_list = string_argument.lower().split()
    for words in word_list:
        if words in main_dict:
            count = main_dict[words] + 1
        else:
            count = 1
        main_dict.update({words: count})
    return main_dict
Kevin Ryu
Kevin Ryu
1,286 Points

I didn't even know there was a .split method! Wow, that would've saved me a lot of time.

Thank you for showing me your last code example. It's much more concise than mine. I guess I've got a ways to go!

andren
andren
28,558 Points

Yeah figuring out simple ways of solving issues can often be quite hard, especially in the beginning when you have not had a lot of experience with the language, and still do not know all of the basics features it has. But it's definitively something that gets better with time, as often times a clever solution you came up with for one specific issue can be re-purposed and modified for other similar problems you come across in the future.

But your code was not bad as far as language understanding was concerned, you used features like list comprehensions which as far as I remember has not actually been brought up in this course yet, and that is considered somewhat complex and hard to wrap your head around.

So I would say you are well on your way. Good luck with your future coding :smile:.