# Finding Most Effecient Distribution of Change -- Won't Enter Loop

Printable View

• 11-28-2009, 10:32 PM
Cod
[SOLVED] Finding Most Effecient Distribution of Change -- Won't Enter Loop
My task is to randomly generate a charge for the user and make them pay in increments of \$20. Once they pay, the program needs to ask for re-payment if not enough is paid and provide the amount of change if over paid. All of this I have figured out. The problem lies with distributing the most effecient use of bills and coins to meet the change requirement (i.e. change of \$5.51 would break down as 1 \$5, 1 quarter, and 1 penny). Here is my code:

Code:

```import java.util.Scanner; import java.util.Random; import java.text.DecimalFormat; public class Project3 {   public static void main(String[] args) {       DecimalFormat df = new DecimalFormat("0.00"); // Setup dollar format     Random generator = new Random(); // Initialize random number generator     Scanner input = new Scanner(System.in);       String answer = "y"; // Used to start program     double charge; // Number owed by user     int bills; // Number of bills paid by user     int payment; // Total payment made by user         // Read in money variables     int tens = 0;     int fives = 0;     int ones = 0;     int quarters = 0;     int dimes = 0;     int nickels = 0;     int pennies = 0;       while (answer.equalsIgnoreCase("y")) { // Loop to run program continuously if user wishes                   charge = generator.nextDouble() * 100; // Random number from 0.00 to 99.99 to charge customer               do {         System.out.println("You have been charged \$" + df.format(charge)); // Print random dollar amount to charge user         System.out.println("You must pay in incredments of \$20. How many \$20 bills would you like to use?"); // Get the # of \$20 bills the user wants to pay           bills = input.nextInt();           payment = bills * 20;                 System.out.println("You paid \$" +payment);         if (payment < charge)           System.out.println("Sorry, but you did not pay enough. Please make your payment again.");               } while (payment < charge);       double change = payment - charge; // Amount owed to user after payment               System.out.println("Thank you for your payment. Your change is \$" + df.format(change));                   while (change > 0.00) {         if (change >= 10.00) {           tens ++;           change -= 10.00; }         else if (change >= 5.00) {           fives ++;           change -= 5.00; }         else if (change >= 1.00) {           ones ++;           change -= 1.00; }         else if (change >= 0.25) {           quarters ++;           change -= 0.25; }         else if (change >= 0.10) {           dimes ++;           change -= 0.10; }         else if (change >= 0.05) {           nickels ++;           change -= 0.05; }         else if (change >= 0.01) {           pennies ++;           change -= 0.01; }       }                   System.out.println("Your change will be broken down as " + tens + " tens, " + fives + " fives, " + ones + " ones, " + quarters + " quarters, " + dimes + " dimes, " + nickels + " nickels, " + pennies + " pennies.");       System.out.println("Would you like to use the tax program again (y / n) ?"); // Ask whether or not the user wants to use the program again         answer = input.next(); // "Y" restarts program, "N" terminates program     }   } }```

Everything compiles fine, but when I run the program, it always comes to an abrupt halt after System.out.println("Thank you for your payment. Your change is \$" + df.format(change));. I don't understand. I changed the while loop into a do-while loop with the same outcome. And just for kicks, I tried utilizing if-else statements (not in a loop) to no avail.

Any guidance would be greatly appreciated.
• 11-28-2009, 10:50 PM
pbrockway2
So you know you never get past the while loop or something would print.

The only thing that changes in that loop is change and its value also determines whether the loop is ever entered. So debug:

Code:

```System.out.println("About to start while loop, change=" + change); while (change > 0.00) {   System.out.println("change=" + change);   if (change >= 10.00) {       // etc```

---------------

Be consistent with your braces. For classes, methods and while loops you are placing the closing } on a line (by itself) with an indent matching the start of the line that it matches up with. That's good.

And for the do loop things are very similar except there is the "while" expression following the closing }. I suggest you follow the same pattern for if statements:

Code:

```if(condition) {   // something } else if(anotherCondition) {   // something else } else if(yaCondition){   // etc } else {   // etc }```
where all of the closing } line up matching the indent of the initial "if".
• 11-29-2009, 12:41 AM
Cod
Thanks for the guidance pbrockway2.

I did some work with the code you asked me to debug, but still could not find anything; however, from digging into the book a little more, I may have come up with another solution. If I'm correct, the way I had the loop set us as an iteration...which is incorrect because the logic calculating change should be a single flow.

With that said, I reworked the code to read (w/o while loop):

Code:

```        if (change >= 10.00) {           tens ++;           change -= 10.00;         }         if (change >= 5.00) {           fives ++;           change -= 5.00;         }         if (change >= 1.00) {           ones ++;           change -= 1.00;         }         if (change >= 0.25) {           quarters ++;           change -= 0.25;         }         if (change >= 0.10) {           dimes ++;           change -= 0.10;         }         if (change >= 0.05) {           nickels ++;           change -= 0.05;         }         if (change >= 0.01) {           pennies ++;           change -= 0.01;         }```

I plan on trying to run this when I get home from work tomorrow morning. No way of running the program from here, unless there is an online way to run a .java or .class file. The only problem I see happening is that if the change needs to include more than one of an item (ie 2 \$10, etc.). I'll find out soon enough...

Also, I tried to clean up my code based on your inputs about the brackets. I believe the code looks cleaner now, thanks for that.

Thanks again for the assistance.
• 11-29-2009, 12:52 AM
pbrockway2
I'm not sure if you intend doing away with the while loop. But if so, note that sometimes the change will involve two pennies or two dimes, two or three quarters etc. So it's not enough to run through that sequence of if statements once.

You will need access to a computer to add the debugging lines and wonder at their output. Your original code needs only the smallest of tweaks to generate the change correctly, but it's best if you see for yourself what that while loop really does. And for how long.
• 11-29-2009, 01:02 AM
Cod
So what I assess would it happen is the likely scenario. I'll put the while loop back in to ensure I don't run into any issues.

Do you know of any online debug programs that I could use while at work?

I really appreciate the fact that you aren't "giving" me the answers. This stuff is interesting to me, but a little challenging (which is a good thing). Much thanks!
• 11-29-2009, 01:18 AM
pbrockway2
I don't know of any online debuggers. So you are left with going through the code line by line, following its logic and keeping track of each of the values.

Just to confirm: you don't have any compiler on the computer you are using? If so you're best bet would be to wait. (If you can get away with it you can always put the JDK onto a pendrive...)
• 11-29-2009, 01:33 AM
Cod
Correct, I do not have a compiler on this computer. I can wait until I get home in about 11-hours. Its not a huge rush. Project isn't due until midnight on Sunday (17-hours from now).

I'll be sure to post my findings once I get home and run the debugger.

Thanks again.
• 11-29-2009, 02:09 AM
pbrockway2
OK - I just wanted to make sure, because by "debug" I just meant to add those two lines of output and run the program. Nothing more elaborate is needed.
• 11-29-2009, 12:31 PM
Cod
Hmmm...I just don't get it. Why is the loop never ending? I try using the df.format within the while statement and it won't let me because you cannot use the ">" operator with a string double. I cannot figure out how to format the number so that it will work properly...

