Homework 06


Assignment: Three problems, worth 10, 15, and 25 points, respectively (plus up to 20% extra credit), due on:

Reading: Your CS5 lecture notes and the online readings for week 6.


Problem 1     the Morning Meander!     (10 points)     [topic: using loops and methods]

In this problem, you will create a simple ASCII animation that represents a tired student's trek from the dining hall to either the east or west side of campus. Your program should represent the student by an ASCII character (a visible, printable one!) of your choice. It should also somehow indicate the endpoints of the student's path. The example below uses vertical bars '|' to do this. Before displaying anything however, you should ask the user for the width of the path (the distance from the center to the path's edge).

When run, the program should continually output lines of text displaying the position of the student on the path. Each line should show a random "step" of the student: unmoving or left or right, until she is adjacent to one or the other ends of the path, at which point the program stops. At the end, the program should print out the total number of steps taken during its run.

Example Run: Here is an example run; the student randomly stays still, moves left or moves right. The S character represents the student; the vertical bar | characters represent the end of the path:


How wide would you like your path?   24

    |                        S                        |
    |                        S                        |
    |                       S                         |
    |                        S                        |
    |                       S                         |
    |                        S                        |
    |                        S                        |
    |                       S                         |
    |                        S                        |
    |                         S                       |
    |                         S                       |
    |                        S                        |
    |                       S                         |
    |                        S                        |
    
               < many lines skipped... >               
    
    |  S                                              |
    |   S                                             |
    |    S                                            |
    |    S                                            |
    |    S                                            |
    |    S                                            |
    |   S                                             |
    |  S                                              |
    |   S                                             |
    |  S                                              |
    |  S                                              |
    |   S                                             |   
    |   S                                             |
    |  S                                              |
    |  S                                              |
    |   S                                             |
    |  S                                              |
    | S                                               |
    |S                                                |


The student took 996 steps.

Method to write Yes, it is possible to write this program with no external methods. However, in order to practice using methods, for this problem you should write the following one

public static void printLine(int w, int p)

that prints a single line of the student's wander. The input variable p represents the position of the student; it should always lie within the range[-w,w]. The variable w represents the distance from the center of the path to either edge. The end of the path should be one space past w and -w. When the student hits w or -w, their wandering should stop.

Hint on drawing One way to draw a single line of output is with a for loop, in which i runs from -w to w. Outside this for loop would be the characters that mark either end of the path. Inside the for loop you might want to print one character per loop -- an if statement is a good method for deciding which character to print.

Although this is not required, I also found it helpful to write two other methods:
public static boolean hasEnded(int w, int p)
which returns true when the student's walk has ended (w and p have the same meaning as they had in printLine), and
public static int nextStep(int p)
which returns the new location of the student, after having taken their next random step. Given these three methods, main can be written in a very straightforward and obvious manner.

Extra Credit For extra credit (up to 5 points), improve this simple ASCII animation according to your own tastes. Whenever possible, write the code to be as modular as you can; feel free to redesign printLine's function signature (or other function's signatures, if you use them) when they result easier-to understand code. Also feel free to add more functions! (As my grandmother used to say: Functions and variables are cheap! Use them with abandon if they simplify your code and make it more understandable.) Here's an extra credit modification that students have had a lot of fun with in the past: have there be multiple students, and have them "bounce off" each other or annihilate each other when they step to the same location. As always, creativity is encouraged!

Submission Be sure to submit your CS5App.java file under homework 6, problem 1. If you decide to do the extra credit, simply resubmit again with the extended file (thus the server will maintain both copies).


Problem 2     Throwing Darts at Pi     (15 points)     [topic: using loops and methods]

In this problem you will write a program to compute pi (3.14159...). This problem will revisit the idea of Monte Carlo methods used in the Monte Hall program of HW4, this time using a geometric metaphor.

main method: Your main method should offer the user a choice of two options, for example, as follows:

 
     Welcome to the pi estimator. You may 
        (0) Throw a specific number of darts when estimating pi
        (1) Throw darts to estimate pi to a certain accuracy 
        (9) Quit
    
     Which would you like to try?  

There are two more options available for extra credit -- see the bottom of this assignment for details on them.

Methods to write Yes, it is possible to write this program with no external methods. However, in order to practice using a method that returns a boolean value, for this problem you should write the following method (and use it to help implement choices 0 and 1):

 
public static boolean throwDart()

