# Passing Functions

Discussion in 'Python' started by yoro, Mar 11, 2011.

1. ### yoroGuest

Hi,

I am having an issue with passing values from one function to another
- I am trying to fill a list in one function using the values
contained in other functions as seen below:

infinity = 1000000
invalid_node = -1
startNode = 0

#Values to assign to each node
class Node:
distFromSource = infinity
previous = invalid_node
visited = False

def network():
f = open ('network.txt', 'r')
theNetwork = [[int(node) for node in line.split(',')] for line in
print theNetwork

return theNetwork

#for each node assign default values
def populateNodeTable():
nodeTable = []
index = 0
f = open('network.txt', 'r')
for line in f:
node = map(int, line.split(','))
nodeTable.append(Node())

print "The previous node is " ,nodeTable[index].previous
print "The distance from source is
" ,nodeTable[index].distFromSource
index +=1
nodeTable[startNode].distFromSource = 0

return nodeTable

#find the nearest neighbour to a particular node
def nearestNeighbour(currentNode, theNetwork):
nearestNeighbour = []
nodeIndex = 0
for node in nodeTable:
if node != 0 and currentNode.visited == false:
nearestNeighbour.append(nodeIndex)
nodeIndex +=1

return nearestNeighbour

if __name__ == "__main__":
nodeTable = populateNodeTable()
theNetwork = network()
nearestNeighbour(currentNode, theNetwork, )

So, I am trying to look at the values provided by the network
function, set all nodes to 'visited = false' in populateNodeTable
function and then determine the nodes' nearest neighbour by looking at
the values provided in the previous function, though I get this error
message:

if node != 0 and currentNode.visited == false:
AttributeError: 'int' object has no attribute 'visited'

I'm not sure what to try next

yoro, Mar 11, 2011

2. ### alex23Guest

On Mar 11, 11:13 am, yoro <> wrote:
> Hi,
>
> I am having an issue with passing values from one function to another
> - I am trying to fill a list in one function using the values
> contained in other functions as seen below:
>
> infinity = 1000000
> invalid_node = -1
> startNode = 0
>
> #Values to assign to each node
> class Node:
>      distFromSource = infinity
>      previous = invalid_node
>      visited = False
>
> #read in all network nodes
> def network():
>     f = open ('network.txt', 'r')
>     theNetwork = [[int(node) for node in line.split(',')] for line in
>     print theNetwork
>
>     return theNetwork
>
> #for each node assign default values
> def populateNodeTable():
>     nodeTable = []
>     index = 0
>     f = open('network.txt', 'r')
>     for line in f:
>       node = map(int, line.split(','))
>       nodeTable.append(Node())
>
>       print "The previous node is " ,nodeTable[index].previous
>       print "The distance from source is
> " ,nodeTable[index].distFromSource
>       index +=1
>     nodeTable[startNode].distFromSource = 0
>
>     return nodeTable
>
> #find the nearest neighbour to a particular node
> def nearestNeighbour(currentNode, theNetwork):
>      nearestNeighbour = []
>      nodeIndex = 0
>      for node in nodeTable:
>           if node != 0 and currentNode.visited == false:
>              nearestNeighbour.append(nodeIndex)
>              nodeIndex +=1
>
>      return nearestNeighbour
>
> if __name__ == "__main__":
>     nodeTable = populateNodeTable()
>     theNetwork = network()
>     nearestNeighbour(currentNode, theNetwork, )
>
> So, I am trying to look at the values provided by the network
> function,  set all nodes to 'visited = false' in populateNodeTable
> function and then determine the nodes' nearest neighbour by looking at
> the values provided in the previous function, though I get this error
> message:
>
> if node != 0 and currentNode.visited == false:
> AttributeError: 'int' object has no attribute 'visited'
>
> I'm not sure what to try next

Well, for starters, you're not actually instantiating any Nodes:

> theNetwork = [[int(node) for node in line.split(',')] for line in f.readlines()]

You're returning a list of integers, none of which have the visited
attribute.

At the very least, you need a constructor on your Node class:

class Node:
def __init__(self, distFromSource=infinity, previous=invalid_node,
visited=False):
self.distFromSource = distFromSource
self.previous = previous
self.visited = False

Now, I'm _assuming_ your network.txt file consists of 3 number
separated by commas, so in network() it should probably be something
like:

def network():
with open('network.txt', 'r') as f:
network_data = ([int(node) for node in line.split(',')] for line
theNetwork = [Node(*data) for data in network_data]
return theNetwork

The with statement ensures the file is closed at the end of the block.
'network_data' is a generator that reads each line and splits it into
a list of ints: '[x, y, z]'
'Node(*data)' takes a list of ints and creates a node from those
values.

Since both populateNodeTable and nearestNeighbour relay on nodeTable,
you might be better off making a NodeTable class.

None of this is tested, sorry, but hopefully it'll set you in the
right direction.

alex23, Mar 11, 2011

3. ### MRABGuest

On 11/03/2011 01:13, yoro wrote:
> Hi,
>
> I am having an issue with passing values from one function to another
> - I am trying to fill a list in one function using the values
> contained in other functions as seen below:
>
> infinity = 1000000
> invalid_node = -1
> startNode = 0
>
> #Values to assign to each node
> class Node:
> distFromSource = infinity
> previous = invalid_node
> visited = False
>
> #read in all network nodes
> def network():
> f = open ('network.txt', 'r')
> theNetwork = [[int(node) for node in line.split(',')] for line in
> print theNetwork
>
> return theNetwork
>
> #for each node assign default values
> def populateNodeTable():
> nodeTable = []
> index = 0
> f = open('network.txt', 'r')
> for line in f:
> node = map(int, line.split(','))
> nodeTable.append(Node())
>
> print "The previous node is " ,nodeTable[index].previous
> print "The distance from source is
> " ,nodeTable[index].distFromSource
> index +=1
> nodeTable[startNode].distFromSource = 0
>
> return nodeTable
>
> #find the nearest neighbour to a particular node
> def nearestNeighbour(currentNode, theNetwork):
> nearestNeighbour = []
> nodeIndex = 0
> for node in nodeTable:
> if node != 0 and currentNode.visited == false:
> nearestNeighbour.append(nodeIndex)
> nodeIndex +=1
>
> return nearestNeighbour
>
> if __name__ == "__main__":
> nodeTable = populateNodeTable()
> theNetwork = network()
> nearestNeighbour(currentNode, theNetwork, )
>
> So, I am trying to look at the values provided by the network
> function, set all nodes to 'visited = false' in populateNodeTable
> function and then determine the nodes' nearest neighbour by looking at
> the values provided in the previous function, though I get this error
> message:
>
> if node != 0 and currentNode.visited == false:
> AttributeError: 'int' object has no attribute 'visited'
>
> I'm not sure what to try next
>

In nearestNeighbour, 'currentNode' is an int because that's what you're
passing in ... except that you aren't.

You're passing in the value of the global 'currentNode', which doesn't
exist. Perhaps you meant 'startNode'?

When I run the above program I get:

Traceback (most recent call last):
line 49, in <module>
nearestNeighbour(currentNode, theNetwork, )
NameError: name 'currentNode' is not defined

MRAB, Mar 11, 2011
4. ### yoroGuest

On Mar 11, 2:00 am, MRAB <> wrote:
> On 11/03/2011 01:13, yoro wrote:
>
> > Hi,

>
> > I am having an issue with passing values from one function to another
> > - I am trying to fill a list in one function using the values
> > contained in other functions as seen below:

>
> > infinity = 1000000
> > invalid_node = -1
> > startNode = 0

>
> > #Values to assign to each node
> > class Node:
> >       distFromSource = infinity
> >       previous = invalid_node
> >       visited = False

>
> > #read in all network nodes
> > def network():
> >      f = open ('network.txt', 'r')
> >      theNetwork = [[int(node) for node in line.split(',')] for line in
> >      print theNetwork

>
> >      return theNetwork

>
> > #for each node assign default values
> > def populateNodeTable():
> >      nodeTable = []
> >      index = 0
> >      f = open('network.txt', 'r')
> >      for line in f:
> >        node = map(int, line.split(','))
> >        nodeTable.append(Node())

>
> >        print "The previous node is " ,nodeTable[index].previous
> >        print "The distance from source is
> > " ,nodeTable[index].distFromSource
> >        index +=1
> >      nodeTable[startNode].distFromSource = 0

>
> >      return nodeTable

>
> > #find the nearest neighbour to a particular node
> > def nearestNeighbour(currentNode, theNetwork):
> >       nearestNeighbour = []
> >       nodeIndex = 0
> >       for node in nodeTable:
> >            if node != 0 and currentNode.visited == false:
> >               nearestNeighbour.append(nodeIndex)
> >               nodeIndex +=1

>
> >       return nearestNeighbour

>
> > if __name__ == "__main__":
> >      nodeTable = populateNodeTable()
> >      theNetwork = network()
> >      nearestNeighbour(currentNode, theNetwork, )

>
> > So, I am trying to look at the values provided by the network
> > function,  set all nodes to 'visited = false' in populateNodeTable
> > function and then determine the nodes' nearest neighbour by looking at
> > the values provided in the previous function, though I get this error
> > message:

>
> > if node != 0 and currentNode.visited == false:
> > AttributeError: 'int' object has no attribute 'visited'

>
> > I'm not sure what to try next

>
> In nearestNeighbour, 'currentNode' is an int because that's what you're
> passing in ... except that you aren't.
>
> You're passing in the value of the global 'currentNode', which doesn't
> exist. Perhaps you meant 'startNode'?
>
> When I run the above program I get:
>
> Traceback (most recent call last):
> line 49, in <module>
>      nearestNeighbour(currentNode, theNetwork, )
> NameError: name 'currentNode' is not defined

I've found the error, I had to type in:

for node in nodeTable:
if node != 0 and Node.visited == False:

yoro, Mar 11, 2011
5. ### John NagleGuest

On 3/11/2011 5:49 AM, yoro wrote:

> I've found the error, I had to type in:
>
> for node in nodeTable:
> if node != 0 and Node.visited == False:

(Also, you shouldn't have anything but Node items in
nodeTable, so you don't need the "node != 0".)

The biggest problem is at

#Values to assign to each node
> > class Node:
> > distFromSource = infinity
> > previous = invalid_node
> > visited = False

Those are variables of the entire class. Every
instance of Node shares the same variables. You
need

class Node:
def __init__(self) :
self.distFromSource = infinity
self.previous = invalid_node
self.visited = False

John Nagle

John Nagle, Mar 11, 2011