Joanna Smith CS 315H 55580 Calvin Lin Prog2 -- Random Writing Section One: The intent of this assignment was to randomly create text that resembled a provided work, based on the probability of each character occurring after a “seed” of characters taken from the original text. My personal goals in this assignment, though, were to develop my knowledge of working with provided files, to learn more of how to use command-line input, and to explore corner cases of a project. I particularly hoped to learn how to think out different possibilities for test cases and account for those. Section Two: My solution design was fairly simple. In the main method, I tested for fault input information. If all of the input information checked out, I called the readText() method to read in the file and store all of the text into a single String object, as well as to randomly choose the initial seed. Then, from the main method, I called the writeText() method to write out the individual characters to the output file. One assumption I made was that class variables were allowed. In my past experience, class variables were always frowned upon. However, to be able to access the seed and text String objects, it seemed like a necessity, and a lesser crime than changing the method signatures in both the RandomWriter class and the TextProcessor interface that that class implements. The algorithm I used was the one suggested in the instruction packet. I chose to create a String object that contained the full text of the source file, and to use nested loops to find each occurrence of the seed in that source, and then store the following character into a dynamic array. I then randomly chose a character from that array, wrote it to the output file, and updated the seed. Section Three: I am fairly disappointed in the quality of my solution. It does work correctly, and I have tested it in many cases. However, it is inefficient in regards to speed. It takes quite a while to execute for large source texts or for large output lengths. However, I have had little experience working with speed efficiency and am not sure how to approach this problem. I am confident in the correctness of my program, however, and in its memory efficiency. Some problems that I encountered were fairly simple. I continued to have a weird bug, where the program would run, find a seed, and output characters, but the sequence would be redundant. The same three or four characters would continuously be written to the output file, but in no particular order. I eventually realized that I had forgotten to clear out the ArrayList I was using to store the possible characters that followed the seed after it completed each round of execution. A second problem I had was that my output would not show up in the output file, as if the characters were not being written at all. Once I realized that I had forgotten to close the output file stream, however, that problem was also fixed. The implementation of my code is fairly simple. In the main method, I first focus on checking the provided input arguments. The first if…else statement checks to be sure that precisely four arguments are provided. If there are any more or less, an error is cast asking for only the four intended arguments and the system exits. If four are provided, though, it enters into a series of try blocks. The first checks to see if k is an integer by calling parseInt(). If an exception is thrown at this point, an error is cast asking for a positive integer value to be entered and the system exits. If k is an integer, however, it then is tested to see if the number is nonnegative. If not, an exception is thrown to be caught in the catch block. If so, then the next try block is entered. This one repeats this same process to test the value of length. The third try block tests to see if the provided source file can be opened. If it cannot, and an exception is thrown, an error is thrown asking for a valid file or one with more characters than the provided k value, and the system exits. If the file can be opened, however, the file is then checked to see if it contains more characters than the value of k. If it does not, an exception is thrown to be caught in the catch block. If it does, then the process continues to the next try block, which tries to open the output file in the same fashion. Both of these try blocks also contain a finally block to close the streams that were opened. The next step in the main method is to create an object of the RandomWriter class. This is so that the nonstatic methods below can be called from the static method main. Within readText(), the file is opened and the class variable text is initialized to null. A temporary String is also created to hold the value returned by readLine() and to serve as the loop control variable as the file is read in. The text variable then adds the value of temp to itself and the loop continues. Once the text is fully read in from the input file, a random seed is chosen from the text using a Random class object to find the beginning index and then by calling substring() from the text variable. Within writeText(), an ArrayList object is created to store String representations of all of the possible characters that follow the seed in the text. The output file is then opened and the c is created to store the character that is to be written out. Then, a set of nested loops are entered. The first loop executes for the number of characters that are to be written, or the value of length. Within that loop is a second loop that executes for the number of characters in the text minus the size of the seed, so that an IndexOutOfBounds Exception will not occur if the seed extends beyond the end of the text. This inner loop checks for every occurrence of the seed within the text. If the seed is found, as determined by comparing a substring taken from the text and the seed itself using the equals method, then the following character is added to the ArrayList of possible characters. Once this loop completes, all possible characters for that seed have been stored into the dynamic array. Then, if the size of that array is greater than zero, namely, if there are possible characters and the seed does not occur at the end of the text, then a random index of the ArrayList is chosen using the Random class, and the character stored at that index is written to the output file. The seed is then updated by appending the character to the end of the seed variable, and deleting the character at the beginning of the seed StringBuffer object. However, if the size of the array is not greater than zero, a new seed is randomly chosen by the same process from the readText() method. Then, the array is cleared and the loop continues for the new seed. Once the outer loop completes, the stream is closed and the program has completed. I tested this solution in many ways. I tried providing excess or invalid input information, such as words where integers should be, or file names that did not exist for the source file. I also provided files that had less characters than k, or less characters than the output length. All but the last caused errors and the system exited. But the latter of the tests still functioned correctly. To test the actual writing of the output, I used many various types of input. I tried the provided files with various k values and output lengths. And I used as much of the text of Anna Karenina as would fit into a text file on Notepad. I also tried several Emily Dickinson poems to explore the effects of using different mediums that didn’t follow normal grammatical conventions. While writing and debugging my code, I created output statements to display the seed values and the characters in the dynamic array, so that I could track the process that the computer was taking. I did this by opening a second file stream and writing these out to that file, so that I could compare this “process file” with the resulting output of the chosen characters. As for code that is not my own, I did not know how to access and use command-line arguments as input. Thus, I looked up information on that, and used some examples I found as a template for checking the validity of the provided arguments in my code. This information, I got from the following site: http://java.sun.com/docs/books/tutorial/essential/environment/cmdLineArgs.html