How can i shorten this code and make it less repetitive? - java

I made a simple calculator but the if statements are very repetitive and long. I am wondering what other solution I could use to shorten it and make it less repetitive. For example using a method (which i have tried but not succeeded) or any other techniques that are usable. Preferably not too advanced since I'm a beginner.
import static java.lang.System.*;
import static javax.swing.JOptionPane.*;
import static java.lang.Integer.*;
public class SimpleCalc {
public static void main(String[] args) {
String operator = showInputDialog("Choose operation: " + "\n" +
"[1] = Plus" + "\n" +
"[2] = Minus" + "\n" +
"[3] = Multiply" + "\n" +
"[4] = Divide" + "\n");
int c = parseInt(operator);
if (c > 4) {
showMessageDialog(null, "You cant do that.");
} else if (c == 1) {
String textA = showInputDialog("Enter first number: ");
String textB = showInputDialog("Enter second number: ");
int a = parseInt(textA);
int b = parseInt(textB);
showMessageDialog(null, a + " + " + b + " = " + (a + b));
} else if (c == 2) {
String textA = showInputDialog("Enter first number: ");
String textB = showInputDialog("Enter second number: ");
int a = parseInt(textA);
int b = parseInt(textB);
showMessageDialog(null, a + " - " + b + " = " + (a - b));
} else if (c == 3) {
String textA = showInputDialog("Enter first number: ");
String textB = showInputDialog("Enter second number: ");
int a = parseInt(textA);
int b = parseInt(textB);
showMessageDialog(null, a + " * " + b + " = " + (a * b));
} else if (c == 4) {
String textA = showInputDialog("Enter first number: ");
String textB = showInputDialog("Enter second number: ");
int a = parseInt(textA);
int b = parseInt(textB);
showMessageDialog(null, a + " / " + b + " = " + (a / b));
}
}
}

Try something like
String textA = showInputDialog("Enter first number: ");
String textB = showInputDialog("Enter second number: ");
int a = parseInt(textA);
int b = parseInt(textB);
switch(c) {
case 1:
showMessageDialog(null, a + " + " + b + " = " + (a+b));
break;
case 2:
...
default:
showMessageDialog(null, "You cant do that.");

Well, to start; you can move the
String textA = showInputDialog("Enter first number: ");
String textB = showInputDialog("Enter second number: ");
int a = parseInt(textA);
int b = parseInt(textB);
outside of the if blocks so that it only asks once before the if block, which will save you 12 lines of code.
Or you can also use methods or functions as a practice; but that wouldn't shorten your code further, really. I'd also suggest looking into Codegolf, you can learn a LOT about code-shortening.

The following will be identical, but doesn't repeat the same lines over and over. You can also use the switch statement in place of the 4 if/else if statements.
public class SimpleCalc {
public static void main(String[] args) {
String operator = showInputDialog("Choose operation: " + "\n" +
"[1] = Plus" + "\n" +
"[2] = Minus" + "\n" +
"[3] = Multiply" + "\n" +
"[4] = Divide" + "\n");
int c = parseInt(operator);
if (c>4) {
showMessageDialog(null, "You cant do that.");
return;
}
String textA = showInputDialog("Enter first number: ");
String textB = showInputDialog("Enter second number: ");
int a = parseInt(textA);
int b = parseInt(textB);
if(c==1) {
showMessageDialog(null, a + " + " + b + " = " + (a+b));
}
else if (c==2) {
showMessageDialog(null, a + " - " + b + " = " + (a-b));
}
else if (c==3) {
showMessageDialog(null, a + " * " + b + " = " + (a*b));
}
else if (c==4) {
showMessageDialog(null, a + " / " + b + " = " + (a/b));
}
}
}

There are a couple approaches:
Put the common code into a method
Move the common code to a different part of the current method so that it is executed unconditionally.
Put the non-common code into a function / method / class that can be used to parameterize the common code.
In this case, the second approach works best; e.g.
if(c==1) {
String textA = showInputDialog("Enter first number: ");
String textB = showInputDialog("Enter second number: ");
int a = parseInt(textA);
int b = parseInt(textB);
showMessageDialog(null, a + " + " + b + " = " + (a+b));
}
else if (c==2) {
String textA = showInputDialog("Enter first number: ");
String textB = showInputDialog("Enter second number: ");
int a = parseInt(textA);
int b = parseInt(textB);
showMessageDialog(null, a + " - " + b + " = " + (a-b));
}
...
can be transformed into:
String textA = showInputDialog("Enter first number: ");
String textB = showInputDialog("Enter second number: ");
int a = parseInt(textA);
int b = parseInt(textB);
int result;
char op;
if (c == 1) {
result = a + b;
op = '+';
} else if (c == 2) {
result = a - b;
op = '-';
}
...
showMessageDialog(null, a + " " + op + " " + b + " = " + result);
(I have left a problem there for you to notice and sort out ... as a learning exercise.)

Just for fun. Factor out the stuff that's common! And handle the possibility that you'll need to implement unary operators. You'll probably also want to put it in a loop, and add an exit command.
public class SimpleCalc {
public static void main(String[] args) {
String operator = showInputDialog(
"Choose operation: " + "\n" +
"[1] = Add" + "\n" +
"[2] = Subtract" + "\n" +
"[3] = Multiply" + "\n" +
"[4] = Divide" + "\n");
"[5] = Negate" + "\n");
int c = parseInt(operator);
int operand_count = 0;
switch (c) {
case 1:
case 2:
case 3:
case 4:
operand_count = 2;
break;
case 5:
operand_count = 1;
break;
default:
showMessageDialog(null, "You cant do that.");
return(-1);
}
int a = 0;
int b = 0;
if (operand_count >= 1) {
String textA = showInputDialog("Enter first number: ");
int a = parseInt(textA);
}
if (operand_count >= 2) {
String textB = showInputDialog("Enter second number: ");
int b = parseInt(textB);
}
char * opname = "";
int result = 0;
switch (c) {
case 1:
opname = "+";
result = a + b;
break;
case 2:
opname = "-";
result = a - b;
break;
case 3:
opname = "*";
result = a * b;
break;
case 4:
opname = "/";
result = a / b;
break;
case 5:
opname = "-";
result = -a;
break;
}
if (operand_count == 1) {
showMessageDialog(null, opname + " (" + a + ") = " result);
} else {
showMessageDialog(null, a + " " + opname + " " + b + " = " + result);
}
}
}

