Lists in python - slope of a list of lines

I want to calculate the slope of a line using python in dynamo…
No problem:

#Load the Python Standard and DesignScript Libraries
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

xycoords = IN[0][7]

#Strips the commas from the string
xycoords = xycoords.replace(",","")
#Splits the string up into lines
xycoords = xycoords.split()
#Gets the X and Y coordinates and converts back into numbers
x1 = float(xycoords[4])
y1 = float(xycoords[7])
x2 = float(xycoords[15])
y2 = float(xycoords[18])
	
#Formula for slope of line
M = (y2-y1) / (x2-x1)

OUT = M

However… I want it to calculate the slope for a list of lines… I’m still struggling with the nested loop.
Help!

So I tried this:

##Load the Python Standard and DesignScript Libraries 
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

xycoords = IN[0]
M = [ ]

for num in xycoords:
	for xy in num:
		xy = str(num)
		
		#Strips the commas from the string
		xy = xy.replace(",","")
		#Splits the string up into lines
		xy = xy.split()
		C = 0 
		#Gets the X and Y coordinates and converts back into numbers
		x1 = float(xy[C][4])
		y1 = float(xy[C][7])
		x2 = float(xy[C][15])
		y2 = float(xy[C][18])
		#Formula for slope of line
		M.append (y2-y1) / (x2-x1)
		C = C+1

		
OUT = M

But when the line is horizontal I get an error (cos you can’t divide by 0)

So I put in a try except but then the output is a huge list of whatever I’ve put in the except.

What am I doing wrong?

Maybe I am missing something, but why are you doing the string conversion? It looks like you have points before than, why not just use those?

The string methods I’m using don’t work on lists?

The small portion of the graph you are sharing shows a “String from Object” node, which appears to be coming from a list of points. I am asking why you are converting points (numbers) to strings, to split, to then convert back into floats. Why not use StartPoint and EndPoint nodes on the lines and use numbers all the way through? That would also allow you to do it without any python I believe. Of course, this is just speculation based on what little I can see.

I could use start point and endpoint in dynamo but I’m learning python and in theory it should be much easier than it is in dynamo…

In dynamo I’d get start point and end point… Then get x1, y1 and x2 and y2 then run each through a code block with a formula in…

Calculating the slope (M) for one line in python was dead easy (easier than in dynamo), it’s just my lack of python skills that are preventing me doing it for a list (I think).

OK, if you are after a learning experience in python, that is understandable, but I would still leave the data in its native format as much as possible. You can feed python a list of points and get the Start and End points within the loop.

Something like this?

1 Like

Thanks! That’s pretty awesome and obviously a very sleek way of doing it!

I do really want to understand how to get the nested loops to work though… Any idea on my code? I don’t get why it works for 1 line but when I nest the loops it goes crazy.

From what I see, the nested loop you have isn’t really doing anything.

  1. You cycle the xycoords (list of curves)
  2. Then you cycle num, which doesn’t have anything to cycle because there are nested items here.
  3. You could cycle the xy after you have split it because it creates a list, but you don’t
  4. All of these after some unnecessary conversions that I have already mentioned.
1 Like

I’m trying to get my head round HOW the nested loop stuff works…

I got this to work but am pretty sure it’s a bad way of doing it?

The double [0][0] indexy thingy… :expressionless: It’s getting it to loop through the sub level I can’t get my head round.

Look at my example that I shared above.

xycoords = UnwrapElement(IN[0])
for xycoord in xycords:
    coord = xycoord.replace(",","")
    splitCoord = coord.split()
    x1 = float(splitCoord[4]) #why are you indicating specific indices here?
    #...the rest is like you have it 
    M.append(##)
    #No need for iterator increment here
1 Like