FE 459
Spring 2025

Assignment 1: Python Functions and the Time Value of Money

Discussion on Wednesday 1/22/25
No Workshop
Submission due by 9:00 p.m. on Wednesday 1/29/25.

Preliminaries

In your work on this assignment, make sure to abide by the collaboration policies of the course.

For each problem in this problem set, we will be writing or evaluating some Python code. You are encouraged to use the Spyder IDE which will be discussed/presented in class, but you are welcome to use another IDE if you choose.

If you have questions while working on this assignment, please post them on Piazza! This is the best way to get a quick response from your classmates and the course staff.

Programming Guidelines

  • Refer to the class Coding Standards for important style guidelines. The grader will be awarding/deducting points for writing code that comforms to these standards.

  • Every program file must begin with a descriptive header comment that includes your name, username/BU email, and a brief description of the work contained in the file.

  • Every function must include a descriptive docstring that explains what the function does and identifies/defines each of the parameters to the function.

  • Your functions must have the exact names specified below, or we won’t be able to test them. Note in particular that the case of the letters matters (all of them should be lowercase), and that some of the names include an underscore character (_).

  • Make sure that your functions return the specified value, rather than printing it. None of these functions should use a print statement.

  • If a function takes more than one input, you must keep the inputs in the order that we have specified.

  • You should not use any Python features that we have not discussed in class or read about in the textbook.

  • Your functions do not need to handle bad inputs – inputs with a type or value that doesn’t correspond to the description of the inputs provided in the problem.

  • You must test each function after you write it. Here are two ways to do so:

    • Run your a1task1.py file after you finish a given function. Doing so will load your latest code into the shell, where you can call the function using different inputs and check to see that you obtain the correct outputs.

    • Add test calls to the bottom of your a1task1.py file. These will be called every time that you run the file, which will save you from having to enter the tests yourself. We have given you an example of one such test in the starter file.

Warnings: Individual Work and Academic Conduct!!

  • This is an individual assignment. You may discuss the problem statement/requirements, Python syntax, test cases, and error messages with your classmates. However, each student must write their own code without copying or referring to other student’s work.

  • It is strictly forbidden to use any code that you find from online websites including but not limited to as CourseHero, Chegg, or any other sites that publish homework solutions.

  • It is strictly forbidden to use any generative AI (e.g., ChatGPT or any similar tools**) to write solutions for for any assignment.

Students who submit work that is not authentically their own individual work will earn a grade of 0 on this assignment and a reprimand from the office of the Dean.

If you have questions while working on this assignment, please post them on Piazza! This is the best way to get a quick response from your classmates and the course staff.



Task 1: Functions for time value of money calculations

40 points; individual-only

Create a new Python code file and save it with the name a1task1.py. Remember to create a header comment at the top of your file with your name, email address, assignment number, and a brief description. Write all of the functions for this task in the file a1task1.py.

  1. Write a function fv_lump_sum(r, n, pv) to calculate and return the future value of a lump sump pv invested at the periodic rate r for n periods. Recall the equation for the future value of a lump sum: FVFORUMULA

Examples:

    >>> # $100 at 5% rate for 2 years
    >>> fv_lump_sum(0.05, 2, 100)
    110.25
    >>> # $400 at 8% APR for 20 years (with monthly compounding)
    >>> fv_lump_sum(0.08/12, 20*12, 400)
    1970.7211083238797
  1. Write a function pv_lump_sum(r, n, fv) to calculate and return the present value of a lump sum fv to be received in the future, discounted at the periodic rate r for n periods. Recall the equation for the present value of a lump sum:

    PVFORUMULA

