Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > option argument length

Reply
Thread Tools

option argument length

 
 
Ritesh Raj Sarraf
Guest
Posts: n/a
 
      12-04-2005
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I'm using optparse module to parse all options and arguments.

My program uses mostly "option arguments" hence my len(args) value is always
zero. I need to check if the user has passed the correct number of "option
arguments". Something like:

(options,args) = parser.parse_args()

len(options) != 1 or len(options) > 2:
print "Incorrect number of arguments passed."

How do I accomplish it ?

Regards,

rrs
- --
Ritesh Raj Sarraf
RESEARCHUT -- http://www.researchut.com
"Stealing logics from one person is plagiarism, stealing from many is
research."
"Necessity is the mother of invention."

Note: Please CC me. I'm not subscribed to the list
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFDk1Nh4Rhi6gTxMLwRApx0AJ9XHlWFU1J0NdN02gtvim ogUSgDkACgmkOO
2pX8ocoC7pot1a8R4u2BWrY=
=piNo
-----END PGP SIGNATURE-----

 
Reply With Quote
 
 
 
 
Marc 'BlackJack' Rintsch
Guest
Posts: n/a
 
      12-04-2005
In <(E-Mail Removed)>, Ritesh Raj
Sarraf wrote:

> My program uses mostly "option arguments" hence my len(args) value is always
> zero. I need to check if the user has passed the correct number of "option
> arguments". Something like:
>
> (options,args) = parser.parse_args()
>
> len(options) != 1 or len(options) > 2:
> print "Incorrect number of arguments passed."
>
> How do I accomplish it ?


Just insert an ``if`` in front of the condition and end the program with
``sys.exit()`` after the message.

Ciao,
Marc 'BlackJack' Rintsch
 
Reply With Quote
 
 
 
 
Peter Otten
Guest
Posts: n/a
 
      12-04-2005
Ritesh Raj Sarraf wrote:

> My program uses mostly "option arguments" hence my len(args) value is
> always zero. I need to check if the user has passed the correct number of
> "option arguments". Something like:
>
> (options,args) = parser.parse_args()
>
> len(options) != 1 or len(options) > 2:
> print*"Incorrect*number*of*arguments*passed."
>
> How do I accomplish it ?


Judging from your code sample invention is the mother of that necessity.
You can pass a custom Values object with a __len__() method

class MyValues:
def __len__(self):
return len(self.__dict__)

# ...

options, args = parser.parse_args(values=MyValues())

but you should do your users a favour and give them meaningful error
messages. I can't conceive how you could achieve this by checking the
number of options. Explicit constraint checks like

options, args = parser.parse_args()
if options.eat_your_cake and options.have_it:
parser.error("Sorry, you cannot eat your cake and have it")

will increase your script's usability and make it easier to maintain for
only a tiny amount of work.

Peter

 
Reply With Quote
 
Ritesh Raj Sarraf
Guest
Posts: n/a
 
      12-05-2005
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Marc 'BlackJack' Rintsch on Monday December 5 2005 03:24 wrote:

> In <(E-Mail Removed)>, Ritesh Raj
> Sarraf wrote:
>
>> My program uses mostly "option arguments" hence my len(args) value is
>> always zero. I need to check if the user has passed the correct number of
>> "option arguments". Something like:
>>
>> (options,args) = parser.parse_args()
>>
>> len(options) != 1 or len(options) > 2:
>> print "Incorrect number of arguments passed."
>>
>> How do I accomplish it ?

>
> Just insert an ``if`` in front of the condition and end the program with
> ``sys.exit()`` after the message.
>
> Ciao,
> Marc 'BlackJack' Rintsch


This won't help because "options" is an instance.

Regards,

rrs
- --
Ritesh Raj Sarraf
RESEARCHUT -- http://www.researchut.com
"Stealing logics from one person is plagiarism, stealing from many is
research."
"Necessity is the mother of invention."

Note: Please CC me. I'm not subscribed to the list
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFDlIbH4Rhi6gTxMLwRAlgSAJ0Y3TT9eCBgrck5N2Y9Yj OTZMxUgwCcDeO5
qqgzY6rz2E4YKvurnlHL0nQ=
=hlZO
-----END PGP SIGNATURE-----

 
Reply With Quote
 
Ritesh Raj Sarraf
Guest
Posts: n/a
 
      12-05-2005
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Peter Otten on Monday December 5 2005 03:34 wrote:

> options, args = parser.parse_args(values=MyValues())
>
> but you should do your users a favour and give them meaningful error
> messages. I can't conceive how you could achieve this by checking the
> number of options. Explicit constraint checks like
>
> options, args = parser.parse_args()
> if options.eat_your_cake and options.have_it:
> parser.error("Sorry, you cannot eat your cake and have it")
>
> will increase your script's usability and make it easier to maintain for
> only a tiny amount of work.


