SlideShare a Scribd company logo
1 of 68
Download to read offline
What Can Journalists
Teach Developers About
Writing Source Code?
Alex Aitken	

@alexaitken

Alistair McKinnell	

@amckinnell
In some sense techniques for controlling

complexity is what computer science is about.
Harold Abelson
Agenda
What Is Inverted Pyramid ?	

!

Writing Source Code
Using Inverted Pyramid
What Is Inverted Pyramid ?
The inverted pyramid is a metaphor 

used by journalists to illustrate how 

information should be prioritized.
“The Lead”

The Lead

“The Body”
“The Tail”
“The Lead”

The Lead

“The Body”
“The Tail”

“The Lead”: the most

important information
“The Lead”

The Lead

“The Body”
“The Tail”

“The Lead”: the most

important information
“The Body”: the crucial

information
“The Lead”

The Lead

“The Body”
“The Tail”

“The Lead”: the most

important information
“The Body”: the crucial

information
“The Tail”: any extra

information
The Lead

Benefits for Readers

1. Readers can leave an article at any point
and understand it, even if they do not
have all the details. 	

2. For those readers who wish to proceed, it
conducts them through the article details.
Exercise
1
•
•
•

Arrange cards as above	

1–2 groups per table 	

3–4 people per group

22
2
2
Some Boos at Graduation After Judge Bars Prayer
Associated Press
May 21, 2001
WASHINGTON, Ill. - A top student who gave a traditional farewell
speech at a high school graduation was booed and another student
was applauded for holding a moment of silence after a judge barred
prayer at the ceremony.

•
•
•
•

22
2
2

Experience inverted pyramid 	

Read one card at a time	

You have 4 minutes	

It’s not important to read all cards
Some Boos at Graduation After Judge Bars Prayer
Associated Press
May 21, 2001

“The Lead”

WASHINGTON, Ill. - A top student who gave a traditional farewell speech at a high school graduation was
booed and another student was applauded for holding a moment of silence after a judge barred prayer at
the ceremony.
A federal judge issued a restraining order days before Sunday's ceremony at Washington Community
High School blocking any student-led prayer. It was the first time in the 80-year history of the school that
no graduation prayers were said.

The Lead

“The Body”

Natasha Appenheimer, the class valedictorian, traditionally a top student chosen to give the class
graduation speech, was booed when she received her diploma. Her family, backed by the American Civil
Liberties Union, had filed the lawsuit that led to the restraining order. Meanwhile, some stood and
applauded class speaker Ryan Brown when he bowed his head for a moment of silence before his
speech.
About 200 people attended a prayer vigil before the ceremony, and a placard-carrying atheist and a
Pentecostal minister got into a shouting match.
In spite of the turbulent atmosphere, Appenheimer said she wasn't upset by the way things turned out.

“The Tail”

"It's my graduation. I'm happy," she said. The lawsuit "was worth it. We changed things, we righted a
wrong and made something better than it was before. I learned that when you believe in something, you
should stand up for it."
Graduate Annie White disagreed, saying many class members wanted to demonstrate that "God was a
part of our graduation."
Superintendent Lee Edwards said the school district might appeal McDade's ruling. He said the
invocation and benediction prayers usually said at the ceremony were innocuous, and "You would have to
have been working pretty hard to be offended."
School district officials defended the prayer on grounds that students, not administrators, were in charge
of graduation.
The Supreme Court's landmark 1962 decision outlawed organized prayer in public schools. In 1992, the
justices barred clergy-led prayers at graduations, and last year, the court barred officials from letting
students lead crowds in prayer before football games.
public class StringCalculator {	

!
!
!
!
!

public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	
failWhenContainsNegatives(values);	
return sumOf(values);	
}	
private String[] parseValues(String numbers) {	
if (numbers.isEmpty()) {	
return new String[] {};	
}	
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValues(numbers);	
}	

!
!
!

!

!

}	
private List<Integer> convertToInteger(String[] numbers) {	
List<Integer> result = new ArrayList<>();	

!
!
!

}	
private boolean containsCustomDelimiters(String numbers) {	
return numbers.startsWith("//");	
}	
private String[] parseCustomDelimitedValues(String numbers) {	
int newlineIndex = numbers.indexOf('n');	
String delimiters = numbers.substring(2, newlineIndex);	
String numberList = numbers.substring(newlineIndex + 1);	
String[] customDelimiters = parseCustomDelimiters(delimiters);	

!

!

for (String customDelimiter : customDelimiters) {	
numberList = numberList.replaceAll(	
quoteRegularExpression(customDelimiter), ",");	
}	

!

return result;	
}	
private void failWhenContainsNegatives(List<Integer> values) {	
List<Integer> negatives = new ArrayList<>();	
for (Integer value : values) {	
if (value < 0) negatives.add(value);	
}	
if (!negatives.isEmpty()) {	
String message = "Error: negatives not allowed " + negatives;	
throw new RuntimeException(message);	
}	
}	

