CPSC 124 | Introduction to Programming | Spring 2024 |
Subroutines are powerful organizational tools. Part of their power comes from reuse — you can write a subroutine once, and then use it many times (in the same program or in new programs). Even more of their power comes from being able to use subroutines like building blocks to progressively create more complex things. Functions allow the subroutines to compute a value that is then used by the rest of the program, increasing the utility of subroutines even more.
Labs and projects are for practice and learning. While it can be very productive to work on problems with your peers, it is also easy to underestimate how much you yourself understand and can do in such situations — so often something looks easy when someone else does it! With this in mind, you should always make the first attempt on a problem or programming task yourself using only the resources provided for the course (textbook, slides and examples posted on the schedule page, other resources linked on the course webpages). After that point, you are encouraged to come to office hours and/or go to Teaching Fellows. You may not collaboratively write solutions or code, and you may not copy solutions or code written by others, even if you contributed ideas.
You can discuss specific exercises with other students in general terms — such as how you might get started on that problem, or how or when to use various programming constructs, or strategies for debugging — but how to use a particular programming construct to solve a specific problem or debugging a particular program should only be discussed in office hours or with the Teaching Fellows.
For all exercises:
Unless otherwise indicated in the problem, if specific output is shown to indicate what your program should do, be sure your program's output matches what is shown exactly.
Employ good programming style, including choosing descriptive variable names and autoformatting your code. Use blank lines and comments to group and label statements that together perform a distinct task.
Write Javadoc-style comments for the program as a whole and for each subroutine and function. Also identify and check preconditions, throwing an IllegalArgumentException if a precondition is violated.
Include your name and a description of the program in each program.
Utilize incremental development — implement small pieces (such as a subroutine or function) one-by-one, testing after each. One strategy is to start with the subroutines/functions, writing code in main to test each, before then writing the actual main program.
We have now seen enough to understand what the following means:
public static void main ( String[] args ) { }
This is the declaration for a subroutine called main which takes an array of Strings and a parameter and does not return anything.
Write a program called CommandlineArgs which prints the contents of the args array, one element per line.
Then:
Compile and run the program as usual.
java CommandlineArgs
Observe what happens.
Now run the program as follows:
java CommandlineArgs apple bat cat 1 2 3
Observe what happens.
Modify the program so that it prints "no commandline arguments" instead of nothing if there are no commandline arguments (as in the first case of running the program above).
Write a program called DiceStats which computes and displays statistics on the frequency of sums obtained when rolling a pair of dice, as described below.
Your program must contain the following elements:
A subroutine called printHashes which takes an integer as a parameter and prints that many # symbols on a line, ending with a new line.
A subroutine called printHistogram which takes an array of integers and two additional integers (called low and high) as parameters, and, for each slot between low (inclusive) and high (exclusive), prints out the number of the slot followed by a number of hashes determined by the value stored in the array at that slot. For example, if the array contains the seven values 1 8 0 3 2 10 7, low is 1, and high is 5, then printHistogram should produce:
1: ######## 2: 3: ### 4: ##
A function called generateStats which takes the number of sides on a die and the number of times to roll as parameters, rolls a pair of dice with the specified number of sides the specified number of times, and returns an array where slot i of the array contains the number of times the sum i was rolled.
A main program which rolls a pair of 6-sided dice 400 times and prints out a histogram showing how often each sum was rolled.
Make use of the various subroutines and functions where you can — printHistogram should use printHashes to print the hashes for each slot of the array and the main program should use generateStats and printHistogram.
Hint: The task performed by generateStats is very similar to the task performed by the DiceCounter program from class, except that generateStats should be able to work with dice with any number of sides (not just 6) and should return the counts array instead of printing the frequencies.
As a kid, you might have used Pig Latin to be silly or to carry on secret conversations. In Pig Latin, each word is replaced by a transformed word intended to be nonsensical to those who don't know Pig Latin. There are some variations of Pig Latin, but here's the version we will use:
If the word begins with one or more consonants, the consonants are moved from the beginning of the word to the end and "ay" is added. For example: cat = atcay, dog = ogday, scratch = atchscray, computer = omputercay, science = iencescay.
If the word begins with a vowel, "yay" is added at the end. For example: apple = appleyay, orange = orangeyay.
In the unlikely case that a word has no vowels, it is left as-is.
Write a program called PigLatin which repeatedly prompts the user for a word and prints out the Pig Latin version of that word. The program should stop when the user enters "stop". (Do not convert "stop" to Pig Latin.)
Your program must contain the following elements:
A function called isVowel which takes a character (type char) as a parameter and returns true if the character is a vowel and false if it is not. Vowels are the letters a, e, i, o, and u.
A function called findFirstVowel which takes a string as a parameter and returns the position of the first vowel occurring in the string, or -1 if there are no vowels in the string. Counting should start at 0 (like arrays), so the function should return 0 for "apple" and "orange", 1 for "cat" and "dog", 3 for "scratch", and -1 for "xyzzy". The function should go through the characters of the string one at a time and determine if each is a vowel or not. (Do not find some alternative method for locating the position of the first vowel.)
A function called pigifyWord which takes a string representing a single word as a parameter, and returns the Pig Latin version of that string. (Don't print it!)
A main program which repeatedly prompts the user for a word and prints out the Pig Latin version of that word. The program should stop when the user enters "stop". (Do not convert "stop" to Pig Latin.)
Call the various subroutines and functions as appropriate: findFirstVowel should use isVowel to determine if a particular character is a vowel or not, pigifyWord should use findFirstVowel to find the position of the first vowel in the word so you can determine how to pigify it, and main should use pigifyWord to convert each word to Pig Latin.
Hints:
For isVowel, you may want to review section 2.2.3 which talks about how to write char literals.
For findFirstVowel, you may find it useful to review section 2.3.3 in the text to figure out how to extract individual characters from a string.
For pigifyWord, you may find it useful to review section 2.3.3 in the text to find functions to help you extract whole chunks (known as substrings) of a string.
Don't forget to hand in your work when you are done!
As in lab 2 (and all labs), grading will be based on both functionality and style. Style means following the good programming style conventions outlined in lab 2, as well as producing reasonably compact and elegant solutions. "Reasonably compact and elegant" means that your program is not significantly longer or more complex than it needs to be. In particular, you must use loops when loops are appropriate — achieving repetition by copying-and-pasting a bunch of code will not earn credit.