Need help with GHpython script! Input list and multiple counters

Hi everybody!

I am stuck and in need of some help with python.
The following script needs to be adjusted so it will work when using a list as input for x and output a list as result. For every index of the input x, the script needs to function the same way as this script.

The code:

"""Provides a scripting component.
Inputs:
    x: The x script variable
    y: The y script variable
    reset: Boolean input to reset the counter
    counter_start: Initial value of the counter
Output:
    a: The a output variable"""

__author__ = "fenno.walta"
__version__ = "2024.03.06"

import scriptcontext as sc

# Define a global variable to keep track of the counter
counter = sc.sticky.get("counter")
if counter is None:
    counter = counter_start if "counter_start" in locals() else 4000

# Get the input values from Grasshopper
input_value_x = x  # Assuming x is defined elsewhere
input_value_y = y  # Assuming y is defined elsewhere
reset_input = reset  # Assuming reset is defined elsewhere

# Check if the reset input is True
if reset_input:
    # Reset the counter
    counter = counter_start if "counter_start" in locals() else 4000

# Check conditions and update the counter accordingly
if input_value_x <= input_value_y - 100:
    # Increment the counter by 100
    counter += 100
elif input_value_x >= input_value_y + 100:
    # Decrease the counter by 100
    counter -= 100

# Output the current counter value
a = counter

# Store the updated counter value
sc.sticky["counter"] = counter

Thank you so much for your help!

Hi Fenno

The code can be made very clean, using GH Component SDK Mode, as the starting state and current state can just be stored on the component instance, meaning global variables, sc.sticky (assuming no other components are magically accessing it instead of using normal Grasshopper connections) and the locals() hack are all no longer required.

import Grasshopper

class MyComponent(Grasshopper.Kernel.GH_ScriptInstance):

    counter_start = 4000

    # Instance variable to keep track of the counter
    counter = counter_start

    def update_counter(self, x_i, y):
        
        # Check conditions and update the counter accordingly
        if x_i <= y - 100:
            # Increment the counter by 100
            self.counter += 100
        elif x_i >= y + 100:
            # Decrease the counter by 100
            self.counter -= 100

    def RunScript(self, x, y, reset):
        __author__ = "fenno.walta"
        __version__ = "2024.03.06"
        
        # If the GH input is unconnected, x is None
        x = x or []
        
        for i, x_i in enumerate(x):
            # i is the index if needed.
            self.update_counter(x_i, y)
        
        # Check if the reset input is True
        if reset:
            # Reset the counter
            self.counter = self.counter_start
        
        # Output the current counter value
        return self.counter


Fennos_counter.gh (12.0 KB)

Hey James! Thanks for your response and great support!

That’s a really nice and clean solution indeed.
I hadn’t thought about it this way yet.

Unfortunately I cannot rely on any custom components for this project I am working on.
Is there any way I could make this work in the GHpython component?

Those are all native components. A GhPython component’s mode can be changed using its “Grasshopper” fly down menu (top left of the component editor window in Rhino 8).

But the basic principle of a for loop and a function will work in a GhPython component in script mode (and almost any programming language).

Thanks James! Sorry for my late response, things got in the way.

1 Like