Skip to content

Homework 3: Loops

This assignment focuses on for loops, strings, and arrays. In addition, you will write and submit your own JUnit tests for grading.

Important

Starter code is not provided for this homework. You will need to create a hw3 folder in your CS159/src/hws folder. All classes must be defined in the hws.hw3 package.

Please review the Grading Criteria at the end of this page before you start programming.

Submission

For each exercise, you will submit two files: Name.java and NameTest.java (where Name is the exercise name). To receive full credit, your tests must pass and cover every line in your code. Javadoc comments are not required for test methods.

Learning Objectives

After completing this homework, you should be able to:

  • Use a for loop to analyze the contents of a string.
  • Manipulate text using methods of the String class.
  • Declare, initialize, and modify one-dimensional arrays.
  • Write JUnit tests that call appropriate assert methods.

This assignment must be completed individually. Your work must comply with the JMU Honor Code. Authorized help is limited to general discussion on Piazza, the lab assistants assigned to CS 159, and the instructor. Copying code from someone else, including the use of generative AI, is prohibited and will be grounds for a reduced or failing grade in the course.

Exercise 3.1 Nifty Spelling

A word is said to be abecedarian (pronounced "A-B-C darian") if the letters in the word appear in alphabetical order. The following examples are six-letter English abecedarian words:

abdest, acknow, acorsy, adempt, adipsy, agnosy, befist, behint, beknow, bijoux, biopsy, cestuy, chintz, deflux, dehors, dehort, deinos, diluvy, dimpsy

Write a method that takes a string and returns a boolean indicating whether the string is an abecedarian word. You may assume that the string will not be empty.

Main Class

Create a class named NiftySpelling that implements the following method:

/**
 * Check if the letters in the given word appear in alphabetical order.
 *
 * @param word the word to check
 * @return true if word is abecedarian
 */
public static boolean abecedarian(String word) {
}

Test Class

Create a class named NiftySpellingTest that includes the following method:

@Test
public void testAbecedarian() {
    assertTrue(NiftySpelling.abecedarian("biopsy"));
    assertFalse(NiftySpelling.abecedarian("nifty"));
}

Since the abecedarian() method returns boolean, use the assertFalse() and assertTrue() methods from JUnit to test your code. Two test cases are provided; add at least four more before submitting to Gradescope.

Exercise 3.2 Scrabble Words

A word is said to be a doubloon if every letter that appears in the word appears exactly twice. Here are some example doubloons found in the English language:

Abba, Anna, appall, appearer, appeases, arraigning, beriberi, bilabial, boob, Caucasus, coco, Dada, deed, Emmett, Hannah, horseshoer, intestines, Isis, mama, Mimi, murmur, noon, Otto, papa, peep, reappear, redder, sees, Shanghaiings, Toto

Write a method that takes a string and checks whether it is a doubloon. To ignore case, invoke the toLowerCase() method before checking.

Hint: One way to solve this problem is to use nested loops: for each letter, count the number of matching letters. If the count is not two, then the word is not a doubloon.

Main Class

Create a class named ScrabbleWords that implements the following method:

/**
 * Check if every letter of the word appears exactly twice. This method
 * ignores case when comparing letters.
 *
 * @param word the word to check
 * @return true if word is a doubloon
 */
public static boolean doubloon(String word) {
}

Warning

Your solution must NOT use arrays or collections. For this exercise, Gradescope will reject submissions containing words like import, new, and [].

Test Class

Create a class named ScrabbleWordsTest that includes the following method:

@Test
public void testDoubloon() {
    assertTrue(ScrabbleWords.doubloon("Hannah"));
    assertFalse(ScrabbleWords.doubloon("Banana"));
}

Since the doubloon() method returns boolean, use the assertFalse() and assertTrue() methods from JUnit to test your code. Two test cases are provided; add at least four more before submitting to Gradescope.

Exercise 3.3 Basic Statistics

