How to restore connections when recreating replicants

Here’s a python solution:

[code]target_table = op( ‘table1’ )
source_table = op( ‘select3’ )

target_table.clear()
rowOffset = 0

for tableRow in range( int( source_table.numRows / 5 ) ):

startTime 	= source_table[rowOffset, 0]
endTime		= source_table[rowOffset + 1, 0]
line1 		= source_table[rowOffset + 2, 0]
line2 		= source_table[rowOffset + 3, 0]
room 		= source_table[rowOffset + 4, 0]
newLine 	= [ startTime, endTime, line1, line2, room ]

target_table.appendRow( newLine )

rowOffset  += 6[/code]

base_schedule.tox (2.12 KB)

This would need some error handling to make sure it didn’t break, or if there were any inconsistencies in the incoming xlm, but it’s a start for you.

Also worth pointing out that you can do this with just DATs to parse the XML and then re-assemble a table with the data you want.

base_schedule_just_dats.tox (1.55 KB)

Thanks!

Leaving work now so will look into this in detail tomorrow!

Thanks, Matthew!

I guess my next project is to learn python!

Does the code you wrote run automatically when a new XML file is read in…or do I need some method to run it?

The right way to really do this with python would be to do the parsing here as well. That would look like:

[code]# example by matthew ragan

matthewragan.com

import xml.etree.ElementTree as ET

setting up some variables for our script to use

source = op( ‘text1’ ).text
targetTable = op( ‘table_target’ )
root = ET.fromstring( source )

the number of entires in the XML

numEntries = len(root)

our header names for our targetTable

tableHeader = [ ‘start’,
‘end’,
‘client’,
‘event_name’,
‘room’]

set up our target table

targetTable.clear()
targetTable.appendRow( tableHeader )

for child in root:
# child[1] is start
# child[2] is end
# child[3] is client
# child[4] is event name
# child[5] is room
newRow = [ child[1].text,
child[2].text,
child[3].text,
child[4].text,
child[5].text,]

targetTable.appendRow(newRow)[/code]

base_schedul_pure_python.tox (1.92 KB)

I’d probably lean on using the DAT Only method unless you want a code-centric solution. This new script better handles entries in a correct way - unlike the other table parsing method which could fall victim to oddities in your incoming XML.

This script isn’t set-up to run automatically, so you’ll just need an execute DAT or CHOP to trigger the script.

Hope this helps!

Thanks again, Matthew!

I’m using the DATs only method and am able to get a good table of rooms in use for the day.

Now I need to access the SIZEX SIZEY POSX POSY TEXTSIZE data in my table of all possible rooms configs. I was thinking the best idea is to run a script that compares the room names from the master list to the room list for today and, if they match, update the MEETING BOOKED column in the master list to a value of 1…and if they don’t match set that value to 0. This would allow me to use the existing network to select only the rooms with a 1 in column 6 to be replicated.

Here’s my first, nonworking attempt at a script to do this:

[code]# script to change column 6 value in table1

t1 = op(‘table1’)
t2 = op(‘select1’)

for item in range (t1.numRows):

for item in range (t2.numRows):
	
	if t1[0, 0] == t2[0, 0]:
		t1[0,6] = 1
		
else:

	t1[0,6]= 0[/code]

I think this is working but only on ROW 0 COLUMN 0…and I can see why! But I don’t know how to make the row numbers follow the item in the range…(does that make sense?)

Your help is greatly appreciated!

I tried the following after writing the previous post thinking I had had a flash of insight… I was wrong.

[code]# script to change column 6 value in table1

t1 = op(‘table1’)
t2 = op(‘select1’)

for item in range (t1.numRows):

for item in range (t2.numRows):
	
	if t1[item, 0] == t2[item, 0]:
		t1[item,6] = 1
		
else:

	t1[item,6]= 0[/code]

Are you looking to display if a room is booked during a given block of time or just if it’s been booked during the day?

Your nested for loops mean that you run your second loop as many times as you have rows in t1.

Based on what you’re saying it sounds more like you need a second table with the rooms, and time for the day. You’d loop through your scheduled list, then fill in your second table based on matching time and room hits. This would likely be easier if you change your times to 24 hour bases instead of am/pm - at least for your internal checks.

It might look something like this:
base_booking_table.tox (1.04 KB)

The primary focus of my project is to draw a room map which reflects the room configurations (wall arrangments) based on the daily schedule output of EMS. We already have a table-based display of the meetings/rooms/times for the day. The problem we are trying to solve is that attendees of the meetings don’t know where the rooms are.

For example:

There are 2 rooms called Cougar A and Cougar B and a third room next to them called Spartans. Each of these rooms can be booked individually and would show up on the map as such. The doors to these rooms have signs outside to identify them. However, we can also book a “room” called Cougar Combo which is comprised of all 3 rooms (Cougar A, Cougar B and Spartans). The signs outside the doors still say Cougar A, Cougar B and Spartans so attendees are confused as they are looking for something called Cougar Combo.

The SelfAdjustingMap8.toe I sent you shows how we will draw the map based on which “room” configurations are in use. I can see that we will have to have some sort of time-based method to redraw the map to reflect possible configuration changes that occur during the day. That will be phase 2.

Thanks to your assistance, I have been able to take an XML file exported from EMS and bring it into TD, parse it and get out the data I need (which at this time is primarily the name of the “room” that is booked). The task now is to compare each line item (room name) to the list of “rooms” in the master list and if it matches make the value in column 6 equal to 1. If not make it equal to 0. Doing this will allow me to use the existing network in SelfAdjustingMap8.toe to draw the map. I will just need to link my processed data to the master list so column 6 will be modified.

Am I on the right track? The nested loop script I wrote does not seem to work although I am not getting any script errors. Am I correct in thinking that my problem is the use of the word “item” in both loops?

I think you’re on the right track, I’m just guessing that you’ll end up needing to resolve overlapping times. Which is to say that asking if a room is booked at 1:00 is different than asking if a room is booked today. It sounds like you might be handling this in Phase2 - my suggestion here would be to take some time to think through what that might look like so you don’t program yourself into a corner.

When it comes to loops in loops you can reuse the same variable name, and that will mostly work… though it can cause some unintentional errors. Using a new variable name will make it easier to complete logical tests, as otherwise you’ll end up with some frustrating results. Here’s a quick look at how that can be a little murky:
base_loops_in_loops.tox (774 Bytes)

I think part of what you want is the col() method of the table DAT class. This creates a list of the contents of a given column, making it easier to do a comparison:

[code]# example by matthew ragan

matthewragan.com

booking = op( ‘table_booking’ )
schedule = op( ‘table_schedule’ )
booked_rooms = schedule.col(4)

reset the booking column

for room in range(booking.numRows)[1:]:
booking[room, 6] = 0

loop through the rooms

for room in range(booking.numRows)[1:]:
#check to see if the room is in the list of booked rooms
if booking[room, 0] in booked_rooms:
# if true, mark the room as booked
booking[room, 6] = 1
[/code]

In practice, that might work like this:
base_schedule_room_comparison.tox (1.78 KB)

Matthew -

Thanks for clarifying the formatting of the clock CHOP! I’m using the CHOP replace method you described. I had created a sub-network just to format the minutes display…now it is a single textTOP! BTW… if you know how to include that conversation in this thread please add it.

Next question: (please note I did not say LAST question :wink: )

Is there a way to force a carriage return/line feed in a line of text? I’m assuming you could embed a special character code. Or… is it better practice to use the word-wrap feature in the textTOP and set the width to one that breaks the line where you want it?

Andy

from https://www.derivative.ca/Forum/viewtopic.php?f=27&t=8242

Hey Andy - text formatting has lots of solutions, and it really comes down to what’s right for your project. Attached in this example there are three distinct ways to consider:

from a text DAT with word wrap on - this approach will use the contents of a text DAT faithfully respecting new lines. This is great if you’re doing all of your formatting in Python, then just want to dump that into a text DAT and have it show up. This approach would benefit form a script approach that filled in the contents of the text DAT with all the spacing you’d like. Here an additional consideration would be using the format() method in python. Using format, you compose a string that has placeholders for your intended text, which is then substituted in. For example:

myStr = "hello {}, how are you?" formatStr = myStr.format( 'Andy' ) print( formatStr )

would return:
hello Andy, how are you?

You can also use keywords with format, so while the above approach relies on the order that you supply substitutions, keyword use does not. That would look like:

myStr = "hello {name}, how are you?" formatStr = myStr.format( name='Andy' ) print( formatStr )

In the second text DAT example you’ll see the use of a new line character in python to inject a carriage return. The trick here is that you have to set your string to be an expression so the new line character is correctly evaluated. In the text parameter you’ll see:

"you can use special \ncharacters in python"

which should evaluate to

you can use special
characters in python

Finally, you could use a merge DAT approach. Here you’d have a fixed number of blocks of text with space between them created by a blank text DAT - though if you add more carriage returns you’ll get more space between blocks. Here again a script would probably be useful to fill in your blocks in a meaningful way.
base_text_DATs_and_TOPs.tox (838 Bytes)

Thanks, Matthew!

I think I can now format my room names into two lines so they will better fit the on the map when overlaying the room rectangle.

I am creating the room rectangle and the textTOP with the room name at the same output resolution (1280x720) and then scaling and translating them through their own transformsTOPS to fit on the base map. The text seems to get fairly soft when I do this. I’ve tried the various display options (bitmap, texture, etc.) Any suggestions to improve the sharpness of the scaled and translated text?

I’m starting to think that I should create a folder full of .png files for every room name at the proper scale and location and then just load that image to a movieinTOP instead of creating the text on the fly. Thoughts?

Scaled text is going to suffer some softening without pretty careful attention - you could display as polygon and then use an anti-alias top after scaling… but that’s likely to look a bit hit and miss I’d guess.

I’d definitely go the route of creating pre-made maps with text (and probably a set without as well), adding only additional text that’s appropriate for a given day. I’d then load all of these into known network location at start, and then just select them as needed.

Matthew -

On the schedule side of this project, I am trying to automatically adjust the height of the rows in the event schedule based on the number of rows on any given day. I’ve attached a sample .toe file I’m using to work out the logic. The actual implementation will be using a replicator to create the rows based on the schedule DAT.

I think this sort of works, but the rectangleTOPS (rows) need to be force-cooked to reflect the computational changes caused by changing the number of inputs connected to comp1. Not sure how to do that… or if there is a more elegant way (I’m sure there is!)

AutoRowSizing.toe (4.65 KB)

Have you considered using a table COMP for this instead?
derivative.ca/wiki099/index … Table_COMP

They’re a little bit of a rodeo to get a handle on, but I think this might be a simpler way to get to what you’re after - especially if you also want them to have text inside at some point.

I’ve changed the color of the table DATs that I added to an otherwise default table COMP:
container_table_example.tox (1.61 KB)

Matthew -

The example file I included only had 5 rows (rectangles), while the actual schedule file may have anywhere between 1 and 30 or so rows depending on the bookings for the day.

How do I create the necessary additional TableDATs within the TableCOMP on an “as needed” basis?

Can I create the maximum number I might need and then only use those needed for a given day based on the .numRows of the scheduleDAT?

The way the table COMP works you wouldn’t need to dynamically create any of the lookups,you’d just set them up ahead of time and then decide what rules the cells need to adhere to.

This is a little old now, but a good look at some of the basics for a table COMP:
matthewragan.com/2015/03/31/thp … hdesigner/

If you look in the last example I posted you’ll see a set of tables that define what cell1 - cell5 should look like, but these could be whatever number of different items that you need.

Take a look at this example:
container_table_comp_example2.tox (1.94 KB)

In container1 look at the constant1 CHOP and change the numRows val to be any whole number. You’ll see that the size of the table COMP is updated, and the number of rows in a table DAT that feeds the table COMP changes. An expression inside of the tableCOMP modulos the cell count - which insures there’s always a match for a lookup table. You can also put text in a table COMP or use images as backgrounds.

Take a look at these examples:
tableExamples.tox (3.51 KB)

Does that make sense?

Here is a screenshot of what I am currently doing:

This layout is being created through some fairly convoluted selecting & merging of DATs, then taking each column of text to a textTOP, compositing them together, compositing them again over a background color, then replicating the whole process to get mulitple rows.

To accomplish something similar using a TableCOMP would I have three TableCOMPs (one for each column of data with matching backgrounds) horizontally aligned in a ContainerCOMP?

As this is merely a display and does not require any user interaction is the TableCOMP the best method?

It really comes down to what you want to do - in my opinion, while a table COMP is typically associated with being an interactive element it doesn’t have to be one, and I think it certainly solves some of the challenges you’re facing here.

Take a look at this example and see if it makes better sense:
container_table_comp_example_schedule.tox (3.03 KB)

In container2 there are two containers one for the header row and another for the body. The body is - as you suspected - comprised of 3 table comps. Each gets a single column from a master table. The background of these tables comes from the rectangle_bg TOP which I used to mimic your background.

Table2 and 3 are clones of Table1 - which means that any changes you make to 1 will be reflected in 2 and 3 (should you decide to change fonts, or text size, etc.

If I were in your position I’d likely use something like this, or a list COMP - though those are pretty heavy on the python to get set up and styled - though that’s also a perfectly viable approach that could be done with a single list COMP rather than multiple Table COMPs. Either one of these is going to be fast, should be relatively easy on resources, and should update fast when you push a new schedule.