7
\$\begingroup\$

This is an updated version of my previous Java program that asks the user for a sentence and then separates the words and then converts the sentence into Pig Latin. My previous program was working, but there was some tweaking that needed to be done which I did after getting positive feedback. Apparently, my loop in the separateWords function was checking for capital letters twice or so. I have included the instructions for the assignment for reference and the code for peer edit.

  1. The program will accept a string as input in which all of the words are run together, but the first character of each word is uppercase. Convert the string to a string in which the words are separated by spaces and only the first word starts with an uppercase letter. For example, the string "StopAndSmellTheRose" would be converted to "Stop and smell the roses"

  2. Then the program will convert each word in the result string of task 1 into "Pig Latin". In one version of Pig Latin, you convert a word by removing the first letter, placing that letter at the end of the word, and then appending "ay" to the word.

For example, for the result string "Stop and smell the roses" in task 1, the Pig Latin string should be "topSay ndaay mellsay hetay osesray"

Requirements:

  • Your program should have 3 methods: a main method, a method for task 1, and a method for task2
  • the method for task 1 should return the result string of task1
  • the method for task 2 should display the Pig Latin string

public class Assignment9 {
public static void main(String[] args) {    
    // Variables
    String sentence, revisedSentence; 

    // Create a Scanner object for keyboard input
    Scanner keyboard = new Scanner(System.in); 

    // Get the input string
    System.out.print("Enter sentence: ");
    sentence = keyboard.nextLine(); 

    //Close keyboard
    keyboard.close();

    // Call function to perform Task 1
    revisedSentence = separateWords(sentence); 

    System.out.print("Revised Sentence: " +revisedSentence); 

    // Call function to perform Task 2
    toPigLatin(revisedSentence); 
}

private static String separateWords(String sentence) 
{
    // Variables 
    StringBuilder str = new StringBuilder(sentence); 
    int i = 1; 

     // While loop repeats until the end of the sentence
    while (i < str.length())
    {
        // Checks for upper case characters
        if(Character.isUpperCase(str.charAt(i)))
        {
            str.insert(i, ' '); 
            i++;
            char ch = Character.toLowerCase(str.charAt(i)); 
            str.setCharAt(i, ch);
        }
        i++; 
    }
    return str.toString();
}

private static void toPigLatin(String revisedSentence) 
{   
    // Variables
    String latin = " "; 

    // Split sentence by spaces
    String[] tokens = revisedSentence.split(" ");       

    // Convert English sentence into Pig Latin 
    for (int i = 0; i < tokens.length; i++)
    {
        // Get string from array
        String str = tokens[i]; 

        // Get first letter from string
        String str1 = str.substring(0, 1); 

        // Get substring from string
        String str2 = str.substring(1, str.length()); 

        // Concatenate the two strings in a required format
        str2 = str2.concat(str1); 

        // Concatenate the result and "AY" 
        str2 = str2.concat("ay"); 

        // Make a sentence with all the words 
        latin = latin.concat(str2 + " "); 
    }

    // Display pig latin verison
    System.out.println("\nPig Latin Version:" +latin ); 
    }
}
\$\endgroup\$
  • 2
    \$\begingroup\$ My comments on your previous question still applies... if you're on Java 7, you can use try-with-resources on your Scanner() object, and if you're on Java 8, you may want to take a look at my suggestion there too. \$\endgroup\$ – h.j.k. Apr 24 '15 at 4:15
8
\$\begingroup\$

Your commenting is absolutely abusive. This one is particularly beautiful... in its own way:

//Close keyboard
keyboard.close();

None of these comments are useful, because:

  • They state the obvious. Let the code speak for itself!
  • They tell the reader what the code is doing, but not why it's doing it.
  • They are a distraction. Reader/maintainer reads the comment, and then the code, and then subconsciously validates whether the comment reflects what the code underneath is saying.

See this beautiful answer specifically about comments - two things to remember:

  • Comments are supposed to make plain what the code does not tell us already.

  • Good code seldom needs comments


The naming is also inconsistent:

StringBuilder str = new StringBuilder(sentence); 

String str = tokens[i]; 

A better name for the former could be builder, and a meaningful name for the latter could be token.

Comments should not replace meaningful names:

// Get first letter from string
String str1 = str.substring(0, 1); 

If str1 were firstLetter...

\$\endgroup\$
7
\$\begingroup\$

Consistency

This may seem trivial, and perhaps it is; but, you are inconsistently using two indentation styles:

public static void main(String[] args) {    
    // Variables
    String sentence, revisedSentence;

And...

private static String separateWords(String sentence) 
{
    // Variables 
    StringBuilder str = new StringBuilder(sentence);

It's best to stick to one style. In your case, the standard for Java is the first example.


Naming

The comments actually work to point out naming issues in the code. Here is what seems like the most apparent example, to me:

// Variables 
StringBuilder str = new StringBuilder(sentence); 
int i = 1; 

 // While loop repeats until the end of the sentence
while (i < str.length())

Good naming would make that comment unneeded:

StringBuilder builder = new StringBuilder(sentence); 
int i = 1; 

while (i < builder.length())
\$\endgroup\$
4
\$\begingroup\$

separateWords()

Loops of this form…

int i = 1;
while (i < str.length())
{
    …
    i++;
}

… would be better written as a for loop.

The comments are inane. If you're going to write any comment at all, write JavaDoc.

/**
 * Transforms "StringsLikeThis" into "Strings like this".
 */
private static String separateWords(String interCaps) 
{
    StringBuilder s = new StringBuilder(interCaps); 
    for (int i = 1; i < s.length(); i++) {
        if (Character.isUpperCase(s.charAt(i))) {
            s.setCharAt(i, Character.toLowerCase(s.charAt(i)));
            s.insert(i++, ' ');
        }
    }
    return s.toString();
}

toPigLatin()

The toPigLatin() function is worse than your separateWords() in two ways:

  • Code reusability: Since toPigLatin() prints its output instead of returning it, you'll never be able to reuse it for anything else. You can't feed its output into another string transformation function, like you did with the output of separateWords(). You won't be able to use it in a program with a graphical or web interface. You won't be able to run unit tests on the function.
  • Efficiency: When you do many string concatenations, use a StringBuilder. There is a lot of redundant copying here due to the use of String concatenation.

The output from this function has an extra space at the beginning and end. I would consider that a bug.

If the sentence contains two consecutive spaces, the function crashes when attempting to take substrings from an empty word.

The one-argument form of String.substring(index) automatically takes everything to the end.

private static String toPigLatin(String sentence) {
    String[] words = sentence.split(" ");
    StringBuilder latin = new StringBuilder(sentence.length() + words.length * "ay".length());
    for (int i = 0; i < words.length; i++) {
        if (i > 0) {
            latin.append(' ');
        }
        String word = words[i];
        if (!word.isEmpty()) {
            char initial = word.charAt(0);
            char remaining = word.substring(1);
            latin.append(remaining).append(initial).append("ay");
        }
    }
    return latin.toString();
}
\$\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.