First Python Script - Some Advice Please

Hi all,

I am trying my hand with my first Python Script and wanted some help with making it work more cleanly.

It’s to create blended setback curves at adjacent edges on a surface, which I then use as rails in future. It’s really just a plaything for me to try and test what I’ve learnt so far, because I can kind of see the steps.

My first version worked perfectly fine on untrimmed surfaces. v1.01 I was trying to make work on trimmed surfaces, where adjacent edges aren’t necessarily following the clockwise rule when I’ve created the edge curves.

I think I just need my if statement to work properly. It’s in a bit of a loop where I keep overwriting the curve directions with the else from before. So it’s a logic issue that I can see but not code. There may be a lot of redundant steps covered in one command too if anybody knows of any. (4.7 KB)

Hello Jonathan,

Well done - that’s a great start with some nice commenting, clear variable names and print statements to help you work out where it is going.

I can immediately see two features of python which could help you to reduce repetition and clean up the code: loops and functions.

You can use a for loop to repeat the same actions over a list of objects. You can use a while loop to keep repeating an action until a condition is false, e.g.:

while start1 == start2:
    # flip the curves

You can write your own functions to organise simple bits of code which you want to reuse.

Finally, I have found rs.DuplicateSurfaceBorder(my_surface, type = 1) to be useful for retrieving a python list of all of the edge curves of a surface in order.

Happy pythoning


Thanks graham. I really appreciate that. For a long time I’ve looked on the forums just thinking what on earth. But I guess this confirms what is aid about Python, and it being okay for beginners…

Here’s a simple one that I just know the rule about yet. How can I print something like:

radius = rs.CurveRadius(pulled, midpoint)*

print "Actual radius is"
print radius

On the same line in Rhino command line? A bit silly I know, but at the moment I can only figure how to do it on a separate line! So printing one variable and one string.

Given the radius of the blend at the midpoint is basically fake, the next step I think is to take the radius value input, and then compute some best fitting values above and below to get a lower deviation. I have no idea how to do that yet.

You can use the “format” statement…

print "Actual radius is {}".format(radius)

Or just concatenate the string-ified radius

print "Actual radius is " + str(radius)

The concatenation did it. Thanks! Can you explain the first way you’ve mentioned? (3.7 KB)

I think I fixed my logic between lines 29-62. Also not mastered pasting the code onto the forum in the clean way others do…

three “backticks” and python
paste the code in
three backticks

like this:

``` python
<paste your entire code here>

The format statement in python is something I really like to use when working with strings. It’s basically a substitution where you insert curly brackets in the string where you want your inserted text to appear, then inside the parentheses after the .format, you put the variables in order that they appear in the string.


"I like {} {} and {}".format("green","eggs","spam")
>>> "I like green eggs and spam"

What’s cool about format statements is that it takes care of the… formatting. So you do not have to specifically convert numbers or guids into strings, if you throw in a 3Dpoint object, it inserts the X,Y,Z coordinates as a properly formatted string etc. You can even do conditionals:

print "{} object{} selected".format(len(objs), "" if len(objs) == 1 else "s")


Right, got it. So you’re conditioning whether to pluralise or not.

This is my next problem: if the result of the pull back onto the surface is two curves. (resulting from set back of 2mm)

problem-corner.3dm (56.5 KB)

My guess is that this is because midpoint is being given two values to evaluate. Guess I have to just determine which is the longest if that happens then delete it. Or better still, join them.

if len(pulled) >1:

Do I need to ‘return’ after that?

Also I need all the stuff about protecting from None values… I know Tibbitts wrote about this at length in the 101.

I think for now, I’ll leave it here. (3.8 KB)

1 Like

How can I end the scrpt part way through? I’ve been able to determine whether or not picked curves are adjacent/have shared start/ends, so if this is not the case I’d want to end the script.

If you want to end a script “gracefully” (without an ugly error message popping up) or you want to be able to abort mid-stream for some reason, you should encapsulate the entire script in a definition.

So, for example, if you ask the user to pick some objects and the objects don’t correspond to certain criteria or if the user decides to abort, you can exit cleanly.

So instead of this:

import rhinoscriptsyntax as rs
crvs=rs.GetObjects("Select some curves",4)
  • which will error out if the user doesn’t pick any curves or the curves can’t make a planar surface, you can do this:
import rhinoscriptsyntax as rs

def MakePlanarSrfFromCrvs():
    crvs=rs.GetObjects("Select some curves",4)
    if not crvs: return
    if srf:
  • which will simply exit quietly if the user doesn’t pick any curves or the surface is not made.

So it’s the

if not crvs: return

part which is the quiet exit, right?


It is telling the function to return nothing : to go quit the function, sending a value None back to the script

This none value is then silently dropped

Good that you startet scripting. Coding within Rhino is a great and fun way to learn coding. However I would advice to follow tutorials about basic Python at first. I mean its not wrong to stick to Rhino, but it really helps to understand basic concepts of the language. A lot of these questions can be solved by yourself if you know them. The bad thing, you really need to learn Python 2 Syntax which differs occasionally from modern Python 3.

1 Like

I used the free python 2 course from Codecademy and the Rhino Python 101 for this. A great combination in my view

Yeah I’ve already looked into basic Python learning where I can, but only in relation to Rhino. I’ve read RhinoScript 101 cover to cover twice and also Jose Sanchez’s Plethora Project videos multiple times on YouTube as recommended by David Leon at McNeel (which are great). This has given me a basic understanding just through repetition.

A lot of these questions don’t crop up in a linear fashion, and indeed aren’t necessarily explicit chapter titles and so on. And so I’ve asked here for very specific answers for single things (which I am really grateful for - and as such I do try and offer input elsewhere in the forum where I can to push other discourse areas forward).

I’ve used exactly the same plan of attack! Although I only realised yesterday that the CodeAcademy lessons themselves are free! For the time being though, I am just cementing existing knowledge picked up from the other references I’ve referred to. It’s nice to pick little tricks like multiline string and %s etc.

I’m doing Long Nguyen’s Python course next February in the UK. Maybe I will have to discuss this point, as to the longevity of certain aspects of learning and specifically the topic/debate within Rhino. I did read some of this topic, for example:

1 Like

This one is actually a quite well explained tutorial:


Thanks my friend!

+1 for the community.

On a side note… at last, I have found a use for ‘WebBrowser’ command and panel is useful in Rhino, ha! So that’s how you can keep the API commands up and see your script simultaneously.

Have you tried import antigravity ?

I got a link to this… is that right? :smile: