0

I'm working in a small code to receive multiple arguments from an MQTT server and use them to predict another value. I'm showing a simplified code here just to get some help. To pass the arguments to the script for executing the prediction, first part is the creation of a numpy array, then pass the arguments to the script using sys.argv[], then the indexing to position the incoming values.

import numpy as np
import sys

    # creating empty numpy array for feature values
X = np.empty(2).reshape(1, 2)

    #storing the arguments
azimuth_sin=sys.argv[1]
azimuth_cos=sys.argv[2]

    #displaying the arguments
print("azimuth_sin : " + azimuth_sin)
print("azimuth_cos : " + azimuth_cos)
print("Number of arguments : ", len(sys.argv))
   
    # set vector values
X[:,0] = sys.argv[1]
X[:,1] = sys.argv[2]

print(X)

However, I have an issue with the second argument as I get an error:

exit code: 1, Traceback (most recent call last): File "numpy-array.py", line 10, in azimuth_cos=sys.argv[2] IndexError: list index out of range

The only way to avoid that error is if I set both arguments to: sys.arg[1]

   #storing the arguments
azimuth_sin=sys.argv[1]
azimuth_cos=sys.argv[1]

   #displaying the arguments
print("azimuth_sin : " + azimuth_sin)
print("azimuth_cos : " + azimuth_cos)
print("Number of arguments : ", len(sys.argv))
   
   # set vector values
X[:,0] = sys.argv[1]
X[:,1] = sys.argv[1]

print(X)

Then I get two consecutive outputs:

azimuth_sin : -0.9152180545267792 azimuth_cos : -0.9152180545267792 Number of arguments : 2 [[-0.91521805 -0.91521805]]

and:

azimuth_sin : 0.40295894662883136 azimuth_cos : 0.40295894662883136 Number of arguments : 2 [[0.40295895 0.40295895]]

which are actually the values of the two arguments printed, but repeated twice: sin = -0.9152180545267792 and cos = 0.40295894662883136

If I put the arguments in one line:

   #storing the arguments
azimuth_sin, azimuth_cos = sys.argv[1:2] 

The error is:

exit code: 1, Traceback (most recent call last): File "numpy-array-t1.py", line 10, in azimuth_sin, azimuth_cos = sys.argv[1:2] ValueError: not enough values to unpack (expected 2, got 1)

I've tried many ways to fix this without success, I'd appreciate any help or suggestions. Thank you in advance.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
miinch
  • 11
  • 1
  • 5
  • 1
    `sys.argv` contains strings. You need to convert them to float to store them in the array. – Barmar Jan 17 '22 at 21:22
  • 1
    Please post how you ran the program. – Red Jan 17 '22 at 21:43
  • 1
    if `sys.argv[2]` is out of range, then you didn't pass two arguments to your program... – John Gordon Jan 17 '22 at 21:48
  • We tried in your previous question to figure out how you called your script, but you don't seem to understand what sets the ``sys.argv` values. Where does this `-0.9152180545267792` come from? – hpaulj Jan 17 '22 at 23:32
  • What's this `MQTT server`? – hpaulj Jan 17 '22 at 23:35
  • @Barmar I used this to try to correct that: "azimuth_cos=float(sys.argv[2])", but still got "IndexError: list index out of range". John Gordon, apparently not even argument[1] is stored, trying to figure it out why as I'm doing it as explained in the web. hjpaulj That's the value of one of the arguments in the script, obtained from azimuth (sun position), but is printed twice. The MQTT retrieves sensor data from equipment. Thanks to all for your comments. – miinch Jan 18 '22 at 19:23
  • Show how you're running the script. It needs to be `python yourscript.py azimuth_sin azimuth_cos` – Barmar Jan 18 '22 at 19:25

2 Answers2

0

Start with something simple to validate the data you are receiving.

Do something like:

import sys  
  
# Verify first so you don't get an error  
# This check verifies we have at least two parameters
if 1 < len(sys.argv):
    if sys.argv[1]:
        var_argv1 = sys.argv[1]
        print("var_argv1 type: %s, length: %s" % (type(var_argv1), len(var_argv1)))

        # It is pointless to continue if argv[1] has no data
        if sys.argv[2]:
            var_argv2 = sys.argv[2]
            print("var_argv2 type: %s, length: %s" % (type(var_argv2), len(var_argv2)))
        else:
            print("sys.argv[2] has no data")
    else:
        print("sys.argv[1] has no data")

It may be that you are trying to process a numpy object on the command line

Note:
Do you have access to the MQTT server?
It might be easier to pick a channel (topic) to use for this data transfer.
You could get the MQTT server to publish this data on a channel and have this script subscribe to that channel.
Then you could make sending information as easy as a function call on your MQTT system.

  • Hi, thank you so much for your help! When trying your suggestion I get this: "sys.argv[1] has no data", so it seems to be a big problem since I cannot even store the data as a fisrt step. I'm getting the data from the MQTT channel in node-red, then reusing it for this script using a node called pythonshell, I'm trying to do it as suggested here, without much success: https://discourse.nodered.org/t/passing-parameter-from-node-red-to-python/10340/3 – miinch Jan 18 '22 at 10:18
0

In Linux terminal window, I have a simple script that just displays sys.argv:

1619:~$ cd mypy
1619:~/mypy$ cat echo.py
import sys
print(sys.argv)

When I call it thus:

1619:~/mypy$ python3 echo.py 1.23 3.112 foo bar
['echo.py', '1.23', '3.112', 'foo', 'bar']

See that sys.argv is list of 5 strings, which come from the commandline.

If you are calling your script from a shell or windows command window, you should be able to enter and see multiple strings.

But people have problems using sys.argv (and argparse) when running the script from something like pydev or as a Jupyter notebook. I don't know anything about the MQTT server so can't help with providing even one command line argument. As I demonstrate, sys.argv is primarily intended as a way of providing startup values and options when running a script from the operating system.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Thanks for your help! When doing your suggestion cat script.py I get the script displayed, but also [''] which I guess indicates that I have no arguments stored. I should have mentioned that I'm doing this in node-red, just the way as it is suggested in this link: https://discourse.nodered.org/t/passing-parameter-from-node-red-to-python/10340/3. The script is longer, I had to split it in different parts, to get the errors and move fwd. This script was made by someone else about a year ago, my task is to run it in node-red, I guess the issue is actually translate it into the tool. – miinch Jan 18 '22 at 09:53