0

This is my first post to Stack Overflow by the way.

I've created a class called 'Network' that that holds a list of nodes which contains a string as data and a list of attributes and corresponding weights that represent that data and the degree of relatedness. i.e. NetworkObject.data = "dog" and NetworkObject.attributes = [("four_legs", 1.0), ("brown", 0.2)]. These Nodes are then connected to each other based upon average similarity between attributes. This creates a graph structure in which edges are stored in the 'Node' variable 'connected'.

The goal is to create the function 'pulse' which returns nodes a certain distance(determined by a 'strength' argument) from the node that 'pulse' is called on.

The 'Network' works as I want it to and the 'pulse' function works on the first call. But whenever I call it a second time, 'traversal'(which is a variable that contains the nodes to be returned) still contains all the values from the previous call. So for example if I call 'pulse' and traversal = [1.0, .5, .75], the next time I call it, those same values remain in the list.

I've tried transferring the 'traversal' list to a second variable and replacing the 'traversal' with an empty list right before return but I still get the same result.

Node Class:

class Node:
    """Class of data containers with the dict variable 'attributes'. Using these attributes, the 'Network' structure forms connections between 
    collections of nodes. Note: Many of the 'Node' class functions parallel those of the 'Network' class. The node functions directly change the nodes
    according to the arguments in the function, while the network functions assess what should be changed and delegates those changes to the Node class"""
    def __init__(self, idx, data):
        self.data = data
        self.idx = idx
        self.attributes = {}
        self.connections = []

Network Class

class Network:
    """Graph Structure which organizes 'Nodes' according to their attribute weight."""
    def __init__(self):
        self.nodeList = []

Pulse Function(function of the Network Class):

    def pulse(self, node_idx, strength, weight=1, traversed=[]):
        """A pulse is the main 'search' function of the ACN. It recursively digs into the network in all directions 
        until it's strength reaches zero. At this point it returns all the traversed nodes. Note:
        strength is drained by the inverse of weight each node i.e. weight of .7 = .3 drained"""
        node = self.nodeList[node_idx]
        strength -= (1 - weight)
        if strength >= 0:
            traversed.append(node.idx)
            for conn_node in node.connections:
                if conn_node[0] not in traversed:
                    traversed = self.pulse(conn_node[0], strength, conn_node[1], traversed)
            
        return traversed

Console Function which allows the user to provide the necessary information for pulse call:

   def pulse(self):
        print("Network Nodes(idx, data): ", end="")
        print([(node.idx, node.data) for node in self.network.nodeList])
        node = int(input("What is the index of the node you'd like to pulse?"))
        strength = float(input("Strength?: "))
        traversal = self.network.pulse(node, strength)
        print("Returns: {}".format([self.network.nodeList[idx].data for idx in traversal]))

Any help would be appreciated. Thank you!

VinneB
  • 1
  • Welcome to Stackoverflow, and thanks for the detailed first post. Your problem comes down to the fact that you used a default argument list in your `Network.pulse` method. Look here: https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument – Paul M. Jul 01 '20 at 22:09
  • Thank you! I wasn't aware that default arguments were bound a definition rather than execution. This fixes my problem perfectly – VinneB Jul 02 '20 at 22:33

0 Answers0