How to call a module object? [duplicate] - python

This question already has answers here:
TypeError: 'module' object is not callable
(16 answers)
Closed 1 year ago.
I tried to run this Ant Colony algorithm code (ant_colony.py) in Python:
from threading import Thread
class ant_colony:
class ant(Thread):
def __init__(self, init_location, possible_locations, pheromone_map, distance_callback, alpha, beta, first_pass=False):
Thread.__init__(self)
self.init_location = init_location
self.possible_locations = possible_locations
self.route = []
self.distance_traveled = 0.0
self.location = init_location
self.pheromone_map = pheromone_map
self.distance_callback = distance_callback
self.alpha = alpha
self.beta = beta
self.first_pass = first_pass
self._update_route(init_location)
self.tour_complete = False
def run(self):
while self.possible_locations:
next = self._pick_path()
self._traverse(self.location, next)
self.tour_complete = True
def _pick_path(self):
if self.first_pass:
import random
return random.choice(self.possible_locations)
attractiveness = dict()
sum_total = 0.0
for possible_next_location in self.possible_locations:
pheromone_amount = float(self.pheromone_map[self.location][possible_next_location])
distance = float(self.distance_callback(self.location, possible_next_location))
attractiveness[possible_next_location] = pow(pheromone_amount, self.alpha)*pow(1/distance, self.beta)
sum_total += attractiveness[possible_next_location]
if sum_total == 0.0:
def next_up(x):
import math
import struct
if math.isnan(x) or (math.isinf(x) and x > 0):
return x
if x == 0.0:
x = 0.0
n = struct.unpack('<q', struct.pack('<d', x))[0]
if n >= 0:
n += 1
else:
n -= 1
return struct.unpack('<d', struct.pack('<q', n))[0]
for key in attractiveness:
attractiveness[key] = next_up(attractiveness[key])
sum_total = next_up(sum_total)
import random
toss = random.random()
cummulative = 0
for possible_next_location in attractiveness:
weight = (attractiveness[possible_next_location] / sum_total)
if toss <= weight + cummulative:
return possible_next_location
cummulative += weight
def _traverse(self, start, end):
self._update_route(end)
self._update_distance_traveled(start, end)
self.location = end
def _update_route(self, new):
self.route.append(new)
self.possible_locations.remove(new)
def _update_distance_traveled(self, start, end):
self.distance_traveled += float(self.distance_callback(start, end))
def get_route(self):
if self.tour_complete:
return self.route
return None
def get_distance_traveled(self):
if self.tour_complete:
return self.distance_traveled
return None
def __init__(self, nodes, distance_callback, start=None, ant_count=50, alpha=.5, beta=1.2, pheromone_evaporation_coefficient=.40, pheromone_constant=1000.0, iterations=80):
if type(nodes) is not dict:
raise TypeError("nodes must be dict")
if len(nodes) < 1:
raise ValueError("there must be at least one node in dict nodes")
self.id_to_key, self.nodes = self._init_nodes(nodes)
self.distance_matrix = self._init_matrix(len(nodes))
self.pheromone_map = self._init_matrix(len(nodes))
self.ant_updated_pheromone_map = self._init_matrix(len(nodes))
if not callable(distance_callback):
raise TypeError("distance_callback is not callable, should be method")
self.distance_callback = distance_callback
if start is None:
self.start = 0
else:
self.start = None
#init start to internal id of node id passed
for key, value in self.id_to_key.items():
if value == start:
self.start = key
#if we didn't find a key in the nodes passed in, then raise
if self.start is None:
raise KeyError("Key: " + str(start) + " not found in the nodes dict passed.")
if type(ant_count) is not int:
raise TypeError("ant_count must be int")
if ant_count < 1:
raise ValueError("ant_count must be >= 1")
self.ant_count = ant_count
if (type(alpha) is not int) and type(alpha) is not float:
raise TypeError("alpha must be int or float")
if alpha < 0:
raise ValueError("alpha must be >= 0")
self.alpha = float(alpha)
if (type(beta) is not int) and type(beta) is not float:
raise TypeError("beta must be int or float")
if beta < 1:
raise ValueError("beta must be >= 1")
self.beta = float(beta)
if (type(pheromone_evaporation_coefficient) is not int) and type(pheromone_evaporation_coefficient) is not float:
raise TypeError("pheromone_evaporation_coefficient must be int or float")
self.pheromone_evaporation_coefficient = float(pheromone_evaporation_coefficient)
#pheromone_constant
if (type(pheromone_constant) is not int) and type(pheromone_constant) is not float:
raise TypeError("pheromone_constant must be int or float")
self.pheromone_constant = float(pheromone_constant)
#iterations
if (type(iterations) is not int):
raise TypeError("iterations must be int")
if iterations < 0:
raise ValueError("iterations must be >= 0")
self.iterations = iterations
#other internal variable init
self.first_pass = True
self.ants = self._init_ants(self.start)
self.shortest_distance = None
self.shortest_path_seen = None
def _get_distance(self, start, end):
if not self.distance_matrix[start][end]:
distance = self.distance_callback(self.nodes[start], self.nodes[end])
if (type(distance) is not int) and (type(distance) is not float):
raise TypeError("distance_callback should return either int or float, saw: "+ str(type(distance)))
self.distance_matrix[start][end] = float(distance)
return distance
return self.distance_matrix[start][end]
def _init_nodes(self, nodes):
id_to_key = dict()
id_to_values = dict()
id = 0
for key in sorted(nodes.keys()):
id_to_key[id] = key
id_to_values[id] = nodes[key]
id += 1
return id_to_key, id_to_values
def _init_matrix(self, size, value=0.0):
ret = []
for row in range(size):
ret.append([float(value) for x in range(size)])
return ret
def _init_ants(self, start):
#allocate new ants on the first pass
if self.first_pass:
return [self.ant(start, self.nodes.keys(), self.pheromone_map, self._get_distance,
self.alpha, self.beta, first_pass=True) for x in range(self.ant_count)]
#else, just reset them to use on another pass
for ant in self.ants:
ant.__init__(start, self.nodes.keys(), self.pheromone_map, self._get_distance, self.alpha, self.beta)
def _update_pheromone_map(self):
#always a square matrix
for start in range(len(self.pheromone_map)):
for end in range(len(self.pheromone_map)):
#decay the pheromone value at this location
#tau_xy <- (1-rho)*tau_xy (ACO)
self.pheromone_map[start][end] = (1-self.pheromone_evaporation_coefficient)*self.pheromone_map[start][end]
#then add all contributions to this location for each ant that travered it
#(ACO)
#tau_xy <- tau_xy + delta tau_xy_k
# delta tau_xy_k = Q / L_k
self.pheromone_map[start][end] += self.ant_updated_pheromone_map[start][end]
def _populate_ant_updated_pheromone_map(self, ant):
route = ant.get_route()
for i in range(len(route)-1):
#find the pheromone over the route the ant traversed
current_pheromone_value = float(self.ant_updated_pheromone_map[route[i]][route[i+1]])
#update the pheromone along that section of the route
#(ACO)
# delta tau_xy_k = Q / L_k
new_pheromone_value = self.pheromone_constant/ant.get_distance_traveled()
self.ant_updated_pheromone_map[route[i]][route[i+1]] = current_pheromone_value + new_pheromone_value
self.ant_updated_pheromone_map[route[i+1]][route[i]] = current_pheromone_value + new_pheromone_value
def mainloop(self):
for _ in range(self.iterations):
#start the multi-threaded ants, calls ant.run() in a new thread
for ant in self.ants:
ant.start()
#source: http://stackoverflow.com/a/11968818/5343977
#wait until the ants are finished, before moving on to modifying shared resources
for ant in self.ants:
ant.join()
for ant in self.ants:
#update ant_updated_pheromone_map with this ant's constribution of pheromones along its route
self._populate_ant_updated_pheromone_map(ant)
#if we haven't seen any paths yet, then populate for comparisons later
if not self.shortest_distance:
self.shortest_distance = ant.get_distance_traveled()
if not self.shortest_path_seen:
self.shortest_path_seen = ant.get_route()
#if we see a shorter path, then save for return
if ant.get_distance_traveled() < self.shortest_distance:
self.shortest_distance = ant.get_distance_traveled()
self.shortest_path_seen = ant.get_route()
#decay current pheromone values and add all pheromone values we saw during traversal (from ant_updated_pheromone_map)
self._update_pheromone_map()
#flag that we finished the first pass of the ants traversal
if self.first_pass:
self.first_pass = False
#reset all ants to default for the next iteration
self._init_ants(self.start)
#reset ant_updated_pheromone_map to record pheromones for ants on next pass
self.ant_updated_pheromone_map = self._init_matrix(len(self.nodes), value=0)
#translate shortest path back into callers node id's
ret = []
for id in self.shortest_path_seen:
ret.append(self.id_to_key[id])
return ret
and my module-test file is:
import ant_colony
import math
test_nodes = {0: (0, 7), 1: (3, 9), 2: (12, 4), 3: (14, 11), 4: (8, 11) ,5: (15, 6), 6: (6, 15), 7: (15, 9), 8: (12, 10), 9: (10, 7)}
def distance(start, end):
x_distance = abs(start[0] - end[0])
y_distance = abs(start[1] - end[1])
return math.sqrt(pow(x_distance, 2) + pow(y_distance, 2))
colony = ant_colony(test_nodes, distance)
answer = colony.mainloop()
print(answer)
but when it runs, this error appears:
TypeError: 'module' object is not callable
I tried a lot of ways but they didn't work at all. I tried to test two coordinates instead of distance, I tried to test using arguments and so on, but they did not work. How can I fix it?

