Iterating command switches from a data file - have a working solutionbut it seems inefficient

N

News

Hi everyone,

My goal is to pull command switches/options from a file and then assign
the values to select variables which would eventually be included in a
class object.

The data file looks something like this but the switches could be in any
order and not all may be used.

-m quemanager -s server -p port -k key -o object -c 20 -t (e-mail address removed)

Also, please keep in mind that the source code will have more than one
line in it and each has to be treaded separately.


In a first pass, I wrote the following code which works but there is
probably a better way of doing it.

Any ideas to make it more efficient/stream-lined would be greatly
appreciated.

#!/usr/bin/python

import string
inp = open("const.txt","r")
#
# Read File
#

while True:

#
# Get line from file
#
line=inp.readline()

#
# Check for EOF or break line up to extract relevant pieces
#
if len(line) == 0:
break
else:
split_line=line.split()
length=len(split_line)
count=0

#
# Evaluate list item and assign variable based on its contents
# Print statements are for debugging purposes only
#
for i in range(length):
if split_line[count] == "-m":
qmgr=split_line[count+1]
print "Queue Manager",qmgr;
elif split_line[count] == "-s":
server=split_line[count+1]
print "Server",server;
elif split_line[count] == "-p":
port=split_line[count+1]
print "Port",port;
elif split_line[count] == "-o":
object=split_line[count+1]
print "Object",object;
elif split_line[count] == "-k":
key=split_line[count+1]
print "Key",key;
elif split_line[count] == "-t":
mto=split_line[count+1]
print "To",mto;
elif split_line[count] == "-c":
check=split_line[count+1]
print "Check",check;
elif split_line[count] == "-d":
report=""
print "Report",report;
elif split_line[count] == "-q":
display=False
print "Display",display;
else:
continue

count=count+1

# Close input file
#
inp.close()
 
P

Peter Hansen

News said:
Hi everyone,

My goal is to pull command switches/options from a file and then assign
the values to select variables which would eventually be included in a
class object.

The data file looks something like this but the switches could be in any
order and not all may be used.

-m quemanager -s server -p port -k key -o object -c 20 -t (e-mail address removed)

Also, please keep in mind that the source code will have more than one
line in it and each has to be treaded separately.

I think you could just use getopt or optparse, passing in each line
after doing a simple .split() on it. The resulting handling of the
arguments would be much simpler and cleaner than what you have.

That won't work perfectly well if you can have quoted arguments with
spaces in them, however, but the example above does not.

-Peter
 
J

James Stroud

News said:
Hi everyone,

My goal is to pull command switches/options from a file and then assign
the values to select variables which would eventually be included in a
class object.

The data file looks something like this but the switches could be in any
order and not all may be used.

-m quemanager -s server -p port -k key -o object -c 20 -t (e-mail address removed)

Also, please keep in mind that the source code will have more than one
line in it and each has to be treaded separately.


In a first pass, I wrote the following code which works but there is
probably a better way of doing it.

Any ideas to make it more efficient/stream-lined would be greatly
appreciated.

#!/usr/bin/python

import string
inp = open("const.txt","r")
#
# Read File
#

while True:

#
# Get line from file
#
line=inp.readline()

#
# Check for EOF or break line up to extract relevant pieces
#
if len(line) == 0:
break
else:
split_line=line.split()
length=len(split_line)
count=0

#
# Evaluate list item and assign variable based on its contents
# Print statements are for debugging purposes only
#
for i in range(length):
if split_line[count] == "-m":
qmgr=split_line[count+1]
print "Queue Manager",qmgr;
elif split_line[count] == "-s":
server=split_line[count+1]
print "Server",server;
elif split_line[count] == "-p":
port=split_line[count+1]
print "Port",port;
elif split_line[count] == "-o":
object=split_line[count+1]
print "Object",object;
elif split_line[count] == "-k":
key=split_line[count+1]
print "Key",key;
elif split_line[count] == "-t":
mto=split_line[count+1]
print "To",mto;
elif split_line[count] == "-c":
check=split_line[count+1]
print "Check",check;
elif split_line[count] == "-d":
report=""
print "Report",report;
elif split_line[count] == "-q":
display=False
print "Display",display;
else:
continue

