Computer Science 15-100 (Sections S-V), Fall 2008
Homework 3
Due: Mon 15-Sep-2008 at 11:59pm (email copy) and at Tuesday's
class/recitation
(identical physical copy)
(no late submissions accepted).
Read these instructions first!
public static void testSameChars() { System.out.print("Testing sameChars... "); assert(sameChars("abc", "abc") == true); assert(sameChars("abc", "cba") == true); assert(sameChars("ab", "abc") == false); assert(sameChars("abc", "ab") == false); assert(sameChars("ababab", "ababbbb") == true); assert(sameChars("ababab", "abcabbbb") == false); assert(sameChars("abcabbbb", "ababab") == false); assert(sameChars(null, null) == false); assert(sameChars(null, "abc") == false); assert(sameChars("abc", null) == false); System.out.println("Passed all tests!"); }
Helper Method: sameChars1
In writing the sameChars method, you will see that you have to test whether
all the characters in s1 occur somewhere in s2, and then if all the
characters in s2 occur somewhere in s1. This suggests that we write
the following helper method (which in fact you must write):
Write the following method helper method for your sameChars method:
public static
boolean sameChars1(String s1, String s2)
This method works the
same as sameChars, only in one direction: it only checks whether all
the characters in s1 occur somewhere in s2. That is, this method takes
two strings and returns true if the first string is composed only of letters
occurring in the second string (though perhaps in different numbers and in
different orders) -- that is, if every character that is in the first
string, is in the second -- and false otherwise. This test is
case-sensitive, so "ABC" and "abc" do not contain the same characters. The
method returns false if either string is null, but returns true if both
strings are empty (why?). Here is a test method for you:
public static void testSameChars1() { System.out.print("Testing sameChars1... "); assert(sameChars1("abc", "abc") == true); assert(sameChars1("abc", "cba") == true); assert(sameChars1("ab", "abc") == true); // false for sameChars assert(sameChars1("abc", "ab") == false); assert(sameChars1("ababab", "ababbbb") == true); assert(sameChars1("ababab", "abcabbbb") == true); // false for sameChars assert(sameChars1("abcabbbb", "ababab") == false); assert(sameChars1(null, null) == false); assert(sameChars1(null, "abc") == false); assert(sameChars1("abc", null) == false); System.out.println("Passed all tests!"); }
Another Helper Method: contains
In writing the sameChars1
method, you will need to iterate over every character in s1 and test whether
that character occurs in s2 This suggests that we write the yet
another helper method (which you also must write):
Write the following method helper method for your sameChars method:
public static
boolean contains(String s, char c) {
This method takes a
string and a char and returns true if the given char occurs in the given
String and false otherwise. The method also returns false if the String is
null. Here is a test method for you:
turns true if the first string is composed only of letters occurring in the
second string (though perhaps in different numbers and in different orders)
-- that is, if every character that is in the first string, is in the second
-- and false otherwise. This test is case-sensitive, so "ABC" and
"abc" do not contain the same characters. The method returns false if either
string is null, but returns true if both strings are empty (why?).
Here is a test method for you:
public static void testContains() { System.out.print("Testing contains... "); assert(contains("abcd",'c') == true); assert(contains("abcdabcd",'d') == true); assert(contains("This is a test!",'!') == true); assert(contains("abcd",'e') == false); assert(contains("",'f') == false); assert(contains(null,'g') == false); System.out.println("Passed all tests!"); }
Reminder: You may not use any String methods except charAt() and length()
in this assignment. Using other String methods will result in zero
points for that problem.
Note: When writing sameChars, we decomposed the problem with the
helper method sameChars1. Then, when writing that method, we further
decomposed the problem with the helper method contains. This approach
of problem solving by repeated decomposition is called
top-down design. It
is a very effective way to design well-written and robust programs,
especially when each helper method is carefully tested with its own test
method (which is called unit
testing).
Note:
Top-down design
via decomposition
into helper
methods along with
unit testing
is a great way to design your programs. You are expected to use
this approach in this and all future programming assignments.
public static void testNthTwinPrime() { System.out.print("Testing nthTwinPrime... "); assert(nthTwinPrime(-5) == -1); assert(nthTwinPrime(0) == -1); assert(nthTwinPrime(1) == 3); assert(nthTwinPrime(2) == 5); assert(nthTwinPrime(3) == 11); assert(nthTwinPrime(4) == 17); assert(nthTwinPrime(5) == 29); assert(nthTwinPrime(6) == 41); System.out.println("Passed all tests!"); }
Note: to receive full credit, you must write at least one
well-chosen helper method (and its corresponding test method) for this
method.
public static void testPi() { System.out.print("Testing pi... "); assert(pi(1) == 0); assert(pi(2) == 1); assert(pi(3) == 2); assert(pi(4) == 2); assert(pi(5) == 3); assert(pi(100) == 25); // there are 25 primes in the range [2,100] System.out.println("Passed all tests!"); }
public static void testH() { System.out.print("Testing H... "); assert(almostEqual(h(0),0.0)); assert(almostEqual(h(1),1/1.0 )); // h(1) = 1/1 assert(almostEqual(h(2),1/1.0 + 1/2.0 )); // h(2) = 1/1 + 1/2 assert(almostEqual(h(3),1/1.0 + 1/2.0 + 1/3.0)); // h(3) = 1/1 + 1/2 + 1/3 System.out.println("Passed all tests!"); }
Note: here we use "almostEqual" rather than "==" because this
method returns a double.
public static void testEstimatedPi() { System.out.print("Testing estimatedPi... "); assert(estimatedPi(100) == 27); assert(estimatedPi(200) == 46); assert(estimatedPi(300) == 63); System.out.println("Passed all tests!"); }
public static void testEstimatedPiError() { System.out.print("Testing estimatedPiError... "); assert(estimatedPiError(100) == 2); // pi(100) = 25, estimatedPi(100) = 27 assert(estimatedPiError(200) == 0); // pi(200) = 46, estimatedPi(200) = 46 assert(estimatedPiError(300) == 1); // pi(300) = 62, estimatedPi(300) = 63 assert(estimatedPiError(400) == 1); // pi(400) = 78, estimatedPi(400) = 79 assert(estimatedPiError(500) == 1); // pi(500) = 95, estimatedPi(500) = 94 System.out.println("Passed all tests!"); }
Aside: as you can see, the estimatedPi function is an amazingly accurate estimation of the pi function. For example, the estimatedPi function predicts that there should be 94 prime numbers up to 500, and in fact there are 95 prime numbers in that range. And so we must conclude that there is some kind of very deep relationship between the sum of the reciprocals of the integers (1/1 + 1/2 + ...) and the number of prime numbers. This relationship has been explored in great detail by many mathematicians over the past few hundred years, with some of the most important results in modern mathematics relating to it.
public static void testWordCount() { System.out.print("Testing wordCount... "); // First, create the file "wordCountTest.txt" String filename = "wordCountTest.txt"; PrintStream out = getFilePrintStream(filename); out.println("Roses are red,"); out.println("Violets are blue."); out.println("Some poems rhyme,"); out.println("But not this one."); // now count the words! assert(wordCount(filename) == 13); String nonExistentFilename = "FileThatDoesNotExist.txt"; assert(wordCount(nonExistentFilename) == -1); System.out.println("Passed all tests!"); }
Note: in general, to receive full credit, you must write well-chosen helper methods
where appropriate. It turns out that this method is simple
enough that it does not need a helper method.
Hint: You should use the getFileScanner helper method
from the notes. Also, note that this method returns null if the file
does not exist.
Hint: You will call scanner.next() to get each word, but we
don't really care what the words themselves are, so you will in fact
ingore the result of this call! Just keep calling scanner.next()
until there is no more input.
public static void testCurrentTemperature() { System.out.print("Testing currentTemperature.. "); int temp = currentTemperature(); assert((temp > 0) && (temp < 100)); System.out.println("Passed all tests (if current temp is " + temp + ")!"); }
Hint: Here you should use the getUrlTextScanner
helper method from the notes.
public static void testNumberGuessingGame() { System.out.print("Testing currentTemperature.. "); System.out.println("Manual testing required!"); System.out.println("---------------------------------------"); numberGuessingGame(); System.out.println("---------------------------------------"); System.out.println(" ... Passed all tests (if it looks right!)"); }Note: For user responses to the yes/no questions, you can presume the user types "y" or "n", and you do not have to deal with other cases.
Carpe diem!