ordered keywords?

Ron Adam rrr at ronadam.com
Tue Oct 18 04:45:01 CEST 2005

Kent Johnson wrote:
> Ron Adam wrote:
>> drawshapes( triangle=3, square=4, color=red,
>>             polygon(triangle, color),
>>             polygon(square, color) )
>> This comes close to the same pattern used in SVG and other formats 
>> where you have definitions before expressions.
> Why is this better than the obvious
> triangle=3
> square=4
> color=red
> drawshapes(polygon(triangle, color),
>             polygon(square, color) )
> or even
> drawshapes(polygon(3, red),
>             polygon(4, red) )
> which is concise and readable IMO...?
> Kent

That example was over simplified quite a bit.  :-)

The reason I'm trying to get named attributes is so I can change colors 
or the text items later without having to recreate the object.  The 
objects I'm using are capable inheriting from other predefined objects 
so you only have to add or modify it a tiny bit.

For example the following creates shapes that build on each other and 
they all have a .draw() method to draw on a Tk canvas.  In addition they 
can be scaled, stretched and rotated. Well, the ones based on polygons 
and lines can be rotated and stretched.  I'm still working on how to do 
that with arcs and text items.

## These are the most basic shape elements which use the
## Tkinter canvas items specified by the 'obj' attribute.

# base shapes.
text = Shape( obj='text', text='', fill='black', size=1,
               font='', style='', pos=(0,0), points=(0,0) )

line = Shape( obj='line', arrow='none', fill='black', smooth='false',
               pos=(0,0), width=.1, points=(-.5,0,.5,0), size=1,
               rotate=0, center=(0,0) )

polygon = Shape( obj='polygon', fill='grey', outline='', size=1,
                  smooth='false', pos=(0,0), width=0, points=(0,0),
                  rotate=0, center=(0,0), ratio=(1,1) )

arc = Shape( obj='arc', fill='grey', outline='', pos=(0,0), width=0,
              size=1, style='arc', start='0', extent='90',
              points=(-.5,-.5,.5,.5) )

## This next group inherits from the shapes above and only
## needs to change what's different.

# shape variations
chord = arc(style='chord')
pie = arc(style='pieslice')
rectangle = polygon(points=[-.5,-.5,.5,-.5,.5,.5,-.5,.5])
triangle = polygon(points=getpolygon(3))
square = polygon(points=getpolygon(4))
octagon = polygon(points=getpolygon(8))
circle = polygon(smooth='true', points=getpolygon(16))

# The oval is stretched circle, which is a smoothed polygon.
# this can be rotated, the Tkinter oval can't.
oval = circle(ratio=(1,.7))

## Grouping combines the shapes together.  Again only what is
## different needs to be changed, such as color or size and
## relative position. Any previously defined
## shapes can be combined to create complex new ones.

caution = Group(
     triangle(pos=(6,5), size=75),
     triangle(fill='yellow', size=75),
     txt = text( text='!', font='times', style='bold',
                 pos=(0,-3), size=30,) )

error = Group(
     octagon(pos=(6,5), size=55),
     octagon(fill='red', size=55),
     circle(fill='white', size=37),
     circle(fill='red', size=25),
     line(fill='white', width=.2, rotate=45, size=28) )

## For this next group it would be nice if the bubbletip
## shape could be in the argument list, but it would need
## to be after the other refernces to it, and they
## would not find it. I did it this way to try out
## the idea of reusing objects, it would be no trouble
## just to duplicate the bubbletip in this case.

bubbletip = polygon(points=[-5,10, 20,10, 30,30])
question = Group(
     oval(pos=(6,5), size=60),
     oval(fill='lightblue', size=60),
     txt = text( text='?', font='times', style='bold',
                 size=25 ) )

## Here I just need to change the text element to 'i' to get
## the Info icon. Since it has a name we can do that.

info = question()     # get a copy of question
info.txt.text = 'i'   # change the '?' mark to 'i'

These can all be in a file ready to import and then you can use them 
anywhere in Tkinter that accepts a normal canvas commands.

     caution.draw(c, pos=(70,50), scale=.5)  # small caution icon
     error.draw(c, pos=(150,48), scale=3)    # triple sized error icon

Now this all works wonderfully, but I can only have one named attribute 
because I can't depend on the order a dictionary has.  So I'm going to 
probaby need to have a layer attribute.  Thus the need for either 
ordered keyword arguments, or a way to specify keywords as a variable 
for the arguments list.

Eventually I will be able to mix groups and shapes together in other 
groups by using them exactly like any other shape.  So I can take a 
image of a guy, add a hat, tilt the hat, and few other props, put some 
text on it, and I have a nice illustration with very little effort.

There are still a lot of small details that still need to be worked out 
before it's suitable for real use.  It works now, but too much will 
change as I add too it at this stage.  ;-)


More information about the Python-list mailing list