return result;	

	

for (String number : numbers) {	
result.add(toInteger(number));	
}	

!

for (Integer value : values) {	
result += value;	
}	

!

return parseStandardDelimiters(numbers);	

!
!

private int sumOf(List<Integer> values) {	
int result = 0;	

!
!
!
!
!
}

return numberList.split(",");	
}	
private String[] parseCustomDelimiters(String rawCustomDelimiters) {	
return rawCustomDelimiters.replaceAll("[", "").split("]");	
}	
private String quoteRegularExpression(String customSeparator) {	
return "Q" + customSeparator + "E";	
}	
private String[] parseStandardDelimiters(String numbers) {	
return numbers.split("[,n]");	
}	
private Integer toInteger(String number) {	
Integer value = Integer.parseInt(number);	
return value <= 1000 ? value : 0;	
}
Benefits for Readers

public class StringCalculator {	

!
!
!

The Lead

!

public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	

private int
int

!

for

result += value;	

failWhenContainsNegatives(values);	
return sumOf(values);	
}	

}	

!
!

return
}	

1. Readers can leave an article at any point
!
!
!
and understand it, even if they do not
!
have all the details. 	

 !
!
private String[] parseValues(String numbers) {	
if (numbers.isEmpty()) {	
return
}	

private
return
}	
private
int

if (containsCustomDelimiters(numbers)) {	
return
}	

String delimiters = numbers.substring(2, newlineIndex);	
String numberList = numbers.substring(newlineIndex + 1);	

return parseStandardDelimiters(numbers);	

	

}	

!

String[] customDelimiters = parseCustomDelimiters(delimiters);	

private List<Integer> convertToInteger(String[] numbers) {	
List<Integer> result =

for

for (String number : numbers) {	
result.add(toInteger(number));	
}	

numberList = numberList.replaceAll(	
quoteRegularExpression(customDelimiter),
}	

!

!
2. For those readers who wish to proceed, it
!
!
conducts them through the article details.
!
!
return

}	

return result;	

}	

private
return
}	

private void failWhenContainsNegatives(List<Integer> values) {	
List<Integer> negatives =
for (Integer value : values) {	
if (value < 0) negatives.add(value);	
}	

!

if (!negatives.isEmpty()) {	
String message =
throw
}	
}	

!
!
!
!
}

private
return
}	
private
return
}	

private
Integer value = Integer.parseInt(number);	
return
}
The Lead

Benefits for Developers

1. Readers can leave an article at any point
and understand it, even if they do not
have all the details. 	

2. For those readers who wish to proceed, it
conducts them through the article details.
The Lead

Benefits for Developers

1. 
Developers can leave source code at any

point and understand it, even if they do
not have all the details.
	

2. For those readers who wish to proceed, it
conducts them through the article details.
The Lead

Benefits for Developers

1. Developers can leave source code at any
point and understand it, even if they do
not have all the details.	

2. For those developers who need to see
more implementation details, it conducts
them through the source code.
The Lead

Benefits for Developers

1. Understanding without all the details	

2. Details are effectively organized
Exercise
Lead

•
•

Body
Body
Body

Same groups as last exercise 	

Arrange cards as above

Tail
Tail
Tail
int add(String numbers)
numbers

add(numbers)

“1,2,3”

6

“1,1001,2”

3

“1,-2,3,-4”

Error showing -2, -4

“//#n2#4#6”

12
int add(String numbers)
numbers

add(numbers)

“1,2,3”

6

“1,1001,2”

3

“1,-2,3,-4”

Error showing -2, -4

“//#n2#4#6”

12

“//#n2#4#6”
public int add(String numbers) {
List<Integer> values = convertToInteger(parseValues(numbers));
failWhenContainsNegatives(values);
return sumOf(values);
}

Body
Body
Body

Tail
Tail
Tail

•
•

Flip over the card labelled Lead	


•

Share that understanding with your group

What can you say about the add()
method from reading the Lead card ?
public int add(String numbers) {
List<Integer> values = convertToInteger(parseValues(numbers));
failWhenContainsNegatives(values);

private String[] parseValues(String numbers) {
if (numbers.isEmpty()) {
return new String[] {};
}

return sumOf(values);

if (containsCustomDelimiters(numbers)) {
return parseCustomDelimitedValues(numbers);
}

}

Body
Body

return parseStandardDelimiters(numbers);
}

Tail
Tail
Tail

•
•

Flip over the Body cards one at a time	


•
•

Next, flip over the Tail cards	


Ask yourself: What do I notice about the
code after reading each card ?	

It’s not important to read all cards
public class StringCalculator {	

!
!
!
!
!

public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	
failWhenContainsNegatives(values);	
return sumOf(values);	
}	
private String[] parseValues(String numbers) {	
if (numbers.isEmpty()) {	
return new String[] {};	
}	
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValues(numbers);	
}	

!
!
!

!

