Featured Post

The Pin of Contents

OI! CLICK DIS TO HELP YA FIND YER WAY! Your hub for everything Gordo... if you happen to share my narrow view of what 'everything Gor...

Thursday, February 11, 2016

I'm learning to code! Wanna learn with me?


I'm motivated to educate myself in a more practical way! Must be some kind of miracle. Let's see how long it lasts, shall we?

I've never been a big note-taker. It's probably time to change that, particularly because I'm going to be learning from a 'custom curriculum' compiled by agupieware.com. As such, I won't have classmates, in a traditional sense, won't be able to ask questions, and only have myself to account to. As such, maybe making notes in a public place can help provide the illusion of social interactivity.

Who knows, maybe I'll even snag some tips from the occasional eccentric who stumbles across a hashtag =P.

Thus far, I'm very early into the introductory phase: Lecture 3 in 'introduction to computer science and programming' from MIT. Remedial, even to me, who hasn't had any experience coding since High School and the occasional HTML. Still, I expect it's gonna ramp up pretty quick.

Anyhoo. Let's work on the assignments.

Crazy thinks. Gord's notes!

Let's learn by riding the stream of thought!

The assignment is themed; essentially one big story problem. Here's the premise:

------ 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 18% annual interest rate and 2% minimum monthly payment rate. After a year, how much is the remaining balance? Use the following equations.

Minimum monthly payment = Minimum monthly payment rate x Balance (Minimum monthly payment gets split into interest paid and principal paid)
Interest Paid = Annual interest rate / 12 months x Balance
Principal paid = Minimum monthly payment – Interest paid
Remaining balance = Balance – Principal paid

For month 1, we can compute the minimum monthly payment by taking 2% of the balance:

Minimum monthly payment = .02 x $5000.0 = $100.0

We can’t simply deduct this from the balance because there is compounding interest. Of this $100 monthly payment, compute how much will go to paying off interest and how much will go to paying off the principal. Remember that it’s the annual interest rate that is given, so we need to divide it by 12 to get the monthly interest rate.

Interest paid = .18/12.0 x $5000.0 = $75.0
Principal paid = $100.0 – $75.0 = $25

The remaining balance at the end of the first month will be the principal paid this month subtracted from the balance at the start of the month.

Remaining balance = $5000.0 – $25.0 = $4975.0

 For month 2, we repeat the same steps:

Minimum monthly payment = .02 x $4975.0 = $99.50
Interest Paid = .18/12.0 x $4975.0 = $74.63
Principal Paid = $99.50 – $74.63 = $24.87
Remaining Balance = $4975.0 – $24.87 = $4950.13

After 12 months, the total amount paid is $1167.55, leaving an outstanding balance of $4708.10. Pretty depressing! -------

Credit is such a racket. Anyhoo! Apparently there's 3 bits of code to write for this assignment. Let's check the instructions for this first one:

------Paying the Minimum

Problem 1

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.

Use raw_input() to ask for the following three floating point numbers:

1. the outstanding balance on the credit card
2. annual interest rate
3. minimum monthly payment rate

For each month, print the minimum monthly payment, remaining balance, principle paid in the format shown in the test cases below. All numbers should be rounded to the nearest penny. Finally, print the result, which should include the total amount paid that year and the remaining balance. ------

Man. For being such a rudimentary program, it sure could help a lot of people. You know... the hypothetical final product, at least. Alright, I remember raw_input from last time. Somewhat. You write code that looks something like x = raw_input(Command the user to tell us what the hell he wants in these parenthesis)

The = and raw_input() are the key syntax here. = by itself transforms whatever precedes it into a variable - in this case, the familiar x. Even though x is first in the line, it's meaningless until = defines it - or tries to, with what follows.

Which is, of course, raw_input(). I think the lecturer said more recent versions of python cut the raw_ part of the syntax? Whatevs, we can roll with that punch when it's thrown. Back to the subject: raw_input instructs python to prompt the user to provide it with information.

So together, = raw_input() assigns the user's input to the variable preceding =. Fun refresher. SO! Apply it to the instructions, Gordo.

Ah, one last thing. We need to use the 'float' type so it only accepts numbers as input. We use 'float' instead of 'int' because 'int' won't accept decimals... I think.

outsbal = float(raw_input('Enter the amount you owe your idiot butthole creditors (to the nearest penny): '))
annint = float(raw_input('Enter the percent theyre going to skim off each year (the annual interest rate, and use a decimal to represent the percent. Dummy.): '))
minpay = float(raw_input('Enter the minimum you gotta fork over before they break your kneecap (as a decimal representing the percent): '))


I think that'll properly record all the input. We can make sure by commanding python to print these values, so let's do just that:

print 'You owe 'outsbal
print 'They skim 'annint 'converted to a percent annually.'
print 'You gotta fork over 'minpay 'times the current balance each month to stay afloat.'

Gonna test all this out. Ten bucks says I broke something...

Ha! You owe me Ten bucks. We forgot about using commas to separate print command components. It needs to look like this:

