I'm a bit confused about how += assignment operator works. I know that x += 1 is x = x+1. However, in this code there is a string variable called 'String output' and initialized with an empty string. My confusion is that that there are 5 different outputs for the variable 'output' but I don't see where it's being stored. Help clarify my misunderstanding. I can't seem to figure it out.
import java.util.Scanner;
public class SubtractionQuiz {
public static void main(String[] args) {
final int NUMBER_OF_QUESTIONS = 5; //number of questions
int correctCount = 0; // Count the number of correct answer
int count = 0; // Count the number of questions
long startTime = System.currentTimeMillis();
String output = " "; // Output string is initially empty
Scanner input = new Scanner(System.in);
while (count < NUMBER_OF_QUESTIONS) {
// 1. Generate two random single-digit integers
int number1 = (int)(Math.random() * 10);
int number2 = (int)(Math.random() * 10);
// 2. if number1 < number2, swap number1 with number2
if (number1 < number2) {
int temp = number1;
number1 = number2;
number2 = temp;
}
// 3. Prompt the student to answer "What is number1 - number2?"
System.out.print(
"What is " + number1 + " - " + number2 + "? ");
int answer = input.nextInt();
// 4. Grade the answer and display the result
if (number1 - number2 == answer) {
System.out.println("You are correct!");
correctCount++; // Increase the correct answer count
}
else
System.out.println("Your answer is wrong.\n" + number1
+ " - " + number2 + " should be " + (number1 - number2));
// Increase the question count
count++;
output += "\n" + number1 + "-" + number2 + "=" + answer +
((number1 - number2 == answer) ? " correct" : "
wrong");
}
long endTime = System.currentTimeMillis();
long testTime = endTime = startTime;
System.out.println("Correct count is " + correctCount +
"\nTest time is " + testTime / 1000 + " seconds\n" + output);
}
}
Answer given by Badshah is appreciable for your program and if you want to know more about operator' usability, jst check out this question i came across
+ operator for String in Java
The answers posted have very good reasoning of the operator
Its Add AND assignment operator.
It adds right operand to the left operand and assign the result to left operand.
In your case
output += someString // output becomes output content +somestring content.
`
Maybe the proper answer was written but if I understand your question correctly, you want some clarification instead of meaning of +=
Change the code;
// Increase the question count
count++;
output += "\n" + number1 + "-" + number2 + "=" + answer +
((number1 - number2 == answer) ? " correct" : "wrong");
as this:
output += "\nCount: " + count + " and the others: " +
number1 + "-" + number2 + "=" + answer +
((number1 - number2 == answer) ? " correct" : "wrong");
// Increase the question count
count++;
So you can see the line and the count together. Then increase as your wish.
In Java, Strings are immutable. So output += somethingNew makes something like this:
String temp = output;
output = temp + somethingNew;
At the end, it becomes something like concat/merge
Related
I added a if statement that parses a entered number into a double to use when I do my calculations in the second if statement block, the program has to run if only numbers where entered and not letters, the program doesn't seem to read the numbers when I entered a double(5.5) but works fine when I enter a int(5) number/numbers.
Scanner numbers = new Scanner(System.in);
Scanner operation = new Scanner(System.in);
double number1 = 0;
double number2 = 0;
String operator;
System.out.print("Enter the operator you would like to choose(+, -, *, /): ");
operator = operation.next();
System.out.print("Enter the first number: ");
String num1 = numbers.nextLine();
System.out.print("Enter your second number: ");
String num2 = numbers.nextLine();
boolean check1 = num1.trim().matches("^[0-9]+$");
boolean check2 = num2.trim().matches("^[0-9]+$");
if (check1 == true && check2 == true){
number1 = Double.parseDouble(num1);
number2 = Double.parseDouble(num2);
}else {
System.out.println("Only enter numbers not letters.");
}
String calculation;
if (operator.equals("+")){
calculation = (number1 + " + " + number2 + " = " + (number1 + number2));
System.out.println(calculation);
}else if (operator.equals("-")){
calculation = (number1 + " - " + number2 + " = " + (number1 - number2));
System.out.println(calculation);
}else if (operator.equals("*")){
calculation = (number1 + " * " + number2 + " = " + (number1 * number2));
System.out.println(calculation);
}else if (operator.equals("/")){
calculation = (number1 + " / " + number2 + " = " + (number1 / number2));
System.out.println(calculation);
}else{
calculation = operator + ":" + " Is not a valid operator!";
System.out.println(calculation);
}
I think its maybe the ( . ) thats the problem,
my output to console
Enter the operator you would like to choose(+, -, *, /): +
Enter the first number: 5.5
Enter your second number: 5.5
Only enter numbers not letters.
0.0 + 0.0 = 0.0
And now the int numbers that works fine.
Enter the operator you would like to choose(+, -, *, /): +
Enter the first number: 5
Enter your second number: 5
5.0 + 5.0 = 10.0
Do not use more than one Scanner object. There is no need for more than one, and this could also have some side effects you don't want to deal with.
Since you are using regular expression and others have suggested other solutions, I decided to show you how to use regular expression to evaluate a floating-point value. The correct expression for this is
[-+]?[0-9]*\\.?[0-9]+
or better yet...
[-+]?\\d*\\.?\\d+
This expression evaluates a value that may contain an optional sign (positive or negative) followed by zero or more digits, then followed by optional decimal point and an unlimited number of decimal digits. However, if the decimal point is used, at least one digit must be present. In a case like +2., only the +2 is matched.
The code below is your version of the solution, slightly modified:
public static void main(String[] args) {
final String REGEX = "[-+]?[0-9]*\\.?[0-9]+";
Scanner scanner = new Scanner(System.in);
double number1 = 0;
double number2 = 0;
String operator;
System.out.print("Enter the operator you would like to choose(+, -, *, /): ");
operator = scanner.next();
System.out.print("Enter the first number: ");
String num1 = scanner.next();
System.out.print("Enter your second number: ");
String num2 = scanner.next();
scanner.close();
boolean check1 = num1.trim().matches(REGEX);
boolean check2 = num2.trim().matches(REGEX);
if (check1 && check2) {
number1 = Double.parseDouble(num1);
number2 = Double.parseDouble(num2);
}else {
System.out.println("Only enter numbers not letters.");
}
String calculation;
switch (operator) {
case "+":
calculation = (number1 + " + " + number2 + " = " + (number1 + number2));
break;
case "-":
calculation = (number1 + " - " + number2 + " = " + (number1 - number2));
break;
case "*":
calculation = (number1 + " * " + number2 + " = " + (number1 * number2));
break;
case "/":
calculation = (number1 + " / " + number2 + " = " + (number1 / number2));
break;
default:
calculation = operator + ":" + " Is not a valid operator!";
break;
}
System.out.println(calculation);
}
The main differences are that I used only one Scanner object and that I replaced your nested if/else with a switch.
Below is a sample run
Enter the operator you would like to choose(+, -, *, /): +
Enter the first number: 5.5
Enter your second number: -7.2
5.5 + -7.2 = -1.7000000000000002
Other recommended improvements are:
Loop until a valid operator is provided. There is no reason to wait until all inputs are provided to then determine the calculation cannot be done due to invalid operator.
Do something similar to #1 above for each number.
Use BigDecimal the calculation.
Format the result to show however many decimal values you want to show.
The regular expression "^[0-9]+$" only evaluates to true for integers, because it checks whether the string consists of 0 - 9. If you want to check for doubles as well, this might help: https://www.baeldung.com/java-check-string-number
The first suggestion there is probably the easiest. Surround Double.parseDouble with a try catch, because it will give you an NumberFormatException if its not a number.
How do I append every user chosen equation in an if, else if statement to a text file. I am not sure where would the best place be to put the append to file because putting it in under every else if statement seems repetitive.
import java.util.Formatter;
import java.util.Scanner;
public class javaCalculator {
public static void main(String[] args){
Scanner numbers = new Scanner(System.in);
Scanner operation = new Scanner(System.in);
double number1;
double number2;
String operator;
System.out.print("Enter the operator you would like to choose(+, -, *, /): ");
operator = operation.next();
System.out.print("Enter the first number: ");
number1 = Double.parseDouble(numbers.nextLine());
System.out.print("Enter your second number: ");
number2 = Double.parseDouble(numbers.nextLine());
if (operator.equals("+")){
String calculation = (number1 + " + " + number2 + " = " + (number1 + number2));
}else if (operator.equals("-")){
String calculation = (number1 + " - " + number2 + " = " + (number1 - number2));
}else if (operator.equals("*")){
String calculation = (number1 + " * " + number2 + " = " + (number1 * number2));
}else if (operator.equals("/")){
String calculation = (number1 + " / " + number2 + " = " + (number1 / number2));
}else{
String calculation = (operator + ":" + " Is not a valid operator!");
}
try {
Formatter file1 = new Formatter("C:\\Users\\27711\\Desktop\\PROGRAMMING\\java\\JavaCalculator");
file1.format(calculation);
}
catch (Exception e){
System.out.println("Error");
}
}
}
There are two problems here:
Attempting to use a variable when it isn't in scope
The way you're writing to a file using Formatter
Making the calculation variable available
All you need to do is declare your calculation variable once, before the if/else statements:
String calculation;
if (operator.equals("+")) {
calculation = number1 + " + " + number2 + " = " + (number1 + number2);
} else if (operator.equals("-")) {
calculation = number1 + " - " + number2 + " = " + (number1 - number2);
} else if (operator.equals("*")) {
String calculation = number1 + " * " + number2 + " = " + (number1 * number2);
} else if (operator.equals("/")) {
calculation = number1 + " / " + number2 + " = " + (number1 / number2);
} else {
calculation = operator + ":" + " Is not a valid operator!";
}
// Code to append to the file
In your current code, you're declaring a different variable in each if/else block, which means no calculation variable is in scope by the time you reach the file appending code.
An alternative approach would be to use a conditional operator. Some folks really don't like multiple uses like this, but I personally think it ends up being very readable:
String calculation =
operator.equals("+") ? number1 + " + " + number2 + " = " + (number1 + number2)
: operator.equals("-") ? number1 + " - " + number2 + " = " + (number1 - number2)
: operator.equals("*") ? number1 + " * " + number2 + " = " + (number1 * number2)
: operator.equals("/") ? number1 + " / " + number2 + " = " + (number1 / number2)
: operator + ":" + " Is not a valid operator!";
Alternatively, you might want to consider a switch statement, maybe in a whole separate method:
private static String calculate(String operator, double number1, double number2) {
switch (operator) {
case "+":
return number1 + " + " + number2 + " = " + (number1 + number2);
case "-":
return number1 + " - " + number2 + " = " + (number1 - number2);
case "*":
return number1 + " * " + number2 + " = " + (number1 * number2);
case "/":
return number1 + " / " + number2 + " = " + (number1 / number2);
default:
return operator + ":" + " Is not a valid operator!"
}
}
... or a switch expression if you're using a recent version of the language.
Writing to the file
The documentation for Formatter starts:
An interpreter for printf-style format strings.
While you can use a Formatter to write to a file, you don't want to interpret printf-style format strings at all... and you're currently not closing the formatter, either.
I'd suggest using the Files class instead. You can just write:
Files.write(Paths.get(filename), Arrays.asList(calculation));
To append, you can pass in StandardOpenOptions.APPEND:
Files.write(
// Where to write...
Paths.get(filename),
// The lines to write...
Arrays.asList(calculation),
// How to open the file...
StandardOpenOption.APPEND);
I need to first ask the user to input how many problems they want to do. Then generate the first, then the second after they answer the first and so on.
public static void main(String[] args) {
int number1 = (int) (Math.random() * 40 + 10), number2 = (int) (Math.random() * 40 + 10), uanswer, ianswer, counter, icounter,
acounter, counter1, ui, aacounter, bcounter;
Scanner input = new Scanner(System.in);
System.out.println("How many problems do you want to do?");
ui = input.nextInt();
counter = 1;
icounter = 1;
acounter = counter + icounter;
{
System.out.print("What is " + number1 + " + " + number2 + "? ");
}
uanswer = input.nextInt();
ianswer = number1 + number2;
while (counter < 10000 && icounter < 1000 && acounter < 1000 && number1
+ number2 != uanswer) {
System.out.println("Incorrect, the answer is "
+ ianswer + ", " + icounter + " out of " + icounter + " incorrect. Try again?");
icounter++;
acounter++;
uanswer = input.nextInt();
}
if (ianswer == ianswer) {
aacounter = acounter - 1;
bcounter = icounter - 1;
System.out.println("Correct, the answer is " + ianswer
+ ", " + counter + " out of " + aacounter + " correct, "
+ bcounter + " out of " + aacounter + " incorrect.");
}
}
With my current code, I only see one problem, even though I asked for 2 or more problems at the beginning.
You need to add a loop around this statement:
System.out.print("What is " + number1 + " + " + number2 + "? ");
like:
for(int i=0; i<ui; i++){
System.out.print("What is " + number1 + " + " + number2 + "? ");
...
EDIT
So I didn't realize that the program was running, it was just blank, because java reads down, the system was waiting for me to input the answer before I saw the answer. Thank you #wdc for your help.
Original
I'm currently practicing java, I came into a problem that I solved, but I don't understand why, how come the program runs when I have it like this:
import java.util.Scanner;
public class Practice {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int number1 = (int)(System.currentTimeMillis() % 10);
int number2 = (int)(System.currentTimeMillis() / 10 % 10);
System.out.print("What is " + number1 + " + " + number2 + "?");
int answer = in.nextInt();
System.out.println(number1 + " + " + number2 + " = " + answer + " is " + (number1 + number2 == answer));
}
}
But doesn't work when I have it like this:
import java.util.Scanner;
public class Practice {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int number1 = (int)(System.currentTimeMillis() % 10);
int number2 = (int)(System.currentTimeMillis() / 10 % 10);
int answer = in.nextInt();
System.out.print("What is " + number1 + " + " + number2 + "?");
System.out.println(number1 + " + " + number2 + " = " + answer + " is " + (number1 + number2 == answer));
}
}
I want to know so I can avoid this problem in the future.
Thank you ahead of time.
If I understood your question correctly, you are not sure why is the output different in this two cases?
Note that java executes the statements in the order as they appear in the code. So,
When you put int answer = in.nextInt(); before the System.out.print("What is " + number1 + " + " + number2 + "?"); your program is waiting for user input and you don't see anything printed on the screen. If you enter something in the console and press enter, the program will continue it's execution and you would see the rest of the output.
But if you move int answer = in.nextInt(); after the print statement the first print statement will be executed and you would see some output in the console.
Well saying it doesn't work its not really correct, because it does.
The problem is in the seconde snippet you have the blocking method "in.nextInt()", before the console print of the question, so you need to put he answer and only after you have the question.
Hi guys I'm writing a maths quiz program as a learning exercise and I cant get this 'response' variable to be recognised later in the method. Specifically the 'response' variable with *s either side of it does not link to the response variables declared earlier. I'm new to programming so fairly sure I'm making a basic error but I can't work it out and I'd be grateful if anyone can help me. Thanks!
import acm.util.*;
import acm.program.*;
public class MathsQuiz extends ConsoleProgram{
public void run(){
println("This program gives atudents a series of maths questions");
askQuestions();
}
private void askQuestions(){
for (int i = 0; i < NUMBER_OF_QS; i++){
askQ();
}
}
private void askQ(){
int answer = rgen.nextInt(0,20);
int number1 = rgen.nextInt(0,20);
int number2 = answer - number1;
if (number2 > 0){
int response = readInt("What is " + number1 + "+" + number2 + "?");
}else {
int response = readInt("What is " + number1 + " " + number2 + "?");
}
if (**response** == answer){
println("Correct!");
}else{
println("Incorrect");
}
}
private RandomGenerator rgen = RandomGenerator.getInstance();
int NUMBER_OF_QS = 5;
int RES = 0;
}
Move response to an outer scope:
int response;
if (number2 > 0) {
response = readInt("What is " + number1 + "+" + number2 + "?");
} else {
response = readInt("What is " + number1 + " " + number2 + "?");
}
Local variables have the most limited scope. Such a variable is
accessible only from the function or block in which it is declared.
The local variable's scope is from the line they are declared on until
the closing curly brace of the method or code block within which they
are declared.
You need to define response outside of the if statement:
int response = -1;
if (number2 > 0) {
response = /* ... Something ... */
} else {
response = /* ... Something else ... */
}
Just declare it before the if statement:
int response;
if (number2 > 0) {
response = ...
} else {
response = ...
}
Alternatively, spot the small amount of difference between the two blocks, and change just that using a conditional operator:
String separator = number2 > 0 ? "+" : " ";
int response = readInt("What is " + number1 + separator + number2 + "?");
its because you are creating the variable response inside of the if statement. try this instead
private void askQ(){
int answer = rgen.nextInt(0,20);
int number1 = rgen.nextInt(0,20);
int number2 = answer - number1;
int response; //to create the variable in the right scope
if (number2 > 0){
response = readInt("What is " + number1 + "+" + number2 + "?");
}else {
response = readInt("What is " + number1 + " " + number2 + "?");
}
if (**response** == answer){
println("Correct!");
}else{
println("Incorrect");
}
}
response is a local variable, and its accessibility is limited to inside the block in which it has been declared. So, response is accessible only within the if else block. IF you try to use response outside the area of scope, you will get a compile time error, until you don't redeclare it.
So, if you want to use response out of the if else block, you have to declare it out of the block as follows:
int response;
if (number2 > 0){
response = readInt("What is " + number1 + "+" + number2 + "?");
}else {
response = readInt("What is " + number1 + " " + number2 + "?");
}