What We Will Cover
Continuations
Homework Questions?
^ top
8.1: Designing With Methods
Objectives
At the end of the lesson the student will be able to:
- Use top down design to create algorithms
- Write methods following the black-box analogy
|
^ top
8.1.1: Top Down Design
- Recall that programming is about solving problems using a computer program
- The first phase of writing a program is the problem solving phase
- The output of the problem solving phase is an algorithm
- A good approach for designing algorithms is to break down the task to be accomplished into a few subtasks
- Then you break down each subtask into smaller subtasks as needed
- Eventually, the tasks are so trivial that they are easy to implement in Java
- This technique is called top down design (also stepwise refinement or divide and conquer)
Using Methods in Top Down Design
- Preserving your top down design in your Java code makes your programs:
- Easier to understand
- Easier to write, test and debug
- Easier to change when needed
- The way to preserve your top down design is to implement the structure in methods
- One advantage of using methods to structure your code is that different people can work on different subtasks
- When producing large programs, this sort of teamwork is important
- Many people can work together to produce a program faster
- However, this technique only works if the work is divided in a structured way
- This design approach provides much of the structure needed to produce large programs
^ top
8.1.2: Designing Methods Using the Black Box Analogy
- A key concept in designing methods is called the black-box analogy
- A black box is something that we know how to use but not how it operates
- An example might be a cell phone or an iPod
- These devices have controls that we know how to operate
- However, we really do not know how they work
Methods as Black Boxes
- A method should be designed like a black box
- The method has a job to do
- For example: find the square root of a number
- As a programmer using the method, you need to know what the method's job is so you can use it
- However, you do not need to know how the method does its job
- This is known as, "treating the method like a black box"
- Calling something a black box is a figure of speech
- It is intended to convey the image of a physical device that we know how to use but not how it operates
- If a method is well designed, then a programmer can use it as if it were a black box
- All a programmer needs to know is that if correct arguments are passed to the method then a correct value will come out of the black box
- Thus, when we call the method
Math.sqrt(9.0), we know we will get 3.0 back
System.out.println(Math.sqrt(9.0));
A programmer should not have to look at a method's code to know what will come back
Method Comment Blocks
^ top
8.1.3: Case Study
- Let's apply top down design and the black box analogy to a case study
Adapted from: C++, An Introduction to Problem Solving and Programming, 5/e, Walter Savitch, Addison Wesley, ISBN 0-321-26865-2, pp.120-127
- Often times the large "economy" size of a product is not always a better buy than the smaller size
- This is often true when buying pizza
- Pizza sizes are given in diameters
- However, the amount of pizza you get is really the area of the pizza
- Which is proportional to the square of the radius
- The problem is: which size of pizza gives the lowest cost per square inch?
- We need to write a program that gives us the price per area of any two pizza sizes
^ top
8.1.4: Problem Analysis
- To better understand the problem we are solving, we ask some questions:
- What output do we want?
- A decision on which size is the best buy
- Based on the cost per square inch for each size of pizza
- What data do we have to work with?
- Diameter of two sizes of pizza
- Cost of the same two sizes of pizza
- What formulas do we need?
- area = πr2
- cost per inch = price / area
- What if the cost per square inch is the same?
- The smaller size will be the better buy
^ top
8.1.5: Algorithm Design
- We use top-down design to break down the overall task into steps or subtasks
- Looking at the tasks, what do you notice?
- Subtask 1: Get the input data for each size of pizza
- Subtask 2: Compute the price per inch for smaller pizza
- Subtask 3: Compute the price per inch for larger pizza
- Subtask 4: Determine which size is the better buy
- Subtask 5: Output the results
- Subtask 1 is straightforward
- Just ask for the input values and store them in variables
- Similarly subtasks 4 and 5 are easy
- To determine the best buy in subtask 4, we just compare the cost/inch of the two pizzas using an
if statement
- Subtask 5 just prints the result
- However, notice subtasks 2 and 3
- Subtasks 2 and 3 are the same task with the only difference being the data used for the calculation
- Both of these tasks take the same type of input and return the same type of result
- Whenever you see a subtask take some values (like numbers) and return a single value, it is easy to make a method out of them
- Whenever two or more subtasks make the same computation, you should make a method out of them
- For our program, we make a method named
calcUnitPrice()
/**
* Calculates the price per square inch of a pizza
*
* @param diameter The diameter of the pizza in inches.
* @param price The price of the pizza in dollars.
* @return The price per square inch of a pizza.
*/
double calcUnitPrice(int diameter, double price);
Notice that our method is designed so that it can be treated as a black box
A programmer knows what values can be sent to the method and what to expect back from the method without needing to see the method code
calcUnitPrice Algorithm Design
- Now we design the algorithm for
calcUnitPrice
- The hard part of the algorithm is determining the area of the pizza
- Once we know the area, then we compute the price per inch using the formula:
price / area
- Since a pizza is roughly a circle, we can use the area formula:
- Thus, our algorithm for
calcUnitPrice is:
- Compute the radius of the pizza
- Compute the area of the pizza using πr2
- Return the value of:
(price / area)
- To get more detail and precision, we convert the algorithm to pseudocode
- Pseudocode is a mixture of Java and ordinary English (or any natural language)
- With pseudocode, you can make your algorithms precise without worrying about the details of Java syntax
- Our pseudocode is:
radius = diameter / 2;
area = π * radius * radius
return (price / area)
With the pseudocode defined, translation to Java is easy
^ top
8.1.6: Coding and Testing
- To start translating our program into Java, we start with our template
1
2
3
4
5
6
7
8
|
import java.util.*;
public class Template {
public static void main(String[] args) {
// Enter code here
}
}
|
- We rename the class and save the file as
Pizza.java
- Then we compile and run it to make certain everything works
- Next we add the code for subtask 1 to our program
- After adding each task, we compile and run the program to make sure every still works
- If we find an error, we correct it before continuing
- Since we have coded these types of tasks before, I leave this subtask for you to do so we can focus on the new material
- In
main(), we implement subtasks 2 and 3 as calls to calcUnitPrice
- We save the results of the method calls in two variables as shown:
unitPriceSmall = calcUnitPrice(diameterSmall, priceSmall);
unitPriceLarge = calcUnitPrice(diameterLarge, priceLarge);
- Next we "stub out" the method and then compile and run the program to make sure every still works
- Stubs are the outline of a method but without the algorithm implemented
- Since the method must return a value, we return a "dummy" value
double calcUnitPrice (int diameter, double price) {
return 1; // dummy value
}
With our subtasks 2 and 3 in place, we go on to implement subtasks 4 and 5
Again, since we have coded these types of tasks before, I leave these subtasks for you to do so we can focus on the new material
After we complete our main() method, we come back and implement the algorithm for calcUnitPrice
Coding calcUnitPrice
- We translate our pseudocode into Java and obtain the following:
static double calcUnitPrice(int diameter, double price) {
const double PI = 3.14159;
double radius, area;
radius = diameter / 2;
area = PI * radius * radius;
return (price / area);
}
What do you notice about the code?
The following statement looks right but is a serious mistake
radius = diameter / 2;
We want the radius to include the fractional part of the size
However, integer division truncates the remainder
How do we fix the problem?
static double calcUnitPrice(int diameter, double price) {
const double PI = 3.14159;
double radius, area;
radius = diameter / 2.0;
area = PI * radius * radius;
return (price / area);
}
Now radius will include fractional parts
radius = diameter / 2.0;
Here is a link to our completed program: Pizza.java
Testing
- Just because a program compiles and runs does not mean that it is correct
- To verify that you program returns the correct answers, you should test it with known values and compare it with known results
- You can get known values and results by using pencil and paper or a calculator
- Once you have checked your program with a few known values, then you can have more confidence that it is correct
^ top
8.1.7: Summary
- Top-down design is a technique for creating algorithms
- The ideas is to break down the tasks into subtasks
- Then you break down each subtask into smaller subtasks as needed
- Eventually, the tasks are so trivial that they are easy to code
- A black box refers to something that we know how to use, but not how it operates
- A programmer who uses a method needs to know what the method does, not how it does it
- You want to write methods so that the method declaration and block comments are all a programmer needs to use the method
- We applied top-down design to the problem of buying the best size of a pizza
- Along the way, we made sure to design our methods as black boxes
Check Yourself
- What is meant by the term top-down design?
- What does it mean to say that a programmer should be able to treat a method as a black box?
- What is the purpose of the comment that accompanies a method declaration?
- What is the purpose of testing code that compiles?
^ top
8.2: Pre-Midterm Q&A
^ top
Wrap Up
^ top
Home
| WebCT
| Announcements
| Schedule
| Expectations
| Course info
Help
| FAQ's
| HowTo's
| Links
Last Updated: October 16 2005 @22:40:04
|