HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Java Console Quiz

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
consolequizjava

Problem

I started learning Java 2 weeks ago, so I don't know that much. I recently made a working console quiz and I'm wondering if there is a simpler way to do it.

```
import java.util.*;
import java.io.*;

class StudyBot
{
static int[][][] GradeValues = {{{93, 100}, {90, 92}}, {{87, 89}, {83, 86}, {80, 82}}, {{77, 79}, {73, 76}, {70, 72}}, {{67, 69}, {64, 66}}, {{0, 63}}};
static Scanner istr = new Scanner(System.in), iint = new Scanner(System.in);
static Map data = new HashMap();
static boolean word_Prob, multi_Choice;
static double correct = 0, incorrect = 0;
static int question_Number = 0, amount_Of_Questions = 10;
static String result = "";

public static void main(String[] args)
{
new StudyBot();
}

public StudyBot()
{
setupData(); mainMenu();
}

void mainMenu()
{
printline(0);
print("[StudyBot] Welcome to StudyBot!");
printline(0);
print("[StudyBot] Pick a Mode: Study OR Add Data");
String input = istr.nextLine();
if(input.equalsIgnoreCase("Study")) start();
else if(input.equalsIgnoreCase("Add Data")) addData();
else print("Invaild mode!"); mainMenu();
}

void start()
{
for(int index = 0; index keys = new ArrayList(data.keySet());
String key = keys.get(rand(keys.size()));
String value = (String) data.get(key);
askQuestion(key, value);
}

void askQuestion(String question, String answer)
{
questionType();
if(word_Prob) wordProblem(question, answer);
else multiChoice(question, answer);
}

void wordProblem(String question, String answer)
{
question_Number++;
printline(0);
print("[Question " + question_Number + "] What is " + question + "?");
printline(1);
String user_Answer = istr.nextLine();
String[] user_Words = user_Answer.split(" "), answer_Words = answer.split(" ");
List matched

Solution

Your a beginner and we can see it.

So let's educate you a few important things.

Access modifiers.

This is the first thing that I noticed, and almost every beginner will make this fault.

class StudyBot {


At this moment is your access modifier package private, and this is a choice what's rarely need's to be made.

The normal setup for a class is public, protected or private.

The same counts for your variable :

static int[][][] GradeValues = {{{93, 100}, {90, 92}}, {{87, 89}, {83, 86}, {80, 82}}, {{77, 79}, {73, 76}, {70, 72}}, {{67, 69}, {64, 66}}, {{0, 63}}};
static Scanner istr = new Scanner(System.in), iint = new Scanner(System.in);
static Map data = new HashMap();


Make them private, if you don't need to acces them outside this class.

Static, Final when to choose?

We just spoke of your variable to have an acces modifier.

Some of your variable you never want to instantiate a second time.

If this is the case, make them also final.

But don't forget a static variable is the same for all instances.

If you change your result and a second instance is running, they will mix it up.

So always think good when you make a variable static. Will it interfere with other instances or not.

Naming variable

Your naming is overall good.

Some small errors like :

static int[][][] GradeValues = {{{93, 100}, {90, 92}}, {{87, 89}, {83, 86}, {80, 82}}, {{77, 79}, {73, 76}, {70, 72}}, {{67, 69}, {64, 66}}, {{0, 63}}};
static Scanner istr = new Scanner(System.in), iint = new Scanner(System.in);


The first one(GradeValue) should start with a lowercase.

istr is just a bad name because if you don't see the instance, you never know what it means.

A better name could be scanner.

As for iint, well it's never used in your class, so remove it.

1 line 1 thing.

public StudyBot() {
    setupData(); mainMenu();
}


While it's not wrong, we do prefer to have this in 2 lines to improve the readability for other people.

public StudyBot() {
    setupData();
    mainMenu();
}


The same counts for here :

else setupData(); pickQuestion();


You even make an (unwanted) fault here.

For the readers this seems like the 2 methods should be executed in the else.

The actually effect is that pickQuestion(); is always executed, think of the "goto fail" bug of apple.

This should be better :

else {
    setupData();
}
pickQuestion();


As you can see, you do more things like this but please put curly braces with each if and else.

Boolean operators

for(int index = 0; index < (amount_Of_Questions + 1); index++)


Here you count 1 to
amount_Of_Questions but actually you can say smaller or equal.

The +1 is done by every iteration, witch means every iteration you take time to add 1 to
amount_Of_Questions.

Better could be :

for(int index = 0; index <= (amount_Of_Questions + 1); index++)


Almost the same for here :

if(!(index < amount_Of_Questions))


Here you say if it's not smaller then.

Not smaller then is the same as : bigger or the same.

if(index >= amount_Of_Questions)


But if we look further, index can never be bigger then
amount_Of_Questions because the last iteration is when it's equal.

So an even better improvement could be :

if(index = amount_Of_Questions)


Usage of for each, and beyond

void displayData(String s) {
    Set set = data.entrySet(); 
    Iterator i = set.iterator();
    while(i.hasNext())
    {
        Map.Entry e = (Map.Entry)i.next();
        String key = e.getKey().toString();
        String k = (String) e.getKey(), v = (String) e.getValue();
        String data = ((s != null ? (key.equals(s) ? (k + ": " + v) : null) : (k + ": " + v)));
        if(data != null) print(data);
    }
}


You iterate over the whole entryset of a Map.

You even bring casting to it because you work with the iterator.

Let us use a foreach :

private void displayData(String s) {
    for (Entry e : data.entrySet()) {
        String key = e.getKey().toString();
        String k = (String) e.getKey(), v = (String) e.getValue();
        String data = ((s != null ? (key.equals(s) ? (k + ": " + v) : null) : (k + ": " + v)));
        if(data != null) {
            print(data);
        }
    }
}


As you can see, it's already a lot smaller and cleaner.

But I'm not finding this clean or good.

Let us use some methods of
Map.

private void displayData(String key) {
    if (data.containsKey(key)) {
        Object value = data.get(key);
        print(key + ": " + String.valueOf(value));
    }
}


So you wanted to print when you had an key in the
Map.

Map has a method called containsKey(Object key) so we use it to know if we need to fetch the value and print it.

When the key is present, we will fetch the value, and print it out.

One of the best things to do is call
String.valueOf if you want to convert a Object to a String`.

I'm going to leave it here for the moment.

I hope you ar

Code Snippets

class StudyBot {
static int[][][] GradeValues = {{{93, 100}, {90, 92}}, {{87, 89}, {83, 86}, {80, 82}}, {{77, 79}, {73, 76}, {70, 72}}, {{67, 69}, {64, 66}}, {{0, 63}}};
static Scanner istr = new Scanner(System.in), iint = new Scanner(System.in);
static Map<String, Object> data = new HashMap<String, Object>();
static int[][][] GradeValues = {{{93, 100}, {90, 92}}, {{87, 89}, {83, 86}, {80, 82}}, {{77, 79}, {73, 76}, {70, 72}}, {{67, 69}, {64, 66}}, {{0, 63}}};
static Scanner istr = new Scanner(System.in), iint = new Scanner(System.in);
public StudyBot() {
    setupData(); mainMenu();
}
public StudyBot() {
    setupData();
    mainMenu();
}

Context

StackExchange Code Review Q#110327, answer score: 2

Revisions (0)

No revisions yet.