I'm using this for "option arguments" which are mutually inclusive.
But I want the user to pass atleast one "option argument" for the program to
function properly.

For example, I have an option "--fetch-update" which requires a file "foo"
to check what it has to fetch. If the file is provided as an argument, it
uses it, else I add a parser.set_defaults("foo") which makes the program to
look for it in the current working directory.

WHen the program see the "--fetch-update" option, it should execute the
required code. Now how do I check if at least one option has been passed at
the command-line ?
I have multiple options but I have parser.set_defaults() for each of them.

Regards,

rrs
- --
Ritesh Raj Sarraf
RESEARCHUT -- http://www.researchut.com
"Stealing logics from one person is plagiarism, stealing from many is
research."
"Necessity is the mother of invention."

Note: Please CC me. I'm not subscribed to the list
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFDlIhF4Rhi6gTxMLwRAsLTAJ9ydjppGrFVbH2kL00vL0 0HgtrxqQCghZBq
pC0/1HftWE+9Eipx6vF+3Bo=
=Ay8m
-----END PGP SIGNATURE-----

 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      12-06-2005
Ritesh Raj Sarraf wrote:

> I'm using this for "option arguments" which are mutually inclusive.
> But I want the user to pass atleast one "option argument" for the program
> to function properly.
>
> For example, I have an option "--fetch-update" which requires a file "foo"
> to check what it has to fetch. If the file is provided as an argument, it
> uses it, else I add a parser.set_defaults("foo") which makes the program
> to look for it in the current working directory.
>
> WHen the program see the "--fetch-update" option, it should execute the
> required code. Now how do I check if at least one option has been passed
> at the command-line ?
> I have multiple options but I have parser.set_defaults() for each of them.


I'm sorry I don't understand your example. Wouldn't you need at least two
options to demonstrate "mutually inclusive" options? The set_default()
method seems to accept only keyword arguments -- but even it were used
correctly I'm still unclear why you would need it at all.

Perhaps you can post a few sample invocations (both correct and illegal) of
your script together with a description (in English, not code) of how the
script should react?

Peter, puzzled

 
Reply With Quote
 
Ritesh Raj Sarraf
Guest
Posts: n/a
 
      12-07-2005
On Tue, 6 Dec 2005, Peter Otten wrote:

> Ritesh Raj Sarraf wrote:
>
>> I'm using this for "option arguments" which are mutually inclusive.
>> But I want the user to pass atleast one "option argument" for the program
>> to function properly.
>>
>> For example, I have an option "--fetch-update" which requires a file "foo"
>> to check what it has to fetch. If the file is provided as an argument, it
>> uses it, else I add a parser.set_defaults("foo") which makes the program
>> to look for it in the current working directory.
>>
>> WHen the program see the "--fetch-update" option, it should execute the
>> required code. Now how do I check if at least one option has been passed
>> at the command-line ?
>> I have multiple options but I have parser.set_defaults() for each of them.

>
> I'm sorry I don't understand your example. Wouldn't you need at least two
> options to demonstrate "mutually inclusive" options? The set_default()
> method seems to accept only keyword arguments -- but even it were used
> correctly I'm still unclear why you would need it at all.
>
> Perhaps you can post a few sample invocations (both correct and illegal) of
> your script together with a description (in English, not code) of how the
> script should react?
>
> Peter, puzzled
>
>



try:
version = "0.6b"
reldate = "03/10/2005"
copyright = "(C) 2005 Ritesh Raj Sarraf - RESEARCHUT (http://www.researchut.com/)"

#FIXME: Option Parsing
# There's a flaw with either optparse or I'm not well understood with it
# Presently you need to provide all the arguments to it to work.
# No less, no more. This needs to be converted to getopt sometime.

#parser = OptionParser()
#parser = optparse.OptionParser()
parser = optparse.OptionParser(usage="%prog [OPTION1, OPTION2, ...]", version="%prog " + version)
parser.add_option("-d","--download-dir", dest="download_dir", help="Root directory path to save the downloaded files", action="store", type="string")
parser.set_defaults(download_dir="foo")
parser.add_option("-s","--cache-dir", dest="cache_dir", help="Root directory path where the pre-downloaded files will be searched. If not, give a period '.'",action="store", type="string", metavar=".")
parser.set_defaults(cache_dir=".")
#parser.set_defaults(cache_dir=".")
#parser.add_option("-u","--uris", dest="uris_file", help="Full path of the uris file which contains the main database of files to be downloaded",action="store", type="string")

