Need advice on subclassing code

2005-11-15 Thread Rusty Shackleford
Hi --

We have some code that returns an object of a different class, depending
on some parameters.  For example:

if param x is 1 and y is 1, we make an object of class C_1_1.
if param x is 1 and y is 2, we make an object of class C_1_2.

C_1_1 and C_1_2 share a common C ancestor, and in practice may be
identical, but theoretically, could have the same function name with two
different implementations underneath.

We have a file where all the C_X_Y classes are defined.  It looks sort
of like this:

class C_1_1(C):
Creates a x=1 and y=1 class
def __init__(self):
C.__init__(self, 1, 1)

class C_1_2(C):
Creates a x=1 and y=2 class
def __init__(self):
C.__init__(self, 1, 2)

99% of the specific classes do the exact same thing.  For a tiny few,
the class definition looks like this:

class C_3_5(C):
Creates a x=3, y=5 class.
def __init__(self):
C.__init__(self, 3, 5)

def foo(self):
Redefine the default C.foo() function.
return 99

The reason for this is that we want to allow different classes to do
non-standard behavior.  In practice, however, it turns out that most of
the time, we don't need anything special.

Is this the best solution?  Is there some way of doing a default vs.
non-default deal, without having to manually hardcode all the different
possible subclasses?

Thanks for the help.

-- 
A better way of running series of SAS programs:
http://overlook.homelinux.net/wilsonwiki/SasAndMakefiles
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Need advice on subclassing code

2005-11-15 Thread [EMAIL PROTECTED]
Would the approach of using a switch to decide to instatite which class
good for you, like:

py class C:
py. name = 'C'
py.
py class D:
py. name = 'D'
py.
py switch = { (1, 1): C, (1,2): D }
py x = 1
py y = 2
py c = switch[(x,y)]()
py print c.name
D
py

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Need advice on subclassing code

2005-11-15 Thread bruno at modulix
Rusty Shackleford wrote:
 Hi --
 
 We have some code that returns an object of a different class, depending
 on some parameters.  For example:
 
 if param x is 1 and y is 1, we make an object of class C_1_1.
 if param x is 1 and y is 2, we make an object of class C_1_2.
 
 C_1_1 and C_1_2 share a common C ancestor, and in practice may be
 identical, but theoretically, could have the same function name with two
 different implementations underneath.
 
 We have a file where all the C_X_Y classes are defined.  It looks sort
 of like this:
 
(snip)

 99% of the specific classes do the exact same thing.  For a tiny few,
 the class definition looks like this:
 
(snip same code with minor differences...)

 The reason for this is that we want to allow different classes to do
 non-standard behavior.  In practice, however, it turns out that most of
 the time, we don't need anything special.
 
 Is this the best solution? 

No, of course - but I guess you knew it already !-)

 Is there some way of doing a default vs.
 non-default deal, without having to manually hardcode all the different
 possible subclasses?

Here are the pieces of the puzzle:
- A dict is usually the best choice for lookups.
- A tuple can serve as key for a dict.
- A (reference to) a class object can be stored in a dict (or the name
of the class, as a string).
- the get() method of a dict allow for an optional default value to be
use if the requested key is not found

And here's a first go:

def get_object(x, y):
  specials = {
(1, 2): C_1_2,
(33, 42): C_33_42,
  }
  # assume class C is the default class
  klass = specials.get((x, y), C)
  return klass()

Now if you store the class names as strings, ie :


  specials = {
(1, 2): C_1_2,
(33, 42): C_33_42,
  }

you can use a config file (ini, XML, Yaml, or even plain old python) to
store the 'specials' mapping and the default class name, and have
get_object() read from that config file. The trick is to get the class
from the class's name, which is solved with getattr():

def get_object(x, y):
  specials = {
(1, 2): C_1_2,
(33, 42): C_33_42,
  }
  # assume class 'C' is the default class
  class_name = specials.get((x, y), C)

  # from class name to class:
  klass = getattr(module_where_classes_live, class_name)
  return klass()


I think you should be able to solve your problem with this.

A last thing: the name of the module storing the classes can also be
stored in a conf file. Use __import__() to get the module object from
it's name.


