7
\$\begingroup\$

Over the last few days I created this Pig Latin Translator just for fun. I would really appreciate it if anybody could give suggestions of how to improve the code and make the program more efficient.

Here is the GitHub link for the project.

For anybody who doesn't know the Pig Latin, feel free to look at the README, which explains what Pig Latin is, and the rules of the language. The code is in PigLatin.java.

    /*  -------------------- Program Information --------------------
    Name Of Program: PigLatin.java
    Date of Creation: 7/3/2018
    Name of Author(s): Agnik Banerjee
    Version of Java: 1.8.0_171
    Created with: IntelliJ IDEA 2017.3.5 Community Edition
    -------------------- Program Information --------------------  */

import java.util.Scanner;

public class PigLatin {

    private static Scanner scan = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.print("Enter one or more words that you would like to translate to Pig Latin: ");
        final String userInput = scan.nextLine();
        scan.close();

        String[] word = userInput.split(" "); // Splits the string into an array of words
        String output = "";

        for (int i = 0; i < word.length; i++) {
            String pigLatinWord = translateWord(word[i]); // Translates each word individually
            output += pigLatinWord + " "; // Joins the translated word back into the output
        }

        System.out.println("Original Word(s): " + userInput);
        System.out.println("Translation: " + output + "\n");
    }

    public static String translateWord(String word) {
        String lowerCaseWord = word.toLowerCase();
        int pos = -1; // Position of first vowel
        char ch;

        // This for loop finds the index of the first vowel in the word
        for (int i = 0; i < lowerCaseWord.length(); i++) {
            ch = lowerCaseWord.charAt(i);

            if (isVowel(ch)) {
                pos = i;
                break;
            }
        }

        if (pos == 0) {
            // Translating word if the first character is a vowel (Rule 3)
            return lowerCaseWord + "yay"; // Adding "yay" to the end of string (can also be "way" or just "ay")
        } else {
            // Translating word if the first character(s) are consonants (Rule 1 and 2)
            String a = lowerCaseWord.substring(pos); // Extracting all characters in the word beginning from the 1st vowel
            String b = lowerCaseWord.substring(0, pos); // Extracting all characters located before the first vowel
            return a + b + "ay"; // Adding "ay" at the end of the extracted words after joining them.
        }
    }

    // This method checks if the character passed is a vowel (the letter "y" is counted as a vowel in this context)
    public static Boolean isVowel(char ch) {
        if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'y') {
            return true;
        }
        return false;
    }
}
\$\endgroup\$
  • \$\begingroup\$ IntelliJ should have already suggested you change string concatenation in a loop to StringBuilder, and simply the if condition in the method isVowel. Most of the time, you can go with what is suggested by your IDE. \$\endgroup\$ – Ankit Soni Jul 6 '18 at 6:57
2
\$\begingroup\$

I would suggest the following points to make this programme more object-oriented:

Try using a collection object provided by Java instead of using array

String[] word = userInput.split(" ");

could be

List<String> words = Arrays.asList(userInput.split(" "));

or using external library Guava

List<String> words = Splitter.on(" ").splitToList(userInput);

Avoid comments where you can.

In this case I can see you can easily avoid comment if you can wrap up the particular code snippet with the meaningful name. For instance You could take the user input and breaking it in a list in separate class and call the class from your main

List<String> words = new UserInputHandler().getInputAsList();

Try to use foreach loop over for loop:

You can easily use the foreach loop to iterate over words

for (String word : words) {
    String pigLatinWord = translateWord(word); // Translates each word individually
    output += pigLatinWord + " "; // Joins the translated word back into the output
}

Again as suggested before you can wrap the code inside for loop in a separate class so that you could call

for (String word : words) {
    output = new PigLatinTranslator(word, output).translate();
}
\$\endgroup\$
  • \$\begingroup\$ Thank you for you suggestions, Debmalya! I'll make sure to implement them into my program as soon as I can! \$\endgroup\$ – Agnik Banerjee Jul 14 '18 at 17:10
1
\$\begingroup\$

Just a small detail without repeating what other answers have provided

isVowel

Your isVowel method can be reduced significantly. The first step is to simply return the expression, instead of true if the expression results in a truthy, or false otherwise. Have a look:

public static Boolean isVowel(char ch) {
    return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'y';
}

The next step is to get rid of this huge ugly line. You can utilize indexOf to check if the passed character is within a string, shortening this line greatly. Have a look:

public static boolean isVowel(char c) {
    return "aeiouy".indexOf(c) != -1;
}

If the character passed is not in the string containing all vowels, then indexOf will return -1, causing the function to return false. Using some built in java methods can really help shorten your code and perhaps make it more efficient.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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