print 'You owe $', outsbal
print 'They skim ', annint, 'converted to a percent annually.'
print 'You gotta fork over ', minpay, 'times the current balance each month to stay afloat.'

Ironically, we succeeded in the essential part of the code and broke it in the part that tests the input. So, tiny success; we've defined 3 variables and asked for the user to define them. Moving on.

Now comes a hard part. We need to print a whole bunch of calculations based on this information, and we want to do it efficiently. 1 option is to use the same variables and transform them as we go; outsbal transforms with each month after the monthly payment is subtracted. The weakness here is the idea that the program will 'forget' what the original outstanding balance was.

The other option is to create a new variable for each month. I hate this idea and my initial reflex is we don't need to really consider this idea.

Of course, the option we'll choose is between: we'll create 1 new variable to remember the original balance, then let the program transform outsbal as it goes. So we'll add the following line of code to remember the original balance:

oribal = outsbal

Ran a quick test, and yes, this works: variables can be commanded to copy the value of another variable. Neat! Now we can move on again.

Next comes figuring out the calculation we'll make the computer do. Wait a second, math? Dammit, what am I, an accountant? Why're you assuming I know anything about compound interest? Ugh, whatever. I'll figure it out, but I'll resent you while I do it.

So. This sadist has provided us with the 'Jeopardy' answers to the questions our program will ask. We know what the data should look like if our program calculates the input correctly. In this case, the minimum monthly payment should be $96 dollars (2% of $4800 outstanding balance) Yep, easy enough. Alright, now for the most powerful force in the universe: interest. Annual interest rate is 20%. ...what exactly does that mean? That, assuming we pay the loan off in a year, the total amount paid should be 4800 * 1.2, yes? Okay. So that would be...5760. The interest would be $960. 10 times the minimum monthly payment. Ohmygaaaaawd this is dumb; alright, rally Gordo.

What are we trying to determine again? Well, we're trying to figure out how much a minimum monthly payment subtracts from the outstanding balance. We know the minimum monthly payment is $96. Because we know the Jeopardy! answers, we know that the first monthly payment is supposed to subtract $16 from the outstanding  balance for a remaining balance of $4784. Which means we pay $80 in interest for the month. Well, 960/80 = 12, because of course it does, because that's the number of months in a year. This wasn't nearly as hard as I made it out to be, was it?

The first step in the equation is to determine the minimum payment for the month. 4800 (outstanding balance) divided by minimum payment rate (2%). That equals 96. Next we determine the interest that needs to be paid that month. To do that, you apply the interest rate to the outstanding balance - 20% of $4800 is 960. 'Annual' means that's how much interest accrues over a full year, and since we're only paying for 1/12th of a year, we divide that annual interest by 12. We owe $80 in interest this month.

