Why Is Programming Important?

advertisement
Administration
• Upcoming deadlines
– Milestone 1 code due Monday Feb. 2
– Graphics proposal document: due Friday, Feb. 13
– Milestone 2 on web: due Monday, Feb. 23
Good Coding Style
Continued
5. Many Short Functions
Short functions
–
–
–
–
Easier to re-use
Fix bugs in one place, not many
Make code easier to read: more abstraction
How long should functions be?
• Should have many 5 to 10 line functions
• Should very rarely have a function > 100 lines
Thoughts on This Code?
#include <math.h>
void myFunc (float a[], float b[], int nvals) {
float absAvg1 = 0;
for (int i = 0; i < nvals; i++)
absAvg1 += abs(a[i]);
absAvg1 /= nvals;
float absAvg2 = 0;
for (int i = 0; i < nvals; i++)
absAvg2 += abs(b[i]);
absAvg2 /= nvals;
There is no honour
in copy
and paste coding!
Refactor!
...
}
Better Version?
#include <math.h>
float compAbsAvg (float array[], int nvals) {
float absAvg = 0;
for (int i = 0; i < nvals; i++)
absAvg += abs (array[i]);
return (absAvg / nvals);
}
void myFunc (float a[], float b[], int nvals) {
float absAvg1 = compAbsAvg (a, nvals);
float absAvg2 = compAbsAvg (b, nvals);
...
}
1. Not much shorter, but easier to read
2. Less chance of more code copying  future
code will be shorter
6. Don’t Do Too Much in a Statement / Line
#include <string>
#include “StreetsDatabaseAPI.h”
string name = getIntersectionName(getStreetSegmentEnds(
getIntersectionStreetSegment(id,0)).to);
// Hard to read!
unsigned firstSeg = getIntersectionStreetSegment (myInterId,0);
unsigned destInterId = getStreetSegmentEnds(firstSeg).to;
string destInterName = getIntersectionName (destInterId);
// Show your work  divide into several steps on several lines
// Use good variable names to show what intermediate results
// are.
7. Defensive Coding
A. Use assertions to verify assumptions in your code
void myFunc (int *ptr) {
// Don’t ever call myFunc with a NULL ptr!
if (*ptr == 1) {
…
#include <assert.h>
void myFunc (int *ptr) {
assert (ptr != NULL);
if (*ptr == 1) {
…
•
•
Exits program if ptr is NULL (condition not true)
Better than a comment:
–
Checked at runtime & gives useful error message
> assert failed on line 208 of file myFunc.cpp: ptr != NULL
What If I Need That Last Bit of Speed?
#define NDEBUG
// Just turned off assertion checking
// Make sure this line is in front of
// #include <assert.h>
#include <assert.h>
void myFunc (int *ptr) {
ptr = NULL;
assert (ptr != NULL);
…
•
// Not checked  won’t fire.
Can turn off assertion checking in release build
–
–
–
Avoids any speed overhead
Leave on for debug build for extra checking
And maybe leave on in release too if your program not very
time critical
7. Defensive Coding
B. Set deleted / invalid pointers to NULL
delete (ptr);
ptr = NULL;
// Now we’ll crash if we try to use it  good!
…
ptr->value = 1; // Will seg fault immediately
C. Self-checking code (advanced technique)
program_ok = validate_key_data_structure (my_struct);
Should have used assert or validity checkers!
10
Find the Bug!
const int NUM_WEIGHTS = 20; // 1. Constant variable
#define WEIGHT_ZERO 0
// 2. Pre-processor constant
enum WtReturn {HAS_NEG = -1, HAS_ZERO = 0, ALL_POS = 1};
// 3. make an “enumeration” (list) of int constants
int checkWeights (int weights[NUM_WEIGHTS]) {
for (int i = 0; i < NUM_WEIGHTS; i++) {
if (weights[i] = 0)
return (HAS_ZERO);
if (weights[i] < 0)
return (HAS_NEG);
}
return (ALL_POS);
}
Test program, find a failing case …
• weights = {-1, 2, 3, 4, 5, 6, … 20}
• checkWeights returns ALL_POS
8. Use Compiler Warnings
> g++ -Wall weights.cpp
> weights.cpp: In function ‘int checkWeights(int*)’:
> weights.cpp:11: warning: suggest parentheses around
assignment used as truth value
int checkWeights (int weights[NUM_WEIGHTS]) {
for (int i = 0; i < NUM_WEIGHTS; i++) {
if (weights[i] = 0)
Line 11
return (HAS_ZERO);
if (weights[i] < 0)
return (HAS_NEG);
}
return (ALL_POS);
}
8. No Warnings
Don’t have any warnings in your code
–
–
–
–
Warnings flag potentially problematic code
If you leave some warnings in, hard to see new ones
Fix right away: stay at 0 warnings!
Tell compiler to generate all useful warnings (more
than default)
• Command line: g++ –Wall <…>
• Netbeans:
– File | Project Properties | C++ Compiler | More Warnings
Code Reviews
• If you do one thing for code quality, do code
reviews
• Altera: 4 reviewers read code written by one
team member
– Significant amount: ~400 – 1000 lines
– Write down thoughts
– Then meet to discuss  readable, clear, efficient?
• Google: every commit reviewed and approved
Code Reviews
• This course: you will read another team’s
milestone1 code submission
– Both teams have the same TA
• Write a short (1 page) code review
– Can have an appendix with code examples
– 2% of your final mark
– Does not affect the other team’s grade
•
•
•
•
TA already reviewed their code for style
Same TA will read your code review
Code sent to you week of Feb. 2
Review due Monday, Feb. 9
Intro to Graphics
Graphics APIs
myProg.exe
Low level APIs
Different for different platforms
win32 API
x11 API
PostScript
Graphics APIs
myProg.exe
Solution: another layer
Higher level API
Can target multiple low-level APIs
win32 API
x11 API
PostScript
Graphics APIs
myProg.exe
This course: EasyGL
(simple, cross-platform graphics)
win32 API
x11 API
PostScript
EasyGL Overview
#include “graphics.h”
• In any file where you want to make graphics calls
Need to include 3 files in your project, and some libraries in your build step
• See EasyGL quick start guide and example code/makefile
Background
colour
• First call: set up window
init_graphics (“Some example graphics”, WHITE);
Window title
• Second call: choose your coordinate system
set_visible_world (xleft, ybottom, xright, ytop);
EasyGL Overview
• Set drawing attributes
– setcolor (int color_index); // E.g. BLUE (== 9)
– setcolor (t_color (red, green, blue));
// red, green and blue are 8-bit integers
// e.g. t_color (0, 0, 255) is also blue
– setlinewidth (3);
// 3 pixels wide
– setlinestyle (DASHED);
– sticky: affect all subsequent drawing until changed
• Draw primitives
– drawline (x1, y1, x2, y2);
– fillrect (lower_left_pt, upper_right_pt);
– ...
Issue: Interaction?
myProg.exe
How to pass
this information
to myProg.exe?
Hardware
receives the
input and
X11 knows
there is an
event
User resizes
window
or
User clicks
on a button
This course: EasyGL
(simple, cross-platform graphics)
x11 API
Graphics
drawing:
myProg.exe
calls
functions
Solution: Callbacks
EasyGL checks
the event
queue and calls
the appropriate
callback  now
myProg.exe
can handle it.
Hardware
receives the
input and
X11 inserts
event into
event queue
User resizes
window
or clicks on
a button …
myProg.exe
This course: EasyGL
(simple, cross-platform graphics)
x11 API
myProg.exe
registers
callback
functions for
various
events
Then hands
control to
EasyGL
Download