Where do I go from here?
• 11-29-2009, 12:38 PM
dinosoep
while(change>=0){
this should work
• 11-29-2009, 01:04 PM
Cod
Quote:

Originally Posted by dinosoep
while(change>=0){
this should work

Nope, that didn't work.

I cannot figure out how to format change throughout the while loop so that it runs the way it is meant to. Because right now, I get stuck in an infinite loop due to the format issue.
• 11-29-2009, 08:41 PM
pbrockway2
> Hmmm...I just don't get it. Why is the loop never ending?

So, what is the value of change that gets "trapped" in an endless while loop?

It is due to the value of change that you end up in this loop. It has nothing to do with formatting.
• 11-29-2009, 08:45 PM
pbrockway2
Quote:

Originally Posted by dinosoep
while(change>=0){
this should work

Why should it work? Or better: does it work? Or better yet: why does it not work?

@OP: Yes, you have to change the condition governing the while loop. You need something more restrictive than "change>0.0". The value that change ends up with is curious (in terms of money) and should suggest what the condition should really be.
• 11-29-2009, 09:28 PM
Cod
Quote:

Originally Posted by pbrockway2
> Hmmm...I just don't get it. Why is the loop never ending?

So, what is the value of change that gets "trapped" in an endless while loop?

It is due to the value of change that you end up in this loop. It has nothing to do with formatting.

I'm still not grasping it. I thought it was the formatting since the number going into the loop is a very long decimal (well beyond two decimal places). So I added a function from the math class to ensure the variable change remains at 2 decimal places:

Code:

`change = (double)Math.round(change * 100) / 100;`
It is still not working and I'm getting frustrated at this point.
• 11-29-2009, 09:49 PM
pbrockway2
Quote:

Originally Posted by Cod
I'm still not grasping it. I thought it was the formatting since the number going into the loop is a very long decimal (well beyond two decimal places). So I added a function from the math class to ensure the variable change remains at 2 decimal places...

Yes, it's a very long decimal number. But that's not a question of formatting: you are dealing with a "very long" decimal value right from the line:

Code:

`charge = generator.nextDouble() * 100; // Random number from 0.00 to 99.99 to charge customer`
Basically all floating point values are "very long" in this sense. Don't try and fight it with voodoo like

Code:

`change = (double)Math.round(change * 100) / 100;`
(which, incidentally, doesn't alter how "long" change is.)

Instead notice the value that change ends up with. It's a "very long" decimal value, but the important thing is: it is less than one cent. So change the condition in the while loop so that the loop exits when the amount of change to be calculated falls below one cent.

Code:

```while (change >= 0.01) {     if (change >= 10.00) {```
• 11-29-2009, 09:49 PM
Cod
Yay! I finally figured it out...after hours of thinking at work and home. Sorry I didn't figured out the "less than a cent" thing. I just posted at the same time as your most recent post. I do see how I should've gone with your method from the start...I just couldn't get my hands around it when you were "hinting" at it.

Here is the final source code I ended up with:

Code:

```import java.util.Scanner; import java.util.Random; import java.text.DecimalFormat; import java.lang.Math; public class Project3 {   public static void main(String[] args) {       DecimalFormat df = new DecimalFormat("0.00"); // Setup dollar format     Random generator = new Random(); // Initialize random number generator     Scanner input = new Scanner(System.in);       String answer = "y"; // Used to start program     double charge; // Number owed by user     int bills; // Number of bills paid by user     int payment; // Total payment made by user           while (answer.equalsIgnoreCase("y")) { // Loop to run program continuously if user wishes       // Read in money variables       int tens = 0;       int fives = 0;       int ones = 0;       int quarters = 0;       int dimes = 0;       int nickels = 0;       int pennies = 0;                   charge = generator.nextDouble() * 100; // Random number from 0.00 to 99.99 to charge customer             do {         System.out.println("You have been charged \$" + df.format(charge)); // Print random dollar amount to charge user         System.out.println("You must pay in incredments of \$20. How many \$20 bills would you like to use?"); // Get the # of \$20 bills the user wants to pay           bills = input.nextInt();           payment = bills * 20;                 System.out.println("You paid \$" + payment);         if (payment < charge)           System.out.println("Sorry, but you did not pay enough. Please make your payment again.");               } while (payment < charge);       double change = payment - charge; // Amount owed to user after payment             System.out.println("Thank you for your payment. Your change is \$" + df.format(change));             while (change > 0.00) {         change = (double)Math.round(change * 100) / 100;         if (change >= 10.00) {           tens ++;           change -= 10.00; }         else if (change >= 5.00) {           fives ++;           change -= 5.00; }         else if (change >= 1.00) {           ones ++;           change -= 1.00; }         else if (change >= 0.25) {           quarters ++;           change -= 0.25; }         else if (change >= 0.10) {           dimes ++;           change -= 0.10; }         else if (change >= 0.05) {           nickels ++;           change -= 0.05; }         else if (change >= 0.01) {           pennies ++;           change -= 0.01; }       }                  System.out.println("Your change will be broken down as " + tens + " tens, " + fives + " fives, " + ones + " ones, " + quarters + " quarters, " + dimes + " dimes, " + nickels + " nickels, " + pennies + " pennies.");       System.out.println("Would you like to use the tax program again (y / n) ?"); // Ask whether or not the user wants to use the program again         answer = input.next(); // "Y" restarts program, "N" terminates program     }   } }```

Thank you very, very much of the guidance pbrockway2. I definitely owe you a drink.
• 11-29-2009, 10:28 PM
pbrockway2
You're welcome!

I see you've moved the "int tens = 0;" etc inside the while loop. I could see that looming but had to bite my tongue...

I should mention - because someone else is bound to! - that for money problems people often use pennies rather than dollars in order to avoid the subtle difference between ">0.0" and ">=0.01".
• 11-29-2009, 11:27 PM
dinosoep
oops, shouldve checked completely befor i answered, i gave the wrong response, sorry
• 11-30-2009, 12:58 AM
Cod
Quote:

Originally Posted by pbrockway2
You're welcome!

I see you've moved the "int tens = 0;" etc inside the while loop. I could see that looming but had to bite my tongue...

I caught it after I ran the program a second time. Thanks again!