3
\$\begingroup\$

This is a program where you are asked what operation you would like (addition, subtraction etc), what range of numbers you'd like, and then it creates an exercise then it asks you for the answer.

Feel free to comment about anything. It is my first time showing my code to other people so it's bound to be crappy.

import java.util.Scanner;
import java.util.Random;
public class mathWork {
    public static void main(String[] args) {
        SetUp setUp = new SetUp();
        UserChoices user = new UserChoices();
        setUp.chooseNumberRange(user); 
        System.out.println("Your max range is! " + user.getUserMaxRange());
        System.out.println("Your chosen operator is " + user.getUserOperator());
        CreateExercise create = new CreateExercise();
        create.generateExercise(user);
    }
}
class SetUp {
    public void chooseNumberRange(UserChoices user) {
        //These are the possible number ranges for a math exercise.
        int min1 = 0;
        int max1 = 9;
        int min2 = 10;
        int max2 = 100;
        Scanner scan = new Scanner(System.in);
        //Here we prompt the user to choose his type of math exercise.
        System.out.println("Welcome to Math Work! Please select your " 
            + "choice of operation: \n" + " 1.Addition" 
            + "\n 2.Subtraction" + "\n 3.Multiplicaiton" 
            + "\n 4.Division");
        int userOperatorChoice = scan.nextInt();
        switch (userOperatorChoice) {
            case 1:
                user.setUserOperator('+');
                break;
            case 2:
                user.setUserOperator('-');
                break;
            case 3:
                user.setUserOperator('*');
                break;
            case 4:
                user.setUserOperator('/');
                break;
        }
        //Here we prompt the user to choose what range of numbers he'd want in a math drill
        System.out.println("Now please select preferred number" 
            + " range. Your options are: \n 1." + min1 + " to " + max1 
            + "\n 2." + min2 + " to " + max2);
        int userRangeChoice = scan.nextInt();
        switch(userRangeChoice) {
            case 1 :
                user.setUserMinRange(min1);
                user.setUserMaxRange(max1);
                break;
            case 2 :
                user.setUserMinRange(min2);
                user.setUserMaxRange(max2);
                break;
        }
    }
}
class UserChoices {
    //Here we store the user choices
    private int userMinRange = 0;
    private int userMaxRange = 0;
    private char operator;

    public void setUserMinRange(int u) {
        userMinRange = u;
    }
    public int getUserMinRange() {
        return userMinRange;
    }

    public void setUserMaxRange(int u) {
        userMaxRange = u;
    }
    public int getUserMaxRange() {
        return userMaxRange;
    }

    public void setUserOperator(char o) {
        operator = o;
    }
    public char getUserOperator() {
        return operator;
    }
}

class CreateExercise {
    //Here we create the exercises and prompt the user for an answer
    public void generateExercise(UserChoices user) {
        Random rng = new Random();
        Scanner scan = new Scanner(System.in);
        int max = user.getUserMaxRange();
        int min = user.getUserMinRange();
        int i = 0;
        while(i < 10) {
            int firstNum = rng.nextInt((max + 1) - min) + min ;
            int secondNum = rng.nextInt((max + 1) - min) + min ;

            System.out.println("What is the answer to: \n" +
                firstNum + user.getUserOperator() + secondNum);
            switch(user.getUserOperator()){
                case '+': 
                    if (scan.nextInt() == (firstNum+secondNum)) {
                        System.out.println("Correct!");
                        break;
                    } else {System.out.println("Wrong");}
                case '-': 
                    if (scan.nextInt() == (firstNum-secondNum)) {
                        System.out.println("Correct!");
                        break;
                    } else {System.out.println("Wrong");}
                case '*': 
                    if (scan.nextInt() == (firstNum*secondNum)) {
                        System.out.println("Correct!");
                        break;
                    } else {System.out.println("Wrong");}
                case '/': 
                    if (scan.nextInt() == (firstNum/secondNum)) {
                        System.out.println("Correct!");
                        break;
                    } else {System.out.println("Wrong");}
                i++;
            }
        }
    }
}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

First of all: getting a program running is an achievement in itself. Stylistic improvement is the next step of the learning curve.

Main concern: the classes you introduced often represent more procedures than objects. So you missed some opportunities for a more object-oriented design.

When you describe the task your program is to solve in written English, the nouns from the sentences are good candidates for classes, and the verbs for methods inside the classes.

UserChoices class

Of your classes, I like UserChoices most. Its fields (and methods) represent exactly what the name tells: the choices that the user made.

Setup class

I don't like the Setup class. It does not represent a type of entity, but just holds one method, and this method is all about UserChoices and how to get them from the user. So, I'd delete the Setup class, move this method over to the UserChoices class and change it to a static method returning the choices the user made:

public static UserChoices fromUser() {
    // user dialog instructions
    return new UserChoices(min, max, operation);
}

Maybe you noticed that I introduced a UserChoices constructor with 3 parameters. I recommend to have an instance filled with the necessary data already in the constructor. This reduces the risk that you forget to set one of the fields (e.g. the operation) and later your program behaves strangely because of an incompletely-filled UserChoices object. With the fully-parameterized constructor, there's no need for the UserChoices.setXXX() methods anymore, so they can be deleted.

And I changed from the parameter UserChoices user to a return value of class UserChoices. Why? The thing you pass into the method isn't yet "user choices". It's plain empty, so it doesn't contain any information useful as input to the user dialog. It's just the other way round: logically, the user choices are the result of the dialog, they begin to exist because of the dialog. So I chose to have the method create and return a UserChoices object. This more naturally reflects the real information flow.

CreateExercise class

Once again, this class is named for an action and not for a type of entity. So I'd rename it to simply Exercise.

Object-oriented design is about objects and activities for these objects. So, what can you do with your exercise? You can set the parameters (UserChoices), and you can run an exercise based on these parameters. I'd implement these actions as distinct methods, so you can later implement more complex learning programs that guide the user through different exercises, depending on his or her results, practicing a given operation until the results are satisfactory.

public class Exercise {
    private UserChoices parameters;
    public Exercise() {
    }
    public void setParameters(UserChoices parameters) {
        this.parameters = parameters;
    }
    public void run() {
        // do the exercise
    }
}

mathWork class

I'd eliminate this class and move the main method into the Exercise (unless you want to extend your program to other aspects besides exercises).

And the class name is the only one that doesn't follow the Java Naming conventions. It starts with a lowercase character - so to me it looks like a method or field name.

Summary

My version of the program has two classes: Exercise being the main thing (an exercise), and UserChoices as a property of the exercise, defining its topic (operation) and difficulty (number range).

With the changes I proposed, the resulting main method is:

public static void main(String[] args) {
    Exercise exercise = new Exercise();
    exercise.setParameters(UserChoices.fromUser());
    exercise.run();
}

I hope you like it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.