I am doing something wrong. I am trying to transport a class to another component (which worked when working with simple lists but now it is a tree within a class).
Do you might know how to solve this puzzle?
Thank you for your response
I am doing something wrong. I am trying to transport a class to another component (which worked when working with simple lists but now it is a tree within a class).
Do you might know how to solve this puzzle?
Thank you for your response
Hi F,
Classes are a major part of object-oriented programming, meaning that first you need to make an instance/object, before you can use it. The class itself is only part of the script, nothing more!
1st component:
class Dataset:
def __init__(self, npnts):
self.npnts = th.three_to_list(npnts)
# Output
dataset = Dataset(npnts)
print dataset
2nd component:
print dataset.npnts
Just like functions, classes donāt do anything unless you instantiate/call them first.
Thank you.
What I want to do is this.
Having multiple data input to a class migrated through one connection to another component.
I am able to manage it with lists but not with trees.
problem send class 02.gh (41.6 KB)
Yes, I get that! There are numerous ways to accomplish this, but what - in my opinion - isnāt possible, is to pass code from one component to another. This seems to be, what you are currently trying to do, but you need to pass data instead!
Code can also be passed through the optional code input of the GHPython component, however that would have to be in form of a string (i.e. external .py file), which isnāt practical or necessary for this application.
I guess you need to understand a little more what classes are, given that itās a complex topic!
Just imagine your class as being the blueprint to a factory. You can build as many factories (i.e. objects, class instances) as you want with this blueprint (code), but letās say that beyond that, it doesnāt do much.
Each factory gets build/instantiated with some inherent functionality. def init(ā¦)
defines what is done/setup on instantiation of your class, analog to the day the factory opens, or rather the construction time.
However, as your factories grow economically, you might have to add machines to increase productivity, and thus update your blueprint. In Python, you can extend your class with methods/functions that help you manage class functionality and data.
Thereās much more to classes, but itās important to get the basics first!
problem send class 03.gh (38.9 KB)
Furthermore, if you donāt add more functionality to classes, than just saving data inside variables, it is much more efficient to use dictionaries, instead of class objects. You can also use dictionaries inside classes.
For example, this ā¦:
class Node:
def __init__():
self.pos = None
self.vel = None
self.acc = None
nd = Node()
print nd.pos
ā¦ and this ā¦:
node = dict()
node["pos"] = None
node["vel"] = None
node["acc"] = None
print node["pos"]
ā¦ does practically the same, in terms of data storage, but the dictionary handles for instance being searched much more efficiently.
Hereās a more extended example of the above code using a single dictionary inside the class to handle your points lists:
problem send class 04.gh (38.8 KB)
Good news: see attached.
Bad news: you date the wrong girl ā¦ meaning: you must do the C# > P thingy.
CastClass_EntryLevel_V1.gh (11.8 KB)
best
Another option for quickly creating immutable class objects would be:
from collections import namedtuple
Node = namedtuple('Node','pos vel acc')
n = Node(1,2,3)
print n
print n.pos
n.pos = 2
Traceback (most recent call last):
File "<string>", line 1, in <module>
AttributeError: can't set attribute
When using the component data output and data input in another file the class does not go there.
Do you know why?
I have three trees. For C#, do you know a mighty manual of C#?
I am trying to make a class and with the components data output and date input to another file to transport the data.
Do you know if it is possible to transport classes to other files with the components data ouput and data input?
Reading your other questions, do you mean, instead of passing the instantiated class objects from your first component to the second, you want to pass it to another Grasshopper file?
Hm, for that you can use the sticky dictionary to transport all kinds of data.
Example GH File 1:
from scriptcontext import sticky
import Rhino.Geometry as rg
# Put your data into the sticky dictionary
sticky["test"] = rg.Point3d(3, 2, 1)
Example GH File 2:
from scriptcontext import sticky
# Fetch your data from the sticky dictionary and output it
a = sticky["test"]
I guess for this to work, both GH files need to be open! Instead of the point, you can also save class instances, as well as all kinds of other data types.
Another possibility would be to export structured data to a file (i.e. text file, JSON, etc.) on your hard-drive, which would be loaded into your second GH file, but thatās more complicated!
I am going to use several datasets. Naming something sticky[āAā], sticky[āBā] will make it a little bit difficult.
Like with that one python component and input of three trees, I have several python components of those.
Do you might know a way to make it possible to use the components output and input in order to transfer classes to other files?
Or do people in general do that in a smarter way than I can came up with?
@PeterFotiadis @Dancergraham I am going to have several files with some repetition.
I now use the components output and input to let GH files communicate with each other and to transport data.
Making a class and transporting it through such portals as the components output and input works very handy for me.
I donāt know much about GH.
Have you tried defining your class in one python file, eg node.py
then using eg from node import Node
at the top of each of your python components ?
Is the thing to do (see attached as well: with regard entry level query matters). Provide a full case of yours: data, what exactly you want to do, why, queries, more queries, clustering goals etc etc.
CastClass_EntryLevel_V1A.gh (15.2 KB)
Other than that Reset Now For Ever:
C# in Depth (Jon Skeet) - the Bible.
Effective, More Effective C# (Bill Wagner)
Concurrency in C# Cookbook (Stephen Cleary)
C# 6 for Programmers (Paul/Harvey Dietel)
Itās quite hard to tell what exactly it is youāre aiming for, but it definitely feels like you might be overcomplicating things. Implementing both classes, datatrees, and sticky for structuring/piping around data seems like a lot complexity (generally speaking, you can pass around whatever you like between GHPython components without much fuss). Perhaps you can provide us with a more explicit description of the pipeline you are imaging?
GH_file_00 | Class_A, Class_B, Class_C > component output
GH_file_01 | component input > Class_A, Class_B, Class_C
The class contains several types of data such as numbers, points, curves, breps, meshes.
All classes are build the same because they receive the same kind of data; like for example a ring, it has a size, amount of diamonds, and informing curves and points all āzippedā to a class in order to unzip it in other files.
I have three rings therefor I made three classes.
During the process of different files I cut the ring, curves, points, etc. to get to a smaller scale; and I intend not to call the new datasets āsmallpnts, smallerpnts, smallersmallerpntsā in the naming.
I just want to say Class_A through several files just recognizing the data by the input component like GH_file_04 for example.
As you can read out of this, I am trying to find a workflow without having the output component containing many names (27 names).
Because I am aware of the possibility to make classes I am trying to make it classes to just work with (3 names) for the output component.
Do you have a better idea?
EDIT: please wait a second
@diff-arch
@PeterFotiadis
@Dancergraham
@AndersDeleuran
Please safe the output file again.
I am looking to this basic workflow. Within this workflow I can theoretically add as many data to a class as possible.
I tried C# but could not figure it completely out right.
And imagine this added many more data to the classes which I can input to other python and C# files in other GH_files as well.
What I win with doing it like this is winning time because I do not have to name all the stuff to the output component anymore because it is made a dataset.
@Dancergraham I could not figure out the Node thing yet.
Or is there a better workflow for transporting classes or data without naming everything over and over again you know about?
GH_file_01.gh (16.3 KB) GH_file_00.gh (98.8 KB)Well ā¦ if I got it correctly (?):
Clustering in plain English (Flat, HAC, whatever) or some sort of Data mining.
If this schema is correct ā¦ then the only way to cut the mustard is by doing LINQ stuff - like the primitive stuff in V1A above - in a List of a properly written custom class that contains all (or some) of the properties required.
For instance imagine going after 3d object equality (a chimera ā¦ but anyway): thereās a lot of things to compare while if one comparison fails thereās no need to proceed to the next.
So : are the above generally describe your goal(s)?
Hello,
So if you want to put your data into and out of files you can use pickle and/or shelve. Shelve basically acts like a dictionary - you can put any pickleable object in it.
Warning
The pickle module is not secure against erroneous or maliciously constructed data. Never unpickle data received from an untrusted or unauthenticated source.
@ForestOwl, I feel like you already have all the information to get to your goal. Remember the class is the blueprint, the instantiated object of it your collection of information.
So, this should read āGH_file_00 | Object_A, Object_B, Object_C > component outputā, and āGH_file_01 | component_input > Object_A, Object_B, Object_Cā.
No worries here, classes can swallow all kinds of data. Thereās no type declaration in Python, meaning your variables can hold pretty much everything!
I donāt get what the problem is. Hereās another example:
In this file, you create your blueprint class, initialise as many class objects as you need, and store them in the sticky dictionary!
The information that you want to provide from the outside to the class on initialisation, is passed as arguments/attributes to the initialisation method (e.g. def__init__(self, base_curve)
), and stored into class variables (i.e. self.base_curve=base_curve) inside this method.
Other information also gets initialised inside def__init__(self)
, but doesnāt have to be provided on initialisation (i.e. div_points=None), but the empty variable needs to be initialised (to be available later).
import Rhino.Geometry as rg
import scriptcontext as sc
import random
class Ring:
"""A ring.
Attributes:
base_curve (Rhino.Geometry.Curve): A ring base curve.
size (float): A ring radius.
num_diamonds (int): A number of diamonds.
"""
def __init__(self, base_curve, size, num_diamonds):
"""Inits a ring."""
self.base_curve = base_curve
self.size = size
self.num_diamonds = num_diamonds
self.div_points = None # Get done when needed!
def divide(self):
"""Equally divides the ring base curve."""
# Save division points in self.div_points, previously initialised as empty variable
self.div_points = self.base_curve.DivideByCount(self.num_diamonds, True)
# And return the new division points, or don't! This is optional.
return self.div_points
sc.sticky["my_rings"] = [] # stores your ring objects (not the class, but the class objects)
# base_curves provided through input
for i in xrange(len(base_curves)):
curve = base_curves[i]
size = random.uniform(1.7, 2.5)
num_diamonds = random.randint(1, 12)
# Instantiate a new ring
ri = Ring(curve, size, num_diamonds)
# Store your ring inside a list in sticky under "my rings"
sc.sticky["my_rings"].append(ri)
Note how all the rings are saved under a single key āmy_ringsā, which can be used as such in each and every GH file that you want to fetch the information in.
In the other files, you simply fetch the information from the sticky dictionary.
Note how we use the class method Ring.divide() here, to perform something after the rings have been initialised. Cool right!
import Rhino.Geometry as rg
import scriptcontext as sc
if "my_rings" in sc.sticky.keys():
# Get the rings from sticky
rings = sc.sticky["my_rings"]
# Divide the rings
for ri in rings:
print "Diamonds: {}".format(ri.num_diamonds)
print ri.div_points
ri.divide()
print ri.div_points
No, problem doing this with this method! Forget about C#, this doesnāt need its performance benefits and is easily achievable with Python.
You donāt have to name everything over and over again!