Image

Imagedotplaid wrote in Imagepython_dev

Unclear On Global Variable Use

Hi all,

I have defined global variables that I *think* are passed to functions, but I'm running into a problem:

# ** begin file coordinate_transformer **

#converts points between cartesian, cylindrical, and spherical coordinate systems

#to-do list: graphical interface (PyJamas?); volumes;


import math

height, phi, radius, theta, x, y, z = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
menu_choice = 0
in_sys = "input_coordinate_system"

def print_menu():
    print                                    #purely for aesthetics
    print "LIST OF OPTIONS (ENTER '0' TO SHOW THIS LIST)"
    print "1. Cartesian to Cylindrical"
    print "2. Cartesian to Spherical"
    print "3. Cylindrical to Cartesian"
    print "4. Cylindrical to Spherical"
    print "5. Spherical to Cartesian"
    print "6. Spherical to Cylindrical"
    print "7. Exit"

def cartesian (in_sys, num1, num2, num3):
    if in_sys == "cylindrical":                #Cylindrical to Cartesian
        x = radius*round(math.cos(math.radians(theta)),3)
        y = radius*round(math.sin(math.radians(theta)),3)
        z = height*1.0
    elif in_sys == "spherical":                #Spherical to Cartesian
        x = radius*round(math.sin(math.radians(theta)),3)*round(math.cos(math.radians(phi)),3)
        y = radius*round(math.sin(math.radians(theta)),3)*round(math.sin(math.radians(phi)),3)
        z = radius*round(math.cos(math.radians(theta)),3)
    return x, y, z

def cylindrical (in_sys, num1, num2, num3):
    if in_sys == "cartesian":                #Cartesian to Cylindrical
        radius = round(math.sqrt(x**2 + y**2),3)
        theta = round(math.atan(y/x),3)
        height = z*1.0
    elif in_sys == "spherical":                #Spherical to Cylindrical (out of order due to need to preserve radius value)
        height = radius*round(math.cos(phi),3)
        radius = radius*round(math.sin(phi),3)
        theta = theta*1.0
    return radius, theta, height

def spherical (in_sys, num1, num2, num3):
    if in_sys == "cartesian":                #Cartesian to Spherical
        radius = round(math.sqrt(x**2 + y**2 + z**2),3)
        theta = round(math.atan(y/x),3)
        phi = round(math.acos(z/radius),3)
    elif in_sys == "cylindrical":            #Cylindrical to Spherical (out of order due to need to preserve radius value)
        phi = round(math.atan(radius/height),3)
        radius = round(math.sqrt(radius**2 + height**2),3)
        theta = theta*1.0
    return radius, phi, theta

print_menu()
while menu_choice != 7:
    print
    menu_choice = input ("Select an option: ")
    if menu_choice == 0:
        print_menu()
    elif menu_choice == 1:                    #Cartesian to Cylindrical
        x = input ("Enter x: ")
        y = input ("Enter y: ")
        z = input ("Enter z: ")
        radius, theta, height = cylindrical("cartesian", x, y, z)
        print "The cylindrical coordinates are ( r = ", radius, ", theta = ", theta, ", h = ", height, ")"
    elif menu_choice == 2:                    #Cartesian to Spherical
        x = input ("Enter x: ")
        y = input ("Enter y: ")
        z = input ("Enter z: ")
        radius, theta, phi = spherical("cartesian", x, y, z)
        print "The spherical coordinates are ( r = ", radius, ", phi = ", phi, ", theta = ", theta, ")"
    elif menu_choice == 3:                    #Cylindrical to Cartesian
        print "Radius is the magnitude of the P vector; Theta is the angle (between 0 & 360 degrees) from the X-axis"
        radius = input ("Enter the radius: ")
        theta = input ("Enter theta: ")
        height = input ("Enter the height: ")
        x, y, z = cartesian("cylindrical", radius, theta, height)
        print "The Cartesian coordinates are ( x = ", x, ", y = ", y, ", z = ", z, ")"
    elif menu_choice == 4:                    #Cylindrical to Spherical
        radius = input ("Enter the radius: ")
        theta = input ("Enter theta: ")
        height = input ("Enter the height: ")
        radius, theta, phi = spherical("cylindrical", radius, theta, height)
        print "The Spherical coordinates are ( r = ", radius, ", phi = ", phi, ", theta = ", theta, ")"       
    elif menu_choice == 5:                    #Spherical to Cartesian
        print "Radius is the magnitude of the P vector; Theta is the azimuthal angle (between 0 & 360 degrees); Phi is the elevation or zenith angle (between 0 & 180 degrees)"
        radius = input ("Enter the radius: ")
        theta = input ("Enter the theta: ")
        phi = input ("Enter phi: ")
        x, y, z = cartesian("spherical", radius, theta, phi)
        print "The Cartesian coordinates are ( x = ", x, ", y = ", y, ", z = ", z, ")"
    elif menu_choice == 6:                    #Spherical to Cylindrical
        print "Radius is the magnitude of the P vector; Theta is the azimuthal angle (between 0 & 360 degrees); Phi is the elevation or zenith angle (between 0 & 180 degrees)"
        radius = input ("Enter the radius: ")
        theta = input ("Enter the theta: ")
        phi = input ("Enter phi: ")
        radius, theta, height = cylindrical("spherical", radius, theta, phi)
        print "The Cylindrical coordinates are ( r = ", radius, ", theta = ", theta, ", h = ", height, ")"


While debugging I get the following error while converting from Cylindrical to Spherical:

Traceback (most recent call last):
  File "/home/dotplaid/PythonMyStuff/coordinate_transformer.py", line 86, in <module>
    radius, theta, phi = spherical("cylindrical", radius, theta, height)
  File "/home/dotplaid/PythonMyStuff/coordinate_transformer.py", line 52, in spherical
    phi = round(math.atan(radius/height),3)
UnboundLocalError: local variable 'radius' referenced before assignment


I presume that the error is thrown because I'm using the variable radius incorrectly, but I don't see how. I would really much rather not rename radius in order to use it, so I changed the order of use in the cylindrical and spherical functions thinking that I could use the radius that was passed in and then re-evaluate it.

Any insights that don't involve creating temporary (local) variables are most appreciated.

All the best,
.plaid