JMU JMU - Department of Computer Science
Help Tools
Lab: Experimenting with Loops


Instructions: Answer the following questions one at a time. After answering each question, check your answer (by clicking on the check-mark icon if it is available) before proceeding to the next question.

Getting Ready: Before going any further, you should:

  1. Depending on your development environment, create either a directory or a project for this lab.
  2. Setup your development environment.
  3. Download the following files:
    to an appropriate directory/folder. (In most browsers/OSs, the easiest way to do this is by right-clicking/control-clicking on each of the links above.)

1. The Basics of Loops: This part of the lab will help you understand the basics of for and while loops, and give you experience with some common mistakes.
  1. Compile and execute DiePrinter.
  2. What was output?


    1
    2
    3
    4
    5
    
    Expand
  3. This output is not correct since a die has six sides, not five. Change the < operator to <=.
  4. Save, compile and execute DiePrinter.
  5. What was output?


    1
    2
    3
    4
    5
    6
    
    Expand
  6. Change spots=spots+1 to ++spots.
  7. Save, compile and execute DiePrinter.
  8. What was output?


    1
    2
    3
    4
    5
    6
    
    Expand
  9. Add the statement
        JMUConsole.printf("After: %d\n", spots);
        

    after the for loop.

  10. Save and compile DiePrinter.
  11. What compile-time error was generated?


    DiePrinter.java:17: cannot find symbol
    symbol  : variable spots
    location: class DiePrinter
           JMUConsole.printf("After: %d\n", spots);
    
    Expand
  12. Why was this error generated?


    The variable spots has block scope. So, it cannot be referred to by name outside of the block.
    Expand
  13. Delete the "offending" statement.
  14. Change the body of the loop to:
              if (spots%2 == 0) JMUConsole.printf("Spots: %d\n", spots);          
        
  15. Save, compile and execute DiePrinter.
  16. What was output?


    2
    4
    6
    
    Expand
  17. Why?


    spots%2 is only 0 when spots is even.
    Expand
  18. Change the body of the loop back to:
              JMUConsole.printf("Spots: %d\n", spots);          
        
  19. Let's try and accomplish the same thing in another way. Change ++spots to:
              spots=spots+2;
        
  20. Save, compile and execute DiePrinter.
  21. What was output?


    1
    3
    5
    
    Expand
  22. This output is obviously wrong. Fix it by changing the initialization statement.
  23. What change did you make?


    I changed int spots=1; to int spots=2;
    Expand
  24. Replace the entire for loop with the following:
           int spots;
           
           spots = 1;
           while (spots <= 6)
           {
              spots = spots + 1;
              JMUConsole.printf("Spots: %d\n", spots);          
           }
        
  25. Save, compile and execute DiePrinter.
  26. What was output?


    2
    3
    4
    5
    6
    7
    
    Expand
  27. This output is obviously wrong. To fix it, replace the body of the loop with the following:
              JMUConsole.printf("Spots: %d\n", spots);          
              spots = spots + 1;
        
  28. Save, compile and execute DiePrinter.
  29. What was output?


    1
    2
    3
    4
    5
    6
    
    Expand
  30. Compile and execute Countdown.
  31. What was output?


    Nothing
    Expand
  32. This application is supposed to count from 10 down to 0. Why didn't it?


    The expression i<=0 evaluates to false when i is 10.
    Expand
  33. Change i<=0 to i>0.
  34. Compile and execute Coundtdown.
  35. What was output?


    10 9 8 7 6 5 4 3 2 1
    Expand
  36. Why isn't 0 part of the output (the way it should be)?


    0>0 evaluates to false, so the body of the loop is not executed.
    Expand
  37. Fix this problem.
  38. What change did you make?


    I changed 0>0 to 0>=0.
    Expand
2. Loops and Conditions: This part of the lab will help you understand the difference between if statements and loops.
  1. Compile OldPersonRadar.
  2. Execute OldPersonRadar and enter 19 for the age.
  3. What was output?


    Nothing
    Expand
  4. To ensure that something is output for young people, add the following else block after the while block:
           else
           {
              JMUConsole.printf("You are not old!\n");          
           }       
        
  5. Compile OldPersonRadar.
  6. What compile-time error was generated?


     OldPersonRadar.java
    OldPersonRadar.java:26: 'else' without 'if'
           else
           ^
    
    Expand
  7. Why?


    while loops cannot have else blocks.
    Expand
  8. Comment-out the else block.
  9. Compile OldPersonRadar.
  10. Execute OldPersonRadar and enter 57 for the age.
  11. What was output?


    You are old!
    

    over and over. It really rubbed it in!

    Expand
  12. Stop the execution of OldPersonRadar. (Note: You can stop a program that is currently executing. In jGRASP click on End near the I/O window. In the command shell type Ctrl-c.)
  13. What caused this infinite loop?


    The expression age > 50 always evaluates to true.
    Expand
  14. Change while to if, and uncomment the else block.
  15. Execute OldPersonRadar and enter 52 for the age.
  16. What was output?


    You are old!
    
    Expand
  17. Execute OldPersonRadar and enter 19 for the age.
  18. What was output?


    You are not old!
    
    Expand
