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

shopping list

I am keep getting a typeErrorr but I can't figure out why. I look through this code for a couple hours and rewatched the videos. Can someone take a look at it and let me know what the problem is. I bet it is something simple. https://w.trhou.se/58o883fjb7

1 Answer

Alex Koumparos
seal-mask
.a{fill-rule:evenodd;}techdegree
Alex Koumparos
Python Development Techdegree Student 36,887 Points

Hi Gregory,

Let's take a look at the traceback and see if we can debug your error:

Traceback (most recent call last):                                                                 
  File "Shopping_list3.py", line 63, in <module>                                                   
    add_to_list(new_item)                                                                          
  File "Shopping_list3.py", line 18, in add_to_list                                                
    show_list()                                                                                    
  File "Shopping_list3.py", line 47, in show_list                                                  
    print('-'+10)                                                                                  
TypeError: must be str, not int 

You're going to be looking at Tracebacks a lot, so it's worth learning what it is telling you. We'll start at the bottom:

TypeError: must be str, not int 

This is telling you exactly what kind of bug caused your program to crash. In this case, you passed something that has a type of int (i.e., a number) into a function that requires a string.

The line above this tells you exactly where in your code this happened, and shows you the line of code that crashed:

File "Shopping_list3.py", line 47, in show_list                                                  
    print('-'+10)

So we see the crash happened on line 47 while inside the show_list function. This line is:

print('-'+10)

Let's focus on the contents of the print statement (the print statement itself is syntactically valid, provided the one argument you pass into it is one that Python can evaluate). Thus we are just looking at:

'-'+10

The + operator in Python has different behaviour depending on the type of the object on the left of the + sign (the reason for this might not be interesting to you at this stage in your Python journey, so I'll explain later). You've probably noticed that when you use + to add a number to another number, you get something like this:

>>> 1 + 1
2

Python treats the + when the left side is an int as an arithmetic add function. If you pass it something that isn't a valid number, you'll get a TypeError:

>>> 3 + 'hello'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

When the left side is a str (like in your case), it behaves as string concatenation:

>>> 'hello' + 'world'
'helloworld'

Since Python intends to do string concatenation when the left side object is a string, it needs the right side object to also be a string.

I suspect that rather than concatenating 10 to '-' you actually intended to repeat the value '-' 10 times. In which case you want to use the * method instead of the + method.

The same principle as described above still applies with the * method: the left side dictates what type of value is valid for the right side. However, with * both ints and strs expect the value on the right to be of type int.

Hope that clears everything up for you.

Cheers

Alex

Digression

The possibly boring bit about why it's the object on the left that dictates the behaviour of the + function:

Under the hood, x + y is Python's syntactic sugar for a more conventional looking method on an object (and in Python, everything is an object): x.__add__(y).

Since we are calling the __add__ method on x, it is x's type that determines what is a valid argument for the method, and for determining the behaviour of the method. So int.__add__() is written to take a y of type int and then arithmetically add it to the calling int object.

Similarly, str.__add__() is written to take a y of type str and then concatenate it to the calling object.

Put another way, it is the left side object's type that is responsible for defining and implementing its __add__() method (you can do the same thing on any custom class you create to enable you to use the + operator with your class, without Python knowing anything about what sort of object you are defining).