Tuesday, August 13, 2013

Bug-Checking a Program

Thought I might go ahead and post this, cuz why not. Work has somewhat slowed down as I begin writing this at 2:48 on a Tuesday afternoon (though I am tempting fate with that statement), and I've had enough free time to work on this so far...

The program is supposed to ask for the total amount of a loan, the interest rate the loan was taken at, and the monthly payment. Note that I am posting this despite the fact that I KNOW there is something up with my calculations -- otherwise, I wouldn't be having a problem!

The example in the book states:

Amount of Loan: 20000.00
Interest Rate: 6.0
Monthly Payment: 386.66

Balance remaining after first payment: $19713.34
Balance remaining after second payment: $19425.25
Balance remaining after third payment: $19135.71

Seeing as this is the easiest way to tell if my own calculations are correct, I'm using this as a constant. So, here's the code I've come up with, after tweaking it for a bit and adding some variables:

#include <stdio.h>
#define months 12

int main (void)
{
   float loan_total, interest, interest_rate;
   float monthly_pymt, balance;
   float balance_first, balance_second, balance_third;

   printf("Enter Loan Amount: ");
   scanf("%f", &loan_total);

   printf("Enter Interest Rate: ");
   scanf("%f", &interest);

   printf("Enter Monthly Payment: ");
   scanf("%f", &monthly_pymt);

   interest_rate = (interest/100)/months;
      /* 100 is used to turn the value given as the interest rate
      into a percentage */
   balance = loan_total - monthly_pymt;
   balance_first = balance + (balance * interest_rate);

   printf("Balance after first payment: %.2f\n", balance_first);

   balance = balance_first - monthly_pymt;
   balance_second = balance + (balance * interest_rate);

   printf("Balance after second payment: %.2f\n", balance_second);

   balance = balance_second - monthly_pymt;
   balance_third = balance + (balance * interest_rate);

   printf("Balance after third payment: %.2f\n", balance_third);

   return 0;

}

This was a test on my part, and I've already ruled out the possibility that balance is retaining its first value throughout the program. When entering the same credentials, here is what the above program returns:

Enter Loan Amount: 20000.00
Enter Interest Rate: 6.0
Enter Monthly Payment: 386.66

Balance after first payment: 19711.41
Balance after second payment: 19421.37
Balance after third payment: 19129.88

Pennies of a difference! Okay, maybe a few dollars. But still! Naturally, the next step is to check over the equations to make sure they are doing what they need to do...

And I think I found it. 

balance_first = balance + (balance * interest_rate);

The balance after the first payment is off by approximately 2.50 because the interest is being calculated against the updated balance here -- I think it needs to be calculated against the original loan amount.

balance_first = balance + (loan_amount * interest_rate);

This should even out the rest... Gonna run a quick test.

Enter Loan Amount: 20000.00
Enter Interest Rate: 6.0
Enter Monthly Payment: 386.66

Balance after first payment: 19713.34
Balance after second payment: 19423.31
Balance after third payment: 19131.84

Well, it fixed the first payment. But I see exactly what needs to change now!

balance_second = balance + (balance_first * interest_rate);

balance_third = balance + (balance_second * interest_rate);

Testing with this minor change...

Enter Loan Amount: 20000
Enter Interest Rate: 6.0
Enter Monthly Payment: 386.66

Balance after first payment: 19713.34
Balance after second payment: 19425.25
Balance after third payment: 19135.71

Hah! Yes! It is now returning the correct amounts!! I never did like accounting... It can be somewhat confusing. The problem essentially came from the interest being calculated with the newly initialized balance value, instead of the balance that had been reported for the previous month. Of course, interest isn't going to take into consideration that you are making a payment this month -- it's going to accrue based on the last month's balance. I swapped out those variables so the interest calculated correctly, and voila!

So there. A bug-checking process for you all! I am now off to take notes on Chapter 3!! See you all when its time for more programming exercises!!

Feeling Confident

I have this tendency. I will sit down and start writing a program, then get halfway through it and realize the entire logic of the thing is fucked.

I started on this exercise around 9:30 or 10 this morning (though it has taken so long partially due to the nature of being at work and actually having to... well... work). The exercise is to write a program that will take an original dollar amount, and split it into twenties, tens, fives, and ones.

Oh man. When I wrote it the first time? I thought I had too many variables to begin with, so I tried to make the variables I had do crazy things. I should have saved it. I can't remember exactly what I did, but it ended up with hilarious answers like:

$20 bills: 3
$10 bills: 0
$5 bills: -13
$1 bills: -137

I couldn't help but laugh and delete the whole thing, ahahaha...

After tweaking and pouring over my graphing calculator and a few paper scraps with notes on them, I did get it working though! As of 11:45, here is my working USD splitting program:


#include <stdio.h>
#define twenty 20
#define ten 10
#define five 5
#define one 1

