0

I am working on a uni project. I have already finished writing my code for the program. But there are some modules which I dont think will be on the pc connected to the presenting projector. So I also have to make an installer which will install the necessary modules. This is my code -

#-------------------------------------------------------------------------------
# Name:        DBC Instalations
# Purpose:     Install necesarry components needer for DBC
#
# Author:      MS Productions
# Created:     19/09/2022
# Copyright:   (c) MS Productions 2022
#-------------------------------------------------------------------------------
import time ,sys , subprocess, os
import multiprocessing as mp

def run_cmd(agrs):

    cmd = "pip install "+agrs
    print(agrs)
    print(cmd)
    os.system(cmd)

print("[INFO] Running script -")
print("[INFO] Installing modules :")
start = time.perf_counter()

p1 = mp.Process(target=run_cmd,args="pynput pyautogui datetime selenium openpyxl")
p2 = mp.Process(target=run_cmd,args="tkinter numpy pystray struct Pillow")

if __name__ == '__main__':
    p1.start()
    p2.start()

    p1.join()
    p2.join()

finish = time.perf_counter()
print(f'Finished in {round(finish-start, 2)} second(s)')

But when I run it, It shows this error :

[INFO] Running script -
[INFO] Installing modules :
Process Process-1:
Traceback (most recent call last):
  File "C:\Users\Matt - PC\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 315, in _bootstrap
    self.run()
  File "C:\Users\Matt - PC\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
TypeError: run_cmd() takes 1 positional argument but 43 were given
[INFO] Running script -
[INFO] Installing modules :
Finished in 0.0 second(s)
Process Process-2:
Traceback (most recent call last):
  File "C:\Users\Matt - PC\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 315, in _bootstrap
    self.run()
  File "C:\Users\Matt - PC\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
TypeError: run_cmd() takes 1 positional argument but 35 were given
[INFO] Running script -
[INFO] Installing modules :
Finished in 0.0 second(s)
Finished in 0.04 second(s)

Please provide a solution for the error message, Thank you

MT_276
  • 303
  • 1
  • 2
  • 7
  • 1
    the `args` argument to `Process` is expected to be an iterable of arguments. If you iterate over a string, you get the individual characters. Instead put your string inside another iterable such as a tuple: `args=("mystring", )` – Aaron Sep 19 '22 at 14:59
  • 1
    as a side note, it is not a good idea to run `pip` in parallel, or the library dependency matching could break. – Aaron Sep 19 '22 at 15:00

1 Answers1

-3
from concurrent.futures import ThreadPoolExecutor as TPE
import subprocess, time

print("[INFO] Running script -")
modules_toinstall = ['pynput', 'pyautogui', 'datetime', 'selenium', 'openpyxl', 'tkinter', 'numpy', 'pystray', 'struct', 'Pillow']

def install(module):
    subprocess.check_output(['pip', 'install', module], stderr=subprocess.DEVNULL)
    print(f'[INFO] {module} installed!')

print("[INFO] Installing modules :")
start = time.perf_counter()

with TPE(max_workers=500) as x:
    x.map(install, modules_toinstall)

finish = time.perf_counter()
print(f'Finished in {finish-start:.2f} second(s)')

My code is alot better and faster, Try it. It uses ThreadPoolExecutor as the thread module. Mine only takes 20s

Hope it help.

For mkrieger1, the question is not about asking what was the error about, but the solution.

yrifl
  • 12
  • 2