Examples:

    >>> # $1000 to be received in 5 years at 6% per year
    >>> pv_lump_sum(0.06, 5, 1000)
    747.2581728660571
    >>> # $500 received in 5 years, 6% APR, semi-ann. compounding
    >>> pv_lump_sum(0.06/2, 5*2, 500)
    372.0469574483625
  1. Write a function fv_annuity(r, n, pmt) to calculate and return the future value of an annuity of pmt to be received each period for n periods, invested at the periodic rate r. Recall the equation for the future value of an annuity is: FVANNUITY

    Examples:

    >>> # invest $100 per year for 5 years at 4% interest
    >>> fv_annuity(0.04, 5, 100)
    541.6322560000003
    >>> # invest $100 per month for 10 years at 9% APR
    >>> fv_annuity(0.09/12, 10*12, 100)
    19351.42770833082
    
  2. Write a function pv_annuity(r, n, pmt) to calculate and return the present value of an annuity of pmt to be received each period for n periods, discounted at the rate r. Recall the equation for the present value of an annuity is: PVANNUITY

    Examples:

    >>> # pv of 30 payments of $250 per year, 5% interest
    >>> pv_annuity(0.05, 30, 250)
    3843.1127567207104
    >>> # pv of 60 payments of $471.75 per month, 0.9% APR
    >>> pv_annuity(0.009/12,60, 471.75)
    27667.441596482677
    
  3. Write a function annuity_payment(r, n, pv) that calculates the amortizing annuity
    payment for a present value of pv to be repaid at a periodic interest rate of r for n periods. Recall the equation for the amortizing annuity payment is:

PMT

Examples:

    >>> # annuity payment for pv of $1,000 for 10 year at 5%
    >>> annuity_payment(0.05, 10, 1000)
    129.5045749654566
    >>> # annuity payment for pv of $27,667 for 60 months at 0.9% APR
    >>> annuity_payment(0.009/12, 60, 27667.44)
    471.7499727788093


Task 2: The Life-Cycle Model of Saving and Consumption

30 points; individual-only

Background/Overview

The Life-Cycle Model was first developed by Nobel Prize winning economist Franco Modigliani in the 1950s to help explain household’s decisions about spending and saving over time. Modigliani observed that households accumulate wealth during their working years and spend down that wealth during their retirement years, with the goal of maintaining a relatively smooth standard of living for all years, i.e., to keep spending the same amount year in and year out, even when they stop working.

To find this smooth level of consumption, we will need to find a household’s total economic resources, which are a combination of human capital (the value of future income) and financial assets. Given a household’s total economic, we can calculate the sustainable (smooth) amount of spending for each year of life until some maximum age.

Assumptions: We will make several simplifying assumptions, but these can be removed to make a more realistic implementation of the life-cycle model. - We assume to work only in real (inflation-adjusted dollars) and to use an inflation-adjusted risk free interest rate. - We assume no taxes or benefits from government. - We assume a single individual, no spouse or dependents.

Here are two examples to give you an idea of how this program should work:

