Below is the solution I used.
From the subprocess
module I used the function Popen
with argument shell=True
to call my python2 scripts from the python3 and collected the stdout
. (This means everything has be printed to the console.)
This is python2 code I want to call in python3:
#readying.py
import axographio #this is the python2 package
import os #specific to the problem of reading data
import sys #needed to use arguments from the command line
if __name__=='__main__': #when y
path = sys.argv[1]
filename = sys.argv[2]
os.chdir(path)
file = axographio.read(filename)
# print 'done reading files'
data = file.data
no_measurements = len(data)
measurement_len = len(data[0])
print(no_measurements)
print(measurement_len)
for i, name in enumerate(file.names):
print(name)
for i in range(no_measurements):
for j in range(measurement_len):
print(data[i][j])
print('next measurement')
#this acts as a seperator when reading the data in python3, anything that cannot be converted to a float works
What this code does is simply take argument from the commad line. (Using the sys
module they can be passed to a .py scripts in the command line in the form python2 script.py arg1 arg2 arg2
.
The output of reading.py
is given out using print statements. Note that I print every datum individually in order to avoid truncation of the output. In this way the output is the standard output stdout
of the python2
call.
The python3 code is
#analyze.py
import subprocess
import numpy as np
def read_data(path, filename):
module_name = 'reading.py'
cmd = 'python2 '+module_name+' '+path+' '+filename
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
out, err = p.communicate()
#out is a bytes object
result = out.split(b'\n') #the output from different print statements is seperated by "b'\n'" in the bytes object
#everything below here is concerned with unpacking the output and structuring it as I needed it
output = []
i = 0
while i < len(result):
output.append(result[i].decode("utf-8"))
i+=1
ind = 0 #this should keep track of where in the output list we are
no_measurements = int(output[ind])
ind += 1
measurement_len = int(output[ind])
ind += 1
names = []
for i in np.arange(ind,ind+no_measurements):
names.append(output[i])
ind += 1
data = []
measurement = []
while ind<len(output):
try:
measurement.append(float(output[ind]))
ind+=1
except:
data.append(measurement)
measurement = []
ind+=1
data = np.array(data)
return names, data
What this does is to use the subprocess
module to execute as a shell command python2 reading.py path filename
. As mentioned above the stdout
of this call is the output of its print
statements. These are bytes
objects encoded with 'UTF-8'. Using the decode
method they can be converted to string objects which can then be changed in type using functions like float
. (This is another reason why it is useful to print everything seperately since it is rather annoying to have to scan through a string to find arrays or numbers.) In readying.py
data are seperated explicitely while being printed which makes it easy to structure them once they are read.
Tags: axographio in python3--read axograph files python3