Run .exe with command line input arguments with Python - python

I've got an .exe which prompts the user for input at the command line interface for several numerical parameters and then generates data in a .txt. I would like to use Python in order to run the .exe repeatedly with different numerical parameters.
In Python, I've called the executable with:
subprocess.call(["executable.exe"])
How can I run the executable and specify input parameters (note: I am not referring to miscellaneous parameters such as -s, -t, etc but actual numerical parameters which are fed into the .exe)?
Thanks
EDIT: My .exe was created from a .cpp which doubles a integer given by the user when prompted at CLI.
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main() {
int ExampleNumber;
cout << "Please enter a number: ";
cin >> ExampleNumber;
ExampleNumber = ExampleNumber*2;
ofstream ExampleFile;
ExampleFile.open("ExampleFile.txt");
ExampleFile << ExampleNumber;
ExampleFile.close();
}
I tried running the .py with the an input of '3' as an example but it does not seem to be working still?
import subprocess
subprocess.call(["Executable.exe", '3'])

You can pass arguments as follows
subprocess.call(["executable.exe", '--parametername1', 'value1',
'--parameter2', 'value2'])
Edit: I mentioned this answer when the code was not given. I assumed that program can read parameters from CLI. My answer is valid only if executable.exe can use input arguments from command line which is not the case here.

Related

How can I pass variables from Python back to C++?

I have 2 files - a .cpp file and a .py file. I use system("python something.py"); to run the .py file and it has to get some input. How do I pass the input back to the .cpp file? I don't use the Python.h library, I have two separate files.
system() is a very blunt hammer and doesn't support much in the way of interaction between the parent and the child process.
If you want to pass information from the Python script back to the C++ parent process, I'd suggest having the python script print() to stdout the information you want to send back to C++, and have the C++ program parse the python script's stdout-output. system() won't let you do that, but you can use popen() instead, like this:
#include <stdio.h>
int main(int, char **)
{
FILE * fpIn = popen("python something.py", "r");
if (fpIn)
{
char buf[1024];
while(fgets(buf, sizeof(buf), fpIn))
{
printf("The python script printed: [%s]\n", buf);
// Code to parse out values from the text in (buf) could go here
}
pclose(fpIn); // note: be sure to call pclose(), *not* fclose()
}
else printf("Couldn't run python script!\n");
return 0;
}
If you want to get more elaborate than that, you'd probably need to embed a Python interpreter into your C++ program and then you'd be able to call the Python functions directly and get back their return values as Python objects, but that's a fairly major undertaking which I'm guessing you want to avoid.

Call function from python in C++

I'm currently working on a project with a separate cli and gui. The gui part is written in C++ to keep the exectuable small. I compiled my python program with pyinstaller and need to call some functions from the C++ program.
Python part:
import configparser
def getconfig() -> list:
config = configparser.ConfigParser()
config.read("config.ini")
section1 = config["general"]
section2 = section["section2"]
return [section1, section2] #should be a list of dict?
Compiling it via pyinstaller --onefile --clean myprogram.py
What i would like to do in C++ is :
//please correct me if this is the wrong type,
//i know i probably need to do a bit of parsing between python and C++ types
std::vector<std::unordered_map<std::string, std::string>> > = myprogram.getconfig()
I just don't want to do the config parsing in C++ again, or would you recommend this as it's probably easier to call the compiled python binary?
This program just needs to run on linux, windows is not necessary.
If you are only planning to run on POSIX-compatible systems (ie. GNU/Linux), you could spawn a new process to run the Python script, e.g. using the C function exec. Example:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main()
{
char* args[] = { "pythonscript.py", NULL };
int t = execv("pythonscript.py", args);
if(t < 0) printf("%s\n", strerror(errno));
return 0;
}
And then in pythonscript.py:
#!/usr/bin/python3
print("hello, world!")
This trick works with bash scripts as well.
The script must be executable though, so remember to run chmod +x pythonscript.py.
EDIT:
You will likely need to use pipes or other mechanisms for inter-process communication. (this is not my expertise!)

Sending processor rank generated using C++ and Open MPI to Python script