Example 1: 35 year-old, mid-career, with $150,000 of assets:

    Welcome to the Life-Cycle Sustainable Spending Calculator.

    Enter the current inflation-indexed risk-free rate of return: 0.03
    Enter your age now: 35
    Enter your expected retirement age: 67
    Enter your current annual income: 83000

    You have 32 remaining working years with an income of $    83,000.00 per year.
    The present value of your human capital is about $ 1,692,267.54

    Enter the value of your financial assets: 150000
    Your economic net worth is: $ 1,842,267.54

    Your sustainable standard of living is about $    64,747.99 per year.
    To achieve this standard of living to age 100, you must save $    18,252.01 per year.

    Here is a annual summary of your financial plan:

    Age     Income          Consumption     Saving          Assets
    36      $    83,000.00  $    64,747.99  $    18,252.01  $   172,752.01
    37      $    83,000.00  $    64,747.99  $    18,252.01  $   196,186.58
    38      $    83,000.00  $    64,747.99  $    18,252.01  $   220,324.19
    39      $    83,000.00  $    64,747.99  $    18,252.01  $   245,185.92
    40      $    83,000.00  $    64,747.99  $    18,252.01  $   270,793.51
    41      $    83,000.00  $    64,747.99  $    18,252.01  $   297,169.33
    42      $    83,000.00  $    64,747.99  $    18,252.01  $   324,336.42
    43      $    83,000.00  $    64,747.99  $    18,252.01  $   352,318.52
    44      $    83,000.00  $    64,747.99  $    18,252.01  $   381,140.08
    45      $    83,000.00  $    64,747.99  $    18,252.01  $   410,826.30
    46      $    83,000.00  $    64,747.99  $    18,252.01  $   441,403.09
    47      $    83,000.00  $    64,747.99  $    18,252.01  $   472,897.20
    48      $    83,000.00  $    64,747.99  $    18,252.01  $   505,336.12
    49      $    83,000.00  $    64,747.99  $    18,252.01  $   538,748.22
    50      $    83,000.00  $    64,747.99  $    18,252.01  $   573,162.67
    51      $    83,000.00  $    64,747.99  $    18,252.01  $   608,609.56
    52      $    83,000.00  $    64,747.99  $    18,252.01  $   645,119.86
    53      $    83,000.00  $    64,747.99  $    18,252.01  $   682,725.47
    54      $    83,000.00  $    64,747.99  $    18,252.01  $   721,459.24
    55      $    83,000.00  $    64,747.99  $    18,252.01  $   761,355.03
    56      $    83,000.00  $    64,747.99  $    18,252.01  $   802,447.69
    57      $    83,000.00  $    64,747.99  $    18,252.01  $   844,773.13
    58      $    83,000.00  $    64,747.99  $    18,252.01  $   888,368.33
    59      $    83,000.00  $    64,747.99  $    18,252.01  $   933,271.39
    60      $    83,000.00  $    64,747.99  $    18,252.01  $   979,521.54
    61      $    83,000.00  $    64,747.99  $    18,252.01  $ 1,027,159.20
    62      $    83,000.00  $    64,747.99  $    18,252.01  $ 1,076,225.98
    63      $    83,000.00  $    64,747.99  $    18,252.01  $ 1,126,764.77
    64      $    83,000.00  $    64,747.99  $    18,252.01  $ 1,178,819.73
    65      $    83,000.00  $    64,747.99  $    18,252.01  $ 1,232,436.33
    66      $    83,000.00  $    64,747.99  $    18,252.01  $ 1,287,661.43
    67      $    83,000.00  $    64,747.99  $    18,252.01  $ 1,344,543.28
    68      $         0.00  $    64,747.99  $   -64,747.99  $ 1,320,131.59
    69      $         0.00  $    64,747.99  $   -64,747.99  $ 1,294,987.55
    70      $         0.00  $    64,747.99  $   -64,747.99  $ 1,269,089.18
    71      $         0.00  $    64,747.99  $   -64,747.99  $ 1,242,413.87
    72      $         0.00  $    64,747.99  $   -64,747.99  $ 1,214,938.29
    73      $         0.00  $    64,747.99  $   -64,747.99  $ 1,186,638.45
    74      $         0.00  $    64,747.99  $   -64,747.99  $ 1,157,489.62
    75      $         0.00  $    64,747.99  $   -64,747.99  $ 1,127,466.31
    76      $         0.00  $    64,747.99  $   -64,747.99  $ 1,096,542.31
    77      $         0.00  $    64,747.99  $   -64,747.99  $ 1,064,690.59
    78      $         0.00  $    64,747.99  $   -64,747.99  $ 1,031,883.32
    79      $         0.00  $    64,747.99  $   -64,747.99  $   998,091.83
    80      $         0.00  $    64,747.99  $   -64,747.99  $   963,286.60
    81      $         0.00  $    64,747.99  $   -64,747.99  $   927,437.20
    82      $         0.00  $    64,747.99  $   -64,747.99  $   890,512.33
    83      $         0.00  $    64,747.99  $   -64,747.99  $   852,479.71
    84      $         0.00  $    64,747.99  $   -64,747.99  $   813,306.11
    85      $         0.00  $    64,747.99  $   -64,747.99  $   772,957.30
    86      $         0.00  $    64,747.99  $   -64,747.99  $   731,398.03
    87      $         0.00  $    64,747.99  $   -64,747.99  $   688,591.98
    88      $         0.00  $    64,747.99  $   -64,747.99  $   644,501.75
    89      $         0.00  $    64,747.99  $   -64,747.99  $   599,088.81
    90      $         0.00  $    64,747.99  $   -64,747.99  $   552,313.49
    91      $         0.00  $    64,747.99  $   -64,747.99  $   504,134.90
    92      $         0.00  $    64,747.99  $   -64,747.99  $   454,510.96
    93      $         0.00  $    64,747.99  $   -64,747.99  $   403,398.30
    94      $         0.00  $    64,747.99  $   -64,747.99  $   350,752.26
    95      $         0.00  $    64,747.99  $   -64,747.99  $   296,526.84
    96      $         0.00  $    64,747.99  $   -64,747.99  $   240,674.65
    97      $         0.00  $    64,747.99  $   -64,747.99  $   183,146.90
    98      $         0.00  $    64,747.99  $   -64,747.99  $   123,893.32
    99      $         0.00  $    64,747.99  $   -64,747.99  $    62,862.13
    100     $         0.00  $    64,747.99  $   -64,747.99  $         0.00