You can see that error says module object is not callable. Because when you wrote
import ant_colony
What you did was import that whole module when what you really wanted was just the class
so you can go ahead and do
from ant_colony import ant_colony
and you are good to go!

You are importing module but not a class. Replace this line of code:
import ant_colony
with this line of code:
from ant_colony import ant_colony
What's the difference? In my example you are importing class called ant_colony from file called ant_colony. The first thing is path to file and the second thing is the name of class, function etc.

You have to call it as ant_colony.ant_colony(...) , not ant_colony(...)
See this thread TypeError: 'module' object is not callable

Related

How to define instantiation of object class as global variable in Python?

I am a starter & want to integrate dfs code with Fibonacci series generating code. The Fibonacci code too runs as dfs, with calls made from left to right.
The integration is incomplete still.
I have two issues :
(i) Unable to update 'path' correctly in fib(), as the output is not correctly depicting that.
(ii) Stated in fib() function below, as comment.
P.S.
Have one more issue that is concerned with program's working:
(iii) On modifying line #16 to: stack = root = stack[1:]; get the same output as before.
import sys
count = 0
root_counter = 0
#path=1
inf = -1
node_counter = 0
root =0
def get_depth_first_nodes(root):
nodes = []
stack = [root]
while stack:
cur_node = stack[0]
stack = stack[1:]
nodes.append(cur_node)
for child in cur_node.get_rev_children():
stack.insert(0, child)
return nodes
def node_counter_inc():
global node_counter
node_counter = node_counter + 1
class Node(object):
def __init__(self, id_,path):
self.id = node_counter_inc()
self.children = []
self.val = inf #On instantiation, val = -1, filled bottom up;
#except for leaf nodes
self.path = path
def __repr__(self):
return "Node: [%s]" % self.id
def add_child(self, node):
self.children.append(node)
def get_children(self):
return self.children
def get_rev_children(self):
children = self.children[:]
children.reverse()
return children
def fib(n, level, val, path):
global count, root_counter, root
print('count :', count, 'n:', n, 'dfs-path:', path)
count += 1
if n == 0 or n == 1:
path = path+1
root.add_child(Node(n, path))
return n
if root_counter == 0:
root = Node(n, path)
root_counter = 1
else:
#cur_node.add_child(Node(n, path)) -- discarded for next(new) line
root.add_child(Node(n, path))
tmp = fib(n-1, level + 1,inf, path) + fib(n-2, level + 1,inf,path+1)
#Issue 2: Need update node's val field with tmp.
#So, need suitable functions in Node() class for that.
print('tmp:', tmp, 'level', level)
return tmp
def test_depth_first_nodes():
fib(n,0,-1,1)
node_list = get_depth_first_nodes(root)
for node in node_list:
print(str(node))
if __name__ == "__main__":
n = int(input("Enter value of 'n': "))
test_depth_first_nodes()
Want to add that took idea for code from here.
Answer to the first question:
Path in this particular question is an int. It is a numbering of path from the root to a leaf in a greedy dfs manner.
This can be achieved by letting path be a global variable rather than an input to fib function. We increment the path count whenever we reach a leaf.
I have also modified the fib function to returns a node rather than a number.
import sys
count = 0
root_counter = 0
path=1
inf = -1
node_counter = 0
root = None
def node_counter_inc():
global node_counter
node_counter = node_counter + 1
print("node_counter:", node_counter)
return node_counter
class Node(object):
def __init__(self, id__,path):
print("calling node_counter_inc() for node:", n )
try:
self.id = int(node_counter_inc())
except TypeError:
self.id = 0 # or whatever you want to do
#self.id = int(node_counter_inc())
self.val = inf #On instantiation, val = -1, filled bottom up;
#except for leaf nodes
self.path = path
self.left = None
self.right = None
def __repr__(self):
return "Node" + str(self.id) + ":"+ str(self.val)
def fib(n, level, val):
# make fib returns a node rather than a value
global count, root_counter, root, path
print('count :', count, 'n:', n, 'dfs-path:', path)
count += 1
if n == 0 or n == 1:
path = path+1
new_Node = Node(n, path)
new_Node.val = n
return new_Node
#root.add_child(new_Node)
# return new_node
#if root_counter == 0:
# root = Node(n, path)
# root_counter = 1
#else:
#cur_node.add_child(Node(n, path)) -- discarded for next(new) line
# root.add_child(Node(n, path))
#tmp = fib(n-1, level + 1,inf) + fib(n-2, level + 1,inf)
#Issue 2: Need update node's val field with tmp.
#So, need suitable functions in Node() class for that.
#print('tmp:', tmp, 'level', level)
#return tmp
ans = Node(n, path)
ans.left = fib(n-1, level + 1, inf)
ans.right = fib(n-2, level + 1, inf)
ans.val = ans.left.val + ans.right.val
print("the node is", ans.id, "with left child", ans.left.id, "and right child", ans.right.id)
print("the corresponding values are", ans.val, ans.left.val, ans.right.val)
return ans
def test_depth_first_nodes():
ans = fib(n,0,-1)
print("The answer is", ans.val)
#node_list = get_depth_first_nodes(root)
#for node in node_list:
# print(str(node))
if __name__ == "__main__":
n = int(input("Enter value of 'n': "))
test_depth_first_nodes()

