[Tutor] Help...

Alan Gauld alan.gauld at btinternet.com
Tue Jul 28 10:48:26 CEST 2009


"Ryan V" <memorylasts at gmail.com> wrote

> as i am returning all the values. it is telling me that there is no value
> for the variables i am returning.  any help is greatly appreciated!

You are returning the values to variables in the main function.
But in Python variables inside functions (aka local variables) are
only visible inside that fuinction, they are NOT cvisible to
functions that are called from inside the same function.

So yor variables in main() are not visible to the input_xxxx
set of functions. They are visible to calc_price because
you pass them in as arguments.

> def main():
>    print 'The menu is:'
>    print 'Yum Yum Burger for $0.99'
>    print 'Grease Yum Fries for $0.79'
>    print 'Soda Yum For $1.09'
>    mealOrder = input_meal()
>    burgerPrice = input_burger()
>    friesPrice = input_fries()
>    sodaPrice = input_soda()
>    mealEnd = input_mealEnd()
>    calc_total(burgerPrice, friesPrice, sodaPrice)
> #    print_info(total)
>
> def input_meal():
>    print 'If you want the Yum Yum Burger please press 1'
>    print 'If you want the Grease Yum Fries please press 2'
>    print 'If you want the Soda Yum please press 3'
>    print 'If you entered no instead of yes just hit 4'

Whee would the user enter no instead of yes?
At this stage of the program you haven't asked them to enter yes or no.

BTW from a presentation point of view you might want to
put the menu in a long string using triple quotes which
will help you align the menu options:

print '''
If you want the Yum Yum Burger please press     1
If you want the Grease Yum Fries please press  2
If you want the Soda Yum please press                3
If you entered no instead of yes just hit                 4
'''

>    mealOrder = input('Enter Now - ')

In Python 2.x using input() is considered a bad idea since it
allows users to (deliberately or by accident) enter python code
that could do damage to your program or even your computer!
Its better to use raw_input() and convert the result to the
required type, such as int.

mealOrder = int( raw_input('Enter Now - ') )

Slightly more typing but much safer.

>    if mealOrder == '1' :
>        input_burger()
>    elif mealOrder == '2' :
>        input_fries()
>    elif mealOrder == '3' :
>        input_soda()
>    elif mealOrder == '4' :
>        calc_total(burgerPrice, friesPrice, sodaPrice)

But this won't work because you are inside input_meal()
which doesn''t have any variables called burgerPrice etc.

However, this also means that you are going to call
calc_total twice, since after you return from input_meal()
you also call calc_total in main(). I suspect you don't want
that, instead you want to return the values back to main
so that calc_total there can do the calculation after all the
data collection has been completed?

> def input_burger():
>    amountBurger = input('How many burgers would you like?')
>    burgerPrice = amountBurger * 0.99
>    input_mealEnd()
>    return burgerPrice

Now this is where it gets really complicated.
You call input_MealEnd here which in turn can
call input_meal which in turn can call input_burger
and so on. This kind of deep cyclic tree of function
calls is called recursion and is not the best way to
control the flow of your code. Look at using loops
and branches to do that at the top level. The top
level function should control the flow of your program,
the lower level functions should perform only one step
and return a value.

> def input_fries():
>    amountFries = input('How many Fries would you like?')
>    friesPrice = amountFries * 0.79
>    input_mealEnd()
>    return friesPrice

Notice that these other functions are exactly the same
as each other apart from the names you used for the
variables. You could therefore write one function that
takes the food and price as parameters:

> def input_food(food, price):
>    amount = int( raw_input('How many %s would you like?' % food) )
>    thePrice = amount * price
>    return thePrice

You would then call it as:

friesPrice = input_food('fries', 0.79)

> def input_mealEnd():
>    mealEnd = raw_input('Would you like to end your order? (Enter yes or
> no)')
>    if mealEnd == 'yes' :
>        calc_total(burgerPrice, friesPrice, sodaPrice)
>    elif mealEnd == 'no' :
>        input_meal()

And here we have yet another call to calc_total....

> #Calculation of meal cost
> def calc_total(burgerPrice, friesPrice, sodaPrice):
>    totalFood = burgerPrice + friesPrice + sodaPrice
>    totalTax = totalFood * .06
>    total = totalTax + totalFood
>    print 'The total price for food is $', totalFood
>    print 'The Tax is $', totalTax
>    print 'The total is $', total

Its probably better not to print the values in a rfunction that
claims to calculate. Instead return the values so that a display
function can print them suitable formatted. That way you can
easily change the display(to HTML say) without changing
the calculation functions.

So instead of the print lines simply return the three values:

     return totalFood, totalTax, total


> #Displays total, and what you ordered
> #def print_info(total):
> #    print 'The meal price is $', total

Then I'd extend this to print all of the values that were in the
calc_total function

> Would you like to end your order? (Enter yes or no)yes
> *Traceback (most recent call last):
>  File "...", line 74, in <module>
>    main()
>  File "...", line 16, in main
>    sodaPrice = input_soda()
>  File "...", line 51, in input_soda
>    input_mealEnd()
>  File "...", line 57, in input_mealEnd
>    calc_total(burgerPrice, friesPrice, sodaPrice)
> NameError: global name 'burgerPrice' is not defined*

Remember the local variables of function A are not
visible to functions that are called by A

HTH,


-- 
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/ 




More information about the Tutor mailing list