What is the best way to print the usage string ?

L

Leonel Gayard

Hi all,

I had to write a small script, and I did it in python instead of
shell-script. My script takes some arguments from the command line,
like this.

import sys
args = sys.argv[1:]
if args == []:
print """Concat: concatenates the arguments with a colon :)) between them
Usage: concat arg1 [arg2...]
Example: concat a b c prints \"a.jar:b.jar:c/\""""
sys.exit(1)
print reduce(lambda x, y: x + ':' + y, sys.argv[1:])

Notice that the string messes the indentation in my script. The
indentation is correct, and if the script is invoked without
arguments, the usage string is printed correctly.

Now, how can I achieve the same result while keeping a clean
indentation ? How is this done in python world ? In C, I would do
this:

;; This buffer is for notes you don't want to save, and for Lisp evaluation.
;; If you want to create a file, visit that file with C-x C-f,
;; then enter the text in that file's own buffer.

if (argc < N) {
printf("Usage: blah blah blah\n"
"Some more lines in the usage text\n"
"Some more lines here too\n");
exit(1);
}

The whitespace at the beginning of the string helps me keep the
indentation clean, and the construct "a" "b" is syntactic sugar that
allows me to create a large string without concatenating them at
runtime.

How can I get this in Python ?

[]'s
Leonel
 
B

BartlebyScrivener

Leonel said:
Notice that the string messes the indentation in my script. The
indentation is correct, and if the script is invoked without
arguments, the usage string is printed correctly.

Now, how can I achieve the same result while keeping a clean
indentation ? How is this done in python world ? In C, I would do
this:
The whitespace at the beginning of the string helps me keep the
indentation clean, and the construct "a" "b" is syntactic sugar that
allows me to create a large string without concatenating them at
runtime.

How can I get this in Python ?

Not sure exactly what you are after, but it sounds like you need the
textwrap module:

http://docs.python.org/lib/module-textwrap.html

Or look at string formatting opeartions

http://docs.python.org/lib/typesseq-strings.html

rd

:
 
P

Peter Otten

Leonel said:
Notice that the string messes the indentation in my script. The
indentation is correct, and if the script is invoked without
arguments, the usage string is printed correctly.

Now, how can I achieve the same result while keeping a clean
indentation ? How is this done in python world ? In C, I would do
this:

;; This buffer is for notes you don't want to save, and for Lisp
evaluation. ;; If you want to create a file, visit that file with C-x C-f,
;; then enter the text in that file's own buffer.

if (argc < N) {
printf("Usage: blah blah blah\n"
"Some more lines in the usage text\n"
"Some more lines here too\n");
exit(1);
}

The whitespace at the beginning of the string helps me keep the
indentation clean, and the construct "a" "b" is syntactic sugar that
allows me to create a large string without concatenating them at
runtime.

How can I get this in Python ?
.... "Personally, though,\n"
.... "I wouldn't bother.")
You can do that in Python too.
Personally, though,
I wouldn't bother.

Like in C, you get a single string:
'ab'

The parentheses are just there to allow you to spread that string over
multiple lines.

Peter
 
S

Simon Forman

Leonel said:
Hi all,

I had to write a small script, and I did it in python instead of
shell-script. My script takes some arguments from the command line,
like this.

import sys
args = sys.argv[1:]
if args == []:
print """Concat: concatenates the arguments with a colon :)) between them
Usage: concat arg1 [arg2...]
Example: concat a b c prints \"a.jar:b.jar:c/\""""
sys.exit(1)
print reduce(lambda x, y: x + ':' + y, sys.argv[1:])

Notice that the string messes the indentation in my script. The
indentation is correct, and if the script is invoked without
arguments, the usage string is printed correctly.

Now, how can I achieve the same result while keeping a clean
indentation ? How is this done in python world ? In C, I would do
this:

;; This buffer is for notes you don't want to save, and for Lisp evaluation.
;; If you want to create a file, visit that file with C-x C-f,
;; then enter the text in that file's own buffer.

if (argc < N) {
printf("Usage: blah blah blah\n"
"Some more lines in the usage text\n"
"Some more lines here too\n");
exit(1);
}

The whitespace at the beginning of the string helps me keep the
indentation clean, and the construct "a" "b" is syntactic sugar that
allows me to create a large string without concatenating them at
runtime.

How can I get this in Python ?

[]'s
Leonel

Python also concatenates adjacent strings, but the "real" newlines
between your strings will need to be escaped (otherwise, because the
newlines are statement separators, you will have one print statement
followed by string literals with the wrong indentation.)

print "Usage: blah blah blah\n" \
"Some more lines in the usage text\n" \
"Some more lines here too."

