View Full Version : Trouble doing simple math
I am doing simple processing of long integer data that are recieved by the stdinEvent via a RS232.
SNAP Python does not seem to process or convert integers consistantly when I try to do math on the inputs. Maybe it thinks they are characters? Maybe I just need to format the data correctly?
Here is an example that works on a node:
CountL = 0
AverageL = 0
def stdinEvent(data):
print "Input Recieved :", data
AverageL = data
CountL = 1
print "---------",AverageL
print "--------", CountL
Here is what I really want to do but Python does not cooperate at all - just gives runtime errors:
CountL = 0
AverageL = 0
def stdinEvent(data):
print "\rInput Recieved :", data
if CountL > 1 :
AverageL += long(data)
CountL += 1
print "---------",AverageL/CountL
print "--------", CountL
When I do the even the super simple counter math it fails on the node but on the interpreter it works, Interpreter output:
CountL = 0
print CountL
0
CountL = CountL + 1
print CountL
1
print CountL
1
CountL = CountL + 1
print CountL
2
Obviouisly I am new to Python data objects - I do know lots of other languages - PERL / C / Java are good ones for me - but I can use a few tips on how to get the data type setup to do this in Python without reading too many references.
Thanks.
kbanks
12-03-2008, 08:39 AM
Yes, that is a string of characters that is passed to stdin.
You were very close... SNAPpy only supports 16-bit signed integers. (SNAP Reference page 20 as one example).
If you look in section 7 of the SNAP Reference Manual, you will see there is no such thing as a long() function in SNAPpy.
However, if you look on page 45, you will see that there IS an int() function.
This is what you would use if you wanted "123" to become 123.
Or maybe your incoming data stream really represents raw bytes. For example, "123" in your system really means 0x31, 0x32, 0x33 (three separate numbers).
In that case you want to use the ord() function (SNAP Reference page 48) instead.
I don't get why. Even the CountL fails when I increment ...
CountL = 0
AverageL = 0
def stdinEvent(data):
print "\rInput Recieved :", data
if Count > 1 :
AverageL += int(data)/CountL
CountL += 1
print "---------",AverageL
print "--------", CountL
And when I just try to update a counter each time data comes using the funtion below:
CountL = 0
AverageL = 0
def ProcInput(data):
print "\rInput Recieved :", data
CountL += 1
print "---------",AverageL
print "--------", CountL
I get the expected data value but the counter increment gives this error output: ?? !!
Input Recieved :124440451
Error 6 in ProcInput @9
Error 4 in ProcInput @12
---------0
--------Error 6 in ProcInput @26
I intercepted STDOUT and saw Portal output the error again when I was updateing the counter. I asume that the big error I keep hitting is:
Snappy Script Error: Unbound local variable in function "ProcInput" line 118
How do I 'bind' local variables in SNAP Python? Can I make them like a C/C++ static so I can accumulate values over time? Does SNAP always make numbers into characters? How to I force it to just use numbers?
Sorry this is so confusing to me because it should be super simple to count and add numbers in Python like this - it just won't work for me ! ... thanks in advance for some help.
kbanks
12-03-2008, 01:11 PM
Look at SNAP Reference page 17
Because you are omitting the "global" statements, you are creating new, temporary, local variables where your intent is to modify the existing global variables.
Yes, this handling of local versus global variables is different from C, C++, etc.
However, it exactly matches Python's handling of such variables. SNAPpy is a subset of Python.
I see what you mean about the variables and how they are created.
... still limited on doing any calculations with my the input data since its more than 16 bit integers coming in. I can use floats() if they are 32 bit and supported in SNAPpy - not the best solution but may work.
Otherwise I will have to process more on the other side of the serial interface prior to sending to big a number.
Thanks
Seems that globals have special rules. I can not seem to modify a global using the data I get in from the stdinEvent(data) ... I tried to put that value into a local varable and then add that local variable into a global but it failed. It seemes like it won't let me put that data value into any global.
So how do I get data from stdinEvent(data) and accululate it within my SNAPpy script? I need to get data off the serial and keep a running sum of it within the script. Is it possible in SNAPpy?
Thanks.
msellers
12-03-2008, 01:29 PM
If you have a PC in your network running Portal, you have access to the full math power of the PC and full Python scripts there. You can send your data to a Portal script for processing. This may or not be acceptable in your project but has been done in some.
kbanks
12-03-2008, 01:41 PM
I can use floats() if they are 32 bit and supported in SNAPpy
There are no floats (32-bit or otherwise) in SNAPpy.
As to your other question, global and local variables should work in your stdin event handler.
If you have a PC in your network running Portal, you have access to the full math power of the PC and full Python scripts there. You can send your data to a Portal script for processing. This may or not be acceptable in your project but has been done in some.
Yes this will be acceptable. Can you guide me to some good examples on how to use a Protal script to get and send data to a node?
Thanks
mgenti
12-15-2008, 12:58 PM
Yes this will be acceptable. Can you guide me to some good examples on how to use a Protal script to get and send data to a node?
The EK2500 Users Guide has a section on Portal scripting which should be a good place to start.
msellers
12-15-2008, 05:02 PM
In your node script, you will call a function in the portal script using rpc to the portal address.
portalAddr = '\x00\x00\x01' # hard-coded address for Portal
adcValue = readAdc(0)
rpc(portalAddr,"calcData",adcValue)
In your portal script (you can select portal as a node in the node list and it has an upload script tool bar button just like a node) you would have your calculation function:
def calcData(newReading):
#calculation would happen here
output = (newReading ** 2) / 1.68 + 500
print output #show result in event log
You could then convert it to a string, pass it back to a node, etc. See the manymeter demo for how to instantiate a window in wxPython on the PC to display results.
Jheath
12-16-2008, 03:50 PM
Section 11 (The Portal API) of the SNAP reference manual outlines the functions presented to Portal scripts.
You can use the predefined functionality or create your own. Much like other nodes in a SNAP network, Portal can send and received RPC calls to built-in or user defined functions.
martinnossel
12-17-2008, 09:05 PM
I didn't see the second page of answers, and put this together. (surprising how similar the examples are.)
If you load them to portal and a node, you can click on the node function
get_temp() and see the results on the log.
This took me a a fair time to debug, note the str where needed, the int, initializing variables xx = 0.0, (always a pain, always forgotten)
Martin
vBulletin® v3.8.0, Copyright ©2000-2012, Jelsoft Enterprises Ltd.