Creating formatted output using picture strings
MRAB
python at mrabarnett.plus.com
Wed Feb 10 14:56:25 EST 2010
Tim Chase wrote:
> python at bdurham.com wrote:
>> Original poster here.
>>
>> Thank you all for your ideas. I certainly learned some great techniques
>> by studying everyone's solutions!!
>
> Thanks for the positive feedback -- it's something most folks like to
> hear when they try to assist and such thanks appears too rarely on the
> list.
>
>> Here's the solution I came up with myself. Its not as sexy as some of
>> the posted solutions, but it does have the advantage of not failing when
>> the number of input chars <> the number of placeholders in the pic
>> string.
> >
>> Any feedback on what follows would be appreciated.
> [snip]
>> # test cases
>> print picture("123456789", "(@@@)-@@-(@@@)[@]")
>> print picture("123456789ABC", "(@@@)-@@-(@@@)[@]")
>> print picture("1234", "(@@@)-@@-(@@@)[@]")
>> print picture("123456789", "(@@@)-@@-(@@@)")
>> print picture("123456789", "(@@@)-@@-(@@@)[@][@@@@@]")
>>
>
> You don't give the expected output for these test cases, so it's hard to
> tell whether you want to pad-left or pad-right.
>
> Riffing on MRAB's lovely solution, you can do something like
>
> def picture(
> s, pic,
> placeholder='@',
> padding=' ',
> pad_left=True
> ):
> assert placeholder != '%'
> s = str(s)
> expected = pic.count(placeholder)
> if len(s) > expected:
> s = s[:expected]
> if len(s) < expected:
> if pad_left:
> s = s.rjust(expected, padding)
> else:
> s = s.ljust(expected, padding)
> return pic.replace(
> '%', '%%').replace(
> placeholder, '%s') % tuple(s)
>
> print picture("123456789", "(@@@)-@@-(@@@)[@]", pad_left=False)
> print picture("123456789ABC", "(@@@)-@@-(@@@)[@]", pad_left=False)
> print picture("1234", "(@@@)-@@-(@@@)[@]", pad_left=False)
> print picture("123456789", "(@@@)-@@-(@@@)", pad_left=False)
> print picture("123456789", "(@@@)-@@-(@@@)[@][@@@@@]", pad_left=False)
>
> That way you can specify your placeholder, your padding character, and
> whether you want it to pad to the left or right.
>
The code changes any existing '%' to '%%' because each placeholder will
be changed to '%s'. However, if the placeholder itself is '%' then the
initial 'fix' isn't necessary. Therefore:
def picture(s, pic, placeholder='@', padding=' ', pad_left=True):
s = str(s)
expected = pic.count(placeholder)
if len(s) > expected:
s = s[:expected]
elif len(s) < expected:
if pad_left:
s = s.rjust(expected, padding)
else:
s = s.ljust(expected, padding)
if placeholder != '%':
pic = pic.replace('%', '%%')
return pic.replace(placeholder, '%s') % tuple(s)
More information about the Python-list
mailing list