Data vs. Information Think about the problem, what information is available? ¥ Shark: what do we know about him? where is the shark how hungry is the shark ¥ Fish: where is the fish? How fast is it swimming? Did it swim out of the game area? ¥ Game area: How wide, how tall? Background color? Data vs. Information ¥ World consists of the area, the fish and the shark ¥ Shark Position - consists of the x and y coordinate Life time remaining ¥ Fish Position - consists of the x and y coordinate ... maybe the speed ¥ Game area width and height We also have to draw the shapes. Design the classes for Fish, Shark, OceanWorld. ¥ Design Recipe for Data Definition: -- can it be represented by a primitive type? - select the type -- are there several parts that represent one entity? - a class -- are there several related variants? - a union of classes -- add arrows to connect data definitions ¥ Convert information to examples of data ¥ Interpret data as information Designing the functionality Think of the tasks to do: ¥ Move the shark up and down in response to the arrow keys ¥ Move the fish left as the time goes on ¥ Replace the fish with a new one if it gets out of bounds ¥ Check if the shark ate the fish - if yes, replace the fish with a new one ¥ Starve the shark as the time goes on, check if he is dead (Think of the verbs: move, replace, starve, ate, check ...) (Think of questions: ate the fish? out of bounds? is dead? ...) Designing the program ¥ How do you eat an elephant? - one bite at a time One task --- one function/method ¥ Think systematically about each small task ¥ Make a wish list if the task is too complex Program tasks - somewhat decomposed: ¥ Move the shark up and down in response to the arrow keys ¥ Move the fish left as the time goes on ¥ Is the fish out of bounds? ¥ Replace the fish with a new one ¥ Can the shark eat the fish ¥ Shark eats the fish --> fish dies --> is replaced by a new one ¥ Is the shark dead? ¥ Starve the shark as the time goes on Designing a Method: Step 1 -- Problem analysis ---------------------------------------------- Method to design: -- check if the shark ate the fish What data do we need? -- one Shark and one Fish What class is responsible for this task? -- could be either - choose Shark -- the Fish becomes the method argument What type of result do we produce? -- a boolean value What else do we need to consider? ... well, when can the shark eat the fish? ... -- when they are close enough to each other Designing a Method: Step 2 -- Purpose Statement and a Header ------------------------------------------------------------ In the class Shark : // check if this shark ate the given fish boolean ateFish(Fish fishy){...} Designing a Method: Step 3 -- Examples with Expected Outcomes ------------------------------------------------------------- // check if this shark ate the given fish boolean ateFish(Fish fishy){...} The method produces a boolean result ... we need at least two examples: The shark and the fish far away from each other The shark and the fish are close to each other Fish fish1 = new Fish(new CartPt(200, 100), 5); Fish fish2 = new Fish(new CartPt(25, 100), 5); Shark shark = new Shark(new CartPt(20, 100), 30); shark.ateFist(fish1) ... expect false shark.ateFist(fish2) ... expect true Designing a Method: Step 4 -- Template/Inventory ------------------------------------------------ Make an inventory of what we know about the shark and the fish // check if this shark ate the given fish boolean ateFish(Fish fishy){ ... this.loc ... -- CartPt ... this.life ... -- int ... fishy.loc ... -- CartPt ... fishy.speed ... -- int } The result depends on how close are the this.loc and fishy.loc Remember: one task --- one function/method Design a method boolean distTo(CartPt that) in the class CartPt: ----------------------------------------------------------------- // compute the distance of this point to that boolean distTo(CartPt that) Now the template/inventory becomes: // check if this shark ate the given fish boolean ateFish(Fish fishy){ ... this.loc ... -- CartPt ... this.life ... -- int ... fishy.loc ... -- CartPt ... fishy.speed ... -- int ... this.loc.distTo(fishy.loc) ... -- int } Designing a Method: Step 5 -- Design the body of the method What should we do next? We are now ready to design the body of the method ... one question remains: -- how close does the fish have to be for the shark to eat it? -- we decide it must be within 20 -- of whatever unit we use to measure the distance Here is the complete method - we hope: // check if this shark ate the given fish boolean ateFish(Fish fishy){ return this.loc.distTo(fishy.loc) < 20;} Designing a Method: Step 6 -- Convert examples into tests and run the tests --------------------------------------------------------------------------- What else needs to be done? ... how do we know we are correct? ... does the method work as we expected it to? We already have examples with the expected outcomes! Convert the examples into tests and test the method // check if this shark ate the given fish boolean ateFish(Fish fishy){ return this.loc.distTo(fishy.loc) < 20;} Fish fish1 = new Fish(new CartPt(200, 100), 5); Fish fish2 = new Fish(new CartPt(25, 100), 5); Shark shark = new Shark(new CartPt(20, 100), 30); checkExpect(shark.ateFist(fish1), false); checkExpect(shark.ateFist(fish2), true; ... add more tests if needed