1

I need to use variables created in one function as parameters/arguments in another function. I am not sure how to do so without getting a continuous error signal as I am repeating the function every 10 milliseconds. Here is the code:

def addFish():
    x = createRandomX()
    y = createRandomY()
    Dx = createRandomDx()
    Dy = createRandomDy()
    fish = canvas.create_image(x, y, image = fishRight)
    updateFish(x, y, Dx, Dy, fish)
    return x, y, Dx, Dy, fish


fishButton = Button(root, text = "Add a fish", command = addFish)
fishButton.grid(row = 1, column = 0)



def updateFish(x, y, Dx, Dy, fish):
    #global x, y, Dx, Dy, fish
    canvas.coords(fish, x , y )
    x = x + Dx
    y = y + Dy

    if x < 0 or x > 500:
        Dx = Dx * -1
    if y < 0 or y > 500:
        Dy = Dy * -1
    if Dx == 1:
        canvas.itemconfig(fish, image=fishRight)
    if Dx == -1:
        canvas.itemconfig(fish, image=fishLeft)

    canvas.after(10, updateFish(x, y, Dx, Dy, fish))


updateFish(x, y, Dx, Dy, fish)

root.mainloop()

So, when I do this i get the error that x is not defined. This is because when I call updateFish, the first argument x is not a global variable, it is only a local variable of addFish(). So, I need to know how to be able to use the variables in addFish() as arguments in the function updateFish.

I'm building a fish tank for class that has the fish bounce around continuously, but I need the updateFish function to work for all of the fish that I add--therefore it needs to be an argument in the function.

user3329772
  • 11
  • 1
  • 4
  • What do you expect the value of `x` to be at the time that you call `updateFish`? – BrenBarn Feb 19 '14 at 20:00
  • I want it to be the same random x that i created in the create a fish. I want to create a fish in a random location, then send that location to the update fish so that it can move. I only need that location once at the start of the updateFish, because once it gets in the update fish, the x and y values are going to start changing ever time the function is passed so that the fish moves around. – user3329772 Feb 19 '14 at 23:52
  • At the time of your first call to `updateFish`, you have never called `addFish`, so there is no created fish. – BrenBarn Feb 20 '14 at 02:09
  • yeah but the point is to be able to push the button whenever I want to add a fish. Even if i do call it before updateFish, it will not realize x as a variable because it is still local. I just tried it. – user3329772 Feb 20 '14 at 04:16

2 Answers2

1

The problem is that all your values are passed by value, so changing them within your function will not update the original variables from the function call:

>>> def test (x):
        x = x * 10
>>> x = 20
>>> test(x)
>>> x
20

If you want to keep a state for multiple fish, I would suggest you to create a fish type:

class Fish (object):
    def __init__ (self, x, y, dx, dy, canvas):
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.canvas = canvas
        self.image = canvas.create_image(x, y, image=fishRight)

Then, you can create a fish using Fish(x, y, dx, dy, canvas) and have a single object which you can pass by reference. Changing the values of that object will then update the values globally.

You can then also move some of the functions inside the class, as methods. E.g. the updateFish method would probably fit well inside the class.

poke
  • 369,085
  • 72
  • 557
  • 602
  • thank you for the help. I'm in a beginning python course so I doubt that this would be the way considering I have seen nothing like it before. Is there any way to do this which uses most of the concepts that I have in there so far? – user3329772 Feb 19 '14 at 20:51
1

Do you know about closures? Define foo within an enclosing function fooMama and foo has access to all of fooMama's local variables, even after fooMama returns.

Better explanation: https://stackoverflow.com/a/4020443/2037637

[edit] I realize this doesn't really answer your question but it might be helpful at least.

Community
  • 1
  • 1
Alex Shroyer
  • 3,499
  • 2
  • 28
  • 54