How to write this code block more elegant and shorter

Hi,

I am sure there is a clever way to shorten repeating lines of code and operator lists, however I did not find solution for this particular situation. I am building an eloaborate messaging system that needs to trigger multiple components individually, hence long lists of these operators. Perhaps there is a way to collapse them into a list?

Thank you so much!

hi,

first of all, the “else” statement should be the last one, after all cases are evaluated as false, like the default option. Un your case the “else” section is evaluated everytime val is not 0.

Also you should use “else if” for every other values. In python you can use the keyword “elif”. Otherwise every other case is being evaluated.

Example :

if val = 0:
  //action 0
elif val = 1:
  //action 1
elif val = 2:
  //action 2
else :
  //default action

Now for long options list like this, you can also use the “match” option like :

match val:
  case 0:
    //action 0
  case 1:
    //action 1
  case 2:
    //action 2
  case _:
    //default action
1 Like

Hi Gallo,

Thank you for quick response! And I apologise if my code language sounds a bit awry.
I wonder if your solution is still valid in my case. Which is

  • There is a random val number generator [0-8], which works as a main trigger for 9 light pots.
  • If the val = 0, then turn on Light1, otherwise turn it off.
  • Then I am going through all list of 8 values to trigger each light or keep it off.
    Does this explanation make sense?
    Therefore, I wonder what is the benefit for using elif val = 1,2,3,etc and ending up witgh else:
    The code (eventhough not properly written) worked smoothly turning lights one and off. Also, the light needs to turn off beofre the next one lights up, so it did look proper in the space.

The second suggestion using cases, I do not fully understand how that can be implemented.
Do you mean like so:

  • make 9 cases for each light (add all operators how they need to behave)
  • implement “case 0” in if statement code above to make it shorter?

Thank you! I appreciate your input <3

Thing is the else section will always be triggered unless val = 0.
For example if val = 1 then it is not 0, so the else section will be executed, and then the if val = 1 section will be executed as well.
If this is the way you intend it to work so this is ok.

Depends on what you are trying to achieve.
The difference is when using “if”, every statement will be evaluated. For example, if you receive a value of 0, you will execute the val = 0 section. Then it will test if val = 1, then val = 2…
When using “elif”, if value is equal to 0, it will execute the val = 0 section and then exit the loop and bypass all other options as the value was already evaluated a 0 and can’t be another value. Basically it will only continue to test values until there is a successful attempt.

This is another way to organize the code. simply the same as if, elif, else…

match val: // test the val value
  case 0: // if val = 0
    //action 0
  case 1: // if val = 1
    //action 1
  case 2: // if val = 2
    //action 2
  case _: // in any other case not mentioned above
    //default action
1 Like

Without knowing too much about your project, it seems like you are applying the same value to multiple parameters as a matter of course. This usually means that you’d be better off consolidating the other side of your data hierarchy to just reference a single value. A crafty way of doing this in TouchDesigner that doesn’t really require any code is to use Custom Parameters. Wrapping your OPs here in a parent COMP and creating Custom OPs would be a good way to reduce the number of pars that need to be operated on. Then you can simply refer to the value of the Custom Pars within your network.

If you want to consolidate the number of duplicate calls in your python code, a fairly straightforward and pythonic approach would be to create additional functions that handle distributing the identical value to multiple params for you and calling them like so:

# instead of doing this

def onValuechange(channel, sampleIndex, val, prev):
  if val == 0:
    op('level25').par.opacity = 1
    op('Fresnels').par.const0value = .05
    op('Fresnels').par.const1value = 1
    op('Fresnels').par.const2value = 1
    op('Fresnels').par.const3value = 1
    op('Fresnels').par.const4value = 1
    op('Fresnels').par.const5value = 1
    op('Fresnels').par.const6value = 1
    op('level52').par.opacity = 1
    op('level67').par.opacity = 1
    op('level42').par.opacity = 1
    op('level45').par.opacity = 1
  else:
    op('level25').par.opacity = 0
    op('Fresnels').par.const0value = 0
    op('Fresnels').par.const1value = 0
    op('Fresnels').par.const2value = 0
    op('Fresnels').par.const3value = 0
    op('Fresnels').par.const4value = 0
    op('Fresnels').par.const5value = 0
    op('Fresnels').par.const6value = 0
    op('level52').par.opacity = 0
    op('level67').par.opacity = 0
    op('level42').par.opacity = 0
    op('leve145').par.opacity = 0

# do something like this:

def setAggregatedVals(inputVal: float):
  op('level25').par.opacity = inputVal
  # skip unique valued par
  op('Fresnels').par.const1value = inputVal
  op('Fresnels').par.const2value = inputVal
  op('Fresnels').par.const3value = inputVal
  op('Fresnels').par.const4value = inputVal
  op('Fresnels').par.const5value = inputVal
  op('Fresnels').par.const6value = inputVal
  op('level52').par.opacity = inputVal
  op('level67').par.opacity = inputVal
  op('level42').par.opacity = inputVal
  op('level45').par.opacity = inputVal
  return

def onValuechange(channel, sampleIndex, val, prev):
  if val == 0:
    op('Fresnels').par.const0value = .05 # handle the unique value here
    setAggregatedVals(1)
  else:
    op('Fresnels').par.const0value = 0 # handle the unique value here
    setAggregatedVals(0)
1 Like

On a most simplistic level, I’d add an extra function that sets the parameter values:

def setlight(vals):
  op('level25').par.opacity = vals[0]
  op('Fresnels').par.const0value = vals[1]
... and so on. ..

And then in the onValueChange() function, call setlights():

if val == 0:
  setlights([1, .05, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
else:
  setlights([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

This at least makes certain that every parameter gets touched each time (note that after your if val == 1 you’re referencing op level26 which you don’t do above, that means level26 gets set but never unset.

However, IMO the approach could be improved upon by using a pair of DAT tables, one that is a list of all lights and if they’re on or off, and the second table that is a list of opnames, parnames, offvalue and onvalues. Then your code would iterate through the two tables and for each light, see if it’s 0 or 1, and then iterate through each line of the second DAT and set the op/par/value based on the ‘on’ or ‘off’ column.

The advantage of the DAT table approach is you can see all your numbers changing dynamically all in one place. You might even want more than one light on at a given time, or ramp lights up or down. The result could be a third DAT table that is the full set of parameters and values.

1 Like

Hey Antoine,
Thank you for your solution and idea to create DAT tables, that will also help to keep the states more organised and visible before implementation. I appreciate your elegant input, thank you!

Kavi

Hi Florian,

Thank you so much for sharing your thoughts and solution. I will try to implement this and see how this goes. I appreciate your time and expertise.

Kavi