Related

I ned a while loop statment that makes the calculations loop and ask again

im not too sure how you add a loop statement to this. I want it to be a while loop that makes it do that the calculations repeat after finishing. I've tried but it just keeps on giving me errors. ive tried doing While statements but just will not work im not sure how you set it up as my teacher did not explain very well
import com.godtsoft.diyjava.DIYWindow;
public class Calculator extends DIYWindow {
public Calculator() {
// getting number one
double number1 = promptForDouble("Enter a number");
//getting number2
int number2 = promptForInt("Enter an integer");
//getting what to do with operation
print("What do you want to do with these numbers?\nAdd\tSubtract\tMultiply\tDivide");
String operation = input();
//declaring variable here so the same one can be used
double answer = 0;
switch(operation) {
case "add":
answer = number1 + number2;
print(number1 + " + " + number2 + " = " + answer);
break;
case "subtract":
answer = number1 - number2;
print(number1 + " - " + number2 + " = " + answer);
break;
case "multiply":
answer = number1 * number2;
print(number1 + " * " + number2 + " = " + answer);
break;
case "divide":
try {
answer = number1 / number2;
}
catch(ArithmeticException e) {
print("A number cannot be divided by 0.");
}
print(number1 + " / " + number2 + " = " + answer);
break;
}
double double1 = promptForDouble("Enter a number");
double double2 = promptForDouble("Enter another number");
double double3 = promptForDouble("Enter one last number");
print("What do you want to do with these numbers?\nAdd\tSubtrack\tMultiply\tDivide");
String operation2 = input();
double answer2 = 0;
switch(operation2) {
case "add":
answer2 = double1 + double2 + double3;
print(double1 + " + " + double2 + " + " + double3 + " = " + answer2);
break;
case "subtract":
answer2 = double1 - double2 - double3;
print(double1 + " - " + double2 + " - " + double3 + " = " + answer2);
break;
case "multiply":
answer2 = double1 * double2 * double3;
print(double1 + " * " + double2 + " * " + double3 + " = " + answer2);
break;
case "divide":
try {
answer2 = double1 / double2 / double3;
}
catch(ArithmeticException e) {
print("A number cannot be divided by 0.");
}
print(double1 + " / " + double2 + " / " + double3 + " = " + answer2);
break;
}
want it to loop after the code on top
}
private double promptForDouble(String prompt) {
double number1 = 0;
print(prompt);
String number = input();
try {
number1 = Double.parseDouble(number);
}
catch(NumberFormatException e){
print("That is not a number. Please enter a number.");
number1 = promptForDouble(prompt);
}
return number1;
}
private int promptForInt(String prompt) {
int number2 = 0;
print(prompt);
String number = input();
try {
number2 = Integer.parseInt(number); }
catch(NumberFormatException e) {
print("That is not an integer. Enter an integer.");
number2 = promptForInt(prompt); }
return number2;
}
public static void main(String[] args) {
new Calculator();
}
}
Put this in your main method:
while (true)
{
Thread.sleep(1000); // optional, make some deplay for more nature
new Calculator();
}
Or you can wrap all body blocks of the constructor inside the above while statement.

