Leon Surrao
Leon Surrao

Reputation: 637

Python type conversion error

Am trying to print a given result using the str.format() in python but I keep running into an TypeError. Here is my current piece of code that gives me the error:

def Restaurant_calorie_average(rest):
    result = []
    for item in rest.menu:
        result.append(item.calories)
    return sum(result)/len(rest.menu)

def Restaurant_str(self: Restaurant) -> str:
return (
    "Name:     " + self.name + "\n" +
    "Cuisine:  " + self.cuisine + "\n" +
    "Phone:    " + self.phone + "\n" +
    "Menu:     " + Menu_str(self.menu) +  "\n"+
    "\t  Average Price: {0:3.2f}.  Average calories {1:}: ".format(Restaurant_price_average(self), str(Restaurant_calorie_average(self))) + "\n\n")

def Collection_str(C: list) -> str:
''' Return a string representing the collection
'''
s = ""
if not C:
    return ''
else:
    for r in C:
        s = s + Restaurant_str(r)
    return s

This is the error I get:

    Traceback (most recent call last):
  File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 229, in <module>
    restaurants()
  File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 19, in restaurants
    our_rests = handle_commands(our_rests)
  File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 48, in handle_commands
    print(Collection_str(C))
  File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 176, in Collection_str
    s = s + Restaurant_str(r)
  File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 84, in Restaurant_str
    "\tAverage Price: {0:3.2f}.  Average calories: {1:}".format(Restaurant_price_average(self), Restaurant_calorie_average(self)) + "\n\n")
  File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 113, in Restaurant_calorie_average
    return float(sum(result)/len(rest.menu))
TypeError: unsupported operand type(s) for +: 'int' and 'str'

What I don't understand is, that another function Restaurant_price_average() in my program has the exact same parameters and returns a float like the Restaurant_calorie_average() and it works just fine in the current program if I remove the Restaurant_calorie_average() part. I tried type converting 'Restaurant_calorie_average()into string, putting float in format {1:3.1f} but it still doesn't seem to work. Can anyone help me with this? The full program is here Rprogram for your reference.

Upvotes: 0

Views: 6241

Answers (1)

Lev Levitsky
Lev Levitsky

Reputation: 65791

The error means that the items in the result list have strings as calories and not numbers (at least some of them). The sum() function can't work like that because it internally adds the elements to 0, which results in the error you see:

In [1]: sum(['42'])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-86653ad6b5d8> in <module>()
----> 1 sum(['42'])

TypeError: unsupported operand type(s) for +: 'int' and 'str'

In [2]: sum([1, 2, '42'])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-c2f90238e02a> in <module>()
----> 1 sum([1, 2, '42'])

TypeError: unsupported operand type(s) for +: 'int' and 'str'

The error is not related to the .format() call, because, as you can see in the traceback, it happens inside Restaurant_calorie_average.

You should fix your code (not shown in the question) so that rest.menu items only contain numbers in their calories attribute. Looking at your full code, apparently this part needs to be fixed:

def Dish_get_info() -> Dish:
    """ Prompt user for fields of Dish; create and return.
    """
    return Dish(
        input("Please enter the Dish's name:  "),
        float(input("Please enter the price of that dish:  ")),
        input("Please enter the calories in the food:  ") # <-- you are not converting
                                                          # to float here
        )

As a side note, I agree with Kevin's comment that you would have much more readable code if you wrote actual classes with methods, rather than functions. And if you do use functions, it's a widely adopted convention that function names start with lowercase letters.

Upvotes: 1

Related Questions