0

I'm trying to control input to allow only greater than 0 numbers, but upon testing this block of text, if I enter an illegal character first (a string, 0 or negative number), receive the error output and then input a valid value, it returns the first value I entered instead of the valid one just entered (which then causes the rest of my script to fail due to type mismatch or illogical values). I've tried moving the "return x" around but it does the same thing either way. says "variable x referenced before assignment" in the second case.

def getPrice():
    try:
        x = float(input("What is the before-tax price of the item?\n"))
        if x <= 0:
            print("Price cannot be less than or equal to zero.")
            getPrice()
        return x
    except ValueError:
        print("Price must be numeric.")
        getPrice()

and

def getPrice():
    try:
        x = float(input("What is the before-tax price of the item?\n"))
        if x <= 0:
            print("Price cannot be less than or equal to zero.")
            getPrice()
    except ValueError:
        print("Price must be numeric.")
        getPrice()
    return x

How can I fix this?

Also if you're curious, this is for a school assignment, I've completed the entire program on my own but I just can't figure out how to debug this.

Edit:

I got a working method now:

def getPrice():
    while True:
        try:
            x = float(input("What is the before-tax price of the item?\n"))
        except ValueError:
            print("Price must be numeric.")
            continue
        if x <= 0:
            print("Price cannot be less than or equal to zero.")
        else:
            return x
            break

and fixed the original code block (but it still uses recursion):

def getPrice():
        try:
            x = float(input("What is the before-tax price of the item?\n"))
            if x <= 0:
                print("Price cannot be less than or equal to zero.")
                x = getPrice()
        except ValueError:
            print("Price must be numeric.")
            x = getPrice()
        return x
Sparx
  • 66
  • 6
  • 1
    What does the getPrice() function do? Perhaps you should show us all your code. x will always stay to what it was last assigned. And you only assign it once in your code. I believe you may be having trouble understanding variable scope. – korylprince Sep 28 '12 at 07:07
  • Oops, forgot about that, added the function header to the question. Upon encountering an error it just refers back to itself to try again (not sure if that's bad practice or not..) – Sparx Sep 28 '12 at 07:14
  • The code seems to be formatted incorrectly, but I get the point. You're using recursion. In some cases that's okay, but in this case it's really not since enough bad input from a user would crash your program after hitting the stack limit. – korylprince Sep 28 '12 at 07:19
  • Actually, if the input is bad and the exception triggers it never gets assigned *at all*. That should tell you something about the second error you're getting. Now when you call getPrice(), what happens to its return value? – korylprince Sep 28 '12 at 07:27
  • Oop. In your third code block, you're using recursion again inside your while loop! While that should still work, it's not what you want. Remember any time you make a function call itself, it's recursion. Change that function call to "next". – korylprince Sep 28 '12 at 07:59

1 Answers1

0

I'm not going to spell out an answer since it is homework, but I will point you in the right direction. First I suggest using a while loop instead of recursion.

The code might look something like:

while True:
    try:
        x = <get input>
        if input is good:
            break
        else:
            <print error>
    except badstuff:
        <Print error>
        next #redundant in this case as we'd do this anyways

Second, the problem you're having now has everything to do with variable scope. When bad input happens you call the function again, but do nothing with the output.

Remember that the x in the first function call is completely separate from the x in the second function call.

So if you intend to use recursion, you need to figure out how to pass the x value "back up the chain."

korylprince
  • 2,969
  • 1
  • 18
  • 27
  • I have no idea how to pass the x value "back up the chain." However, if I do use a while loop, should I keep the try and except block? – Sparx Sep 28 '12 at 07:26
  • Yes, you should keep the try except clause. You always want that if you're parsing unknown data. But in the exception instead of calling the function you would use the next keyword to skip to the next iteration. – korylprince Sep 28 '12 at 07:30
  • What I'm getting at about passing up the chain, is that when you call getPrice, the output disappears because you don't assign anything to it. In order to give the output to the parent function, you need to assign a variable to it. So in this case you would write x=getPrice(). Now x gets updated with the new value. Before the new x you got died because you never passed it on. – korylprince Sep 28 '12 at 07:33
  • Ok, I got it to work with a while loop (see the OP), but I have 2 questions: is the "return x" along with "break" needed, or just return x? Also, I got my original method working by adding "x = getPrice()" to the if block and the except block, but I would still want to use a while loop to avoid hitting the stack limit correct? – Sparx Sep 28 '12 at 07:49
  • First, in your exception, replace x=0 with "next". This will skip everything and go back to the top of the loop which is slightly faster. Just return x. You would use break if you still needed to do some processing on x inside of the function. Yes, use the whole loop. It's a better decision in this case. Generally you would use recursion for more mathy algorithms. I hope you have more understanding now! – korylprince Sep 28 '12 at 07:55
  • Tried "next", got an error, but replaced it with "continue" and now it works great. Thanks for your help! – Sparx Sep 28 '12 at 08:05
  • Sorry about that. "next" is for for loops. If you feel your question has been answered, please select the answer. Glad we could help! – korylprince Sep 28 '12 at 08:09