-5

I am trying to make a grid, starting at (0, 0), each different function changes your value, this is the code:

X = 0
Y = 0
MaximumX = 5
MinimumX = -5
MaximumY = 5
MinimumY = -5

def Move(Direction):
    Direction_functions[Direction]
    print (str(X),",",str(Y))

def Left(CoordinateX):
    if CoordinateX != MinimumX:
        CoordinateX -= 1
    else:
        Fail()

def Right(CoordinateX):
    if CoordinateX != MaximumX:
        CoordinateX += 1
    else:
        Fail()

def Up(CoordinateY):
    if CoordinateY != MinimumY:
        CoordinateY -=1
    else:
        Fail()

def Down(CoordinateY):
    if CoordinateY != MaximumY:
        CoordinateY += 1
    else:
        Fail()

def Fail():
    print ("Failure\n", str(X),",",str(Y))

Direction_functions = [Left(int(X)), Right(int(X)), Up(int(Y)), Down(int(Y))]

while True:
    Number = input("")
    Move(int(Number)) #Infinite loop is for testing purposes

This is the output after trying to move left:

>>> ================================ RESTART ================================
>>> 
1
0 , 0
1
0 , 0
1
0 , 0
1
0 , 0
1
0 , 0
1
0 , 0
1
0 , 0
styvane
  • 59,869
  • 19
  • 150
  • 156
Paldox
  • 33
  • 1
  • 5
  • 6
    Instead of posting garbage text, you could explain which output you expect. – Felix Kling May 24 '15 at 16:56
  • 1
    Also, your directions array contains values, not functions (the functions are called just once when the array is initialized). If you want an array of functions, it would look like `Direction_functions = [Left, Right, Up, Down]` – nobody May 24 '15 at 17:02

3 Answers3

1

You are attempting to set values to global variables without declaring them as global within the scope of your functions, but instead passing them as parameters, which in python are passed by value (meaning you can't change the original variable). This causes python to change local variables inside each function that overshadow the global variables, causing their values to stay the same in the global scope. If you want your functions to modify global variables, you must declare them so, for example:

def Left():
    global CoordinateX
    if CoordinateX != MinimumX:
        CoordinateX -= 1
    else:
        Fail()
tbrisker
  • 15,518
  • 1
  • 16
  • 17
1
Direction_functions = [Left(int(X)), Right(int(X)), Up(int(Y)), Down(int(Y))]

You assign the return values of the functions to an array. Since none of the functions return anything explicitly, that value is None. You end up with:

Direction_functions = [None, None, None, None]

Left and all the other direction functions only operate on a copy and don't return anything, they are useless as they are at the moment.

def Left(CoordinateX):  # the parameter is a copy, you don't change anything.
    if CoordinateX != MinimumX:
        CoordinateX -= 1
    else:
        Fail()

Lastly lets get to your Move function:

def Move(Direction):
    Direction_functions[Direction]
    print (str(X),",",str(Y))

Direction_function[Direction] looks up the value of a list and does nothing to it (they are all None anyways in your code).

Now you print the values of X and Y global variables that you changed nowhere in your code.

martineau
  • 119,623
  • 25
  • 170
  • 301
AliciaBytes
  • 7,300
  • 6
  • 36
  • 47
0

The code in your question is invalid. For example the Direction_functions[Direction] in Move() doesn't do anything useful. However I think I understand what you're asking.

Integers are immutable, so when you try to change the value of one, a new one is created and the result is assigned to variable name being used.

Function arguments are essentially local variables, so in each of your functions CoordinateX or CoordinateY are just names for the value you passed the function. When your functions change this value, they are only changing what the argument name refers to, locally.

One way to fix this is to pass the values in a mutable container object, like a list, and then modify the contents of the list. Another, all too common, workaround is to use global variable and have the functions modify those.

Here's a working version of your code that minimizes the use of global variables by passing a list with the x and y coordinates in it:

X, Y = 0, 1
MINIMUM_X, MAXIMUM_X = -5, 5
MINIMUM_Y, MAXIMUM_Y = -5, 5

def Move(Direction, position):
    DIRECTION_FUNCTIONS[Direction](position)
    print('{}, {}'.format(*position))

def Left(position):
    if position[X] > MINIMUM_X:
        position[X] -= 1
    else:
        Fail(position)

def Right(position):
    if position[X] < MAXIMUM_X:
        position[X] += 1
    else:
        Fail(position)

def Up(position):
    if position[Y] > MINIMUM_Y:
        position[Y] -= 1
    else:
        Fail(position)

def Down(position):
    if position[Y] < MAXIMUM_Y:
        position[Y] += 1
    else:
        Fail(position)

def Fail(position):
    print('Failure\n{}, {}'.format(*position))

DIRECTION_FUNCTIONS = [Left, Right, Up, Down]

location = [0, 0]
while True:  # Infinite loop for testing purposes
    Number = input("enter a number from 0 to 3: ")
    direction = int(Number)
    if 0 <= direction <= 3:
        Move(direction, location)
    else:
        print("Input out of range, try again.")
martineau
  • 119,623
  • 25
  • 170
  • 301