patternjavaModerate
Maths test program
Viewed 0 times
mathsprogramtest
Problem
I have written this simple program that is a basically a maths test. I would like to know is there any areas I can improve on and if I have any bad habits that would be useful to break now. I realise I could have written this in the main class, but I was trying to practice implementing other classes, so I tried to use a few classes.
Also, are there good practices that I am using that I should try to keep?
P.S. I don't usually use the comments I just added them to tell you what my intention is for a particular piece of code.
Also, are there good practices that I am using that I should try to keep?
P.S. I don't usually use the comments I just added them to tell you what my intention is for a particular piece of code.
import java.util.Scanner;
import java.util.Random;
class Machine {
int num1, num2, ans, att;
int score = 0;
Random rand = new Random();
Scanner in = new Scanner(System.in);
public void sumGenerator(){
num1 = rand.nextInt(10);
num2 = rand.nextInt(10);
ans = num1 + num2;
System.out.println(num1 + " + " + num2 );
}//sumGenerator Method
public void answerGetter_score(){
att = in.nextInt();
if(att == ans){
score = score + 1;
System.out.println("Correct");
System.out.println("Score is currently: " + score + "/5");
}else{
score = score - 1;
System.out.println("Incorrect");
System.out.println("Score is currently: " + score + "/5");
}//else
}//answer Getter method
}//machine class
public class calcu {
public static void main(String[] args) {
Machine machine1 = new Machine();
System.out.println("***Welcome to addition Math test***");
for(int i=5; i>0; i--){
machine1.sumGenerator();
machine1.answerGetter_score();
}
System.out.println("Thanks for taking the test.");
}//main methodSolution
Naming and Problem Decomposition
For this problem, I think that there should be two classes:
What if you want to change the quiz to do multiplication? Just swap out the
Code Formatting (only because you asked about good habits)
Consistent indentation is very important for readability. Do that, and discard the noisy
Also, add some horizontal spacing around punctuation, such as comparison operators.
The one-point penalty for an incorrect answer deserves a comment, since not everyone expects that behaviour.
Proposed Solution
QuestionGenerator.java:
SumGenerator.java:
ArithmeticQuiz.java:
- Class names should be nouns; method names should be verbs. If you have a method named as a noun like
sumGenerator(), that's a red flag.
- Each method should do one thing only; its name should reflect its purpose. If you have a method named
answerGetter_score(), that's a red flag. Is it getting an answer and keeping score? It also breaks the standardinterCapsNaming()convention.
- Each class should do one thing only; its name should reflect its purpose. I have no idea what a
Machineor acalcuis. The latter also breaks the standard capitalization convention.
- Separate your input/output routines from the calculation routines. Forcing yourself to separate the two helps you come up with clean designs.
- Keep your
main()function minimal. The temptation to stuff a lot of functionality intomain()leads to sloppy design.
- Avoid hard-coding assumptions in more than one place. What if you want to change the length of the quiz? Currently, 5 is hard-coded in several places. It's easy to introduce a bug if someone fails to make the same change everywhere.
For this problem, I think that there should be two classes:
SumGenerator and ArithmeticQuiz. SumGenerator is responsible for making random addition questions. ArithmeticQuiz "drives" it.What if you want to change the quiz to do multiplication? Just swap out the
SumGenerator for a ProductGenerator. To ease that transition, it would be helpful to define a QuestionGenerator interface.Code Formatting (only because you asked about good habits)
Consistent indentation is very important for readability. Do that, and discard the noisy
//end comments.Also, add some horizontal spacing around punctuation, such as comparison operators.
The one-point penalty for an incorrect answer deserves a comment, since not everyone expects that behaviour.
Proposed Solution
QuestionGenerator.java:
interface QuestionGenerator {
void next();
String getQuestion();
int getAnswer();
}SumGenerator.java:
import java.util.Random;
class SumGenerator implements QuestionGenerator {
private int maxAddend, num1, num2, ans;
private Random rand = new Random();
public SumGenerator(int maxAddend) {
this.maxAddend = maxAddend;
this.next();
}
@Override
public void next() {
num1 = rand.nextInt(this.maxAddend + 1);
num2 = rand.nextInt(this.maxAddend + 1);
ans = num1 + num2;
}
@Override
public String getQuestion() {
return num1 + " + " + num2;
}
@Override
public int getAnswer() {
return ans;
}
}ArithmeticQuiz.java:
import java.util.Scanner;
public class ArithmeticQuiz {
private int length;
private QuestionGenerator questions;
public ArithmeticQuiz(int length, QuestionGenerator q) {
this.length = length;
this.questions = new SumGenerator();
}
public void run() {
// Closing the Scanner after use is a good habit.
// Automatically closing the Scanner using the
// try-with-resources feature of Java 7 is even better.
try (Scanner in = new Scanner(System.in)) {
int score = 0;
for (int i = this.length; i > 0; i--) {
System.out.println(this.questions.getQuestion());
int answer = in.nextInt();
if (this.questions.getAnswer() == answer) {
score++;
System.out.println("Correct");
}else{
score--; // Penalty for incorrect answer
System.out.println("Incorrect");
}
System.out.printf("Score is currently: %d/%d\n", score, this.length);
this.questions.next();
}
}
}
public static void main(String[] args) {
System.out.println("***Welcome to addition Math test***");
ArithmeticQuiz quiz = new ArithmeticQuiz(5, new SumGenerator(9));
quiz.run();
System.out.println("Thanks for taking the test.");
}
}Code Snippets
interface QuestionGenerator {
void next();
String getQuestion();
int getAnswer();
}import java.util.Random;
class SumGenerator implements QuestionGenerator {
private int maxAddend, num1, num2, ans;
private Random rand = new Random();
public SumGenerator(int maxAddend) {
this.maxAddend = maxAddend;
this.next();
}
@Override
public void next() {
num1 = rand.nextInt(this.maxAddend + 1);
num2 = rand.nextInt(this.maxAddend + 1);
ans = num1 + num2;
}
@Override
public String getQuestion() {
return num1 + " + " + num2;
}
@Override
public int getAnswer() {
return ans;
}
}import java.util.Scanner;
public class ArithmeticQuiz {
private int length;
private QuestionGenerator questions;
public ArithmeticQuiz(int length, QuestionGenerator q) {
this.length = length;
this.questions = new SumGenerator();
}
public void run() {
// Closing the Scanner after use is a good habit.
// Automatically closing the Scanner using the
// try-with-resources feature of Java 7 is even better.
try (Scanner in = new Scanner(System.in)) {
int score = 0;
for (int i = this.length; i > 0; i--) {
System.out.println(this.questions.getQuestion());
int answer = in.nextInt();
if (this.questions.getAnswer() == answer) {
score++;
System.out.println("Correct");
}else{
score--; // Penalty for incorrect answer
System.out.println("Incorrect");
}
System.out.printf("Score is currently: %d/%d\n", score, this.length);
this.questions.next();
}
}
}
public static void main(String[] args) {
System.out.println("***Welcome to addition Math test***");
ArithmeticQuiz quiz = new ArithmeticQuiz(5, new SumGenerator(9));
quiz.run();
System.out.println("Thanks for taking the test.");
}
}Context
StackExchange Code Review Q#42449, answer score: 12
Revisions (0)
No revisions yet.