Finally, we subtract the interest from the minimum, then subtract that difference from the outstanding balance. At this stage, it means 4800-(96-80=4784. Let's bring that back to variables:

outsbal-((minpay*outsbal)-((annint*outsbal)/12))

Whew. Can we test that as the code? Let's have this equation transform outsbal and then print the result.

outsbal = (outsbal-((minpay*outsbal)-((annint*outsbal)/12)))
print outsbal

Holy butt, it exactly worked. I'm such a genius! What time did I start doing this? Let's just say it was an hour and a half ago. I'm a slow genius.

Alright, time to apply it harder. Let's print out everything we need for the month. This is gonna mean more variables. We need to display the monthly payment due: paydue. We need to display how much of that payment goes towards the principle: principle. The final bit of data for the month is just transformed outsbal, so no new variable needed there. Apply!

paydue = minpay*outsbal
print 'The minimum payment is $', paydue, 'this month.'
principle = paydue-((annint*outsbal)/12)
print 'Interest means you only paid $', principle, 'towards the outstanding balance.'
outsbal = outsbal-principle
print 'This means your new balance is $', outsbal

Success!

The next step is to repeat this step 12 times. We could write a linear program, but that's super inefficient. We want a loop - we want the computer to repeat this step 12 times with as little codes as possible, so we use a loop to make this code (or something like it) to repeat 12 times. Also, we need to keep track of how much we paid over the year - including interest! - so we can print it out once the loop concludes. That means a new variable: yearlytotal

That sounds easy, let's do the variable first:

paydue = minpay*outsbal
print 'The minimum payment is $', paydue, 'this month.'
principle = paydue-((annint*outsbal)/12)
print 'Interest means you only paid $', principle, 'towards the outstanding balance.'
outsbal = outsbal-principle

print 'This means your new balance is $', outsbal
yearlytotal = yearlytotal + paydue

Now we need to put that in a loop. Like, the whole damn thing. What's that look like? Lemme find the syntax real quick: the lecture is using a 'while' loop for its example cube root calculation, so let's see if we can for this, too.

while abs(ans**2-x) >= epsilon and ans <= x:
       ans += 0.00001
       numGuesses += 1

What this says in english is: while the absolute value of this function () is greater than or equal to the epsilon variable and the ans variable is less than or equal to x, repeat the loop. Looks like this += is a shortcut for my 'yearlytotal = yearlytotal + paydue' line, lemme integrate that rq...

paydue = minpay*outsbal
print 'The minimum payment is $', paydue, 'this month.'
principle = paydue-((annint*outsbal)/12)
print 'Interest means you only paid $', principle, 'towards the outstanding balance.'
outsbal -= principle

print 'This means your new balance is $', outsbal
yearlytotal += paydue

Hallelujah. Okay! Now, let's make a loop that terminates after 12 rounds. While we're at it, let's display each month in succession. This will require more variables. deadline to count down to the first anniversary and... do we need a variable to separate the months? I think we can get away with print 'Month ', 12-deadline, can't we?

deadline = 11
yearlytotal = 0
while deadline >= 0 and outsbal >= 0.00:
    print 'Month ', 12-deadline
    paydue = minpay*outsbal
    print 'The minimum payment is $', paydue, 'this month.'
    principle = paydue-((annint*outsbal)/12)
    print 'Interest means you only paid $', principle, 'towards the outstanding balance.'
    outsbal -= principle
    print 'This means your new balance is $',outsbal
    yearlytotal += paydue
    deadline -= 1

Works perfectly. Oo, I got chills! Okay, not really. There is a flaw! we need to keep it rounded to the penny. Python has a round function, let's find the syntax. It is...round(). Around the variable? No the lecture was coy, so let's just test it... no. Put round() around the function that defines the variable. This works perfectly:

outsbal = float(raw_input('Enter the amount you owe your idiot butthole creditors (to the nearest penny): '))
annint = float(raw_input('Enter the percent theyre going to skim off each year (the annual interest rate, and use a decimal to represent the percent. Dummy.): '))
minpay = float(raw_input('Enter the minimum you gotta fork over before they break your kneecap (as a decimal representing the percent): '))

oribal = outsbal

print 'You owe $', outsbal
print 'They skim ', annint, 'converted to a percent annually.'
print 'You gotta fork over ', minpay, 'times the current balance each month to stay afloat.'

deadline = 11
yearlytotal = 0
while deadline >= 0 and outsbal >= 0.00:
    print 'Month ', 12-deadline
    paydue = minpay*outsbal
    print 'The minimum payment is $', paydue, 'this month.'
    principle = paydue-((annint*outsbal)/12)
    print 'Interest means you only paid $', principle, 'towards the outstanding balance.'
    outsbal -= principle
    print 'This means your new balance is $',outsbal
    yearlytotal += paydue
    deadline -= 1

print 'Remember, you originally owed $', oribal

Okay, this exactly matches the Jeopardy! results! There's a 2nd set to test, though; we need to test this with 4% minimum payment. Does it match? ... yes it does. BOOM! This completed the problem! There are 2 more, but before we get to them, let's satisfy our curiosity and compute how much we wasted on interest this year, just to insult ourselves. Turns out, it looks like this:

##
outsbal = float(raw_input('Enter the amount you owe your idiot butthole creditors (to the nearest penny): '))
annint = float(raw_input('Enter the percent theyre going to skim off each year (the annual interest rate, and use a decimal to represent the percent. Dummy.): '))
minpay = float(raw_input('Enter the minimum you gotta fork over before they break your kneecap (as a decimal representing the percent): '))

oribal = outsbal

print 'You owe $', outsbal
print 'They skim ', annint, 'converted to a percent annually.'
print 'You gotta fork over ', minpay, 'times the current balance each month to stay afloat.'

deadline = 11
yearlytotal = float(0)
while deadline >= 0 and outsbal >= 0.00:
    print 'Month ', 12-deadline
    paydue = round(minpay*outsbal,2)
    print 'The minimum payment is $', paydue, 'this month.'
    principle = round(paydue-((annint*outsbal)/12),2)
    print 'Interest means you only paid $', principle, 'towards the outstanding balance.'
    outsbal -= principle
    print 'This means your new balance is $',outsbal
    yearlytotal += paydue
    deadline -= 1

print 'You paid $', yearlytotal, 'this year, you tool! And yet, your outstanding balance is still $', outsbal
print 'Remember, you originally owed $', oribal, '. That means your lenders got $', yearlytotal-(oribal-outsbal), 'in pure interest. Damn you, capitalism!'

##

That's the entire program. You can take my word for it, it works to the specifications of the assignment! Problem 1/3 down, ~3 hours later. Huh, wonder how that compares to the average student at MIT in 2011 taking 6.00SC Introduction to Computer Science and Programming. Eh, who cares? This feels like an achievement for me.

I did this after working all night! I'ma call it a success. We'll get back to it soon, or if not, we'll lose at life some more. We'll see what happens.

With that, the stream of thought ends.

Whew. Alright. This post contains curriculum from MIT OpenCourseWare http://ocw.mit.edu. This was my solution to problem 1 in problem set 1 of 6.00 SC Introduction to Computer Science and Programming ('due' for lecture 4, link here)

Thanks Boston, and agupieware.com. I'm a little more enriched today.

No comments:

Post a Comment