3
\$\begingroup\$

This program has the goal to teach the user words of another language. The user has to learn words of a current section and than they get tested. The program can be modified easy. The programmer just has to add the new name of the language and the corresponding translations in the Words class.

I would like to know how I could make this more readable.

Main.java

package main;

/*
 * This Program tries to teach the user words of a foreign language.
 * It is written for the JVM 7
 */

public class Main {
    public static void main(String[] args) {
        // display some tips
        System.out.println("Some inputs require national special characters.");
        System.out.println("If your keyboard doesnt know them, put them in a file for");
        System.out.println("copying them.");
        System.out.println("This program also makes a difference between uppercase and");
        System.out.println("lowercase letters\n");

        // start program
        Test program = new Test();
        program.run();

        HelpfulFunctions.printIntrusiveAdvertising();
    }
}

Test.java

package main;

import java.util.Scanner;
import java.io.File;

// this class represents the main program and therefore the tests the user has to pass
public class Test { 
    private static Scanner input = new Scanner(System.in);

    // represents the level of the user and is also the index of the word list that has 
    // to be tested
    private int level;
    // represents the index of the language the user already knows
    // this variable  will be used to get the known language from Words.languages
    private int knownLanguageIndex;
    // represents the index of the language the user wants to learn
    private int languageToLearnIndex;
    // in this file the level of the user will be stored each time he passes a test
    private File saveFile;
    // in this file the language index numbers will be saved
    private File configFile;

    // creates a new instance of the class
    // this method automatically checks if the user already has made progress in a
    // former session
    // if he runs that program for the first time, he will be asked what he wants to 
    // learn
    public Test() {
        saveFile = new File(".languageLearningSaveFile");
        configFile = new File(".languageLearningConfigFile");
        if (saveFile.exists() && configFile.exists()) {
            loadConfig();
            loadProgress();
        } else {
            askForConfig();
            level = 0;
        }
    }

    // this is the main program of the class. Here the user can learn words for a
    // next test or he can get tested
    public void run() {
        boolean run = true;
        while(run && (level) < Words.words.length) {
            System.out.println("Your Level: " + level);
            System.out.println("[0] Leave Program");
            System.out.println("[1] Learn words");
            System.out.println("[2] Test");
            int decision = HelpfulFunctions.saveIntInput(0, 2);
            System.out.println();

            switch (decision) {
                case 0: run = false; break;
                case 1: showWords(); break;
                case 2: test(); break;
            }   
        }

        if (level == Words.words.length) {
            System.out.println("You know everything the program cna teach you!");
            System.out.println("If you want to restart, delete twe to save files");
            System.out.println("that start with a \".\".");
        }
    }

    public void showWords() {
        System.out.println("These are the words you have to learn to reach level " + 
                (level + 1) + ".\n");
        for(int i = 0; i < 15; i++) {
            System.out.println(Words.words[level][i][knownLanguageIndex] + " - " + 
                    Words.words[level][i][languageToLearnIndex]);
        }
        System.out.println();
    }

    // this is the method that tests the user
    // he has to know 15 words
    // if he makes a mistake, he has to retry the test
    // if he makes more than 3 mistakes, he loses a level
    public void test() {
        // deleting old command line output so the user can not cheat
        for (int i = 0; i < 1000; i++) {
            System.out.println("\n");
        }

        int mistakes = 0;
        for (int i = 0; i < 15; i++) {
            System.out.print(Words.words[level][i][knownLanguageIndex] + " - ");
            String guess = input.nextLine();
            if(guess.equals(Words.words[level][i][languageToLearnIndex])) {
                System.out.println("Right");
            } else {
                mistakes++;
                System.out.println("Wrong!");
                if (mistakes == 3) {
                    break;
                }
            }
        }
        System.out.println();
        if (mistakes == 0) {
            level++;
            System.out.println("Congratulations!");
            System.out.println("Your reached level " + level + "!");
        } else if (mistakes == 3) {
            System.out.println("Sorry, but you have made to many mistakes!");
            if (level > 0) {
                level--;
                System.out.println("You have to retry an old test");
            }
        } else if (mistakes < 3) {
            System.out.println("Sorry but you have made to many mistakes!");
            System.out.println("More luck next time!");
        }
        saveProgress();
        System.out.println();
        HelpfulFunctions.wait(2000);
    }

