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