Example 2: 22-year old, first job, $100,000 of student loan debt (i.e., negative assets):

    Welcome to the Life-Cycle Sustainable Spending Calculator.

    Enter the current inflation-indexed risk-free rate of return: 0.02
    Enter your age now: 22
    Enter your expected retirement age: 65
    Enter your current annual income: 45600

    You have 43 remaining working years with an income of $    45,600.00 per year.
    The present value of your human capital is about $ 1,306,967.24

    Enter the value of your financial assets: -100000
    Your economic net worth is: $ 1,206,967.24

    Your sustainable standard of living is about $    30,688.06 per year.
    To achieve this standard of living to age 100, you must save $    14,911.94 per year.

    Here is a annual summary of your financial plan:

    Age     Income          Consumption     Saving          Assets
    23      $    45,600.00  $    30,688.06  $    14,911.94  $   -87,088.06
    24      $    45,600.00  $    30,688.06  $    14,911.94  $   -73,917.88
    25      $    45,600.00  $    30,688.06  $    14,911.94  $   -60,484.30
    26      $    45,600.00  $    30,688.06  $    14,911.94  $   -46,782.04
    27      $    45,600.00  $    30,688.06  $    14,911.94  $   -32,805.74
    28      $    45,600.00  $    30,688.06  $    14,911.94  $   -18,549.91
    29      $    45,600.00  $    30,688.06  $    14,911.94  $    -4,008.97
    30      $    45,600.00  $    30,688.06  $    14,911.94  $    10,822.79
    31      $    45,600.00  $    30,688.06  $    14,911.94  $    25,951.19
    32      $    45,600.00  $    30,688.06  $    14,911.94  $    41,382.15
    33      $    45,600.00  $    30,688.06  $    14,911.94  $    57,121.74
    34      $    45,600.00  $    30,688.06  $    14,911.94  $    73,176.11
    35      $    45,600.00  $    30,688.06  $    14,911.94  $    89,551.58
    36      $    45,600.00  $    30,688.06  $    14,911.94  $   106,254.55
    37      $    45,600.00  $    30,688.06  $    14,911.94  $   123,291.58
    38      $    45,600.00  $    30,688.06  $    14,911.94  $   140,669.36
    39      $    45,600.00  $    30,688.06  $    14,911.94  $   158,394.68
    40      $    45,600.00  $    30,688.06  $    14,911.94  $   176,474.52
    41      $    45,600.00  $    30,688.06  $    14,911.94  $   194,915.95
    42      $    45,600.00  $    30,688.06  $    14,911.94  $   213,726.21
    43      $    45,600.00  $    30,688.06  $    14,911.94  $   232,912.68
    44      $    45,600.00  $    30,688.06  $    14,911.94  $   252,482.87
    45      $    45,600.00  $    30,688.06  $    14,911.94  $   272,444.47
    46      $    45,600.00  $    30,688.06  $    14,911.94  $   292,805.30
    47      $    45,600.00  $    30,688.06  $    14,911.94  $   313,573.35
    48      $    45,600.00  $    30,688.06  $    14,911.94  $   334,756.76
    49      $    45,600.00  $    30,688.06  $    14,911.94  $   356,363.83
    50      $    45,600.00  $    30,688.06  $    14,911.94  $   378,403.05
    51      $    45,600.00  $    30,688.06  $    14,911.94  $   400,883.05
    52      $    45,600.00  $    30,688.06  $    14,911.94  $   423,812.65
    53      $    45,600.00  $    30,688.06  $    14,911.94  $   447,200.85
    54      $    45,600.00  $    30,688.06  $    14,911.94  $   471,056.81
    55      $    45,600.00  $    30,688.06  $    14,911.94  $   495,389.88
    56      $    45,600.00  $    30,688.06  $    14,911.94  $   520,209.62
    57      $    45,600.00  $    30,688.06  $    14,911.94  $   545,525.76
    58      $    45,600.00  $    30,688.06  $    14,911.94  $   571,348.21
    59      $    45,600.00  $    30,688.06  $    14,911.94  $   597,687.12
    60      $    45,600.00  $    30,688.06  $    14,911.94  $   624,552.80
    61      $    45,600.00  $    30,688.06  $    14,911.94  $   651,955.80
    62      $    45,600.00  $    30,688.06  $    14,911.94  $   679,906.86
    63      $    45,600.00  $    30,688.06  $    14,911.94  $   708,416.93
    64      $    45,600.00  $    30,688.06  $    14,911.94  $   737,497.21
    65      $    45,600.00  $    30,688.06  $    14,911.94  $   767,159.10
    66      $         0.00  $    30,688.06  $   -30,688.06  $   751,814.22
    67      $         0.00  $    30,688.06  $   -30,688.06  $   736,162.45
    68      $         0.00  $    30,688.06  $   -30,688.06  $   720,197.64
    69      $         0.00  $    30,688.06  $   -30,688.06  $   703,913.53
    70      $         0.00  $    30,688.06  $   -30,688.06  $   687,303.74
    71      $         0.00  $    30,688.06  $   -30,688.06  $   670,361.76
    72      $         0.00  $    30,688.06  $   -30,688.06  $   653,080.94
    73      $         0.00  $    30,688.06  $   -30,688.06  $   635,454.50
    74      $         0.00  $    30,688.06  $   -30,688.06  $   617,475.53
    75      $         0.00  $    30,688.06  $   -30,688.06  $   599,136.98
    76      $         0.00  $    30,688.06  $   -30,688.06  $   580,431.66
    77      $         0.00  $    30,688.06  $   -30,688.06  $   561,352.24
    78      $         0.00  $    30,688.06  $   -30,688.06  $   541,891.22
    79      $         0.00  $    30,688.06  $   -30,688.06  $   522,040.99
    80      $         0.00  $    30,688.06  $   -30,688.06  $   501,793.75
    81      $         0.00  $    30,688.06  $   -30,688.06  $   481,141.56
    82      $         0.00  $    30,688.06  $   -30,688.06  $   460,076.34
    83      $         0.00  $    30,688.06  $   -30,688.06  $   438,589.80
    84      $         0.00  $    30,688.06  $   -30,688.06  $   416,673.54
    85      $         0.00  $    30,688.06  $   -30,688.06  $   394,318.95
    86      $         0.00  $    30,688.06  $   -30,688.06  $   371,517.27
    87      $         0.00  $    30,688.06  $   -30,688.06  $   348,259.56
    88      $         0.00  $    30,688.06  $   -30,688.06  $   324,536.69
    89      $         0.00  $    30,688.06  $   -30,688.06  $   300,339.37
    90      $         0.00  $    30,688.06  $   -30,688.06  $   275,658.10
    91      $         0.00  $    30,688.06  $   -30,688.06  $   250,483.20
    92      $         0.00  $    30,688.06  $   -30,688.06  $   224,804.81
    93      $         0.00  $    30,688.06  $   -30,688.06  $   198,612.84
    94      $         0.00  $    30,688.06  $   -30,688.06  $   171,897.04
    95      $         0.00  $    30,688.06  $   -30,688.06  $   144,646.92
    96      $         0.00  $    30,688.06  $   -30,688.06  $   116,851.80
    97      $         0.00  $    30,688.06  $   -30,688.06  $    88,500.78
    98      $         0.00  $    30,688.06  $   -30,688.06  $    59,582.74
    99      $         0.00  $    30,688.06  $   -30,688.06  $    30,086.33
    100     $         0.00  $    30,688.06  $   -30,688.06  $        -0.00