Python - high disk usage in SumTree

I've encountered some weird behaviour of my python program. Basically when I tried to create adn fill a SumTree of length larger than 1000, my disk usage increases a lot to ~300MB/s then the programme died.
I'm pretty sure there's no file r/w involved in this process, and the problem is with the add function. The code is shown below.
import numpy as np
class SumTree():
trans_idx = 0
def __init__(self, capacity):
self.num_samples = 0
self.capacity = capacity
self.tree = np.zeros(2 * capacity - 1)
self.transitions = np.empty(self.capacity, dtype=object)
def add(self, p, experience):
tree_idx = self.trans_idx + self.capacity - 1
self.transitions[self.trans_idx] = experience
self.transitions.append(experience)
self.update(tree_idx, p)
self.trans_idx += 1
if self.trans_idx >= self.capacity:
self.trans_idx = 0
self.num_samples = min(self.num_samples + 1, self.capacity)
def update(self, tree_idx, p):
diff = p - self.tree[tree_idx]
self.tree[tree_idx] = p
while tree_idx != 0:
tree_idx = (tree_idx - 1) // 2
self.tree[tree_idx] += diff
def get_leaf(self, value):
parent_idx = 0
while True:
childleft_idx = 2 * parent_idx + 1
childright_idx = childleft_idx + 1
if childleft_idx >= len(self.tree):
leaf_idx = parent_idx
break
else:
if value <= self.tree[childleft_idx]:
parent_idx = childleft_idx
else:
value -= self.tree[childleft_idx]
parent_idx = childright_idx
data_idx = leaf_idx - self.capacity + 1
return leaf_idx, self.tree[leaf_idx], self.transitions[data_idx]
#property
def total_p(self):
return self.tree[0] # the root
#property
def volume(self):
return self.num_samples # number of transistions stored
Here's an example where this SumTree object will be used:
def add(self, experience)
max_p = np.max(self.tree.tree[-self.tree.capacity:])
if max_p == 0:
max_p = 1.0
exp = self.Experience(*experience)
self.tree.add(max_p, exp)
where Experience is a named tuple and self.tree is a Sumtree instance, when I removed the last line the high disk usage disappears.
Can anyone help me with this?
I finally sort this out because each experience is a tuple of namedtuple and I'm creating another namedtuple Experience from it. Fixed by changing experience to a tuple of numpy arrays.

