Making a CLI based Java calculator - java

I want to make a simple calculator but, I don't know how to enter many operations just like a real calculator.
switch (choice)
{
case 1:
System.out.println("Please enter 2 numbers only: " );
x = input.nextInt();
y = input.nextInt();
sum = calc.add(x,y);
System.out.printf("The sum is %d\n\n",sum);
out.write(x + "+" + y + "=" + sum);
break;
case 2:
...
case 3:
...
}

There is no question but I have some suggestions.
I would
make the case statements based on the operation '+', instead of 1.
make the messages match the operations. e.g. write(x + "*" + y when multiplying. Also don't call them all "sum"
make sure I read the nextLine() at the end.
write a new line after each line.
add a default: when the user enters an unknown operation.

Use the ScriptEngine. E.G. here.
=
That has a GUI (obviously) but you could simply allow the user to type in whatever formula JS can handle. Here is another example at my site that allows formula entry by text field.

Related

Java, How do I validate input when using scanner?

I am currently working on Java code. Basically, the int input works. However, if I type in a character, the whole system crashes. My question is as to what needs to be changed in the below code in order for the user to receive a message stating that only an int is the valid input, and to try again if they input a character.
do {
System.out.println("How many players would like to participate in this game?\t(2-4 players)");
numberOfPlayers = in.nextInt();
} while(in.hasNextInt());
numberOfPlayers = in.nextInt();
I personally prefer to use a while loop for this sort of thing rather than the do/while. Not that there is anything wrong with the do/while, I just feel it's more readable to use the while loop.
I agree with others here, accept String digits from the User instead of Integer. In my opinion it saves you other possible problems down the road and you have no need to purposely apply a try/catch mechanism should the User supply an invalid entry. It also allows you to easily apply a mechanism to quit the application which, again IMHO, should be made available to all Console app's.
You've got your answer for carrying out the task using a do/while loop but I would like to show you another way to do this sort of thing:
Scanner in = new Scanner(System.in);
String ls = System.lineSeparator();
int numberOfPlayers = 0;
String userInput = "";
while (userInput.equals("")) {
// The Prompt to User...
System.out.print("How many players would like to participate in this game?" + ls
+ "2 to 4 players only (q to quit): --> ");
userInput = in.nextLine();
// Did the User enter: q, quit (regardless of letter case)
if (userInput.toLowerCase().charAt(0) == 'q') {
// No, the User didn't...
System.out.println(ls + "Quiting Game - Bye Bye.");
System.exit(0); // Close (exit) the application.
}
/* Did the User supply a string representation of a numerical
digit consiting of either 2, 3, or 4. */
if (!userInput.matches("[234]")) {
// No, the User didn't...
System.out.println("Invalid input! You must supply a number from 2 to 4 "
+ "(inclusive)." + ls + "Try again..." + ls);
userInput = "";
continue; // Loop again.
}
// Convert numerical string digit to an Ingeger value.
numberOfPlayers = Integer.parseInt(userInput);
}
System.out.println(ls + "The Number of players you provided is: --> "
+ numberOfPlayers);
You will notice that the Scanner#nextLine() method is used to accept User input as a String. This now means that we need to validate the fact that a string representation of a Integer numerical digit (2 to 4 inclusive) was supplied by that User. To do this you will notice that I used the String#matches() method along with a small Regular Expression (RegEx) which consists of the following string: "[234]". What this does in conjunction with the String#matches() method is it checks to see if the string value in the userInput variable contains either a single "2", a single "3", or a single "4". Anything else other than any one of those three digits will display this message:
Invalid input! You must supply a number from 2 to 4 (inclusive).
Try again...
and, force the User make yet another entry.

How to go back to upper position in a program

I am trying to make node based big integer calculator in Java, and I want to re print the menu of calculator after operations. I thought of using goto but it gives error saying goto byte expected.
I am new in java, so can any one help me with the below demo code-
up:
System.out.println("YOU HAVE FOLLOWING CHOICES : ");
System.out.println("1. ADDITION");
System.out.println("2. SUBTRACTION ");
int i=s.nextInt();
System.out.println("ENTER FIRST NUMBER ");
int a=s.nextInt();
System.out.println("ENTER SECOND NUMBER ");
int b=s.nextInt();
int result = 0;
switch(i)
{
case 1:
result=a+b;
break;
case 2:
result=a-b;
break;
default:
goto up;
}
Thank you, I just want to reprint the menu.
You should use a simple while-loop for that. Maybe create a boolean as the running condition and set it to false, when the user types something else than 1 or 2.
Java does not support goto, as it is a reserved keyword.
Also, IMHO, using goto is not a great way to write a program.
A better approach would be to write a function which displays the menu and call that function whenever you want. Or just use a do-while loop.
Here is a way to look at "goto" in a java environment, using your code as the example:
public void addUp() {
System.out.println("YOU HAVE FOLLOWING CHOICES : ");
System.out.println("1. ADDITION");
System.out.println("2. SUBTRACTION ");
int i=s.nextInt();
System.out.println("ENTER FIRST NUMBER ");
int a=s.nextInt();
System.out.println("ENTER SECOND NUMBER ");
int b=s.nextInt();
int result = 0;
switch(i)
{
case 1:
result=a+b;
break;
case 2:
result=a-b;
break;
default: addUp();
}
}
Java doesn't use goto as it doesn't really fit into the Object-Oriented concept (I faced the same problem years ago when I made the switch from Basic). So you'll have to reconsider your code's logic to implement a loop of some sort.
Something like:
do {
// add an exit option to the menu
System.out.println("YOU HAVE FOLLOWING CHOICES : ");
System.out.println("1. ADDITION");
System.out.println("2. SUBTRACTION ");
System.out.println("3. EXIT");
// continue with the same logic you had before
} while (i !=3)
I hope that helps.
note: if you lookup the keyword goto in Java documentation, you'll see that it's reserved but it doesn't do anything. They probably reserved it as a placeholder for these situations

Java: Labeled Break

I am working on a practice exercise in my online pursuit to learn Java and am stumped!
The gist of my program is I have the user select an option via the input of a single char, then the program proceeds to cases based off of the value. If the default case executes, that means the input was invalid and I want to then return to the user input prompt.
I initial thought was to use a 'goto', however from what I understand, I would probably be stoned to death by anyone besides me reading the code. And then there's the fact that goto doesn't exist in Java... So while Googling, I found 'labeled breaks'. It looked just like what I needed. However, the spot which I have inserted the label is unrecognized, even though it's in the same class as the cases. How should I go about doing this?
String newLine = System.getProperty("line.separator");
restart:
System.out.println("Please select the type of shape you wish to calcuate information for: "
+ newLine + "A: Square" + newLine + "B: Rectangle" + newLine + "C: Circle");
char typeShape = input.next().charAt(0);
String shape = Character.toString(typeShape);
switch (shape.toLowerCase()) {
case "a":
//do something
break;
case "b":
//do something
break;
case "c":
//do something
break;
default:
System.out.println("Invalid selection. Please re-enter shape.");
break restart;
}
I believe you want to label a block. Something like
restart: {
System.out.println("Please select the type of shape you wish to calculate "
+ "information for: " + newLine + "A: Square" + newLine + "B: Rectangle"
+ newLine + "C: Circle");
char typeShape = input.next().charAt(0);
String shape = Character.toString(typeShape);
switch (shape.toLowerCase()) {
case "a":
//do something
break;
case "b":
//do something
break;
case "c":
//do something
break;
default:
System.out.println("Invalid selection. Please re-enter shape.");
break restart;
}
}
I guess a simple approach will be to use the do-while loop. If the condition is not satisfied (invalid input/character), continue the loop, otherwise set the flag to false and come out.
boolean inputFlag;
do {
System.out.println("Please select the type of shape you wish to calcuate information for: "
+ newLine + "A: Square" + newLine + "B: Rectangle" + newLine + "C: Circle");
char typeShape = input.next().charAt(0);
String shape = Character.toString(typeShape);
switch (shape.toLowerCase()) {
case "a":
inputFlag = false;
//do something
break;
case "b":
inputFlag = false;
//do something
break;
case "c":
inputFlag = false;
//do something
break;
default:
System.out.println("Invalid selection. Please re-enter shape.");
inputFlag = true;
}
} while (inputFlag);
Java allows you to label a loop construct (e.g. for, while) and then jump out of the inside one of the loops to an outer level.
The language does not allow you to label arbitrary lines and "goto" them.
UPDATE: Apparently I was wrong. Java supports labeling arbitrary blocks (but not individual statements). See https://stackoverflow.com/a/1940322/14731
Labeled blocks are frowned upon for similar reasons goto is frowned upon: it's not a natural flow.
With that said, you might be wondering how you would manage the behavior you want, which is pretty simple: use a loop
//pseudo-code
while(something) {
repeatCode
}
In your case, you would do something like:
boolean choosing = true;
while(choosing) {
switch(...) {
case "a":
choosing = false;
break;
case "b":
choosing = false;
break;
}
}
You may find this a bit verbose. Instead, you could set choosing to false as soon as you enter the loop, then set it back to true if the user didn't enter a correct name.
Or better yet, use a do-while loop:
boolean choosing = false;
do {
switch(...) {
case "a":
break;
default:
choosing = true;
break;
}
} while(choosing);

adding char to users choice

Hi,I'm having a problem with this. Here is the situation. There are 4 choices
[1]black
[2]red
[3]blue
For example, if the user choose any of this numbers code will print:
you choose black
here is my code so far
System.out.print("Course: \n[1] BSIT \n[2] ADGAT \n[3] BSCS \n[4] BSBA \n[5] NITE \n enter course:");
course=Integer.parseInt(input.readLine());
The problem is, when I call system.out.print(""+course); it prints the number and not the word itself?
You cannot print the course without any kind of datastructure. If you want to relate the number to some kind of data you need to do it yourself. For example store the names in an array:
String[] names = {"BSIT","ADGAT","BSCS","NITE"};
Then reference your array with corresponding lookup:
//...
int course = Integer.parseInt(input.readLine());
System.out.println("You chose: " + names[course-1]);
Remember that indexing starts from zero when working with arrays so we decrease by one.
What you do there:
1. You print out a sentence.
2. You let the user input a sentence, which you expect to contain a number and convert it as such.
The program itself has no clue that the first sentence you gave to the user is actually a selection of different things he should choose from.
What you need to to is to convert the number back to the thing it actually represented.
The easiest way would be a
String word;
switch(course) {
case 1: word = "BSIT"
break;
case 2: word = "ADGAT";
break;
case 3: word = "BSCS";
break;
case 4: word = "BSBA";
break;
case 5: word = "NITE";
break;
default:
throw new IllegalArgumentException("The choice '" + course + "' is not a valid one. Only 1-5 would be legal);
}
System.out.println("The course you've chosen is: " + word);
That's the most straight forward way to do it here, but actually not my favorite, because it duplicates the places where the mapping is done. I would prefer to actually tell the program what those things are, like:
private enum Courses {
BSIT(1), ADGAT(2), BSCS(3), BSBA(4), NITE(5);
private int userChoice;
private Courses(int theUserChoice) {
userChoice = theUserChoice;
}
public int getUserChoice() {
return userChoice;
}
public static fromUserChoice(int aChoice) {
for (Courses course: Courses.values() {
if (course.userChoice == aChoice) {
return course;
}
throw new IllegalArgumentException("The choice '" + course + "' is not a valid one. Only 1-5 would be legal);
}
}
}
private static String printCourseList() {
System.out.print("Courses: ");
for (Courses course: Courses.values()) {
System.out.print("[" + course.getUserChoice() + "] " + course.name() + " ");
}
System.out.println();
}
public static main(String[] args) {
printCourseList();
Courses course = Courses.fromUserChoice(Integer.valueOf(System.console().readLine()));
System.out.println("You're selected course is: " + course.name());
}
I prefer it that way because now the program actually knows that there is a special thing called 'Courses'. It knows that it is bound to a number and that some numbers might actually reflect a choice of a courses. It is done in a central place (the definition of the courses).
Hopefully this is not too much information and you'll see this as helpful.
use this
switch(course)
{
case 1:
System.out.println("black");
break;
case 2:
System.out.println("red");
break;
case 3:
System.out.println("blue");
break;
default:
System.out.println("invalide number"); // this will execute if course var does not equale to 1 , 2 or 3
break;
}

How to properly use a switch statement in while loop

I don't think my switch statement is doing anything with my code, I'm new to java so I'm not sure how to use a switch statement in a while loop. I'm trying to take each grade/credit entered so I can find the GPA, but I added a System.out.print for the grades and it says it's worth 0 no matter what gets entered. Please help!
package exercises;
import java.text.DecimalFormat;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
public class GPA_Calculator {
public static void main(String[] args)
{
String greeting = "Hello, this program will calculate your GPA. You will be asked \n"+
"to enter your letter grade for each class, then you will be asked to enter \n"+
"the corresponding number of credits for that class. Once all the grades and credits\n"+
"have been entered, the program will display your GPA.";
JOptionPane.showMessageDialog(null,greeting,"Greeting - Introduction",1);
char gradeEntered;
String grade = "";
String creditEntered = "";
String inputGrade = "";
String inputCredit = "";
String enterGradePrompt = "Enter your letter grade (A, B, C, D, F)\n"+
"Enter Q to display your results\n\n";
String enterCreditPrompt = "Enter the credit hours for your course (0, 1, 2, 3, 4, 5, 6)\n"+
"Enter Q to display your results\n\n";
int points = 0, sum = 0, credits = 0, gradeCount = 0;
while(!inputGrade.toUpperCase().equals("Q"))
{
inputGrade = JOptionPane.showInputDialog(null,enterGradePrompt,"Enter grade",1);
gradeEntered = inputGrade.charAt(0);
grade += inputGrade.toUpperCase()+"\n";
inputCredit = JOptionPane.showInputDialog(null,enterCreditPrompt,"Enter grade",1);
creditEntered += inputCredit+"\n";
if(inputCredit.toUpperCase().equals("Q"))
continue;
credits = Integer.parseInt(inputCredit);
credits++;
switch (gradeEntered){
case 'A': points = 4;
break;
case 'B': points = 3;
break;
case 'C': points = 2;
break;
case 'D': points = 1;
break;
case 'F': points = 0;
break;
}
sum += gradeEntered;
gradeCount++;
}
// Prevents "Q" from being printed in results
grade = grade.substring(0,grade.length()-2);
creditEntered = creditEntered.substring(0,creditEntered.length()-2);
DecimalFormat df = new DecimalFormat("#.##");
double gpa = sum / gradeCount;
String results = "The courses you entered are:\n\n"+
"Grade "+"Hours \n"+
grade+" "+creditEntered+"\n"+
"Resulting in a GPA of "+df.format(gpa)+"\n\n"+
"This program will now terminate!";
JOptionPane.showMessageDialog(null, new JTextArea(results),
"results from the Invitation list generator",1);
}
}
The problem is that your switch statement is checking the value of grade, but your input is stored in inputGrade. The former is never reassigned from the empty string, so points never gets incremented.
EDIT: To expand on the comment below:
the conditional in either a while or do/while loop isn't being checked. You're checking it inside the loop and breaking out, which is fine, as you can just make an infinite loop and let the break terminate it. However, it shouldn't be duplicated in the loop conditional.
You should do check that condition early. There's no sense in performing anything inside the loop if the user enters 'q' (also, then, you don't have to have the part where you try to strip it afterwards).
Also, you should always try to keep your variables as locally as possible. There's no need to have anything but the aggregators (totalXxx and yyyEntered in this case) outside of the loop. It just makes it confusing for you in this case, as it's masking the source of your problem. When the switch statement hits the first time, it checks the empty string. The second time, it checks the first string. When you hit 'q', it breaks, and skips your last input. If these input variables were declared inside the loop, that would be immediately apparent.
Finally, while I'm here, you have an error in your gpa calculation. The points per score should take the weight of credits as a positive, not a negative. Something like:
sum(grade * credits) / sum(credits)
I can post fixed code if you want, but since I suspect this is an academic exercise, it would be more beneficial if you came to the solution yourself.
Your switch statement is using grade which seems to be never written to. It's always "".
You get inputGrade, but you don't write to grade itself.
As it is always "", you always get nothing from your switch
You are appending each grade to your gradeEntered
gradeEntered += inputGrade.toUpperCase()+"\n"; // at a point this is something like A\nB\nC\nD\nE.... so it will not match anyway
switch (gradeEntered) {
case "A": points = 4;
break;
case "B": points = 3;
break;
case "C": points = 2;
break;
case "D": points = 1;
break;
case "F": points = 0;
break;
}
so most of the times it will not match to any of your cases.
Either you have to have a separate char for grade and use it in the switch or first use switch and then append it to your variable
You are adding a newline ("\n") to your input, (inputGrade.toUpperCase()+"\n";) so none of your cases are valid.
That is, "A" does not equal "A\n"
I think you should not use "gradeEntered" and instead use:
switch (inputGrade.toUpperCase())
especially since after running the loop more than once, your "gradeEntered" string will start to look like this: "A\nB\nF\nQ\n", which is very far removed from all your cases.
Also, switching on strings is not good practice - it is a newish development in java, and won't be supported by computers running older versions fo java - though for your own use, if the compiler doesn't complain then it is fine. Still, better to get in the habit of switching on chars or ints, since most other programming languages won't let you switch on strings.

Categories