Calculating averages of multiple non-contiguous row of table

Hi Guys:

I have a table where the user can select multiple non-contig. rows. I placed a button on the window and a numeric label. The code for the button on the actionPerformed action is:

table = event.source.parent.getComponent(“tblTTrack”)
selectedRows = table.getSelectedRows()
if len(selectedRows)>0:
total = 0
for rowNum in selectedRows:
value = table.data.getValueAt(rowNum, 6) # 3 is the column index of “RawValue”
total += value
average = total / len(selectedRows)
lbln_Avg_OG.Text=average

Which gives the following error:

NOTE: Likely I am not allowed to assign a variable to the text property of another control, as in the last code line above. Just thought I’d try. If this is the error, how do you suggest populating the label with the calculated value? TIA D. Lewis

Traceback (innermost last):
File “event:actionPerformed”, line 7, in ?
TypeError: add nor radd defined for these operands

at org.python.core.Py.TypeError(Py.java)
at org.python.core.PyObject._add(PyObject.java)
at org.python.core.PyObject.__iadd__(PyObject.java)
at org.python.pycode._pyx4.f$0(<event:actionPerformed>:7)
at org.python.pycode._pyx4.call_function(<event:actionPerformed>)
at org.python.core.PyTableCode.call(PyTableCode.java)
at org.python.core.PyCode.call(PyCode.java)
at org.python.core.Py.runCode(Py.java)
at com.calmetrics.factoryhmi.application.script.ScriptManager.runCode(ScriptManager.java:156)
at com.calmetrics.factoryhmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:137)
at com.calmetrics.factoryhmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:277)
at com.calmetrics.factoryhmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:54)
at $Proxy1.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

David,

First, in response to your note, the assignment to the text property is perfectly valid (except that it should be ‘text’ and not ‘Text’ - property names are case sensitive)

The error is on line 7. The value that you’re grabbing out of the table isn’t a number, it is likely a string. (Python doesn’t allow adding of numbers and strings, hence the error message “add not defined for these operands”) Maybe you got the column number wrong? Note that the column numbers start at 0, and that hidden columns are counted.

I would use the print statement to help you debug this script. Change the script to the following, and then look at the console to see what is printed out. This will show you what you are pulling out of the table. Post back to this thread with whatever is printed out.

table = event.source.parent.getComponent("tblTTrack") selectedRows = table.getSelectedRows() if len(selectedRows)>0: total = 0 for rowNum in selectedRows: value = table.data.getValueAt(rowNum, 6) print ("The value at row %d column 6 is: "%rowNum), value total += value # error is happening here average = total / float(len(selectedRows)) lbln_Avg_OG = event.source.parent.getComponent("lbln_Avg_OG") lbln_Avg_OG.text=average

Hope this helps,

Carl:

Thanks. I think I got just about everything wrong that is possible. I neglected to count hidden columns, I forgot python is case sensitive (too used to vb), and I didn’t explicity coerce the value to a double. It was Friday…

David

David,

Glad you got it working!

Hi Carl:

I pasted the code into the actionPerformed event, and got the following error:

Note: I’m not clear on what you mean by the console? Is that something like the immediate window in vb (alt+G)? It seems to me that the code was supposed to do something like a debug.print to some window, but I don’t see what window anywhere. As far as the rest of the error below, I see that the final error is trying to treat the calculated average as a string, but I don’t see a toString conversion function in the help documentation.

TIA D. Lewis

Traceback (innermost last):
File “event:actionPerformed”, line 11, in ?
TypeError: can’t convert 3461.3333333333335 to java.lang.String

at org.python.core.Py.TypeError(Py.java)
at org.python.core.Py.tojava(Py.java)
at org.python.core.PyBeanProperty._doset(PyBeanProperty.java)
at org.python.core.PyInstance.__setattr__(PyInstance.java)
at org.python.pycode._pyx3.f$0(<event:actionPerformed>:11)
at org.python.pycode._pyx3.call_function(<event:actionPerformed>)
at org.python.core.PyTableCode.call(PyTableCode.java)
at org.python.core.PyCode.call(PyCode.java)
at org.python.core.Py.runCode(Py.java)
at com.calmetrics.factoryhmi.application.script.ScriptManager.runCode(ScriptManager.java:156)
at com.calmetrics.factoryhmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:137)
at com.calmetrics.factoryhmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:277)
at com.calmetrics.factoryhmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:54)
at $Proxy0.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

First of all, you open the console window in the designer under the Tools -> Advanced menu, or CTRL-SHIFT-C.

The console is where all Python print statements print to. This is very useful for debugging.

You can open the console in the runtime through the button on the “About FactoryPMI” window.

Now, as to the error: change the last line to

	lbln_Avg_OG.text = str(average)

Sorry, missed the conversion there.

Hope this helps,

Hi Carl:

I am pretty far along in getting the code to work the way I want. However, I cannot seem to get jython to do more than one thing at a time. For example, the following works:

ogTotal = round(ogTotal/bblTotal)
lbln_Avg_OG.text=str(ogTotal)

However, this does not:

lbln_Avg_OG.text=str(round(ogTotal/bblTotal))

Is this by design, or am I missing something?

Also I spent some time fiddling with indents. I had been using tabs, but it didn’t seem to like that. In the end, I copied a code block you had posted and rewrote it to my needs. You indent 3, 6 etc. spaces for each successive indent. Is jython particular about this?

TIA D. Lewis

I hadn’t seen that some of the values are null – that seems to be the reason the code is bonking. Checking in the documentation, I don’t notice an isnull() function in jython. Is there an elegant way to skip the value if it is nonnumeric? TIA D. Lewis

[quote="David"]I cannot seem to get jython to do more than one thing at a time. For example....
Is this by design, or am I missing something?[/quote]
This type of nested function calls should definately work, there must be something else going on here.. (see next post)

Yes. Python lets you use whatever kind of indentation you want, but you must be consistent within a script. That means you can't indent with 4 spaces here, 1 tab there, 2 spaces somewhere else. You must be consistent. I prefer to use tabs, but the forum here converts my tabs into 3 spaces :angry:

You will notice that the examples in the documentation use tabs..

In the Python world, nulls become None (equivalent terms), so, to test if something is null (None) or not, you would do simply:

if myVar != None: callMyFunction(myVar)

Hope this helps,