python sys.argv can't get the argument value? - python

I tried to pass some variables to my python code . the variable is a list, after i run the python script . which is simply just print out sys.argv. the output is following:
:~ xxx$ /var/folders/kg/qxxxxxd343433gq/T/Cleanup\ At\ Startup/pdTry-375321896.860.py.command ; exit;
var1, var2, var1, var2
the len argv is 1
/Users/xxx/python/pdTry.py
Traceback (most recent call last):
File "/Users/xxx/python/pdTry.py", line 58, in <module>
main()
File "/Users/xxx/python/pdTry.py", line 33, in main
print (sys.argv[1])
IndexError: list index out of range
logout
you can see the the list contains var1 and var2 actually print out 2 times. but i can get the value, the len sys.argv is 1. No value for sys.argv[1]. Do anyone know why? Why the length is 1, should it be 2? arg[0] is the script name, and arg[1] is the variable list i passed to it?
The code is simply
def main():
os.system ('osascript up.scpt')
#print (sys.argv)
a= 'the len is '+str(len(sys.argv))
print (a)
print (sys.argv[0])
print (sys.argv[1])

Remember that lists in python start at 0.
List Length : 1 2 3 4
Element number: 0 1 2 3
Data : A B C D
so when you have length 1 you only have 1 element (argv[0]) which means argv[1] doesn't exist.

Dude,
you are reading argv[[1] when your length is 1. How can array of length have two items ( read 0th and 1st item).

It seems you left out any real arguments for the script, which could be added to the sys.argv list. In the call you posted, I see no list of variables passed to the script. If the semicolon separating the commands (the script name and exit shell builtin) was escaped, then most likely you would have len(sys.argv) equal to 3 (but I doubt it was your original intention to have the semicolon and exit as sys.argv values).
# simple test script
$ cat exittest.py
import sys
print(sys.argv, len(sys.argv))
# and some calls
$ python3.2 exittest.py
['exittest.py'] 1
$ python3.2 exittest.py \; exit
['exittest.py', ';', 'exit'] 3
# and for a similar call as you posted I ssh'ed to my localhost
# to test it with exit builtin
$ python3.2 exittest.py ; exit
['exittest.py'] 1

Related

Unexpected Python for-loop behaviour?

Can someone explain what happened in the second run ? Why did I get a stream of 9's when the code should have given an error?
>>> for __ in range(10): #first run
... print(__)
...
0
1
2
3
4
5
6
7
8
9
This was the second run
>>> for __ in range(10): #second run
... print(_)
...
9
9
9
9
9
9
9
9
9
9
>>> exit()
After this, when I ran the code for the third time, the same code executed as expected and gave the below error. I realize that this question has no practical use. But, I would really like to know why it happened?
NameError: name '_' is not defined
The _ variable is set in the Python interpreter, always holding the last non-None result of any expression statement that has been run.
From the Reserved Classifiers and Identifiers reference:
The special identifier _ is used in the interactive interpreter to store the result of the last evaluation; it is stored in the builtins module.
and from sys.displayhook():
If value is not None, this function prints repr(value) to sys.stdout, and saves value in builtins._. [...] sys.displayhook is called on the result of evaluating an expression entered in an interactive Python session.
Here, that result was 9, from an expression you must have run before the code you shared.
The NameError indicates you restarted the Python interpreter and did not yet run an expression statement yet that produced a non-None value:
>>> _
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_' is not defined
>>> 3 * 3
9
>>> _
9

Cannot understand specific Python 3 code

While trying to solve a problem on Hackerank(The Problem). I checked the solutions of people who have solved this problem. Here is the solution from one person-
n = input()
l = []
for _ in range(n):
s = raw_input().split()
cmd = s[0]
args = s[1:]
if cmd !="print":
cmd += "("+ ",".join(args) +")"
eval("l."+cmd)
else:
print l
I cannot understand line 8 and line 9, can someone explain me these lines? Can i write line 8 and line 9 in Python 3 as i'm learning Python 3 ? How ?
Basically, cmd is constructed by appending the command (say "insert"), to the operands. This cmd forms a correct python expression (for example l.insert(0,5), to insert 5 at index 0, in list l).
Here, l. is hardcoded(start of line 9), cmd is initialized in cmd = s[0], and operands are added in line 8.
eval(str) evaluates the command str, in string format, as if it were in a command line.
It would be nice to just include the problem :) . The input is a (text) file as below:
Sample Input 0
12
insert 0 5
insert 1 10
insert 0 6
print
remove 6
append 9
append 1
sort
print
pop
reverse
print
And the expected output for a correct answer is as below:
Sample Output 0
[6, 5, 10]
[1, 5, 9, 10]
[9, 5, 1]
Before looking at the answer you quoted it would be good to read about eval; it takes the argument provided and tries to run it as a python expression using the global and local namespace. So in this case it needs only the local for the "l"-list and "cmd"-tuple.
What is happening is the following:
Empty list l is created.
The "command" (cmd) single-value list is parsed from the line by slicing (cmd = s[0]), since every line starts with or only has a list method
The other arguments are placed in args
Line 8 (as asked): These other arguments are then joined in a string tuple. So "insert 0 5" gives "insert" for l and "(0, 5)" for cmd
Line 8 continued (as asked): cmd is then combined with args using string concatenation (read here for a good and bad example) resulting in "insert(0,5)" as value for cmd
Line 9 (as asked): the eval parameter is yet another string concatenation yielding "l.insert(0,5)" as final expression to be interpreted. Which then inserts integer value 5 on spot 0 in list l (pushing forward any other values already in l)
Hope it helps, keep on trucking!

