Aleksandr Zakirov - 9 months ago 28

Python Question

I am completely new to python and programming but I am trying to learn it using more practical approach.

What I am trying to do is an exercise for converting different units, e.g. pounds -> kilograms, foot -> meter etc.

I have defined all the functions for different unit pairs:

`def kg_to_g(value):`

return round(value*1000.0,2)

def g_to_kg(value):

return round(value/1000.0,2)

def inch_to_cm(value):

return round(value*2.54,2)

def cm_to_inch(value):

return round(value/2.54,2)

def ft_to_cm(value):

return round(value*30.48,2)

etc.

and created a list with names of these functions:

`unit_list = ['kg_to_g','g_to_kg','inch_to_cm','cm_to_inch',`

'ft_to_cm','cm_to_ft','yard_to_m','m_to_yard',

'mile_to_km','km_to_mile','oz_to_g','g_to_oz',

'pound_to_kg','kg_to_pound','stone_to_kg','kg_to_stone',

'pint_to_l','l_to_pint','quart_to_l','l_to_quart',

'gal_to_l','l_to_gal','bar_to_l','l_to_bar']

The program should randomly choose a unit pair(e.g. kg->pounds) and value (e.g. 134.23), and the user will be asked to convert those values.

`random_unit = random.choice(unit_list)`

lower = 0.1001

upper = 2000.1001

range_width = upper - lower

ranval = round(random.random() * range_width + lower, 2)

When user enters answer, the program should compare answer with the calculations defined by function and tell user if it is a correct answer or wrong answer:

`def input_handler(answer):`

if answer == random_unit(ranval):

label2.set_text("Correct!")

else:

label2.set_text("Wrong!")

Unfortunately, that way program doesn't work, and codesculptor(codesculptor.org) returns with an error

`TypeError: 'str' object is not callable`

Could someone please explain to me what is wrong with the code and suggest something to solve the problem.

Answer

Because you've enclosed the function names (in the list) in quotes, they have become strings.

Change your list to:

```
unit_list = [kg_to_g, g_to_kg, inch_to_cm, cm_to_inch,
ft_to_cm, cm_to_ft, yard_to_m, m_to_yard,
mile_to_km, km_to_mile, oz_to_g, g_to_oz,
pound_to_kg, kg_to_pound, stone_to_kg, kg_to_stone,
pint_to_l, l_to_pint, quart_to_l, l_to_quart,
gal_to_l, l_to_gal, bar_to_l, l_to_bar]
```

And now it is a list of functions, which can be called like this: `unit_list[0](34)`

, for example.

So now `random_unit(ranval)`

should not throw an exception.

Note also that comparing floats (`if answer == random_unit(ranval)`

) will most likely cause you problems. See Is floating point math broken? for some detailed explanations of why this is.

As you are rounding you may get away with it, but it's good to be aware of this and understand that you need to deal with it in your code.