1 Chapter 12 – Type Details and Alternate Coding Mechanisms Primitive Data Types Integer Types Floating-Point Types BigInteger and BigDecimal BigInteger for Cryptography char Type ASCII Table Unicode Standard Type Conversions – Promotions, Type Casting Prefix/Postfix Modes for Increment/Decrement Operators Operator Precedence and Evaluation Order Embedded Assignment Expressions Conditional Operator Expressions Expression Evaluation Practice 2 Chapter 12 – Type Details and Alternate Coding Mechanisms Short-Circuit Evaluation Empty Statement break Statement Within a Loop for Loop Header Details Enumerated Types Comparing Enumerated Type Values An Enumerated Type as a Class Retrieving All the Objects of an Enumerated Type Binary, Hexadecimal, and Octal Numbers Introduction to GridWorld Case Study (Optional) Primitive Data Types In Java, there are two basic categories of values primitive values and objects. For a while now, we've focused on objects. Now let's return to primitive values and cover them in more detail. Primitive values are categorized into these primitive data types: byte, short, int, long float, double char boolean 3 4 Integer Types Type Storage Wrapper Class's MIN_VALUE Wrapper Class's MAX_VALUE byte 8 bits -128 127 short 16 bits -32768 32767 int 32 bits -2 billion 2 billion long 64 bits -9*1018 9*1018 To access a data type's minimum and maximum values, use the MIN_VALUE and MAX_VALUE named constants that come with the data type's wrapper class. For example, here's how to print the maximum int value: System.out.println("Largest int = " + Integer.MAX_VALUE); Integer Types Default integer constant type = int. To explicitly force an integer constant to be a long, use an l or L suffix. This generates a compilation error: long ageOfPlanet = 4_540_000_000; But this, with the L suffix, works just fine: long ageOfPlanet = 4_540_000_000L; 5 Floating-Point Types – float, double Type Storage Precision Wrapper Class's MIN_NORMAL Wrapper Class's MAX_VALUE float 32 bits 6 digits 1.2 * 10-38 3.4*1038 double 64 bits 15 digits 2.2 * 10-308 1.8*10308 Normally, the double type is preferred over the float type because the double type provides more accuracy. For doubles, the number of significant digits is approximately 15. For floats, the number of significant digits is approximately 6. 6 Floating-Point Types – float, double To access a floating-point data type's minimum and maximum values, use the MIN_NORMAL and MAX_VALUE named constants that come with the data type's wrapper class. Note that a floating-point MIN_NORMAL is qualitatively different from an integer MIN_VALUE. Instead of being the largestmagnitude negative value, it's the smallest-magnitude positive value. For floating-point numbers, if you want the largest-magnitude negative value, use the negation operator (-) with the MAX_VALUE named constant. For example, here's how to print the largest-magnitude negative float value: System.out.println( "Largest-magnitude negative float = " + -Float.MAX_VALUE); 7 Floating-Point Types – float, double The default floating-point constant type is double. If you declare a variable to be a float, you must append an f or F suffix to all floating-point constants that go into it, like this: float gpa1 = 3.22f; float gpa2 = 2.75F; float gpa3 = 4.0; compilation error 8 BigInteger and BigDecimal Normally, for applications that use numbers with large magnitude and/or high precision, the long and double data types should be sufficient. However, if you require greater magnitude or higher precision, you can use the BigInteger and BigDecimal classes to store integer and floatingpoint numbers, respectively, with magnitude and precision limited only by the computer's memory. The easiest way to create BigInteger and BigDecimal objects is to call their constructors with string arguments like this: BigInteger num = new BigInteger("12345678"); BigDecimal x = new BigDecimal("12.34567890123456e400"); 9 BigInteger and BigDecimal The BigInteger and BigDecimal classes are defined in the java.util package, so when using those classes, import the java.util package. The BigInteger and BigDecimal classes have many methods and many constructors. Here are the API headings for some of the more common BigInteger methods: BigInteger add(BigInteger val) BigInteger subtract(BigInteger val) BigInteger multiply(BigInteger val) BigInteger divide(BigInteger val) BigInteger mod(BigInteger val) returns quotient returns remainder BigInteger pow(BigInteger val) The BigDecimal class implements all of the methods above except for the mod method. 10 BigInteger for Cryptography Cryptography is the encryption and decryption of a message, so that an intended recipient(s) can read the message, while others cannot read it. The RSA algorithm is a popular cryptography algorithm that relies on the difficulty of factoring large integers. As part of its implementation, it uses large prime numbers and modular division. For an explanation of the RSA algorithm and a relatively simple implementation using BigInteger, see: http://www.thedeveloperspoint.com/implementing-rsa-in-java/ The program on the next slide implements the first part of the RSA algorithm - it generates a modulus value which is used in the RSA algorithm's encryption and decryption process. 11 BigInteger for Cryptography 12 import java.util.*; // for Random import java.math.*; // for BigInteger public class RSAModulusGenerator { public static void main(String[] args) { // The number of bits in p and q should be sufficient to prevent an // attacker from guessing the values of p and q using brute force. int BIT_LENGTH = 512; // p and q are guaranteed to be prime with a probability of at // least 1 - (1 / Math.pow(2, CERTAINTY)). Higher CERTAINTY // values lead to greater security, but slower calculations. int CERTAINTY = 15; BigInteger p, q; // large prime numbers BigInteger n; // modulus value used for encryption and decryption p = new BigInteger(BIT_LENGTH, CERTAINTY, new Random()); q = new BigInteger(BIT_LENGTH, CERTAINTY, new Random()); n = p.multiply(q); System.out.println("p = " + p); System.out.println("q = " + q); System.out.println("n = " + n); } // end main } // end class Test Creates two randomly generated BigInteger values, each with a specified number of bits and with a specified certainty that the value is prime. char Type For most languages (including Java), character values have an underlying numeric value. For example, the letter 'A' has the underlying value of 65. For most languages, the ASCII table specifies the underlying numeric values for characters. What's the point of having an underlying numeric value? So characters can be ordered (e.g., 'A' comes before 'B' because A's 65 is less than B's 66). Character ordering is necessary so characters and strings can be sorted. Using the ASCII table on the next slide, what are the underlying numeric values for: the character 't' the character '3' 13 14 ASCII Table numeric value 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 character null start of heading start of text end of text end of transmission enquiry acknowledge audible bell backspace horizontal tab line feed vertical tab form feed carriage return shift out shift in data link escape device control 1 device control 2 device control 3 device control 4 negative acknowledge synchronous idle end transmission block cancel end of medium substitute escape file separator group separator record separator unit separator numeric value 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 character space ! " # $ % & ' ( ) * + , . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? numeric value 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 character @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ numeric value 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 character ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ delete char Type 15 As expected, you can concatenate a char value to a string using the + operator. Note this example: Code fragment output char first = 'J'; char last = 'D'; System.out.println( "Hello, " + first + last + '!'); Hello, JD! When the JVM sees a string next to a + sign, it converts the operand on the other side of the + sign to a string. char Type 16 Be aware that if you apply the + operator to two chars, the + operator does not perform concatenation; instead, it performs mathematical addition using the characters' underlying ASCII values. Note this example: Code fragment output char first = 'J'; char last = 'D'; System.out.println( first + last + ", What's up?"); 142, What's up? The intended output is: JD, What's up? How can you fix the code? Unicode Standard Problem with the ASCII character set It specifies only 128 characters and there are way more than 128 characters in the world (think of all the foreign alphabets!). The Unicode Standard defines underlying numeric values for a huge set of 65,536 characters. Since the ASCII character set was and is such a popular standard with many programming languages, the Unicode designers (the Unicode Consortium) decided to use the ASCII character set as a subset of the Unicode character set. They inserted the ASCII character set's characters in the first 128 slots of the Unicode character set. That means programmers can find those characters’ numeric values by referring to a simple ASCII table; they don't have to wade through the enormous Unicode character set. 17 Unicode Standard 18 To see all the Unicode characters, go to http://www.unicode.org/charts/. Unfortunately, console output (which is what we use prior to the later GUI chapters) only supports the ASCII portion of the Unicode table, not the non-ASCII portion of the Unicode table. To print non-ASCII characters, you'll need to use GUI output. For more details, read the optional GUI section at the end of the chapter. 19 Primitive Type Conversions Ordering scheme for primitive type conversions: narrower byte wider short int long float double char Conversions are allowed only for numeric types, not booleans. There are two types of type conversion - promotion and type casting. Promotion: A promotion is an implicit conversion. It's when an operand's type is automatically converted without having to use a cast operator. It occurs when there's an attempt to use a narrower type in a place that expects a wider type; i.e., it occurs when you’re going with the flow of the arrows in the above diagram. 20 Promotions For each statement, what happens in terms of promotion? long x = 44; float y = x; double z = 3 + 4.5; int num = 'k' + 2; These are mixed expressions. Mixed expressions contain operands of different data types. With a mixed expression, the narrower operand(s) is promoted to match the type of the wider operand. Promotions Promotions typically occur as part of assignment statements, mixed expressions, and method calls. Here's a method call example. public class MethodPromotion { public static void main(String[] args) { float x = 4.5f; printSquare(x); printSquare(3); } private static void printSquare(double num) { System.out.println(num * num); } } // end class MethodPromotion 21 Type Casting Type casting is an explicit type conversion. It's when an expression's type is converted by using a cast operator. It's legal to use a cast operator to convert any numeric type to any other numeric type; i.e., the conversion can go in either direction in the previous "ordering scheme" diagram. Syntax: (<type>) <expression> For example: double x = 12345.6; int y = (int) x; System.out.println("x = " + x + "\ny = " + y); 22 Type Casting 23 import java.util.*; public class PrintCharFromAscii { public static void main(String[] args) { Scanner stdIn = new Scanner(System.in); int asciiValue; // user entered ASCII value char ch; // the asciiValue's associated character char nextCh; // the character after ch in the ASCII table System.out.print("Enter an integer between 0 and 127: "); asciiValue = stdIn.nextInt(); ch = (char) asciiValue; nextCh = (char) (asciiValue + 1); System.out.println("Entered number: " + asciiValue); System.out.println("Associated character: " + ch); System.out.println("Next character: " + nextCh); } // end main } // end class PrintCharFromAscii 24 Prefix/Postfix Modes for Increment/Decrement Operators There are two different modes for the increment operator – prefix and postfix. Prefix mode: ++x increment x before x's value is used Example: y = ++x; x = x + 1; y = x; Postfix mode: x++ increment x after x's value is used Example: y = x++; y = x; x = x + 1; 25 Prefix/Postfix Modes for Increment/Decrement Operators Trace this code fragment: int x, y; x = 4; y = ++x; System.out.println(x + " " + y); x = 4; y = x++; System.out.println(x + " " + y); x y output Puzzler: What does this code fragment print? int a, b; b = 2; a = b++ + b; b = b++; System.out.println(a + " " + b); After retrieving the variable's value from a postfix operator expression, the JVM immediately updates the variable's value (no waiting for other operations). 26 Prefix/Postfix Modes for Increment/Decrement Operators Decrement operators work the same as increment operators except that subtraction is performed instead of addition. Trace this code fragment: int a, b, c; a = 8; b = --a; c = b-- + 2; System.out.println(a + " " + b + " " + c); a b c output Operator Precedence and Evaluation Order Operator precedence: Operator precedence determines the grouping of operands to operators when an expression is surrounded by two operators. So these are equivalent: z = y + ++y * y z = (y + ((++y) * y))) Evaluation order: The JVM uses operator precedence to identify an expression's binary operations. The JVM then evaluates the expression's binary operations left to right - left expression first, then right expression, then the binary operation's operator is executed. What does the following code print? int y = 3; z = y + ++y * y; System.out.println("z = " + z); 27 Embedded Assignment Expressions Assignment expressions are sometimes embedded inside larger expressions. When that happens, remember that: An assignment expression evaluates to the assigned value. The assignment operator exhibits right-to-left associativity and right-to-left evaluation order (which is an exception to the left-to-right evaluation order rule on the previous slide). Trace this code fragment: int a, b = 8, c = 5; a = b = c; System.out.println(a + " " + b + " " + c); 28 Embedded Assignment Expressions In the interest of compactness, it's fairly common to embed an assignment expression inside a loop condition. For example: import java.util.Scanner; public class AverageScore { public static void main(String[] args) { double score; double count = 0; double totalScore = 0; Scanner stdIn = new Scanner(System.in); System.out.print("Enter a score (or -1 to quit): "); while ((score = stdIn.nextDouble()) != -1) { count++; totalScore += score; System.out.print("Enter a score (or -1 to quit): "); } if (count > 0) { System.out.println("Average score = " + totalScore / count); } } // end main } // end AverageScore class 29 Conditional Operator Expressions Conditional operator expressions implement if else logic using a more compact form. Conditional operator expression syntax: <condition> ? <expression1> : <expression2> Semantics: If the condition is true, then the conditional operator expression evaluates to the value of expression1. If the condition is false, then the conditional operator expression evaluates to the value of expression2. Assume x = 2 and y = 5. What does this expression evaluate to? (x>y) ? x : y 30 Conditional Operator Expressions A conditional operator expression cannot appear on a line by itself because it is not considered to be a statement. Instead, it must be embedded inside of a statement. For example: int score = 58; boolean extraCredit = true; score += (extraCredit ? 2 : 0); System.out.println( "grade = " + ((score>=60) ? "pass" : "fail")); What does the above code fragment print? 31 Conditional Operator Expressions Using the conditional operator and not the Math.abs method, write a one-line code fragment that implements this pseudocode: x absolute value of y 32 Expression Evaluation Practice Evaluate the following expressions: 5 + 6 + "7" + 8 + 9 '5' + '6' + "7" + '8' + '9' 5 + '6' 33 Expression Evaluation Practice Assume: int x = 6, y = 4; double z = 10; Evaluate the following expressions: (z - x / y * 4) / 4 x + y++ 8 + --z z = y = x % 2 34 Expression Evaluation Practice Assume: int x = 5, y = 6; double z = 7.7; Evaluate the following expressions: (int) z - z y = 8.0 ('A' == 65) && ('c' < 'D') ? "yes" : "no" (x <= 10) && (z = 2.2) 35 Short-Circuit Evaluation The following code fragment calculates a basketball player's shooting percentage and prints an associated message. What happens when the code runs with input values of 0 and 0? System.out.print("Number of shots attempted: "); attempted = stdIn.nextInt(); System.out.print("Number of shots made: "); made = stdIn.nextInt(); if ((attempted > 0) && ((double) made / attempted) >= .5) { System.out.printf( "Excellent shooting percentage – %.1f%%\n", 100.0 * made / attempted); } Use %% to print a percent sign. else { System.out.println("Practice your shot more."); } 37 Short-Circuit Evaluation An expression containing && or || is evaluated only until truth or falsity is known. Therefore, For the && operator, short-circuiting takes place when the left operand is false. For the || operator, short-circuiting takes place when the left operand is true. So what's the benefit of short-circuit evaluation? Aside: To print a percent sign (%) in a printf statement, use the %% conversion specifier. Unlike the other conversion specifiers, it is a standalone entity; it doesn’t have an argument that plugs into it. It simply prints the percent character. For example, what does the previous slide's code fragment print if the input is 10 and 6? 38 39 Empty Statement The empty statement is a statement that does nothing. It consists of a semicolon by itself. Use the empty statement in places where the compiler requires a statement, but there is no need to do anything. Example: The for loop below can be used as a "quick and dirty" way to add a delay to your program: <print monster> for (int i=0; i<1_000_000_000; i++) ; <erase monster> Style requirement: Put the empty statement on a line by itself and indent it. Empty Statement Empty statements can sometimes be useful, but they can also lead to cryptic code. Use them only if there's a good reason to do so. Be aware that programmers sometimes accidentally introduce the empty statement into a program. Such statements are usually the source of runtime errors. For example: System.out.print("Do you want to play a game (y/n)? "); while (stdIn.next().equals("y")); { empty statement // The code to play the game goes here ... System.out.print("Play another game (y/n)? "); } 41 break Statement Within a Loop The break statement when used inside a loop: It terminates the immediately enclosing loop and gives control to the next statement after the bottom of the loop. What does the program on the next slide do? Don't fall into the trap of using the break statement too often. Usually, someone reading your program will look only at the loop heading to figure out how the loop terminates. In using a break statement, you force the reader to look inside of the loop for loop termination conditions. And that makes your program harder to understand. Nonetheless, in certain situations, the break statement improves readability rather than hinders it. 42 break Statement Within a Loop public class DayTrader { public static void main(String[] args) { double balance = 1000; // money that's not invested double moneyInvested; // money that is invested double moneyReturned; // money that's earned at end of day int day; // current day, ranges from 1 to 90 for (day=1; day<=90; day++) { if (balance < 1 || balance > 5000) { break; } balance = moneyInvested = balance / 2.0; moneyReturned = moneyInvested * (Math.random() * 2); balance += moneyReturned; } // end for System.out.printf("final balance on day %d: $%4.2f\n", day - 1, balance); } // end main } // end DayTrader 43 Enumerated Types An enumerated type is a programmer-defined type that is used to restrict a variable to holding one of a fixed set of values defined by the programmer. Suppose you are writing a program that needs to keep track of the day of the week. An elegant solution would be to define a Day enumerated type like this: An enumerated type’s values are named constants, so they should use all uppercase. public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY } After Day is defined, you can use it to declare a day variable like this: Day day; Later, you can assign one of the enumerated values to day like this: day = Day.FRIDAY; 45 Grade Management Program import java.util.Scanner; public class GradeManagement { private enum Grade {F, D, C, B, A} public static void main(String[] args) { int numOfCourses = 0; Grade grade; int totalPts = 0; do { grade = GradeManagement.getGrade(); // null entry means quit if (grade != null) { numOfCourses++; For case switch (grade) constants, use { the enumerated case A: totalPts += 4; type's value by itself. break; 46 case B: totalPts += 3; break; case C: totalPts += 2; break; case D: totalPts += 1; } // end switch } // end if } while (grade != null); if (numOfCourses == 0) { System.out.println( "No scores were entered."); } else { System.out.printf( "Overall GPA: %.2f\n", (float) totalPts / numOfCourses); } } // end main Grade Management Program private static Grade getGrade() { Scanner stdIn = new Scanner(System.in); float percentage; // overall percentage for one course Grade grade = null; // the course grade System.out.print( "Enter course overall percentage (-1 to quit): "); percentage = stdIn.nextFloat(); if (percentage >= 90.0) grade = Grade.A; else if (percentage >= 80.0) grade = Grade.B; else if (percentage >= 70.0) grade = Grade.C; else if (percentage >= 60.0) grade = Grade.D; else if (percentage >= 0.0) grade = Grade.F; return grade; } // end getGrade } // end class GradeManagement To access an enumerated type's value, preface it with the enumerated type's name and a dot. 48 Comparing Enumerated Type Values 49 You can test enumerated types for equality using == and != operators, like this: if (grade == Grade.F) { System.out.println( "If this is a required course, you must retake it."); } The computer pays attention to the order in which we list an enumerated type’s values. Values listed earlier are “less than” ones listed later. But we cannot use <, >, <=, or >= directly. First, we must have the enumerated constant call its ordinal method, which returns its position within its enumerated type declaration where 0 is the first position. For example: if (grade.ordinal() < Grade.C.ordinal()) { System.out.println("If this is a prerequisite course for" + " a required course, you must retake it."); } An Enumerated Type as a Class An enumerated type is a class of pre-instantiated constant objects. The definition of an enumerated type can be in a separate file with a .java extension, like any other class, and after compiling, it’s compiled form will be in a file with a .class extension. Steps in defining an enumerated type as a fixed list of objects: 50 Step 1: Provide a list of names for the objects, with each name followed by a list of values in parentheses. Step 2: Provide a list of instance constants that correspond to and will store each object’s parenthetical list of values. Step 3: Provide a private constructor whose parameters correspond to the parenthetical lists of values in step 1, and have that constructor use those values to initialize the instance constants in step 2. Because the constructor is private, it cannot be called from outside the enumerated type definition. So what calls this constructor? The items in Step 1’s list. Each name in step 1’s list and its corresponding parenthetical list of constants is a cryptic constructor call. The name is the name of the created object, and the values in parentheses after that name are the arguments passed to the constructor. Enumeration of Cities /************************************************************* * City.java * Dean & Dean * * Stores location properties of a group of cities and provides * the ability to calculate distances between them. *************************************************************/ public enum City { PARKVILLE (39.2, -94.7), HAVANA (23.1, -82.4), KINGSTON (18.0, -76.8), NASSAU (25.1, -77.3), SAINT_THOMAS (18.3, -64.9); // // // // // USA Cuba Jamaica Bahamas Virgin Islands // location of the city in degrees public final double latitude; public final double longitude; private City(double latitude, double longitude) { this.latitude = latitude; this.longitude = longitude; } 51 Enumeration of Cities // This method returns the distance in km between two cities. public double getDistance(City destination) { final double R = 6371; // approximate mean radius of earth in km double lat1, lon1; // latitude and longitude of origin city double lat2, lon2; // latitude and longitude of destination city double a; // intermediate value used in haversine formula // upcoming trig functions work with radians, not degrees lat1 = Math.toRadians(this.latitude); lon1 = Math.toRadians(this.longitude); lat2 = Math.toRadians(destination.latitude); lon2 = Math.toRadians(destination.longitude); a = Math.pow(Math.sin((lat2 - lat1) / 2), 2) + Math.pow(Math.sin((lon2 - lon1) / 2), 2) * Math.cos(lat1) * Math.cos(lat2); return (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))) * R; } // end getDistance } // end City 52 CityTravel Program /************************************************************* * CityTravel.java * Dean & Dean * * This class prints the distance between two cities. *************************************************************/ public class CityTravel { public static void main(String[] args) { final double KM_TO_MILES = 0.62137; // conversion factor City origin = City.PARKVILLE; City destination = City.KINGSTON; double distance = origin.getDistance(destination); // in km System.out.printf("%s to %s: %.1f km, or %.1f miles\n", origin, destination, distance, distance * KM_TO_MILES); } // end main } // end CityTravel Output: PARKVILLE to KINGSTON: 2922.1 km, or 1815.7 miles 53 54 Retrieving All the Objects of an Enumerated Type You can retrieve all the objects in an enumerated type by calling the enumerated type’s values method. This method call returns an array of the enumerated type’s objects. You can then process each of these objects using a standard loop or a foreach loop, like this: for (City city : City.values()) { System.out.print(city + " "); } Binary, Hexadecimal, and Octal Numbers Since computers are binary and 16 is a simple power of two (16 = 24), it’s common practice to express computer quantities in base 2 or base 16. Base 2 numbers are called binary numbers, and base 16 numbers are called hexadecimal numbers. Sometimes you’ll encounter base 8 numbers, which are called octal numbers. Binary numbers use just the two symbols, 0 and 1. Base 16 numbers use the following sixteen symbols: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f In Java code, if you want the computer to interpret your presentation of an isolated number as something other than decimal, you must prefix your presentation of that number with a special qualifier: For a binary number, use a 0b or 0B prefix. For a hexadecimal number, use a 0x or 0X prefix. 55 Binary, Hexadecimal, and Octal Conversions public class NumberConversions { public static void main(String[] args) { System.out.printf("%x\n", 9786); System.out.printf("%x\n", 0b01010111); System.out.printf("%d\n", 0b01010111); System.out.printf("%o\n", 0b01010111); System.out.println(Integer.toString(9786, 16)); System.out.println(Integer.toString(9786, 8)); System.out.println(Integer.toString(9786, 2)); } // end main } // end NumberConversions class Output: 263a 57 87 127 263a 23072 10011000111010 56 Introduction to GridWorld (Optional) 57 GridWorld is a two-dimensional checkerboard that holds pieces called “actors”. The actors are animated. BugRunner is the driver for an introductory demo. It generates a GUI display with one randomly located rock and one randomly located bug, with the bug pointing up. Clicking a Step button makes the bug move forward. As the bug moves, it deposits flowers in its wake, and as time passes, these flowers darken. Whenever the bug encounters a flower it replaces it with a new flower and continues moving forward. When it encounters an obstacle like a rock or a boundary, instead of moving forward it turns right by 45 degrees. Turning 90 degrees requires two steps. Clicking a Run button makes the bug run forward in repeated steps. You can control how fast the bug runs by adjusting a slow-fast slider. Once you click the Run button a subdued Stop button brightens. Then clicking the Stop button makes the bug stop running. You can move, resize, maximize, minimize, or close the window. Help options describe mouse actions and keyboard shortcuts. Introduction to GridWorld (Optional) This display is produced by executing BugRunner and clicking Step sixteen times. Starting points are random, so different executions give different results. Clicking Run produces automatic stepping at a rate controlled by the slider. Clicking an empty location within the grid displays a list of constructors. Selecting one of those constructors inserts a rock, bug, or flower into that square. Clicking an occupied location displays a list of the methods the actor at that location can call. Selecting one of those methods executes it. 58