# How do I reverse every other row of a table?

Hi,

I have a top converting to a chop converting into a dat.

I want to reverse every other row at some point in this chain, I can do this in python but I’ve noticed it is quite a bit slower doing all that row by row modification to a table so I was hoping there was a more elegant solution that uses nodes / expressions?

Any thoughts?
Thanks!

A slight revision to my question, I actually need to reverse every 3 rows:

row1 - regular
row2 - regular
row3 - regluar
row4 - reversed
row5 - reversed
row6 - reversed
row7 - regular
row8 - regular
row9 - regular

is there even a way to do this with expressions?

You can use a evaluate DAT and this expression:

``[me.inputCell.val,me.inputCell.val[::-1]][(me.inputCell.row//3)%2]``

cheers
Markus

Wow that’s impressive! Thank you.

I get all but then last line, could you explain what it means?

Basically you are looking at a python list evaluation:

the list entries are:

``````#the current evaluated cells value
me.inputCell.val``````

and

``````#the current evaluated cells value in reverse
me.inputCell.val[::-1]``````

The syntax for the second entry is called “Extended Slice” where [begin:end:step]. By only specifying step as -1 you are stepping backwards through the string.

The second part of your expression now is a lookup into the list. By floor dividing the current row number by 3, this will always return integers and now by applying a modulo of 2 it will either return 0 or 1 for every 3 rows. This 0 and 1 is your lookup into the list…

``````#this will divide the current Cells row number by 3 as an integer,
#the modulo over 2 will return either 0 or 1 which is used
#as the lookup into the first list
(me.inputCell.row//3)%2``````

Does that make sense?
Simplified you could write:

``````#this will return 'abc'
['abc','cba'][0]

#this will return 'cba'
['abc','cba'][1]``````

cheers
Markus

much better explanation Elburz - and it’s gone again - oh no… It really was much better to understand…

I liked yours better since I guess it’s not actually a bool, but a list lookup., but I’ll repost it : ) :

It acts like an if statement but wrapped in brackets instead of writing out if and else.

A simple way to think of it is like this:
[‘false’,‘true’][0]

would return ‘false’, while:
[‘false’,‘true’][1]

would return ‘true’. The 0 and 1 from above is the bool and the first section is what passes depending on the bool.

In Markus’ expression, if you start from the bool section ( [(me.inputCell.row//3)%2] ), you’re dividing by 3 ( using // floors the result so you always have an int) and then performing modulus 2, which divides by 2 and returns any remainder. Then depending on the value returned, it chooses between the 2 different options in the first half ( [me.inputCell.val,me.inputCell.val[::-1]] ). If it returns 0, it chooses me.inputCell.val, which basically just passes the cells value straight through. If it returns 1, it would perform me.inputCell.val[::-1], which would reverse the contents.

[me.inputCell.val,me.inputCell.val[::-1]][(me.inputCell.row//3)%2]

Also remember that you wrote row1-9, but row index starts at 0.

Wow, thanks for the break down guys, I am no where near where I want to be with expressions, they are dead useful!

Any recommendations on general resources for learning or thinking in terms of these kinds of expressions? Or is all this pretty much a touch designer way of thought mostly?

You may want to try a simpler approach and put the above expression piece in a Script DAT:

`````` def cook(scriptOP):
scriptOP.clear()

a = scriptOP.inputs[0]
for r in a.rows():
rownum = r[0].row   #any cell in list will return the same row
if ((rownum//3)%2):
r.reverse()
scriptOP.appendRow(r)
return
``````

Usually I look for solutions to python problems by just searching for it online and the recipes mostly come from the website stackoverflow.
My search for your problem was reverse a string in python and the one line list solution I found when encountering a problem where I needed to do something similar in a parameter where you only have 1 line to do it all.
I found it by searching for 1 line if statement python

An approach that worked for me when it comes to expressions is that if I can see a pattern in what I need the data to be, then usually there is a simple solution to it out there So the first task might be to formulate and break down the problem into simple terms.

cheers
Markus

Rob:
Thanks for posting what is a MUCH more elegant python solution than what I had come up with originally. the modulus thing is something I can see my self using over and over again since I’m always finding my self making a variable that counts up or down, then starts over when it reaches a predefined limit.

Wouldn’t modifying a table be slower than an expression that didn’t resize the table every cook?
Or does the .clear() function not actually remove rows/columns but just clear them?

Markus,
So, the expressions in touch designer in 088 are fully python based unless the toggle at the top of the parameters dialog is set to tScript?

Very good point to break down the process, I will do that in the future I think I was stuck on a way to loop/count by 3’s which modulus was a good fix for too.

Thanks again!
Lucas

This every 3 rows reverse business is going into a somewhat home grown led panel mapping setup in touch for a logo panel I’m eventually doing for a dj/friend.

This video is of my R&D panels setup with some ramp animations:
[url]3rd led panel R&D setup - YouTube

some led panels zip zag left to right as they go down and others just left to right, row after row.
I tied it in with a check box to make it a toggle/option per panel.

Yup, by default all nodes created in TouchDesigner088 are set to Python mode. Toggling will revert it back to tscript.
cheers
Markus

PS: the LED panel looks great. Awesome effort!

One exception to this rule is that if you create a new node off the connector output of a tscript node (ie. using RMB or MMB on the connector) the new node will also be in tscript mode. This is by design so if you are extending a tscript network each node added is already in tscript mode.