I don't know how to return a variable from my function regardless how many times the function itself is called inside

https://www.codecademy.com/workspaces/61784afc9187e265417290c1

I need help.
I understand why my function will return min_radius variable, only when user inputs a correct value on the first attempt, but i want it to be returned always, once user finally has input it.
Also, I’m happy with any other way of writing this function. I used try and except because i didn’t have any better idea.

Thanks in advance.

The problem is that you’re only actually setting min_radius on the first call. You have to remember that in python, variables scoped in functions exclusively live in those functions unless returned. And so when it’s if we think about what happens on a recursion call sequentially we can see the issue.

  1. Function is called with the initial user input. Let’s say the user inputs “ten”.
  2. This causes a value error within the try clause, forcing it to the exception.
  3. This then calls the function again with a new input call.
  4. This time the user inputs 10. This is an accepted input, therefore it executes the full try block.
  5. This call reaches the return within the else block, returning the value of min_radius which is 10.
  6. It steps back out to the first function call having executed the recursion. This then returns min_radius. Since this is the first function call, min_radius has the value of “ten”, and so this is what is returned.

Hopefully you can see the issue from the above. The recursive call is executing totally fine, however it’s never actually stored anywhere. The min_radius variable in each recursion call is bound to the scope of that call, and unless we save the return value to a variable we cannot use that value. Therefore the solution is to save the value of the recursion call to min_radius anywhere that it’s called within the function. This will carry the value through the calls and give you what you are looking for: see below.

#defining a function that allows a user to define a minimum radius of the crane in metres. user needs to give a value which is a number > 0 

def user_min_radius(min_radius):

  try:

    min_radius = float(min_radius)
    min_radius = round(min_radius, 1)

    if min_radius <= 0:
      print("please enter a valid radius in metres")
      min_radius = user_min_radius(input("What's the minimum radius in metres?"))
      return min_radius
    else:
      print("The minimum radius is set to " + str(min_radius) + "m")
      return min_radius

  except ValueError:
    print("please enter a valid radius in metres")
    min_radius = user_min_radius(input("What's the minimum radius in metres?"))
    return min_radius

  

min_radius = user_min_radius(input("What's the minimum radius in metres?"))
print(min_radius)
1 Like

wow, that was quick, definitely didn’t expect a solution so quick.

what would you different? is there a more concise and elegant way to write this function?

maybe it doesn’t need to be a function at all, or maybe it can be made into a “define a radius” function, which can be used for defining minimum, maximum and whatever other radius?

I don’t think there’s necessarily a correct way to do it. Personally I would have probably gone for a while loop that only breaks on a successful input, something like

def user_min_radius():
  valid_number = False
  while not valid_number:
    user_input = input("What's the minimum radius in metres? ")
    try:
      user_input_as_int = int(user_input)
      if user_input_as_int >= 0:
        valid_number = True
      else:
        print("Please input a valid positive integer in metres.\n")
    except ValueError:
      print("Please input a valid positive integer in metres.\n")
  
  print(f"The minimum radius is set to {user_input}m.\n")
  return user_input
  
print(user_min_radius())

Its another way of doing it, and I’ve always gravitated more towards loops even though I generally like the rest of the principles of functional programming. But there’s nothing wrong with a recursive function and many people prefer it, in most cases it’s really just personal preference.

1 Like