HTH
-- 
bruno desthuilliers
python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '[EMAIL PROTECTED]'.split('@')])
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Need advice on subclassing code

2005-11-15 Thread Kent Johnson
Rusty Shackleford wrote:
 Hi --
 
 We have some code that returns an object of a different class, depending
 on some parameters.  For example:
 
 if param x is 1 and y is 1, we make an object of class C_1_1.
 if param x is 1 and y is 2, we make an object of class C_1_2.
 
 C_1_1 and C_1_2 share a common C ancestor, and in practice may be
 identical, but theoretically, could have the same function name with two
 different implementations underneath.
 
 We have a file where all the C_X_Y classes are defined.  
 Is this the best solution?  Is there some way of doing a default vs.
 non-default deal, without having to manually hardcode all the different
 possible subclasses?

How are you instantiating the correct class? You should be able to provide a 
default behaviour. For example if the classes are all defined in module C you 
could have a factory like this:

import C
def makeC(x, y):
  subtype = 'C_%d_%d' % (x, y)
  cls = getattr(C, subtype, C.C)
  return cls(x, y)

Then in module C just define the subtypes you need to specialize; all other 
values of x and y will get the base class C.C.

Kent
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Need advice on subclassing code

2005-11-15 Thread Michael Spencer
Kent Johnson wrote:
 Rusty Shackleford wrote:
 ...
 C_1_1 and C_1_2 share a common C ancestor, and in practice may be
 identical, but theoretically, could have the same function name with two
 different implementations underneath.

 ...
 
 How are you instantiating the correct class? You should be able to provide a 
 default behaviour. For example if the classes are all defined in module C you 
 could have a factory like this:
 
 import C
 def makeC(x, y):
   subtype = 'C_%d_%d' % (x, y)
   cls = getattr(C, subtype, C.C)
   return cls(x, y)
 
 Then in module C just define the subtypes you need to specialize; all other 
 values of x and y will get the base class C.C.
 
 Kent

Or, if you actually want different classes for each set of parameters (say for 
debugging or introspection), you could compose the default ones on the fly:


import C
def makeC(x, y):
   subtype = 'C_%d_%d' % (x, y)
   cls = getattr(C, subtype, None)
   if not cls:
 # No specialized class found, so compose a default
 # This requires C.C to be a new-style class
 cls = type(subtype, (C.C,), {__autogenerated__: True})
   return cls(x, y)

Michael



-- 
http://mail.python.org/mailman/listinfo/python-list


Advice on this code

2005-10-12 Thread LenS
If this is the wrong place to post this, please advise better place.
Otherwise, I have created the following python program and it works.
Running on XP.  I think I am now at that stage of learning python where
I'm not quit a newbie and I am not really knowlegable.  I know just
enough to be dangerous and can really screw things up.

Any suggestion on improving would be greatly appreciated.  However my
real question is I would like to run this program under a GUI interface
and have the GUI have a start button to start this process running and
the messages in the program placed in a multiline text field which when
the stop button is pressed the text field would be copied to a logfile
and the program exited.  Below this program is the skeleton of the
python gui program using wxPython (the gui program also works).  I have
a metal block on merging the two programs.  I think part of the problem
is the first is not really using object except for the database access
and the gui is all object.  Second, I'am getting all wrapped up with
variable, object, etc scope issues.



** FIRST PROGRAM **
This program is an attempt to modularize the lmsface program.
I also will try to document the logic of the program

import os
import glob
import time
import re
import shutil

from win32com.client import Dispatch
from ADOConstants import *

def cvtfiles():
 cvtfiles is the driving routine for converting and/or changing
