I can't redefine global variable, despite it being returned by a function

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

once the work_shift(work) function asks wether user wish to continues and user says yes, the current_radius variable should be equal to what the dropping_load(current_radius) returned (after previously assigning it a value of next_radius, yet the code goes back to the place where current_radius was defined for the first time (current_radius = minimum radius)

also, functions def user_min_radius(min_radius) and def user_max_radius(max_radius) when they get to the block except ValueError: print("please enter a valid radius in metres") behave as expected, print the message and continue with the script, now seemingly similar block in funtions def lifting(current_radius) and def dropping_load(current_radius) causes them to throw the ValueError back at me and stop the script.

please help, thanks!

When you pass ‘current_radius’ into dropping_load and lifting functions, you are creating two new local variables - you’re not altering the global variable with the same name.
Also, whilst you are returning the values from the functions, you are not assigning them to anything so the value is being lost.
e.g.
value = function(arg)

1 Like

Hi, that’s what i thought, but when i try to specify inside these two functions that this is global current radius inside the function, i get SyntaxError: name 'current_radius' is parameter and global

How can i let the computer know, that this is the same current_radius all throughout the code?

It cannot be both a local parameter AND have global bindings at the same time. Remove the parameter (and argument) or remove the global statement and return a new value that can be reassigned to the global.

i tried that. so in the dropping_load function i comment out current_radius = next_radius statement, then return next_radius instead of current_radius, then i modify work_shift fnction from:

def work_shift(work):
    while work == True:
        lifting(current_radius)
        answer = input(
            "Would you like to continue lifting? Press 'y' and 'enter' for 'yes'")
        if answer != "y":
            print("Bye")
            work = False
to:

def work_shift(work):
while work == True:
lifting(current_radius)
answer = input(
“Would you like to continue lifting? Press ‘y’ and ‘enter’ for ‘yes’”)
if answer != “y”:
print(“Bye”)
work = False
else:
lifting(next_radius)

then the script goes through the whole code (work_shift function) once and when answered that i wish to continue i get NameError: name 'next_radius' is not defined

Where current_radius is a global? You have not defined next_radius.

current_radius is a global yes. next_radius is defined inside dropping_load function and then returned so it should be available globally. clearly it’s not, same problem i had when the function was assigning the value of next_radius to current_radius and returning current_radius. i thought once a function returns a variable then it’s available globally.

That variable will need to be returned to your function and assigned. What is lifting() doing?

Can you show us your complete revised (and formatted) code?

#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?"))

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

def user_max_radius(max_radius):
  try:
    max_radius = float(max_radius)
    max_radius = round(max_radius, 1)
    if max_radius <= min_radius:
      print("please enter a radius that is higher than the minimum radius")
      max_radius = user_max_radius(input("What's the maximum radius in metres?"))
      return max_radius
      
    else:
      print("The maximum radius is set to " + str(max_radius) + "m")
      return max_radius

  except ValueError:
    print("please enter a valid radius in metres")
    max_radius = user_max_radius(input("What's the maximum radius in metres?"))
    return max_radius
  
max_radius = user_max_radius(input("What's the maximum radius in metres?"))

current_radius = min_radius


#lifting() function will ask the user for a location of the load that needs to be moved and if it's between it's minimum and maximum radius the crane will pick it up

def lifting(current_radius):
  print("current radius is " + str(current_radius) + " m.")
  next_radius = input("At what radius is the next load?")
  next_radius = float(next_radius)
  next_radius = round(next_radius, 1)
  try:
    if next_radius < min_radius or next_radius > max_radius:
      print("The load is not within the reach of the crane")
      return current_radius
    else:
      current_radius = next_radius
      print("current radius is " + str(current_radius) + " m.")
      dropping_load(current_radius)
  except ValueError:
    print("Enter a valid radius in metres")
    return current_radius

#dropping_load() function will ask the user what is the load's destination and if it's within the crane's reach, the crane will deliver the load to that location.

def dropping_load(current_radius):
  next_radius = input("To what radius is this going?")
  next_radius = float(next_radius)
  next_radius = round(next_radius, 1)
  try:
    if next_radius < min_radius or next_radius > max_radius:
      print("This radius is not within the reach of the crane")
      dropping_load(current_radius)
    else:
      current_radius = next_radius
      print("current radius is " + str(current_radius) + " m.")
  except ValueError:
    print("Input a radius in metres")
    dropping_load(current_radius)

work = True

#work_shift function will put everything together and after delivering the load will ask the user if there is another load to lift, in wich case the whole process will be repeated.

def work_shift(work):
  while work == True:
    lifting(current_radius)
    answer = input("Would you like to continue lifting? Press 'y' and 'enter' for 'yes'")
    if answer != "y":
      print("Bye")
      work = False

work_shift(work)

this is the original code where dropping_load returns current_radius. Returning next_radius instead doesn’t solve it and makes the code more complicated.

Suggest write the code to work with supplied inputs (not user inputs) and get the code working from values where you know what to expect. The code is far more complicated than it needs to be.