I am a beginner C++ and MPI user. I am working in an HPC environment and need to do the following:
Use a C++ code to get the processor rank.
Pass rank to a bash script.
Feed a python script this rank value and run it (from the bash script).
This is the code I have written:
C++ (file name- cpp2bash_test.cpp):
#include <iostream>
#include <mpi.h>
int main(int argc, char** argv)
{
MPI_Init(&argc, &argv);
int size, rank;
MPI_Status status;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
cout << rank << endl;
MPI_Finalize();
return 0;
}
I compile the file as:
mpicxx -g -std=c++14 -o PRank cpp2bash_test.cpp
Bash:
#!/bin/sh
result=$(./PRank)
python3 bash2py_test.py $result
Finally, I submit the bash script as a PBS job. Here is the output file:
The line "Argument accepted= " is from the python script which simply accepts the rank and prints it.
To better understand why the python script gets a weird value, I changed the shell script to not accept any input from the C++ code. Instead, the C++ code simply printed its output. This is a partial screenshot of what I see in the output file:
The Python file output(not shown in the second image) is still similar to the one shown previously.
I googled for that warning but I did not really understand much of what I got to read. In fact, I don't even know if what I am reading is relevant to my problem.
I suspect that the full output from the C++ code contains the warning which, when passed to Python, gets truncated to just those weird values inside the square brackets. How do I remove these warnings and pass the right values to the python script?
Note that for most queue systems, there are system variables being set that indicate process rank. Once inside your script (that is started as MPI) you should be able to get it from the environment (you have to look into your queue system manual).
Another way is to produce some wrapped log and grep for the info, e.g.:
cout << "RANK:" << rank << endl;
Then, you can do something like this:
result=$(echo "RANK:2" | grep RANK | cut -f2 -d':')
echo $result
in your case it will be
result=$(./PRank | grep RANK | cut -f2 -d':')
echo $result

Linking the output of a Python script to the input of a C++ program

My python script is outputting the values of an analogue to digital converter to the console of a Raspberry Pi. In order to manipulate this data, I need to send this output to the input of a C++ file. Should I wrap my python code as C++ and include it inside of the program, or is there an easier way of passing the data directly?
To pass such a small amount of data I would recommend using the bash pipe. It seems to be the easiest way.
python script.py | ./cpp_prog
My fist thought on this would be to embed your script into a C++ program. Python itself suggests this. This would be the cleanest way. So you can control, if and when you get new data from your ADC.
Short excerpt from the link:
The simplest form of embedding Python is the use of the very high level interface. This interface is intended to execute a Python script without needing to interact with the application directly. This can for example be used to perform some operation on a file.
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print 'Today is',ctime(time())\n");
Py_Finalize();
return 0;
}
The Py_SetProgramName() function should be called before Py_Initialize() to inform the interpreter about paths to Python run-time libraries. Next, the Python interpreter is initialized with Py_Initialize(), followed by the execution of a hard-coded Python script that prints the date and time. Afterwards, the Py_Finalize() call shuts the interpreter down, followed by the end of the program. In a real program, you may want to get the Python script from another source, perhaps a text-editor routine, a file, or a database. Getting the Python code from a file can better be done by using the PyRun_SimpleFile() function, which saves you the trouble of allocating memory space and loading the file contents.
And so on and so forth. This will guide you in your way. May your project be good =)
If you mean at runtime, probably the simpelst way is via a std::system call
From https://en.cppreference.com/w/cpp/utility/program/system:
#include <cstdlib>
#include <fstream>
#include <iostream>
int main()
{
std::system("ls -l >test.txt"); // execute the UNIX command "ls -l >test.txt"
std::cout << std::ifstream("test.txt").rdbuf();
}
Possible output:
total 16
-rwxr-xr-x 1 2001 2000 8859 Sep 30 20:52 a.out
-rw-rw-rw- 1 2001 2000 161 Sep 30 20:52 main.cpp
-rw-r--r-- 1 2001 2000 0 Sep 30 20:52 test.txt
And just run your python whatever instead.

Running a file with arguments from python embedded within c

I'm currently working on a project that uses a C source file that has to interact with a python file (run the file and capture output) and im not exactly sure how to do it. currently the python file is run through terminal (linux) using:
python file arg1 arg2 arg3 arg4
and i am trying to embed python into the C code to just run the file first (no output capture) using the following code:
void python() {
FILE * file;
int argc;
char * argv[5];
argc=5;
argv[0]="pathtofile/file";
argv[1]="arg1";
argv[2]="arg2";
argv[3]="arg3";
argv[4]="arg4";
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc,argv);
file= fopen("pathtofile/file","r");
PyRun_SimpleFile(file,"pathtofile/file");
PyFinalize();
}
args1-2 are hard coded, and args3-4 are determined by the C code (just determines integer values), this is then passed to the python file where it then executes.
When running the above code i get a:
TypeError: unsupported operand type(s) for + :NoneType and 'str'
Any advice from here on what could be my issue is greatly appreciated.
EDIT:
I was using this as a guide as it seems to be similar to what im trying to acheive
Run a python script with arguments
Your argc is uninitialized - did you compile with warnings enabled and warnings made into errors (-Wall, -Werror on GCC?); and your argv is not properly null-terminated. Thus your code has undefined behaviour. Anything might happen including demons flying out of your nose. The argument to fopen mode must be a string yet you pass an int (character constant) - which has another UB.
Thus at least you must do:
int argc = 5;
char *argv[] = {
"pathtofile/file",
"arg1",
"arg2",
"arg3",
"arg4",
0
};
input = fopen(..., "r"); // "r", not 'r'!
Additionally you're not checking the return values of any of these functions. Any of them may fail and with Python you should expect them to fail - including your fopen! (Please tell that they're omitted for brevity).

Categories

Resources