!

}	
private List<Integer> convertToInteger(String[] numbers) {	
List<Integer> result = new ArrayList<>();	

!
!
!

}	
private boolean containsCustomDelimiters(String numbers) {	
return numbers.startsWith("//");	
}	
private String[] parseCustomDelimitedValues(String numbers) {	
int newlineIndex = numbers.indexOf('n');	
String delimiters = numbers.substring(2, newlineIndex);	
String numberList = numbers.substring(newlineIndex + 1);	
String[] customDelimiters = parseCustomDelimiters(delimiters);	

!

!

for (String customDelimiter : customDelimiters) {	
numberList = numberList.replaceAll(	
quoteRegularExpression(customDelimiter), ",");	
}	

!

return result;	
}	
private void failWhenContainsNegatives(List<Integer> values) {	
List<Integer> negatives = new ArrayList<>();	
for (Integer value : values) {	
if (value < 0) negatives.add(value);	
}	
if (!negatives.isEmpty()) {	
String message = "Error: negatives not allowed " + negatives;	
throw new RuntimeException(message);	
}	
}	

return result;	

	

for (String number : numbers) {	
result.add(toInteger(number));	
}	

!

for (Integer value : values) {	
result += value;	
}	

!

return parseStandardDelimiters(numbers);	

!
!

private int sumOf(List<Integer> values) {	
int result = 0;	

!
!
!
!
!
}

return numberList.split(",");	
}	
private String[] parseCustomDelimiters(String rawCustomDelimiters) {	
return rawCustomDelimiters.replaceAll("[", "").split("]");	
}	
private String quoteRegularExpression(String customSeparator) {	
return "Q" + customSeparator + "E";	
}	
private String[] parseStandardDelimiters(String numbers) {	
return numbers.split("[,n]");	
}	
private Integer toInteger(String number) {	
Integer value = Integer.parseInt(number);	
return value <= 1000 ? value : 0;	
}
public class StringCalculator {	

!
public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	

!
failWhenContainsNegatives(values);	

!
return sumOf(values);	
}
public class StringCalculator {	

!
public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	

!
failWhenContainsNegatives(values);	

!
return sumOf(values);	
}
The Lead

Understanding without all the detail	

Details are effectively organized
Writing Source Code
Using Inverted Pyramid
Compose Method	

!

You can’t rapidly understand
a method’s logic.	

!

Transform the logic into a
small number of intentionrevealing steps at the same
level of detail.
Composed Method	

!

Compose methods out of
calls to other methods, each
of which is at roughly the
same level of abstraction.
Composed Method and SLAP	

!

Composed method
encourages factoring (or
refactoring) code into small,
cohesive, readable chunks.	

	

SLAP stands for the Single 

Level of Abstraction Principle.
Example
public int add(String numbers) {
List<Integer> negatives = new ArrayList<>();
int sum = 0;
for (String number : parseValues(numbers)) {
Integer value = Integer.parseInt(number);
if (value < 0) {
negatives.add(value);
} else if (value <= 1000) {
sum += value;
}
}
if (!negatives.isEmpty()) {
throw new RuntimeException("Error: negatives not allowed " +
negatives);
}
return sum;
}
public int add(String numbers) {
List<Integer> negatives = new ArrayList<>();
int sum = 0;
for (String number : parseValues(numbers)) {
Integer value = Integer.parseInt(number);
if (value < 0) {
negatives.add(value);
} else if (value <= 1000) {
sum += value;
}
}
if (!negatives.isEmpty()) {
throw new RuntimeException("Error: negatives not allowed " +
negatives);
}
return sum;
}

You can’t rapidly understand

a method’s logic.
public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	

!
failWhenContainsNegatives(values);	

!
return sumOf(values);	
}

Compose methods out of
calls to other methods, each
of which is at roughly the
same level of abstraction.
public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	

!
failWhenContainsNegatives(values);	

!
return sumOf(values);	
}

Understanding without all the detail	

The Lead

Details are effectively organized
Example
The Lead
The Lead
The Lead
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
int newlineIndex = numbers.indexOf('n');	
	
String delimiters = numbers.substring(2, newlineIndex);	
String numberList = numbers.substring(newlineIndex + 1);	
	
String[] customDelimiters = delimiters.	
replaceAll("[", "").split("]");	
	
for (String customDelimiter : customDelimiters) {	
numberList = numberList.	
replaceAll("Q" + customDelimiter + "E", ",");	
}	
	
return numberList.split(",");	
}	

!
return numbers.split("[,n]");	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
int newlineIndex = numbers.indexOf('n');	
	
String delimiters = numbers.substring(2, newlineIndex);	
String numberList = numbers.substring(newlineIndex + 1);	
	
String[] customDelimiters = delimiters.	
replaceAll("[", "").split("]");	
	
for (String customDelimiter : customDelimiters) {	
numberList = numberList.	
replaceAll("Q" + customDelimiter + "E", ",");	
}	
	
