I apparently had this written back in October of last year when I was working on a calendar program in C, but I never posted it because it was titled "To be written tomorrow..." and I obviously got fucking distracted. Anyway, here's my (very likely hackish) calendar program.
After mulling over this ALL day, here is the answer I've come up with for this programming project.
/* Write a program that prints a calendar. */
#include <stdio.h>
int main (int argc, char* argv[]) {
int days_month, week_begin, var1, var2;
printf("Enter the number of days in the month: ");
scanf("%d", &days_month);
printf("Enter the day of the week the first day falls upon (1=Sun, 7=Sat): ");
scanf("%d", &week_begin);
var2 = 1;
while (week_begin > var2) {
printf(" ");
var2++;
}
for (var1 = 1; days_month >= var1; var1++, ++week_begin) {
printf("%3d", var1);
if (week_begin >= 7) {
printf("\n");
week_begin -= 7;
}
}
printf("\n");
return 0;
}
I looked up the answer in the book answer key and 50% of my program is almost identical to the author's program. Woohoo!
Unfortunately, that last gnarly bit with the if statement is vastly different from his. He used all sorts of maths like remainder and variables - 1 * variables to get his answer. I can't see the relationships of numbers quite that easily... yet. :(
Showing posts with label success. Show all posts
Showing posts with label success. Show all posts
Monday, March 7, 2016
Tuesday, September 15, 2015
EXCITE
I got it to work!!!!!!
All I had to do was change the variable being tested for zero value, and the location of the test!!! I had designed it one way at first, and then changed a few variables around and forgotten to change that one very important detail.
The more I think about it, the more this program is probably extremely hackish. The whole point of the project was to create a program that would take a whole, non-negative, non-zero number and repeat it back in reverse order.
In the book, my hint was to use a do loop to continuously divide the input by 10 until it reached 0. That was fine and all, but every time it divided by 10, it would give me answers like 9876, 987, 98, 9. If I only used modulo to get the remainder, I would consistently get the last digit.
So I started thinking: if I needed the last digit of each result of dividing the entry, why not use mod?
From this frame of thinking, I realize that I probably went the extra mile and made this more complex than it should be. Here is my first working program, though:
#include <stdio.h>
int main(int argc, char* argv[]) {
int entry, right_digit, left_digits, MOD, DIVISOR;
// these are named to reflect the position of the digit in the input
printf("Enter a whole, non-negative number with any amount of digits: ");
scanf("%d", &entry);
MOD = 10;
DIVISOR = 10;
// This takes care of the right-most digit, and prints it on the left
right_digit = entry % MOD;
printf("%d", right_digit);
// my hint is to use a do loop for the left digits
do {
MOD *= 10;
left_digits = entry;
left_digits %= MOD;
left_digits /= DIVISOR;
if (left_digits <= 0) {
break;
}
printf("%d", left_digits);
DIVISOR *= 10;
} while (left_digits > 0);
printf("\n");
return 0;
}
Skip past all of the printf/scanf nonsense that comes before the actual maths.
The right-most digit of the entry is taken care of first, because it needs to be printed on the far left if the number is to be reversed. Assume we use the number 5932 as our entry. The remainder of 5932 % 10 is 2. 2 is printed first.
Once that's done, we move into the do loop.
MOD starts out at 10 for the first calculation. The first part of the do loop multiplies MOD by 10.
left_digits is then assigned the value of entry. I worked with the original value through this because I couldn't figure out how else to do it (granted, I also couldn't figure out what was decrementing to 0 to give me a floating point exception).
left_digits is then divided by 100 and the remainder is stored back into left_digits. Assuming the original entry is 5932, for example, the remainder is 32.
left_digits is then divided by DIVISOR, which also begins at 10. Because it is an integer, and assuming we continue using the example above, left_digits is assigned the value of 3.
There is a conditional here to end the loop prematurely if left_digits is less than or equal to 0.
left_digits is printed. Continuing with the example entry above, the value printed here is 3. So far, our reversed number is: 23
DIVISOR is then multiplied by 10, making it 100.
Since left_digits is not 0, we loop again!
MOD is multiplied by 10 again and is now 1000.
left_digits is assigned the value of entry again because of the way this works. You'll see the pattern, just hang on.
left_digits is divided by MOD, which is 1000, and the remainder is assigned back into left_digits. Using the example above, the remainder would be 932.
left_digits is divided by DIVISOR, which is 100, and assigns the value to left_digits. Using our example, the value is now 9.
left_digits is printed, as long as it is not 0. So far in this loop, our reversed number is: 239
DIVISOR is multiplied by 10 again, making it 1000.
So, you see??? I got it to work!! Is there a better way to do it??? Probably!! But it does work, hahahaha.
I wonder when it will be that I look back at this little fragment and say, "What was I thinking??"
Oh, and I wonder if it's worth noting that I also hand-calculated the entire loop path to see exactly what it was doing, and that's exactly how I found out why I was getting a floating point exception error.
All I had to do was change the variable being tested for zero value, and the location of the test!!! I had designed it one way at first, and then changed a few variables around and forgotten to change that one very important detail.
The more I think about it, the more this program is probably extremely hackish. The whole point of the project was to create a program that would take a whole, non-negative, non-zero number and repeat it back in reverse order.
In the book, my hint was to use a do loop to continuously divide the input by 10 until it reached 0. That was fine and all, but every time it divided by 10, it would give me answers like 9876, 987, 98, 9. If I only used modulo to get the remainder, I would consistently get the last digit.
So I started thinking: if I needed the last digit of each result of dividing the entry, why not use mod?
From this frame of thinking, I realize that I probably went the extra mile and made this more complex than it should be. Here is my first working program, though:
#include <stdio.h>
int main(int argc, char* argv[]) {
int entry, right_digit, left_digits, MOD, DIVISOR;
// these are named to reflect the position of the digit in the input
printf("Enter a whole, non-negative number with any amount of digits: ");
scanf("%d", &entry);
MOD = 10;
DIVISOR = 10;
// This takes care of the right-most digit, and prints it on the left
right_digit = entry % MOD;
printf("%d", right_digit);
// my hint is to use a do loop for the left digits
do {
MOD *= 10;
left_digits = entry;
left_digits %= MOD;
left_digits /= DIVISOR;
if (left_digits <= 0) {
break;
}
printf("%d", left_digits);
DIVISOR *= 10;
} while (left_digits > 0);
printf("\n");
return 0;
}
Skip past all of the printf/scanf nonsense that comes before the actual maths.
The right-most digit of the entry is taken care of first, because it needs to be printed on the far left if the number is to be reversed. Assume we use the number 5932 as our entry. The remainder of 5932 % 10 is 2. 2 is printed first.
Once that's done, we move into the do loop.
MOD starts out at 10 for the first calculation. The first part of the do loop multiplies MOD by 10.
left_digits is then assigned the value of entry. I worked with the original value through this because I couldn't figure out how else to do it (granted, I also couldn't figure out what was decrementing to 0 to give me a floating point exception).
left_digits is then divided by 100 and the remainder is stored back into left_digits. Assuming the original entry is 5932, for example, the remainder is 32.
left_digits is then divided by DIVISOR, which also begins at 10. Because it is an integer, and assuming we continue using the example above, left_digits is assigned the value of 3.
There is a conditional here to end the loop prematurely if left_digits is less than or equal to 0.
left_digits is printed. Continuing with the example entry above, the value printed here is 3. So far, our reversed number is: 23
DIVISOR is then multiplied by 10, making it 100.
Since left_digits is not 0, we loop again!
MOD is multiplied by 10 again and is now 1000.
left_digits is assigned the value of entry again because of the way this works. You'll see the pattern, just hang on.
left_digits is divided by MOD, which is 1000, and the remainder is assigned back into left_digits. Using the example above, the remainder would be 932.
left_digits is divided by DIVISOR, which is 100, and assigns the value to left_digits. Using our example, the value is now 9.
left_digits is printed, as long as it is not 0. So far in this loop, our reversed number is: 239
DIVISOR is multiplied by 10 again, making it 1000.
So, you see??? I got it to work!! Is there a better way to do it??? Probably!! But it does work, hahahaha.
I wonder when it will be that I look back at this little fragment and say, "What was I thinking??"
Oh, and I wonder if it's worth noting that I also hand-calculated the entire loop path to see exactly what it was doing, and that's exactly how I found out why I was getting a floating point exception error.
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:
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:
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;
}
Subscribe to:
Posts (Atom)