Output copied twice in Nim game in Java

Im learning java with "programmingbydoing" and i have a problem with Nim game, everything works fine apart from one thing, which is that both:
"System.out.print(n1 + ", choose a pile: ");"
and
"System.out.print(n2 + ", choose a pile: ");"
is out printed twice after the first time.
Here is code:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Player one, enter your name: ");
String n1 = input.nextLine();
System.out.print("Player two, enter your name: ");
String n2 = input.nextLine();
int a = 3;
int b = 4;
int c = 5;
int count = 1;
System.out.println("A: "+a+" B: "+b+" C: "+c);
nim_loop:while(a > 0 || b > 0 || c > 0) {
while(count % 2 != 0 ) {
System.out.print(n1+", choose a pile: ");
String first = input.nextLine();
if (first.contains("a") || first.contains("A")) {
System.out.print("How many to remove from pile " + first + "? ");
int second = input.nextInt();
count = count + 1;
a = a - second;
System.out.println("A: " + a + " B: " + b + " C: " + c);
if(a <= 0 && b <= 0 && c <= 0){
break nim_loop;
}
}
else if (first.contains("b") || first.contains("B")) {
System.out.print("How many to remove from pile " + first + "? ");
int second = input.nextInt();
count = count + 1;
b = b - second;
System.out.println("A: " + a + " B: " + b + " C: " + c);
if(a <= 0 && b <= 0 && c <= 0){
break nim_loop;
}
}
else if (first.contains("c") || first.contains("C")) {
System.out.print("How many to remove from pile " + first + "? ");
int second = input.nextInt();
count = count + 1;
c = c - second;
System.out.println("A: " + a + " B: " + b + " C: " + c);
if(a <= 0 && b <= 0 && c <= 0){
break nim_loop;
}
}
}
while(count % 2 == 0) {
System.out.print(n2 + ", choose a pile: ");
String third = input.nextLine();
if (third.contains("a") || third.contains("A")) {
System.out.print("How many to remove from pile " + third + "? ");
int fourth = input.nextInt();
count = count + 1;
a = a - fourth;
System.out.println("A: " + a + " B: " + b + " C: " + c);
} else if (third.contains("b") || third.contains("B")) {
System.out.print("How many to remove from pile " + third + "? ");
int fourth = input.nextInt();
count = count + 1;
b = b - fourth;
System.out.println("A: " + a + " B: " + b + " C: " + c);
} else if (third.contains("c") || third.contains("C")) {
System.out.print("How many to remove from pile " + third + "? ");
int fourth = input.nextInt();
count = count + 1;
c = c - fourth;
System.out.println("A: " + a + " B: " + b + " C: " + c);
}
}
}
if (count % 2 != 0) {
System.out.println("Game ended, Player " + n1 + " is a winner.");
} else if (count % 2 == 0){
System.out.println("Game ended, Player " + n2 + " is a winner.");
}
}
}
And here are the pictures of what happens when i run it:
When the first if condition in first inner loop is true and when you get the user input by using nextInt() it only reads the int value and does not consume the last new line character i,e \n. So the subsequent call to nextLine() will be skipped i,e the nextLine() call in second inner while loop will be skipped without any value but System.out.print(n2 + ", choose a pile: "); will be printed as it is before nextLine() call and control goes back to outer while loop.
Now the count value is 2 so first inner while condition will be false and control goes to second inner while loop. And again it prints b, choose a pile:. Hope this clears your question
Workaround is fire a blank nextLine() call after every nextInt() or use nextLine() inside if condition and parse the user input using Integer.parseInt(String) method.
Example code :
if (first.contains("a") || first.contains("A")) {
System.out.print("How many to remove from pile " + first + "? ");
int second = input.nextInt();
input.nextLine(); // firing an blank nextLine call
count = count + 1;
a = a - second;
System.out.println("A: " + a + " B: " + b + " C: " + c);
if(a <= 0 && b <= 0 && c <= 0){
break nim_loop;
}
For more information - Scanner is skipping nextLine() after using next(), nextInt() or other nextFoo() methods

Printing a string?

I'm in my first programming class; can anyone help me understand why I can't print my last line please?
package program4;
import java.util.*;
public class Program4 {
public static void main(String[] args) {
int a, b, c, numComparisons;
String comparisons = "Comparisons for triangleType determination: ";
Scanner scan = new Scanner(System.in);
for (int i = 0; i < 7; i++) {
}
String triangleType = "";
System.out.print("Enter 3 positive integer lengths for the sides of a "
+ "triangle:");
a = scan.nextInt();
b = scan.nextInt();
c = scan.nextInt();
System.out.println("The input lengths are: a = " + a + ", b = " + b + ", and"
+ " c = " + c + "");
if ((a + b < c) || (b + c < a) || (a + c < b)) {
System.out.print("There is no triangle with sides " + a + ", " + b + " and "
+ "" + c + ".");
} else {
numComparisons = 1;
comparisons += "a==b";
if (a == b) {
comparisons += "(T)" + "(b==c)";
numComparisons++;
if (b == c) {
comparisons += "(T)";
triangleType = "Equilateral";
}
} else {
comparisons += "(F)";
if (a == c) {
comparisons += "(T)";
triangleType = "Isosceles";
} else {
comparisons += "b==c";
numComparisons++;
comparisons += "(F)";
if (b == c) {
triangleType = "Isosceles";
} else {
comparisons += "a==c";
numComparisons++;
comparisons += "(F)";
triangleType = "Scalene";
}
}
}
System.out.printf("" + comparisons + (""));
System.out.printf("numComparisons = " + numComparisons);
System.out.println("The triangles with sides " + a + ", "
+ " + b + ", and " + c + ", is + triangleType + ");
}
}
}
Your last line syntax is pretty messed up.
this
System.out.println("The triangles with sides " + a + ", "
+ " + b + ", and " + c + ", is + triangleType + ");
should be
System.out.println("The triangles with sides " + a + ", "
+ b + ", and " + c + ", is " + triangleType);
System.out.println("The triangles with sides " + a + ", "
+ " + b + ", and " + c + ", is + triangleType + ");
What IDE/editor are you using? It should should show you the errors here. This should be
System.out.println("The triangles with sides " + a + ", "
+ b + ", and " + c + ", is" + triangleType);
This is better

Calling method on an object, and using same object as parameter for method

I am working on a java program for creating a slot machine. The program works how I want it to but I am not sure if one of my method calls is proper java etiquette. In my main method below, inside my for loop, I call the method rollAndCompare() on the FourTumblers object, machine. This method returns an integer, coin, which represents how much the user won based on the number of tumblers matched. This if-else statement is written in the FourTumblers class. However, I also pass the same machine object as a parameter so that the method can access the tumbler values of the object. Is there a better way to do this? Is this correct?
public static void main(String[] args) {
int coins;
int addtLives;
int bank = 0;
int lives = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Please enter how many games you want to play:");
int num = scan.nextInt();
System.out.println("You have decided to play " + num + " games.\n");
for (int i = 1; i <= num; i++) {
FourTumblers machine = new FourTumblers();
coins = machine.rollAndCompare(machine);
bank += coins;
addtLives = coins/100;
lives += addtLives;
System.out.println("You won " + coins + " coins. That's " + addtLives + " lives.");
System.out.println("You now have a total of " + bank + " coins and " + lives + " lives.\n");
}
scan.close();
}
Here is my rollAndCompare method...
public int rollAndCompare(FourTumblers machine) {
value1 = machine.getValue1();
value2 = machine.getValue2();
value3 = machine.getValue3();
value4 = machine.getValue4();
if ((value1 == value2)&&(value2 == value3)&&(value3 == value4)){
System.out.println(value1 + " | " + value2 + " | " + value3 + " | " + value4);
System.out.println("Jackpot!");
coins = 600;
return coins;
}
else if (((value1 == value2)&&(value2 == value3))||((value1 == value3)&&(value3 == value4))||((value1 == value2)&&(value2 == value4))||((value2 == value3)&&(value3 == value4))){
System.out.println(value1 + " | " + value2 + " | " + value3 + " | " + value4);
coins = 300;
return coins;
}
else if ((value1 == value4)||(value1 == value2)||(value1 == value3)||(value2 == value3)||(value2 == value4)||(value3 == value4)){
System.out.println(value1 + " | " + value2 + " | " + value3 + " | " + value4);
coins = 100;
return coins;
}
else{
System.out.println(value1 + " | " + value2 + " | " + value3 + " | " + value4);
coins = 0;
return coins;
}
}
The times you would want to add an object onto itself in a class is if you are going to compare it with other objects from the same class.
Ex:
public class Sample
{
private String name = "Sample Chocolate";
private int cost = 1;
public boolean compareSample(Sample sample)
{
if (sample.name.equals(name) && cost == sample.cost)
return true;
else
return false;
}
Then from another class:
public class SampleTester
{
public static void main(String[] args)
{
Sample sample1 = new Sample();
Sample sample2 = new Sample();
System.out.println("Are sample one and sample two the same?: " + sample1.compareSample(sample2));
}
}
Otherwise you can simply put nothing inside the parenthesis:
public boolean compareSample()
{
if (name.equals("Sample Chocolate") && cost == 1)
return true;
else
return false;
}
As Ashiquzzman eloquently said: You can call that using this.getValue(), you don't need to pass machine (to be used as machine.getValue()).

Hanging token from user input is not allowing me to proceed in my program

My program is not allowing me to enter user input if i do not enter a number and i want to go through the program again, it think its due to a hanging token somewhere but i cannot seem to find it.
import java.util.Scanner;
public class LessonTwo {
static Scanner userInput = new Scanner(System.in);
public static void main(String[] args) {
char answer = ' ';
do {
System.out.print("Your favorite number: ");
if (userInput.hasNextInt()) {
int numberEntered = userInput.nextInt();
userInput.nextLine();
System.out.println("You entered " + numberEntered);
int numEnteredTimes2 = numberEntered + numberEntered;
System.out.println(numberEntered + " + " + numberEntered
+ " = " + numEnteredTimes2);
int numEnteredMinus2 = numberEntered - 2;
System.out.println(numberEntered + " - 2 " + " = "
+ numEnteredMinus2);
int numEnteredTimesSelf = numberEntered * numberEntered;
System.out.println(numberEntered + " * " + numberEntered
+ " = " + numEnteredTimesSelf);
double numEnteredDivide2 = (double) numberEntered / 2;
System.out.println(numberEntered + " / 2 " + " = "
+ numEnteredDivide2);
int numEnteredRemainder = numberEntered % 2;
System.out.println(numberEntered + " % 2 " + " = "
+ numEnteredRemainder);
numberEntered += 2; // *= /= %= Also work
numberEntered -= 2;
numberEntered++;
numberEntered--;
int numEnteredABS = Math.abs(numberEntered); // Returns the
int whichIsBigger = Math.max(5, 7);
int whichIsSmaller = Math.min(5, 7);
double numSqrt = Math.sqrt(5.23);
int numCeiling = (int) Math.ceil(5.23);
System.out.println("Ceiling: " + numCeiling);
int numFloor = (int) Math.floor(5.23);
System.out.println("Floor: " + numFloor);
int numRound = (int) Math.round(5.23);
System.out.println("Rounded: " + numRound);
int randomNumber = (int) (Math.random() * 10);
System.out.println("A random number " + randomNumber);
} else {
System.out.println("Sorry you must enter an integer");
}
System.out.print("Would you like to try again? ");
answer = userInput.next().charAt(0);
}while(Character.toUpperCase(answer) == 'Y');
System.exit(0);
}
}
Yes you are right you need to consume the characters first after the user inputted character in the nextInt before allowing the user to input data again
just add this in your else block and it will work:
else {
System.out.println("Sorry you must enter an integer");
userInput.nextLine(); //will consume the character that was inputted in the `nextInt`
}
EDIT:
change this:
answer = userInput.next().charAt(0);
to:
answer = userInput.nextLine().charAt(0);

Categories

Resources