Pierre Fortin said:
I was hoping to use the likes of: "%(key)*.*f" % map
however, unlike with the non-(key) formats, there appears to be no way
to specify a "*.*" size when a map is used...
It is not clear to me where you would expect to get the values for those
stars from -- 'map' being a dictionary it has no concept of "ordering",
so there is no concept of "next value" after map['key']. If I had this
kind of problem I would doubtlessly tack it with _two_ formattings,
first one to get the values for the stars (with explicit names), giving
a clean format string, then another to get the value for the data. Say:
'%%(key)%(width)d.%(prec)df' % map % map
Not all that readable, alas. Alternatively, you could use a non-keyed
format string and extract things from the map on the RHS...:
'%*.*f' % [map[x] for x in ('key', 'width', 'prec')]
I personally consider this a bit more readable, but that's quite
debatable, of course...
Alex
Thanks to you and Bengt for your patience with this problem...
Since I'd already dipped my toe in the dual-map water in an earlier post,
a "Duh!" moment occured to me as I read your responses... Realizing that
examples rarely show the true complexity of a problem, the answer (for me)
lay in keeping the formatting and data maps separate... I find mapped
strings immensely more readable/maintainable than the simple same-quantity
and gotta-be-in-the-right-order ones:
change=["down","up","unchanged"]
"""On %10s, the closing price of $%6.2f was %s
from the day's open of $%6.2f
....
....
""" % (Date, Close, change[int(float(Open>= ...], Open, ... )
especially when the string needs to be reworked by re-ordering, adding
and/or deleting items.
Here's my reasonably (to me
readable/maintainable solution to this core
problem... Only the "fmt" statement needs tweaking to generate the
desired appearance.
#!/usr/bin/env python
def mkdict(**kwargs):
return kwargs
fmt = { 'wDate':10, 'wOpen':6, 'wHigh':6, 'wLow':6, # width
'wClose':6, 'wVolume':10, 'wAdjClose':6,
'pDate':10, 'pOpen':2, 'pHigh':2, 'pLow':2, # precision
'pClose':2, 'pVolume':0, 'pAdjClose':2 }
# 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 = mkdict(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))]
)
# line continuations must be left-justified to avoid extra spaces
print "%%(Date)%(wDate)d.%(pDate)ds \
%%(Open)%(wOpen)d.%(pOpen)df \
%%(High)%(wHigh)d.%(pHigh)df \
%%(Low)%(wLow)d.%(pLow)df \
%%(Close)%(wClose)d.%(pClose)df \
%%(Volume)%(wVolume)d.%(pVolume)dd \
%%(AdjClose)%(wAdjClose)d.%(pAdjClose)df \
%%(Change)s \
" % fmt % map
Generates:
9-Sep-04 19.49 20.03 19.35 19.93 60077400 19.93 up
8-Sep-04 18.96 19.53 18.92 18.97 52020600 18.96 n/c
7-Sep-04 18.98 19.18 18.84 18.85 45498100 18.84 down
At least, now I understand why mappings are the exception to the "*[.*]"
rule of formatting... :^)
Thanks!
Pierre