string formatting with mapping & '*'... is this a bug?

Pierre Fortin pfortin at pfortin.com
Fri Sep 10 09:31:56 EDT 2004


On Fri, 10 Sep 2004 13:31:09 +0200 Alex wrote:

> You don't need this with Python 2.3 and later -- just call dict with
> keyword args, it just works!-)
Cool! :^)


> >     # line continuations must be left-justified to avoid extra spaces
> 
> nope, you can format as you wish, thanks to Python's handy idea
> (mutuated from C) of merging logically adjacent literals:

I'd bumped into er...  "issues" a few years ago with "print (...)" so I
never re-explored it...  thanks for updating me...  :>


> Anyway, your solution is neat but it seems a bit repetitive to me.

Agreed...  but I've not yet explored classes beyond some really trivial
stuff..


> class formatter:
>     def __init__(self, format_map, default_width=6, default_prec=2):
>         self.__dict__.update(locals())
>     def __getitem__(self, varname):
>         return '%%(%s)%d.%d" % (varname,
>             self.format_map.get('w'+varname, self.default_width),
>             self.format_map.get('p'+varname, self.default_prec))
> 
> now you can modify your code to do
>     fmt = formatter(fmt)

OK so far...  this works, until....

> [[you can actually simplify your fmt dict a lot thanks to the
> defaults]], and then code the printing like:

AH-HA!!!!  anything _not_ specified is defaulted...  took me a minute to
realize that I needed to remove the EXplicits in favor of the IMplicits...
not just remove their values...  DUH!!   Nice!!

MANY THANKS!!

Pierre

PS:  Here's the latest incarnation of the test script...  for me, the
"voodoo" part is
         self.__dict__.update(locals())
   Not sure I could have found that, since without it, the error:
     Traceback (most recent call last):
       File "./foo", line 40, in ?
         print ( "%(Date)ss %(Open)sf %(High)sf %(Low)sf "
       File "./foo", line 7, in __getitem__
         return "%%(%s)%d.%d" % (varname,
     AttributeError: formatter instance has no attribute 'format_map'
   seems cryptic until one realizes it's an initilization problem... 
   Right?  

-------------------------
#!/usr/bin/env python

class formatter:
    def __init__(self, format_map, default_width=6, default_prec=2):
        self.__dict__.update(locals())
    def __getitem__(self, varname):
        return "%%(%s)%d.%d" % (varname,
            self.format_map.get('w'+varname, self.default_width),
            self.format_map.get('p'+varname, self.default_prec))

fmt = dict( wDate=10, pDate=10,
            wVolume=10, pVolume=0,
            wChange=5, pChange=5, )

fmt = formatter(fmt)

# data will be read from several thousand files
sampledata = [
    "9-Sep-04,19.49,20.03,19.35,19.93,60077400,19.93",
    "8-Sep-04,18.96,19.53,18.92,18.97,52020600,18.96",
    "7-Sep-04,18.98,19.18,18.84,18.85,45498100,18.84",
    ]

change=["down","up","n/c"]

for D in sampledata:
    Date, Open, High, Low, Close, Volume, AdjClose = D.split(',')

    map = dict(Date=Date,
               Open=float(Open),
               High=float(High),
               Low=float(Low),
               Close=float(Close),
               Volume=int(Volume),
               AdjClose=float(AdjClose),
               Change=change[int(float(AdjClose) >= float(Open)) +
                             int(float(AdjClose) == float(Open))]
               )
    
    print ( "%(Date)ss %(Open)sf %(High)sf %(Low)sf "
            "%(Close)sf %(Volume)sd %(AdjClose)sf %(Change)ss"
            % fmt % map )
----------------------

MUCH simpler/cleaner!! Though I gotta understand how the 2 mappings got
used. Is it as simple as print() iterating over N mappings, taking the
next character(s) for the format..?  Elegant if so... though more than 2
mappings could be mind-bending... :^)

Note that I changed "%%(Change)s" to likewise get rid of that oddity...

This has turned into quite a "less is more" education for me...  :^)

Thanks again!



More information about the Python-list mailing list