return numberList.split(",");	
}	

!
return numbers.split("[,n]");	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return numbers.split("[,n]");	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return numbers.split("[,n]");	
}

SLAP stands for the Single 

Level of Abstraction Principle.
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return numbers.split("[,n]");	
}

SLAP stands for the Single 

Level of Abstraction Principle.
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return numbers.split("[,n]");	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return numbers.split("[,n]");	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return parseStandardDelimiters(numbers);	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return parseStandardDelimiters(numbers);	
}

SLAP stands for the Single 

Level of Abstraction Principle.
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValue(numbers);	
}	

!
return parseStandardDelimiters(numbers);	
}

Understanding without all the detail	

The Lead

Details are effectively organized
Applying Inverted Pyramid
The Lead
The Lead
Compose Method
Liabilities

• Can lead to an overabundance of small methods.	

• Can make debugging difficult because logic is 

spread out across many small methods.

Refactoring to Patterns
Compose Method
Benefits

•

Efficiently communicates what a method does 

and how it does what it does.	


•

Simplifies a method by breaking it up into 

well-named chunks of behaviour at the 

same level of detail.
Refactoring to Patterns
“The Lead”

The Lead

“The Body”
“The Tail”
The Lead

Benefits for Developers

1. Developers can leave source code at any
point and understand it, even if they do
not have all the details.	

2. For those developers who need to see
more implementation details, it conducts
them through the source code.
Exercise
1
•
•

Grab an index card to write on	

Write down 2 things you are going to
consider next time you write code
1
•

Take turns sharing what you wrote with
everyone at your table	


•

This is optional. Unlike in kindergarten,
you don’t have to share
In some sense techniques for controlling

complexity is what computer science is about.
Harold Abelson
The Lead

Benefits for Developers

1. Understanding without all the details	

2. Details are effectively organized
You know you are working on clean code

when each routine you read turns out to be
pretty much what you expected.
Ward Cunningham
Books

Refactoring to Patterns	

Joshua Kerievsky
Implementation Patterns	

Kent Beck
The Productive Programmer	

Neal Ford
Clean Code	

Robert C. Martin
Photos

www.flickr.com/photos/

ecu_digital_collections/3288382289/

www.morguefile.com/

archive/display/848917

More Related Content

Similar to What Can Journalists Teach Developers About Writing Source Code?

Programming RPi for IoT Applications.pdf
Programming RPi for IoT Applications.pdfProgramming RPi for IoT Applications.pdf
Programming RPi for IoT Applications.pdfrakeshk213994
 
Health monitoring and dependency injection - CNUG November 2019
Health monitoring and dependency injection - CNUG November 2019Health monitoring and dependency injection - CNUG November 2019
Health monitoring and dependency injection - CNUG November 2019Alex Thissen
 
Indexing in Cassandra
Indexing in CassandraIndexing in Cassandra
Indexing in CassandraEd Anuff
 
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...Christopher Adams
 
java review by prof kmt.ppt
java review by prof kmt.pptjava review by prof kmt.ppt
java review by prof kmt.pptssuser1d3c311
 
First Do No Harm - 360|AnDev
First Do No Harm - 360|AnDevFirst Do No Harm - 360|AnDev
First Do No Harm - 360|AnDevAnnyce Davis
 
Better Code through Lint and Checkstyle
Better Code through Lint and CheckstyleBetter Code through Lint and Checkstyle
Better Code through Lint and CheckstyleMarc Prengemann
 
Code transformation With Spoon
Code transformation With SpoonCode transformation With Spoon
Code transformation With SpoonGérard Paligot
 
Write code that writes code!
Write code that writes code!Write code that writes code!
Write code that writes code!Jason Feinstein
 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...DroidConTLV
 
Mongo and Harmony
Mongo and HarmonyMongo and Harmony
Mongo and HarmonySteve Smith
 
Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Scott Wlaschin
 
Devoxx BE - How to fail at benchmarking
Devoxx BE - How to fail at benchmarkingDevoxx BE - How to fail at benchmarking
Devoxx BE - How to fail at benchmarkingPierre Laporte
 
Programming in python Unit-1 Part-1
Programming in python Unit-1 Part-1Programming in python Unit-1 Part-1
Programming in python Unit-1 Part-1Vikram Nandini
 

Similar to What Can Journalists Teach Developers About Writing Source Code? (20)

Programming RPi for IoT Applications.pdf
Programming RPi for IoT Applications.pdfProgramming RPi for IoT Applications.pdf
Programming RPi for IoT Applications.pdf
 
Java Tutorial
Java Tutorial Java Tutorial
Java Tutorial
 
Health monitoring and dependency injection - CNUG November 2019
Health monitoring and dependency injection - CNUG November 2019Health monitoring and dependency injection - CNUG November 2019
Health monitoring and dependency injection - CNUG November 2019
 
Indexing in Cassandra
Indexing in CassandraIndexing in Cassandra
Indexing in Cassandra
 