This method takes no inputs. It "throws a dart" at a 2x2 square by computing a random point (x,y) with -1 <= x < 1 and -1 <= y < 1. This dartHit method should return:

Choice 0 If the user chooses 0, the following is an example of an appropriate interaction (with user input in blue):

      
      Enter an integer number of darts you would like to throw  100000
    
      Total throws:    100000
      Total hits:      78371
      Estimate of PI:  3.13484
    
      < the original menu prints out again >
Thus, for option 0 your program should prompt for an integer number of darts to use. (You may assume this will be a positive integer.) Then, you should "throw" that many darts at a square dart-board spanning from -1 to 1 in both x and y. Use the H.randDouble(low,high) function to generate both x and y. For each dart "thrown," determine whether it landed within the circle of radius 1 centered at the point (0, 0). Your program should count the number of times it hits this circle.

With a dart thrown randomly into the enclosing square, the chances of hitting the circle is pi/4. As a result, you can estimate pi by

 
    4.0 * ( number of hits ) / ( number of darts )

After throwing the desired number of darts, the program should print the total number thrown, the total number of "hits," and the resulting estimate of pi.

Choice 1 If the user chooses number 1 (from the menu in main), the following is approximately (be sure you understand which parts of the following output might be different when you run the code another time!) what your program should do.

 
      Enter a positive tolerance (< 1.0) 0.0000001
    
      Total throws:   34119
      Total hits:     26797

      The resulting estimate of pi is 3.1415926609806855
          The "actual" value of pi is 3.141592653589793
    
      < the main menu would appear again here >

That is, for option 1 your program should prompt for a tolerance within which you want to estimate pi. This will be a double, and you can assume it will be strictly positive and less than 1.

Your program should then "throw darts" in the same way it does for choice 0, determining whether or not each dart hits the circle. Each time, however, the program should compute a new estimate of pi using the formula mentioned above. It should continue until the estimated value of pi is within the user-specified tolerance of the actual value of pi

(for the actual value, use Math.PI).

Interesting aside: What would you do in the more usual circumstance: you're using Monte Carlo to estimate a value whose "truth" you don't know?!? What kinds of things might you try then to determine how many simulations should be used? (Lots of machine learning research involves this question.)

After the program has estimated pi within the desired tolerance, it should print out this estimate, the "true" value of pi (Math.PI), as well as the total number of darts needed and the total number of darts that hit the inner circle. This part is really a test of how much work Monte Carlo estimation requires to achieve a particular level of accuracy.

Think about the logic you'd like to use for Choice 1 on paper before you code it up. You should be able to end up with something fairly simple and obvious.

Other choices Option 9 should quit the program.

If the user types in anything other than a 0 or a 1, the program should remind the user of the possible options and then proceed to the "finishing up" section, below.

Extra Credit For extra credit (of up to 10%), add menu options to estimate ln(x). In particular, add:

 
     (2) Estimate ln(x) using a chosen number of darts 
     (3) Estimate ln(x) to a chosen precision 

Each of these options should work just like the corresponding option for estimating pi, except that the user should be asked to for a value of x for which she would like to estimate ln(x), the natural logarithm of x. You may assume that we will only test x > 1. The same dart-throwing approach should be used, though this one is up to you to design. Keep in mind that ln(x) is by definition the integral from 1 to x of the function f(x) = 1.0/x.

Submission Be sure to submit your CS5App.java file under homework 6, problem 2. If you decide to do the extra credit, you may simply submit the embellished file.


Problem 3 (20 points)     A program that "reads"     (25 points)     [topic: looping, methods, Strings, and chars]

Problem 3 is this homework's Pair Programming problem and should be worked on in groups of two as described at http://www.cs.hmc.edu/cs5/pair_programming.html.

The problem     The Flesch index is a measure of the readability of a particular text. It is often used by textbook publishers and editors to ensure that material is written at a level appropriate for the intended audience. If you're interested in several different numeric measures of readability, there is quite a complete explanation here.

The Flesch index is computed as follows:

