Python is terrific for many things, but it can be quite slow. It is interpreted and has a lot of overhead for many of its features; dynamic typing does not come cheap. It may be difficult to easily access operating system functions from Python. C, C++, and other languages do not have these problems. It’s possible to write a program in Python that calls, for example, a C program to do complex calculations of system calls.
Consider the problem of finding the greatest common divisor (GCD) between two integers; that is, the largest number that divides evenly into both of them. If the GCD between N and M is 1, then these numbers are relatively prime, and they could find use in a random number generator.
1. Example: Find Two Large Relatively Prime Numbers
This problem is solved using a C program to do the GCD calculation and a Python program to pass it large numbers until a relatively prime par is found. There are many C versions of the GCD program. This is a common first-year programming assignment. One such is gcd.c, provided on the accompanying disk:
#include “stdafx.h”
#include <stdio.h>
int tmain(int argc, TCHAR* argv[])
{
long n,m;
scanf(“%ld %ld”,&n,&m);
while(n!=m)
{
if(n>m)
n-=m;
else
m-=n;
}
printf(“%d”,n);
return 0;
This is written for Visual C++ 2010 Express, but very similar code will compile for other compilers and systems. The basic idea is that it reads two large numbers, named n and m, determines their largest common divisor, and prints
that number to standard output. The way that Python communicates with this C program is through the I/O system. C reads from the standard input and writes to the standard output. The Python program co-opts the input and output, pushing text data containing the values of n and m to the input, and capturing the standard output and copying it to a string.
This requires the use of a module named subprocess that permits the program to execute the gcd.exe program and connect to the standard I/O. A function named Popen() takes the name of the file to be executed as a parameter and runs it. It also allows the creation ofpipes, which are data connections that can take the place of files. The Popen() call that runs the gcd program is
p = subprocess.Popen(‘gcd.exe’,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
Connecting stdin and stdout to subprocess PIPEs means that now Python can perform I/O with them. When GCD starts to execute, it expects two integers on input. These can now be sent from the Python program like this:
p.stdin.write(data)
The expression p.stdin represents the file connection to the program, and writing to it does the obvious thing. The Python program writes data to the C program, and the C program reads it from stdin. Data should be of type bytes, and should contain both large numbers in character form. Correspondingly, when the C program has found the greatest common divisor, it writes to standard output. This code is as follows:
s = str(p.stdout.readline())
The C program writes, and the Python program reads. The value returned is of type bytes again, so it is converted into a string.
The final Python solution calls the C program repeatedly until the GCD is 1:
import subprocess
n = 11111122 m = 121
data = bytes (str(n)+ ‘ ‘+str(m), ‘utf-8’)
while True:
p = subprocess.Popen(‘gcd.exe’,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
p.stdin.write(data)
p.stdin.close()
s = str(p.stdout.readline())
print (s)
if s == “b’1″‘:
print (“Numbers are “, n, m)
break
m = m + 1
data = bytes (str(n)+ ‘ ‘+str(m), ‘utf-8’)
This method of communicating with other languages is universal, but slower than passing parameters to functions and methods directly. There are a lot of problems with calling functions in other languages, not the least of which concerns typing. Python, which is a dynamically typed interpreted language, would make the programmer perform a significant amount of work to convert lists or dictionaries into a form that C or Java could use.
Source: Parker James R. (2021), Python: An Introduction to Programming, Mercury Learning and Information; Second edition.