    // this functions asks the user which language he can speak and which language
    // he wants to learn
    public void askForConfig() {
        // initialize knownLanguageIndex
        System.out.println("I can allready speak: ");
        HelpfulFunctions.displayOptions(Words.languages);
        knownLanguageIndex = HelpfulFunctions.saveIntInput(1, Words.languages.length) 
                - 1;

        // initialize languageToLearnIndex
        System.out.println("\nI want to learn: ");
        HelpfulFunctions.displayOptions(Words.languages);
        boolean inputAccepted = false;
        while (!inputAccepted) {
            languageToLearnIndex = HelpfulFunctions.saveIntInput(1, 
                    Words.languages.length) - 1;
            if (languageToLearnIndex == knownLanguageIndex) {
                System.out.println("Nice try. chose a language that doesnt equals "
                        + "the language that you can speak.");
            } else {
                inputAccepted = true;
            }
        }
        System.out.println();
        saveConfig();
    }

    // the following four methods save necessary data to a file or load data from the 
    // files

    public void saveConfig() {
        HelpfulFunctions.storeLinesToFile(configFile, String.valueOf(knownLanguageIndex), 
                String.valueOf(languageToLearnIndex));
    }

    public void loadConfig() {
        String[] config = HelpfulFunctions.readLinesFromFile(configFile, 2);
        knownLanguageIndex = Integer.parseInt(config[0]);
        languageToLearnIndex = Integer.parseInt(config[1]);
    }

    public void saveProgress() {
        HelpfulFunctions.storeLinesToFile(saveFile, String.valueOf(level));
    }

    public void loadProgress() {
        level = Integer.parseInt(HelpfulFunctions.readLinesFromFile(saveFile, 1)[0]);
    }
}

Words.java

package main;

// this class contains the languages and the words that can be learned.
public class Words {
    public static String languages[] = {"English", "Deutsch", "Français"};

    // These array has lists of tests. A test consists of 15 words. Here all words of
    // all languages are stored. The Test class has to care about taking the words
    // the user wants to learn. How Test realizes that is described there.
    public static String words[][][] = 
    {
        { 
            {"hello", "Hallo", "bonjour"},
            {"house", "Haus", "maison"},
            {"love", "Liebe", "amour"},
            {"hate", "Hass", "haine"},
            {"luck", "Glück", "bonheur"},
            {"freedom", "Freiheit", "liberté"},
            {"tree", "Baum", "arbre"},
            {"sweet", "süß", "doux"},
            {"past", "Vergangenheit", "passé"},
            {"stupid", "dumm", "stupide"},
            {"clever", "klug", "sage"},
            {"go", "gehen", "aller"},
            {"run", "laufen", "course"},
            {"take", "nehmen", "prendre"},
            {"sleep", "schlafen", "sommeil"}
        },
        {
            {"pen", "Kugelschreiber", "stylo"},
            {"joy", "Freude", "plaisir"},
            {"happiness", "Fröhlichkeit", "bonne humeur"},
            {"beauty", "Schönheit", "beauté"},
            {"sprint", "sprinten", "sprint"},
            {"program", "programmieren", "programme"},
            {"tell", "erzählen", "dire"},
            {"scream", "schreien", "cri"},
            {"cry", "weinen", "cri"},
            {"exult", "jauchzen", "exulter"},
            {"qualify", "relativieren", "qualifier"},
            {"win", "siegen", "victoire"},
            {"lose", "verlieren", "perdre"},
            {"victory", "Sieg", "victoire"},
            {"defeat", "Niederlage", "défaite"}
        },
        {
            {"programming language", "Programmiersprache", "langage de programmation"},
            {"genius", "Genie", "génie"},
            {"eraser", "Radierer", "gomme"},
            {"train", "Zug", "train"},
            {"table", "Tisch", "table"},
            {"virtual", "virtuell", "virtuel"},
            {"real", "echt", "vraiment"},
            {"plate", "Teller", "plaque"},
            {"fork", "Gabel", "fourchette"},
            {"knife", "Messer", "couteau"},
            {"spoon", "Löffel", "cuillère"},
            {"laptop", "Klapprechner", "plieuse"},
            {"head", "Kopf", "tête"},
            {"shoulder", "Schulter", "épaule"},
            {"knee", "Knie", "genou"},
        },
        {
            {"glasses", "Brille", "lunettes"},
            {"salvation", "Heil", "salut"},
            {"possibility", "Möglichkeit", "occasion"},
            {"error", "Fehler", "erreur"},
            {"lamp", "Lampe", "lampe"},
            {"mouse", "Maus", "souris"},
            {"keyboard", "Tastatur", "clavier"},
            {"pencil case", "Federtasche", "sac à crayons"},
            {"television", "Fernseher", "TV"},
            {"feedback", "Rückkopplung", "réaction"},
            {"acquisition", "Errungenschaft", "acquisition"},
            {"tax", "Steuer", "taxe"},
            {"tabbaco", "Tabak", "tabac"},
            {"beer", "Bier", "bière"},
            {"cigarette", "Zigarette", "cigarette"},
        },
        {
            {"music", "Musik", "musique"},
            {"deny", "verneinen", "nier"},
            {"blessing", "Segen", "bénédiction"},
            {"automobile", "Auto", "voiture"},
            {"explain", "erklären", "expliquer"},
            {"proclaim", "verkünden", "annoncer"},
            {"interesting", "interessant", "intéressant"},
            {"drawer", "Schublade", "tiroir"},
            {"dog", "Hund", "chien"},
            {"cat", "Katze", "chat"},
            {"red", "rot", "rouge"},
            {"green", "grün", "bleu"},
            {"yellow", "gelb", "jaune"},
            {"blue", "blau", "bleu"},
            {"country", "Land", "pays"},
        },
    };
}