the V1sta quote flat file being sent by QuotePro to Unique.  The
function gets a list of the files in the FTP directory path and
opens each file one at a time and copies the data (with any
necessary changes or additions to the output directory where
V1sta's
interface program
 picks it up and converts it into the V1sta's
SQL quote files.  Individual functions are called to process
different segments of the flat file record.

global novehflag
novehflag = False
global ofile
list1 = glob.glob('*.dat')
for f1 in list1:
if f1.lower().startswith(unq):
if f1.lower().rfind(void)  0:
print f1 +  is being processed now.
input1 = open(cfdir + f1, 'r')
output = open(ctdir + f1, 'w+')
ifile = input1.readline()
output.write(wrkpol(ifile))
output.write(wrkdrv(ifile,1406,6))
output.write(wrkveh(ifile,1784,6))
if novehflag == True:
input1.close()
output.close()
shutil.copy2(cfdir + f1,cfdir + 'voided\\' + f1)
os.remove(cfdir + f1)
os.remove(ctdir + f1)
novehflag = False
else:
output.write(wrkmisc(ifile,2582))
output.write(wrkviol(ifile,2774,16))
output.write(wrkaccid(ifile,3270,16))
output.write(wrkmisc2(ifile,3638))
output.write(wrkcov(ifile,3666,6))
output.write(wrklp(ifile,4314,7))
output.write(wrkai(ifile,4909,6))
output.write(wrkmisc3(ifile,5707))
output.close()
input1.close()
shutil.copy2(cfdir + f1,cfdir + 'processed\\' + f1)
os.remove(cfdir + f1)
print f1 +  has been processed.
else:
shutil.copy2(cfdir + f1,cfdir + 'voided\\' + f1)
os.remove(cfdir + f1)
print f1 +  is a VOIDED Quote from QuotePro.
else:
pass


def wrkpol(ifile):
 wrkpol functions converts the policy information segment.
Currently the only changes made to the policy segment is to
change Current-Carrier-Type to 0 if it contains a 0 or 1 or
change Current-Carrier-Type to 1 if it contains a 2

polwrk = ''
polwrk = polwrk + ifile[0:577]
polwrk = polwrk + '   '
polwrk = polwrk + ifile[588:653]
if ifile[653:654] in ['0','1']:
polwrk = polwrk + '0'
else:
polwrk = polwrk + '1'
polwrk = polwrk + ifile[654:974]

maxcnt = 6
cnt = 0
strstart = 974
while cnt  maxcnt:
if ifile[strstart + 41:strstart + 52] == '   ':
polwrk = polwrk + ifile[strstart:strstart + 72]
else:
polwrk = polwrk + ifile[strstart:strstart + 41]
polwrk = polwrk + '   '
polwrk = polwrk + ifile[strstart + 52:strstart + 72]

strstart += 72
cnt += 1
return polwrk

def wrkdrv(ifile,strstart,maxcnt):
 wrkdrv function at this point just moves the data as is.
The driver segment is an occurs 6

cnt = 0
drvwrk = ''
while cnt  maxcnt:
if ifile[strstart + 23:strstart + 31]  '':
drvwrk = drvwrk + ifile[strstart:strstart + 63]
else:
drvwrk = drvwrk + ifile[strstart:strstart + 63]
strstart += 63
   

Re: Advice on this code

2005-10-12 Thread Steve M
output.write(wrkmisc(ifile,2582))
output.write(wrkviol(ifile,2774,16))
output.write(wrkaccid(ifile,3270,16))
output.write(wrkmisc2(ifile,3638))
output.write(wrkcov(ifile,3666,6))
output.write(wrklp(ifile,4314,7))
output.write(wrkai(ifile,4909,6))
output.write(wrkmisc3(ifile,5707))


Ummm... yuck?
First of all, this program is very hard to understand to somebody who
hasn't written it. ALthough I've never heard of Quote Vista so maybe
that's the problem.

Anyway, if you want to integrate the first program with the second GUI
program, you should convert the first program into a set of functions
that can be called to do everything the first program does.

So basically, take the first program and put everything that's not
already in a function into one. That is, all the code that is at zero
indentation, starting with creating the oConn connection, should be
moved into functions. You can also write a big-mama function that calls
those functions in such a way that it would have the exact same overall
effect as the original script before you moved the code into functions.
You can call this big-mama function 'main'.

Now you can integrate it with the GUI program by importing the first
module from the GUI program and binding the functions to the
appropriate buttons. For example you could bind main to the Start
button you  described.

Also, in the first file, you can put the following lines at the bottom,
and it will allow you to run the original script directly to achieve
the same result, while still being able to import it into a second
program and re-use just the functions.

if __name__ == '__main__':
main()

-- 
http://mail.python.org/mailman/listinfo/python-list