Here are some resulting readability scores for a few example publications or styles of writing (cited from Cay Horstmann's book, p. 266). It is, in fact, possible to have a negative readability score:

This problem asks you and your partner to write code to compute the Flesch readability score for text that is read in from a file or the console. To really have fun with this problem, it is important to play with various inputs --- to see how they decompose into syllables, sentences, and words, given the assumptions we outline below. For instance, when does the syllable-counting algorithm that you'll write fail to count syllables in english correctly? Towards this end, I've provided a fair bit of the code that you'd otherwise need to write in order to have a robust environment for poking at the detailed behavior of your syllable-counting algorithm...so that you can focus on the interesting parts!

To complement the code you'll be writing, I'm asking that you and your partner spend some serious effort pouring over the code I've written. (This is often the best way to become a better programmer and problem solver, by looking at others' solutions! In addition, modifying existing code is the most common form of programming, especially if you are in some field outside of CS, where you might want to "borrow someone's system"---a task that often requires tweaking existing code to fit your own needs). To guide you in this process, I'm also asking that you answer a non-trivial number of questions that I've sprinkled (as comments) throughout the code. Areas in the CS5App.java file where I'm expecting an answer can be very easily found: simply search for todo.

As a result of the change in emphasis on this assignment, both of you should read the CS5App.java file very carefully; it is in some ways a more definitive source than this writeup. For instance, at the top of that file, an important part of this assignment is outlined in one of the todos: you and your partner are to identify some inputs that show how the assumptions I outline below are overly simplistic (in AI, it is often easy to build an algorithm that works well on the most common 80 percent; achieving 90 or 95 percent is exponentially harder!). The way I've structured the code, you'll have the scaffolding in place to actually play with various inputs (and see what the algorithms are doing) --- which should be a lot of fun!. To make it as easy as possible to become intimate with this file, I'm also providing a hard-copy to each of you in class along with this writeup.

main method: I've provided a menu in main that allows you to select from certain options:

 Welcome to the text
verbosity calculator! Your options include:

    (0) Calculate number of syllables in word (with work-in-progress printing)
    (1) Calculate verbosity of console input  (with work-in-progress printing)
    (2) Calculate verbosity of console input
    (3) Calculate verbosity of file
    (9) Quit

What option would you like? 

The first two options are for provided to make it easy for you to see what your code is doing. Option 0 --- provided you employ H.pl and/or H.p wisely in numSyllables --- will allow you to troubleshoot potential errors in you're implementation of this assignment's "syllable counting rules." Option 1 serves a similar purpose and provides a window onto what's going on when parsing blocks of text that are larger than a single word. All of these options run in the CS5App.java file you will download (although they don't really do much, aside from parsing input), so you and your partner can start playing with this code right away!

estimate_readability: this method is the main work-horse of the application. It demonstrates how you can get word-by-word input from a file and/or the console, how you can interpret this input as you go (printing out useful messages along the way), and how, at the end, you can use the results of this interpretation to indicate what an input's Flesch measure is. Note also that the main loop that reads in words runs one time per word (not one time per line of text), and that a word is denoted by being separated from other words via whitespace (i.e. tabs, spaces, carriage returns). Currently, aside from reading in all words --- up to a special "stop" word denoted END --- this method doesn't do much.

One of you're jobs is to employ other methods that I've defined and/or asked you to flesh out (the Flesch functionality...hee-hee!) in the "stub" section of this method, so that, for each new word, it can update its tally on:

In order to do this, you should assume that:

If you plan to have this method read input from a file, it should live in your Hw6Pr3 directory. I've provided two for you to play with: fourscore.txt and cow.txt. When a file is used, you'll be asked its name. Be sure to include the entire name (including its extension). If you create your own text files to play with (and you can name these anything you want, although I recommend you use the .txt extension so it is easy to remember what kind of data these files contain), make sure you place an END token at the very end of that file.

Aside: if you happen to enter a file name that doesn't exist, you will see some error messages printed to the console; at this point you can simply enter END and you'll be taken back to the main menu.

numSyllables: I've provided the signature for this function, as well as some bogus "stub" code; fleshing out this body will be the most challenging part of this assignment. As a result, you are required to provide some printing to the console (when the appropriate argument is set; see the code for details). In particular, there should be functionality for printing out when various rules are "activated" (and for what characters in the word that they "fire" on). To be perfectly clear: it is not sufficient to simple write a correctly running method; it must also have the ability to report on what it is doing. This aspect of the exercise (writing code that can provide information for use during debugging) is a very powerful tool, and you will get some experience using this tool in this assignment!

When writing the code that counts syllables in a (punctuation stripped) word, you should assume: