[Edu-sig] Lined up for EuroPython

Arthur ajsiegel at optonline.net
Sat Jun 25 16:10:02 CEST 2005


>PyGeo (a stage for spatial geometry) is sort of like that, as Arthur talks
>of an interpreted setting, and more forgiving syntax i.e. several
>formulations of the same command would be acceptable (but the examples
>weren't specifically Pythonic as I recall).

Appreciate the mention of PyGeo - but not sure where you are going.

What I did with the PyGeo scripting interface is try to give it some
geometric intelligence, and do so while avoiding the use of a lot of keyword
arguments when creating objects - making use of factory functions in a way I
think is kind of cool.

For example - there is a factory function called "Intersect", which creates
Point objects.

Say I have 3 Plane instances and a Line instance previously created.

>>>Intersect(plane1,plane,2,plane3) 

will give the unique point of intersection (barring degenerate cases) of the
3 planes.

>>>Intersect(plane1, line)

Or

>>>Intersect(line, plane1)

will give the unique point of intersection (barring degenerate cases) of the
line and the plane.  

A condensed version of the Intersect function looks like:

def Intersect(*args,**kws):
   __sigs__=[[Real._Plane,Real._Line],
             [Real._Plane,Real._Plane,Real._Plane]]
   t,i = method_get(__sigs__,args)
   if t is None:
      raise Argument_Type_Error(__sigs__,args)
   else:
      if i==0 or i==1:
         return PlaneLineIntersect(t[0],t[1],**kws)
      elif i==3:
         return PlanesIntersect(t[0],t[1],t[2],**kws)

"method_get" is a package level funtion which does compares the __sigs list
to the args for all factory functions and gives back the information
necessary to call the correct class with the correct arguments in the
correct order.

def method_get(sigs,args):
   def order(sig,_args):
      w=[]
      args=_args[:]
      for S in sig:
         v=[issubclass(a.__class__,S) for a in args]

         if 1 in v:
            w.append(args[v.index(1)])
            args.pop(v.index(1))

      return w
   args=list(args)
   for i in range(len(args)):
      if type(args[i])== int:
         args[i]=float(args[i])
   ret=[]
   for S in sigs:
      if len(args) == len(S):
         final_args = order(S,args)
         if len(final_args) == len(S):
             ret.append([final_args,sigs.index(S)])
   if ret:
      return max(ret)
   else:
      return None,None

So to add a new Intersect class possibility, all I need to do is add its
signature to the Intersect __sigs list, and it will be called appropriately.
End of story. And so on throughout PyGeo.
 
Among the scripting flexibility that exists is the fact that one is of
course not forced to *use* the factory function interface,

PlaneLineIntersect(plane1, line) works fine, as well.  But of course from a
geometric point of view the order of arguments (plane and line) should not
have significance - and I can't avoid it being so without the use of keyword
arguments - which I was intent on avoiding. So in my mind "PlaneLine
Intersect" is the API entrance, "Intersect" the scripting entrance. 

Use what works for you, for what you are trying to do. 

What could be more Pythonic?

Took me a while to develop this mechanism - don't know how fragile it might
be for general use - but works fine in Pygeo and I think it accomplishes in
a concise maintainable way, what I am trying to accomplish.

Well probably some improvement to "method_get", if nothing else.

Bon voyage and have fun at EuroPython.

Art






More information about the Edu-sig mailing list