Prolog call python

Hello,

I’m using: SWI-Prolog version 7.6.4

I want the code to be able to pass parameter to Python code and read Python return value.

But what I’m getting is: the output
?- [python_lib].
true.

?- python_call(‘hello_world.py’, ‘delete’, Result).
Result = " ".

My code looks like this:

% your code here

python_call(File, Function, Result) :-
    atomic_list_concat(['from ', File, ' import *;print(', Function, '())'], Command),
    process_create(path(python), [['-c'],[Command]], [stdout(pipe(In))]),
    read_string(In, _, Result).

python

%code
import mysql.connector

def delete():
    connection = mysql.connector.connect(user='root',password='formag',host='localhost',database='test')
        
    mycursor = connection.cursor()
    sql_delete = 'DELETE from tabletest where id = 103'
    mycursor.execute(sql_delete)  
    connection.commit()
    connection.close()
    
    return 'data deleted'

Please help me.

Getting the output of a program is almost correct:

?- process_create(path(echo), [aap, noot], [stdout(pipe(In))]),                                                                                                                read_string(In, _, Result).
In = <stream>(0x5627ff79a890),
Result = "aap noot\n".

It seems to be that [['-c'],[Command]] is wrong though. The argument list is just a list of arguments, not a list of lists of arguments. What made you think so?

That said, SWI-Prolog has library(odbc) to talk to a database. That is way simpler and faster than using Python.

I am really sorry … this prolog seems not talking to and receives python return value…
I changed the code;

test_python(Script,Def,Result):-
    process_create(path(python),[Script,Def],[stdout(pipe(In))]),
    read_string(In, _, Result).
--------------------------------------------------------------------------------------------------------------
(python)
def hello():
    return 'hello'
def value(param):
    return param
-------------------------------------------------------------------------------------------------------------
[trace]  ?- process_create(path(python),['hello_world.py','hello'],[stdout(pipe(In))]),
|    read_string(In,X,Y). 

 Exit: (9) process:process_create(path(python), ['hello_world.py', hello], [stdout(pipe(<stream>(000001EED58BD030)))]) ? creep
   Call: (9) read_string(<stream>(000001EED58BD030), _2844, _2846) ? creep
   Exit: (9) read_string(<stream>(000001EED58BD030), 0, "") ? creep
In = <stream>(000001EED58BD030),
X = 0,
Y = "".

should i opt read_string to others??
what would be the prolog code for def value(param)??

please help
thanks.

Python doesn’t work that way. Here’s one way of calling Python from Prolog:

$ cat /tmp/hello.py
def hello():
    return 'hello world'

if __name__ == '__main__':
    print(hello())

$ cat /tmp/hello.pl
do :-
    process_create(path('python3.7'), ['/tmp/hello.py'], [stdout(pipe(In))]),
    read_string(In, Len, X),
    write(Len:X), nl, halt.

$ swipl -g do /tmp/hello.pl
12:hello world

And this shows passing args through to Python:

$ cat /tmp/hello.py
import sys

def hello():
    return 'hello world: ' + ','.join(sys.argv[1:])

if __name__ == '__main__':
    print(hello())

$ cat /tmp/hello.pl
do :-
    process_create(path('python3.7'),
                   ['/tmp/hello.py', foo, bar],
                   [stdout(pipe(In))]),
    read_string(In, Len, X),
    write(Len:X), nl, halt.
$ swipl -g do /tmp/hello.pl
21:hello world: foo,bar

thanks a lot for your help …

i have another question… prolog + mysql + web

this is my code

prep_output(SQL, Type, Row,Values):-
    odbc_prepare(myDB, SQL, Type,Q,[fetch(fetch)]), 
    odbc_execute(Q,Values,Row), 
    fetch(Q).

fetch(Q):-
        odbc_fetch(Q, Row, []),
        (   Row == end_of_file
        ->  true
        ;   writeln(Row),
            fetch(Q)
        ).

select_all(Table,Id, Species,Dbh):-
    swritef(S,'SELECT * FROM %t', [Table]),
    prep_output(S, [], row(Id, Species,Dbh) , []).

this is my output in web browser - it display record by row

row(103,meranti103,55)
row(104,meranti104,60)
row(105,meranti105,65)
row(106,meranti106,70)

how to display the records by column name?

thanks again.

Note that you can provided SQL as Format-Args., e.g. 'SELECT * from ~w'-[Table]. In any case, writef and friends are old school. Use format/2,3. These predicates are more portable, implemented a lot more robustly and way more versatile.

See Accessing the database dictionary