I am developing a program to be the user interface that collects data and then use an external program to process it, finally, fetch the results back to plot them in main. My problem is that I cannot manage to use a proper import function without falling into a loop.
For simplicity reasons, I will create a dummy code that represents what I am doing and my problem:
main.py
import sys,os, math, statistics, re
from multiprocessing import Process,Queue,Pipe
import subprocess
'''---Data input block---'''
print('-----Welcome to mainX-----')
num1=int(input('type number 1:'))
num2=int(input('type number 2:'))
print('choose a tool between adding and multiplying')
tool=input('multiply/add: ')
'''---Data storage block---'''
class Input:
def __init__(self, point_a, point_b):
self.data_a=num1
self.data_b=num2
def data_a(self):
return(self.data_a)
def data_b(self):
return(self.data_b)
'''---external program block---'''
if tool == 'add':
Add= subprocess.run(['python',"add.py"], capture_output=True)
if tool == 'multiply':
Multiply= subprocess.run(['python',"multiply.py"], capture_output=True)
'''---Plotting block---'''
fig = plt.figure(figsize = (7,5))
ax= fig.add_subplot(111)
TK = np.linspace(1,10)
if tool == add:
ax.plot(TK, addresult, label='This is te result of addition', c='g', linewidth=3)
if tool == multiply:
ax.plot(TK, multiplyresult, label='This is te result of multiplying', c='g', linewidth=3)
ax.set_xlim(270, 400)
plt.legend(fontsize=14)
plt.tight_layout()
plt.show()
Add.py
from main import data_a
addresult:[data_a +1, data_a +2, data_a +3]
Multiply.py
from main import data_b
multiplyresult: [data_b *1, data_b *2, data_b *3]
Disclaimer: There are clearly some errors in this dummy code, but I just wanted to illustrate the general flow.
The errors I am getting are:
ImportError: cannot import name 'data_a' from 'main'
or just going into an infinite loop asking for the input data
Thanks for the help!
In this code you have many mistakes.
There are no data_a
, data_b
but self.data_a
, self.data_b
.
You created class Input
but you never created instances like
data = Input(num1, num2)
to keep data in this class.
But all this is useless because self.data_a
self.data_a
are created dynamically in memory when you run main.py
but import main
can load only code from file main.py
- it can't get data created when main
was running. You would have to save data in file and other script would have to read from file. OR you would have to send it as argument in command line run(['python',"multiply.py", str(num1)]
and other script would have to use sys.argv[1]
to get it. And script has to use print()
to send result back to main
(subprocess
). And main
would have to read this string, split to separated numbers and convert to integer - so it would need a lot work.
There is also other problem. When you import main
then it runs all code in this file which is not in functions - so you have loop which ask again for inputs.
I would do it in different way. I would put code in functions in Add.py
, Multiply.py
and I would import Add, Multiply
in main
. And this way I could run it without subprocess
Something like this
Add.py
def add(data):
return [data+1, data+2, data+3]
Multiply.py
def multiply(data)
return [data*1, data*2, data*3]
main.py
import sys # PEP8: imports in separated lines
import os
import math
import statistics
import re
from Add import add
from Multiply import multiply
# --- classes ---
class Input:
def __init__(self, a, b):
self.a = a
self.a = b
def get_a(self):
return self.a
def get_b(self):
return self.b
# --- functions ---
def main():
# ---Data input block---
print('-----Welcome to mainX-----')
num1 = int(input('type number 1:')) # PEP8: spaces aroung `=`
num2 = int(input('type number 2:'))
print('choose a tool between adding and multiplying')
tool = input('multiply/add: ')
# ---Data storage block---
data = Input(num1, num2)
# ---external program block---
if tool == 'add':
result = add(data.get_a())
if tool == 'multiply':
result = multiply(data.get_b())
# ---Plotting block---
fig = plt.figure(figsize=(7,5))
ax = fig.add_subplot(111)
TK = np.linspace(1,10)
if tool == 'add':
ax.plot(TK, result, label='This is te result of addition', c='g', linewidth=3)
if tool == 'multiply':
ax.plot(TK, result, label='This is te result of multiplying', c='g', linewidth=3)
ax.set_xlim(270, 400)
plt.legend(fontsize=14)
plt.tight_layout()
plt.show()
if __name__ == '__main__':
main()
EDIT:
With subprocess
it could look like this
Add.py
import sys
if len(sys.argv) > 1
data = int(sys.argv[1])
print(data+1, data+2, data+3)
Multiply.py
import sys
if len(sys.argv) > 1
data = int(sys.argv[1])
print(data*1, data*2, data*3)
main.py
import sys # PEP8: imports in separated lines
import os
import math
import statistics
import re
import subprocess
# --- classes ---
class Input:
def __init__(self, a, b):
self.a = a
self.a = b
def get_a(self):
return self.a
def get_b(self):
return self.b
# --- functions ---
def main():
# ---Data input block---
print('-----Welcome to mainX-----')
num1 = int(input('type number 1:')) # PEP8: spaces aroung `=`
num2 = int(input('type number 2:'))
print('choose a tool between adding and multiplying')
tool = input('multiply/add: ')
# ---Data storage block---
data = Input(num1, num2)
# ---external program block---
if tool == 'add':
p = subprocess.run(['python', 'Add.py', str(data.get_a())])
if tool == 'multiply':
p = subprocess.run(['python', 'Multiply.py', str(data.get_b())])
output = p.stdout
result = [int(value) for value in output.split(' ')]
# ---Plotting block---
fig = plt.figure(figsize=(7,5))
ax = fig.add_subplot(111)
TK = np.linspace(1,10)
if tool == 'add':
ax.plot(TK, result, label='This is te result of addition', c='g', linewidth=3)
if tool == 'multiply':
ax.plot(TK, result, label='This is te result of multiplying', c='g', linewidth=3)
ax.set_xlim(270, 400)
plt.legend(fontsize=14)
plt.tight_layout()
plt.show()
if __name__ == '__main__':
main()