When students look at their homework or exam scores, they often want to know how they did compared to the rest of the class. Professors usually release statistics like mean and standard deviation to summarize the range of scores. For this exercise, implement the following two methods in a class named BasicStatistics.

Part A: mean

The mean of a set of numbers is the average value, i.e., the sum of the numbers divided by the count. For example, the mean of {82, 88, 97, 80, 79, 92} is (82 + 88 + 97 + 80 + 79 + 92) / 6.0 = 86.333333. You may assume that numbers will have at least one element.

/**
 * Calculates the mean of an array of numbers.
 *
 * @param numbers array of numbers
 * @return mean of those numbers
 */
public static double mean(double[] numbers) {
}

Part B: stdDev

Standard deviation is a measure of the spread of a set of values around their mean. The higher the standard deviation, the more the values are spread away from the mean. See the Wikipedia article for more details and examples.

Given a set of \(N\) values (\(x_1\) through \(x_n\)) with mean \(\bar{x}\), the standard deviation \(\sigma\) (sigma) is:

\[\sigma = \sqrt{ \frac{1}{N} \sum_{i=1}^{N} (x_i - \bar{x})^2 }\]

In other words, you need a loop that computes the average of the squared differences; this average is called the variance. After the loop, take the square root of the variance to determine the standard deviation.

For example, the standard deviation of {82, 88, 97, 80, 79, 92} is 6.599663. Make sure you understand how to calculate this number by hand before writing any code.

/**
 * Calculates the standard deviation of an array of numbers.
 *
 * @param numbers array of numbers
 * @return standard deviation of those numbers
 */
public static double stdDev(double[] numbers) {
}

Unit Testing

Create a class named BasicStatisticsTest that includes a test method for each method above. Since the above methods return double, use the assertEquals() method from JUnit to test your code. Provide a delta value of 0.001 as the third argument for assertEquals().

Exercise 3.4 Word Count

The GNU/Linux operating system comes with many built-in utilities for getting real work done. For example, imagine you had to analyze thousands of files as part of a forensics investigation. One utility you might use is the wc command, which prints the newline, word, and byte counts for a given file.

For example, if a file contains the text This is the first line.\nThis is the second. then the wc command would print 1 9 43 meaning 1 newline character, 9 words, and 43 bytes. You will implement a similar program, except you will read from a string instead of a file, and you will return the result instead of printing.

Main Class

Create a new class named WordCount that has a single method named analyze() that takes a string parameter and returns an array of three integers. The method should count the number of newlines, words, and characters in the string. The return value is an array of these three counts.

For example, if the string contains the text This is the first line.\nThis is the second. then the analyze() method would return {1, 9, 43} meaning 1 newline character, 9 words, and 43 characters.

For this exercise, a "word" is any sequence of characters separated by whitespace. You can use the Character.isWhitespace() method to test if a character is space, tab, newline, etc.

Unit Testing

Create a class named WordCountTest that includes a testAnalyze() method. The analyze() method returns an array, so you should use the assertArrayEquals() method from JUnit to test your code. Do not use the assertEquals() method, because assertEquals() compares array memory locations, not array contents.

Grading Criteria

Your code will first be graded by Gradescope and then by the professor. The grade you receive from Gradescope is the maximum grade that you can receive on the assignment.

After the due date, the professor may manually review your code. At that time, points may be deducted for inelegant code, inappropriate variable names, bad comments, etc.

Your code must compile with the official tests and pass a Checkstyle audit for you to receive any points. For full credit, your code must pass all JUnit tests that you submit, and your JUnit tests must cover every line in your code.

Gradescope will provide you with hints but might not completely identify the defects in your submission. You are expected to test your own code before submitting.

There is no limit on the number of submissions and no penalty for excessive submissions. Points will be allocated as follows:

Criterion Points Details
Compile 0 pts Success Required
CompileOfficialTests 0 pts Success Required
Style 0 pts Success Required
SelfTests 8 pts Partial Credit Possible
Coverage 12 pts Partial Credit Possible
OfficialTests 80 pts Partial Credit Possible