Perspective table cell number format

Hi
I am using a perspective table to display some data from a database
The table has 2 columns, 'loss_item', and 'loss'
My transform is:

def transform(self, value, quality, timestamp):
	lst = []
	
	r = [r for r in value if r['resource_id'] == self.view.params.node_name]

	row1 = {'loss_item':'Percent loss', 
			'loss': r[0]['pct_loss_per_run']
			}
	lst.append(row1)
	
	row2 = {'loss_item':'Absolute loss', 
			'loss': r[0]['abs_loss_per_run']
			}
	lst.append(row2)

	row2 = {'loss_item':'Loss cost', 
				'loss': r[0]['loss_cost'],		
			}
	lst.append(row2)
	
	return lst

I would like to modify the number format of column 1 ('loss) of each row as follows:
Row 1 as a percentage (2 decimal places)
Row 1 as a Float
Row 3 as a currency

I have searched the forum & user manual, tried various things and came up empty.

Any suggestions?

You need to edit columns first.

Thank you
Pls correct me if I'm wrong, but I think that will make all rows have SAME specified format.
If possible I need a DIFFERENT format in each row
Thanks

Sorry, I misunderstood.
If you don't have such high requirements, you can convert all the data into strings.
If there is a lot of data, you can place multiple tables.
If you still need to export data, save the original data to a custom params, and then do the above operation, and use the original data when exporting.
It's really a bit troublesome.

I think you are using a table for something a table was never meant to be used for.
You are better off making a dynamic view to show this data, possibly one with a flex repeater and use parameters to distinguish the rows for data handling.

You are correct of course David !
I wanted to use a table to maintain the aesthetics of my page and was hoping there may be a smart way!

this may be useful: Embedding a View in a Table Cell, perhaps with additional (hidden) columns that define the formatting per-cell. Could even make it just one additional column with json-encoded formatting/viewPath params for every cell in the row.

There is no reason your dynamic view can't look exactly like a table, the table itself is built from just styled containers at a root level. Follow the spacing and the css colours etc from a table in developer view in a browser then recreate it in the view.

1 Like

May I suggest a slight rewrite of the transform:

def transform(self, value, quality, timestamp):
	row  = next(r for r in value if r['resource_id'] == self.view.params.node_name)
	return [
		{
			'loss_item': "Percent loss",
			'loss': row['pct_loss_per_run']
		},
		{
			'loss_item': "Absolute loss",
			'loss': row['abs_loss_per_run']
		},
		{
			'loss_item': "Loss cost",
			'loss': row['loss_cost']
		}
	]

If you're looking for one specific row, use next. As you can see, it can also take a generator expression (the same thing you use in comprehensions). This has 2 benefits:

  • You get the row directly, instead of a list with. No need get its first item.
  • It stops as soon as it find the row, instead of processing the whole list

If it's possible the row doesn't exist, you can either catch the 'StopIteration' it raises:

try:
	next(...)
except StopIteration:
	logger.info("row not found")

Or give a default to next:

next((v for v in value if r == x), default)

You can easily change the format of whatever value you put in your table if you convert it to string in the transform, if you really want to keep using a table:

return [
	{
		'loss_item': "Percent loss",
		'loss': "{:.2f}%".format(row['pct_loss_per_run'])
	}
	...
]

Note that using floats for currency might result in less than ideal outputs. It's usually a good idea to use integers, one for the integer part, and another one for the decimal part.
That's because float operations are not guaranteed to be exact, ie:
image

3 Likes

Thank you all for the inputs
I will review and advise result shortly