How to give start,end coordinates

I'm new to qgis and in here I want to find a path between two selected points on the map(Roads-vector layer). The points are selected by the user, using mouse clicks.
So here I used the astar algorithm to find path between two points.
*******************************astar.py**********************************
import heapq
class AStar(object):
def __init__(self, graphAstar):
self.graphAstar = graphAstar
def heuristic(self, node, start, end):
raise NotImplementedError
def search(self, start, end):
openset = set()
closedset = set()
current = start
openHeap = []
openset.add(current)
openHeap.append((0,current))
while openset:
temp = heapq.heappop(openHeap)
current = temp[1]
if current == end:
path = []
while current.parent:
path.append(current)
current = current.parent
path.append(current)
return path[::-1]
openset.remove(current)
closedset.add(current)
for node in self.graphAstar[current]:
if node in closedset:
continue
if node in openset:
new_g = current.gg + current.move_cost(node)
if node.gg > new_g:
node.gg = new_g
node.parent = current
else:
node.gg = current.gg + current.move_cost(node)
node.H = self.heuristic(node, start, end)
node.parent = current
openset.add(node)
heapq.heappush(openHeap, (node.H,node))
return None
class AStarNode(object):
def __init__(self):
self.gg = 0
self.H = 0
self.parent = None
def move_cost(self, other):
raise NotImplementedError
*****************************astar_grid.py*******************************
from astar import AStar, AStarNode
from math import sqrt
class AStarGrid(AStar):
def heuristic(self, node, start, end):
return sqrt((end.x - node.x)**2 + (end.y - node.y)**2)
class AStarGridNode(AStarNode):
def __init__(self, x, y):
self.x, self.y = x, y
super(AStarGridNode, self).__init__()
def move_cost(self, other):
diagonal = abs(self.x - other.x) == 1 and abs(self.y - other.y) == 1
return 14 if diagonal else 10
and in the main code, the following method is used to create graph from vector layer.
**************************plugin.py**********************************
def make_graph(self, mapinfo):
nodes = [[AStarGridNode(x, y) for y in range(mapinfo['height'])] for x in range(mapinfo['width'])]
graphAstar = {}
for x, y in product(range(mapinfo['width']), range(mapinfo['height'])):
node = nodes[x][y]
graphAstar[node] = []
for i, j in product([-1, 0, 1], [-1, 0, 1]):
if not (0 <= x + i < mapinfo['width']): continue
if not (0 <= y + j < mapinfo['height']): continue
graphAstar[nodes[x][y]].append(nodes[x+i][y+j])
return graphAstar, nodes
And I called that method in FindRoutes method..
def findRoutes(self):
vl=self.canvas.currentLayer()
director = QgsLineVectorLayerDirector( vl, -1, '', '', '', 3 )
properter = QgsDistanceArcProperter()
director.addProperter( properter )
crs = self.canvas.mapRenderer().destinationCrs()
builder = QgsGraphBuilder( crs )
global x1
global y1
global x2
global y2
pStart = QgsPoint( x1, y1 )
pStop = QgsPoint( x2, y2 )
graphAstar, nodes = self.make_graph({ "width": 8, "height": 8 })
paths = AStarGrid(graphAstar)
start, end = ??
path = paths.search(start, end)
My question is, how to pass the start and end coordinates to the function above? Because passing them just as coordinates (start, end = pStart, pStop) does not work.
How do add them to the graph created as nodes?
Or is there any easy way to do it?
Please help me to to find a solution to this problem.
Thank You
When i do an astar, the node i use are intern of the astar and contain a reference vers the original point object (your tuple of position).
Maybe it's the same with your AStarGridNode ?
In your case :
start = AStarGridNode(x1, y1)
stop = AStarGridNode(x2, y2)
This part could be in the your search function to hide this from the user.