3. Numerical Algorithms: This part of the lab will help you understand how loops can be used to perform numerical calculations.
  1. Read and understand Divider.
  2. Compile Divider.
  3. Execute Divider with the values 10 and 5.
  4. What output was generated?


    Result:      2
    
    Expand
  5. Execute Divider with the values 12 and 5.
  6. What output was generated?


    Result:      3
    
    Expand
  7. This answer is obviously wrong. Change num > 0 to num >= den.
  8. Compile Divider.
  9. Execute Divider with the values 12 and 5, 10 and 5, and 3 and 5.
  10. Were the answers correct?


    Yes.
    Expand
  11. Execute Divider with the values 0 and 0.
  12. What happened?


    An infinite loop.
    Expand
  13. Stop the execution of the program.
  14. What caused the infinite loop?


    num starts at 0 and never changes because den is 0. So, num >= den always evaluates to true.
    Expand
  15. How might you fix this problem?


    I would check the value of den and print an error message if it was 0. For example:
           if (den == 0)
           {
              JMUConsole.printf("The denominator can't be 0\n");
           }
           else
           {
              result = 0;
              while (num >= den)
              {
                 num    = num - den;
                 result = result + 1;          
              }
                  
              JMUConsole.printf("Result     : %d\n", result);          
           }       
    
    Expand
  16. Will this algorithm work when the denominator is negative?


    No
    Expand
