I'm having a weird issue with numpy right now on a current assignment. I'm making an ant colony AI for a class (based on the Google AI Ants Challenge), and I'm using a diffusion based approach where I essentially diffuse out a scent from food/enemy hills on each turn. I've been using numpy since each turn basically consists of doing a lot of matrix manipulations, but I just recently got a weird bug that I can't figure out.
At the beginning of each turn, I update the field associated with each scent before I run the diffusion iterations:
# Here I update the "potential" field (hills_f) and the
# diffusion values (hills_l) for the hills scent. Diffusion values
# (lambda values) are 1 except for on ants, where they are higher
# or lower depending on their colony.
self.hills_f *= TURN_DECAY
self.hills_l = np.ones_like(self.hills_l)
# Update the lambda matrix
for r,c in ants.my_ants():
self.hills_l[r][c] = MY_HILLS_LAMBDA
for r,c in ants.enemy_ants():
self.hills_l[r][c] = ENEMY_HILLS_LAMBDA
So this code runs at the beginning of each turn (along with a similar snippet for the food scent), but on a random turn (ranges from 10-40), I get the following error:
Traceback (most recent call last):
File "long_file_path...", line 167, in run
bot.do_turn(ants)
File "MyBot.py", line 137, in do_turn
self.hills_l[r][c] = ENEMY_HILLS_LAMBDA
TypeError: 'numpy.float64' object does not support item assignment
It looks like it randomly turns self.hills_l into a scalar between the two for-loops, which doesn't make any sense to me. It's also weird that there's similar code for the food scent, which doesn't crash ever, and that this problem shows up so non-deterministically.
I can post more code if necessary, but I think everything should be there, especially since the problem seems to occur between the for loops.
Thanks!
Related
I'm writing a program that is for a friend of mine that is currently studying Aeronautical Engineering. I'm trying to test if the math I've implemented works. For those who know, I'm trying to calculate the divergence (I think I'm not an engineer and I'm not going to pretend that I am).
He sent me a Stack overflow link to a how he thinks this should be done. (The thread can be found here. His version doesn't work for me as it gives me a Numpy error as seen below:
numpy.core._internal.AxisError: axis 1 is out of bounds for array of
dimension 1
Now I've tried a different method that gives me a different error as seen below:
ValueError: operands could not be broadcast together with shapes (60,58)
(60,59)
This method gives me the error above and I'm not entirely sure how to fix it. I've put the code that gives me the above error.
velocity = np.diff(c_flow)/np.diff(zex)
ucom = velocity.real
vcom = -(velocity.imag)
deltau = np.divide((np.diff(ucom)),(np.diff(x)))
deltav = np.divide((np.diff(vcom)),np.diff(y))
print(deltau + deltav)
Note: C_flow is defined earlier in the program and is the complex potential. zex is also defined earlier as an early form of the complex variable. x and y are two coordinate matrices from coordinate vectors.
The expected results from the print statement should be zero or a value that is very close to zero. (I'm not entirely sure what the value should be but as I've said, I'm not an engineer)
Thank you in advance
EDIT:
After following BenT's advice I used np.gradient and np.sum but this was adding the axis in the wrong direction so to counteract this the I separated the two functions as seen below:
velocity = np.diff(c_flow)/np.diff(z)
grad = (np.gradient(velocity))
divergence = np.sum(grad, axis=0)
print(np.average(divergence))
print(np.average(velocity))
I am teaching myself Python and am trying out a challenge I found to create a quote program for a gardener. I have almost all of it working and have added in iteration so that the user can make more than one quote without re-starting the program.
It produces the quote perfectly the first time but on the second run it presents this error:
Traceback (most recent call last):
File "/Users/shaunrogers/Desktop/Plymstock Prep/GCSE CS/SOL/Controlled Assessment/Sample Papers Solutions/gardening Task 2.py", line 105, in <module>
lawn = m2_items("lawn",0)
File "/Users/shaunrogers/Desktop/Plymstock Prep/GCSE CS/SOL/Controlled Assessment/Sample Papers Solutions/gardening Task 2.py", line 23, in m2_items
minutes = area*time[index]
TypeError: 'float' object is not subscriptable
I have the following code as a function that is producing the error:
def m2_items (item,index):
global costs, time, LABOUR
length = int(input("How long is the "+ item+"?\n"))
width = int(input("How wide is the "+item+"?\n"))
area = length*width
cost_m2 = float(costs[index])
total_cost = area*cost_m2
minutes = area*time[index]
hours = int(minutes/60)
labour = LABOUR*hours
labour_cost=round(labour,2)
m2_details = [area, cost_m2, total_cost,hours, labour_cost]
return m2_details
I have tried re-setting the local variables on the running of the function (but I didn't think this was needed as the variables should be removed from memory once the function has run).
I hope the question is clear and that I can get some insight. To re-iterate, what I want the program to do is allow me to call this function multiple times.
You are using the global time variable, which is initially subscriptable (probably an array). As your program continues, some other part of your code will assign a new value to time, maybe accidentally because you wrote time = some_calculation() instead of time[i] = some_calculation(), or maybe you are using the name time somewhere else without realizing it's already in use.
Do a search for all the places where you use the name time and you will probably find your error.
This is a common problem with global variables. Sometimes something updates them from another part of the code, and the error will sneak up on you like this.
I'm experiencing a very weird problem when using a large numpy array. Here's the basic context. I have about 15 lists of paired objects which I am constructing adjacency matrices for. Each adjacency matrix is about 4000 x 4000 (square matrix where the diagonal means the object is paired with itself) so it's big but not too big. Here's the basic setup of my code:
def createAdjacencyMatrix(pairedObjectList, objectIndexList):
N = len(objectIndexList)
adj = numpy.zeros((N,N))
for i in range(0, len(pairedObjectList):
#put a 1 in the correct row/column position for the pair etc.
return adj
In my script I call this function about 15 times, one for each paired object list. However every time I run it I get this error:
adj = np.zeros((N,N))
MemoryError
I really don't understand where the memory error is coming from. Even though I'm making this big matrix, it only exists within the scope of that function, so shouldn't it be cleared from memory every time the function is finished? Not to mention, if the same variable is hanging around in memory, then shouldn't it just overwrite those memory positions?
Any help understanding this much appreciated.
EDIT : Here's the full output of the traceback
Traceback (most recent call last):
File "create_biogrid_adjacencies.py", line 119, in <module>
adjMat = dsu.createAdjacencyMatrix(proteinList,idxRefDict)
File "E:\Matt\Documents\Research\NU\networks_project\data_setup_utils.py", line 18, in createAdjacencyMatrix
adj = np.zeros((N,N))
MemoryError
I'm fairly new to python and understand that recursion is an important concept to grasp. I've been dabbling with various scripts to exercise my knowledge and have come up with the following script to simulate a lottery draw, where you simply draw six from 49 numbers and compare them with another six to see if you've won. I'm struggling though with the recursive function taking the value of another function.
I'm sure it's going to be straightforwardish, but cannot fathom it myself.
Here's my code so far:
from random import randint
def drawSix():
six = []
while len(six) < 6:
a = randint(1,49)
if a not in six:
six.append(a)
return sorted(six)
def lottery(draw,ticket):
if draw == ticket:
return 'win'
return lottery(drawSix(),drawSix())
I call the function with lottery(drawSix(),drawSix())
and get the following recursively.
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
lottery(drawSix(),drawSix())
File "/Users/johnhopkins/Desktop/lottery.py", line 14, in lottery
return lottery(drawSix(),drawSix())
def lottery(draw,ticket):
if draw == ticket:
return 'win'
return lottery(drawSix(),drawSix())
The odds of you actually generating two identical tickets are quite large, well over 1000 which is the maximum stack size of Python.
You need to either do this iteratively to avoid blowing your stack.
def lottery(draw,ticket):
while draw != ticket:
draw, ticket = drawSix(), drawSix()
return "win"
Note this has a very ugly O(n) of O(inf) you could end up running this forever if you were unlucky and still not finding a winning pair
Well, your question has has been answered, but I would suggest changing your drawSix function. As it is now, it could technically run forever. random has a sample method to generate unique numbers.
def drawSix():
return sorted(random.sample(range(1, 50), 6))
Yes - the lottery function will keep on calling itself, each time putting a new version of itself onto the call stack, going deeper and deeper into itself until there are two matching numbers.
This can take a long time, and Python will eventually say "oi! stop it!" and crash.
Some programming languages have a feature called 'tail call optimisation', which means if you try to return the result of the same function, instead of making a new call to the function inside the current one, it simply replaces itself in the stack.
Python doesn't do that.
def lottery():
while (drawSix() != drawSix()):
continue
return 'win!'
will have the same effect as your recursive version, but won't die with recursion errors.
You have not made any programming mistakes. However, the probility of winning the lottery is very small, so you need to generate a lot. Easy recursion add something to the stack.
Number of lotto tickets can be found by the formula for combinations with repetition:
(49+6-1)! / (6! * (49-1)!) = 25827165
This is a lot... Decrease the number 6 or 49, add some debugging lines and you'll see that the code works fine!
[SearchAgent] using function depthFirstSearch
[SearchAgent] using problem type PositionSearchProblem
Path found with total cost of 999999 in 0.0 seconds
Search nodes expanded: 1
Traceback (most recent call last):
File "C:\Documents and Settings\vpn\My Documents\Aptana Studio 3 Workspace\Project 1 - Search\pacman.py", line 672, in <module>
runGames( **args )
File "C:\Documents and Settings\vpn\My Documents\Aptana Studio 3 Workspace\Project 1 - Search\pacman.py", line 638, in runGames
game.run()
File "C:\Documents and Settings\vpn\My Documents\Aptana Studio 3 Workspace\Project 1 - Search\game.py", line 662, in run
action = agent.getAction(observation)
File "C:\Documents and Settings\vpn\My Documents\Aptana Studio 3 Workspace\Project 1 - Search\searchAgents.py", line 121, in getAction
if i < len(self.actions):
TypeError: object of type 'NoneType' has no len()
m working on a project in which i have to test my pacman agent to reach to its destination in less possible space and time complexity by applying DFS(Depth First Algorithm)
My code for it is
stack = util.Stack()
explored = list()
start = problem.getStartState()
for item in problem.getSuccessors(start):
state = item[0]
path = list()
path.append(item[1])
stateInfo = (state, path)
stack.push(stateInfo)
explored.append(start)
while stack.isEmpty():
state = stack.pop()
if problem.isGoalState(state[0]):
return state[1]
for states in problem.getSuccessor(state[0]):
newstate = states[0]
newpath = list(state[1])
newpath.append(states[1])
newstateInfo = (newstate, newpath)
stack.push(newstateInfo)
explored.append(state[0])
What should i suppose to do now.. my pacman agent get stuck to its starting position in east dirction opposite to its destination.
The supporting files to run the agent is mentioned in https://www.edx.org/courses/BerkeleyX/CS188.1x/2012_Fall/courseware/Week_2/Project_1_Search/
I think I know what is going on (though I can't be certain given the limited amount of code in the question).
My guess is that the code you've posted is getting called to set up the variable self.actions where you're getting an error. The error is happening because you're getting None returned from the function, rather than the list you expect.
The underlying bug is that your main loop has it's test backwards. You want while not stack.isEmpty(), rather than what you have. Because you've just pushed several values onto the stack, the loop as written exits immediately. After the loop you reach the end of the function, which is equivalent to returning None in Python. That None is causing the exception later.
Even if you fix the broken loop, falling off the end of the function can happen anyway if a path cannot be found to the goal state. I suggest adding code to detect this, and respond appropriately. You could raise an exception (since it shouldn't happen in normal situations), or maybe return an empty list.
There's another issue where you're not checking if a newly visited state has already been explored. This could lead to an infinite loop, as you search from one state to a neighbor and then back. A set will also be better than a list for explored. You can check it with if state in explored (which also works on lists, but less efficiently).
As a side issue, some of your variables are very poorly named. state different types at different times, and having a second variable states makes it even more confusing, especially with indexing thrown in.
I suggest unpacking the tuples you pushed onto the stack with the code state, path = stack.pop(), which will solve part of the issue. Then just rename states to something else (or perhaps unpack it too, with something like for neighbor, direction in problem.getSuccessor(state)) and you'll be good to go.
You can also save a few lines of code by pushing the start state to your stack, rather than doing an extra loop over its neighbors in the setup code.