0

subprocess.Popen calls the calculator.py only when the loop ends. I need the code to run the calculator at once.

from subprocess import Popen
import calculator
while True:
    a='op'
    c='io'
    b=input()
    if a==b:
        #calculator
        Popen(['python', 'calculator.py'])
    elif c==b:
        print('hello')
    else:
        print("hi")
        break
  • 1
    This code would raise a `NameError`. Also, when `a==b` the condition `b!='no'` is not met and the loop breaks. – Axe319 Apr 20 '22 at 19:27
  • 4
    It is strange that you import the `calculator` module, but then run the same module as an external script through another Python script. Why not run the relevant module function straight from this script instead? Why create another process? – 9769953 Apr 20 '22 at 19:37
  • 2
    Your loop isn't infinite. – martineau Apr 20 '22 at 19:41
  • I guess you have already coded a calculator, and with another file you just want to start the file, so `os` module would come handy. Check out `os.startfile` if your os is windows. – Faraaz Kurawle Apr 20 '22 at 19:44
  • Also check https://stackoverflow.com/questions/434597/open-document-with-default-os-application-in-python-both-in-windows-and-mac-os – Faraaz Kurawle Apr 20 '22 at 19:45

2 Answers2

2

Per the docs, "The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. For more advanced use cases, the underlying Popen interface can be used directly." This is a very simple use case, so using run() is preferred. The problem here is that Popen isn't blocking, meaning that your program isn't waiting for it to finish executing, which I think is what you want. run(), by contrast, "Wait(s) for (the) command to complete, then return(s) a CompletedProcess instance."

For clarity's sake, here's some code to explain what's going on:

# instead of Popen, we're going to import run. CompletedProcess is used below
# for illustration purposes, but you don't need it and can remove it from your
# code
from subprocess import CompletedProcess, run

# there's no reason to import calculator, since you don't use it. you should
# remove this line
# import calculator

while True:
    a = "op"
    c = "io"
    b = input()
    if a == b:
        # after the specified command has completed, run returns an object of
        # type CompletedProcess[bytes], which I've indicated below using
        # python's type annotation syntax, i.e. variable: Type. this is for
        # illustration only. Since you're not using the return value, you can
        # simply say:
        # run(['python', 'calculator.py'])
        _completed_process: CompletedProcess[bytes] = run(["python", "calculator.py"])
    elif c == b:
        print("hello")
    else:
        print("hi")
        break
thisisrandy
  • 2,660
  • 2
  • 12
  • 25
  • Thanks for the reply, but the loop stops after `return subprocess.CompletedProcess(['python', 'calculator.py'], 0)`, and I need it not to stop – Таня Воробець Apr 21 '22 at 08:46
  • I think you may have misunderstood. I wasn't saying that *you* should return a `CompletedProcess`. Rather, *`run()`* returns a completed process. I'll update my answer with some code so as to be unambiguous. – thisisrandy Apr 21 '22 at 21:27
  • Unfortunately, it doesn't work. Nothing works but I want the `calculator.py` to open the program in a loop. – Таня Воробець Apr 22 '22 at 08:25
  • The code I've given you will run `calculator.py` when the user inputs `"op"` and wait for that script to run to completion. It will do so repeatedly until the user inputs something other than `"op"` or `"io"`. I'm not sure how to help you further. If you need something else, please edit your question into a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). Then, the community can see exactly what's going wrong and suggest a fix. – thisisrandy Apr 22 '22 at 21:17
0

subprocess.Popen starts the process, but does not wait for its completion. You might use subprocess.run instead.

JojOatXGME
  • 3,023
  • 2
  • 25
  • 41