CSCI 1103 Project 2: Conditions, Loops, Arrays
- Due: 11:59pm Sunday 10/8/2017
- Approximately 5.0% of total grade
- Submit to Canvas
- Projects are individual work: no collaboration with other students is allowed. Seek help from course staff if you get stuck for too long.
CODE DISTRIBUTION: p2-code.zip
CHANGELOG: Empty
1 Introduction
Moving on from straight-line code, conditionals and loops provide the ability to jump around in programs. This opens up the full power of what can be computed but makes programs more difficult to understand. These problems require conditionals, loops, and in some cases a combination of them. Also covered is basic input into an array and looping over its contents to analyze its elements.
2 Download Lab Code and Setup
As in Lab01, download the code pack linked at the top of the page. Unzip this which will create a folder and create your files in that folder.
File | State | Notes |
---|---|---|
TextIO.java | Provided | Allows easy input calls like TextIO.getInt() |
RichterTests.java | Testing | Tests for Problem 1 |
MultTableTests.java | Testing | Tests for Problem 2 |
SymmetricSeqTests.java | Testing | Tests for Problem 3 |
KTests.java | Testing | Test functions, runs all project tests from command line |
junit-1103.jar | Testing | For testing, don't try to edit this one |
Richter.java | Create | Create this file for Problem 1 |
MultTable.java | Create | Create this file for Problem 2 |
SymmetricSeq.java | Create | Create this file for Problem 3 |
3 Problem 1: Richter Scale
The Richter Scale is among the scales used to measure the magnitude of
earthquakes. Below is a table of ranges of magnitudes M
of
earthquakes and brief descriptions of the effects of an event in that
range.
Magnitude (M) | Effects |
---|---|
0.0 ≤ M < 2.0 | Not felt by most people |
2.0 ≤ M < 3.0 | Felt slightly by some people |
3.0 ≤ M < 4.0 | Often felt by people, but very rarely causes damage. |
4.0 ≤ M < 5.0 | Noticeable shaking, felt by most people. None to minimal damage. |
5.0 ≤ M < 6.0 | Felt by everyone. None to slight damage. |
6.0 ≤ M < 7.0 | Damage to a moderate number of buildings, poorly constructed buildings may collapse. |
7.0 ≤ M < 8.0 | Major damage to buildings, structures likely to be destroyed. |
8.0 ≤ M | At or near total destruction - severe damage or collapse to all buildings. |
For reference, the recent 2017 Mexico Earthquake had a magnitude of 7.1 (though this measure is on a slightly different scale). It toppled many buildings and caused widespread damage.
This problem will convert the above table into an easy lookup for users who type in a magnitude and get back a description of the effects.
3.1 Demo
> javac Richter.java > java Richter Enter magnitude of earthquake (ex 5.8): -3.8 -3.8 : Invalid magnitude, must be > 0.0 > java Richter Enter magnitude of earthquake (ex 5.8): 2.345 2.3 : Felt slightly by some people > java Richter Enter magnitude of earthquake (ex 5.8): 6.872 6.9 : Damage to a moderate number of buildings, poorly constructed buildings may collapse. > java Richter Enter magnitude of earthquake (ex 5.8): 7.1 7.1 : Major damage to buildings, structures likely to be destroyed. > java Richter Enter magnitude of earthquake (ex 5.8): 10.1 10.1 : At or near total destruction - severe damage or collapse to all buildings.
3.2 Basic Approach
Create a file Richter.java
.
- Prompt the user to enter a magnitude
- Retrieve this floating point number using
TextIO
- Use a set of
if/else if
conditions to check the magnitude and print out one message from the table above. - Preceding each message, print the magnitude that was entered with 1
digit beyond the decimal place as in
Enter magnitude of earthquake (ex 5.8): 2.374 2.4 : Felt slightly by some people
printf()
is useful for this using a format specifier. - Make sure to check in one condition for magnitudes below 0 which are
invalid and should give a message like
-3.8 : Invalid magnitude, must be > 0.0
3.3 Problem 1 Richter Manual Inspection Criteria (15%) grading
The criteria below will be examined by graders to account for part of your grade.
Wgt | Criteria |
---|---|
2% | Make use of the TextIO class to get input from the user |
3% | Make use of printf() to produce 1 digit beyond the decimal place |
5% | Make use of a series of if/else if conditions to print a single table entry |
5% | Clearly include a case checking for negative magnitudes |
15% | Total weight for these criteria |
4 Problem 2: Multiplication Tables
Most young students learn basic arithmetic initially through memorization: it's hard to do more complex math if one does not know basic combinations like 5 times 3. For this, multiplication tables are among the most common tools though the size of table varies from region to region (10 by 10 is common, but some areas go up to 12 by 12 or larger).
This problem will generate arbitrary sized multiplication tables like the following.
1 2 3 4 5 6 7 8 9 10 +----------------------------------------- 1 | 1 2 3 4 5 6 7 8 9 10 2 | 2 4 6 8 10 12 14 16 18 20 3 | 3 6 9 12 15 18 21 24 27 30 4 | 4 8 12 16 20 24 28 32 36 40 5 | 5 10 15 20 25 30 35 40 45 50 6 | 6 12 18 24 30 36 42 48 54 60 7 | 7 14 21 28 35 42 49 56 63 70 8 | 8 16 24 32 40 48 56 64 72 80 9 | 9 18 27 36 45 54 63 72 81 90 10 | 10 20 30 40 50 60 70 80 90 100
Nested loops will be required to do this where an outer loop produces each row while the inner loop works across each row to generate each table element.
4.1 Demo
> java MultTable Enter max rows and columns: (ex: 4 6) 3 5 1 2 3 4 5 +--------------------- 1 | 1 2 3 4 5 2 | 2 4 6 8 10 3 | 3 6 9 12 15 > java MultTable Enter max rows and columns: (ex: 4 6) 6 2 1 2 +--------- 1 | 1 2 2 | 2 4 3 | 3 6 4 | 4 8 5 | 5 10 6 | 6 12 > java MultTable Enter max rows and columns: (ex: 4 6) 8 9 1 2 3 4 5 6 7 8 9 +------------------------------------- 1 | 1 2 3 4 5 6 7 8 9 2 | 2 4 6 8 10 12 14 16 18 3 | 3 6 9 12 15 18 21 24 27 4 | 4 8 12 16 20 24 28 32 36 5 | 5 10 15 20 25 30 35 40 45 6 | 6 12 18 24 30 36 42 48 54 7 | 7 14 21 28 35 42 49 56 63 8 | 8 16 24 32 40 48 56 64 72 >
4.2 Basic Approach
This problem requires some careful formatting to match the tests so take care to follow the instructions closely and make use of the provided format strings.
Create a file MultTable.java
.
- Prompt a user for 2 integers and read them using
TextIO.java
- Create the header which is the top part of the table like
1 2 3 4 5 6 7 8 9 10 +-----------------------------------------
The header can vary in size so will require a loop.
- The upper left is 6 spaces as in
" "
and should always be printed
- The remainder of the header numbers are printed in a field of
width 3, right justified, and space padded, with one space to the
right. This is done easily with the following
printf()
format string"%3d "
- Remember to loop over the number of columns: 10 columns give 1 to 10, 12 columns gives 1 to 12
- To complete the header, print the horizontal divider line. It
starts with the string
" +-"
and then has 4 dashes for each column as in
"----"
Use a loop over columns to produce the proper number of dashes
- The upper left is 6 spaces as in
- Next set up a nested loop to print the table entries
- The outer loop iterates over the number of rows. Each iteration will complete a row.
- At the beginning of each row, print the row number along with a
vertical bar and space. Use the format specifier
"%3d | "
- Then start the inner loop which iterates over the number of
columns. It should print each table entry which is the row#
multiplied by the column#. Print the table entry with the same
specifier as the table header as in
"%3d "
- At the end of every row make sure to print newlines as in
System.out.printf("\n");
as
printf()
does not print line breaks by default.
4.3 Problem 2 MultTable Manual Inspection Criteria (15%) grading
The criteria below will be examined by graders to account for part of your grade.
Wgt | Criteria |
---|---|
5% | Comments indicate the loops which print the table header |
5% | Comments indicate the loops which print the main table and entries |
5% | Clear style is used in loops which follows a regular pattern of progression over rows/cols |
15% | Total weight for these criteria |
5 Problem 3: Symmetric Sequence
Arrays and loops go hand in hand: arrays store multiple values of the same kind and loops allow one to traverse all the elements of the array in a regular pattern. This problem exercises these two abilities.
A symmetric sequence is a series of numbers which is identical if read either from the beginning to end or from end to beginning. Here are examples of a symmetric sequences and non-symmetric sequences.
SYMMETRIC, length 7 value: 17 22 38 59 38 22 17 index: 0 1 2 3 4 5 6 NOT SYMMETRIC, length 7 value: 17 22 38 59 65 22 17 index: 0 1 2 3 4 5 6 index 2 (38) does not match index 4 (65) SYMMETRIC, length 8 value: 15 25 55 10 10 55 25 15 index: 0 1 2 3 4 5 6 7 NOT SYMMETRIC, length 8 value: 12 25 55 10 12 32 25 15 index: 0 1 2 3 4 5 6 7 index 0 (12) does not match index 7 (15) index 2 (55) does not match index 5 (32) index 3 (10) does not match index 4 (12)
This problem develops a program that reads in a sequence and determines if it is symmetric or not; if not, the detected problems will be printed.
5.1 Demo
> javac SymmetricSeq.java > java SymmetricSeq Enter length of sequence (ex: 7): 4 Enter 4 integers: 1 3 5 9 seq[0] != seq[3] seq[1] != seq[2] NOT Symmetric > java SymmetricSeq Enter length of sequence (ex: 7): 4 Enter 4 integers: 1 3 3 1 Symmetric > java SymmetricSeq Enter length of sequence (ex: 7): 7 Enter 7 integers: 1 4 5 9 5 4 1 Symmetric > java SymmetricSeq Enter length of sequence (ex: 7): 7 Enter 7 integers: 1 4 5 9 9 4 1 seq[2] != seq[4] NOT Symmetric > java SymmetricSeq Enter length of sequence (ex: 7): 7 Enter 7 integers: 2 4 5 9 9 3 1 seq[0] != seq[6] seq[1] != seq[5] seq[2] != seq[4] NOT Symmetric >
5.2 Basic Approach
Create a SymmetricSeq.java
file.
- Prompt the user for the number of sequence elements which will be provided.
- Read this using
TextIO
- Create an array of integers with the given size
- Print a message that the user should type in all the numbers.
- Enter a loop to read ALL the integers into the array. Within the
loop, make
TextIO
calls to get integers from the user but do not print additional prompts for each integer. - Keep in mind that arrays are 0 indexed so for a sequence 7 long, read into elements 0, then 1, then 2, and so on up to index 6. Don't read into index 7 as it is out of bounds.
- Once all integers are in the array, commence with an analysis for symmetry.
- Loop over the array but use variables or indexing to examine related
sequence elements. In a sequence that is 7 long, the indices to
compare are
- 0 to 6
- 1 to 5
- 2 to 4
- 3 does not need to be compared (center element)
- A good strategy is to realize that index 0 is compared to index
array.length-1
, 1 toarray.length-2
, and so forth. - Use an
if
condition to check if the two related elements are equal. If not print a message indicating they are not equal as inseq[1] != seq[5]
Multiple such messages can be printed for a sequence with many problems.
- If any two related elements are found to not be equal, set a boolean indicating that the sequence is not Symmetric. Initially this boolean is true but any discrepancy will change it to false.
- At the end of the loop, use a condition to print
Symmetric
orNOT Symmetric
based on the boolean that is set.
5.3 Problem 3 SymmetricSeq Manual Inspection Criteria (20%) grading
The criteria below will be examined by graders to account for part of your grade.
Wgt | Criteria |
---|---|
5% | Make use of the TextIO class to get input from the user in a loop where needed |
5% | Comments clearly indicate the first phase of reading input from the user |
5% | Comments clearly indicate the second phase of analyzing the sequence for symmetry |
5% | A dynamic array is allocated based on user input; no fixed size arrays are used |
20% | Total weight for these criteria |
6 Automatic Testing (50%) grading
6.1 Running Tests
Run the tests associated with the project and ensure all of them
pass. This can be done in DrJava by pressing the Test
button when
test files are open.
On the command line you can run all tests with the following commands.
On Unix/Mac platforms, use a terminal to run the following commands in the folder where your code exists.
> javac -cp .:junit-1103.jar KTests.java #compile > java -cp .:junit-1103.jar KTests #run tests
On windows, use cmd.exe
and change to the correct directory. Run the
commands below where which use a semicolon (;) rather than a colon (:).
> javac -cp .;junit-1103.jar KTests.java #compile > java -cp .;junit-1103.jar KTests #run tests
Correctly passing all tests will yield output similar to the following.
JUnit version 4.12 .......... Time: 0.024 OK (10 tests)
Failing some tests will yield long messages which hint at where there might be a problem. Failures always end with the number of tests passed/failed as in the following.
FAILURES!!! Tests run: 10, Failures: 5
6.2 Test Grading Policies
Some policies to keep in mind with respect to how automatic tests affect grades.
- Credit on this section is proportional to the number of tests passed.
- If there were 30 total tests for the project…
- Passing 30 / 30 tests gets
30 / 30 * 50 = 50.00
- Passing 15 / 30 tests gets
15 / 30 * 50 = 25.00
- Passing 4 / 30 tests gets
4 / 30 * 50 = 6.67
- A 5% penalty may be deducted from this portion if code does not compile initially but a grader is able to quickly fix the problem.
- Passing no tests because code does not compile or does not work properly gets 0 credit.
7 Zip and Submit
7.1 Submit to Canvas
Once your are confident your code is working, you are ready to submit. Ensure your folder has all of the required files. Create a zip archive of your lab folder and submit it to blackboard.
On Canvas:
- Click on the Assignments section
- Click on the appropriate link for this lab
- Scroll down to "Attach a File"
- Click "Browse My Computer"
- Select you Zip file and press OK
7.2 Late Policies
You may wish to review the policy on late project submission which will cost you late tokens to submit late or credit if you run out of tokens. No projects will be accepted more than 48 hours after the deadline.
http://www-users.cs.umn.edu/~kauffman/1103/syllabus.html#late-projects
8 Optional Problem: Calculate Exponentials
This is an optional problem for enrichment. It is not required but doing it earns only the pride of cracking a tough nut (i.e. no bonus credit).
A common use for computing is to produce numerical estimates which
would otherwise be tedious and error-prone for humans to compute. The
special mathematical constant e
shows up often enough that it has
computing functions specially designated for it: calling
Math.exp(3.0)
will produce e^3.0
. It is possible that the CPU
actually contains a circuit specially designed for this but it is also
possible that the CPU only has instructions to do basic arithmetic
(+,-,*,/
). In that case, an algorithm must be used to compute
e^3.0
which uses only these operators. Implementing such an
algorithm is the subject of this problem.
e^x
has a special identity associated with it which proves very useful
for computational purposes. It is the following:
e^x = 1 + (x / 1!) + (x^2 / 2!) + (x^3 / 3!) + (x^4 / 4!) + ... = 1 + (x / 1) + (x^2 / 2) + (x^3 / 6) + (x^4 / 24) + ...
This is an approximation which adds terms in a specific sequence to
get better and better estimates for e
. The notation 4!
is "4
factorial" which is expands to
4! = 1 * 2 * 3 * 4
Similarly,
6! = 1 * 2 * 3 * 4 * 5 * 6
This suggests the following algorithm to compute e^3.0
which will
add numbers on until we are satisfied with the accuracy.
- Start with an estimate that is just 1.0
- Calculate the next estimate by adding the first
x
term from the sequence. In our casex=3.0
sonewEstimate = curEstimate + (3.0 / 1!) = 1.0 + (3.0 / 1) = 4.0
This changes the estimate by 3.0, a pretty big change.
- The
curEstimate=4.0
, add the nextx
termnewEstimate = curEstimate + (3.0^2 / 2!) = 4.0 + (9.0 / 2) = 8.5
A change of 4.5
- The
curEstimate=8.5
, add the nextx
termnewEstimate = curEstimate + (3.0^3 / 3!) = 8.5 + (27.0 / 6) = 8.5 + 4.5 = 13.0
A change of 4.5
- The
curEstimate=13.0
, add the nextx
termnewEstimate = curEstimate + (3.0^4 / 4!) = 13.0 + (81.0 / 24) = 13.0 + 3.375 = 16.374
A change of 3.375
Subsequently, the changes will gradually diminish until only tiny quantities are added on in additional iterations. At some point, the changes are small enough that a good approximation has been reached. This is often referred to as the tolerance of the approximation: how far off one is willing to tolerate from the true value of interest.
This problem translates the above approach into a numerical loop which
will produce approximations for e^x
.
8.1 Basic Approach
- Prompt the user for their desired power of
e
using the prompt messageEnter positive power of e (ex: 4.567):
- Read the power using
TextIO
- Ensure there is a
tolerance
variable that is set to1e-6
which is valid Java notation for10^-6
of0.000001
. It will be used to check for loop termination. - Establish variables for other important quantities such as
- the current estimate
- the next estimate
- the difference between current and next estimates
- numerator and denominators from the formula
- the iteration count
- Enter a loop which checks whether the change between current and
next estimates is above
tolerance
- Adjust the numerator and denominator variables as per the formula
- Use the new values of numerator and denominator to create the next estimate by adding a term on to the current estimate
- Compute the difference between current and next estimates
- Print a message indicating the current iteration stats. Use
printf()
with the following format string:Iter %2d: e^%.2f = %16.8f (change %.8f)\n
Substitute the iteration count, power, next estimate, and change into this format
- Increase the iteration count and transfer value of the next estimate to the current estimate
- When the loop completes print out the iteration count as in
11 iterations to converge
along with a message with the final estimate for
e
raised to the given power using theprintf()
and the format stringe^%.2f = %16.8f\n
8.2 Demo
> javac EPow.java > java EPow Enter positive power of e (ex: 4.567): 1.0 Iter 1: e^1.00 = 2.00000000 (change 1.00000000) Iter 2: e^1.00 = 2.50000000 (change 0.50000000) Iter 3: e^1.00 = 2.66666667 (change 0.16666667) Iter 4: e^1.00 = 2.70833333 (change 0.04166667) Iter 5: e^1.00 = 2.71666667 (change 0.00833333) Iter 6: e^1.00 = 2.71805556 (change 0.00138889) Iter 7: e^1.00 = 2.71825397 (change 0.00019841) Iter 8: e^1.00 = 2.71827877 (change 0.00002480) Iter 9: e^1.00 = 2.71828153 (change 0.00000276) Iter 10: e^1.00 = 2.71828180 (change 0.00000028) 11 iterations to converge e^1.00 = 2.71828180 > java EPow Enter positive power of e (ex: 4.567): 3 Iter 1: e^3.00 = 4.00000000 (change 3.00000000) Iter 2: e^3.00 = 8.50000000 (change 4.50000000) Iter 3: e^3.00 = 13.00000000 (change 4.50000000) Iter 4: e^3.00 = 16.37500000 (change 3.37500000) Iter 5: e^3.00 = 18.40000000 (change 2.02500000) Iter 6: e^3.00 = 19.41250000 (change 1.01250000) Iter 7: e^3.00 = 19.84642857 (change 0.43392857) Iter 8: e^3.00 = 20.00915179 (change 0.16272321) Iter 9: e^3.00 = 20.06339286 (change 0.05424107) Iter 10: e^3.00 = 20.07966518 (change 0.01627232) Iter 11: e^3.00 = 20.08410308 (change 0.00443791) Iter 12: e^3.00 = 20.08521256 (change 0.00110948) Iter 13: e^3.00 = 20.08546859 (change 0.00025603) Iter 14: e^3.00 = 20.08552346 (change 0.00005486) Iter 15: e^3.00 = 20.08553443 (change 0.00001097) Iter 16: e^3.00 = 20.08553649 (change 0.00000206) Iter 17: e^3.00 = 20.08553685 (change 0.00000036) 18 iterations to converge e^3.00 = 20.08553685 > java EPow Enter positive power of e (ex: 4.567): 0.3 Iter 1: e^0.30 = 1.30000000 (change 0.30000000) Iter 2: e^0.30 = 1.34500000 (change 0.04500000) Iter 3: e^0.30 = 1.34950000 (change 0.00450000) Iter 4: e^0.30 = 1.34983750 (change 0.00033750) Iter 5: e^0.30 = 1.34985775 (change 0.00002025) Iter 6: e^0.30 = 1.34985876 (change 0.00000101) Iter 7: e^0.30 = 1.34985881 (change 0.00000004) 8 iterations to converge e^0.30 = 1.34985881 > java EPow Enter positive power of e (ex: 4.567): 4.67 Iter 1: e^4.67 = 5.67000000 (change 4.67000000) Iter 2: e^4.67 = 16.57445000 (change 10.90445000) Iter 3: e^4.67 = 33.54904383 (change 16.97459383) Iter 4: e^4.67 = 53.36688213 (change 19.81783830) Iter 5: e^4.67 = 71.87674311 (change 18.50986097) Iter 6: e^4.67 = 86.28358490 (change 14.40684179) Iter 7: e^4.67 = 95.89500649 (change 9.61142159) Iter 8: e^4.67 = 101.50567385 (change 5.61066736) Iter 9: e^4.67 = 104.41698680 (change 2.91131295) Iter 10: e^4.67 = 105.77656994 (change 1.35958315) Iter 11: e^4.67 = 106.35377479 (change 0.57720485) Iter 12: e^4.67 = 106.57840368 (change 0.22462889) Iter 13: e^4.67 = 106.65909728 (change 0.08069361) Iter 14: e^4.67 = 106.68601437 (change 0.02691708) Iter 15: e^4.67 = 106.69439455 (change 0.00838018) Iter 16: e^4.67 = 106.69684052 (change 0.00244597) Iter 17: e^4.67 = 106.69751244 (change 0.00067192) Iter 18: e^4.67 = 106.69768676 (change 0.00017433) Iter 19: e^4.67 = 106.69772961 (change 0.00004285) Iter 20: e^4.67 = 106.69773962 (change 0.00001000) Iter 21: e^4.67 = 106.69774184 (change 0.00000222) Iter 22: e^4.67 = 106.69774231 (change 0.00000047) 23 iterations to converge e^4.67 = 106.69774231 >