Python greedy thief

Why is it giving me an error " 'int' object is not subscriptable " when i run the program? I looked if i was doing anything wrong, i understand it has to be an integer on line 24, but when I'm changing capacity[1] to capacity(int[1]) , it gives me the same error. Any hint would be appreciated.
class Bag():
__slots__=('name', 'weight', 'value')
def mkBag(name, weight, value):
thisBag = Bag()
thisBag.name = name
thisBag.weight = weight
thisBag.value = value
return thisBag
def ratio(treasure):
print(treasure)
print(treasure)
return treasure[2]//treasure[1]
def plunder(treasure, capacity):
treasure = sorted(treasure, key=ratio, reverse=True)
bagLst = []
current = 0
while current < capacity:
if capacity != 0:
if capacity > current[1]:
bagLst.append(mkBag(treasure[0],weight[1],current[2]))
capacity = capacity - current[1]
else:
bagLst.append(mkBag(current[0], capacity, (current[2]/current[1]), capacity))
capacity = 0
return bagLst
def main():
capacity = 10
name = ''
weight = 0
value = 0
treasure = [('silver', 20, 100), ('platinum', 10, 400), ('paladium',10,800), ('diamonds',5,900), ('gold', 10,60)]
bagLst = plunder(treasure, capacity)
for line in bagLst:
print('bagLst')
current is an int:
current = 0
but you are trying to use it as a list:
if capacity > current[1]:
bagLst.append(mkBag(treasure[0],weight[1],current[2]))
capacity = capacity - current[1]
else:
bagLst.append(mkBag(current[0], capacity, (current[2]/current[1]), capacity))
everywhere you use current[index] you are trying to index the integer value.
If you expected current to be a sequence instead, you'd need to set it to one.
I suspect you want to inspect the current treasure to add to the bag; you didn't pick any treasure item however. Something along the lines of:
current = 0
while capacity and current < len(treasure):
item = treasure[current]
current += 1
if capacity > item[1]:
bagLst.append(mkBag(item[0], item[1], item[2]))
capacity = capacity - item[1]
else:
bagLst.append(mkBag(item[0], capacity, (item[2]/item[1]), capacity))
capacity = 0
"int" object not subscriptable means you're trying to do 1234[1]. That doesn't make any sense! You can subscript a string ('abcdefg'[1] == 'b') and a list ([1,2,3,4,5][1] == 2) but you can't get the "nth element" of an integer.
In your line:
# in def plunder(...):
if capacity > current[1]:
You're trying to access the 2nd element of current, which is currently equal to the integer 0. Are you trying to make that a list? What are you expecting to be in current[1]?
Here's a substantially better way to accomplish this
Hey there, so I figured you meant that current[1] was actually item[1], meaning the weight of the item you were looking at. Instead, current was intended to be the running-weight of the bag. Understood! That said, I wrote up a better solution for this: take a look see!
class Treasure(object):
def __init__(self,name,weight=0,value=0,id_=0):
self.name = name
self.weight = weight
self.value = value
self.id = id_ # bootstrap for further development
#property
def ratio(self):
return self.value/self.weight
class BagFullError(ValueError):
pass
class Bag(object):
def __init__(self,owner=None,capacity=10):
self.owner = owner
self.capacity = capacity
self.contents = list()
def __str__(self):
return_value = "CONTENTS:"
for item in self.contents:
return_value += "\n ${0.value:4} {0.name:10}{0.weight} lb".format(item)
return return_value
def add(self,other):
if not isinstance(other,Treasure):
raise TypeError("Must pick up Treasure")
if self.weight + other.weight > self.capacity:
raise BagFullError("Bag cannot fit {}({} lb) ({} lb/{} lb)".format(
other.name,other.weight,self.weight,self.capacity))
self.contents.append(other)
def remove(self,other):
self.contents.remove(other)
# may throw ValueError if `other` not in `self.contents`
#property
def weight(self):
return sum(item.weight for item in self.contents)
treasure = [Treasure('silver', 20, 100), Treasure('platinum', 10, 400),
Treasure('paladium',10,800), Treasure('diamonds',5,900),
Treasure('gold', 10,60)]
## map(lambda x: Treasure(*x), [('silver',20,100), ... ])
def plunder(treasure_list,bag=None):
_bag = bag or Bag()
treasures = sorted(treasure_list,
key = lambda x: x.ratio,
reverse = True)
while True:
for treasure in treasures:
try: _bag.add(treasure)
except BagFullError as e:
print(e)
return _bag
bag = Bag("Adam",100)
print(bag)
plunder(treasure,bag)
print(bag)
print("Total Value: {}".format(sum(item.value for item in bag.contents)))

