“I Feel Your Pain”
That which does not kill us makes us stronger.
Friedrich Nietzsche
It Won’t All Be This Bad
Notes
Posting “square” and “square tests” on the
Wiki by 7pm
A “square” is one location in the tutorial on
policyalmanac.org
I will call these “nodes” in today’s lecture
Completion expectations
Demonstrate that you’ve made code and tests
And bottom-up approach
THE PROCESS
“Write Tests First”
OK, is that really what you do first?
“Write Tests First”
OK, is that really what you do first?
Of course not!
Design something to test first!
OK,
so where do I start?
This is a bottom-up process
Constructive or a synthesis method
OK,
so where do I start?
Start with the data
Current Assignment
What data?
A BMP?
What does this data REALLY represent?
It’s actually something
abstract
The source of the data is a BMP but it could
come from a variety of sources
ASCII data is actually quite common for this
PCX – a lossless compression color raster
So what’s wrong with just using
BMP?
So what’s wrong with just using
BMP?
Your design can become inflexible and too
tightly tied to the source data
“tight coupling” will result
That is, your design will depend too much on the
assumptions that the data comes from a BMP
You will use calls to existing libraries when you
should not
So…
Instead of a BMP we have a raster of values
Some are “traversible” and others are not
it implies a graph but it is NOT the graph
It is a source of information about individual nodes
in the graph
We can populate that from a variety of
sources
In this case, we’ve used BMPs
So…a connected graph?
Well, do we really need that?
What we want in the end is a list of nodes that
represents a path
We use the coordinates of them to identify them
and to trace them out
We COULD construct a connected graph with
weighted edges from the data
What is the downside to this approach?
Process
1) Consider the data
What are you going to do with that data?
Process
1) Consider the data
2) Define your operations
Process
Consider the data – build (code) the data
definition
Define your operations - write function/method
specifications in your comments
// this is the TDD process
Repeat:
Write test that verifies an intended outcome
Write code to satisfy the test
Until (all behaviors are defined and tested)
Specifications
We’re talking about comments here
Specifications
//-------------------------------------------------------// IsNodeInList(list, node)
// return true if the node sought is in the list
//-------------------------------------------------------*It might be advantageous to use the nodes’ coordinates as reference
why would I start with this?
Essential
Very simple
Easy to build test data
Can be used to verify subsequent functions
AddNodeToList(list, node)
RemoveNodeFromList(list, node)
Specifications
//--------------------------------------------------------// Hcost( row, column, eRow, eColumn)
// estimate the cost from row, column to
// end row and column (eRow, eColumn)
//--------------------------------------------------------With a very simple calculation this becomes
easily testable
Types of Comments
(worst to best)
Repeat of code
Explanation of code
Marker in code
Summary of code
Description of code’s intent
And then there’s:
“Information that can not possibly be expressed by
the code itself”
Repeat of Code
Tells what the code does in words
Basically useless
“comment pollution”
// assign 100 to a
int a = 100;
Explanation of Code
If code is so complicated or confusing that it
needs explanation then it probably needs
rewriting
total_written=0;
memcpy(tstr,f_rec,8);
i=0;
while ((tstr[i] != 0x20) && (i<8))
i++;
tstr[i]=0;
Explanation of Code
// copy the first 8 chars of the directory entry data
memcpy(tstr,f_rec,8);
// scan the 8 chars above for a space, don’t go over 8
i=0;
while ((tstr[i] != 0x20) && (i<8))
i++;
// terminate with a 0
tstr[i]=0;
Marker in Code
// TODO: make changes here
Summary of Code
Simple summary of code into one or two
sentences
// Function //
read the file indicated by the current dirEntry and rebuild it on the
//
local disk by successively reading and writing clusters that make
//
up the file on the disk being recovered
Description of Code’s Intent
(Most useful)
// extract the root of the filename from the directory entry, terminate with 0 to treat as
// ascii-z string
memcpy(tstr,f_rec,8);
i=0;
// scan to the first blank
while ((tstr[i] != 0x20) && (i<8))
i++;
// insert a 0 to terminate the string
tstr[i]=0;
* still, this should be rewritten
Information that can not…
Copyright notices
Confidentiality
Comment blocks assigned by
instructor
//--------------------------------------------------------------------------------------------// Copyright 2007, eV Interacitve, Inc.
// Modification of this code is not permitted without express written consent of
// Matthew Harmon ***************@ev-interactive.com
//---------------------------------------------------------------------------------------------
Commenting Paragraphs
Write comments at the level of the code’s
intent
Focus on the code itself so that comments
enhance good code
Focus paragraph comments on why rather
than how
Comment the Why, not the How
Example from “recover.c”
if (track >= 1024)
printf("%i WARNING (cylinder) in
%s\n",status,filename);
else
write_count =
write(outFile,io_buff,bytes_2_write);
Comment the Why, not the How
Example from “recover.c”
// this BIOS can not read tracks greater than 1024 without special drivers
// print warning but keep recovering the file anyway
if (track >= LAST_LEGAL_TRACK)
printf("%i WARNING (cylinder) in %s\n",status,filename);
else
write_count = write(outFile,io_buff,bytes_2_write);
*notice the literal or magic number “1024” replaced with
“LAST_LEGAL_TRACK”
Rules of Thumb
Keep comments close to the code they
describe
Document parameters where they’re
declared
Commenting Routines
Say what the routine WON’T do, mention
legal input values
Document global effects
Side effects
Create or destroy anything?
Document source of algorithms
Avoid enormous comment blocks
I like some comments before every routine for
visual delineation at the very least
Good Routine Names
Describe everything the routine does
Avoid meaningless, vague or wishy-washy verbs
Handle, process, output, “deal with”
Don’t differentiate routine names solely by
number – OutputUser1
Make names of routines as long as necessary (ok,
be reasonable)
To Name a function – describe return value
sin(), cos(), atan(), etc
To Name a procedure – strong verb object
BuildNormalVectorTable(normaltable* normals, raster* r)
Design at the Routine Level
Each routine should do ONE thing and do it
well
Results
Higher reliability
Easier debugging
Easier maintainability
Easier to understand
Rules for Routines
Should be impervious or immune to bad input
(?)
Avoid catch-all routines
Avoid HIDDEN functionality
Stick to a standard parameter ordering
Limit the number of parameters
Be mindful of the way data is passed to a
routine
Avoid speculative generality
Solve today’s problem today
Should be impervious or immune
to bad input (?)
This is true when public
Local, helper, private routines may assume no
bad input
Use asserts during development
Avoid catch-all routines
Catch-alls will have characteristics like flags
that indicate operations to be performed
Dispatch to smaller, simpler functions if you
can’t think of a cleaner design
Avoid hidden functionality
Do not modify global data
Do not
Clear memory
Create anything
Destroy anything
Unless that is the purpose of the routine or it is
only for the duration of the routine
Stick to a standard parameter
ordering
Stick to a standard parameter ordering
Example:
Destination first
Source next
Flags last
(any values that modify the destination or source
immediately follow destination or source
Decreasing order of importance
CopyValue(destRaster, row, column, sourceRaster, row, column);
MapValues(destRaster, WATER, SWAMP);
Limit the number of parameters
Limit the number of parameters to about 7
Be mindful of the way data is
passed to a routine
Be mindful of the way data is passed to a
routine
Do not pass large structures or strings to be
modified, pass a reference instead
Avoid speculative generality
Solve today’s problem today
Be general only when you KNOW it will be useful
This is a potential time sink
Length of a Routine
No set rule, except in this class
We set that arbitrarily at 25 lines
One screen of code: 50–150 lines
Length IS correlated with errors
Cost?
Test First
Give an example
Write test case
Write code – just enough to pass the test
Run test
(fail) Repeat (goto “write code”)
(pass) Refactor code or write new test
(how do we decide which to do?)
Writing a test
What should the code do?
How can you tell if it does it?
What does reasonable?
What does UNreasonable input look like?
What about side effects? How do we test for
them?
© Copyright 2026 Paperzz