Truncating Python Command-line Argument

What is the issue truncating sys.argv? Trying to do temp = sys.argv[1, :5]
>> stub.py 123456789
#! /usr/bin/env python
import sys
temp = sys.argv[1]
print temp
print temp[:5]
print sys.argv[1, :5]
That just isn't how to index regular python lists, that is a numpy() slicing convention.
Simply use sys.argv[1][:5] to get your desired result.

List Index out of range in python?

I'm kind of new to python and needed help with this - it says list index out of range?
file=open("Reg_Details.csv","r")
Reg=[line.split(',') for line in file]
file=open("Speed_Exceeded.csv","r")
Speed=[line.split(',') for line in file]
for x in Reg:
for y in Speed:
if x[2]==y[2]:
print("match")
file=open("Details_user.csv","w")
file.write("%s,%s,%s\n" % (x[0],[0],x[1]))
file.close()
(Original screencap)
It means that the list doesn't have an element with the index id you're asking for.
>>> variable = [1,2,3]
>>> variable[2]
3
>>> variable[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
In this example the valid ids are 0, 1 and 2, but 3 is invalid.
When you check
x[2] == y[2]
you're accessing the third element of each of the two lists (0 is the first element). The error you are getting means that either x or y has less than 3 elements, so the element you are asking for is out of range. Most likely Reg_Details.csv or Speed_Exceeded.csv have only 1 or 2 columns.
Also looking at your code, you probably want to replace
file=open("Details_user.csv", "w")
by
file=open("Details_user.csv", "a")
The opening mode "w" puts the writing stream at the beginning of the file, so every time you run this line you are erasing whatever was inside before (meaning each iteration of your loop you are deleting the previous line, and at the end "Details_user.csv" will contain only one line). Using the opening mode "a" (from 'append') opens the file putting the writing stream at the end of the file, so you will append a new line to the file at every iteration.

VIM, Python: how do you use range objects generated by vim.current.range

function! Cut()
python3 << EOF
import vim
cw = vim.current.window
pos = cw.cursor
cr = vim.current.range
x = cr.end - cr.start
vim.command('y')
vim.command(':normal! gv')
print(cr)
print(cr.start)
print(x)
while x:
vim.command('d')
x -= 1
EOF
endfunction
I get:
<range ... (10:10)>
9
0
<range ... (11:11)>
10
0
so on..
Why am i getting multiple print calls - 1 call per line selected?Shouldn't the range object give you the range of lines selected - it's not doing this, instead it's iterating my lines and setting start=current_line_number?
if you want to handle range by yourself in your function, you should add range argument when you declare/define your function. :h function-range-example, then you can in your function get the range information bya:firstline and a:lastline. For example:
function Foo() range
let start = a:firstline
...
endfunction
In this way, you pass the range once to your function. However if you do, as what you did:
function Foo()
echo "foo"
endfunction
then do a 1,10call Foo() , you will see that 10 foo would be printed(echoed). And yes, for each line, your function was invoked.
It is the basic rule, no matter you implement in python or vimscript.

Categories

Resources