(Note that the final string literal newline is not needed since print
will add one of it's own.)

HTH,
~Simon
 
B

Bruno Desthuilliers

Leonel said:
Hi all,

I had to write a small script, and I did it in python instead of
shell-script. My script takes some arguments from the command line,
like this.

import sys
args = sys.argv[1:]
if args == []:
print """Concat: concatenates the arguments with a colon :)) between
them
Usage: concat arg1 [arg2...]
Example: concat a b c prints \"a.jar:b.jar:c/\""""
sys.exit(1)
print reduce(lambda x, y: x + ':' + y, sys.argv[1:])

Notice that the string messes the indentation in my script. The
indentation is correct, and if the script is invoked without
arguments, the usage string is printed correctly.

Now, how can I achieve the same result while keeping a clean
indentation ? How is this done in python world ? In C, I would do
this:

;; This buffer is for notes you don't want to save, and for Lisp
evaluation.
;; If you want to create a file, visit that file with C-x C-f,
;; then enter the text in that file's own buffer.

if (argc < N) {
printf("Usage: blah blah blah\n"
"Some more lines in the usage text\n"
"Some more lines here too\n");
exit(1);
}

The whitespace at the beginning of the string helps me keep the
indentation clean, and the construct "a" "b" is syntactic sugar that
allows me to create a large string without concatenating them at
runtime.

How can I get this in Python ?

Quite close:
.... print "line 1\n" \
.... "line 2\n" \
.... "line 3\n" \
....
....
line 1
line 2
line 3

But this is somehow ugly... the textwrapper module may be a better
solution. Or if you don't plan on making the script a module, you could
use the docstring:

bruno@bousin ~ $ cat ~/playground/concat.py
# !/usr/bin/python
"""
Concat: concatenates the arguments with a colon :)) between
them
Usage: concat arg1 [arg2...]
Example: concat a b c prints \"a:b:c/\
"""

import sys
args = sys.argv[1:]
if not args:
sys.exit(globals()['__doc__'].strip())
print reduce(lambda x, y: x + ':' + y, args)

bruno@bousin ~ $ python ~/playground/concat.py
Concat: concatenates the arguments with a colon :)) between
them
Usage: concat arg1 [arg2...]
Example: concat a b c prints "a:b:c/
bruno@bousin ~ $ python ~/playground/concat.py a b c
a:b:c
bruno@bousin ~ $
 
S

Steven Bethard

Leonel said:
Hi all,

I had to write a small script, and I did it in python instead of
shell-script. My script takes some arguments from the command line,
like this.

import sys
args = sys.argv[1:]
if args == []:
print """Concat: concatenates the arguments with a colon :)) between
them
Usage: concat arg1 [arg2...]
Example: concat a b c prints \"a.jar:b.jar:c/\""""
sys.exit(1)
print reduce(lambda x, y: x + ':' + y, sys.argv[1:])

The short answer is to use textwrap.dedent::
.... print textwrap.dedent('''\
.... Concat: concatenates the arguments with a colon :)) between
.... them
.... Usage: concat arg1 [arg2...]
.... Example: concat a b c prints "a.jar:b.jar:c/"''')
....
Concat: concatenates the arguments with a colon :)) between
them
Usage: concat arg1 [arg2...]
Example: concat a b c prints "a.jar:b.jar:c/"


You also might consider using an argument parsing like argparse[1] to
build your usage string for you:

------------------------------ concat.py ------------------------------
import argparse

if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='concatenates the arguments with a colon :)) '
'between them')
parser.add_argument('args', metavar='arg', nargs='+',
help='one item to be concatenated')
namespace = parser.parse_args()
print ':'.join(namespace.args)
-----------------------------------------------------------------------


$ concat.py
usage: concat.py [-h] arg [arg ...]
concat.py: error: too few arguments

$ concat.py -h
usage: concat.py [-h] arg [arg ...]

concatenates the arguments with a colon :)) between them

positional arguments:
arg one item to be concatenated

optional arguments:
-h, --help show this help message and exit

$ concat.py a b c


Steve

[1] http://argparse.python-hosting.com/
 
S

Sion Arrowsmith

There's been a good lot of response to the problem originally stated,
but no-one's pointed out that:
print reduce(lambda x, y: x + ':' + y, sys.argv[1:])

is a confusing (and slow) way of writing:

print ':'.join(sys.argv[1:])
 
T

Tony Nelson

"Simon Forman said:
Python also concatenates adjacent strings, but the "real" newlines
between your strings will need to be escaped (otherwise, because the
newlines are statement separators, you will have one print statement
followed by string literals with the wrong indentation.)

print "Usage: blah blah blah\n" \
"Some more lines in the usage text\n" \
"Some more lines here too."

(Note that the final string literal newline is not needed since print
will add one of it's own.)

One can also use parentheses:

print ( "Usage: blah blah blah\n"
"Some more lines in the usage text\n"
"Some more lines here too." )

The newlines in the string are still needed, but the ones escaping the
EOLs are not.
________________________________________________________________________
TonyN.:' *firstname*nlsnews@georgea*lastname*.com
' <http://www.georgeanelson.com/>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top