Problem Set 01

1. COUNTING VOWELS

Assume s is a string of lower case characters.

Write a program that counts up the number of vowels contained in the string s. Valid vowels are: 'a', 'e', 'i', 'o', and 'u'. For example, if s = 'azcbobobegghakl', your program should print:

                       Number of vowels: 5

In [3]:
s= 'wordsmith'
vowels = {'a','e','i','o','u'}
count = 0
for char in s:
    if char in vowels:
        count+=1
print "Number of vowels: " + str(count)


Number of vowels: 2

2. COUNTING BOBS

Assume 's' is a string of lower case characters.

Write a program that prints the number of times the string 'bob' occurs in s. For example, if s = 'azcbobobegghakl', then your program should print

                    Number of times bob occurs is: 2

In [4]:
s = 'azcbobobegghakl'
pattern = 'bob'
count =0
for position in range(0,len(s)):
    if s[position:position+3]==pattern:
        count+=1
print count


2

3. Counting and Grouping

A catering company has hired you to help with organizing and preparing customer's orders. You are given a list of each customer's desired items, and must write a program that will count the number of each items needed for the chefs to prepare. The items that a customer can order are: salad, hamburger, and water.

Write a function called item_order that takes as input a string named order. The string contains only words for the items the customer can order separated by one space. The function returns a string that counts the number of each item and consolidates them in the following order:

