15-110 Principles of Computing - Summer Two 2014

Programming Assignment 2 - due Thursday, July 3 by 9:00AM

Note: You are responsible for protecting your solutions to these problems from being seen by other students both physically (e.g., by looking over your shoulder) and electronically. In particular, since the lab machines use the Andrew File System to share files worldwide, you need to be careful that you do not put files in a place that is publicly accessible.

If you are doing the assignment on the Gates-Hillman Cluster machines we use in lab or on unix.andrew.cmu.edu, our recommendation is that you create a pa2 directory under ~/private/15110 for this assignment. That is, the new directory pa2 is inside a directory called 15110, which is inside the directory called private, which is inside your home directory. (Every new andrew account is set up with a private subdirectory within the account's home directory that only that account can access.) Please refer to Setting up Directories for information about managing your directories.

Overview

For this assignment, you will create a Python source file (that is, a text file containing Python code) for each of the problems below. You should store all of these files in a folder named pa2, which you will zip up and submit.

As you will discover this semester, computer programs are rarely correct when they are first written. They often have bugs. In addition to writing the code, you should test your code on multiple inputs, for which you independently know the correct output (e.g., by plugging the inputs into a calculator).

The Formulas

Write Python functions to calculate each formula as indicated below. The calculations should be performed with the full precision shown in the examples.

  1. [2 points] For an account with a deposit of \(P\) dollars that earns interest compounded continuously at an annual rate of \(r\) for \(t\) years, the final amount \(A\) of the account is given by the formula:

    \[A = Pe^{rt}\]

    (Note: \(r\) should be a decimal fraction, so 0.05 would be used to represent a 5% annual interest rate.)

    In interest.py, define a function compute_account(present_value, interest_rate, years) that calculates and returns the final amount that a deposit of present_value would grow to after years years when interest is compounded continously at an annual rate of interest_rate.

    In order to use the built-in definition of the constant e, you must put the following line at the beginning of your Python file:

    	import math
          
    Then you may use math.e in your Python code.

    Example usage:

    > python3 -i interest.py
    >> compute_account(10231.51, 0.05, 5) 
    13137.518891094793
    >> compute_account(998.95, 0.10, 10)
    2715.4276325391634
    >>
    
  2. [2 points] The volume of a cone can be calculated from the radius \(r\) of its base and its height \(h\) using the formula:

    \[\frac{1}{3}\pi r^2 h\]
    1. In cone.py, write a Python function cone_volume(radius,height) that calculates and returns the volume of a cone whose base's radius is radius and whose height is height. In order to use the definition of \(\pi\), put the following line as the first line of your Python file:

      	import math
            
      Use math.pi for \(\pi\) in your Python code

    2. Consider the three-dimensional object shown in the figure to the right, which consists of two cones whose heights are 10m and 15m, respectively, and which share a base, whose radius is 4m.

      In the same file cone.py, define a Python function print_object_volume() that calls the function cone_volume to calculate the total volume occupied by the pictured object (i.e., the total volume occupied by the two cones that make up the object). It should return None after printing the following line of text:

      The total volume of the two cones is XXXX.XXXXXXXXXXX.
      

      (Replacing XXXX.XXXXXXXXXXX with the calculated volume.)

      Your print_object_volume() function must be defined without directly calculating the volume of the cones. Rather you must call the cone_volume function you wrote for part a.

    Example usage:

    > python3 -i cone.py
    >>> cone_volume(4,10)
    167.55160819145564
    >>> cone_volume(4,15)
    251.32741228718342
    >>> print_object_volume()
    The total volume of the two cones is  418.87902047863906
        
    Note that Python does not display None even though that is the value returned.

  3. [4 points] A piano tuner working in the Pittsburgh area a must collect sales tax from her customers. The rate for Allegheny County is 7%, but for adjoining Beaver County it is 6%. The tax can be calculated by the function \[ T = fr \] where \(T\) is the sales tax in dollars, \(f\) is the tuning fee in dollars, and \(r\) is the tax rate represented as a decimal (so 7% is .07).
    1. Use a calculator to determine the amount of sales tax in dollars that the piano tuner should collect for a tuning in Allegheny County with a fee of $150.

      Your answer should be $10.50. (There is nothing to submit, this is just an exercise.)

    2. In the file tax.py, define a Python function compute_sales_tax(f, r) that returns the amount of sales tax that the piano tuner must collect, assuming the tuning fee is equal to f and the tax rate is equal to r (represented as a decimal fraction, e.g. .07, not a percentage).

    3. The piano tuner calculates the total sales tax she has collected every day. Suppose that one day she does a tuning in Allegheny County for a fee of $140, another tuning in Allegheny County for $170, and one in Beaver County for $175.

      In the same file tax.py, define another function compute_workday_tax(). This function must call the function compute_sales_tax you wrote with the correct arguments to compute and print out the amount of sales tax the piano tuner has collected that day. Do not simply recalculate what the sales tax function does. The function should return None (again, don't expect Python to display the value None unless you directly request it as above).

    4. It would be convenient to have a pre-calculated table of tax amounts for the usual fees. In the same file, define another function display_tax_table. This function must use the function compute_sales_tax to compute and print tuning fees from $130 to $150 (inclusive) in increments of $5, each with its corresponding sales tax amount for each possible tax rate, the first number for Beaver County, the second number for Allegheny County. The function should return None.

    Example usage:

    > python3 -i tax.py
    >>> compute_sales_tax(140,.07)
    9.8
    >>> compute_workday_tax()
    32.2
    >>> display_tax_table()
    Sales tax amounts for fee of 130 : 7.8 , 9.100000000000001
    Sales tax amounts for fee of 135 : 8.1 , 9.450000000000001
    Sales tax amounts for fee of 140 : 8.4 , 9.8
    Sales tax amounts for fee of 145 : 8.7 , 10.15
    Sales tax amounts for fee of 150 : 9.0 , 10.500000000000002
    
  4. [2 points] In this problem you will work with the digits of positive integers. The operators // and % are most commonly used for division and getting the remainder, respectively. Observe the following with respect to integer division and modular arithmetic using modulus 10:

    Given this information, write a Python function called get_digit(num, pos) in the file digit.py that takes in any positive integer num and the position of the desired digit pos and returns the digit in the desired position. Assume that the function will always be called with a value for pos that is greater than zero and no larger than the number of digits in num. Furthermore, assume that a pos of 1 indicates the rightmost digit, a pos of 2 indicates the digit second from the right and so on.

    Example usage:

    > python3 -i digit.py
    >> get_digit(73, 1)
    3
    >> get_digit(9824759837450, 8)
    5
    >>
    

Submission

You should now have a pa2 directory that contains the files interest.py, cone.py, tax.py and digit.py. Zip up your directory and hand it in.