Exercise 2.3

Objectives:

  • How to create formatted output such as numbers with a fixed number of decimal places or tables with fixed-width columns.

  • Further practice with string manipulation operations.

  • Continued practice with writing functions.

Files Created: None.

Files Modified: report.py

Creating Formatted Output

In many programs, you want to produce output that is formatted in a very specific manner. For example, you might want to print a table showing a summary of portfolio performance information.

      Name     Shares      Price     Change
---------- ---------- ---------- ----------
        AA        100       9.22     -22.98
       IBM         50     106.28      15.18
       CAT        150      35.46     -47.98
      MSFT        200      20.89     -30.34
        GE         95      13.48     -26.89
      MSFT         50      20.89     -44.21
       IBM        100     106.28      35.84

In the report, "Price" is the current share price of the stock and "Change" is the change in the share price from the initial purchase price.

(a) How to format numbers

A common problem with printing numbers is specifying the number of decimal places. This is easily fixed using the string formatting operator (%). For example:

>>> value = 42863.1
>>> print value
42863.1
>>> print '%0.4f' % value
42863.1000
>>> print '%16.2f cm' % value
        42863.10 cm
>>> print '%-16.2f cm' % value
42863.10         cm
>>>

Documentation on various codes used with % can be found here.

Try using the format() function instead:

>>> print format(value, '0.4f')
42863.1000
>>> print format(value, '>16.2f')
        42863.10
>>> print format(value, '<16.2f')
42863.10
>>> print format(value, '*>16,.2f')
*******42,863.10
>>>

Documentation on the codes used with format() can be found here.

Although it’s commonly used with print, string formatting is not tied to printing. If you want to save a formatted string. Just assign it to a variable. For example:

>>> f = '%0.4f' % value
>>> f
'42863.1000'
>>>

(b) Collecting Data

In order to generate the table in the above report, you’ll first want to collect all of the data shown in the table. Write a function make_report() that takes a list of stocks and dictionary of prices as input and returns a list of tuples containing the rows of the above table. Add this function to your report.py file. Here’s how it should work if you try it interactively:

>>> portfolio = read_portfolio('Data/portfolio.csv')
>>> prices = read_prices('Data/prices.csv')
>>> report = make_report(portfolio,prices)
>>> for r in report:
        print r

('AA', 100, 9.22, -22.980000000000004)
('IBM', 50, 106.28, 15.180000000000007)
('CAT', 150, 35.46, -47.98)
('MSFT', 200, 20.89, -30.339999999999996)
('GE', 95, 13.48, -26.889999999999997)
...
>>>

(c) Printing a formatted table

Redo the above for-loop, but change the print statement to format the tuples. For example:

>>> for r in report:
        print '%10s %10d %10.2f %10.2f' % r

         AA        100       9.22     -22.98
        IBM         50     106.28      15.18
        CAT        150      35.46     -47.98
       MSFT        200      20.89     -30.34
...
>>>

Take the above statements and add them to your report.py program. Have your program take the output of the make_report() function and print a nicely formatted table as shown.

(d) Adding some headers

Suppose you had a tuple of header names like this:

headers = ('Name', 'Shares', 'Price', 'Change')

Add code to your program that takes the above tuple of headers and creates a string where each header name is right-aligned in a 10-character wide field and each field is separated by a single space. For example:

'      Name     Shares      Price      Change'

Write code that takes the headers and creates the separator string between the headers and data to follow. This string is just a bunch of "-" characters under each field name. For example:

'---------- ---------- ---------- -----------'

When you’re done, your program should produce the table shown at the top of this exercise.

(e) Formatting Challenge

How would you modify your code so that the price includes the currency symbol ($) and the output appears like this:

      Name     Shares      Price     Change
---------- ---------- ---------- ----------
        AA        100      $9.22     -22.98
       IBM         50    $106.28      15.18
       CAT        150     $35.46     -47.98
      MSFT        200     $20.89     -30.34
        GE         95     $13.48     -26.89
      MSFT         50     $20.89     -44.21
       IBM        100    $106.28      35.84
Links