title: A variable changing without any apparent reason
body: <p>In my doctorate classes we were assigned to do a single neuron neural network that calculates OR, AND , XOR operations with a Python script. I have a very weird error that drives me crazy in my code. </p>
  
  <p>First of all I have a Vector class:</p>
  
  <pre><code>class Vector3D:                                                                            # Defines the Vector3D class
      def __init__(self,bias,x,y):                                                           # Defines the variables for the Vector3D class
          self.bias = bias
          self.x = x
          self.y = y
      def __add__(self,other):                                                               # Defines the built-in "add" ("+") operation for Vector3D
          return Vector3D(self.bias+other.bias,self.x+other.x,self.y+other.y)
      def __mul__(self,other):                                                               # Defines the built-in "multipication" ("*") operation for Vector3D
          if(isinstance(other,int)):
              return Vector3D(self.bias * other, self.x * other, self.y * other)
          else:
              return Vector3D(self.bias * other.bias, self.x * other.x, self.y * other.y)
      def __str__(self):                                                                     # Defines the built-in string return value for Vector3D
          return "Vector(%f,%f,%f)" % (self.bias, self.x, self.y)
      def UpdateWeights(self,eta, targetOutput, currentOutput, valueX, valueY, valueBias):   # Function for updating the weights
          self.bias = self.bias + (eta * (targetOutput - currentOutput) * valueBias)
          self.x = self.x + (eta * (targetOutput - currentOutput) * valueX)
          self.y = self.y + (eta * (targetOutput - currentOutput) * valueY)
          return Vector3D(self.bias,self.x, self.y)
      def getX(self):                                                                        # Function for getting the x value of a vector
          return self.x
      def getY(self):                                                                        # Function for getting the y value of a vector
          return self.y
      def getBias(self):                                                                     # Function for getting the bias value of a vector
          return self.bias
  </code></pre>
  
  <p>Secondly, I have a neuron class:</p>
  
  <pre><code>class Neuron:                                                                                   # Defines the Neuron class
      def __init__(self, dataTable, eta, theta, targetArrayOr, targetArrayAnd, targetArrayXor):    # Function for defining the variables for initialization
          self.dataTable = dataTable
  
          self.eta = eta
          self.theta = theta
  
          self.targetArrayOr = targetArrayOr
          self.targetArrayAnd = targetArrayAnd
          self.targetArrayXor = targetArrayXor
  
          self.wVbias = random.uniform(-0.2, 0.2)
          self.wVX = random.uniform(-0.2, 0.2)
          self.wVY = random.uniform(-0.2, 0.2)
          self.weightVector = Vector3D(self.wVbias,self.wVX,self.wVY)
  
          self.weightVectorOr = Vector3D(0,0,0)
          self.weightVectorAnd = Vector3D(0,0,0)
          self.weightVectorXor = Vector3D(0,0,0)
  
      def TrainForOr(self) :                                                                       # Function training the weight vector for OR operation
          iteration = 0                                                                            # Number of iterations
          check = 0                                                                                # Initial value of the while loop
          finalCheck = 200                                                                         # Final value of the while loop
          targetReached = False                                                                    # Boolean variable for if the target is reached
          rowNb = 0                                                                                # Initial value of the index number in the data table
          weightVector = self.weightVector                                                # Initial weight vector
          print(self.weightVector)
          while check &lt; finalCheck :                                                               # Makes sure that the entire loop runs 200 times for accuracy
              while rowNb &lt; len(self.dataTable) :                                                  # Makes sure every row is iterated
                  while targetReached == False:
                      D1dotW = DotProduct(self.dataTable[rowNb],weightVector)                      # Dot product of the input vector and the weight vector
                      if(D1dotW &gt; self.theta):
                          currentOutput = 1
                      elif(D1dotW &lt;= self.theta):
                          currentOutput = 0
                      if(currentOutput == self.targetArrayOr[rowNb]):
                          targetReached = True
                      else:
                          iteration = iteration + 1
                          print(self.weightVector)
                          weightVector = weightVector.UpdateWeights(self.eta,self.targetArrayOr[rowNb], currentOutput, self.dataTable[rowNb].getX(), self.dataTable[rowNb].getY(), self.dataTable[rowNb].getBias())
                          print(self.weightVector)
                          targetReached = False
  
  
                  targetReached = False
                  rowNb = rowNb + 1
  
              check = check + 1
              rowNb = 0
          self.weightVectorOr = weightVector                                                       # Sets the OR weight vector
          return "OR - Final weight vector is " + str(weightVector) + " " + "("+ str(iteration) + " iteration(s) )"
  </code></pre>
  
  <p>I also have other methods for AND and XOR but they are the same with above with minor changes.</p>
  
  <p>Now the above code "works" as the "error" is very minor and does not change the end result. But I want to understand why it happens.</p>
  
  <p>When I run the above snippet along with the rest of the GUI code etc., I get the console result:</p>
  
  <pre><code>Vector(-0.051856,-0.099352,0.079270)
  Vector(-0.051856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  Vector(-0.001856,-0.099352,0.079270)
  </code></pre>
  
  <p>This means that the initial <code>self.weightVector</code> is changing at the line:</p>
  
  <pre><code>weightVector = weightVector.UpdateWeights(self.eta,self.targetArrayOr[rowNb], currentOutput, self.dataTable[rowNb].getX(), self.dataTable[rowNb].getY(), self.dataTable[rowNb].getBias())
  </code></pre>
  
  <p>I don't understand this because I am not changing <code>self.weightVector</code> in any way in the <code>UpdateWeights</code> method.</p>
  
  <p>If anyone can explain why this happens it will be appreciated.</p>