ShellOnPrawn
ShellOnPrawn

Reputation: 3

Function not being called despite conditions being met (ie, string value is as expected)

very new to python, just teaching myself and trying to build a library of useful functions and ways of calling them.

I'm using this as a kind of "if x="n" goto: y" replacement in order to keep looping the question until a usable set of answers are inputted.

For some reason, it only loops once then, if it still get's an unusable answer, it reports the error and just quits, despite the "error_c" string being equal to "y"

Relevant chunk of code below; answers on a postcard please

#defies strings for error checking
error_c=""
x=""
y=""
z=""

def ages():
    age_str = input("How old are you and your two siblings?: ")
    error_c="n"             #Establishing/re-establishing the error check string
    tokens = age_str.split() 
    try:
        x = int(tokens[0])   
        y = int(tokens[1])
        z = int(tokens[2])
    except IndexError:       #various error checks
        error_c="y"             
        x, y, z = "", "", ""
        print("You must enter 3 values")
    except NameError:
        error_c="y"
        x, y, z = "", "", ""
        print("You must enter 3 values")
    except ValueError:      
        error_c="y"
        x, y, z = "", "", ""
        print("Invalid integer format")
    return (x, y, z, error_c)

x, y, z, error_c = ages()

if error_c == "n":      #only printing if error checks haven't retunred a positive
    print (" ")
    print ("x = "+str(x))
    print (" ")
    print ("y = "+str(y))
    print (" ")
    print ("z = "+str(z))
elif error_c =="y":
    x, y, z, error_c = ages()
elif error_c =="":
    print ("String values not returned from ages function")
else:
    print ("unknown error")

print (error_c)     #Checking that the correct value for looping is in play

Upvotes: 0

Views: 46

Answers (2)

Brian Behe
Brian Behe

Reputation: 542

If you want to execute ages() continually until you get acceptable input then you can wrap your code in a while loop and only terminate when the appropriate condition has been met. For example:

#defies strings for error checking
error_c=""
x=""
y=""
z=""

def ages():
  age_str = input("How old are you and your two siblings?: ")
  error_c="n"             #Establishing/re-establishing the error check string
  tokens = age_str.split() 
  try:
    x = int(tokens[0])   
    y = int(tokens[1])
    z = int(tokens[2])
  except IndexError:       #various error checks
    error_c="y"             
    x, y, z = "", "", ""
    print("You must enter 3 values")
  except NameError:
    error_c="y"
    x, y, z = "", "", ""
    print("You must enter 3 values")
  except ValueError:      
    error_c="y"
    x, y, z = "", "", ""
    print("Invalid integer format")
  return (x, y, z, error_c)

x, y, z, error_c = ages()


while(True):
  if error_c == "n": #only printing if error checks haven't retunred a positive
    print (" ")
    print ("x = "+str(x))
    print (" ")
    print ("y = "+str(y))
    print (" ")
    print ("z = "+str(z))
    break #added a break statement to exit the while loop
  elif error_c =="y":
    x, y, z, error_c = ages()
  elif error_c =="":
    print ("String values not returned from ages function")
  else:
    print ("unknown error")
    break
  print (error_c)     #Checking that the correct value for looping is in play

Upvotes: 0

Ben Taylor
Ben Taylor

Reputation: 515

You don't have any loop construction in there. You call ages() once, if it fails you call it again, and then you're out of code.

You want something like:

error_c = "n"
while error_c == "n":
    x, y, z, error_c = ages()

Incidentally, it's both more "pythonic" and faster (and less error-prone) to use boolean True or False as the values for error_c, not strings:

error_c = True
while error_c:
    x, y, z, error_c = ages()

# ...and then in ages() where you're setting error_c to "n" 
# set it to True, and where you're setting error_c to "y" set 
# it to False, meaning there either is or is not an error

Upvotes: 1

Related Questions