0

I'm in the midst of coding a simulation for studying UAV interaction in swarms and obstacle avoidance scenarios. The issue I'm having currently is in getting the vehicles to update their positions. Basically, I have a base class which contains the update() method which does the calculation to arrive at the new position and velocity. The actual objects in the sim code are instances of a subclass of this, and in the subclass's update() method, all I do is update the acceleration vector and call super().update(). However, the values are retained after the function call. I assume this is just a lack of knowledge of Python on my part, as I'm just starting with it (coming from C++ for many years). The searches I've done for pass by reference and such are giving me good information, but so far I can't get an answer to this specific problem. Here's the code:

[EDIT] Per jonrsharpe's request, I've written out a minimal example that encapsulates the problem I'm having. Here's the minimal code:

class UpdateTester:
    x = [0,0]

    def update(self):
        for elem in self.x:
            elem += 1

class SubClassTester(UpdateTester):
    def update(self):
        super(SubClassTester,self).update()


a = SubClassTester()

for i in range(1,5):
    a.update()
    print(a.x)

So basically, per my(admittedly limited) understanding, I should get an output which shows increments to the list a.x. However, my output from running this example shows repeated [0,0]'s as output.

gankoji
  • 853
  • 1
  • 10
  • 23
  • I should add that I track the position of the objects by printing each state vector, which are initialized to [0,0]. Through the whole simulation run, the states never change from that, which is how I know the values aren't being updated for each instance. – gankoji Oct 14 '14 at 18:21
  • 1
    Could you cut and add where necessary to convert this to a complete [minimal example](http://stackoverflow.com/help/mcve), with input data, so we can recreate the issue? – jonrsharpe Oct 14 '14 at 20:16
  • Certainly, give me a few minutes to put it together :) – gankoji Oct 14 '14 at 20:23
  • Output from my interpreter: [0, 0] [0, 0] [0, 0] [0, 0] The thread 'MainThread' (0x1c49c) has exited with code 0 (0x0). The program '[97620] python.exe' has exited with code 0 (0x0). – gankoji Oct 14 '14 at 20:31
  • 1
    `elem += 1` **does not** change `x` (which is a *class attribute*, by the way); see e.g. http://stackoverflow.com/q/14406449/3001761 – jonrsharpe Oct 14 '14 at 20:36
  • The enumerate solution given in that post is working for the minimal example. I don't understand comprehensions enough to try implementing his comprehensions based solution yet, so I'll work on that and update when I have results there. – gankoji Oct 14 '14 at 20:57
  • For now, I'm using enumerate in my simulation program and it's working fine. Comprehensions for lists are going to take me a while to get, but I wanted to post here that the problem has been solved, at least for now. – gankoji Oct 14 '14 at 22:04

1 Answers1

1

Integers are immutable in Python therefore for elem in self.x: elem += 1 does nothing. It doesn't change self.x. If you want to change self.x:

for i, value in enumerate(self.x):
    self.x[i] = value + 1

Also UpdateTester.x is a class variable. It is the same for all instances. Lists are mutable in Python therefore if you call .update() on any instance of UpdateTester class then you change the list for all of them. To create per instance list instead, put it in __init__():

class UpdateTester(object):
    def __init__(self, **kwargs):
        super(UpdateTester, self).__init__(**kwargs) # for multiple inheritence
        self.x = []
jfs
  • 399,953
  • 195
  • 994
  • 1,670