I am working on a code that will create a visual Sierpinski triangle to 3D print, and in order for it to work I have to use a Pascal triangle algorithm that will create an array so I can use to tell my algorithm that will create my triangles where not to put triangles.
Anyway the problem is, that my code that arranges the triangles creates the triangles by column instead of by row like the Pascal algorithm does so I am just trying to do a quick fix by having a subroutine that rearranges the Pascal array. I am just stumped on how to do it since I am not sure how to avoid index out of range
errors.
This is the code that creates the array for Pascal's triangle.
TL:DR I am trying to make an rearrange an array where rows are the columns and columns are the rows
def pascal(n):
"""Prints out n rows of Pascal's triangle."""
row = [1]
global array
array = [[0 for x in range(int(n))] for y in range(int(n))]
array[0]=row
k = [0]
for x in range(int(max(n,0)-1)):
row=[l+r for l,r in zip(row+k,k+row)]
array[x+1]=row
return 1
This is the output of printing the array. I just want the rows to be columns and columns to be rows
[[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1],
[1, 5, 10, 10, 5, 1],
[1, 6, 15, 20, 15, 6, 1],
[1, 7, 21, 35, 35, 21, 7, 1]]
Here is the full code if you are curious about the project, but it requires rhinoscriptsyntax
to make the model.
import rhinoscriptsyntax as rhino
import math
obj = rhino.GetObject("Select object to transform", preselect=True)
scale = 3
n=math.pow(3,scale)
def pascal(n):
"""Prints out n rows of Pascal's triangle."""
row = [1]
global array
array = [[0 for x in range(int(n))] for y in range(int(n))]
array[0]=row
k = [0]
for x in range(int(max(n,0)-1)):
row=[l+r for l,r in zip(row+k,k+row)]
array[x+1]=row
return 1
pascal(math.pow(2,scale))
print array
def remakePascal():
pass
my_horizontalVector = [[1,0,0,6],
[0,1,0,0],
[0,0,1,0],
[0,0,0,1]]
my_tsfm = [[1,0,0,0], #identity
[0,1,0,0],
[0,0,1,0],
[0,0,0,1]]
def makeTriangle(scale,obj):
w=1/scale
h=1/scale
tsfm= [[w,0,0,0], #scale about origin
[0,h,0,0],
[0,0,1,0],
[0,0,0,1]]
output= rhino.XformMultiply(my_tsfm,tsfm)
new_obj=rhino.TransformObject(obj,output,copy=True)
return new_obj
def placeObj(i):
my_moveUpVector = [[1,0,0,(3/scale)*i],
[0,1,0,(4/scale)*i],
[0,0,1,0],
[0,0,0,1]]
vector = rhino.XformMultiply(my_tsfm,my_moveUpVector)
return vector
n=0
for i in range(int(math.pow(2,scale))):
if(i>0):
hPlace=rhino.XformMultiply(my_tsfm,my_horizontalVector)
obj = rhino.TransformObject(obj,hPlace)
factor = int(math.pow(2,scale))-n
for j in range(factor):
if():
pass
else:
Vertobj=makeTriangle(scale,obj)
tsfm = rhino.TransformObject(Vertobj,placeObj(j),copy=True)
n=n+1
You could do it as shown. It works by first making the array square so that all the rows have the same number of elements. then transposes the rows and columns using the built-in zip()
function, and then finally removes the elements it initially added.
Note also I removed the use of the global variable array
. Global variables are best avoided.
from pprint import pprint
def pascal(n):
"""Creates n rows of Pascal's triangle."""
array = [None for y in range(n)]
row = [1]
array[0] = row
k = [0]
for x in range(max(n, 0)-1):
row = [l+r for l,r in zip(row+k, k+row)]
array[x+1] = row
return array
def transpose(array):
array = array[:] # make copy to avoid changing original
n = len(array)
for i, row in enumerate(array):
array[i] = row + [None for _ in range(n - len(row))]
array = zip(*array)
for i, row in enumerate(array):
array[i] = [elem for elem in row if elem is not None]
return array
array = pascal(8)
array = transpose(array)
pprint(array)
Output:
[[1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 3, 4, 5, 6, 7],
[1, 3, 6, 10, 15, 21],
[1, 4, 10, 20, 35],
[1, 5, 15, 35],
[1, 6, 21],
[1, 7],
[1]]