-1

I get this error when calling my python script from command line, passing in an input string (parameter 1) and a blank string (parameter 2) that will store my output from parsing this input string in my module

C:\Windows\system32>set project_name=

C:\Windows\system32>echo "%project_name%" " "

C:\Windows\system32>"C:\Python27\python" "C:\IR125422\GetProject1.py" "#p=/Product Delivery/Product Delivery.pj#s=Team P rojects/Team Projects.pj#s=Platform Pack/Platform Pack.pj#s=Runtime/Runtime.pj"   project_name

Traceback (most recent call last):   File "C:\IR125422\GetProject1.py", line 5, in <module>
    startpos = rindex("/",stext) NameError: name 'rindex' is not defined

My python program takes the string staring with "#p" and locates the last substring "/" in the string, then copies into the string project_name the remainder of this string from the last "/" to the end of the string. So after the program is run project_mane should contain "runtime.pj"

Here is the program

import os, sys
stext = sys.argv[1]
rtext =  sys.argv[2]
startpos = rindex("/",stext)
rtext = stext(startpos+1,len(rtext))
print "Extracting project"
print rtext;

However it seems that the string method rindex is not recognised. Do I need to add a module to my "Import" section? I thought that this was not required for string handling in python as it is intrinsic to python

Two-Bit Alchemist
  • 17,966
  • 6
  • 47
  • 82
Sproggit
  • 71
  • 1
  • 7
  • "Parameter 2 will store my output from parsing this input string in my module." What exactly are you going to pass in there, a suggested memory location? This is neither required nor does it make any sense in the context of Python. (Or really any program accepting command-line arguments.) – Two-Bit Alchemist Dec 09 '15 at 14:25

1 Answers1

1

rindex is not available as a global function, but rather as a method of the str class. The usage is str.index(self, sub[, start[, end]]). So if you replace the line:

startpos = rindex("/",stext)

with either of the following two:

startpos = str.rindex(stext, "/")
startpos = stext.rindex("/")

the line in question should work.

Note however that the following line also contains an error:

rtext = stext(startpos+1,len(rtext))

As it is currently, you would be calling stext as if it were a function, rather than indexing it as an iterable. Try the following instead:

rtext = stext[startpos+1:]

This will result in a "slice" of the original string, starting at startpos+1 and ending at the end of the string. So your complete code, without further modification would be:

import os, sys
stext = sys.argv[1]
rtext =  sys.argv[2]
startpos = stext.rindex("/") # This line changed
rtext = stext[startpos+1:]   # This line changed
print "Extracting project"
print rtext;

Giving the output:

Extracting project
Runtime.pj

Edited to add:

As suggested by Two-Bit Alchemist, your code can also be cleaned up a bit. The initial assignment to rtext does nothing and can be omitted. The print statements can be combined by adding a newline inside the string and using format, or if you want to somehow capture and use the output in DOS or PowerShell you might even want to omit the first print statement altogether. This may also be a good moment to make the print statements Python3-friendly by adding parentheses. Additionally, Two-Bit Alchemist suggested to calculate rtext more directly:

rtext = stext.split('/')[-1]

Which splits the string into a list at each '/' and then takes the last element, corresponding to the string portion after the final '/' just like the current solution. Finally, the os import is unused and the semicolon after the second print statement is superfluous, therefore both can be omitted. The cleaned up code would be:

import sys
stext = sys.argv[1]
rtext = stext.split('/')[-1]
print(rtext)

Or even more compact:

import sys
print(sys.argv[1].split('/')[-1])
Community
  • 1
  • 1
  • 1
    If this is the intent of the OP's code (admittedly, I can't tell), then why bother calculating the string indices yourself? `stext.split('/')[-1]` will do just fine. Likewise, what is `sys.argv[2]` even for here? It's stored briefly in `rtext` then just immediately overwritten and discarded. – Two-Bit Alchemist Dec 09 '15 at 14:22
  • 1
    There is also `from string import rindex`. – Kijewski Dec 09 '15 at 14:26
  • 1
    Just to be clear, I'd like to explicitly push back on this idea behind your answer and, I think, Kay's comment. Sometimes OP's who are new at programming try very strange things that don't actually make much sense from the perspective of experience. Just because someone tried it in their question does _not_ mean we should bring it into answers. Look for the intent of what they're doing and suggest _good programming_. Would you really write a program like this, with the same intent they had? If not, why does it appear in answers and comments this way? – Two-Bit Alchemist Dec 09 '15 at 14:28
  • @Kay That is indeed also a possibility, I was unaware of the existence of the `string` module so I guess I learned something here too. That would actually be closer to the OP's original code than my solution, perhaps you could post it as a separate solution? – Zeust the Unoobian Dec 09 '15 at 14:33
  • 1
    @ZeusttheUnoobian, the function was actually removed in Python3, because it is essentially the same as `rindex = str.rindex`. I only meant my comment as a "nice to know", but I would not actually advice one to use it. Also in OPs question the parameters are flipped. I think your question is OK as it is, but with a few more links (e.g. [slicing](http://stackoverflow.com/q/509211/416224)) it would be a good question. :) – Kijewski Dec 09 '15 at 14:40
  • @Two-BitAlchemist I tried to come up with a working solution as close to the OP's original code as possible (though Kay found an even closer but deprecated solution), but indeed there is something to be said for what you say and fixing bad coding practices unrelated to the original question as well. I will edit my answer to provide a cleaned up version of the code as well. – Zeust the Unoobian Dec 09 '15 at 14:41
  • I edited the answer with a cleaner version of the code. Also added a link to the explanation of slicing as provided by @Kay, should I credit him in the answer for providing me with this link or should I leave it as it is? – Zeust the Unoobian Dec 09 '15 at 15:03
  • Hi everyone. Many thanks for your suggestions and apologies for my rudimentary errors as I am new to python. WRT the question "Likewise, what is sys.argv[2] even for here? It's stored briefly in rtext then just immediately overwritten and discarded". This sys_argv2 was meant to return the extracted substring "project.pj" to the calling batch file. The sequence was as follows – Sproggit Dec 16 '15 at 12:26
  • set project_name =" " "C:\Program Files\Python25\python" GetProject.py "#p=/Product Delivery/Product Delivery.pj#s=Team Projects/Team Projects.pj#s=Platform Pack/Platform Pack.pj#s=GERAN SAT(H)/project.pj" %project_name% so sys_argv1 is the full string, sys_argv2 should return the extracted substring containing the "project.pj" in the DOS variable %project_name% . – Sproggit Dec 16 '15 at 12:51
  • However I'm not sure what the scope of the sys_agv2 parameter would be - not sure if this is writeable and whether it could be passed back to the calling batch file in a DOS system variable. Will check this now – Sproggit Dec 16 '15 at 12:52