# We'll have additional options
# --set-update - This will extract the list of uris which need to be fetched
# --fetch-update - This will fetch the list of uris which need for update.
# --install-update - This will install the fetched database files
# The same will happen for upgradation.
# --set-upgrade - This will extract the list of uris which need to be fetched
# --fetch-upgrade - This will fetch the list of uris which need for upgrade
# --install-upgrade - This will install the fetched database files
parser.add_option("","--set-update", dest="set_update", help="Extract the list of uris which need to be fetched for _updation_", action="store", type="string", metavar="foo")
parser.set_defaults(set_update="foo")
parser.add_option("","--fetch-update", dest="fetch_update", help="Fetch the list of uris which are needed for _updation_.", action="store", type="string", metavar="foo")
parser.set_defaults(fetch_update="foo")
parser.add_option("","--install-update", dest="install_update", help="Install the fetched database files ", action="store", type="string", metavar="foo.zip")
parser.set_defaults(install_update="foo.zip")
parser.add_option("","--set-upgrade", dest="set_upgrade", help="Extract the list of uris which need to be fetched ", action="store", type="string", metavar="foo.dat")
parser.set_defaults(set_upgrade="foo.dat")
parser.add_option("","--fetch-upgrade", dest="fetch_upgrade", help="Fetch the list of uris which are needed ", action="store", type="string", metavar="foo.dat")
parser.set_defaults(fetch_upgrade="foo.dat")
parser.add_option("","--install-upgrade", dest="install_upgrade", help="Install the fetched packages ", action="store", type="string", metavar="foo-fetched.zip")
parser.set_defaults(install_ugprade="foofetched.zi p")
(options, args) = parser.parse_args()
#parser.check_required("-d", "-s", "-u")
#if len(arguments) != 2:
# parser.error("Err! Incorrect number of arguments. Exiting")
if len(options) != 1 or len(options) > 2:
print len(args)
parser.error("No arguments were passed\n")
sys.exit(1)
elif not options.set_upgrade and options.upgrade_type:
parser.error("Only options --set-upgrade and --upgrade-type are mutually inclusive\n")
sys.exit(1)


Thanks,

rrs
--
Ritesh Raj Sarraf
RESEARCHUT -- http://www.researchut.com
"Stealing logic from one person is plagiarism, stealing from many is research."
"Necessity is the mother of invention."

 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      12-07-2005
Ritesh Raj Sarraf wrote:

> parser.add_option("-d","--download-dir", dest="download_dir",
> help="Root directory path to save the downloaded files",
> action="store", type="string")
> parser.set_defaults(download_dir="foo")


This can be simplified to

parser.add_option("-d", "--download-dir", default="foo",
help="Root directory path to save the downloaded files")

which seems to be the reason why I've never seen the set_defaults() call
before.

> if len(options) != 1 or len(options) > 2:


It doesn't matter much as it won't work anyway, but

len(options) > 2 implies len(options) != 1, so

if len(options) != 1:
#...

would suffice here.

Now to the actual problem: I think you didn't understand my previous
question. I cannot infer from your non-working code what it actually should
do. I asked for examples of how your script would be used. E. g,
assuming the code above is in a file called sarraf.py, what should the
following invocations

../sarraf.py --fetch-update bar
../sarraf.py --fetch-update bar --the-mutually-inclusive-option baz

do? Would the first terminate with an error message that another option must
also be given? Would it use the default? Would the second be accepted? Try
to describe it as simple and clear as possible. Imagine you were talking to
someone who has never written a line of code.

Peter
 
Reply With Quote
 
Ritesh Raj Sarraf
Guest
Posts: n/a
 
      12-07-2005
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Peter,


Peter Otten on Wednesday December 7 2005 21:25 wrote:

> This can be simplified to
>
> parser.add_option("-d", "--download-dir", default="foo",
> help="Root directory path to save the downloaded files")
>
> which seems to be the reason why I've never seen the set_defaults() call
> before.


As per python docs, it's mentioned that "default=" has been deprecated.
That's why I changed to parser.set_defaults()

>
>> if len(options) != 1 or len(options) > 2:

>
> It doesn't matter much as it won't work anyway, but
>
> len(options) > 2 implies len(options) != 1, so
>
> if len(options) != 1:
> #...
>


Yes, you're right. Sorry.

> would suffice here.
>


But will len(options) give a meaningful output. "options" is an instance.
It gives a Value Error.

> Now to the actual problem: I think you didn't understand my previous
> question. I cannot infer from your non-working code what it actually
> should do. I asked for examples of how your script would be used. E. g,
> assuming the code above is in a file called sarraf.py, what should the
> following invocations
>
> ./sarraf.py --fetch-update bar
> ./sarraf.py --fetch-update bar --the-mutually-inclusive-option baz
>
> do? Would the first terminate with an error message that another option
> must also be given? Would it use the default? Would the second be
> accepted? Try to describe it as simple and clear as possible. Imagine you
> were talking to someone who has never written a line of code.
>


../sarraf.py --fetch-update /bar

