My first "own" python code! (Tips on progression appreciated)

I don’t know if anyone cares but I felt like sharing my first working python script :smiley:

I’m an architecture student who was introduced to Grasshopper last semester (with Gramazio-Kohler Research at ETH Zurich) and loved it, so I want to specialize in parametric design/scripting and therefore have started to learn to code in python. I’ve done some tutorials and basic codes, but this is my first one as a part of something useful!

So the basic setup is a bunch of points, the surrounding points are on the global xy plane and the central points on a higher xy plane. At first I projected them down to global xy plane, created a delaunay network and isolated the triangles. Now to the python code:

“PtA” is a list with the eight original points

“PtB” is a list with the eight projected points

“pts” is a tree with all the points, the 22 main branches referencing the triangles and the 3 sub-branches their respective controlpoints.
Now with the python code, the goal is to take the projected central points and replace them with the original referenced points.

At first (the inactive part of the code), I took the projected points (PtB) and for each one I looked for duplicates in the “pts” tree and when one was found, added it to the path of the grafted projected points (PtB) list (so all the paths of matching points in “pts” for point 0 of “PtB” were on the path {0})

Afterwords, I realised that the more efficient way was to just swap the point directly.

Sorry if I wasted anyones time with this, I’m just really excited to have my first functioning script. And if anyone has any feedback, tips on where I can best learn how to use python in Grasshopper or has any tutorial/ course recommondations that would be very much appreciated!

P.S. I didn’t write this code all by myself, I tried to work with ChatGPT but it never seemed to work, but I took the parts I understood and combined with the Rhino.Python Guide from McNeel was able to get it to work

Net experiments.3dm (49.4 KB)
Net experiments.gh (22.9 KB)

2 Likes

Looks very nice. I only have a few comments on code styling. No changes to logic.

Thank you so much!
I’ll look into your suggestions and make sure to pay closer attention to my code styling in the future.
Why is it good to avoid import? I did it because I received an error saying “No module named Grasshopper”, but it worked with this syntax.

Example below is the kind of import that is considered not very good. Lets assume you want to access Point3d

from Rhino import *

p = Point3d(1, 2, 3)

This is not good because the local scope in your script now includes EVERYTHING under the Rhino. namespace. It is also less readable as other developers might not know where Point3d is coming from.

The better approach is to be specific:

from Rhino import Point3d

p = Point3d(1, 2, 3)

This is how your script is written so GREAT JOB :smiley:

Also to have a little fun, open a new script and type import this and read what is printed in the terminal :smiley:

1 Like

I see, thank you!
Will do :smiley: Have a great day!

1 Like

for bonus points type

import inspect, this
print(inspect.getsource(this))

and try to count the ways in which the source code contradicts the advice from the module

2 Likes

Well done Joel.
Python in Grasshopper, taught me about deployment, and the importance the environment code runs in. I recommend learning CPython and its venv — Creation of virtual environments — Python 3.12.3 documentation, and even if you’ve not considered packaging your code yet, this overview of the different options is helpful and informative. Overview of Python Packaging - Python Packaging User Guide

I’d advice against having functions/classes operate directly on Grasshopper DataTrees, but instead cast to native Python lists on input (and back to DataTrees on output) within the global of the script (e.g. using ghpythonlib.treehelpers). Separation of Grasshopper (i.e. Dataflow programming) and Python (i.e. imperative programming) logic/paradigms is generally advisable to keep things clean and simple. You might find these slideshows and example files useful in your learning journey:

Other than that, looking good :snake:

1 Like

Took me a while for this simple thing but that is really cool!
A nice little “poem” with tips :smiley:
Thanks!

I have to say I’m quite confused by this - what is it trying to do here? It looks like it is scrambling the “import this” terminal.

Alright, I might have a question there but I’ll work through that amazing slideshow and all the resources first, it looks like that will help me a lot and answer a lot of questions.
And I can’t really find a way to express how amazing this link is and how happy this makes me. THANK YOU so so much!! It’s actually everything I’ve been looking for, an in-depth collection of resources for me to dive into and learn all about this! Thank you so much!!
If we ever cross paths in real life, I’ll bake you a cake :smiley:

2 Likes

Thank you!
Going through this I feel like I get the general idea but am still quite overwhelmed with the collection of things I don’t understand about this. I’ll dive into the resources Anders gave me to get a better understanding of python coding and then come back to this. Seems like the more I know of whats going on in the background the better I will get a writing scripts.
Very much appreciated! I’ll get back to it as soon as I have the basics, whatever that means exactly, solidified a little better :smiley:

1 Like

Yes the poem is stored as a string in ROT13 (Caesar cypher) encoding. It is iterating over the string and printing the deciphered letters. :smiley:
It arguable breaks at least the first 9 zen recommendations

2 Likes