List index out of range in 2D list - python

I understand that there are similar questions to this here, here, and here. The first one addresses 1D lists, the second is great except it doesn't seem to work, and the third is close, but I still don't quite understand my issue.
Here is what I am trying to do. I need to create an 2D list (a 2D array in java and C++, which I am much more familiar with) filled with 0's. It needs to be size 20 across and 15 down.
Here is what I have tried:
self.grid = [[0 for x in range(GRID_COLUMN_SIZE)] for y in range(GRID_ROW_SIZE)] # where GRID_ROW_SIZE = 15, GRID_COLUMN_SIZE = 20
Note, I tried with the two constants switched (COLUMN first, then ROW), and it broke slightly later. In addition, I print the 2D list out and it's the wrong dimensions (15 across and 20 down).
Here is my later use of self.grid. Without getting too deep, I am iterating through all the values of the list (grid) and getting the surrounding points.
def populatePaths(self):
for row in range(len(self.grid)):
for column in range(len(self.grid[row])):
if self.isPointAccessible(column, row):
self.addPaths(column, row)
def addPaths(self, x, y):
key = Point(x, y)
print "Each: %s" % (key.toString())
points = key.getSurroundingPoints()
self.removeBarriersFromPath(points)
self.paths[key] = points # a map from Points to lists of surrounding Points
Basically, I remove points along the path that can't be reached:
def removeBarriersFromPath(self, path):
for point in list(path):
print "Surrounding %s" % (point.toString())
if not self.isPointAccessible(point.x, point.y):
path.remove(point)
return path
self.isPointAccessible() is trivial, but this is where it breaks. It checks to see if the value at the (x,y) location is 0: return self.grid[x][y] == 0
I added these print statements (point.toString() returns (x,y)) to show me the points as they happen, and I am able to iterate until x==14, but it breaks at x==15.
I suspect that I am getting the column/row order in the looping incorrect, but I'm not sure when/how.
Let me know if I didn't explain something clearly enough.
Edit Here is the traceback:
Traceback (most recent call last):
File "/home/nu/catkin_ws/src/apriltags_intrude_detector/scripts/sphero_intrude_gui.py", line 70, in start
self.populatePaths()
File "/home/nu/catkin_ws/src/apriltags_intrude_detector/scripts/sphero_intrude_gui.py", line 156, in populatePaths
self.addPaths(column, row)
File "/home/nu/catkin_ws/src/apriltags_intrude_detector/scripts/sphero_intrude_gui.py", line 162, in addPaths
self.removeBarriersFromPath(points)
File "/home/nu/catkin_ws/src/apriltags_intrude_detector/scripts/sphero_intrude_gui.py", line 168, in removeBarriersFromPath
if not self.isPointAccessible(point.x, point.y):
File "/home/nu/catkin_ws/src/apriltags_intrude_detector/scripts/sphero_intrude_gui.py", line 173, in isPointAccessible
return self.grid[x][y] == 0
IndexError: list index out of range

You did not post the whole source for isPointAccessible but from the error message it looks like your return line must be:
return self.grid[y][x] == 0
since y denotes the row number and x is the column.

Related

Program to draw line when y coordinates match or z coordinates

I am working on Ironpython in Revit application.
This is the code below I was trying in python. Help would be appreciated.
From the list of points, there is a first point and second point. I have created functions for them.
The script should check if the y coordinates are same and draw line if true.
Its not working and returning unexpected error - new line error.
`The inputs to this node will be stored as a list in the IN variables.`
points = IN[0]
`# Place your code below this line`
lines = []
def fp(x)
firstpoint = points[x]
return firstpoint
def sp(x)
secondpoint = points[x+1]
return secondpoint
x = 0
while x <= points.Count:
if (fp(x).Y == sp(x).Y) or (fp(x).Z == sp(x).Z):
setlines = Line.ByStartPointEndPoint(fp(x), sp(x))
lines.append(setlines)
x = x + 1
`# Assign your output to the OUT variable.`
OUT = lines
As #itprorh66 points out, there's really not enough info here to definitively answer your question, but one issue is you're incorrectly comparing what I assume are floats.
fp(x).Y == sp(x).Y
Instead of comparing for direct equality, you'll need to compare for equality within a tolerance. Here is some discussion on how to do that, What is the best way to compare floats for almost-equality in Python?

