KernelPanic
KernelPanic

Reputation: 211

How do I fix UnboundLocalError error?

I made a program that is supposed to calculate the perimeter of a wall, and then calculate the cost of the paint needed to paint that wall based on the input.

Code:

def main():
length = float(input('Enter length: ')) #Get length.
width = float(input('Enter width: ' )) #Get width.
height = float(input('Enter height: ')) #Get height.
Paint_cost()
def Paint_cost (length, width, height): #Find total paint cost.
    perimeter = length + width *4 #Find perimiter.
sq_ft = perimeter * height #Find total sq. ft. amount.
Paint = sq_ft / 300 #Calculate paint gallons to nearest int.
round(Paint)
Total= Paint*40 #Calculate total cost.
return total #Display total.

main()

However Python keeps saying "UnboundLocalError: local variable 'Paint_cost' referenced before assignment". What am I doing wrong here?

Upvotes: 1

Views: 150

Answers (3)

ASCIIThenANSI
ASCIIThenANSI

Reputation: 893

You have a few problems:

  • First, you're defining the function Paint_cost() inside main(). You can define this outside of main(), and as long as it's defined before you call the main() function, it will work properly.
  • Second, return returns a value from a function, not print it.
  • Third, your indentation is off. Regardless of the other two errors, Python will raise an IndentationError if you tried to run this.
  • Fourth, total is undefined (you wrote it as Total.)
  • Finally, you're calling Paint_cost() without any arguments. You need to call it with Paint_cost(length, width, height).

This code works perfectly in Python 3:

def Paint_cost (length, width, height): #Find total paint cost.
    perimeter = length + width * 4 #Find perimiter.
    sq_ft = perimeter * height #Find total sq. ft. amount.
    Paint = sq_ft / 300 #Calculate paint gallons to nearest int.
    int(Paint)
    total = Paint*40 #Calculate total cost.
    return total #Display total.
def main():

    length = float(input('Enter length: ')) #Get length.
    width = float(input('Enter width: ' )) #Get width.
    height = float(input('Enter height: ')) #Get height.
    print(Paint_cost(length, width, height)) # Print the cost of the paint.

main()

This one is for Python 2:

def Paint_cost (length, width, height): #Find total paint cost.
    perimeter = length + width * 4 #Find perimiter.
    sq_ft = perimeter * height #Find total sq. ft. amount.
    Paint = sq_ft / 300 #Calculate paint gallons to nearest int.
    int(Paint)
    total = Paint*40 #Calculate total cost.
    return total #Display total.
def main():

    length = float(input('Enter length: ')) #Get length.
    width = float(input('Enter width: ' )) #Get width.
    height = float(input('Enter height: ')) #Get height.
    print Paint_cost(length, width, height)  # Print the cost of the paint.

main()

In this code specifically, print is the only change between Python 2 and 3. The function works without print in either version.
Let me know if something is wrong.

Upvotes: 2

Dan Loewenherz
Dan Loewenherz

Reputation: 11253

You're calling the function Paint_cost before it's defined. Move the Paint_cost function outside of main, and your program should run without an issue.

def Paint_cost (length, width, height): #Find total paint cost.
    return length + width *4 #Find perimiter.
    sq_ft = perimeter * height #Find total sq. ft. amount.
    Paint = sq_ft / 300 #Calculate paint gallons to nearest int.
    round(Paint)
    return Paint*40 #Calculate total cost.

def main():
    length = float(input('Enter length: ')) #Get length.
    width = float(input('Enter width: ' )) #Get width.
    height = float(input('Enter height: ')) #Get height.
    return Paint_cost(length, width, height)

main()

Other notes: You return total in the last line of main(), but that's also not defined anywhere. Python is case-sensitive, so total and Total are not the same thing.

Upvotes: 0

abarnert
abarnert

Reputation: 365995

However Python keeps saying "UnboundLocalError: local variable 'Paint_cost' referenced before assignment". What am I doing wrong here?

Exactly what it says:

Paint_cost()
def Paint_cost (length, width, height): #Find total paint cost.
    perimeter = length + width *4 #Find perimiter.
    # ...

You call Paint_cost() before you've defined it, so it has nothing to call yet, so it raises an exception.


To fix it, just don't do that. Move the call to Paint_cost after the definition. Or move the definition of Paint_cost out to global level. (If it's not accessing any local variables from main, it doesn't need to be defined inside main.)


The message may be slightly confusing because it refers to "assignment" and what you're doing is def Paint_cost(…):, not Paint_cost = …. But def is a kind of assignment, in that it's binding a new name.

Upvotes: 0

Related Questions