Creating formatted output using picture strings

MRAB python at mrabarnett.plus.com
Wed Feb 10 20:56:25 CET 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