How to fix: "Int object not iterable" when assigning variables to two lists?

I tried making a question on this earlier and did a horrible job of explaining what I wanted. Hopefully the information I provide in this one is more helpful.
The program I am trying to make will take read input from a file in the form of the following: (there will be multiple varying test cases)
7 10
4 8
The program will assign a variable to the top-right integer (in this case, 10) and the bottom-left integer (4). The program will then compute the difference of the two variables. Here is the code I have so far -
with open('C:\\Users\\ayush\\Desktop\\USACO\\paint\\paint_test.in', 'r') as fn:
matrix = fn.readlines()
input_array = []
for line in matrix:
input_array.append(line.strip())
for p,q in enumerate(input_array):
for x,y in enumerate(p):
pass
for a,b in enumerate(q):
pass
print(y - a)
When I, however, run this code I get the following error:
Traceback (most recent call last):
File "C:\Users\ayush\Desktop\USACO\paint\paint.py", line 16, in <module>
for x,y in enumerate(p):
TypeError: 'int' object is not iterable
[Finished in 0.571s]
I'm not sure as to what the problem is, and why my lists cannot be iterated.
I hope I did a better job explaining my goal this time. Please let me know if there are any additional details I could try to provide. I would really appreciate some help - I've been stuck on this for the longest time.
Thanks!
Were you going for something along the lines of:
with open('C:\\Users\\ayush\\Desktop\\USACO\\paint\\paint_test.in', 'r') as fn:
matrix = fn.readlines()
input_array = []
for line in matrix:
input_array.append(line.strip())
top_line, bottom_line = input_array # previously p, q
top_right, top_left = top_line.split() # previously x, y
bottom_right, bottom_lefft = bottom_line.split() # previously a, b
print(int(top_left) - int(bottom_right)) # you would have run into issue subtracting strings without the int() calls
?
If so, that should work, but you can avoid all the unpacking if you just use [0] and [-1] indexes to get the first and last items (this has the advantage of working on a matrix of any size):
with open('C:\\Users\\ayush\\Desktop\\USACO\\paint\\paint_test.in', 'r') as fn:
lines = fn.read().splitlines()
matrix = [
[
int(item)
for item in line.split()
]
for line in lines
]
top_left = matrix[0][-1]
bottom_right = matrix[-1][0]
print(top_left - bottom_right)

Code works for a small selection but not the entire database

I have a similar problem to this one.
I am working on Qgis. To speed things up, I've created a small selection of my map on which I test my code. It works great. Here is the section that poses problem later :
layer = qgis.utils.iface.activeLayer()
iter = layer.getFeatures()
dict = {}
#iterate over features
for feature in iter:
#print feature.id()
geom = feature.geometry()
coord = geom.asPolyline()
### GET FIRST AND LAST POINTS OF POLY + N ORIENTATION###
# Get Objective Orientation
d=QgsDistanceArea()
d.setEllipsoidalMode(True)
points=geom.asPolyline()
#second way to get Endpoints
first = points[0]
last = points[-1]
r=d.bearing(first, last)
b= "NorthOrientation= %s" %(math.degrees(r))
# Assemble Features
dict[feature.id() ]= [first, last]
### KEY = INTERSECTION, VALUES = COMMONPOINTS###
dictionary = {}
a = dict
for i in a:
for j in a:
c = set(a[i]).intersection(set(a[j]))
if len(c) == 1:
d = set(a[i]).difference(c)
c = list(c)[0]
value = list(d)[0] #This is where the problem is
if c in dictionary and value not in dictionary[c]:
dictionary[c].append(value)
elif c not in dictionary:
dictionary.setdefault(c, [])
dictionary[c].append(value)
else: pass
print dictionary
This code works for the 10 polylines of my small selection (which I've stored in a seperate shapefile). But when I try to run it though the 40 000 lines of my original database, I get the following Error:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "c:/users/16116/appdata/local/temp/tmp96wd24.py", line 47, in <module>
value = list(d)[0]
IndexError: list index out of range
A few things:
This code stems from a first question that you can find here. I'm still pretty new to python so to be honest I have a hard time understanding how this exact part of the code works, but I know it does (at least for the small dataset).
The small "test selection"'s structure is identical to the entire database. Only the length has changed.
If anyone has had the same experience or knows why this problem occures, I would be very greatful for any indications.

Sampling from degree distribution of graph

I have a simple, stupid Python problem. Given a graph, I'm trying to sample from a random variable whose distribution is the same as that of the degree distribution of the graph.
This seems like it should pretty straightforward. Yet somehow I am still managing to mess this up. My code looks like this:
import numpy as np
import scipy as sp
import graph_tool.all as gt
G = gt.random_graph(500, deg_sampler=lambda: np.random.poisson(1), directed=False)
deg = gt.vertex_hist(G,"total",float_count=False)
# Extract counts and values
count = list(deg[0])
value = list(deg[1])
# Generate vector of probabilities for each node
p = [float(x)/sum(count) for x in count]
# Load into a random variable for sampling
x = sp.stats.rv_discrete(values=(value,p))
print x.rvs(1)
However, upon running this it returns an error:
Traceback (most recent call last):
File "temp.py", line 16, in <module>
x = sp.stats.rv_discrete(values=(value,p))
File "/usr/lib/python2.7/dist-packages/scipy/stats/distributions.py", line 5637, in __init__
self.pk = take(ravel(self.pk),indx, 0)
File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line 103, in take
return take(indices, axis, out, mode)
IndexError: index out of range for array
I'm not sure why this is. If in the code above I write instead:
x = sp.stats.rv_discrete(values=(range(len(count)),p))
Then the code runs fine, but it gives a weird result--clearly the way I've specified this distribution, a value of "0" ought to be most common. But this code gives "1" with high probability and never returns a "0," so something is getting shifted over somehow.
Can anyone clarify what is going on here? Any help would be greatly appreciated!
I believe the first argument for x.rvs() would be the loc arg. If you make loc=1 by calling x.rvs(1), you're adding 1 to all values.
Instead, you want
x.rvs(size=1)
As an aside, I'd recommend that you replace this:
# Extract counts and values
count = list(deg[0])
value = list(deg[1])
# Generate vector of probabilities for each node
p = [float(x)/sum(count) for x in count]
With:
count, value = deg # automatically unpacks along first axis
p = count.astype(float) / count.sum() # count is an array, so you can divide all elements at once

Read file elements into 3 different arrays

I have a file that is space delimited with values for x,y,x. I need to visualise the data so I guess I need so read the file into 3 separate arrays (X,Y,Z) and then plot them. How do I read the file into 3 seperate arrays I have this so far which removes the white space element at the end of every line.
def fread(f=None):
"""Reads in test and training CSVs."""
X = []
Y = []
Z = []
if (f==None):
print("No file given to read, exiting...")
sys.exit(1)
read = csv.reader(open(f,'r'),delimiter = ' ')
for line in read:
line = line[:-1]
I tried to add something like:
for x,y,z in line:
X.append(x)
Y.append(y)
Z.append(z)
But I get an error like "ValueError: too many values to unpack"
I have done lots of googling but nothing seems to address having to read in a file into a separate array every element.
I should add my data isn't sorted nicely into rows/columns it just looks like this
"107745590026 2 0.02934046648 0.01023879368 3.331810236 2 0.02727724425 0.07867902517 3.319272757 2 0.01784882881"......
Thanks!
EDIT: If your data isn't actually separated into 3-element lines (and is instead one long space-separated list of values), you could use python list slicing with stride to make this easier:
X = read[::3]
Y = read[1::3]
Z = read[2::3]
This error might be happening because some of the lines in read contain more than three space-separated values. It's unclear from your question exactly what you'd want to do in these cases. If you're using python 3, you could put the first element of a line into X, the second into Y, and all the rest of that line into Z with the following:
for x, y, *z in line:
X.append(x)
Y.append(y)
for elem in z:
Z.append(elem)
If you're not using python 3, you can perform the same basic logic in a slightly more verbose way:
for i, elem in line:
if i == 0:
X.append(elem)
elif i == 1:
Y.append(elem)
else:
Z.append(elem)

Categories

Resources