Thank you for the proposals!
Staff will give it a first pass.
Dr. Rudolph Pienaar
Fetal Neonatal Neuroimaging and Developmental Science Center
3/1 at 12pm
Mike Chabot
Wednesday 3/2
Frontend, Backend, DevOps
Can we code it now?
Probably not.
We will grade and then schedule meetings!
2/5
2/19
2/26
3/25
5/20
Team Selection
Client Presentations
Project Proposal
Revised Project Proposal
Final Project Documentation
No class
No class
No class
Project Presentations
5/02
No class
Implementation / Testing / Deployment
82 Days
Today!
Divide and Conquer
Problem
Sub-Problem
Sub-Problem
Sub-Problem
Solved
Sub-Problem
Solved
Solution
Divide
Divide
Conquer
Conquer
It's a lifestyle!
Modularity
Split things up...
Subsystem
Module
vs.
independent value
can not function on its own
Information Hiding
treat stuff as black boxes!
Information Hiding
class MathEngine:
def __init__(self):
'''
A constructor.
'''
print('Really new Math Engine instance.')
def add(self, number1, number2):
'''
Takes 2 integers, and adds them.
'''
return number1 + number2
....
controller = MathEngine()
result = controller.add(int(number1), int(number2))
....
Package structure
Controller is separate! (All calculations, logic, algorithms etc.)
View is separate! (All user interactions)
Everything is bundled as one package!
We can import the package and use it!
This was the VC (View and Controller) part of the MVC pattern!
Why structure the code like this?
Architecture is more important than features!
Remember this!
Use Case Diagram
Activity Diagram
Properties
Methods
Class Diagram
Sequence Diagram
What about the code?
"I like my code to be elegant and efficient.
The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations.
Clean code does one thing well."
Dr. Bjarne Stroustrup
Inventor of C++
"I like my code to be elegant and efficient.
The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations.
Clean code does one thing well."
Dr. Bjarne Stroustrup
Inventor of C++
Meaningful Names
Names are everywhere in code!
int d;
// elapsed time in days
int elapsedTimeInDays;
Chapter 2
float doSomething(float param1, float param2) {
return param1+param2;
}
float add(float number1, float number2) {
return number1+number2;
}
Small Functions
1st Rule: Functions should be small
public static String testableHtml(
PageData pageData,
boolean includeSuiteSetup
) throws Exception {
WikiPage wikiPage = pageData.getWikiPage();
StringBuffer buffer = new StringBuffer();
if (pageData.hasAttribute("Test")) {
if (includeSuiteSetup) {
WikiPage suiteSetup =
PageCrawlerImpl.getInheritedPage(
SuiteResponder.SUITE_SETUP_NAME, wikiPage
);
if (suiteSetup != null) {
WikiPagePath pagePath =
suiteSetup.getPageCrawler().getFullPath(suiteSetup);
String pagePathName = PathParser.render(pagePath);
buffer.append("!include -setup .")
.append(pagePathName)
.append("\n");
}
}
WikiPage setup =
PageCrawlerImpl.getInheritedPage("SetUp", wikiPage);
if (setup != null) {
WikiPagePath setupPath =
wikiPage.getPageCrawler().getFullPath(setup);
String setupPathName = PathParser.render(setupPath);
buffer.append("!include -setup .")
.append(setupPathName)
.append("\n");
}
}
// ...
}
Chapter 3
2nd Rule: They should be smaller than that!
public static String renderPageWithSetupsAndTeardowns(
PageData pageData, boolean isSuite
) throws Exception {
boolean isTestPage = pageData.hasAttribute("Test");
if (isTestPage) {
WikiPage testPage = pageData.getWikiPage();
StringBuffer newPageContent = new StringBuffer();
includeSetupPages(testPage, newPageContent, isSuite);
newPageContent.append(pageData.getContent());
}
//...
}
Modular Functions
Functions should do one thing!
They should do it well!
They should do it only!
public static String testableHtml(
PageData pageData,
boolean includeSuiteSetup
) throws Exception {
WikiPage wikiPage = pageData.getWikiPage();
StringBuffer buffer = new StringBuffer();
if (pageData.hasAttribute("Test")) {
if (includeSuiteSetup) {
WikiPage suiteSetup =
PageCrawlerImpl.getInheritedPage(
SuiteResponder.SUITE_SETUP_NAME, wikiPage
);
if (suiteSetup != null) {
WikiPagePath pagePath =
suiteSetup.getPageCrawler().getFullPath(suiteSetup);
String pagePathName = PathParser.render(pagePath);
buffer.append("!include -setup .")
.append(pagePathName)
.append("\n");
}
}
WikiPage setup =
PageCrawlerImpl.getInheritedPage("SetUp", wikiPage);
if (setup != null) {
WikiPagePath setupPath =
wikiPage.getPageCrawler().getFullPath(setup);
String setupPathName = PathParser.render(setupPath);
buffer.append("!include -setup .")
.append(setupPathName)
.append("\n");
}
}
// ...
}
public static String renderPageWithSetupsAndTeardowns(
PageData pageData, boolean isSuite
) throws Exception {
boolean isTestPage = pageData.hasAttribute("Test");
if (isTestPage) {
WikiPage testPage = pageData.getWikiPage();
StringBuffer newPageContent = new StringBuffer();
includeSetupPages(testPage, newPageContent, isSuite);
newPageContent.append(pageData.getContent());
}
//...
}
One Level of Abstraction!
Function Arguments
0 or 1 or 2 parameters ok!
Boolean flags not good!
Argument options might be a solution!
function drawCircle(x, y, z, radius, blacknwhite) {
// ..
};
function drawCircle(point, radius, color) {
// ..
};
var point = {
'x': 0,
'y': 0,
'z': 0
};
point.x = 1;
point.y = 7;
point.z = 5;
var circle = {
'point': [1,5,7], // x,y,z
'radius': 5,
'color': 'black'
};
function drawCircle(circle) {
// ...
}
Code Formatting
Define Style Rules in your team!
Use a Linter!
Formats code automatically!
Chapter 5
Comments
Chapter 4
Comments do not replace good code!
Explain yourself in code!
// C++ comment
/*
* A multi-line
* comment.
*
* /
# Python comment
'''
A multi-line
comment.
'''
Use comments as a placeholder!
// TODO: Please fix this!
/**
* Returns the day of the month.
*
* @return the day of the month.
*/
public int getDayOfMonth() {
return dayOfMonth;
}
Comments
public class wc {
public static void main(String[] args) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line;
int lineCount = 0;
int charCount = 0;
int wordCount = 0;
try {
while ((line = in.readLine()) != null) {
lineCount++;
charCount += line.length();
String words[] = line.split("\\W");
wordCount += words.length;
} //while
System.out.println("wordCount = " + wordCount);
System.out.println("lineCount = " + lineCount);
System.out.println("charCount = " + charCount);
} // try
catch (IOException e) {
System.err.println("Error:" + e.getMessage());
} //catch
} //main
}
Closing Brace Comments
Object Oriented
Constructor
Instances / Instance Variables
Getters / Setters
Static Methods
Singleton Pattern
More Stuff