## 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 :

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 :

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:

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 = "hamburger water hamburger" then the function returns "salad:0 hamburger:2 water:1"

``````

In :

def item_order(order):
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 :

order = "hamburger water hamburger"
item_order(order)

``````
``````

Out:

``````

## 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?

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 :

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:

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 :

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 :

range(12)

``````
``````

Out:

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

``````
``````

In :

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

``````