Reputation: 402
I'm trying to use subprocess
to generate a bunch of test cases, but something goes wrong.
Why is the following (simplified example) not working?
I have a first simple program sphere.py
:
#!/usr/bin/python
# -*- coding: utf-8 -*-
PI = 3.141592
radius = float(input( 'Give the radius of the sphere (in cm): ' ))
area = 4*PI*pow(radius, 2)
volume = 4/3*PI*pow(radius, 3)
print("\narea: {} cm²\nvolume: {} cm³".format(round(area,2),round(volume,2)))
Where an input of 4
results in (after running python3 sphere.py
):
area: 201.06 cm²
volume: 268.08 cm³
Then I have another file, generator.py
which runs the first one with subprocess
:
import subprocess
res = subprocess.run(["python", "sphere.py"], input="4",
capture_output=True, encoding="utf")
result_lines = res.stdout.split("\n")
for line in result_lines:
print(line)
But this results in (different volume, after running python3 generator.py
):
Give the radius of the sphere (in cm):
area: 201.06 cm²
volume: 201.06 cm³
Strangely, when I changed the volume
formula to 4.0/3.0*PI*pow(radius, 3)
it seemed to work fine...
What is going on here?
using Python 3.8
Upvotes: 1
Views: 107
Reputation: 19431
What usually happens on systems that have both Python 2 and 3 installed, is that python
command is linked to Python 2, and python3
is linked with... well obviously Python 3.
So while you are running your files from a shell with Python 3, the subprocess call invokes the Python 2 interpreter. So the easy fix is to force it to use Python 3:
subprocess.run(["python3", "sphere.py"], ...)
Or use sys.executable
to make sure the same Python interpreter is being used:
import sys
subprocess.run([sys.executable, "sphere.py"], ...)
Or, find a better way to run a Python file from another one.
The hint for this problem is the difference with the division operator between Python 2 and 3. In python 2, 4/3
will give 1. While in Python 3 it will give 1.333
. When you did 4.0/3.0
it forced the Python 2 interpreter to use float division as well so the problem was solved.
Interestingly, the use of 4
as the input made the two formulas equivalent (under Python 2). The 4/3
became 1 and didn't affect, and the extra power of radius
became equivalent of multiplying by 4, hence the similar result.
Upvotes: 2