• Post Reply Bookmark Topic Watch Topic
  • New Topic

Change Machine  RSS feed

 
David Coello
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello forum members, I am currently working on a class assignment to display change for a simulated purchase.

I have a working program that displays dollars, quarters, dimes, nickles and pennies.

There is a needed feature, to identify non-numeric characters and I am lost as to how to achieve this.

So far, if when asked for amount due, if I put in letters, I get the following:
java.util.mismatchexception

Is there a specific code or check I can do to identify letters are entered and to say "please input numbers only".

My code is as follows:

[/code]
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The exception you get is caused by the Scanner.nextDouble() method. Basically, it is doing the check to see if the input is a Double, and it is not. What you should do is surround your scan.nextDouble() with a try {}catch(...) {} block to catch when the error occurs and act accordingly. This is usually done in a loop so you can fail multiple times before finally succeeding.
 
Jack Malgam
Greenhorn
Posts: 6
Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Heyo,

Your error is due to Java trying to shoehorn String data into a Double. That won't work, and thankfully you don't have to make it work from the sound of things. All you have to do is tell the misguided user that they are trying to hammer a square peg into a round hole. However, first you have to tell Java to disregard anything that's not round. To that end, have you considered the Scanner.hasNextDouble() method?

hasNextDouble() is one of the hasNext () group of methods, designed to let you identify if Scanner input is acceptable before your program chokes on it. It returns a boolean true|false if the next piece of input is acceptable to its format, but most importantly does not advance the Scanner. This means you can check the input, then if it's what you want to use you can take it. If not, you can carry out a different set of instructions.

The Oracle documentation is here: http://docs.oracle.com/javase/6/docs/api/java/util/Scanner.html#hasNextDouble%28%29 Since they can be a little opaque at times, here's an example of one way you can use hasNextDouble.




Hopefully things are a bit clearer now! Oh, and if you have the book Just Java 2, check out Chapter 17 "Simple Input Output". The author has some good clarification on the Scanner class, and Pg. 393 explains more about the hasNext methods.
 
Greg Ferguson
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi David,

I ran your program. It works well. Jack has the right idea for user error control; that's essentially what I did except I used BigDecimal instead of double for the amounts. Anyway, it's looking good and don't forget our instructor wants the program to loop back to the beginning so he can input different amounts without having to restart the program.
 
David Coello
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Buenny, Jack, Steve and thank you for your suggestions.

I started to implement the Scanner.hasNextDouble() method. I used a while loop to check if not doubles; used it 2 times, first to check the amount due and then to check the amount tender.

It seems that there are some issues with my code, as when I run the program it asks for the amount due, I enter a number, and then it does nothing, until I enter a second number. It looks like the while loop takes the second entry to check if it is a double. I suspect the same with the second while loop.

Also, in the even when a non double is entered, I would need to store a new amount due / tender and display it, and use it to calculate the change to the customer. I am confused, since a new amount due would have to go down a paralell path as the original code to calculate change, maybe using an if (newamountdue == null) to see if a new amount due was entered.

Or just assign the new value to the same "due" double, I don´t know if that can be achieved, I´ve tried and says a value to the variable due is already assigned.

I look forward to your comments and thanks in advance.

David

 
fred rosenberger
lowercase baba
Bartender
Posts: 12565
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would say your code has a few other problems. Primarily, you do everything in the main() method.

One of the most important things to learn is to separate out the components. For example, I would have a method that deals with getting the amount due. So, your main method would first call getAmountDue(), and save the returned value. There are several reasons for this:

1) you want methods to do one simple thing
2) if you compartmentalize the code, then when you change one part, you don't have to worry about anything else
3) You can focus on one piece at a time.

so I would consider making a few methods, like:

getAmountDue
getAmountTendered
calculateChange
calculateDispursement


So you can work on writing getAmountDue, and not worry about anything else. Once you have that done, you don't worry about it any more, you just use it. You would then start to work on getAmountTendered, and perhaps notice it is really doing the same thing - printing a prompt, then reading a value from the user...so maybe you could write one method called "getUserInput", and pass it a string to use for the prompt...thus simplifying things even more..

The other advantage is that your calculateChange method doesn't care HOW you got the amountDue or the amountTendered - it only cares what the values are. So maybe later, you can update your program to get the amount due from a database, or a file, or over a tcp/ip connection...and since each bit of code is modularized, you know that touching one method won't impact the others
 
Greg Ferguson
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey David,

I agree with fred. Working in methods is a lot less tedious and makes things a lot easier to deal with. When I did this project, I created a Money class with nothing but methods that handled different parts of the program (i.e. dollars, quarters, dimes, changeBreakdown, etc.). It made things so much easier, then in the main() method all I had to do was focus on the loops and if statements without a ton of extra code getting in the way.

As of right now, to get your code working as is would involve nesting several while and if statements. Your initial issue appears to be not being able to kick off the first while loop after entering the first value. What I did to combat that was to make a "teaser" line such as "Press enter to start the program". After that, the line "Enter amount due: " appeared and I could continue with the rest of conditions.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!