count=count+1

# Close input file
#
inp.close()

I hope no typos:

opt_map = {'m': 'Queue Manager', 's': 'Server', 'p': 'Port',
'o': 'Object', 'k': 'Key', 't': 'To',
'c': 'Check', 'd': 'Report', 'q': 'Display}

afile = open("filename")

settings = {}
for aline in enumerate(afile):
splitline = aline.split()
flags, options = splitline[::2], splitline[1::2]
flags = [f[1] for f in flags] # get rid of pesky "-"s
for flag, option in zip(flags, options):
settings[opt_map(flag)] = option
print "%s = %s" % (settings[opt_map(flag)], option)
afile.close()

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
J

James Stroud

News said:
Hi everyone,

My goal is to pull command switches/options from a file and then assign
the values to select variables which would eventually be included in a
class object.

The data file looks something like this but the switches could be in any
order and not all may be used.

-m quemanager -s server -p port -k key -o object -c 20 -t (e-mail address removed)

Also, please keep in mind that the source code will have more than one
line in it and each has to be treaded separately.


In a first pass, I wrote the following code which works but there is
probably a better way of doing it.

Any ideas to make it more efficient/stream-lined would be greatly
appreciated.

#!/usr/bin/python

import string
inp = open("const.txt","r")
#
# Read File
#

while True:

#
# Get line from file
#
line=inp.readline()

#
# Check for EOF or break line up to extract relevant pieces
#
if len(line) == 0:
break
else:
split_line=line.split()
length=len(split_line)
count=0

#
# Evaluate list item and assign variable based on its contents
# Print statements are for debugging purposes only
#
for i in range(length):
if split_line[count] == "-m":
qmgr=split_line[count+1]
print "Queue Manager",qmgr;
elif split_line[count] == "-s":
server=split_line[count+1]
print "Server",server;
elif split_line[count] == "-p":
port=split_line[count+1]
print "Port",port;
elif split_line[count] == "-o":
object=split_line[count+1]
print "Object",object;
elif split_line[count] == "-k":
key=split_line[count+1]
print "Key",key;
elif split_line[count] == "-t":
mto=split_line[count+1]
print "To",mto;
elif split_line[count] == "-c":
check=split_line[count+1]
print "Check",check;
elif split_line[count] == "-d":
report=""
print "Report",report;
elif split_line[count] == "-q":
display=False
print "Display",display;
else:
continue

count=count+1

# Close input file
#
inp.close()

Anyone who got the previous message, there was a typo. This looks better

opt_map = {'m': 'Queue Manager', 's': 'Server', 'p': 'Port',
'o': 'Object', 'k': 'Key', 't': 'To',
'c': 'Check', 'd': 'Report', 'q': 'Display}

afile = open("filename")

settings = {}
for aline in afile:
splitline = aline.split()
flags, options = splitline[::2], splitline[1::2]
flags = [f[1] for f in flags] # get rid of pesky "-"s
for flag, option in zip(flags, options):
settings[opt_map(flag)] = option
print "%s = %s" % (opt_map(flag), option)

afile.close()



--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
J

John Machin

Which version of Python is the OP using??
inp = open("const.txt","r")
#
# Read File
#

while True:

#
# Get line from file
#
line=inp.readline()

#
# Check for EOF or break line up to extract relevant pieces
#
if len(line) == 0:
break
else:
split_line=line.split()
length=len(split_line)
count=0

#
# Evaluate list item and assign variable based on its contents
# Print statements are for debugging purposes only
#
for i in range(length):
if split_line[count] == "-m":
qmgr=split_line[count+1]
print "Queue Manager",qmgr; [snip]
elif split_line[count] == "-c":
check=split_line[count+1]
print "Check",check;
elif split_line[count] == "-d":
report=""

Uh-oh ... the plot just changed. Looks like -d and -q are NOT meant to
be followed by an operand.

print "Report",report;
elif split_line[count] == "-q":
display=False
print "Display",display;
else:
continue

count=count+1

# Close input file
#
inp.close()

Anyone who got the previous message, there was a typo. This looks better

opt_map = {'m': 'Queue Manager', 's': 'Server', 'p': 'Port',
'o': 'Object', 'k': 'Key', 't': 'To',
'c': 'Check', 'd': 'Report', 'q': 'Display}

'Queue Manager' is not suitable for later use as an attribute name.
afile = open("filename")

settings = {}
for aline in afile:
splitline = aline.split()
flags, options = splitline[::2], splitline[1::2]
flags = [f[1] for f in flags] # get rid of pesky "-"s

Actually that's getting rid of the first character irrespective of
whether it's "-" or not -- except when there's only one character in
which case it will die in a hole.

for flag, option in zip(flags, options):
settings[opt_map(flag)] = option
print "%s = %s" % (opt_map(flag), option)

opt_map is a dict; should be opt_map[flag] in above two lines
afile.close()

Like Peter said, use optparse -- it handles the no-argument flags, has
error detection, defaults, can be told the type of the flag, already
returns the goodies as attributes of an object, ...
 
J

James Stroud

John said:
On 13/04/2006 11:23 AM, James Stroud wrote:

'Queue Manager' is not suitable for later use as an attribute name.

Who said anything about attribute names? I did it this way to show the
OP that not every value has to be "select variables which would
eventually be included in a class object". Using a dict would be far
more attractive than a bunch of "setattr" & "getattr"s later.
afile = open("filename")

settings = {}
for aline in afile:
splitline = aline.split()
flags, options = splitline[::2], splitline[1::2]
flags = [f[1] for f in flags] # get rid of pesky "-"s


Actually that's getting rid of the first character irrespective of
whether it's "-" or not -- except when there's only one character in
which case it will die in a hole.

Who said the "-" was optional?
for flag, option in zip(flags, options):
settings[opt_map(flag)] = option
print "%s = %s" % (opt_map(flag), option)


opt_map is a dict; should be opt_map[flag] in above two lines
Typos.
afile.close()

Like Peter said, use optparse -- it handles the no-argument flags, has
error detection, defaults, can be told the type of the flag, already
returns the goodies as attributes of an object, ...

Peter's post was up when I responded, but it does not give the OP any
ideas about how to write better python code. Note the 4 page if...elif
construct. optparse might be logical for vet pythonistas, but if someone
is writing code like to OP, it might be better to give him some coding
hints at the expense of sophistication.

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
J

John Machin

Who said anything about attribute names? I did it this way to show the
OP that not every value has to be "select variables which would
eventually be included in a class object".

Sorry, I don't understand that sentence.
Using a dict would be far
more attractive than a bunch of "setattr" & "getattr"s later.

Who said anything about a bunch of *attrs later?

Instead of
settings[opt_map[flag]] = option
you'd have
setattr(anobj, opt_map[flag], option)
with the __init__ for the class setting up the default values.
And no getattrs, you'd use the names like qmgr and port as per the OP:
anobj.qmgr, anobj.port, etc ...
afile = open("filename")

settings = {}
for aline in afile:
splitline = aline.split()
flags, options = splitline[::2], splitline[1::2]
flags = [f[1] for f in flags] # get rid of pesky "-"s


Actually that's getting rid of the first character irrespective of
whether it's "-" or not -- except when there's only one character in
which case it will die in a hole.

Who said the "-" was optional?

Nobody. Who said the user data was going to be syntactically correct?
for flag, option in zip(flags, options):
settings[opt_map(flag)] = option
print "%s = %s" % (opt_map(flag), option)


opt_map is a dict; should be opt_map[flag] in above two lines
Typos.
afile.close()

Like Peter said, use optparse -- it handles the no-argument flags, has
error detection, defaults, can be told the type of the flag, already
returns the goodies as attributes of an object, ...

Peter's post was up when I responded, but it does not give the OP any
ideas about how to write better python code.

Yes it does. It gives the OP the idea that if there's a Python standard
module that does the job, the best Python code that the OP could write
would be calls to that module.
Note the 4 page if...elif
construct.

I did. I read *all* of it.
optparse might be logical for vet pythonistas, but if someone
is writing code like to OP, it might be better to give him some coding
hints at the expense of sophistication.

The "sophistication" of optparse appears to match what the OP appears to
want to do; IMO preferable to the sophistry of something like

flags, options = splitline[::2], splitline[1::2]

which is sure to cause the OP some headscratching and needs to be thrown
away immediately he starts to consider (a) variable number of parameters
(b) error detection.
 
P

Peter Otten

Peter said:
I think you could just use getopt or optparse, passing in each line
after doing a simple .split() on it.  The resulting handling of the
arguments would be much simpler and cleaner than what you have.

That won't work perfectly well if you can have quoted arguments with
spaces in them, however, but the example above does not.

shlex.split() may help with the splitting, e. g.:
['alpha', 'beta', '--gamma', 'delta epsilon', 'zeta eta']

Peter
 
E

Eric Deveaud

News said:
Hi everyone,

My goal is to pull command switches/options from a file and then assign
the values to select variables which would eventually be included in a
class object.

The data file looks something like this but the switches could be in any
order and not all may be used.

-m quemanager -s server -p port -k key -o object -c 20 -t (e-mail address removed)

Also, please keep in mind that the source code will have more than one
line in it and each has to be treaded separately.

I suggest you use getopt or optpase to perform this task
those modules are designed to perform what you want, with error checking

import getopt
inp = open("const.txt","r")
for line in inp:
try:
opt, args = getopt.getopt(iline.split(), 'c:k:m:eek::p:s:t:i')
print opt
except getopt.GetoptError, msg:
# handle the error as you need

Eric
 
B

bruno at modulix

News said:
Hi everyone,

My goal is to pull command switches/options from a file and then assign
the values to select variables which would eventually be included in a
class object.

The data file looks something like this but the switches could be in any
order and not all may be used.

-m quemanager -s server -p port -k key -o object -c 20 -t (e-mail address removed)

Have you looked at optparse ?
 
N

News

bruno said:
Have you looked at optparse ?
I have.

In the interactive version of the code, I use:

#
# Parse command line options and automatically build help/usage
#
parser = OptionParser()

parser.add_option("-q", "--quiet",
action="store_false", dest="verbose", default=1,
help="don't print status messages to stdout")
parser.add_option("-m", dest="qmanager",
help="Queue Manager to inquire against")
parser.add_option("-s", dest="host",
help="Host the que manager resides on")
parser.add_option("-p", dest="port",
help="Port queue manager listens on"),
parser.add_option("-o", dest="object",
help="Queue object being inquired on"),
parser.add_option("-k", dest="key",
help="object attribute to be inquired about"),
parser.add_option("-t", type="string",dest="mto",
help="e-mail address the report will go to"),
parser.add_option("-d", action="store_false",dest="report",
help="optional switch - enabling this sends output
to e-mail")
(options, args) = parser.parse_args()


The module optparse seemed to be aimed at reading from commandline
versus pulling attributes from a read line.
 
E

Eric Deveaud

News said:
I have.

The module optparse seemed to be aimed at reading from commandline
versus pulling attributes from a read line.


hummmm ....

lets see
optparse seems to be reading from commandline. that's not false but not
really true ;-)

point 1:
remember that commandline reading is done thru sys.argv wich provide a a
list of strings

point 2
now consider pulling datas from readline, wich return a string.
if you split this string you'll have a list of string.

point 3
optparse is designed for reading from a list of strings

I let the conclusion to your imagination ;-))


Eric
--
Salut,Je m'appele sed.je suis etudiant en communication, j'ai lu votre
message.je viens vous dire un petiit bonjour,et vous laisser mon
mél: vous pouvez me repondre maintenant si vous étez conecter.
-+-Guide du Neuneu d'Usenet - La com', elle ne passera pas par moi -+-
 
B

bruno at modulix

News said:
I have.

In the interactive version of the code, I use:

#
# Parse command line options and automatically build help/usage
#
parser = OptionParser()

parser.add_option("-q", "--quiet",
action="store_false", dest="verbose", default=1,
help="don't print status messages to stdout")
parser.add_option("-m", dest="qmanager",
help="Queue Manager to inquire against")
parser.add_option("-s", dest="host",
help="Host the que manager resides on")
parser.add_option("-p", dest="port",
help="Port queue manager listens on"),
parser.add_option("-o", dest="object",
help="Queue object being inquired on"),
parser.add_option("-k", dest="key",
help="object attribute to be inquired about"),
parser.add_option("-t", type="string",dest="mto",
help="e-mail address the report will go to"),
parser.add_option("-d", action="store_false",dest="report",
help="optional switch - enabling this sends output
to e-mail")
(options, args) = parser.parse_args()

So why do you inflict yourself the pain of rewriting all the parsing etc???
The module optparse seemed to be aimed at reading from commandline
versus pulling attributes from a read line.

http://www.python.org/doc/2.4.2/lib/optparse-parsing-arguments.html:
"""
The whole point of creating and populating an OptionParser is to call
its parse_args() method:

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

where the input parameters are

args
the list of arguments to process (sys.argv[1:] by default)
"""

what about something like :

line = myfile.readline()
options = parser.parse_args(line.split())

But what, if you prefer to rewrite (and maintain) a custom parser doing
exactly the same thing, please do !-)
 
N

News

bruno said:
News said:
I have.

In the interactive version of the code, I use:

#
# Parse command line options and automatically build help/usage
#
parser = OptionParser()

parser.add_option("-q", "--quiet",
action="store_false", dest="verbose", default=1,
help="don't print status messages to stdout")
parser.add_option("-m", dest="qmanager",
help="Queue Manager to inquire against")
parser.add_option("-s", dest="host",
help="Host the que manager resides on")
parser.add_option("-p", dest="port",
help="Port queue manager listens on"),
parser.add_option("-o", dest="object",
help="Queue object being inquired on"),
parser.add_option("-k", dest="key",
help="object attribute to be inquired about"),
parser.add_option("-t", type="string",dest="mto",
help="e-mail address the report will go to"),
parser.add_option("-d", action="store_false",dest="report",
help="optional switch - enabling this sends output
to e-mail")
(options, args) = parser.parse_args()

So why do you inflict yourself the pain of rewriting all the parsing etc???
The module optparse seemed to be aimed at reading from commandline
versus pulling attributes from a read line.

http://www.python.org/doc/2.4.2/lib/optparse-parsing-arguments.html:
"""
The whole point of creating and populating an OptionParser is to call
its parse_args() method:

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

where the input parameters are

args
the list of arguments to process (sys.argv[1:] by default)
"""

what about something like :

line = myfile.readline()
options = parser.parse_args(line.split())

But what, if you prefer to rewrite (and maintain) a custom parser doing
exactly the same thing, please do !-)

sometimes you can't see the forest .. trees and all that :)

I really appreciate everyones insight on this.

It was very helpful.

OT: I saw several references to "OP". What does this mean?
 
N

News

Hi everyone,

Just to be complete, my final solution was:

parser = OptionParser()

parser.add_option("-m","--qmanager", dest="qmanager",
help="\t\tQueue Manager to inquire against"),

parser.add_option("-s","--server", dest="host",
help="\t\tHost the que manager resides on"),

parser.add_option("-c","--check", dest="check",
help="\t\tTest object if it is less/equal/greater"),

parser.add_option("-p","--port", type="string", dest="port",
help="\t\tPort queue manager listens on"),

parser.add_option("-o","--object", dest="object",
help="\t\tQueue object being inquired on"),

parser.add_option("-k", "--key",dest="key",
help="\t\tobject attribute to be inquired about"),

parser.add_option("-t","--to", type="string",dest="mto",
help="\t\te-mail address the report will go to"),

parser.add_option("-q","--quiet", action="store_false",dest="quiet",
help="\t\toptional - just returns the value"),

parser.add_option("-f", "--file",
action="store", type="string", dest="filename",
help="Pull command strings from FILE",
metavar="FILE")

parser.add_option("-d","--display",
action="store_false",dest="report",
help="\t\toptional - use sends output to e-mail")

(options, args) = parser.parse_args()

if options.filename is not None:
line = use_file()
(options,args) = parser.parse_args(line.split())
 
B

bruno at modulix

News wrote:
(snip)
sometimes you can't see the forest .. trees and all that :)

Yes, been here too... I wrote a CSV parser before realising there was a
pretty good one in the standard lib :(

(snip)
OT: I saw several references to "OP". What does this mean?

Original Poster
 
L

Larry Bates

News said:
Hi everyone,

My goal is to pull command switches/options from a file and then assign
the values to select variables which would eventually be included in a
class object.

The data file looks something like this but the switches could be in any
order and not all may be used.

-m quemanager -s server -p port -k key -o object -c 20 -t (e-mail address removed)

Also, please keep in mind that the source code will have more than one
line in it and each has to be treaded separately.


In a first pass, I wrote the following code which works but there is
probably a better way of doing it.

Any ideas to make it more efficient/stream-lined would be greatly
appreciated.

#!/usr/bin/python

import string
inp = open("const.txt","r")
#
# Read File
#

while True:

#
# Get line from file
#
line=inp.readline()

#
# Check for EOF or break line up to extract relevant pieces
#
if len(line) == 0:
break
else:
split_line=line.split()
length=len(split_line)
count=0

#
# Evaluate list item and assign variable based on its contents
# Print statements are for debugging purposes only
#
for i in range(length):
if split_line[count] == "-m":
qmgr=split_line[count+1]
print "Queue Manager",qmgr;
elif split_line[count] == "-s":
server=split_line[count+1]
print "Server",server;
elif split_line[count] == "-p":
port=split_line[count+1]
print "Port",port;
elif split_line[count] == "-o":
object=split_line[count+1]
print "Object",object;
elif split_line[count] == "-k":
key=split_line[count+1]
print "Key",key;
elif split_line[count] == "-t":
mto=split_line[count+1]
print "To",mto;
elif split_line[count] == "-c":
check=split_line[count+1]
print "Check",check;
elif split_line[count] == "-d":
report=""
print "Report",report;
elif split_line[count] == "-q":
display=False
print "Display",display;
else:
continue

count=count+1

# Close input file
#
inp.close()

Others have addressed your specific question. I'm going to make
a different suggestion. Change your thinking so that you can use
ConfigParser to get your values from a .INI/.CONF file instead.
The file would look something like:

[section001]
m=queuemanager
server=myserver
port=1080
key=somekey
object=someobject
c=20
[email protected]

[section002]
..
.. If you have many of these just put things in a loop
.. and process each section
..



You can then read with (not tested):

import ConfigParser
inifilename='program.ini'
INI=ConfigParser.ConfigParser()
INI.read(inifilename)
section='section001'
option='m'
try: m=INI.get(section, option)
except: m=None
option='server'
try: server=INI.get(section, option)
except: server=None
option='port'
try: port=INI.getint(section, option)
except: port=None # Or set to default port
option='key'
try: key=INI.get(section, option)
except: key=None
option='object'
try: object=INI.get(section, option)
except: object=None
option='c'
try: c=INI.getint(section, option)
except: c=None
option='emailtolist'
try: emailtolist=INI.get(section, option).split(';')
except: emailtolist=None


Just a suggestion.

-Larry Bates
 

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,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top