4. Loops and Arrays: This part of the lab will help you understand how loops can be used with arrays.
  1. Write a class named BlackAdder that has a main() function that prints command-line argument 0.
  2. What code did you write?


    public class BlackAdder
    {
        public static void main(String[] args)
        {
    	JMUConsole.open();
            JMUConsole.printf("%s\n", args[0]);
            JMUConsole.close();
        }
    }
    
    Expand
  3. Modify the main() function in BlackAdder so that it now prints command-line arguments 0, 1, and 2. Do not use a loop. Just add two statements.
  4. What code did you write?


    public class BlackAdder
    {
        public static void main(String[] args)
        {
    	JMUConsole.open();
            JMUConsole.printf("%s\n", args[0]);
            JMUConsole.printf("%s\n", args[1]);
            JMUConsole.printf("%s\n", args[2]);
    	JMUConsole.close();
        }
    }
    
    Expand
  5. Modify the main() function in BlackAdder so that it now prints command-line arguments 0, 1, and 2 using a for loop.
  6. What code did you write?


    public class BlackAdder
    {
        public static void main(String[] args)
        {
            int length;
    
    	JMUConsole.open();
    	length = 3;
    
            for (int i=0; i<length; i++)
            {
                JMUConsole.printf("%s\n", args[i]);
            }
    	JMUConsole.close();
        }
    }
    
    Expand
  7. Modify the main() function in BlackAdder so that it now prints all of the command-line arguments. (Hint: Use a for loop and the Array.getLength() function.)
  8. What code did you write?


    import java.lang.reflect.Array;
    
    public class BlackAdder
    {
        public static void main(String[] args)
        {
            int length;
    
    	JMUConsole.open();
    	length = Array.getLength(args);
    
            for (int i=0; i<length; i++)
            {
                JMUConsole.printf("%s\n", args[i]);
            }
    	JMUConsole.close();
        }
    }
    
    Expand
  9. Test your code using the command line arguments "10.0" "9." "8.5" "7" "5.5" "9.5" "8.5".
  10. Modify the main() function in BlackAdder so that it now converts all of the command-line arguments to double values (using Double.parseDouble(java.lang.String) java.lang.Double#parseDouble(java.lang.String) ) and prints the results in a field of width 10 with 2 places to the right of the decimal point.
  11. What code did you write?


    import java.lang.reflect.Array;
    
    public class BlackAdder
    {
        public static void main(String[] args)
        {
            double value;
            int    length;
    
    	JMUConsole.open();
    	length = Array.getLength(args);
    
            for (int i=0; i<length; i++)
            {
                value = Double.parseDouble(args[i]);
                JMUConsole.printf("%10.2f\n", value);
            }
    	JMUConsole.close();
        }
    }
    
    Expand
  12. Test your code using the command line arguments "10.0" "9." "8.5" "7" "5.5" "9.5" "8.5".
  13. Modify the main() function in BlackAdder so that it now adds all of the double values and, after printing them all out, prints the total (in the same format as the values). (Hint: Use an accumulator. That is, declare a variable named total outside of the loop and initialize it to 0. Then, inside of the loop, increase total by the double value of the command-line argument using the += operator.)
  14. What code did you write?


    import java.lang.reflect.Array;
    
    public class BlackAdder
    {
        public static void main(String[] args)
        {
            double total, value;
            int    length;
    
    	JMUConsole.open();
    	total  = 0.0;
    	length = Array.getLength(args);
    
            for (int i=0; i<length; i++)
            {
                value = Double.parseDouble(args[i]);
    	    total += value;
                JMUConsole.printf("%10.2f\n", value);
            }
    	JMUConsole.printf("\n");
    	JMUConsole.printf("%10.2f\n", total);
    	JMUConsole.close();	
        }
    }
    
    Expand
  15. Test your code using the command line arguments "10.0" "9." "8.5" "7" "5.5" "9.5" "8.5".
5. Loops for Testing with Arrays: This part of the lab will help you understand how loops can be used to test whether two arrays contain all of the selements.
  1. Review the Test class (that you probably created earlier in the semester).
  2. Add an empty method name forEqualIntArray() that is modeled after forEqualInt but is passed int[] parameters rather than int parameters. What code did you add?


        /**
         * Display an alert if any value in the actual int array
         * is not equal to the corresponding value in the expected array.
         *
         * @param description  A description of the test
         * @param expected     The expected array
         * @param actual       The actual array
         */
        public static void forEqualIntArray(String description, 
                                            int[] expected, int[] actual) {
        }
    
    Expand
  3. Suppose you want to compare the length of the two arrays. What import statement do you need to add to the top of the class?


    import java.lang.reflect.Array;
    
    Expand
  4. Add code to the forEqualIntArray() method that prints an alert (that includes the description if the length of the two arrays is not the same. What code did you add?


            int aLength, eLength;
    
            eLength = Array.getLength(expected);
            aLength = Array.getLength(actual);
            if (eLength != aLength) {
                JMUConsole.printf("%s Expected Length: %d, Actual Length %d\n", 
                                  description, eLength, aLength);
            }
    
    Expand
  5. Review ArrayDriver.java.
  6. Compile and execute ArrayDriver. What happened?


    As expected, an alert was printed indicating that the actual array is not the same size as the expected array.
    Expand
  7. Add code that loops through each element of the array, and calls forEqualInt() to print an alert if they aren't equal. What code did you add?


            for (int i=0; i<eLength; i++) {
                forEqualInt(description, expected[i], actual[i]);
            }
    
    Expand
  8. Why is it a good practice to call forEqualInt() rather than duplicate the code?


    It is easy to make a mistake when duplicating code and Duplicate code is hard to maintain if changes need to be made in the future.
    Expand
  9. Modify the actual array in ArrayDriver so that it contains the elements {1, 1, 2, 3, 4, 8}.
  10. Compile and execute ArrayDriver. What happened?


    As expected, an alert was printed indicating that one of the actual elements was not the expected value.
    Expand
  11. Why is it less than ideal to pass the description to forEqualInt()? In other words, what information was not included in the alert?


    The description is about the arrays, and it would be useful to have information about the index of the element.
    Expand
  12. The String.format(java.lang.String,java.lang.Object...) java.lang.String#format(java.lang.String,java.lang.Object...) method is very similar to the printf() method but, it doesn't print anything Instead, it returns the String that "would be" printed.
  13. How might this be useful in the current context?


    We can use it to create a String that includes the original description and the index of the element.
    Expand
  14. Use the String.format() method to initialize (inside of the loop) a String named detailedDescription (declared outside of the loop) in such a way that it includes the original description and the index of the element. Then, pass detailedDescription rather than description to forEqualInt() What does the method look like now?


        public static void forEqualIntArray(String description, 
                                            int[] expected, int[] actual) {
            int aLength, eLength;
            String detailedDescription;
            
    
            eLength = Array.getLength(expected);
            aLength = Array.getLength(actual);
            if (eLength != aLength) {
                JMUConsole.printf("%s Expected Length: %d, Actual Length %d\n", 
                                  description, eLength, aLength);
            } else {
            
                for (int i=0; i<eLength; i++) {
                    detailedDescription = String.format("%s [%d]", description, i);
                    forEqualInt(detailedDescription, expected[i], actual[i]);
                }
            }
        }
    
    Expand
  15. Compile and execute ArrayDriver. What happened?


    As expected, an alert was printed but the description now includes the index of the "offending" element.
    Expand
  16. Add a similar method named forEqualDoubleArray(). What code did you add? (Hint: Remember the tolerance.)


        public static void forEqualDoubleArray(String description, 
                                               double[] expected, double[] actual,
                                               double tolerance) {
            int aLength, eLength;
            String detailedDescription;
            
    
            eLength = Array.getLength(expected);
            aLength = Array.getLength(actual);
            if (eLength != aLength) {
                JMUConsole.printf("%s Expected Length: %d, Actual Length %d\n", 
                                  description, eLength, aLength);
            } else {
            
                for (int i=0; i<eLength; i++) {
                    detailedDescription = String.format("%s [%d]", description, i);
                    forEqualDouble(detailedDescription, 
                                   expected[i], actual[i], tolerance);
                }
            }
        }
    
    Expand
  17. The forEqualIntArray() and forEqualDoubleArray() methods now contain some duplicate code. Normally, we would write a method to eliminate this duplication. Unfortunately, we can't in this case. Why not?


    Because one method uses a double[] and the other uses a int[].
    Expand

Copyright 2019