docs: def propagate(self, **args):
          """
          Propagates activation through the network. Optionally, takes input layer names
          as keywords, and their associated activations. If input layer(s) are given, then
          propagate() will return the output layer's activation. If there is more than
          one output layer, then a dictionary is returned.
  
          Examples:
  
          >>> net = Network() # doctest: +ELLIPSIS
          Conx using seed: ...
          >>> net.addLayers(2, 5, 1)
          >>> len(net.propagate(input = [0, .5]))
          1
          """
          self.prePropagate(**args)
          for key in args:
              layer = self.getLayer(key)
              if layer.kind == 'Input':
                  if self[key].verify and not self[key].activationSet == 0: 
                      raise AttributeError("attempt to set activations on input layer '%s' without reset" % key)
                  self.copyActivations(layer, args[key])
              elif layer.kind == 'Context':
                  self.copyActivations(layer, args[key])
              elif layer.kind == 'Output' and len(args[key]) == layer.size: # in case you expect propagate to handle the outputs
                  self.copyTargets(layer, args[key])
          self.verifyInputs() # better have inputs set
          if self.verbosity > 2: print("Propagate Network '" + self.name + "':")
          # initialize netinput:
          for layer in self.layers:
              if layer.type != 'Input' and layer.active:
                  layer.netinput = (layer.weight).copy() 
          # for each connection, in order:
          for layer in self.layers:
              if layer.active:
                  for connection in self.connections:
                      if (connection.toLayer.name == layer.name
                          and connection.fromLayer.active
                          and connection.active):
  
                          a = connection.fromLayer.activation
                          w = connection.weight
                          m = Numeric.matrixmultiply(a, w)
                          ni = m + connection.toLayer.netinput
  
                          connection.toLayer.netinput = ni
  
                          #connection.toLayer.netinput = \
                          #    (connection.toLayer.netinput + 
                          #     Numeric.matrixmultiply(connection.fromLayer.activation,
                          #                            connection.weight)) # propagate!
  
                  if layer.type != 'Input':
                      layer.activation = self.activationFunction(layer.netinput)
          for layer in self.layers:
              if layer.log and layer.active:
                  layer.writeLog(self)
          self.count += 1 # counts number of times propagate() is called
          if len(args) != 0:
              dict = {}
              for layer in self.layers:
                  if layer.type == "Output":
                      dict[layer.name] = layer.activation.copy()
              if len(dict) == 1:
                  return dict[list(dict.keys())[0]]
              else:
                  return dict