error in converting linked list to a single number in python

here this is the node definition
class Node(object):
def __init__(self,value=None):
self.value = value
self.next = None
this is the conversion for the code a number to linked list
def number_to_list(number):
head,tail = None,None
p = True
for x in str(number):
if x=='-':
p = False
continue
else:
if p:
node = Node(int(x))
else:
node = Node(int("-"+x))
if head:
tail.next = node
else:
head = node
tail = node
return head
pass
this is code for conversion of linked list to number
def list_to_number(head):
neg = False
num = ''
for number in head:
val = str(number)
if (val.find('-')!= -1):
neg = True
num=num+val.replace('-','')
if (neg==False):
return int(num)
else:
return -1*int(num)
pass
here it is the test cases
def test_number_to_list():
import listutils
head = number_to_list(120)
assert [1,2,0] == listutils.from_linked_list(head)
assert 120 == list_to_number(head)
head = number_to_list(0)
assert [0] == listutils.from_linked_list(head)
assert 0 == list_to_number(head)
head = number_to_list(-120)
assert [-1, -2, 0] == listutils.from_linked_list(head)
assert -120 == list_to_number(head)
here from_linked_list means
# avoids infinite loops
def from_linked_list(head):
result = []
counter = 0
while head and counter < 100: # tests don't use more than 100 nodes, so bail if you loop 100 times.
result.append(head.value)
head = head.next
counter += 1
return result
at last in this the problem is while converting the linked list to single number it is encountering an error i.e.,node object is not iterable
please help me out of this to write the code
def list_to_number(head):
neg = False
num = ''
for number in head:
val = str(number)
TypeError: 'Node' object is not iterable
here this is the traceback
The
for number in head:
is not a correct way to iterate of the list.
You need to start from head and then follow the chain of next references.
Note that if __iter__ is defined on Node like this:
class Node(object):
def __init__(self,value=None):
self.value = value
self.next = None
def __iter__(self):
that = self
while that is not None:
yield that.value
that = that.next
Then:
for number in head:
Would actually work.

Categories

Resources