BDD Primer
BDD PrimerBDD Primer
BDD Primer
 
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...
 
java review by prof kmt.ppt
java review by prof kmt.pptjava review by prof kmt.ppt
java review by prof kmt.ppt
 
First Do No Harm - 360|AnDev
First Do No Harm - 360|AnDevFirst Do No Harm - 360|AnDev
First Do No Harm - 360|AnDev
 
Better Code through Lint and Checkstyle
Better Code through Lint and CheckstyleBetter Code through Lint and Checkstyle
Better Code through Lint and Checkstyle
 
Lesson1
Lesson1Lesson1
Lesson1
 
Code transformation With Spoon
Code transformation With SpoonCode transformation With Spoon
Code transformation With Spoon
 
Write code that writes code!
Write code that writes code!Write code that writes code!
Write code that writes code!
 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
 
Chapter 6
Chapter 6Chapter 6
Chapter 6
 
Mongo and Harmony
Mongo and HarmonyMongo and Harmony
Mongo and Harmony
 
Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...
 
Chapter-6.pdf
Chapter-6.pdfChapter-6.pdf
Chapter-6.pdf
 
Devoxx BE - How to fail at benchmarking
Devoxx BE - How to fail at benchmarkingDevoxx BE - How to fail at benchmarking
Devoxx BE - How to fail at benchmarking
 
Feasting On Brains With Taverna Public
Feasting On Brains With Taverna PublicFeasting On Brains With Taverna Public
Feasting On Brains With Taverna Public
 
Programming in python Unit-1 Part-1
Programming in python Unit-1 Part-1Programming in python Unit-1 Part-1
Programming in python Unit-1 Part-1
 

More from Alistair McKinnell

Succeeding with Specification by Example
Succeeding with Specification by ExampleSucceeding with Specification by Example
Succeeding with Specification by ExampleAlistair McKinnell
 
Don't Settle for Poor Names (Or Poor Design)
Don't Settle for Poor Names (Or Poor Design)Don't Settle for Poor Names (Or Poor Design)
Don't Settle for Poor Names (Or Poor Design)Alistair McKinnell
 
Commonality and Variability Analysis: Avoiding Duplicate Code
Commonality and Variability Analysis: Avoiding Duplicate CodeCommonality and Variability Analysis: Avoiding Duplicate Code
Commonality and Variability Analysis: Avoiding Duplicate CodeAlistair McKinnell
 
Agile Tour Shanghai December 2011
Agile Tour Shanghai December 2011Agile Tour Shanghai December 2011
Agile Tour Shanghai December 2011Alistair McKinnell
 
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic Tool
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic ToolAgile Transition in Trouble? Using the Kotter Change Model as a Diagnostic Tool
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic ToolAlistair McKinnell
 
Struggling to Create Maintainable Unit Tests?
Struggling to Create Maintainable Unit Tests?Struggling to Create Maintainable Unit Tests?
Struggling to Create Maintainable Unit Tests?Alistair McKinnell
 

More from Alistair McKinnell (14)

Succeeding with Specification by Example
Succeeding with Specification by ExampleSucceeding with Specification by Example
Succeeding with Specification by Example
 
Don't Settle for Poor Names (Or Poor Design)
Don't Settle for Poor Names (Or Poor Design)Don't Settle for Poor Names (Or Poor Design)
Don't Settle for Poor Names (Or Poor Design)
 
Don't Settle for Poor Names
Don't Settle for Poor NamesDon't Settle for Poor Names
Don't Settle for Poor Names
 
The Boy Scout Rule
The Boy Scout RuleThe Boy Scout Rule
The Boy Scout Rule
 
Advanced Developer Testing
Advanced Developer TestingAdvanced Developer Testing
Advanced Developer Testing
 
Ubiquitous Testing
Ubiquitous TestingUbiquitous Testing
Ubiquitous Testing
 
Commonality and Variability Analysis: Avoiding Duplicate Code
Commonality and Variability Analysis: Avoiding Duplicate CodeCommonality and Variability Analysis: Avoiding Duplicate Code
Commonality and Variability Analysis: Avoiding Duplicate Code
 
Simple Design
Simple DesignSimple Design
Simple Design
 
Agile Tour Shanghai December 2011
Agile Tour Shanghai December 2011Agile Tour Shanghai December 2011
Agile Tour Shanghai December 2011
 
Pair Programming
Pair ProgrammingPair Programming
Pair Programming
 
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic Tool
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic ToolAgile Transition in Trouble? Using the Kotter Change Model as a Diagnostic Tool
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic Tool
 
The Story of a Story
The Story of a StoryThe Story of a Story
The Story of a Story
 
The Testing Landscape
The Testing LandscapeThe Testing Landscape
The Testing Landscape
 
Struggling to Create Maintainable Unit Tests?
Struggling to Create Maintainable Unit Tests?Struggling to Create Maintainable Unit Tests?
Struggling to Create Maintainable Unit Tests?
 

