Reputation: 37
I'm quite new to Python, and I'm busy trying to figure out how these pesky functions work... The program I'm making is supposed to be working out the area of a triangle, but I can't actually get it to return the local variables to other functions. Any help would be greatly appreciated!
# Area of a triangle
base = 0
height = 0
area = 0
def inData():
base = float(raw_input("Base:"))
height = float(raw_input("Height:"))
return base
return height
def triangle(b,h):
area = b / 2 * h
return area
if __name__ == '__main__':
inData()
triangle(base, height)
print "The area of a triangle of base", base, "and height" , height, "will be", area
Upvotes: 2
Views: 1379
Reputation: 1502
There are many problems and misconceptions I see in your code; Let me see if I can start from scratch and try to convey the proper way to do these functions for you. In the end, we will have a working version of your code. :)
note: You do not have to declare functions ahead of time in Python-- it does that itself! So no need for base, height, area
at the top!
Functions are in short, sets of commands that get run in a bundle. You know this. What you miss though are the concepts of arguments and parameters and return vs print.
Arguments vs Parameters
When you define a function, you are setting up what you want it to do in the future and at your beck and call. Just like any function f(x)
in math, you want one equation that will work with whatever input you give it. For f(x)
, x
is your input.
In programming, this is referred to as a parameter. So when you write in Python:
def Function(x):
y = x*x
return y
You have defined x
as your parameter. Now, Arguments are the values that you put into a function, where the parameters go. In Algebra, the applicable idea would be defining a variable. Knowing this, when you actually use that function:
Function(2)
You will get back 4, because you said run Function(x) where x = 2
.
This is the concept of Arguments vs Parameters. It is very useful, because you don't always want to ask a user for input inside the function. The more direct your function is, the less it can do. Sometimes you want to use that same function to do math in the background, for example. You can't very well have raw_input()
if you expect the process to work on its own in the background, can you?
This is the true value of Arguments vs Parameters.
Return vs Print
In the same vein as not using raw_input()
because it is too direct, you want to avoid using print
and use return
instead. I know you didn't use print
here, but you've misunderstood the workings of return
and I figure the same lesson applies.
Here is an example: You have two functions.
def Function1(x,y):
z = x*y
print z
def Function2(x,y):
z = x*y
return z
Function 1 prints z
, which means that no matter what you want it to do, it will always print z
to the console, even if you want it to just do the math.
Meanwhile, Function 2 returns z
, meaning it hands back the value of z
to the program as it was called. It is also worth noting that as soon as a function hits the line return
, it stops running the function further. There is no reason to code beyond this, because the function is no longer being run, unless you had a more advanced code that skipped over return
(for example, an if
statement).
Why is return
so conceptually important?
Because in your original code, you run the function inData()
, and after that, not only do you run return
twice, but in your if
statement, you don't even use what inData
returns, you just tell the program to run inData()
.
When a function returns a value, you have to assign it to something. Take, for instance, simple math in any random programming language. The code:
x = sqrt(4)
print x
will output 2
, because at the end of the function sqrt()
, it returns its answer. Here, we assigned x
to be variable that sqrt(4)
gives a return
to. While it's true that:
sqrt(4)
will also print 2
to the console, this is because of fool-proofing by language developers, where in fact the language assumes you want the code printed. You're not telling it to do that.
So, when you run the lines of code:
inData()
triangle(base, height)
You are basically saying:
run the function inData()
run the function triangle(base, height)
When, because of their returns
, you need to be saying:
set <variable1> equal to the return of inData()
set <variable2> equal to the return of triangle(base,height)
(there is more simplification to be done here, but we'll approach it in a moment).
One last thing on return
. In programming, it is useless to write:
x = 1+1
return x
When return 1+1
accomplishes the same thing. Thus, no need to define what the area
of a triangle will be and then return
the area
. Just tell the function to return
what it calculates the area
to be in the same line of code!
Have I lost you? Still with me? Good!
Your code has a few structural problems that, while it may work, would baffle any more seasoned programmer that looked at it. While we're here, why don't we see if I can have you understand what a better practice for this would be.
In your code, you have written (in a summarized form)
variables defined that you don't need
def FunctionThatGathersData()
def FunctionThatDoesTheMath(x,y)
if (condition)
FunctionThatGathersData()
FunctionThatDoesTheMath(x,y)
print out the results
The structure of this would confuse a programmer who has more experience. He might ask the following questions:
FunctionThatGathersData
and FunctionThatDoesTheMath
?Some of these reasons are already exposited upon above, but let's get to the last two questions.
Why are the variables defined?: On one hand, Python handles variables during execution. So you never have to define them ahead of time, but you can, and the advantage of this is as follows:
x = 0
def Function()
x = 5
y = 10
Looking at this code, you might wonder why x
is defined. The simple answer is that Python will see that you already have an x
, and thus, when you run Function()
, you want to overwrite it with the work inside the function. y
on the other hand, has no previous definition, and thus a new variable will be created.
However, in your function we don't need any of that because your answer, in its best form, won't need to depend on x
outside the function.
Why can't we just combine the two functions together, using what we learned about parameters, arguments, and returns? (hint: we can!)
Here is a new snippet of code that you should now be able to read and understand. Clear your head of what you've read for a moment and see if it makes sense. In it, you will:
DoTheMathAndThenGiveMeTheValueBack
__name__ == '__main__'
base
and height
and then area
based on the function's return.def CalculateTriangleArea(b,h):
return b / 2 * h
if __name__ == '__main__':
base = float(raw_input("Base:"))
height = float(raw_input("Height:"))
area = CalculateTriangleArea(base,height)
print "The area of a triangle of base", base, "and height", height, "will be", area
If you do not grok this, please, comment and ask me more because I remember struggling with this and know what misunderstandings you are having.
Oh! And I forgot to mention to you what to do about multiple returns
.
In the event that you need to return more than one value in a function, you can do so through an array
or a tuple
. This is just a list of values you have stored. You can access any item in an array
or tuple
by including the index
at the end in the form of [i]
, where the first item is at [0]
. For example:
def Function():
string1 = "nobody"
string2 = "expects"
string3 = "the"
string4 = "spanish"
string5 = "inquisition"
return string1, string2, string3, string4, string5
print Function()[0]
print Function()[1]
print Function()[2]
print Function()[3]
print Function()[4]
print Function() #prints the whole tuple!
Will get you:
nobody
expects
the
spanish
inquisition
('nobody', 'expects', 'the', 'spanish', 'inquisition')
Understand? :)
For more hands-on work in python, try this amazing Python tutorial.
Upvotes: 3
Reputation: 3066
The problems with your code:
# Area of a triangle
base = 0 # You don't need to initialize these values. Even if you want
height = 0 # to make these global you can simple assign inside the if
area = 0 # __name__ == '__main__' condition
def inData():
base = float(raw_input("Base:"))
height = float(raw_input("Height:"))
return base # return immediately stops the execution of the function
return height # and returns the value
def triangle(b,h):
area = b / 2 * h
return area
if __name__ == '__main__':
inData() # You are not assigning the returned value to any variable
triangle(base, height)
print "The area of a triangle of base", base, "and height" , height, "will be", area
Correct version of your program:
# Area of a triangle
def inData():
base = float(raw_input("Base:"))
height = float(raw_input("Height:"))
return base, height
def triangle(b,h):
area = b / 2 * h
return area
if __name__ == '__main__':
base, height = inData()
area = triangle(base, height)
print "The area of a triangle of base", base, "and height" , height, "will be", area
Upvotes: 0
Reputation: 64258
When you do return
, the function immediately ends, returning the value. Therefore, your inData
function will only return the base, not the height. In addition, you seem to be asking the user to input the base and the height twice -- that's unnecessary, since your inData
function already does that
Rather, you want to return two values at the same time by doing something like this. (Note -- I renamed some of your functions for clarity)
# Area of a triangle
def get_user_input():
base = float(raw_input("Base:"))
height = float(raw_input("Height:"))
return base, height
def triangle_area(b, h):
area = b / 2 * h
return area
if __name__ == '__main__':
base, height = get_user_input()
area = triangle_area(base, height)
print "The area of a triangle of base", base, "and height" , height, "will be", area
Upvotes: 3