Python Procedures - python

I have developed a graphical Library (in Pascal) and wanted to use it with several other languages. I have tried it with Python and it works.
Here part of the working code:
#file fpgui-test.py
from ctypes import*
fpgui = cdll.LoadLibrary("fpgui-32.dll")
fpgui.fpgInitialize()
fpgui.fpgFormCreate(0, -1)
fpgui.fpgFormSetPosition(0, 300,100,400,200)
fpgui.fpgFormWindowTitle(0, 'Hello world!')
fpgui.fpgButtonCreate(0,0,-1) ;
fpgui.fpgButtonSetPosition(0,0, 15, 10 , 150 , 40)
fpgui.fpgButtonSetText(0,0, 'BUTTON1')
fpgui.fpgButtonCreate(0,1,-1) ;
fpgui.fpgButtonSetPosition(0,1, 15, 70 , 150, 40)
fpgui.fpgButtonSetText(0,1, 'Clickme')
fpgui.fpgFormShow(0)
fpgui.fpgRun()
But now I want to add some procedures. In Pascal a procedure is declared like this:
fpgFormOnClick(index : integer ;TheProc : procedure);
And used like this:
fpgFormOnClick(0,#TheProc); => how can you translate that in Python ?
And, for example, if TheProc procedure is like that in Pascal, how do I do it in Python?
procedure TheProc;
begin
fpgButtonSetText(0,1,'Test');
end;

Here is how you can do it.
# here we register the events
events={}
# registation function for events
def fpgFormOnClick(index, procedure):
events[index] = procedure
# emulates fireing of events
def fire(index):
# check if we have an event registered
if index in events:
# call the registered function/procedure
events[index]()
def TheProc():
# if you use python 3 use
# print("TheProc")
print "TheProc"
# register the function
fpgFormOnClick(0,TheProc)
# and fire it
fire(0)
fire(1)
Or is your question about how to get the python function called by the DLL?

I have found the solution - it was in "CallBack function" in help-doc.
#file fpgui-test.py
from ctypes import*
def TheProc():
fpgui.fpgFormWindowTitle(0, 'Boum')
return 0
def TheProcBut0():
fpgui.fpgButtonSetText(0,0, 'Boum also')
return 0
def TheProcBut1():
fpgui.fpgButtonSetText(0,1, 'Boum too')
return 0
CMPFUNC = CFUNCTYPE(c_int)
TheProcF = CMPFUNC(TheProc)
TheProcB0 = CMPFUNC(TheProcBut0)
TheProcB1 = CMPFUNC(TheProcBut1)
fpgui = cdll.LoadLibrary("fpgui-32.dll")
fpgui.fpgInitialize()
fpgui.fpgSetStyle('Demo Style')
fpgui.fpgFormCreate(0, -1)
fpgui.fpgFormSetPosition(0, 300,100,400,200)
fpgui.fpgFormWindowTitle(0, 'Hello world!')
fpgui.fpgFormOnClick(0,TheProcF)
fpgui.fpgButtonCreate(0,0,-1) ;
fpgui.fpgButtonSetPosition(0,0, 15, 10 , 150 , 40)
fpgui.fpgButtonSetText(0,0, 'BUTTON1')
fpgui.fpgButtonOnClick(0,0,TheProcB0)
fpgui.fpgButtonCreate(0,1,-1) ;
fpgui.fpgButtonSetPosition(0,1, 15, 70 , 150, 40)
fpgui.fpgButtonSetText(0,1, 'Clickme')
fpgui.fpgButtonOnClick(0,1,TheProcB1)
fpgui.fpgFormShow(0)
fpgui.fpgRun()

Related

Python.net is not receiving correct encoded string from .net

I am using .net 4.7.1 console program talking to python.net that VS2017 is reporting as version 2.5.1.0 (runtime version v4.0.30319) Python code is in 3.6
python:
def ping(input):
if (input == 'ping'):
return 'pong'
return 'invalid'
def headervalid(header):
if (header == '#\n\u001e\rANSI '):
return True
return False
if __name__ == '__main__':
input = '#\n\u001e\rANSI '
print(headervalid(input))
input = 'ping'
print(ping(input))
dot net :
using (Py.GIL())
{
dynamic np = Py.Import("numpy");
Console.WriteLine(np.cos(np.pi * 2));
dynamic sin = np.sin;
Console.WriteLine(sin(5));
double c = np.cos(5) + sin(5);
Console.WriteLine(c);
dynamic a = np.array(new List<float> { 1, 2, 3 });
Console.WriteLine(a.dtype);
dynamic b = np.array(new List<float> { 6, 5, 4 }, dtype: np.int32);
Console.WriteLine(b.dtype);
Console.WriteLine(a * b);
dynamic parsers = Py.Import("newworld_parsers.bridgetest");
string input = "ping";
var result = parsers.ping(input);
Console.WriteLine(result);
input = #"#\n\u001e\rANSI ";
result = parsers.headervalid(input);
Console.WriteLine(result);
Console.WriteLine("=======");
Console.ReadLine();
}
The python stand alone run reports:
True
pong
Press any key to continue . . .
Dot net run reports:
1.0
-0.9589242746631385
-0.675262089199912
float64
int32
[ 6. 10. 12.]
pong
False
=== Press any key to continue ====
Notice the True in python vs the False when calling from C#
The special characters in headervalid() from dot net don't seem to be going over correctly. What should I do to fix this? Any ideas greatly appreciated!
Putting '#' character in front of C# string turns it into a raw string, meaning no escape sequences inside will work.
You can see that by adding Console.WriteLine(input); to your code.

python myhdl package how to generate verilog initial block

From the code mostly from the sample of myhdl:
from myhdl import Signal, intbv, delay, always, now, Simulation, toVerilog
__debug = True
def ClkDriver(clk):
halfPeriod = delay(10)
#always(halfPeriod)
def driveClk():
clk.next = not clk
return driveClk
def HelloWorld(clk, outs):
counts = intbv(3)[32:]
#always(clk.posedge)
def sayHello():
outs.next = not outs
if counts >= 3 - 1:
counts.next = 0
else:
counts.next = counts + 1
if __debug__:
print "%s Hello World! outs %s %s" % (
now(), str(outs), str(outs.next))
return sayHello
clk = Signal(bool(0))
outs = Signal(intbv(0)[1:])
clkdriver_inst = ClkDriver(clk)
hello_inst = toVerilog(HelloWorld, clk, outs)
sim = Simulation(clkdriver_inst, hello_inst)
sim.run(150)
I expect it to generate a verilog program that contains an initial block, like something:
module HelloWorld(...)
reg [31:0] counts;
initial begin
counts = 32'h3
end
always #(...
How can you get the initial block generated?
Note that on the google cache for old.myhdl.org/doku.php/dev:initial_values it links to example https://bitbucket.org/cfelton/examples/src/tip/ramrom/ . So it looks the feature should be supported. However the rom sample generates static case statements. That's not what I'm looking for.
Three steps to resolve it:
Update to the latest myhdl on master or a version that contains the hash 87784ad which added the feature under issue #105 or #150. As an example for virtualenv, run a git clone, followed by pip install -e <path-to-myhdl-dir>.
Change the signal to a list.
Set toVerilog.initial_values=True before calling toVerilog.
Code snippet follows.
def HelloWorld(clk, outs):
counts = [Signal(intbv(3)[32:])]
#always(clk.posedge)
def sayHello():
outs.next = not outs
if counts[0] >= 3 - 1:
counts[0].next = 0
else:
counts[0].next = counts[0] + 1
if __debug__:
print "%s Hello World! outs %s %s %d" % (
now(), str(outs), str(outs.next), counts[0])
return sayHello
clk = Signal(bool(0))
outs = Signal(intbv(0)[1:])
clkdriver_inst = ClkDriver(clk)
toVerilog.initial_values=True
hello_inst = toVerilog(HelloWorld, clk, outs)
sim = Simulation(clkdriver_inst, hello_inst)
sim.run(150)

Python - calculations with more than one splited serial data

I use Arduino to receive data from sensors (4 types of data : humidity, temperature, photocell and milliseconds)
Datas comes like this : xx xx xx xxxx in the serial buffer. (data space data space etc...)
I split this line in order to isolate each data because I want to make individual calculations for each sensor.
Calculation for each sensor consist on : ((latest_data) - (data_of_previous_line), latest_data) in order to get a tuple for each sensor. I want all the sensors tuples appearing in the same line.
Doing this with 1 sensor and 1 method (calculate()) is working fine but it doesn't work if I add a second sensor in sensors() object !
QUESTION : how to make all this working with at least 2 sensors data ?
(the code below is working perfectly with 1 "splited" sensor data).
Thanks in advance.
class _share:
def __init__(self):
self.last_val = [0 for i in range(2)]
def calculate(self, val):
self.last_data = val
self.last_val = [self.last_data] + self.last_val[:-1]
diff = reduce(operator.__sub__, self.last_val)
print (diff, val)
return (diff, val)
share = _share()
ser = serial.Serial('/dev/ttyS1', 9600, timeout=0.1)
def sensors():
while True:
try:
time.sleep(0.01)
ser.flushInput()
reception = ser.readline()
receptionsplit = reception.split()
sensor_milli = receptionsplit[3]
sensor_pho_1 = receptionsplit[2]
sensor_tem_1 = receptionsplit[1]
sensor_hum_1 = receptionsplit[0]
int_sensor_milli = int(sensor_milli)
int_sensor_pho_1 = int(sensor_pho_1)
int_sensor_tem_1 = int(sensor_tem_1)
int_sensor_hum_1 = int(sensor_hum_1)
a = int_sensor_milli
b = int_sensor_pho_1
c = int_sensor_tem_1
d = int_sensor_hum_1
return str(share.calculate(b))
except:
pass
time.sleep(0.1)
f = open('da.txt', 'ab')
while 1:
arduino_sensor = sensors()
f.write(arduino_sensor)
f.close()
f = open('da.txt', 'ab')
You need to use different share instance for each sensor otherwise the calculations will be wrong. So use share_a, share_b, share_c and share_d for a, b, c and d respectively for example. Now if I understand this correctly, you can return all the sensors at once by changing your return to:
return [ str(share_a.calculate(a)), str(share_b.calculate(b)), str(share_c.calculate(c)), str(share_d.calculate(d)) ]
The above would return a list containing all 4 sensors and then in your main method you can change to:
arduino_sensor = sensors()
sensor_string ="a:%s b:%s c:%s d:%s"%( arduino_sensor[0], arduino_sensor[1], arduino_sensor[2], arduino_sensor[3] )
print sensor_string # single line screen print of all sensor data
f.write( sensor_string )
I hope that is helpful.

graphics in python to make a task manger

I am designing a task manager for a month using graphics in python. I have created the calendar for the month of July. I would like to display the tasks for a given date, add new tasks, remove/delete tasks and save the changes to a file.
The maximum number of to do tasks for any day is 5. Initially, the list of tasks are read from a file. Each row in the file contains the date followed by a list of semi-colon separated tasks for that date. The following shows an example file:
1; Go to class;Book Train Ticket
2; Call Home
3; Wash the Clothes
7; Submit the Assignment Online
8; Give Assignment Demo;Prepare for Major
10; Take the Exam
11; Go Home
To the right of calendar, there is a textbox to enter a new task to the list of to-do tasks for the date currently being displayed. After entering the new task in the textbox, I need to click on the ’ok’ button to add it to the list. As soon as the ’ok’ button is pressed, the list of tasks being displayed should be refreshed to reflect the addition of the new task. The textbox should be cleared after the changes have been incorporated into the task list. Here's my code:
from graphics import *
win =GraphWin("Task Manager",800,800)
head = Text(Point(130,15),"July2014")
head.setSize(16)
head.draw(win)
add = Text(Point(440,28),"Add Task :")
add.setSize(17)
add.draw(win)
adde = Entry(Point(560,28),20)
adde.draw(win)
rem = Text(Point(440,78),"Remove Task:")
rem.setSize(17)
rem.draw(win)
reme = Entry(Point(570,78),20)
reme.draw(win)
addr = Rectangle(Point(680,15),Point(640,45))
addr.setFill("yellow")
addr.draw(win)
okt = Text(Point(660,30),"ok")
okt.setSize(16)
okt.draw(win)
remr = Rectangle(Point(690,60),Point(650,90))
remr.setFill("green")
remr.draw(win)
okt = Text(Point(670,75),"ok")
okt.setSize(16)
okt.draw(win)
savr =Rectangle(Point(440,120),Point(540,150))
savr.setFill("orange")
savr.draw(win)
savt = Text(Point(490,135),"Save to file")
savt.setSize(15)
savt.draw(win)
exir = Rectangle(Point(590,120),Point(650,150))
exir.setFill("red")
exir.draw(win)
exis = Text(Point(620,135),"exit")
exis.setSize(15)
exis.draw(win)
def isInside(p,rect):
rectP1 = rect.getP1();
rectP2 = rect.getP2();
if(p.getX() >= rectP1.getX() and p.getX() <= rectP2.getX() and
p.getY() >= rectP1.getY() and p.getY() <= rectP2.getY()):
return True;
else:
return False;
dtext = Text(Point(180,350),"no date selected yet")
dtext.setSize(16)
dtext.draw(win)
def rect(a):
squ = Rectangle(Point(20+((a-1)%7)*40,70+(((a-1)//7)-1)*30),Point(20+(((a- 1)%7)+1)*40,70+((a-1)//7)*30))
return squ
for i in range(1,43):
rect(i).draw(win)
l =['sun','mon','tue','wed','thu','fri','sat']
def elem(a):
p = Point(40+((a-1)%7)*40,85+(((a-1)//7)-1)*30)
sti = Text(p,l[a-1])
sti.setSize(15)
return sti
for i in range(1,8):
elem(i).draw(win)
def num(a):
p = Point(40+((a-1)%7)*40,85+(((a-1)//7)-1)*30)
b = Text(p,a-9)
return b
for j in range(10,41):
num(j).draw(win)
id = Text(Point(50,400),"id")
id.setSize(17)
id.draw(win)
task = Text(Point(200,400),"task")
task.setSize(17)
task.draw(win)
while 9 < a< 41:
inputP = win.getMouse()
if isInside(inputP,rect(a)):
dtext.setText("tasks on July"+rect(a).getText()+"are")
else:
dtext.setText("wrong")
win.getMouse()
win.close()

Error using GetExtendedTcpTable in python

I've got some troubles with using "GetExtendedTcpTable". When I tried to run my script, i've got message like this:
AssertionError: [Error 0] The operation completed successfully
Rarely script working normally, I dont understand this message, Operation completed, what`s wrong?
This is code, i tried to execute:
from ctypes import *
from ctypes.wintypes import *
from socket import inet_aton, inet_ntoa, htons
AF_INET = 2
TCP_TABLE_BASIC_LISTENER = 0
TCP_TABLE_BASIC_CONNECTIONS = 1
TCP_TABLE_BASIC_ALL = 2
TCP_TABLE_OWNER_PID_LISTENER = 3
TCP_TABLE_OWNER_PID_CONNECTIONS = 4
TCP_TABLE_OWNER_PID_ALL = 5
TCP_TABLE_OWNER_MODULE_LISTENER = 6
TCP_TABLE_OWNER_MODULE_CONNECTIONS = 7
TCP_TABLE_OWNER_MODULE_ALL = 8
# for storing socket info python style.
class socket_info:
State = None
LocalAddr = None
LocalPort = None
RemoteAddr = None
RemotePort = None
def __init__ (self, **kwargs):
for key, word in kwargs.items():
setattr(self, key, word)
def formatip (ip):
ip = inet_aton (str(ip))
return inet_ntoa (ip[::-1])
states = {
1 : "TCP_STATE_CLOSED",
2 : "TCP_STATE_LISTEN",
3 : "TCP_STATE_SYN_SENT",
4 : "TCP_STATE_SYN_RCVD",
5 : "TCP_STATE_ESTAB",
6 : "TCP_STATE_FIN_WAIT",
7 : "TCP_STATE_FIN_WAIT2",
8 : "TCP_STATE_CLOSE_WAIT",
9 : "TCP_STATE_CLOSING",
10 : "TCP_STATE_LAST_ACK",
11 : "TCP_STATE_TIME_WAIT",
12 : "TCP_STATE_DELETE_TCB",
"TCP_STATE_CLOSED" : 1,
"TCP_STATE_LISTEN" : 2,
"TCP_STATE_SYN_SENT" : 3,
"TCP_STATE_SYN_RCVD" : 4,
"TCP_STATE_ESTAB" : 5,
"TCP_STATE_FIN_WAIT" : 6,
"TCP_STATE_FIN_WAIT2" : 7,
"TCP_STATE_CLOSE_WAIT" : 8,
"TCP_STATE_CLOSING" : 9,
"TCP_STATE_LAST_ACK" :10,
"TCP_STATE_TIME_WAIT" : 11,
"TCP_STATE_DELETE_TCB" : 12 }
class MIB_TCPROW_OWNER_PID(Structure):
_fields_ = [
("dwState", DWORD),
("dwLocalAddr", DWORD),
("dwLocalPort", DWORD),
("dwRemoteAddr", DWORD),
("dwRemotePort", DWORD),
("dwOwningPid", DWORD)
]
class MIB_TCPTABLE_OWNER_PID(Structure):
_fields_ = [
("dwNumEntries", DWORD),
("MIB_TCPROW_OWNER_PID", MIB_TCPROW_OWNER_PID * 100)
]
def GetExtendedTcpTable (vip=AF_INET):
table = MIB_TCPTABLE_OWNER_PID ()
so = sizeof (table)
size = DWORD (so)
order = c_int(1)
failure= windll.iphlpapi.GetExtendedTcpTable (
byref (table),
addressof (size),
order,
vip,
TCP_TABLE_OWNER_PID_ALL,
0 )
assert not failure, WinError (GetLastError ())
pytables = []
tables = table.MIB_TCPROW_OWNER_PID
for index in range(table.dwNumEntries):
table = tables [index]
pytables.append (
socket_info (
State=states.get (table.dwState, "UNKNOWN_STATE_%s" %(str(table.dwState))),
LocalAddr=formatip (table.dwLocalAddr),
LocalPort=htons(table.dwLocalPort),
RemoteAddr=formatip (table.dwRemoteAddr),
RemotePort=htons(table.dwRemotePort),
OwningPid = int (table.dwOwningPid)
)
)
return pytables
def GetTcpTableForPid (pid):
tables = GetExtendedTcpTable ()
for table in tables:
if table.OwningPid == pid: return table
raise "Cannot find tcp table for pid %s" %pid
dict_process = {}
pid_set =set()
pid_list = []
tcp_info_list = []
tcp_info = GetExtendedTcpTable()
for item in tcp_info:
LocalAddr = item.LocalAddr
LocalPort = item.LocalPort
RemoteAddr = item.RemoteAddr
RemotePort = item.RemotePort
OwningPid = item.OwningPid
print('local Addr: '+ LocalAddr,'local port: '+ str(LocalPort),'remote Addr: ' + RemoteAddr, 'Remote Port: ' + str(RemotePort), OwningPid)
The script is run from time to time. It can run for 5 minutes and then don't work about an hour with this stupid mistake. How to get around it?
I really dont know, what's with it. Please, help me, what i do wrong?
I use python 3.2 on Win7 SP1 x64
Thank you a lot!
You shouldn't use addressof(size). That returns a Python integer which will be cast as a 32-bit C int. Use byref(size) to create a pointer, which will be a 64-bit value if you're using 64-bit Python.
GetExtendedTcpTable doesn't call SetLastError. It returns a DWORD with one of the following codes:
NO_ERROR = 0
ERROR_INVALID_PARAMETER = 87
ERROR_INSUFFICIENT_BUFFER = 122
The pdwSize argument has the required size if the buffer was too small. One option here is to start with a length 0 array; then resize the struct; and finally cast the array to the correct size:
class MIB_TCPTABLE_OWNER_PID(Structure):
_fields_ = [
("dwNumEntries", DWORD),
("MIB_TCPROW_OWNER_PID", MIB_TCPROW_OWNER_PID * 0),
]
_GetExtendedTcpTable = windll.iphlpapi.GetExtendedTcpTable
def GetExtendedTcpTable(vip=AF_INET):
table = MIB_TCPTABLE_OWNER_PID()
size = DWORD()
order = 1
failure = _GetExtendedTcpTable(
byref(table),
byref(size),
order,
vip,
TCP_TABLE_OWNER_PID_ALL,
0)
if failure == ERROR_INSUFFICIENT_BUFFER:
resize(table, size.value)
memset(byref(table), 0, sizeof(table))
failure = _GetExtendedTcpTable(
byref(table),
byref(size),
order,
vip,
TCP_TABLE_OWNER_PID_ALL,
0)
if failure:
raise WinError(failure)
ptr_type = POINTER(MIB_TCPROW_OWNER_PID * table.dwNumEntries)
tables = cast(table.MIB_TCPROW_OWNER_PID, ptr_type)[0]
pytables = []
for table in tables:
# rest unchanged
Regarding the Win32 LastError value, in general you shouldn't rely on GetLastError in Python. You don't know if you're seeing an old error code from a previous call or if an intervening call modified the LastError value. If you're checking a single API call that uses LastError, then it should be OK to check GetLastError immediately afterward if the call failed. But more generally you may need to load the DLL with use_last_error=True:
iphlpapi = WinDLL('iphlpapi', use_last_error=True)
Function pointers created from this WinDLL instance will save LastError to thread local storage immediately after the call returns. Calling get_last_error returns the saved error code. Beforehand you can call set_last_error(0) to have 0 swapped in to LastError before the function is called.

Categories

Resources