Recently uploaded

Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 

Recently uploaded (20)

Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 

What Can Journalists Teach Developers About Writing Source Code?

  • 1. What Can Journalists Teach Developers About Writing Source Code? Alex Aitken @alexaitken Alistair McKinnell @amckinnell
  • 2. In some sense techniques for controlling
 complexity is what computer science is about. Harold Abelson
  • 3. Agenda What Is Inverted Pyramid ? ! Writing Source Code Using Inverted Pyramid
  • 4. What Is Inverted Pyramid ?
  • 5. The inverted pyramid is a metaphor 
 used by journalists to illustrate how 
 information should be prioritized.
  • 6. “The Lead” The Lead “The Body” “The Tail”
  • 7. “The Lead” The Lead “The Body” “The Tail” “The Lead”: the most
 important information
  • 8. “The Lead” The Lead “The Body” “The Tail” “The Lead”: the most
 important information “The Body”: the crucial
 information
  • 9. “The Lead” The Lead “The Body” “The Tail” “The Lead”: the most
 important information “The Body”: the crucial
 information “The Tail”: any extra
 information
  • 10. The Lead Benefits for Readers 1. Readers can leave an article at any point and understand it, even if they do not have all the details. 2. For those readers who wish to proceed, it conducts them through the article details.
  • 12. 1 • • • Arrange cards as above 1–2 groups per table 3–4 people per group 22 2 2
  • 13. Some Boos at Graduation After Judge Bars Prayer Associated Press May 21, 2001 WASHINGTON, Ill. - A top student who gave a traditional farewell speech at a high school graduation was booed and another student was applauded for holding a moment of silence after a judge barred prayer at the ceremony. • • • • 22 2 2 Experience inverted pyramid Read one card at a time You have 4 minutes It’s not important to read all cards
  • 14. Some Boos at Graduation After Judge Bars Prayer Associated Press May 21, 2001 “The Lead” WASHINGTON, Ill. - A top student who gave a traditional farewell speech at a high school graduation was booed and another student was applauded for holding a moment of silence after a judge barred prayer at the ceremony. A federal judge issued a restraining order days before Sunday's ceremony at Washington Community High School blocking any student-led prayer. It was the first time in the 80-year history of the school that no graduation prayers were said. The Lead “The Body” Natasha Appenheimer, the class valedictorian, traditionally a top student chosen to give the class graduation speech, was booed when she received her diploma. Her family, backed by the American Civil Liberties Union, had filed the lawsuit that led to the restraining order. Meanwhile, some stood and applauded class speaker Ryan Brown when he bowed his head for a moment of silence before his speech. About 200 people attended a prayer vigil before the ceremony, and a placard-carrying atheist and a Pentecostal minister got into a shouting match. In spite of the turbulent atmosphere, Appenheimer said she wasn't upset by the way things turned out. “The Tail” "It's my graduation. I'm happy," she said. The lawsuit "was worth it. We changed things, we righted a wrong and made something better than it was before. I learned that when you believe in something, you should stand up for it." Graduate Annie White disagreed, saying many class members wanted to demonstrate that "God was a part of our graduation." Superintendent Lee Edwards said the school district might appeal McDade's ruling. He said the invocation and benediction prayers usually said at the ceremony were innocuous, and "You would have to have been working pretty hard to be offended." School district officials defended the prayer on grounds that students, not administrators, were in charge of graduation. The Supreme Court's landmark 1962 decision outlawed organized prayer in public schools. In 1992, the justices barred clergy-led prayers at graduations, and last year, the court barred officials from letting students lead crowds in prayer before football games.
  • 15. public class StringCalculator { ! ! ! ! ! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); failWhenContainsNegatives(values); return sumOf(values); } private String[] parseValues(String numbers) { if (numbers.isEmpty()) { return new String[] {}; } if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } ! ! ! ! ! } private List<Integer> convertToInteger(String[] numbers) { List<Integer> result = new ArrayList<>(); ! ! ! } private boolean containsCustomDelimiters(String numbers) { return numbers.startsWith("//"); } private String[] parseCustomDelimitedValues(String numbers) { int newlineIndex = numbers.indexOf('n'); String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); String[] customDelimiters = parseCustomDelimiters(delimiters); ! ! for (String customDelimiter : customDelimiters) { numberList = numberList.replaceAll( quoteRegularExpression(customDelimiter), ","); } ! return result; } private void failWhenContainsNegatives(List<Integer> values) { List<Integer> negatives = new ArrayList<>(); for (Integer value : values) { if (value < 0) negatives.add(value); } if (!negatives.isEmpty()) { String message = "Error: negatives not allowed " + negatives; throw new RuntimeException(message); } } return result; for (String number : numbers) { result.add(toInteger(number)); } ! for (Integer value : values) { result += value; } ! return parseStandardDelimiters(numbers); ! ! private int sumOf(List<Integer> values) { int result = 0; ! ! ! ! ! } return numberList.split(","); } private String[] parseCustomDelimiters(String rawCustomDelimiters) { return rawCustomDelimiters.replaceAll("[", "").split("]"); } private String quoteRegularExpression(String customSeparator) { return "Q" + customSeparator + "E"; } private String[] parseStandardDelimiters(String numbers) { return numbers.split("[,n]"); } private Integer toInteger(String number) { Integer value = Integer.parseInt(number); return value <= 1000 ? value : 0; }
  • 16. Benefits for Readers public class StringCalculator { ! ! ! The Lead ! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); private int int ! for result += value; failWhenContainsNegatives(values); return sumOf(values); } } ! ! return } 1. Readers can leave an article at any point ! ! ! and understand it, even if they do not ! have all the details. ! ! private String[] parseValues(String numbers) { if (numbers.isEmpty()) { return } private return } private int if (containsCustomDelimiters(numbers)) { return } String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); return parseStandardDelimiters(numbers); } ! String[] customDelimiters = parseCustomDelimiters(delimiters); private List<Integer> convertToInteger(String[] numbers) { List<Integer> result = for for (String number : numbers) { result.add(toInteger(number)); } numberList = numberList.replaceAll( quoteRegularExpression(customDelimiter), } ! ! 2. For those readers who wish to proceed, it ! ! conducts them through the article details. ! ! return } return result; } private return } private void failWhenContainsNegatives(List<Integer> values) { List<Integer> negatives = for (Integer value : values) { if (value < 0) negatives.add(value); } ! if (!negatives.isEmpty()) { String message = throw } } ! ! ! ! } private return } private return } private Integer value = Integer.parseInt(number); return }
  • 17. The Lead Benefits for Developers 1. Readers can leave an article at any point and understand it, even if they do not have all the details. 2. For those readers who wish to proceed, it conducts them through the article details.
  • 18. The Lead Benefits for Developers 1. 
