Tuple, Map and Lambda

We start with Command:EditPythonScript and later we will switch the environment to GhPython.

Tuple

Objects can be added and removed to/from a list type object.
If a small list which structure is thought to be fixed is used,
'Tuple' may be used instead of a list type object.
For example,

a=[1,2,3]
b=(1,2,2)
print str(a)+str(type(a))
print str(b)+str(type(b))

You may get
|[1, 2, 3]<type 'list'>
|(1, 2, 2)<type 'tuple'>
Congratulation:)
The biggest difference between list and tuple type objects is that the size of a list can be changed and that of a tuple is fixed.
Try append() for a tuple type object and get an error:)

Basically, a long list of the same object type objects should be managed by list type.
A small list of different object types which structure is thought to be fixed may be manged by tuple type.

For example,

import rhinoscriptsyntax as rs
pointList=[(1,1,0),(2,4,0),(3,9,0),(4,16,0)]
for el in pointList:
    rs.AddPoint(el)

19.png
import rhinoscriptsyntax as rs
circleList=[((0,0,0),2.0),((1,0,0),4.0),((2,0,0),1.0)]
for circle in circleList:
    rs.AddCircle(circle[0],circle[1])

20.png

Lambda functions

A lambda function is an anonymous function which is treated as an object.

func=lambda x:x**2
print(func(1))
print(func(2))
print(func(3))

You may get
|1
|4
|9
In Python, x**y returns x to the power of y. (Often it is expressed as x^y in other numerical environments)

A lambda function can also return a tuple.
Try

func=lambda x:(x,x**2,0)
print(func(1))
print(func(2))
print(func(3))

You may get
|(1, 1, 0)
|(2, 4, 0)
|(3, 9, 0)

map function

When y=f(x) is given, map([x1,x2,x3]) returns [f(x1),f(x2),f(x3)].

func=lambda x:x**2
x=range(1,5)
y=map(func,x)
print(y)

Again, you may get
|1
|4
|9
Congratulation:)

Again, you can apply tuples to lambda functions.

func=lambda x:(x,x**2,0)
x=range(1,5)
y=map(func,x)
print(y)

Again, you may get
|(1, 1, 0)
|(2, 4, 0)
|(3, 9, 0)

Combination of lambda, tuple and map

func=lambda x:(x,x**2,0)
x=range(1,5)
xyz=map(func,x)
print(xyz)

You may get
|[(1, 1, 0), (2, 4, 0), (3, 9, 0), (4, 16, 0)]
Therefore, you can draw a quadratic function by
func=lambda x:(x,x**2,0)
x=range(1,5)
xyz=map(func,x)
for point in xyz:
    rs.addPoint(point)

21.png

GhPython examples with lambda, tuple and map

Command: Grasshopper->place a GhPython component in the campus.

First GhPython program with lambda, tuple and map

'a' is the variable for output.

import rhinoscriptsyntax as rs
x=rs.frange(0.0,1.0,0.01)
function=lambda x: (x,x**2,0)
xyz=map(function,x)
a=list()
for point in xyz:
    a.append(rs.AddPoint(point))

07.png

Why lambda is so powerful?

Set up the GhPython as taking N as an input and let it as an integer parameter.
Connect a slider with N. Set up the slider as:

  • Type: Integer Numbers (N)
  • min: 1
  • max: 4
16.png
Then try:
import rhinoscriptsyntax as rs
import math
x=rs.frange(0,1.0,0.01)
funcList=list()
funcList.append(lambda x: (x-1,x**2,0))
funcList.append(lambda x: (x-1,math.cos(x*math.pi),0))
funcList.append(lambda x: (x-1,math.exp(-x)-1.0,0))
funcList.append(lambda x: (x-1,math.log(x+1),0))
xyz=map(funcList[N-1],x)
a=list()
for point in xyz:
    a.append(rs.AddPoint(point))

08.png
09.png
10.png
11.png

How to make it smooth?

Set up the GhPython component with 4 input paramters w1,w2,w3 and w4.
Specify every input as a float.
17.png
Write down

import rhinoscriptsyntax as rs
import math
x=rs.frange(0.0,1.0,0.1)
funcList=list()
funcList.append(lambda x: x**2)
funcList.append(lambda x: math.cos(x*math.pi))
funcList.append(lambda x: math.exp(-x)-1.0)
funcList.append(lambda x: math.log(x+1))
w=[w1,w2,w3,w4]
 
def Func(X):
    y=0
    for i in range(4):
        y+=w[i]*funcList[i](X)
    return y
 
y=map(Func,x)
 
a=list()
for (_x,_y) in zip(x,y):
    a.append(rs.AddPoint(_x,_y,0))

Then connect 4 sliders with 4 inputs each.
Set up the sliders as:
Type:Floating Point Numbers (R)
min:0
max:1
Now that you can remix the curves by moving the sliders.

Defining functions

lambda functions are anonymous (without identifiers) functions and should be used for only simple (can be expressed by one line) functions.
Of course, you can define functions with identifiers in Python environment.
If a function takes a function as its argument, either a lambda statement or an identifier of a function is accepted.

zip()

If you have two lists like
a=[a1,a2,a3,a4]
b=[b1,b2,b3,b4],
zip(a,b) yieldes
[(a1,b1),(a2,b2),(a3,b3),(a4,b4)]
Therefore if you write

for el in zip(a,b):
    do something to/with el

(ai,bi) is put into 'el'.
Of course a and b should have the same lengths.

Gaussian function

http://en.wikipedia.org/wiki/Gaussian_function

import rhinoscriptsyntax as rs
import math
A=1.0
B=1.0
C=1.0
x=rs.frange(-5.0,5.0,0.5)
func=lambda x:A*math.exp(-((x-B)**2)/(2*(C**2)))
y=map(func,x)
a=list()
for (_x,_y) in zip(x,y):
    a.append(rs.AddPoint(_x,_y,0))

12.png
Now, comment out A, B and C and take those values from input parameters.
Set up A, B and C as float number inputs.
22.png
import rhinoscriptsyntax as rs
import math
#A=1.0
#B=1.0
#C=1.0
func=lambda x:A*math.exp(-((x-B)**2)/(2*C**2))
x=rs.frange(-1.0,1.0,0.01)
y=map(func,x)
a=list()
for (_x,_y) in zip(x,y):
    a.append(rs.AddPoint(_x,_y,0))

Then, you can change the shape.
23.png