py2neo rel() list indices must be integer not float - python

I'm trying to import nodes into Neo4j in a batch. But when I try to execute it, it throws an error: List indices must be integers, not float. I don't really understand which listitems, I do have floats, but these are cast to strings...
Partial code:
graph_db = neo4j.GraphDatabaseService("http://127.0.0.1:7474/db/data/")
batch = neo4j.WriteBatch(graph_db)
for ngram, one_grams in data.items():
ngram_rank = int(one_grams['_rank'])
ngram_prob = '%.16f' % float(one_grams['_prob'])
ngram_id = 'a'+str(n)
ngram_node = batch.create(node({"word": ngram, "rank": str(ngram_rank), "prob": str(ngram_prob)}))
for one_gram, two_grams in one_grams.items():
one_rank = int(two_grams['_rank'])
one_prob = '%.16f' % float(two_grams['_prob'])
one_node = batch.create(node({"word": one_gram, "rank": str(one_rank), "prob": one_prob}))
batch.create(rel((ngram_node, "FOLLOWED_BY", one_node))) #line 81 throwing error
results = batch.submit()
Full traceback
Traceback (most recent call last):
File "Ngram_neo4j.py", line 81, in probability_items
batch.create(rel((ngram_node, "FOLLOWED_BY", one_node))),
File "virtenv\\lib\\site-packages\\py2neo\\neo4j.py", line 2692, in create
uri = self._uri_for(entity.start_node, "relationships"),
File "virtenv\\lib\\site-packages\\py2neo\\neo4j.py", line 2537, in _uri_for
uri = "{{{0}}}".format(self.find(resource)),
File "virtenv\\lib\\site-packages\\py2neo\\neo4j.py", line 2525, in find
for i, req in pendulate(self._requests):,
File "virtenv\\lib\\site-packages\\py2neo\\util.py", line 161, in pendulate
yield index, collection[index],
TypeError: list indices must be integers, not float
running neo4j 2.0, py2neo 1.6.1, Windows 7/64bit, python 3.3/64bit
--EDIT--
Did some testing, but the error is located in the referencing to nodes.
oversimplified sample code:
for key, dict in data.items(): #string, dictionary
batch = neo4j.WriteBatch(graph_db)
three_gram_node = batch.create(node({"word": key}))
pprint(three_gram_node)
batch.add_labels(three_gram_node, "3gram") # must be int, not float
for k,v in dict.items(): #string, string
four_gram_node = batch.create(node({"word": k}))
batch.create_path(three_gram_node, "FOLLOWED_BY", four_gram_node)
# cannot cast node from BatchRequest obj
batch.submit()
When a node is created batch.create(node({props})), the pprint returns a P2Neo.neo4j. batchrequest object.
At the line add_labels(), it gives the same error as when trying to create a relation: List indices must be integers, not float.
At the batch.create_path() line it throws an error saying it can't cast a node from a P2Neo.neo4j. batchrequest object.
I'm trying the dirty-debug now to understand the indices.
--Dirty Debug Edit--
I've been meddling around with the pendulate(collection) function.
Although I don't really understand how it fits in, and how it's used, the following is happening:
Whenever it hits an uneven number, it gets cast to a float (which is weird, since count - ((i + 1) / 2), where i is an uneven number.) This float then throws the list indices error. Some prints:
count: 3
i= 0
index: 0
(int)index: 0
i= 1 # i = uneven
index: 2.0 # a float appears
(int)index: 2 # this is a safe cast
This results in the list indices error. This also happens when i=0. As this is a common case, I made an additional if() to circumvent the code (possible speedup?) Although I've not unit tested this, it seems that we can safely cast index to an int...
The pendulate function as used:
def pendulate(collection):
count = len(collection)
print("count: ", count)
for i in range(count):
print("i=", i)
if i == 0:
index = 0
elif i % 2 == 0:
index = i / 2
else:
index = count - ((i + 1) / 2)
print("index:", index)
index = int(index)
print("(int)index:", index)
yield index, collection[index]