Implementation Details

Do your work in a file called a1task2.py. Save your file in the same directory as your file from task 1 (above). At the top of your file (after the header comment), write the following statement to be able to access the functions you wrote in task 1:

    from a1task1 import *
  1. Create a function dollar_format(amount), which takes a parameter amount which is a number, and returns a beautifully-formatted string of dollars and cents, including the dollar sign and comma-separated thousands and millions. Here are some sample test cases:

    >>> dollar_format(42)
    '$42.00'
    >>> dollar_format(1234.56)
    '$1,234.56'
    >>> dollar_format(9876543.21)
    '$9,876,543.21'
    

    Hints: You can accomplish this the easy way or the hard way.

    * The hardest way is with lots of if statements and arithmetic operations.
    
    * The easy way is with a small number if statements and string slicing.
    
    * The easiest way is by using Python 3.8's f-string with substitutions 
      and numeric formatting.
    
  2. Do the following tasks in a function called life_cycle_model. This function will interact with the user to collect inputs and display outputs. It does not take any parameters, and does not return any value.

    a. Welcome the user, and collect inputs for the rate of return, the user’s age now, retirement age, and current income. Print out the number of working years remaining and the income per year (use your dollar_format function to do the formatting).

    b. Calculate the human capital, which is the present value of the user’s lifetime income (i.e., an annuity). Use your pv_annuity function. Print out the present value of human capital (use your dollar_format function to do the formatting).

    c. Prompt the user for the amount of current assets. If there are no assets, the user can enter 0, and if there are debts the user can enter a negative number. Calculate the economic net worth as human capital plus assets. Print out the economic net worth (use your dollar_format function to do the formatting).

    d. Calculate the sustainable standard of living (i.e., consumption). Determine the number of years of consumption, as 100 - age. Use your annuity_payment function to calculate the amount of annual consumption that can be sustained from the economic net worth. Print out the annual standard of living (use your dollar_format function to do the formatting).

    e. Calculate the amount of annual savings required. Savings is income minus consumption. Print out the savings (use your dollar_format function to do the formatting).

    f. Generate a neatly-formatted table showing the income, consumption, savings, and assets for each year in the life-cycle model.

    Use a definite loop to iterate over the required years.
    Inside the loop, calculate the following values:

      savings = income - consumption
      assets = assets * (1 + rate of return) + savings
    

    (Still inside the loop) print out (on a single line) all the age, income, consumption, savings, and assets for that year.

Your program should be a self-contained execuatble file, i.e., when we run the file it should automatically call the life_cycle_model function. The best way to do this is using the form:

    if __name__ == '__main__':

        # call the function:
        life_cycle_model()

At the bottom of your file. Test that this works by running your program with several test cases!


Submitting Your Work

20 points; will be assignmed by code review

Log in to GradeScope to submit your work.

Be sure to name your files correctly!

Under the heading for Assignment 1, attach each of the 2 required files to your submission.

When you upload the files, the autograder will test your functions/programs.

Warning: Beware of Global print statements

  • The autograder script cannot handle print statements in the global scope, and their inclusion causes this error:

autograder_fail

*   Why does this happen? When the autograder imports your file, the `print` 
    statement(s) execute (at import time), which causes this error.

*   You can prevent this error by not having any `print` statements in the global scope.
    Instead, create an `if __name__ == '__main__':` section at the bottom of the file, and
    put any test cases/print statements in that controlled block. For example:

        if __name__ == '__main__':

            ## put test cases here:
            print('fv_lump_sum(0.05, 2, 100)', fv_lump_sum(0.05, 2, 100))

*   `print` statements inside of functions do not cause this problem.

Notes: