sys.argv : list indedx out of range - python

part of script
if sys.argv[1] == 'help':
help()
elif len(sys.argv) < 5:
use()
else:
pass
host = sys.argv[1]
username = sys.argv[2]
password = sys.argv[3]
node = sys.argv[4]
opts = sys.argv[5]
this is just part of code where problem is occuring.. when i run it , error occured :
host = sys.argv[1]
IndexError: list index out of range
All were working well, but i just reinstalled python. But, now it is creating problem. This is well working in linux still.
" Through some search, i came to know that '.py association in the registry is incorrect. It's missing %* at the end.' but, i don't know how to fix it.
Current setup path in environment variable is C:\Python27;C:\Python27\Lib\site-packages\;C:
\Python27\Scripts\

sys.argv is a list like any other, except that it's created from the command line.
It has as many items as are indicated by the command line you use to run the script.
The code was never correct and the problem is nothing to do with your Python file associations or your path. (If it were, you'd be getting an error from the command line, but instead you are getting an error that comes from Python.)
The problem is that you assume there will be a sys.argv[1], by checking for 'help' before any check on the length of sys.argv. If the script is run with no arguments at all, then that [1] index is out of range.

Related

Checking whether a sys.argv path exists

I am currently facing a problem in which I run a python script via cmd in which I set some of the arguments required for functions on that script also in cmd. So, I have been using sys.argv. To better explain, I would type the following:
python script.py arg.yaml C:\Users\JohnDoe\Documents
So, the sys.argv are the a yaml file and the second one a path. Please note that the second one is a optional argument, so the user might not choose to add that. My goal is to raise an error if the given path doesn't exist.
I have been try the following:
try:
export_path = sys.argv[2]
if len(sys.argv) == 3:
try:
Path('export_path').is_dir()
except FileNotFoundError:
print(custom_message_error)
except IndexError:
export_path = None
But the program is still proceeding and I am not been able to catch the error. So, how would be possible to check whether or not the sys.argv path folder exists.
I think you confused some concepts here. pathlib.Path.is_dir does not throw an exception if the directory was not found but simply returns False. Moreover, you should not put your variable export_path in quotes when passing it to Path:
from pathlib import Path
export_path = "C:\Users\JohnDoe\Documents"
if Path(export_path).is_dir():
print("Path exists!")
else:
print("Path does not exist")

Script Parameters with PyCharm - Learn Python the Hard way

I started to learn Python with learn Python the Hard Way and I am facing some issues with ex13. I would like to now if it is a mistake of mine or because of the way PyCharm works.
Basically to make the script work as the exercise suggests I saw I have to manually enter the parameters names in PyCharm with run>edit configuration
I put "first" "second" and "third"
But I would like to combine raw_input and argv so I can let the user choose the name of the parameters. Here's what I wrote:
from sys import argv
first = raw_input("First argument: ")
second = raw_input("Second argument: ")
third = raw_input("Third argument: ")
script, first, second, third = argv
print "The script is called:", script
print "Your first variable is:", first
print "Your second variable is:", second
print "Your third variable is:", third
It runs but it returns:
ValueError: need more than 1 value to unpack
It seems that in PyCharm I have to enter manually all the script parameters ? There is no way to combine it with raw input ?
Thanks for your help.
note check out Joran's answer which shows a good combination of using command line args and prompting for user inputs. Below is a break down of what is going on:
This is expected behaviour in PyCharm to specify the parameters you want PyCharm to execute your script with. Think of it like PyCharm doing something like this:
python my_script.py
However, PyCharm does not know the arguments you want to pass, you need to provide this, so it knows how to run your script. If you look near the bottom of your PyCharm window, there is a Terminal tab. You can use that to quickly execute your script and provide args.
Secondly, the reason why you are getting the error you are getting is because you are not handling your script inputs properly when trying to use argv.
You are mixing up using raw_input, which takes in user input when your Python script is running, as opposed to argv which takes parameters in to your Python script when you run it.
So, what you are looking to actually do here, is not use raw_input, but simply argv. Here is a small demo to clarify all this:
from sys import argv
script, first, second, third = argv
print "The script is called:", script
print "Your first variable is:", first
print "Your second variable is:", second
print "Your third variable is:", third
Now, go in to your command prompt and do this:
python my_script one two three
You will get:
The script is called: my_script.py
Your first variable is: one
Your second variable is: two
Your third variable is: three
This is a very simplified example, and you're probably going to need to add some handling of your inputs, or you're going to get a lot of errors with different inputs to your script. With that, I suggest maybe looking at argparse instead
Im not sure i understand the question ... but the code below will use the command line arguments if there are 3(or more) ... otherwise it will prompt and split the same way as the shell splits command line arguments
import shlex # shlex.split will split the string the same way that the shell would for command line args
if len(sys.argv) < 3:
args = (list(sys.argv) + shlex.split(raw_input("Enter Args:")))[:3]
else:
args = sys.argv[:3]
print "Using Args:",args
one,two,three = args

ImageMagick Conversion from .ps to .png, run from python - invalid param

I have been looking through some similar posts and through the ImageMagick page, but I cannot seem to find a reason for my issue:
Note I am using a windows machine.
I have a .ps image in a folder and it works when running with the command to convert it from the cmd: convert saved.ps newsaved.png
However when I try to execute it from my python script with the following code:
args = ["convert","saved.ps newsave.png"]
subprocess.Popen(args)
#or this call(args)
os.system("start newsave.png")
The cmd window says that newsave.png is an invalid parameter. (The error message being: Invalid parameter - newsave.png in the cmd window, which then closes instantly)
Having the everything seperated by a comma in args has also not helped. os.getcwd() returns the current work directory as well, so I know I'm in the right dir. The error happens when the subprocess is called.
Make each command-line argument a separate element of args. Also, use subprocess.call to ensure that the convert function has completed before you call os.system("start newsave.png"):
args = ["convert", "saved.ps", "newsave.png"]
rc = subprocess.call(args)
if rc != 0:
print "rc =", rc
In the end I had to add shell=True in order for the conversion to work properly.
args = ["convert", "saved.ps", "newsave.png"]
subprocess.call(args, shell=True)
Thanks to Warren for the help.

Command-line input

I need to write a complete program that obtains three pieces of data and then process them. The three pieces of information are a Boolean value, a string, and an integer. The logic of the program is this: if the Boolean value is True, print out the string twice, once with double quotes and once without - otherwise print out twice the number. Which I can do just fine, but then I have to write the same program but this time using command-line input, the program below is what I have so far but i keep getting a command not found error.I feel like my "for i in range" is the error
import sys
def main():
x = sys.argv[0].lower() == 'true'
y = str(sys.argv[1])
z = int(sys.argv[2])
for i in range(0,len(sys.argv),1):
print(" ",i,":",sys.argv[i])
return 0;
"Command not found" is the shell response when a file is not in the $PATH or it was never made executable. First make sure that it is executable with
chmod +x myfile.py
second make sure that it is in your path with
which myfile.py
If it is not in your path, you need to execute it with an explicit path such as './myfile.py'
If it is not executable and you do not change it to executable you need to use
python [full path or .]/myfile.py
In your comment, you say that you execute it with "python3" doublecheck that it is the correct call for your system.
I almost forgot to add that the first line in your script needs to be
#!/usr/bin/python
or whatever python points to in your system
def main():
x = sys.argv[1].lower() == 'true'
y = str(sys.argv[2])
z = int(sys.argv[3])
if x:
print "'{}'".format(y)
print '"{}"'.format(y)
else:
print 2*z
return 0;
if __name__ == '__main__':
main()
save this as myfile.py
then from the shell run: chmod +x myfile.py && python myfile.py

I'd like my code to flow with my terminal a little better

So I have a fully functional py script running on Ubuntu 12.04, everything works great. Except I don't like my input methods, it's getting annoying as you'll see below. Before I type out the code, I should say that the code takes two images in a .img format and then does computations on them. Here's what I have:
import os
first = raw_input("Full path to first .img file: ")
second = raw_input("Full path to second .img file: ")
print " "
if os.path.exists(first) == True:
if first.endswith('.img') == False:
print 'You did not give a .img file, try running again'
os.sys.exit()
elif os.path.exists(second) == True:
if second.endswith('.img') == False:
print 'You did not give a .img file, try running again'
os.sys.exit()
else:
print "Your path does not exist, probably a typo. Try again"
os.sys.exit()
Here's what I want; I want to be able to feed python this input straight from the Terminal. In other words, I want to be able to input in the terminal something like
python myscript.py with the two images as input
This way I could make use of the terminal's tab-key shortcut when specifying paths and stuff. Any ideas/suggestions?
EDIT: Ok so I looked into the parsing, and I think I got down how to use it. Here's my code:
import argparse
import nipy
parser = argparse.ArgumentParser()
parser.add_argument("-im", "--image_input", help = "Feed the program an image", type = nipy.core.image.image.Image, nargs = 2)
however now I want to be able to use these files in the script by saying something like first = parser[0] second = parse[1] and do stuff on first and second. Is this achievable?
You want to parse the command line arguments instead of reading input after the program starts.
Use the argparse module for that, or parse sys.argv yourself.
Seeing that the parsing code already exists, all you need to do is accept command-line arguments with Python's sys module:
import sys
first = sys.argv[1]
second = sys.argv[2]
Or, more generally:
import os
import sys
if __name__ == '__main__':
if len(sys.argv) < 2:
print('USAGE: python %s [image-paths]' % sys.argv[0])
sys.exit(1)
image_paths = sys.argv[1:]
for image_path in image_paths:
if not os.path.exists(image_path):
print('Your path does not exist, probably a typo. Try again.')
sys.exit(1)
if image_path.endswith('.img'):
print('You did not give a .img file, try running again.')
sys.exit(1)
NOTES
The first part of the answer gives you what you need to accept command-line arguments. The second part introduces a few useful concepts for dealing with them:
When running a python file as a script, the global variable __name__ is set to '__main__'. If you use the if __name__ == '__main__' clause, you can either run the python file as a script (in which case the clause executes) or import it as a module (in which case it does not). You can read more about it here.
It is customary to print a usage message and exit if the script invocation was wrong.
The variable sys.argv is set to a list of the command-line arguments, and its first item is always the script path, so len(sys.argv) < 2 means no arguments were passed. If you want exactly two arguments, you can use len(sys.argv) != 3 instead.
sys.argv[1:] contains the actual command-line arguments. If you want exactly two arguments, you can reference them via sys.argv[1] and sys.argv[2] instead.
Please don't use if os.path.exists(...)==True and if string.endswith(...)==True syntax. It is much clearer and much more Pythonic to write if os.path.exists and if string.endswith(...) instead.
Using exit() without an argument defaults to exit(0), which means the program terminated successfully. If you are exiting with an error message, you should use exit(1) (or some other non-zero value...) instead.
What you want to do is take in command line parameters, and the best way to do that is using a nifty module called argparse. I have listed below a good resource on how to install and use it.
Here is a great resource for argparse. It is a module used to take command line arguments.
You can probably use sys.argv:
import sys
first = sys.argv[1]
second = sys.argv[2]
Don't forget to check len(sys.argv) before.

Categories