HelpfulFunctions.java

package main;

import java.util.Scanner;
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;

// this class provides useful methods for integer input, for storing data to or reading 
// data from a file and for displaying options in a nice way. 
public class HelpfulFunctions {
    private static Scanner input = new Scanner(System.in);

    // this method reads lines from a file and returns the lines as a String array
    public static String[] readLinesFromFile(File file, int numberOfLines) {
        String[] lines = new String[numberOfLines];

        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            for (int i = 0; i < numberOfLines; i++) {
                lines[i] = br.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return lines;
    }

    // this method stores strings as lines to a specified file
    public static void storeLinesToFile(File file, String... strings) {
        try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
            for (String string : strings) {
                bw.write(string + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // this method can be used as a safe way to get an int value from the user
    public static int saveIntInput(int min, int max) {
        int number = 0;
        boolean inputAccepted = false;
        while(!inputAccepted) {
            System.out.print("Input: ");
            try {
                String userInput = input.nextLine();
                number = Integer.parseInt(userInput);
                if (number > max || number < min) {
                    System.out.println("Please enter a valid argument.");
                } else {
                    inputAccepted = true;
                }
            } catch (NumberFormatException e) {
                System.out.println("Please enter a valid argument.");
            }
        }
        return number;
    }

    // this class takes a string array and prints its elements out with numbers
    public static void displayOptions(String[] list) {
        for (int i = 0; i < list.length; i++) {
            System.out.println("[" + (i + 1) + "] " + list[i]);
        }
    }

    // the program stops its execution for a specified time
    public static void wait(int milliseconds) {
        try {
            Thread.sleep(milliseconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void printIntrusiveAdvertising() {
        System.out.println("Thanks for trying out this program!");
        System.out.println("If you want to learn german, also try out Arthoria.de.");
        System.out.println("Its a nice and very complex german role playing game!");
        wait(5000);
    }
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Wouldn't it make more sense to extend the progam via plain text files so non-programmers can update it too? \$\endgroup\$
    – yuri
    May 9, 2018 at 12:22

1 Answer 1

1
\$\begingroup\$

Comments

I think there are too many comments in your code (Yes, it'a thing). For example :

// this is the main program of the class. Here the user can learn words for a
// next test or he can get tested
public void run() {

These comments don't really need to exist because the person that can read the comments should be able to read the code. And the code should "tell" exactly what your comments are saying. Usually, comments are used to explain a complex piece of code or to provide additional documentation in regards to the code.

Exception handling

} catch (IOException e) {
    e.printStackTrace();
}

This isn't really a good practice. If there's an exception you should either deal with it or crash. If, for example, your application is supposed to be writing to a file and it doesn't work, the app shouldn't keep on going, something abnormal just happened.

Console printing

I don't really understand these sentences (from an user point of view):

System.out.println("You know everything the program cna teach you!");
System.out.println("If you want to restart, delete twe to save files");
System.out.println("that start with a \".\".");

Application flow

I think you should create a variable for this : Words.words[level][i][languageToLearnIndex], for clarity's sake more than anything else. You use it twice and it would remove some clutter from your code.

\$\endgroup\$
2
  • \$\begingroup\$ If this is everything a programmer would mention about my code, I think I can be happy! \$\endgroup\$ May 9, 2018 at 17:00
  • \$\begingroup\$ @DexterThorn There might be other things, and I'm pretty sure other reviews will come, I didn't have time to check your whole code. But you can be proud you did a pretty good job :) \$\endgroup\$
    – IEatBagels
    May 9, 2018 at 17:06

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.