Sticky variables don't get correct values

I cannot wrap my head around why this code:

"""Provides a scripting component.
    Inputs:
        Run: Toggle component On/Off
        Label: Set Label of the component for easier identification
        Update: Manual update
        Pause: Toggle automatic update On/Off
        Low: The Lower value
        High: The Higher value
        Normalized: normalizing the "distance" between Low and High
    Output:
        out: supposed to be console output, but I don't know how to get it
        Value: The a output value
"""
from ghpythonlib.componentbase import executingcomponent as component
import GhPython
import Grasshopper as gh
import System
import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc
from System.Guid import NewGuid as guid
from Grasshopper.Kernel import GH_RuntimeMessageLevel as RML

__author__ = "zooid"
# Global variables, for some reason I need to set them up here
label_L=""
label_H=""
Low = 0.0
High = 0.0


class MyComponent(component):
    """
    Defining starting values not affected by the auto-update
    """
    def __init__(self):
        print("init")
        guidL = guid()
        guidH = guid()
        #print("guidL: "+str(guidL))
        #print("guidH: "+str(guidH))
        label_L = "Low-"+str(guidL)
        label_H = "High-"+str(guidH)
        #print("label_L: "+str(label_L))
        #print("label_H: "+str(label_H))
        sc.sticky[label_L] = Low
        sc.sticky[label_H] = High
        #print("sticky[label_L]: "+str(sc.sticky[label_L]))
        #print("sticky[label_H]: "+str(sc.sticky[label_H]))
    
    """ main loop """
    def RunScript(self, Run, Label, Update, Pause, Low, High, Normalized):
        """
        Manual update: it is intended to stop the main loop
        and assign the starting valuables.
        """
        if Update:
            self.__exit__()
            self.__init__()
        
        """Automatic update function"""
        def updateComponent():
            # Define callback action
            def callBack(e):
                ghenv.Component.ExpireSolution(False)
            
            # Get grasshopper document
            ghDoc = ghenv.Component.OnPingDocument()
            
            # Schedule this component to expire
            ghDoc.ScheduleSolution(100,gh.Kernel.GH_Document.GH_ScheduleDelegate(callBack))
        
        
        
        print("Low: "+str(Low))
        print("High: "+str(High))
        sc.sticky[label_L] = Low
        sc.sticky[label_H] = High
        print("sticky[label_L]: "+str(sc.sticky[label_L]))
        print("sticky[label_H]: "+str(sc.sticky[label_H]))
        low = sc.sticky[label_L]
        high = sc.sticky[label_H]
        print("low: "+str(low))
        print("high: "+str(high))
        
        """ Calculating output depending on the states (booleans)"""
        # Run State
        if not Run:
            Value = round(Low+(High-Low)*Normalized, 3)
            self.__exit__()
            msg = "Not Running"
        else:
            if not Pause:
                msg = "Running..."
                print "Running..."
                if low == None:
                    low = 0
                if high == None:
                    high = 1
                if low > high:
                    print("Error: Low > High")
                    Value = None
                if Normalized == 0:
                    Value = round(low,3)
                elif Normalized == 1:
                    Value = round(high,3)
                else:
                    Value = round(low+(high-low)*Normalized, 3)
                    self.__exit__()
                    
            if Pause:
                msg = "Paused"
                print "Paused"
            
            #auto-update invocation
            updateComponent()
        
    
        # Add component message from the Label
        ghenv.Component.Message = msg
        # return outputs if you have them; here I try it for you:
        return Value
        
    def __exit__(self):
        print "exit"

results in this:


Why the values of the two sticky variables are both 100?

Could anyone point out where my mistake is?

Thanks in advance.

tsk. no GH file.

From just reading the code posted:

  • don’t name arguments nor variables the same as globals
  • probably better to stick to convention where variables are lowercase.
  • move the globals into the class scope and reference them through self.
  • here something that seems to work: zooidscriptfixup.gh (13.4 KB)

Hi @jesterking,

Thanks for the reply.

Yes, that’s because the .gh contains just that script and the sliders and buttons on the screenshots. I’m sorry if I caused any inconvenience.

Duly noted. I’m not a full-time programmer so I usually name variables to be meaningful to me.

Now to the point.

Could you (or anyone) provide me some links with info about ghenv.DataAccessManager.SetData. I need to understand how it works.
How is it that I comment out every line which is assigning a value to my variable Value but still get correct output of the component.

The main reason for this script component and using sticky and making it self-updating is to avoid recursive errors. I’m going to use multiple instances of this component connected to each other. Currently that ability is gone with the code you provided.

With your original unadapted script I also get the recursion error. If you don’t you really should attach your GH file.

Yes, that’s true, I needed to figure out how to get proper values out of the stickies, first. You know how it is, first the calculation should be correct then you continue on with the gimmicks. Previously I managed to make such functionality using multiple components:

  • using data inputanddata output components change_slider_domain_v1.4.gh (7.0 KB). The problem I have here is that it appears to read/write with 1sec delay, and the value converges to the correct one too slow. Also, it requires additional temp_data files.

  • using sticky variables created in different components.
    For that to work properly I had to connect them with the timer component.change_slider_domain_v1.5.gh (16.1 KB). This one works very well, but I want to get rid of the Timer. and the fact that it’s multiple components and you have to be careful with the labels makes it prone to mistakes.

I assumed if I create one self-updating component and define the stickies within, it should work just as well as the aforementioned, alas, I couldn’t create the global variables at the correct place.

Update: here is the current (not working) version of the single component implementation. change_slider_domain_v1.6.gh (15.5 KB)