If the user gives the /bar argument, the program should save the downloaded
files to /bar. But I'm assuming that the user could be dumb or too lazy, in
which case --fetch-udpate should use the parser.set_defaults value
i.e. /foo

../sarraf.py --set-upgrade foo.dat --upgrade-type minimal

set-upgrade will again write data to foo.dat. If the user doesn't pass it as
an arguemnt it should take the defaults (again whatever is there in
parser.set_defaults). This will be inclusive with the --upgrade-type option
because the user will have a choice of selecting what kind of upgrade he'd
like to do, minimal or full or blah.

For this I think this should be enough:

if not options.set_upgrade and options.upgrade_type:
parser.error("They are mutually inclusive options")


But my main concern is what if the user doesn't pass any arguemtns. Every
option I have has a default value. So I want to check what the user has
passed.
But unfortunately the args variable has "0" as its value always.

Is my way (up till now) of using optparse logically incorrect or improper ?


Regards,

rrs
- --
Ritesh Raj Sarraf
RESEARCHUT -- http://www.researchut.com
"Stealing logics from one person is plagiarism, stealing from many is
research."
"Necessity is the mother of invention."

Note: Please CC me. I'm not subscribed to the list
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFDlzC84Rhi6gTxMLwRAtCBAJ9z5zDQ8oyx8Jy/rLe9JrwLII3xtACfTaEV
VhMmj8OD+/p+yN/8wF6xe+8=
=atC6
-----END PGP SIGNATURE-----

 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      12-07-2005
Ritesh Raj Sarraf wrote:

> ./sarraf.py --fetch-update /bar
>
> If the user gives the /bar argument, the program should save the
> downloaded files to /bar. But I'm assuming that the user could be dumb or
> too lazy, in which case --fetch-udpate should use the parser.set_defaults
> value i.e. /foo
>
> ./sarraf.py --set-upgrade foo.dat --upgrade-type minimal
>
> set-upgrade will again write data to foo.dat. If the user doesn't pass it
> as an arguemnt it should take the defaults (again whatever is there in
> parser.set_defaults). This will be inclusive with the --upgrade-type
> option because the user will have a choice of selecting what kind of
> upgrade he'd like to do, minimal or full or blah.
>
> For this I think this should be enough:
>
> if not options.set_upgrade and options.upgrade_type:
> parser.error("They*are*mutually*inclusive*options")
>
>
> But my main concern is what if the user doesn't pass any arguemtns. Every
> option I have has a default value. So I want to check what the user has
> passed.
> But unfortunately the args variable has "0" as its value always.


args are just the leftover arguments. For

../sarraf.py alpha --set-upgrade foo.dat beta

it would be ["alpha", "beta"].

---

I think your description is starting to make sense to me. Your user can
either update or upgrade but you cannot just check the value of e. g.
set_upgrade because you want to treat the default value and that same value
given on the command line differently.

If this is a correct assessment I don't think what you want is covered by
optparse. However, I hacked something together:

import optparse

parser = optparse.OptionParser()

parser.add_option("--alpha")
parser.add_option("--beta")

class Values(object):
def __init__(self):
self.__defaults = {}
def set_defaults(self, **kw):
self.__defaults.update(kw)
def __len__(self):
"""Number of options set by the user."""
return len(self.__dict__) -1
def __getattr__(self, name):
try:
return self.__defaults[name]
except KeyError:
raise AttributeError
def is_default(self, name):
"""Return True when the default fro option 'name'
wasn't overriden by the user"""
return name not in self.__dict__

values = Values()
values.set_defaults(alpha="xxx", beta="yyy")

options, args = parser.parse_args(values=values)

print "len(options) =", len(options)
print "alpha =", options.alpha,
print "(using default)" * options.is_default("alpha")
print "beta =", options.beta,
print "(using default)" * options.is_default("beta")

Not particularly elegant but I'm not able to come up with something better
for the moment. Maybe you should just provide fewer defaults to the parser.
Or you could look into option callbacks for an alternate approach.

> Is my way (up till now) of using optparse logically incorrect or improper
> ?


Well, as the optparse author points out, "required options" are a
self-contradictory term -- don't use them if you can avoid it. Would your
problem go away if you used two different scripts, one for updating and the
other for upgrading?

Peter

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Regex for <option> ... </option> John Perl Misc 10 01-29-2009 11:04 PM
page.aspx?option - how to detect "option" Kevin Blount ASP .Net 6 11-28-2006 09:21 PM
DHCP relay agent versus Option 3; Routers Option lcorrigan Cisco 2 09-27-2006 05:18 PM
no 'option' in aspx file means 'option'="false"? Cas ASP .Net 5 08-28-2006 10:36 AM
g++ -pg option and -shared option Julien ROUZIERES C++ 1 12-21-2004 02:30 PM



Advertisments