salad:[# salad] hamburger:[# hambruger] water:[# water]

If an order does not contain an item, then the count for that item is 0. Notice that each item is formatted as [name of the item][a colon symbol][count of the item] and all item groups are separated by a space.

For example:

If order = "salad water hamburger salad hamburger" then the function returns "salad:2 hamburger:2 water:1"

If order = "hamburger water hamburger" then the function returns "salad:0 hamburger:2 water:1"


In [86]:
def item_order(order):
    dishes = {'salad':0,'hamburger':0,'water':0}
    for dish_ordered in order.split(' '):
        if dish_ordered in dishes.keys():
            dishes[dish_ordered] +=1

    string = 'salad:' + str(dishes['salad']) + ' hamburger:' + str(dishes['hamburger']) + ' water:' + str(dishes['water'])
    return string

In [87]:
order = "hamburger water hamburger"
item_order(order)


Out[87]:
'salad:0 hamburger:2 water:1'

Problem Set 02

PAYING OFF CREDIT CARD DEBT

Each month, a credit card statement will come with the option for you to pay a minimum amount of your charge, usually 2% of the balance due. However, the credit card company earns money by charging interest on the balance that you don't pay. So even if you pay credit card payments on time, interest is still accruing on the outstanding balance.

Say you've made a \$5,000 purchase on a credit card with an 18% annual interest rate and a 2% minimum monthly payment rate. If you only pay the minimum monthly amount for a year, how much is the remaining balance?

You can think about this in the following way.

At the beginning of month 0 (when the credit card statement arrives), assume you owe an amount we will call $b_0$ (b for balance; subscript 0 to indicate this is the balance at month 0).

Any payment you make during that month is deducted from the balance. Let's call the payment you make in month 0, p_0. Thus, your unpaid balance for month 0, $ub_0$, is equal to $b_0−p_0$.

$$ ub_0=b_0 −p_0 $$

At the beginning of month 1, the credit card company will charge you interest on your unpaid balance. So if your annual interest rate is r, then at the beginning of month 1, your new balance is your previous unpaid balance $ub_0$, plus the interest on this unpaid balance for the month. In algebra, this new balance would be

$$ b_1=ub_0+r/12.0⋅ub_0 $$

In month 1, we will make another payment, p_1. That payment has to cover some of the interest costs, so it does not completely go towards paying off the original charge. The balance at the beginning of month 2, b_2, can be calculated by first calculating the unpaid balance after paying p_1, then by adding the interest accrued:

$$ ub_1=b_1−p_1 $$$$ b2=ub_1+r/12.0⋅ub_1 $$

If you choose just to pay off the minimum monthly payment each month, you will see that the compound interest will dramatically reduce your ability to lower your debt.

Let's look at an example. If you've got a \$ 5,000 balance on a credit card with 18% annual interest rate, and the minimum monthly payment is 2% of the current balance, we would have the following repayment schedule if you only pay the minimum payment each month:

Month Balance Minimum Payment Unpaid Balance Interest
0 5000.00 100 (= 5000 * 0.02) 4900 (= 5000 - 100) 73.50 (= 0.18/12.0 * 4900)
1 4973.50 (= 4900 + 73.50) 99.47 (= 4973.50 * 0.02) 4874.03 (= 4973.50 - 99.47) 73.11 (= 0.18/12.0 * 4874.03)
2 4947.14 (= 4874.03 + 73.11) 98.94 (= 4947.14 * 0.02) 4848.20 (= 4947.14 - 98.94) 72.72 (= 0.18/12.0 * 4848.20)

You can see that a lot of your payment is going to cover interest, and if you work this through month 12, you will see that after a year, you will have paid \$ **1165.63** and yet you will still owe \$ 4691.11 on what was originally a \$ 5000.00 debt. Pretty depressing!

1. PAYING THE MINIMUM

Write a program to calculate the credit card balance after one year if a person only pays the minimum monthly payment required by the credit card company each month.


In [ ]:
balance = 5000
months=12
payment_min = balance * monthlyPaymentRate
balance_remaining = balance - payment_min
interest = balance_remaining * (annualInterestRate/12.0)

In [34]:
def remainingBalance(balance,annualInterestRate,monthlyPaymentRate,months=12):
    balance_remaining =balance
    payment_min = 0
    for month in range(0,months):
        payment_min = balance_remaining * monthlyPaymentRate
        balance_remaining = balance_remaining - payment_min
        interest = balance_remaining * ((annualInterestRate)/12.0)
        balance_remaining += interest
        #print (payment_min,balance_remaining,interest)
    return round(balance_remaining,2)

remainingBalance(balance=5000,annualInterestRate=0.18,monthlyPaymentRate=0.02,months=12)


Out[34]:
4691.11

2. PAYING DEBT OFF IN A YEAR

Now write a program that calculates the minimum fixed monthly payment needed in order pay off a credit card balance within 12 months. By a fixed monthly payment, we mean a single number which does not change each month, but instead is a constant amount that will be paid each month.


In [ ]:
balance = 5000
months=12
payment_min = balance * monthlyPaymentRate
balance_remaining = balance - payment_min
interest = balance_remaining * (annualInterestRate/12.0)

In [37]:
def remainingBalance(balance,annualInterestRate,monthlyPaymentRate,months):
    balance_remaining =balance
    payment_min = 0
    for month in range(0,months):
        payment_min = monthlyPaymentRate
        balance_remaining = balance_remaining - payment_min
        interest = balance_remaining * ((annualInterestRate)/12.0)
        balance_remaining += interest
        
    return round(balance_remaining,2)
    
def payOffDebt(balance,annualInterestRate,monthlyPaymentRate=0.0,months=12):
    
    monthlyPaymentRate+=10
    balance_remaining = remainingBalance(balance,annualInterestRate,monthlyPaymentRate,months)
    rate = monthlyPaymentRate
    
    if balance_remaining<=0:
        print 'Lowest Payment: ' + str(rate)
    
    else:
        #print balance_remaining
        payOffDebt(balance,annualInterestRate,monthlyPaymentRate,months)
        
payOffDebt(3329,0.2)
payOffDebt(4773,0.2)
payOffDebt(3926,0.2)


Lowest Payment: 310.0
Lowest Payment: 440.0
Lowest Payment: 360.0

3. USING BISECTION SEARCH TO MAKE THE PROGRAM FASTER


In [14]:
range(12)


Out[14]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

In [17]:
def payOffDebtBisection(balance,annualInterestRate,months=12):
    
    balance_remaining = balance
    monthlyInterestRate = annualInterestRate/12.0
    
    lower_limit = balance/12.0
    upper_limit = balance * ((1+monthlyInterestRate)**12)/12.0
    
    tolerance =0.01
    
    while abs(balance_remaining) > tolerance:
        balance_remaining = balance
        payment = ( lower_limit + upper_limit )/2
        
        for month in range(12):
            balance_remaining = balance_remaining-payment
            balance_remaining = balance_remaining*(1+monthlyInterestRate)
        
        if balance_remaining<=0:
            upper_limit = payment
            
        else:
            lower_limit = payment
    print 'Lowest Payment: ' + str(round(payment, 2))
        
payOffDebtBisection(320000,0.2)
payOffDebtBisection(999999,0.18)


Lowest Payment: 29157.09
Lowest Payment: 90325.03