Basically I am creating a function to determine the perimeter of a polygon based on the vertices. The input parameter is an xyList that contains the coordinates, basically a nested list of coordinate pairs within another list, like so: [ [x1,y1], [x2, y2], [x3,y3], ...]

I am using the good ol' distance formula and summing each distance. My question is related to the syntax of accessing the individual x and y coordinates within the list. Here is the function I have written:

def polyPerimeter(xyList):
perim = float(0)
count = len(xyList)
b = 0; db = 1
while b < count:
tempDist = math.sqrt((float(xyList[b+1[0]]) - float(xyList[0[0]]))**2 + (float((xyList[b+1[1]]) - float(xyList[0[1]])**2)))
perim = perim + tempDist
b += db
return perim

Here is the error I am getting in the Interactive Window:
>>> Unhandled exception while debugging...
Traceback (most recent call last):
File "C:\GEOG560\hw3_perimRect_v2.py", line 24, in polyPerimeter
tempDist = math.sqrt((float(xyList[1[0]]) - float(xyList[0[0]]))**2 + (float((xyList[1[1]]) - float(xyList[0[1]])**2))) # distance formula
TypeError: 'int' object is unsubscriptable

I am pretty sure it is the syntax related to accessing the coordinates. I have tried to make sure that the coordinates are not still strings after being read in from the text file, but I have been using the syntax "print xyList[0[0]]" (i.e. to print the first x coordinate) which is obviously wrong. I haven't been able to find this in the documentation and am still waiting to receive my "Learning Python" text in the mail. Any help is greatly appreciated!

Edited 7 Years Ago by SomewhereInKS: n/a

I would check the way your accessing your list

xylist[0][1] is the way I do it

Or is your way the new Python 3.1.1 way of doing things

Edited 7 Years Ago by gerard4143: n/a

When I try that syntax PythonWin highlights the first [0] in the distance formula and says "Failed to run scrip - syntax error" and will not let me debug at all. I have to use python 2.5 for this class so I'm not sure if the syntax is different.

Open python's interpreter and type this. Do you get an error?

mylist = [[1,2],[3,4]]

print float(mylist[0][0])

I tried "print float(xyList[0][0])" in the interactive window and it DID print the right x coordinate. Despite this I cannot run the script without commenting out the distance formula.

I attached a screenshot of what happens when I try to run the script WITH the distance formula.

Attachments pywin.jpg 95.14 KB

just saw the extra ] and that was it... oh the joy
Thanks for the help

I also have to create a function to determine the minimum bounding rectangle of this polygon (which is just the Xmin, Ymin, Xmax, Ymax). I see how it would be easy to do if I had the X and Y coordinates in separate lists by just using xyList.sort. Is there a similar way to sort a nested list based on the first variable (x) and then for the second (y)?

just saw the extra ] and that was it... oh the joy
Thanks for the help

I also have to create a function to determine the minimum bounding rectangle of this polygon (which is just the Xmin, Ymin, Xmax, Ymax). I see how it would be easy to do if I had the X and Y coordinates in separate lists by just using xyList.sort. Is there a similar way to sort a nested list based on the first variable (x) and then for the second (y)?

I think you answered your own question, copy the x values to a list - sort and copy the y values to another list - sort and you have your max and min values

or

You could try the map function with a lambda function to achieve this

Edited 7 Years Ago by gerard4143: n/a

I think you answered your own question, copy the x values to a list - sort and copy the y values to another list - sort and you have your max and min values

or

You could try the map function with a lambda function to achieve this

alright thanks a bunch for the help

Hmm, your after fixing your originally posted code (which you've already done)...
When running the code I got an index out of bounds error..
So I've made a minor alteration..Not sure if you've already found and fixed this but...

import math

def polyPerimeter(xyList):
    perim = float(0)
    count = len(xyList)-1 # len(xylist) caused an index out of bounds error for me!
    b = 0; db = 1
    while b < count:
        tempDist = math.sqrt(math.fabs((float(xyList[b+1][0]) - float(xyList[b][0])))**2 + math.fabs((float(xyList[b+1][1]) - float(xyList[b][1])))**2)
        perim = perim + tempDist
        b += db
    # finally add the distance between the first and last points...
    tempDist = math.sqrt(math.fabs((float(xyList[0][0]) - float(xyList[count][0])))**2 + math.fabs((float(xyList[0][1]) - float(xyList[count][1])))**2)
    perim+=tempDist
    return perim

# crap I added to test the function
myList = [[0,0],[4,0], [4,4], [0,4]]
perimeter = polyPerimeter(myList)
print "Perimeter is:", perimeter

I've also used fabs to ensure that the distances are all positive and altered the algorithm to include the length between the first and last items in the list.
Just thought I'd mention it!

Cheers for now,
Jas.

Edited 7 Years Ago by JasonHippy: updated code...

Hmm, your after fixing your originally posted code (which you've already done)...
When running the code I got an index out of bounds error..
So I've made a minor alteration..Not sure if you've already found and fixed this but...

import math

def polyPerimeter(xyList):
    perim = float(0)
    count = len(xyList)-1 # len(xylist) caused an index out of bounds error for me!
    b = 0; db = 1
    while b < count:
        tempDist = math.sqrt(math.fabs((float(xyList[b+1][0]) - float(xyList[b][0])))**2 + math.fabs((float(xyList[b+1][1]) - float(xyList[b][1])))**2)
        perim = perim + tempDist
        b += db
    # finally add the distance between the first and last points...
    tempDist = math.sqrt(math.fabs((float(xyList[0][0]) - float(xyList[count][0])))**2 + math.fabs((float(xyList[0][1]) - float(xyList[count][1])))**2)
    perim+=tempDist
    return perim

# crap I added to test the function
myList = [[0,0],[4,0], [4,4], [0,4]]
perimeter = polyPerimeter(myList)
print "Perimeter is:", perimeter

I've also used fabs to ensure that the distances are all positive and altered the algorithm to include the length between the first and last items in the list.
Just thought I'd mention it!

Cheers for now,
Jas.

awesome, thanks. I disabled the perim function when I was debugging the rectangle bound one for testing and didn't notice this. Thanks though, it makes sense

I have finished everything required of me for the assignment except for one little detail. I had to write all of the data for each polygon in a loop to an output.txt file. The input coordinates are floats (ex: (813367.216157178627327, 4433390.361361747607589)). We are supposed to output the coordinates with 2 decimal places. I know floats are a pain when it comes to rounding and was wondering if there is a way to format the numbers this way. Any help is appreciated as always.

Here is the output to the file I have:

outFile.write(str(polyID) +", " + str(polyPerim) +", " + str(minRect[0]) + ", " + str(minRect[2]) +", " + str(minRect[1]) +", " + str(minRect[3]) + "\n")

I wasn't sure if there was a way to do this in this output statement due to the output having to be a string.

>>> x = 813367.216157178627327
>>> x
813367.21615717863
>>> b = '%.2f' % x
>>> b
'813367.22'
>>> f = open('poly.txt', 'w')
>>> f.write(b)
>>> f.close()
>>> a = open('poly.txt', 'r')
>>> a.read()
'813367.22'
>>>
This article has been dead for over six months. Start a new discussion instead.