int main (void)
{
   int original_amount;
   int twenty_bills, ten_bills, five_bills, one_bills;
   int orig_after_twen, orig_after_ten, orig_after_five;

   printf("Please enter the original dollar amount: ");
   scanf("%d", &original_amount);

   twenty_bills = original_amount/twenty;
   orig_after_twen = original_amount - (twenty_bills * twenty);

   printf("$20 bills: %d\n", twenty_bills);

   ten_bills = orig_after_twen/ten;
   orig_after_ten = orig_after_twen - (ten_bills * ten);

   printf("$10 bills: %d\n", ten_bills);

   five_bills = orig_after_ten/five;
   orig_after_five = orig_after_ten - (five_bills * five);

   printf("$5 bills: %d\n", five_bills);

   one_bills = orig_after_five/one;

   printf("$1 bills: %d\n", one_bills);

   return 0;
}

Valuable Lesson Learned

So, last night I was working some more on my programming projects. I got through one of them with no trouble at all, but the next one was giving me a fit. I had to write a program to ask for a value for x, then compute that value in a fifth degree polynomial.

My lesson came after I had corrected the errors and warnings that was keeping the program from compiling. I entered the value I chose for x, and the answer was -6. I entered another value for x... and the answer was still -6. It seemed way off to me.

Here's a look at the code I had written:

#include <stdio.h>

int main (void)
{
   float x, final_value;

   final_value = ((((3*x+2)*x-5)*x-1)*x+7)*x-6;  

       /* By the way, this is an example of Horner's Method, which allows
      for polynomials to be solved, despite C not having an exponential 
      function */

   printf("For the polynomial 3x^5 + 2x^4 - 5x^3 - x^2 + 7x - 6\n");
   printf("Please enter a value for x: ");
   scanf("%f", &x);
   
   printf("Final answer: %.1f\n", final_value);

   return 0;

}

Most people will probably find the issue immediately, but it was totally baffling me. It got to the point where I had to ask my fiance for help. He did some tests, such as changing the final integer of the polynomial to 4. When he ran that test, the answer the program gave was -4 instead of -6!! Fortunately, he knew what to do...

#include <stdio.h>

int main (void)
{
   float x, final_value;

   printf("For the polynomial 3x^5 + 2x^4 - 5x^3 - x^2 + 7x - 6\n");
   printf("Please enter a value for x: ");
   scanf("%f", &x);

   final_value = ((((3*x+2)*x-5)*x-1)*x+7)*x-6;

   printf("Final answer: %.1f\n", final_value);

   return 0;
}

Can we say DERP??? In the first example, x hadn't been initialized because the polynomial came first in the program. It assumed x must be 0, solved the polynomial, stored the final integer (because everything else had been multiplied by 0, because x was equal to 0) as the value of final_value, and returned that every time. It was working correctly! Just not the way I wanted it to!!

In the second example, x is initialized by scanf right off the bat. THEN the program enters it into the polynomial, returning final_value with x equivalent to the value initialized with scanf.

Ahhhhhhhhhhhhh....

Monday, August 12, 2013

Quietly Lurking, Quietly Working

Oh man, I've been pulled in so many different directions lately.

Over the past few weeks, I have:

  • Watched Last of Us from start to finish as my fiance played it (WOW, what an amazing game)
  • Resubbed to World of Warcraft (ugh, Mists is terrible)
  • Started playing Guild Wars 2 again
  • WRITTEN A LOT OF STUFF
  • Watched Minority Report, Tron, Tron: Legacy, The Fifth Element, Daybreakers, and kept up with Breaking Bad and Dexter
  • Messed around with C
  • Done some really fulfilling sketches for character designs
I've been really really busy. But the main reason I'm posting today is to say, "LOOK, LOOK!! I'm coding things on my own!!"

Take a gander! :)

These are exercises in my textbook -- which I have since decided that taking the notes down in my notebook is time-consuming enough... I don't think I'll be uploading them to this blog anymore. Instead, I'll be sharing the source that I write, when I feel like it. C: I'm stingy, I know.

So, the program I'm particularly fond of at this time is this exercise. I was prompted to find the volume of a sphere using a constant. So I did:

#include <stdio.h>
#define RADIUS 10.0f

int main(void)
{
   float volume;

   volume = (4.0f/3.0f * 3.14159 * (RADIUS * RADIUS * RADIUS));

   printf("Radius = %.1f\n", RADIUS);
   printf("Volume = %.3f\n", volume);

   return 0;

}

It was pretty nifty! Compiled and performed just fine out of Xcode (which is what I use on Mac because I haven't had time to investigate any others -- on the Zombie, I've just been using Mousepad to make changes so far). But I wondered if there was another way to do it. So I experimented...

#include <stdio.h>

int main(void)
{
   float radius, volume;

   radius = 10.0f
   volume = (4.0f/3.0f * 3.14159 * (radius * radius * radius));

   printf("Radius = %.1f\n", radius);
   printf("Volume = %.3f\n", volume);

   return 0;

}

Wouldn't you know! It compiled and worked just fine, too!! Gave the same answer I calculated manually on my calculator (which is 4188.787, rounded as the final decimal repeats). I'm so thrilled!

The second part of the exercise stated to alter the program so the user enters the radius before the calculation is made. Here goes:

#include <stdio.h>

int main(void)
{
   float radius, volume;

   printf("Enter radius of sphere: ");
   scanf("%f", &radius);

   volume = (4.0f/3.0f * 3.14159 * (radius * radius * radius));
   printf("Volume of sphere: %.3f\n", volume);

return 0;
}

Ahh, works perfectly. So I now have a fifteen line program that calculates the volume of a sphere... You know, just in case. ;D