soft debug : print ngram_node and one_node to see what they contains
dirty debug : modify File "virtenv\lib\site-packages\py2neo\util.py", line 161, add a line before :
print index
You are accessing a collection (a Python list given the traceback), so, for sure, index must be an integer :)
printing it will probably help you to understand why exception raised
(Don't forget to remove your dirty debug afterwards ;))

While it is currently possible for WriteBatch objects to be executed multiple times with edits in between, it is inadvisable to use them in this way and this will be restricted in the next version of py2neo. This is because objects created during one execution will not be available during a subsequent execution and it is not easy to detect when this is being requested.
Without looking back at the underlying code, I'm unsure why you are seeing this exact error but I would suggest refactoring your code so that each WriteBatch creation is paired with one and only one execution call (submit). You can probably achieve this by putting your batch creation within your outer loop and moving your submit call out of the inner loop into the outer loop as well.

Related

I'm getting a weird error in my python script

Traceback (most recent call last):
File "main.py", line 17, in <module>
max_height = max(botmoves)
TypeError: '>' not supported between instances of 'tuple' and 'int'
This is the error I'm trying to find the biggest value in a list but it saying something about a ">" here is my code
from random import randint
points = 0
botmoves = [-1000]
for i in range(20):
guess = randint(0, 100)
print('Bot',"guessed the number was", guess)
print("The bot was",abs(guess-100),"off")
print("The bot gets",50 - abs(guess-100),"points")
points = 50 - abs(guess-100),"points"
botmoves.append(points)
max_height = max(botmoves) #this is where the error is
print(botmoves)
The max function needs to be able to compare values to each other, and it does that with the > operator. What the error is telling you is that there are different types of elements in the list, which cannot sensibly be compared to each other. In this case, an int and a tuple.
The reason for that is this line:
points = 50 - abs(guess-100),"points"
The ,"points" at the end makes points into a tuple, for example (37, "points"). The parentheses are optional in many cases.
Probably that's just a copy/paste mistake from the line above, and you didn't mean to put that there:
points = 50 - abs(guess-100)

Causes of Panda3D GeomVertex Writer/Rewriter type error when using the same syntax and object types as in the documentation?

I am completely new to Panda3D on Python and trying to edit a 3D mesh in-place to move its vertices following the user's inputs.
I am using the GeomVertexRewriter or GeomVertexReader + GeomVertexWriter APIs (I tried both), as suggested in the Panda3D documentation here.
However I could not create any GeomVertexWriter (or GeomVertexRewriter which herits from both GeomVertexReader and GeomVertexWriter) object without encountering the following error:
TypeError: Arguments must match:
GeomVertexWriter()
GeomVertexWriter(GeomVertexArrayData array_data)
GeomVertexWriter(GeomVertexData vertex_data)
GeomVertexWriter(Thread current_thread)
GeomVertexWriter(GeomVertexData vertex_data, const InternalName name, Thread current_thread)
GeomVertexWriter(GeomVertexArrayData array_data, int column, Thread current_thread)
GeomVertexWriter(GeomVertexArrayData array_data, Thread current_thread)
GeomVertexWriter(GeomVertexData vertex_data, Thread current_thread)
The error does not happen when I create a GeomVertexReader, and it seems to work perfectly.
Also, my vdata is of the correct type (<class 'panda3d.core.GeomVertexData'>) and prints correctly too (shortened version below):
CatMesh2
949 rows.
Array 0 (0000018310B6A3E0, [ vertex(3f) normal(3f) ]):
row 0:
vertex 1.57086 8.22246 0.487809
normal 0.672279 0.738758 0.0477129
row 1:
vertex 1.69762 8.07273 1.88392
normal 0.748853 0.662674 0.00910493
[...]
row 948:
texcoord 0.249509 0.530177 0
It seems that everywhere I searched, the only way this constructor is ever called is with the very same syntax GeomVertexWriter(vdata, 'vertex') (or 'texcoord'), so I don't really see why this type error occurs.
I tried the following code (that doesn't work):
vertex = GeomVertexRewriter(vdata, 'vertex')
while not vertex.isAtEnd():
v = vertex.getData3()
vertex.setData3(v[0], v[1], 0.0)
>>> File "...\src\geometry_processing.py", line 6, in editVertexData
vertex = GeomVertexRewriter(vdata, 'vertex')
TypeError: Arguments must match:
[...]
Same goes for this one:
vertexW = GeomVertexWriter(vdata, 'vertex')
vertexR = GeomVertexReader(vdata, 'vertex')
v = vertexR.getData3()
vertexW.setData3(v[0], v[1], newVal)
It also happens when I replace 'vertex' with 'texcoord'.
The reader version however works fine:
vertexR = GeomVertexReader(vdata, 'vertex')
v = vertexR.getData3()
print(v)
>>> LVecBase3f(1.57086, 8.22246, 0.487809)
Has anyone ever encountered this error? I have no idea why it occurs even though I am doing the same thing as in the examples in the documentation and in other places. If it was not my mistake, could it be that the vdata from the model I am using is the issue?
How did you obtain the GeomVertexData object? It's possible that you have a "const" version of this object, such as obtained from geom.getVertexData(), but you need a non-const version, such as obtained from geom.modifyVertexData().

Pyomo TypeError: unhashable type: 'EqualityExpression'

I am building an energy planning model in Pyomo and I am running into problems building some power grid constraints.
def grid2grid_rule(m, ts):
return m.power['grid','grid', ts] == 0
m.const_grid2grid = Constraint(ts_i, grid2grid_rule)
def import_rule(m, ts):
return m.gridImport[ts] == sum(m.power['grid',derIn,ts] for derIn in elIn)
m.const_import = Constraint(ts_i, rule = import_rule)
def export_rule(m, ts):
return m.gridExport[ts] == sum(m.power[derOut,'grid',ts] for derOut in elOut)
m.const_export = Constraint(ts_i, export_rule)
Definition of Power:
m.power = Var(elOut, elIn, ts_i, within = NonNegativeReals)
Explaining the code:
m.power is a decision variable with 3 indices: The electricity source (elOut), the electricity 'usage' (elIn) and the current timestep index ts_i. elOut and elIn are numpy arrays with strings and ts_i a numpy array with integers from 0 to how many timesteps there are.
The first constraint just says that at any timestep there the electricity cannot flow from the grid to the grid. The import constraint says that the grid imports at each timestep are the sum over all power flows from the grid to electricity takers. The export constraint says that the grid exports at each timestep are a sum of all powerflows from electricity 'givers' to the grid.
Now, my problem is, when I comment the grid2grid and the export constraint, it works and a set of constraints is built as expected. However, for example when I uncomment the export rule, which is almost identical to the import rule, I get this error:
m = build_model('Input_Questionaire.xlsx', 'DER_excel', yeardivision = "repr_day")
ERROR: Constructing component 'const_export_index_1' from data=None failed:
TypeError: Problem inserting gridExport[1] == power[pv_ground,grid,1] +
power[wind_s,grid,1] + power[battery,grid,1] + power[grid,grid,1] into set
const_export_index_1
Traceback (most recent call last):
File "C:\Users\Axel\Anaconda3\lib\site-packages\pyomo\core\base\sets.py", line 824, in add
if tmp in self:
File "C:\Users\Axel\Anaconda3\lib\site-packages\pyomo\core\base\sets.py", line 998, in __contains__
return self._set_contains(element)
File "C:\Users\Axel\Anaconda3\lib\site-packages\pyomo\core\base\sets.py", line 1302, in _set_contains
return element in self.value
TypeError: unhashable type: 'EqualityExpression'
Accompanied with this error:
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
...
...
...
File "C:\Users\Axel\Anaconda3\lib\site-packages\pyomo\core\base\sets.py", line 833, in add
raise TypeError("Problem inserting "+str(tmp)+" into set "+self.name)
TypeError: Problem inserting gridExport[1] == power[pv_ground,grid,1] + power[wind_s,grid,1] + power[battery,grid,1] + power[grid,grid,1] into set const_export_index_1
I do not know how to fix it, especially since there is basically no difference in the two Constraints...
Thanks heaps for your help!
Axel
Ugh... just saw it. It's an easy one. :)
you omitted "rule=" portion of the constraint construction, so it is passing in the function as a set or something weird...
Anyhow. Change:
m.const_export = Constraint(ts_i, export_rule)
to:
m.const_export = Constraint(ts_i, rule=export_rule)
same for your grid2grid

'tuple' not callable error

I now that this question has been asked several times. However, the answers do not seem to resolve my problem.
I get a type error, 'tuple' object is not callable. I get this even though the tuple inside the list is separated by commas in the correct way:
def aiMove(b):
movesList = moves(b, -1)
heuristic = []
if movesList:
for m in movesList:
bt = copy.deepcopy(b)
print("bt: ", bt)
bt[m[0]][m[1]] = -1
h = heat[m[0]][m[1]]
for move in m[2]:
i=1;
try:
while (-1* bt[m[0] + i*move[0]][m[1] + i*move[1]] < 0):
bt[m[0] + i*move[0]][m[1] + i*move[1]] *= -1
bt[m[0] + i*move[0]][m[1] + i*move[1]] += -1
i += 1;
except IndexError:
continue
alpha = max(float('-inf'), alphabeta(bt, depth-1, h, float('-inf'), float('inf'), 1))
heuristic.append(alpha)
if (float('inf') <= alpha):
break
selectedMove = movesList[int(heuristic.index(max(heuristic)))]
move(b, selectedMove, -1)
else:
print ("The AI can't move!")
return []
selectedMove is (3, 2, [(0 , 1)]) for example. The moves() function returns a list of moves like the final value for selectedMove. It is an alpha beta pruning implementation for game tree search. The move() function actually moves the piece to that position and updates the board to finish the computers' turn.
the variable b represents values on the current game board
Every conversion I try (i.e. force selectedMove to be a list in itself, etc..) will give the same error in the line "move(b, selectedMove, -1)"
Does somebody see what may be wrong?
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1489, in __call__
return self.func(*args)
File "C:\Users\Loek Janssen\Documents\GitHub\CITS1401-Project\DrawBoard.py", line 131, in eventfun
placePiece(x, y, b, n)
File "C:\Users\Loek Janssen\Documents\GitHub\CITS1401-Project\DrawBoard.py", line 119, in placePiece
project2.aiMove(b)
File "C:\Users\Loek Janssen\Documents\GitHub\CITS1401-Project\project2.py", line 225, in aiMove
move(b, selectedMove, -1)
TypeError: 'tuple' object is not callable
In this line, you say that you're going to use the name move to refer to elements of m[2]:
for move in m[2]:
But then later, you try to call a function that you've called move:
move(b, selectedMove, -1)
Once you've seen this, the error message makes complete sense:
TypeError: 'tuple' object is not callable
because the name move doesn't refer to the function any more, but to the last tuple it was bound to in the loop.
More important than fixing this particular error (don't use move for a variable name if you also want to use it to refer to a function) is recognizing how the interpreter told you exactly what the problem was.
It said that a tuple wasn't callable; in the line of code it complained about, you were calling move; thus move was a tuple, and your next step should've been adding print(move) (or print(type(move), repr(move)) if you want to be fancy) to see what tuple it actually was.

How do I multiply a string without getting TypeError: can't multiply sequence by non-int of type 'function'?

I want to be able to print symbols that represent numbers using functions and while loops
Ex:
number = 250
# symbols
C = 100
^ = 50
should print
CC^
While printing one function may work, trying to concatenate two or more print functions lead me to the type error:
TypeError: can't multiply sequence by non-int of type 'function'
number = 251;
def numeral_C(number_par):
while number_par >=100:
numeral_C = number_par / 100
print "C"*numeral_C,
number_par = number_par - numeral_C*100
return ""
def numeral_UpArrow(number_par):
while number_par >=50:
numeral_upArrow = number_par / 50
print "^"*numeral_UpArrow, #error
number_par = number_par - numeral_UpArrow*50
return ""
etruscan_C = str(numeral_C(number))
etruscan_UpArrow = str(numeral_UpArrow(number)) #error
print etruscan_C+etruscan_UpArrow
Traceback (most recent call last):
File "/Applications/Wing IDE/WingIDE.app/Contents/MacOS/src/debug/tserver/_sandbox.py", line 15, in
File "/Applications/Wing IDE/WingIDE.app/Contents/MacOS/src/debug/tserver/_sandbox.py", line 11, in numeral_UpArrow
**TypeError: can't multiply sequence by non-int of type 'function'
I wonder, Is there a way I can print two or more functions without getting the error?
As the others state, you have a problem in re-using in an assignment something that is already the same name as a function:
def numeral_C(number_par):
while number_par >=100:
#this numeral_C is already a known function name, now youre reusing it as an int
numeral_C = number_par / 100
#you're using print inside a function, not a best practice, but.....
print "C"*numeral_C,
#uncomment the below line to see why the loop is unnecessary
#print '%d = %d - %d' % (number_par - numeral_C*100, number_par, numeral_C*100)
number_par = number_par - numeral_C*100
return ""
#you're printing, rather than returning, making this useless, and you're str()-ing the "" on return
number = 25101;
etruscan_C = str(numeral_C(number))
print
def numeral_c(number_par):
num_c = number_par / 100
return 'C'*num_c
print numeral_c(number)
As you can see by the comments, a simple rename of your function will cure this, and perhaps even a rename of your variable. But onto what I consider the 'larger' problem...
I feel like your original math makes a needless loop. compare the behavior of your numeral_C with my numeral_c: both result in the same numeral-C, but one is more re-usable (by having the 'C' return as a string) and also it lacks a loop and lots of reassignments.
Realistically, I cannot find a case when the loop will happen a second time, based on your reassignment of number_par to subtract the nearest FLOORED 100-multiple. In other words, much of that logic is useless. You could reasonably accomplish that whole function with:
'C'*int(number/100)
You're both using & assigning to the function name numeral_UpArrow (which is a function) inside of that function.

Categories

Resources