Post on 02-Jan-2016
transcript
Introduction to Software Engineering Principles
Introduction to Procedural AbstractionProcedures and Functions
Reminder
• Youse guys (Okay I’m from New Jersey) can control the pace of the lecture!
• How? With questions!
• Always welcome, don’t have to be clever:– “That makes no sense.”– “I have no idea what you’re talking about.”– “Could you repeat the last couple of slides?”
Documenting Algorithms
FICTION: The main audience for an algorithm is a computer.
FACTS: Only 10-20% of $$ cost is writing algorithm. 80-90% is subsequent repair, extension, reuse by people.
TRUTH: Writing algorithms for the human audience is critical and essential.
DOCUMENTATION: refers to brief, explanatory comments that are written into the algorithm for the purpose of making it easy for people to understand.
Documenting Algorithms
• To signify documentation, use double slash marks (//).• Whatever follows is documentation (notes to the reader)• Computer will ignore everything on the line after the //
• Document:– purpose of algorithm and modules– the role of data structures– key decision points– complex calculations– changes in flow of control
• Don’t document the trite & trivial: // Assign the value 4 to a_value a_value <- 4
Self-Documenting Algorithms
• Make the algorithm self-documenting by:• Using descriptive identifiers. Choose variable
names that describe the data they will hold.
If declaring variables to hold values for the radius and area of a circle . . .
Goodradius, area isoftype NumBadx isoftype Num // store radiusy isoftype Num // store area
Literals
Data values that are “hardwired” into the algorithm: algorithm Literals num_one isoftype Num num_one <- 1 your_grade isoftype Char your_grade <- ‘A’ your_score isoftype Num your_score <- 42
print(“each stmt here has a literal”)endalgorithm
CSBuzzword
Alert
Hardwire
• Literally: Physically connecting wires as opposed to using devices such as plugs or quick connectors
• Meaning: To design, build or construct in a way that make change difficult i.e. inflexible, typically poor practice.
• Example: Imagine wiring all electrical appliances directly into house wiring system as opposed to having wall plugs.
LB
Constants
Constants are non-variable values in an algorithm.
A constant allows us to give a name (identifier) to a fixed value, making it easier to read and understand.
PI is 3.1415926 JANUARY is 1 DECEMBER is 12
if (Month = 1) becomes if (Month = JANUARY)
NOTE: You CANNOT print constants and assume you get the text name. E.g. print(JANUARY) will print “1” to screen.
Use Constants to Improve
• Readability– 168– 10560– 8760
HOURS_PER_WEEK
FEET_PER_2_MILES
HOURS_PER_YEAR
• Maintainability
WORKWEEK is 40
WORKWEEK is 35
PI is 3.141592
PI is 3.141592653589793
LB
Complete Algorithm
algorithm Get_Circumference // Constants PI is 3.1415
//Variables radius, circumference, diameter isoftype Num // Get Data print(“Enter the radius”) read(radius)
// Calculate and Show Data diameter <- radius * 2 circumference <- diameter * PI print(“Diameter is: ”, diameter) print(“Circumference is: ”, circumference)endalgorithm
Don’t Do This!
algorithm Get_Circumference // Constants PI is 3.1415 TWO is 2 //Variables radius, circumference, diameter isoftype Num // Get Data print(“Enter the radius”) read(radius)
// Calculate and Show Data diameter <- radius * TWO circumference <- diameter * PI print(“Diameter is: ”, diameter) print(“Circumference is: ”, circumference)endalgorithm
LB
Nor This!
algorithm Get_Circumference // Constants PI is 3.1415 DEUX is 2 //Variables radius, circumference, diameter isoftype Num // Get Data print(“Enter the radius”) read(radius)
// Calculate and Show Data diameter <- radius * DEUX circumference <- diameter * PI print(“Diameter is: ”, diameter) print(“Circumference is: ”, circumference)endalgorithm
LB
Maintaining Algorithms
• Imagine trying to work with (maintain) an algorithm that someone had already written.
• Without some way of logically grouping instructions ...– 100 instructions (lines of code) wouldn’t be too
bad to handle– 1,000 would be difficult– 10,000 would be a nightmare– Millions of instructions would be impossible
LB
Poor Implementation
algorithm Compute_Grade_Bad_Example
// Calculates the course grade based// on the student’s assignments
prog_avg, quiz_avg, lab_avg, exam_score, grade_avg isoftype Num
letter_grade isoftype Char
print(“The purpose of this algorithm”) print(“is to ask the user for grade”) print(“information, calculate the”) print(“numeric grade, and then print”) print(“the letter grade for the given”) print(“input.”)
Poor Implementation
// continuing
print(“Enter your program average:”) read (prog)
print (“Enter your quiz average:”) read (quiz)
print (“Enter your lab average:”) read (lab)
print (“Enter your exam score:”) read (exam)
grade_avg <- Average(prog_avg, quiz_avg, lab_avg, exam_score)
Poor Implementation
// continuing
if (grade_avg >= 90) then letter_grade <- ‘A’ elseif (grade_avg >= 80) then letter_grade <- ‘B’ elseif (grade_avg >= 70) then letter_grade <- ‘C’ elseif (grade_avg >= 60) then letter_grade <- ‘D’ else letter_grade <- ‘F’ endif
print (“Your letter grade is”, letter_grade)
endalgorithm
Modularity
• Most algorithms solve complicated problems.
• We need to break the algorithm into smaller pieces.
• We write sub-algorithms to simplify the algorithm.
• This is not just an “available option,” but the very core of good design.
• Algorithms that don’t feature modularity feature low abstraction, are hard to understand and fix, and are bad.
• This wasn’t always held to be true, thus have had to overcome bad precedents and habits. (Y2K)
LB
A Hierarchy of Abstraction
Each sub-algorithm handles a single logical “chunk” of the solution.
The “main” algorithm coordinates the overriding logic.
It’s abstraction because we’re “considering the essence” (each task) “apart from the embodiment” (it’s component parts).
It’s a hierarchy of abstraction because we’re doing this at multiple levels (task, subtask, the details hidden within the subtask, etc.).
Main
Display Purpose Calc Grade Calc Letter Grade
Advantages of Modularity
• Details of the algorithm are hidden in the sub-algorithms, enhances understanding by hiding obscurant detail
• Makes the algorithm easier to write by helping us manage the complexity (allows multiple people to work together)
• Saves time, space, and effort -- modules can be called from many places within an algorithm
• Permits reuse of logic – modules can be reused across different algorithms as we extend the program language
• Localize errors and help in maintenance of the algorithm
Scope of Data
“Where in the algorithm can something be seen/accessed?”
Global Data – constants and type definitions can be seen by all modules
Local Data – variables are only visible in the module in which they are declared
Main
Task 1 Task 2 Task 3
profit, loss
gross income op_expenses tax_costs
JANUARY is 1
Question
If variables are only “visible” in the module where they are declared...
...How are we going to pass data back and forth between modules?
LB
Parameters
• Because scope is limited, we need some way for modules to communicate with other parts of the algorithm.
A parameter is a specific kind of variable which allows values to be passed between the main algorithm and its modules and among those modules themselves.
• Parameters are the best way to handle inter-module communication regardless of a given language’s scope rules.
• Don’t confuse what a given programming language will LET you do with what you SHOULD do.
Examples of Parameters
read(number1, number2)
print(“Hello World!”)
print(“Sum = ”, number1 + number2)
Relations Between Modules
User
Module
Caller
Read/Print Parameters
FormalParameters
ActualParameters
Three Kinds of Parameters
• The parameter type is defined in relation to which direction data is flowing relative to the server (module):
• Input parameters – pass data into a module from wherever it
was called (client)• Output parameters
– passes data from the module back to the place of call (client)
• Input/Output parameters– communicate both ways
Mass Confusion?
• Input/Output Operations
– read– print
• Parameter Passing
– in– out– in/out
LB
Not the same thing
Two Flavors of Modules
• Each module must be either a function or a procedure
• Functions
1. Resolve to a single value of any type
2. May not change “state of the world”
(no effects on other data, no Input/Output)
3. May only have IN parameters
• Procedures
1. May produce any number of values
2. May change “the state of the world”
(side effects on other variables, Input/Output OK)
3. May have IN, OUT, and IN/OUT parameters
Module Example
Algorithm Calculator
ProcedureDisplay MenuRead Choice
ProcedureQuadratic
ProcedureQuadMath
FunctionSquare
Root
out
None
In
In/Out
LB
Use of Procedures and Functions
A procedure is used as a statementA function is used as an expression
algorithm Do_Stuff
this_Num isoftype Num
that_Num isoftype Num
read(this_Num)
that_Num <- Cube(this_Num)
Do_Fancy_Output(this_Num,that_Num)
this_Num <- that_Num + this_Num
print(this_Num, that_Num)
endalgorithm //Do_Stuff
Client/Server Module Relationship
• The module (server) services a request from the caller (client)
• The server (usually) expects some valid input• The client (usually) expects some valid output• A contract between the two is necessary
• Pre-conditions, post-conditions, and purpose documentation establish this contract
Design by Contract
Example
Calculate_Avg returnsa num (num1, num2, num3)
//Purpose: calculate the sum of input numbers
//Pre-condition: three valid numbers are
// passed in from the client
//Post-condition: the correct numeric average
// is returned to the client
Note: this example module definition is syntactically simplified, but the comments are correct
Why Two Types of Modules?
• We want to be able to describe the intent of the instructions as clearly as possible
• If the module should have no side-effects and resolves to a single value, we want the ability to specify this– Makes clearer the intent– Restricts actions (helps in maintenance)– “Cleaner” solutions
Procedures
• Used for varied tasks
• Take any number of parameters of any kind (IN, OUT, IN/OUT)
• Change the values of output or input/output variables
• Used as an statement unto itself
• Can perform reading & printing
Calling Procedures
algorithm Compute_Grade// Calculates the course grade based// on the student’s assignments
prog_avg, quiz_avg, lab_avg, exam_score, grade_avg isoftype Num
Display_Purpose
Get_Data(prog_avg, quiz_avg, lab_avg, exam_score)
grade_avg <- Average(prog_avg, quiz_avg, lab_avg, exam_score)
Output_Grade(grade_avg)endalgorithm
Procedure Declaration Template
Fill in the name and list any parameters as needed:
procedure <NAME> ( <OPTIONAL PARAMETERS> )
// contract information (purpose, pre- and
// post-conditions
Constants
Variables
Instructions
endprocedure
Declaring Procedures
procedure Display_Purpose// Purpose: Prints the purpose of the algorithm// Pre-condition: none// Post-condition: purpose of alg is displayed
print(“The purpose of this algorithm”) print(“is to ask the user for grade”) print(“information, calculate the”) print(“numeric grade, and then print”) print(“the letter grade for the given”) print(“input.”)
endprocedure // Display_Purpose
Declaring Procedures
procedure Get_Data (prog, quiz, lab, exam isoftype out Num)
// Purpose: Prompts user for data & returns them// Pre-condition: none// Post-condition: passes values back to point of call
print(“Enter your program average:”) read (prog)
print (“Enter your quiz average:”) read (quiz)
print (“Enter your lab average:”) read (lab)
print (“Enter your exam score:”) read (exam)
endprocedure //Get_Data
Declaring Proceduresprocedure Output_Grade (grade_avg isoftype in Num)//Purpose: Prints the letter grade//Pre-condition: Numeric average passed in//Post-condition: correct letter grade printed
letter_grade isoftype Char
if (grade_avg >= 90) then letter_grade <- ‘A’ elseif (grade_avg >= 80) then letter_grade <- ‘B’ elseif (grade_avg >= 70) then letter_grade <- ‘C’ elseif (grade_avg >= 60) then letter_grade <- ‘D’ else letter_grade <- ‘F’ endif
print (“Your letter grade is”, letter_grade)endprocedure //Output_Grade
Functions
• Return a single value (reduces to that value)
• Have any number of input parameters
• NOT have output or input/output parameters
• Be used as an expression(or as part of an expression)
• Not be used as a statement
Calling the Function
algorithm Compute_Grade// Calculates the course grade based// on the student’s assignments
prog_avg, quiz_avg, lab_avg, exam_score, grade_avg isoftype Num
Display_Purpose
Get_Data(prog_avg, quiz_avg, lab_avg, exam_score)
grade_avg <- Average(prog_avg, quiz_avg, lab_avg, exam_score)
Output_Grade(grade_avg)endalgorithm
Function Declaration Template
Fill in the name and list any parameters as needed:
function <NAME> returnsa <TYPE>
( <OPTIONAL IN PARAMETERS> )
// contract information (purpose, pre- and
// post-conditions
Constants
Variables
Instructions
<NAME> returns <VALUE of TYPE>
endfunction
Declaring Functions
function Average returnsa Num (prog, quiz,lab, exam isoftype in Num)
// Purpose: Calculates and returns the average// Pre-condition: valid scores passed in// Post-condition: correct weighted avg returned
PROG_FACTOR is .35 //weight of progs QUIZ_FACTOR is .30 //weight quizzes LAB_FACTOR is .10 //weight of labs EXAM_FACTOR is .25 //weight of final
Average returns (prog * PROG_FACTOR) + (quiz * QUIZ_FACTOR) + (lab * LAB_FACTOR) + (exam * EXAM_FACTOR)
endfunction // Average
Summary of Module Usage
There are two kinds of modules:
Procedures• Can have an effect outside of itself • Used as a statement• May change the state of the world (via I/O)• May change the state of other modules’ data (via output
or input/output params)
Functions• Resolves to a single value• Must have a “returns” statement• Used as an expression• May not change the state of the world or of other
modules’ data• May not call a procedure