2

I'm new user of stackoverflow, besides I'm not an English guy, so I'm sorry for my english.

I was programming in python 'til I got a mistake tho I'm not able to figure out what's wrong...

#!/usr/bin/env python2.7 from random import choice import sys def help(): print ("Please, you need to introduce a Int in this way: PWrand 10") def PWrand(insert_by_user): chars = 'ABCDEFGHIJKLMNOPQRSTUWXYZabcdefghijklmnopqrstuwxyz0123456789!-_:.,;&)(' for password in range(insert_by_user): sys.stdout.write(choice(chars)) #Command Line if __name__ == '__main__': if len(sys.argv) < 2 or len(sys.argv) > 2: help() elif (type(sys.argv[2]) != int): print("It need to be an Int!") else: insert_by_user = (sys.argv[2]) print(PWrand(insert_by_user)) 

So, this is what I take.

Traceback (most recent call last): File "./passwordrandom.py", line 24, in <module> elif (type(sys.argv[2]) != int): IndexError: list index out of range 

Thank you all!

5
  • 3
    Numbering of list elements starts with 0, so for a list with two elements the elements have which numbers? Commented Dec 6, 2017 at 0:06
  • Oh... I thought it started in '2' 'cause it's the second argument you know? like, first one the python name, and second one the argument. Now I see, tho I found another issue, I can't read that like a int Commented Dec 6, 2017 at 0:09
  • If a list has two items, the first is item 0 and the second is item 1. There is no item 2, and trying to access one is an error. Commented Dec 6, 2017 at 0:09
  • 2
    it won't be an int, it will be a string. use insert_by_user = int(sys.argv[1]) and of course, if it is not the string representation of an int, like "b", be ready to catch that ValueError exception. Commented Dec 6, 2017 at 0:12
  • What is confusing to new programmers is using length on a sequence e.g. len(sys.arg) which in your testing will return 2, and an index on the sequence like sys.argv[2] which will give you the #3 item. There's some good reasons for zero-based indexing but mostly it causes confusion. Also, in your question you should show how you are calling the python script with your args to make it clear that you test with 2 args. Commented Dec 6, 2017 at 0:17

2 Answers 2

1

You have two issues here. The first is that you're a little confused about list indexes. Lists in python are "zero-indexed" meaning that to get the first element of a list named L you need to do L[0]. Similarly, to get the second, like you need, you do L[1].

The other issue is that all elements from sys.argv are going to be strings, so checking the type won't work. You should try to cast the piece of user input as an int inside a try block and catch a ValueError. It'd look something like this:

if __name__ == '__main__': if len(sys.argv) < 2 or len(sys.argv) > 2: help() else: try: insert_by_user = int(sys.argv[1]) print(PWrand(insert_by_user)) except ValueError: print("It need to be an Int!") 

The code inside the except ValueError: block will only be executed if the user's input cannot be properly cast to an integer.

Sign up to request clarification or add additional context in comments.

1 Comment

Ohh, I see, now it makes sense! Thank you a lot!
1

It's because the first if catch every list that has less than 2 elements or everything that has more than 2 elements, so the elif is catching everything that has exactly 2 elements, which will be stored in the position 0 and 1.

if len(sys.argv) is not 2: help() else: user_input = sys.argv[1].decode() if not user_input.isnumeric(): print("It need to be an Int!") else: user_input = int(user_input) 

should fix it.

6 Comments

The sentence "is not" was so helpful, also makes sense xD! Thank you!
Awesome, glad it could help. also notes that type() returns elements in the form of <type 'type_of_element'> but it's the say that the types return. E.g: if you type "int" in the python interpreter it returns <type 'int'> that's the pythonic way to check for a type of an object, variable, etc..
You should note that the elif branch can never return true. The argv list elements will always be strings and you should test its intness by attempting a conversion to int and taking the throwing of an exception as a sign it failed.
@PaulRooney check it now ;)
Its ok you needn't correct it. It's not part of the answer after all. Although I don't think you need the decode part. Its a string and you normally call decode on a bytes object.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.