Developers can leave source code at any 
point and understand it, even if they do not have all the details. 2. For those readers who wish to proceed, it conducts them through the article details.
  • 19. The Lead Benefits for Developers 1. Developers can leave source code at any point and understand it, even if they do not have all the details. 2. For those developers who need to see more implementation details, it conducts them through the source code.
  • 20. The Lead Benefits for Developers 1. Understanding without all the details 2. Details are effectively organized
  • 22. Lead • • Body Body Body Same groups as last exercise Arrange cards as above Tail Tail Tail
  • 25. public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); failWhenContainsNegatives(values); return sumOf(values); } Body Body Body Tail Tail Tail • • Flip over the card labelled Lead • Share that understanding with your group What can you say about the add() method from reading the Lead card ?
  • 26. public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); failWhenContainsNegatives(values); private String[] parseValues(String numbers) { if (numbers.isEmpty()) { return new String[] {}; } return sumOf(values); if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } } Body Body return parseStandardDelimiters(numbers); } Tail Tail Tail • • Flip over the Body cards one at a time • • Next, flip over the Tail cards Ask yourself: What do I notice about the code after reading each card ? It’s not important to read all cards
  • 27. public class StringCalculator { ! ! ! ! ! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); failWhenContainsNegatives(values); return sumOf(values); } private String[] parseValues(String numbers) { if (numbers.isEmpty()) { return new String[] {}; } if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } ! ! ! ! ! } private List<Integer> convertToInteger(String[] numbers) { List<Integer> result = new ArrayList<>(); ! ! ! } private boolean containsCustomDelimiters(String numbers) { return numbers.startsWith("//"); } private String[] parseCustomDelimitedValues(String numbers) { int newlineIndex = numbers.indexOf('n'); String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); String[] customDelimiters = parseCustomDelimiters(delimiters); ! ! for (String customDelimiter : customDelimiters) { numberList = numberList.replaceAll( quoteRegularExpression(customDelimiter), ","); } ! return result; } private void failWhenContainsNegatives(List<Integer> values) { List<Integer> negatives = new ArrayList<>(); for (Integer value : values) { if (value < 0) negatives.add(value); } if (!negatives.isEmpty()) { String message = "Error: negatives not allowed " + negatives; throw new RuntimeException(message); } } return result; for (String number : numbers) { result.add(toInteger(number)); } ! for (Integer value : values) { result += value; } ! return parseStandardDelimiters(numbers); ! ! private int sumOf(List<Integer> values) { int result = 0; ! ! ! ! ! } return numberList.split(","); } private String[] parseCustomDelimiters(String rawCustomDelimiters) { return rawCustomDelimiters.replaceAll("[", "").split("]"); } private String quoteRegularExpression(String customSeparator) { return "Q" + customSeparator + "E"; } private String[] parseStandardDelimiters(String numbers) { return numbers.split("[,n]"); } private Integer toInteger(String number) { Integer value = Integer.parseInt(number); return value <= 1000 ? value : 0; }
  • 28. public class StringCalculator { ! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); ! failWhenContainsNegatives(values); ! return sumOf(values); }
  • 29. public class StringCalculator { ! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); ! failWhenContainsNegatives(values); ! return sumOf(values); }
  • 30. The Lead Understanding without all the detail Details are effectively organized
  • 31. Writing Source Code Using Inverted Pyramid
  • 32. Compose Method ! You can’t rapidly understand a method’s logic. ! Transform the logic into a small number of intentionrevealing steps at the same level of detail.
  • 33. Composed Method ! Compose methods out of calls to other methods, each of which is at roughly the same level of abstraction.
  • 34. Composed Method and SLAP ! Composed method encourages factoring (or refactoring) code into small, cohesive, readable chunks. SLAP stands for the Single 
 Level of Abstraction Principle.
  • 36. public int add(String numbers) { List<Integer> negatives = new ArrayList<>(); int sum = 0; for (String number : parseValues(numbers)) { Integer value = Integer.parseInt(number); if (value < 0) { negatives.add(value); } else if (value <= 1000) { sum += value; } } if (!negatives.isEmpty()) { throw new RuntimeException("Error: negatives not allowed " + negatives); } return sum; }
  • 37. public int add(String numbers) { List<Integer> negatives = new ArrayList<>(); int sum = 0; for (String number : parseValues(numbers)) { Integer value = Integer.parseInt(number); if (value < 0) { negatives.add(value); } else if (value <= 1000) { sum += value; } } if (!negatives.isEmpty()) { throw new RuntimeException("Error: negatives not allowed " + negatives); } return sum; } You can’t rapidly understand
 a method’s logic.
  • 38. public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); ! failWhenContainsNegatives(values); ! return sumOf(values); } Compose methods out of calls to other methods, each of which is at roughly the same level of abstraction.
  • 39. public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); ! failWhenContainsNegatives(values); ! return sumOf(values); } Understanding without all the detail The Lead Details are effectively organized
  • 44. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { int newlineIndex = numbers.indexOf('n'); String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); String[] customDelimiters = delimiters. replaceAll("[", "").split("]"); for (String customDelimiter : customDelimiters) { numberList = numberList. replaceAll("Q" + customDelimiter + "E", ","); } return numberList.split(","); } ! return numbers.split("[,n]"); }
  • 45. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { int newlineIndex = numbers.indexOf('n'); String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); String[] customDelimiters = delimiters. replaceAll("[", "").split("]"); for (String customDelimiter : customDelimiters) { numberList = numberList. replaceAll("Q" + customDelimiter + "E", ","); } return numberList.split(","); } ! return numbers.split("[,n]"); }
  • 46. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { return parseCustomDelimitedValues(numbers); } ! return numbers.split("[,n]"); }
  • 47. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { return parseCustomDelimitedValues(numbers); } ! return numbers.split("[,n]"); } SLAP stands for the Single 
 Level of Abstraction Principle.
  • 48. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { return parseCustomDelimitedValues(numbers); } ! return numbers.split("[,n]"); } SLAP stands for the Single 
 Level of Abstraction Principle.
  • 49. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { return parseCustomDelimitedValues(numbers); } ! return numbers.split("[,n]"); }
  • 50. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } ! return numbers.split("[,n]"); }
  • 51. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } ! return parseStandardDelimiters(numbers); }
  • 52. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } ! return parseStandardDelimiters(numbers); } SLAP stands for the Single 
 Level of Abstraction Principle.
  • 53. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValue(numbers); } ! return parseStandardDelimiters(numbers); } Understanding without all the detail The Lead Details are effectively organized
  • 57. Compose Method Liabilities • Can lead to an overabundance of small methods. • Can make debugging difficult because logic is 
 spread out across many small methods. Refactoring to Patterns
  • 58. Compose Method Benefits • Efficiently communicates what a method does 
 and how it does what it does. • Simplifies a method by breaking it up into 
 well-named chunks of behaviour at the 
 same level of detail. Refactoring to Patterns
  • 59. “The Lead” The Lead “The Body” “The Tail”
  • 60. The Lead Benefits for Developers 1. Developers can leave source code at any point and understand it, even if they do not have all the details. 2. For those developers who need to see more implementation details, it conducts them through the source code.
  • 62. 1 • • Grab an index card to write on Write down 2 things you are going to consider next time you write code
  • 63. 1 • Take turns sharing what you wrote with everyone at your table • This is optional. Unlike in kindergarten, you don’t have to share
  • 64. In some sense techniques for controlling
 complexity is what computer science is about. Harold Abelson
  • 65. The Lead Benefits for Developers 1. Understanding without all the details 2. Details are effectively organized
  • 66. You know you are working on clean code
 when each routine you read turns out to be pretty much what you expected. Ward Cunningham
  • 67. Books Refactoring to Patterns Joshua Kerievsky Implementation Patterns Kent Beck The Productive Programmer Neal Ford Clean Code Robert C. Martin