cmimm101
cmimm101

Reputation: 37

Basic Functions Help - Python

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

Answers (3)

jwarner112
jwarner112

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

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!

Simplification of your code

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:

  • What?
  • Why are you returning things this way?
  • Why are the variables defined?
  • Why don't you combine 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:

  • Define your function DoTheMathAndThenGiveMeTheValueBack
  • Decide if __name__ == '__main__'
  • Provide your values (put them in variables)
  • Pass those variables as arguments into the function
  • tell the program to print the base and height and then area based on the function's return.

The Code

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

Ankur Ankan
Ankur Ankan

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

Michael0x2a
Michael0x2a

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

Related Questions