HyperSizer Support Forum

Software Use => Scripting => Topic started by: Ruben on April 29, 2016, 07:58:06 AM

Title: Setting Component Variables from Python
Post by: Ruben on April 29, 2016, 07:58:06 AM
Hello,

I am trying to write a Python script to set the required stiffness for each component, however I am struggling to set the values.
I have the component that I want to set: objComponent and the property that I want to set is cp (cp=35 pcpDesignA11), with a value of vA11.
objComponent.PanelProperty(cp) only returns the current value and there does not seem to be a way to set it from Python?

Regards,
Ruben
Title: Re: Setting Component Variables from Python
Post by: Ryan on April 29, 2016, 11:58:04 AM
Hi Ruben,

Component.PanelProperty is a 'property' with arguments (as opposed to a method). Most languages do not support this. For Python add 'Set' to the property name to set the value of the property.

component.SetPanelProperty(cp, A11).

http://hypersizer.com/help_7.2/#COM/Object/Component-PanelProperty.php

-Ryan
Title: Re: Setting Component Variables from Python
Post by: Ruben on May 03, 2016, 03:11:10 AM
Thanks Ryan, I was browsing the Hypersizer Object Library in VBA and SetPanelProperty is not there for components, which is why I missed it. I guess not all the methods appear in the Object browser?

Regards,
Ruben
Title: Re: Setting Component Variables from Python
Post by: Ryan on May 03, 2016, 07:54:03 AM
Basically it's a special case. Here's the long-winded explanation.

The API defines Component.PanelProperty as a property. Properties are public data. The data can be read-only (getter only) or mutable (getters and setters).

In Python, properties are implemented using the @property and @foo.setter attributes. For example below is a 2-D Point class where X and Y coordinates are properties.


class Point:

   def __init__(self, x, y):
      self._x = x
      self._y = y
      
   @property
   def X(self):
      return self._x
      
   @X.setter
   def X(self, value):
      self._x = value
      
   @property
   def Y(self):
      return self._y
      
   @Y.setter
   def Y(self, value):
      self._y = value

def main():

   pt = Point(1.0, 2.0)
   
   # Call getters to print to the screen
   # Note the lack of parentheses in pt.X and py.Y.
   print ("(x, y) = {0}, {1}".format(pt.X, pt.Y))
   
   # Call 'setters'
   pt.X = 3.0
   pt.Y = 4.0
   
   print ("(x, y) = {0}, {1}".format(pt.X, pt.Y))


if __name__ == '__main__':

   main()


In all languages except VB6 (and perhaps VB.NET) properties do not have arguments - you just get and set the data directly with a single value (as illustrated in the Python code).

In our API, which is built using VB6, we have some properties with arguments. Because Python does not support this, Python uses a workaround. The getter is treated as a method foo = component.PanelProperty(cp). The setter is also treated as a method. The setter method name has "Set" prepended and the incoming value is passed explicitly as method argument. This magic is not visible in the Object Browser because it is specific to Python (more specifically the pywin32 library).

component.PanelProperty(cp) = foo   # NOPE
component.SetPanelProperty(cp, foo) # YES


In MATLAB there is a similar issue. In MATLAB, the workaround is to use the generic get() and set() methods.
get(component, 'PanelProperty', cp)
set(component, 'PanelProperty', cp, foo)


In our API, we no longer expose new properties like this, but there are key portions of the API that have remained unchanged for compatibility reasons.

Ryan