0

I have a dictionary that looks something like this:

d = {
    'last_price': '760.54',
    'change': 'N/A',
    'days_range': '760.00 - 775.00',
    'previous_close': '771.23',
    'change_percent': '-1.39%', 
}

All of the values in this dictionary are subject to change. The numbers can vary widely from single digits to numbers several digits long. I would like to format this information and consistently present it like this:

Last:            $760.54         Change:         N/A (-1.39%)
Prev Close:      $771.23         Day's Range:    $760.00 - $775.00

So far, I've been trying to do this by doing this:

print "\
Last: {last_price:>17} \t Change: {change:>11} ({change_percent}) \n\
Prev Close: {previous_close:>11} \t Day's Range: {days_range:>18}\
".format(**d)

This produces output that looks like this:

Last:            760.54          Change:         N/A (-1.39%)
Prev Close:      771.23          Day's Range:    760.00 - 775.00

While this works well enough if the numbers don't change, if "days_range" is set to a value like "78.91 - 79.91" it will jump further to the right. For example:

Last:             79.21          Change:         N/A (-1.19%)
Prev Close:       80.16          Day's Range:      78.91 - 79.91

I also can't say I'm very content with using "\t" to separate the columns, as I am concerned that if the values in the first column are too long this can cause the right column to get pushed further right than desired.

Is there an easy and elegant way to do this? I would prefer a solution that does not depend on nonstandard libraries and is relatively straightforward.

I'd also like to know an easy way to prepend values with dollar signs without having to modify the values in the dictionary.

ag415
  • 392
  • 2
  • 15
  • It jumps to the right because it's a shorter string and you're right-aligning them. It sounds like you want each value left-aligned within a column. – TigerhawkT3 Nov 19 '16 at 03:28

2 Answers2

2

In Python 3 and newer version, you may do it via str.format() as:

print('{:<15} {:<15} {:<15} {:<15}'.format('Last:', d['last_price'], 'Change:', '{} ({})'.format(d['change'], d['change_percent'])))
#         ^ Note this

which prints:

 Last:           760.54          Change:         N/A (-1.39%)

Here, < means that you want the content to be left align from the cursor position you mentioned where as > means right aligned.

Here is the result of data you are printing when printed simultaneously:

>>> '{:<15} {:<15} {:<15} {:<15}'.format('Prev Close:', 771.23, 'Day\'s Range:', '760.00 - 775.00')
"Prev Close:     771.23          Day's Range:    760.00 - 775.00"
>>> '{:<15} {:<15} {:<15} {:<15}'.format('Prev Close:', 80.16, 'Day\'s Range:', '78.91 - 79.91')
"Prev Close:     80.16           Day's Range:    78.91 - 79.91  "

All the coulmns are left aligned.


Note: Above sysntax for string formatting is only available from Python 3 and newer. In older versions you have to do it with %s as:

'%-15s %-15s %-15s %-15s' % ('Change: ', d['last_price'], 'Change:', '{} ({})'.format(d['change'], d['change_percent']))
#       ^  '-'ive value means align left

which prints:

'Change:         760.54          Change:         N/A (-1.39%)   '
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
1

You can change it to align to the left and it worked for me (I used ljust() but the way you're doing it with format should also work):

def print_data(d,spaces):
    print('Last:'.ljust(spaces) + d['last_price'].ljust(spaces) + \
          'Change:'.ljust(spaces) + d['change'] + ' (' + d['change_percent'] + ')')
    print('Prev close:'.ljust(spaces) + d['previous_close'].ljust(spaces) +
          "Day's Range:".ljust(spaces) + d['days_range'])

data = {
    'last_price': '760.54',
    'change': 'N/A',
    'days_range': '760.00 - 775.00',
    'previous_close': '771.23',
    'change_percent': '-1.39%', 
}
print_data(data,15)

print()

data['days_range'] = '78.91 - 79.91'
print_data(data,15)

As to your second question about prepending the dollar signs, everything except the "Day's Range" should be easy. For "Day's Range" I can't think of an easier way than adding one to the front and splitting the string down ' - ' and adding one to the second half.

abacles
  • 849
  • 1
  • 7
  • 15