Get
Carter
Michael Caine
Get
Kata
@KevlinHenney
@KevlinHenney
@KevlinHenney
@KevlinHenney
form
pattern
style
way
training
exercise
You do deliberate practice to improve
your ability to perform a task. It’s about
skill and technique.
Deliberate practice means repetition.
You do deliberate practice to master the
task, not to complete the task.
Jon Jagger
Do Lots of Deliberate Practice
Rien n’est plus dangereux
qu’une idée, quand on n’a
qu’une idée.
Émile-Auguste Chartier
Nothing is more dangerous
than an idea, when you
have only one idea.
Émile-Auguste Chartier
a
b
c
a2 + b2 = c2
a2
b2
c2
a2 + b2 = c2
c2
a2
b2
a2 + b2 = c2
c2
½ab
½ab ½ab
½ab
c2 + 2ab
(a + b)2
a2 + b2 + 2ab
a2 + b2 + 2ab = c2 + 2ab
a2 + b2 = c2
½c2
½ab
½ab
½c2 + ab
½(a + b)2
½a2 + ½b2 + ab
½a2 + ½b2 + ab = ½c2 + ab
a2 + b2 = c2
Fizz buzz is a group word
game for children to teach
them about division.
http://en.wikipedia.org/wiki/Fizz_buzz
Players generally sit in a circle. The player
designated to go first says the number "1", and
each player thenceforth counts one number in
turn. However, any number divisible by three is
replaced by the word fizz and any divisible by five
by the word buzz. Numbers divisible by both
become fizz buzz. A player who hesitates or
makes a mistake is eliminated from the game.
http://en.wikipedia.org/wiki/Fizz_buzz
Players generally sit in a circle. The player
designated to go first says the number "1", and
each player thenceforth counts one number in
turn. However, any number divisible by three is
replaced by the word fizz and any divisible by five
by the word buzz. Numbers divisible by both
become fizz buzz. A player who hesitates or
makes a mistake is eliminated from the game.
http://en.wikipedia.org/wiki/Fizz_buzz
Players generally sit in a circle. The player
designated to go first says the number "1", and
each player thenceforth counts one number in
turn. However, any number divisible by three is
replaced by the word fizz and any divisible by five
by the word buzz. Numbers divisible by both
become fizz buzz. A player who hesitates or
makes a mistake is eliminated from the game.
http://en.wikipedia.org/wiki/Fizz_buzz
Adults may play Fizz buzz as a
drinking game, where making
a mistake leads to the player
having to make a drinking-
related forfeit.
http://en.wikipedia.org/wiki/Fizz_buzz
[citation needed]
Fizz buzz has been used as an
interview screening device for
computer programmers.
http://en.wikipedia.org/wiki/Fizz_buzz
FizzBuzz was invented to avoid
the awkwardness of realising
that nobody in the room can
binary search an array.
https://twitter.com/richardadalton/status/591534529086693376
public class FizzBuzzTests
{
@Test
public void testFizzBuzz()
{
...
}
}
public class FizzBuzzTests
{
@Test
public void testFizzBuzzIsOK()
{
...
}
}
public class FizzBuzzTests
{
@Test
public void fizzBuzzOf1Is1()
{
...
}
}
public class FizzBuzzTests
{
@Test
public void fizzBuzzOf1Is1()
{
...
}
@Test
public void fizzBuzzOf2Is2()
{
...
}
}
public class FizzBuzzTests
{
@Test
public void fizzBuzzOf1Is1()
{
...
}
@Test
public void fizzBuzzOf2Is2()
{
...
}
@Test
public void fizzBuzzOf3IsFizz()
{
...
}
}
public class FizzBuzzTests
{
@Test
public void fizzBuzzOf1Is1()
{
...
}
@Test
public void fizzBuzzOf2Is2()
{
...
}
@Test
public void fizzBuzzOf3IsFizz()
{
...
}
...
}
public class FizzBuzzCalculator
{
...
}
I have yet to see any problem,
however complicated, which,
when you looked at it in the
right way, did not become still
more complicated.
Anderson's Law
public class FizzBuzzCalculator
{
private static final String FIZZ = "Fizz";
private static final String BUZZ = "Buzz";
private static final String FIZZBUZZ = "FizzBuzz";
private int fizzMultipleValue;
private int buzzMultipleValue;
private int fizzBuzzMultipleValue;
public FizzBuzzCalculator(int fizzMultipleValue, int buzzMultipleValue)
{
this.fizzMultipleValue = fizzMultipleValue;
this.buzzMultipleValue = buzzMultipleValue;
calculateFizzBuzzMultipleValue();
}
private void calculateFizzBuzzMultipleValue()
{
fizzBuzzMultipleValue = fizzMultipleValue * buzzMultipleValue;
}
public int getFizzMultipleValue()
{
return fizzMultipleValue;
}
public void setFizzMultipleValue(int fizzMultipleValue)
{
this.fizzMultipleValue = fizzMultipleValue;
calculateFizzBuzzMultipleValue();
}
public int getBuzzMultipleValue()
{
return buzzMultipleValue;
}
public void setBuzzMultipleValue(int buzzMultipleValue)
{
this.buzzMultipleValue = buzzMultipleValue;
calculateFizzBuzzMultipleValue();
}
public String returnFizzBuzzOrNumber(int n)
{
if (isFizzBuzz(n))
return FIZZBUZZ;
if (isFizz(n))
return FIZZ;
if (isBuzz(n))
return BUZZ;
return new Integer(n).toString();
}
private static boolean isFizz(int n)
{
return n % fizzMultipleValue == 0;
}
private static boolean isBuzz(int n)
{
return n % buzzMultipleValue == 0;
}
private static boolean isFizzBuzz(int n)
{
return n % fizzBuzzMultipleValue == 0;
}
}
def fizzbuzz(n)
{
result = ''
if (n % 3 == 0)
result += 'Fizz'
if (n % 5 == 0)
result += 'Buzz'
if (!result)
result += n
result
}
def fizzbuzz(n)
{
if (n % 15 == 0)
'FizzBuzz'
else if (n % 3 == 0)
'Fizz'
else if (n % 5 == 0)
'Buzz'
else
n.toString()
}
def fizzbuzz(n)
{
n % 15 == 0 ? 'FizzBuzz' :
n % 3 == 0 ? 'Fizz' :
n % 5 == 0 ? 'Buzz' :
n.toString()
}
def fizzbuzz(n)
{
n in (0..100).step(15) ? 'FizzBuzz' :
n in (0..100).step(3) ? 'Fizz' :
n in (0..100).step(5) ? 'Buzz' :
n.toString()
}
fizzes = [''] + ([''] * 2 + ['Fizz']) * 33 + ['']
buzzes = [''] + ([''] * 4 + ['Buzz']) * 20
numbers = (0..100)*.toString()
def fizzbuzz(n)
{
fizzes[n] + buzzes[n] ?: numbers[n]
}
$0 % 3 == 0 { printf "Fizz" }
$0 % 5 == 0 { printf "Buzz" }
$0 % 3 != 0 && $0 % 5 != 0 { printf $0 }
{ printf "n" }
echo {1..100} | tr ' ' 'n' | awk '
$0 % 3 == 0 { printf "Fizz" }
$0 % 5 == 0 { printf "Buzz" }
$0 % 3 != 0 && $0 % 5 != 0 { printf $0 }
{ printf "n" }
'
echo {1..100} | tr ' ' 'n' | awk '
$0 % 3 == 0 { printf "Fizz" }
$0 % 5 == 0 { printf "Buzz" }
$0 % 3 != 0 && $0 % 5 != 0 { printf $0 }
{ printf "n" }
' | diff - expected && echo Pass
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
We instituted a rigorous regression
test for all of the features of AWK. Any
of the three of us who put in a new
feature into the language [...], first
had to write a test for the new feature.
Alfred Aho
http://www.computerworld.com.au/article/216844/a-z_programming_languages_awk/
Red
Write a failing test for
a new feature
Green
Write enough code to
pass the test
Refactor
Refine code and tests
Test-First Cycle
Red
Write a failing test for
a new feature
Green
Write enough code to
pass the test
Test-First Dumbed Down
assert fizzbuzz(1) == '1'
def fizzbuzz(n):
return '1'
assert fizzbuzz(1) == '1'
assert fizzbuzz(2) == '2'
def fizzbuzz(n):
if n == 1: return '1'
return '2'
assert fizzbuzz(1) == '1'
assert fizzbuzz(2) == '2'
assert fizzbuzz(3) == 'Fizz'
def fizzbuzz(n):
if n == 1: return '1'
if n == 2: return '2'
return 'Fizz'
assert fizzbuzz(1) == '1'
assert fizzbuzz(2) == '2'
assert fizzbuzz(3) == 'Fizz'
assert fizzbuzz(4) == '4'
assert fizzbuzz(5) == 'Buzz'
assert fizzbuzz(6) == 'Fizz'
assert fizzbuzz(7) == '7'
assert fizzbuzz(8) == '8'
assert fizzbuzz(9) == 'Fizz'
assert fizzbuzz(10) == 'Buzz'
assert fizzbuzz(11) == '11'
assert fizzbuzz(12) == 'Fizz'
assert fizzbuzz(13) == '13'
assert fizzbuzz(14) == '14'
assert fizzbuzz(15) == 'FizzBuzz'
def fizzbuzz(n):
if n == 1: return '1'
if n == 2: return '2'
if n == 3: return 'Fizz'
if n == 4: return '4'
if n == 5: return 'Buzz'
if n == 6: return 'Fizz'
if n == 7: return '7'
if n == 8: return '8'
if n == 9: return 'Fizz'
if n == 10: return 'Buzz'
if n == 11: return '11'
if n == 12: return 'Fizz'
if n == 13: return '13'
if n == 14: return '14'
return 'FizzBuzz'
assert fizzbuzz(1) == '1'
assert fizzbuzz(2) == '2'
assert fizzbuzz(3) == 'Fizz'
assert fizzbuzz(4) == '4'
assert fizzbuzz(5) == 'Buzz'
assert fizzbuzz(6) == 'Fizz'
assert fizzbuzz(7) == '7'
assert fizzbuzz(8) == '8'
assert fizzbuzz(9) == 'Fizz'
assert fizzbuzz(10) == 'Buzz'
assert fizzbuzz(11) == '11'
assert fizzbuzz(12) == 'Fizz'
assert fizzbuzz(13) == '13'
assert fizzbuzz(14) == '14'
assert fizzbuzz(15) == 'FizzBuzz'
...
assert fizzbuzz(98) == '98'
assert fizzbuzz(99) == 'Fizz'
assert fizzbuzz(100) == 'Buzz'
def fizzbuzz(n):
if n == 1: return '1'
if n == 2: return '2'
if n == 3: return 'Fizz'
if n == 4: return '4'
if n == 5: return 'Buzz'
if n == 6: return 'Fizz'
if n == 7: return '7'
if n == 8: return '8'
if n == 9: return 'Fizz'
if n == 10: return 'Buzz'
if n == 11: return '11'
if n == 12: return 'Fizz'
if n == 13: return '13'
if n == 14: return '14'
if n == 15: return 'FizzBuzz'
...
if n == 98: return '98'
if n == 99: return 'Fizz'
return 'Buzz'
def fizzbuzz(n):
if n == 1: return '1'
if n == 2: return '2'
if n == 3: return 'Fizz'
if n == 4: return '4'
if n == 5: return 'Buzz'
if n == 6: return 'Fizz'
if n == 7: return '7'
if n == 8: return '8'
if n == 9: return 'Fizz'
if n == 10: return 'Buzz'
if n == 11: return '11'
if n == 12: return 'Fizz'
if n == 13: return '13'
if n == 14: return '14'
if n == 15: return 'FizzBuzz'
...
if n == 98: return '98'
if n == 99: return 'Fizz'
if n == 100: return 'Buzz'
def fizzbuzz(n):
return {
1: lambda: '1',
2: lambda: '2',
3: lambda: 'Fizz',
4: lambda: '4',
5: lambda: 'Buzz',
6: lambda: 'Fizz',
7: lambda: '7',
8: lambda: '8',
9: lambda: 'Fizz',
10: lambda: 'Buzz',
11: lambda: '11',
12: lambda: 'Fizz',
13: lambda: '13',
14: lambda: '14',
15: lambda: 'FizzBuzz',
...
98: lambda: '98',
99: lambda: 'Fizz',
100: lambda: 'Buzz'
}[n]()
def fizzbuzz(n):
return {
1: '1',
2: '2',
3: 'Fizz',
4: '4',
5: 'Buzz',
6: 'Fizz',
7: '7',
8: '8',
9: 'Fizz',
10: 'Buzz',
11: '11',
12: 'Fizz',
13: '13',
14: '14',
15: 'FizzBuzz',
...
98: '98',
99: 'Fizz',
100: 'Buzz'
}[n]
def fizzbuzz(n):
return [
'1',
'2',
'Fizz',
'4',
'Buzz',
'Fizz',
'7',
'8',
'Fizz',
'Buzz',
'11',
'Fizz',
'13',
'14',
'FizzBuzz',
...
'98',
'Fizz',
'Buzz'
][n-1]
Red
Write a failing test for
a new feature
Green
Write enough code to
pass the test
Refactor
Refine code and tests
Test-First Cycle
Plan
Establish hypothesis,
goal or work tasks
Do
Carry out plan
Study
Review what has
been done against
plan (a.k.a. Check)
Act
Revise approach
or artefacts based
on study
Deming/Shewhart Cycle
Write
Create or extend a test
case for new
behaviour — as it's
new, the test fails
Reify
Implement so that
the test passes
Reflect
Is there something in
the code or tests that
could be improved?
Refactor
Make it so!
Test-First Cycle
actual = [fizzbuzz(n) for n in range(1, 101)]
truths = [
every result is 'Fizz', 'Buzz', 'FizzBuzz' or a decimal string,
every decimal result corresponds to its ordinal position,
every third result contains 'Fizz',
every fifth result contains 'Buzz',
every fifteenth result is 'FizzBuzz',
the ordinal position of every 'Fizz' result is divisible by 3,
the ordinal position of every 'Buzz' result is divisible by 5,
the ordinal position of every 'FizzBuzz' result is divisible by 15
]
assert all(truths)
actual = [fizzbuzz(n) for n in range(1, 101)]
truths = [
all(a in {'Fizz', 'Buzz', 'FizzBuzz'} or a.isdecimal() for a in actual),
all(int(a) == n for n, a in enumerate(actual, 1) if a.isdecimal()),
all('Fizz' in a for a in actual[2::3]),
all('Buzz' in a for a in actual[4::5]),
all(a == 'FizzBuzz' for a in actual[14::15]),
all(n % 3 == 0 for n, a in enumerate(actual, 1) if a == 'Fizz'),
all(n % 5 == 0 for n, a in enumerate(actual, 1) if a == 'Buzz'),
all(n % 15 == 0 for n, a in enumerate(actual, 1) if a == 'FizzBuzz')
]
assert all(truths)
A work of art is the
unique result of a
unique temperament.
Oscar Wilde
https://twitter.com/wm/status/7206700352
/ WordFriday
bi-quinary coded decimal, noun
▪ A system of representing numbers based on counting in fives,
with an additional indicator to show whether the count is in the
first or second half of the decimal range, i.e., whether the number
represented is in the range 0–4 or 5–9 (or in the range 1–5 or 6–10).
▪ This system is found in many abacus systems, with paired
columns of counters (normally aligned) representing each bi-
quinary range.
▪ The Roman numeral system is also a form of bi-quinary coded
decimal.
proc roman numerals = (int year) string:
skip;
assert (roman numerals (1) = “I”)
proc roman numerals = (int year) string:
“I”;
assert (roman numerals (1) = “I”);
assert (roman numerals (5) = “V”)
proc roman numerals = (int year) string:
if year = 5 then “V” else “I” fi;
assert (roman numerals (1) = “I”);
assert (roman numerals (5) = “V”);
assert (roman numerals (10) = “X”)
proc roman numerals = (int year) string:
if year = 10 then “X”
elif year = 5 then “V”
else “I”
fi;
assert (roman numerals (1) = “I”);
assert (roman numerals (5) = “V”);
assert (roman numerals (10) = “X”);
assert (roman numerals (50) = “L”);
assert (roman numerals (100) = “C”);
assert (roman numerals (500) = “D”);
assert (roman numerals (1000) = “M”)
proc roman numerals = (int year) string:
if year = 1000 then “M”
elif year = 500 then “D”
elif year = 100 then “C”
elif year = 50 then “L”
elif year = 10 then “X”
elif year = 5 then “V”
else “I”
fi;
[] struct (int value, string letters) mapping =
(
(1000, “M”),
(500, “D”),
(100, “C”),
(50, “L”),
(10, “X”),
(5, “V”),
(1, “I”)
);
proc roman numerals = (int year) string:
begin
string result := "";
for entry from lwb mapping to upb mapping do
if value of mapping[entry] = year then
result := letters of mapping[entry]
fi
od;
result
end;
proc roman numerals = (int year) string:
(
string result := "";
for entry from lwb mapping to upb mapping do
if value of mapping[entry] = year then
result := letters of mapping[entry]
fi
od;
result
);
[] proposition roman numerals spec =
(
("Decimal positions correspond to numerals",
((1, "I"), (10, "X"), (100, "C"), (1000, "M"))),
("Quinary values correspond to numerals",
((5, "V"), (50, "L"), (500, "D")))
);
[] proposition roman numerals spec =
(
("Decimal positions correspond to numerals",
((1, "I"), (10, "X"), (100, "C"), (1000, "M"))),
("Quinary intervals correspond to numerals",
((5, "V"), (50, "L"), (500, "D")))
);
test (roman numerals, roman numerals spec)
mode test = struct (int input, string expected);
mode proposition = struct (string name, flex [1:0] test tests);
proc test = (proc (int) string function, [] proposition spec) void:
for entry from lwb spec to upb spec do
print (name of spec[entry]);
string report := "", separator := " failed:";
[] test tests = tests of spec[entry];
for test from lwb tests to upb tests do
int input = input of tests[test];
string expected = expected of tests[test];
string actual = function (input);
if actual /= expected then
report +:=
separator + " for " + whole (input, 0) +
" expected " + expected + " but was " + actual
separator := “,”
fi
od;
print (if report = "" then (new line) else (new line, report, new line) fi)
od;
[] proposition roman numerals spec =
(
("Decimal positions correspond to numerals",
((1, "I"), (10, "X"), (100, "C"), (1000, "M"))),
("Quinary intervals correspond to numerals",
((5, "V"), (50, "L"), (500, "D"))),
("Multiples of decimals are additive",
((2, "II"), (30, "XXX"), (200, "CC"), (4000, "MMMM")))
);
proc roman numerals = (int year) string:
(
string result := "";
int value = year;
for entry from lwb mapping to upb mapping do
if value mod value of mapping[entry] = 0 then
while value > 0 do
result +:= letters of mapping[entry];
value -:= value of mapping[entry]
od
fi
od;
result
);
[] proposition roman numerals spec =
(
("Decimal positions correspond to numerals",
((1, "I"), (10, "X"), (100, "C"), (1000, "M"))),
("Quinary intervals correspond to numerals",
((5, "V"), (50, "L"), (500, "D"))),
("Multiples of decimals are additive",
((2, "II"), (30, "XXX"), (200, "CC"), (4000, "MMMM"))),
("Non-multiples of decimals are additive",
((6, "VI"), (23, "XXIII"), (273, "CCLXXIII"), (1500, "MD")))
);
proc roman numerals = (int year) string:
(
string result := "";
int value = year;
for entry from lwb mapping to upb mapping do
while value >= value of mapping[entry] do
result +:= letters of mapping[entry];
value -:= value of mapping[entry]
od
od;
result
);
[] proposition roman numerals spec =
(
("Decimal positions correspond to numerals",
((1, "I"), (10, "X"), (100, "C"), (1000, "M"))),
("Quinary intervals correspond to numerals",
((5, "V"), (50, "L"), (500, "D"))),
("Multiples of decimals are additive",
((2, "II"), (30, "XXX"), (200, "CC"), (4000, "MMMM"))),
("Non-multiples of decimals are additive",
((6, "VI"), (23, "XXIII"), (273, "CCLXXIII"), (1500, "MD"))),
("Numeral predecessors are subtractive",
((4, "IV"), (9, "IX"), (40, "XL"), (90, "XC"), (400, "CD"), (900, "CM")))
);
[] struct (int value, string letters) mapping =
(
(1000, "M"), (900, "CM"),
(500, "D"), (400, "CD"),
(100, "C"), (90, "XC"),
(50, "L"), (40, "XL"),
(10, "X"), (9, "IX"),
(5, "V"), (4, "IV"),
(1, "I")
);
[] proposition roman numerals spec =
(
("Decimal positions correspond to numerals",
((1, "I"), (10, "X"), (100, "C"), (1000, "M"))),
("Quinary intervals correspond to numerals",
((5, "V"), (50, "L"), (500, "D"))),
("Multiples of decimals are additive",
((2, "II"), (30, "XXX"), (200, "CC"), (4000, "MMMM"))),
("Non-multiples of decimals are additive",
((6, "VI"), (23, "XXIII"), (273, "CCLXXIII"), (1500, "MD"))),
("Numeral predecessors are subtractive",
((4, "IV"), (9, "IX"), (40, "XL"), (90, "XC"), (400, "CD"), (900, "CM"))),
("Subtractive predecessors are additive",
((14, "XIV"), (42, "XLII"), (1968, "MCMLXVIII")))
);
We could, of course, use any notation
we want; do not laugh at notations;
invent them, they are powerful. In
fact, mathematics is, to a large extent,
invention of better notations.
Richard Feynman
$ ./roman 42
XLII
$ cat roman
printf %$1s |
tr ' ' 'I' |
sed '
s/IIIII/V/g
s/IIII/IV/
s/VV/X/g
s/VIV/IX/
s/XXXXX/L/g
s/XXXX/XL/
s/LL/C/g
s/LXL/XC/
s/CCCCC/D/g
s/CCCC/CD/
s/DD/M/g
s/DCD/CM/
'
echo
Style is time’s fool.
Form is time’s student.
Stewart Brand

Get Kata

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 17.
    You do deliberatepractice to improve your ability to perform a task. It’s about skill and technique. Deliberate practice means repetition. You do deliberate practice to master the task, not to complete the task. Jon Jagger Do Lots of Deliberate Practice
  • 18.
    Rien n’est plusdangereux qu’une idée, quand on n’a qu’une idée. Émile-Auguste Chartier
  • 19.
    Nothing is moredangerous than an idea, when you have only one idea. Émile-Auguste Chartier
  • 20.
  • 21.
  • 22.
  • 24.
  • 25.
  • 26.
    (a + b)2 a2+ b2 + 2ab
  • 27.
    a2 + b2+ 2ab = c2 + 2ab
  • 28.
    a2 + b2= c2
  • 29.
  • 30.
    ½(a + b)2 ½a2+ ½b2 + ab
  • 31.
    ½a2 + ½b2+ ab = ½c2 + ab
  • 32.
    a2 + b2= c2
  • 33.
    Fizz buzz isa group word game for children to teach them about division. http://en.wikipedia.org/wiki/Fizz_buzz
  • 34.
    Players generally sitin a circle. The player designated to go first says the number "1", and each player thenceforth counts one number in turn. However, any number divisible by three is replaced by the word fizz and any divisible by five by the word buzz. Numbers divisible by both become fizz buzz. A player who hesitates or makes a mistake is eliminated from the game. http://en.wikipedia.org/wiki/Fizz_buzz
  • 35.
    Players generally sitin a circle. The player designated to go first says the number "1", and each player thenceforth counts one number in turn. However, any number divisible by three is replaced by the word fizz and any divisible by five by the word buzz. Numbers divisible by both become fizz buzz. A player who hesitates or makes a mistake is eliminated from the game. http://en.wikipedia.org/wiki/Fizz_buzz
  • 36.
    Players generally sitin a circle. The player designated to go first says the number "1", and each player thenceforth counts one number in turn. However, any number divisible by three is replaced by the word fizz and any divisible by five by the word buzz. Numbers divisible by both become fizz buzz. A player who hesitates or makes a mistake is eliminated from the game. http://en.wikipedia.org/wiki/Fizz_buzz
  • 37.
    Adults may playFizz buzz as a drinking game, where making a mistake leads to the player having to make a drinking- related forfeit. http://en.wikipedia.org/wiki/Fizz_buzz [citation needed]
  • 38.
    Fizz buzz hasbeen used as an interview screening device for computer programmers. http://en.wikipedia.org/wiki/Fizz_buzz
  • 39.
    FizzBuzz was inventedto avoid the awkwardness of realising that nobody in the room can binary search an array. https://twitter.com/richardadalton/status/591534529086693376
  • 40.
    public class FizzBuzzTests { @Test publicvoid testFizzBuzz() { ... } }
  • 41.
    public class FizzBuzzTests { @Test publicvoid testFizzBuzzIsOK() { ... } }
  • 42.
    public class FizzBuzzTests { @Test publicvoid fizzBuzzOf1Is1() { ... } }
  • 43.
    public class FizzBuzzTests { @Test publicvoid fizzBuzzOf1Is1() { ... } @Test public void fizzBuzzOf2Is2() { ... } }
  • 44.
    public class FizzBuzzTests { @Test publicvoid fizzBuzzOf1Is1() { ... } @Test public void fizzBuzzOf2Is2() { ... } @Test public void fizzBuzzOf3IsFizz() { ... } }
  • 45.
    public class FizzBuzzTests { @Test publicvoid fizzBuzzOf1Is1() { ... } @Test public void fizzBuzzOf2Is2() { ... } @Test public void fizzBuzzOf3IsFizz() { ... } ... }
  • 46.
  • 47.
    I have yetto see any problem, however complicated, which, when you looked at it in the right way, did not become still more complicated. Anderson's Law
  • 48.
    public class FizzBuzzCalculator { privatestatic final String FIZZ = "Fizz"; private static final String BUZZ = "Buzz"; private static final String FIZZBUZZ = "FizzBuzz"; private int fizzMultipleValue; private int buzzMultipleValue; private int fizzBuzzMultipleValue; public FizzBuzzCalculator(int fizzMultipleValue, int buzzMultipleValue) { this.fizzMultipleValue = fizzMultipleValue; this.buzzMultipleValue = buzzMultipleValue; calculateFizzBuzzMultipleValue(); } private void calculateFizzBuzzMultipleValue() { fizzBuzzMultipleValue = fizzMultipleValue * buzzMultipleValue; } public int getFizzMultipleValue() { return fizzMultipleValue; } public void setFizzMultipleValue(int fizzMultipleValue) { this.fizzMultipleValue = fizzMultipleValue; calculateFizzBuzzMultipleValue(); } public int getBuzzMultipleValue() { return buzzMultipleValue; } public void setBuzzMultipleValue(int buzzMultipleValue) { this.buzzMultipleValue = buzzMultipleValue; calculateFizzBuzzMultipleValue(); } public String returnFizzBuzzOrNumber(int n) { if (isFizzBuzz(n)) return FIZZBUZZ; if (isFizz(n)) return FIZZ; if (isBuzz(n)) return BUZZ; return new Integer(n).toString(); } private static boolean isFizz(int n) { return n % fizzMultipleValue == 0; } private static boolean isBuzz(int n) { return n % buzzMultipleValue == 0; } private static boolean isFizzBuzz(int n) { return n % fizzBuzzMultipleValue == 0; } }
  • 54.
    def fizzbuzz(n) { result ='' if (n % 3 == 0) result += 'Fizz' if (n % 5 == 0) result += 'Buzz' if (!result) result += n result }
  • 55.
    def fizzbuzz(n) { if (n% 15 == 0) 'FizzBuzz' else if (n % 3 == 0) 'Fizz' else if (n % 5 == 0) 'Buzz' else n.toString() }
  • 56.
    def fizzbuzz(n) { n %15 == 0 ? 'FizzBuzz' : n % 3 == 0 ? 'Fizz' : n % 5 == 0 ? 'Buzz' : n.toString() }
  • 57.
    def fizzbuzz(n) { n in(0..100).step(15) ? 'FizzBuzz' : n in (0..100).step(3) ? 'Fizz' : n in (0..100).step(5) ? 'Buzz' : n.toString() }
  • 58.
    fizzes = ['']+ ([''] * 2 + ['Fizz']) * 33 + [''] buzzes = [''] + ([''] * 4 + ['Buzz']) * 20 numbers = (0..100)*.toString() def fizzbuzz(n) { fizzes[n] + buzzes[n] ?: numbers[n] }
  • 59.
    $0 % 3== 0 { printf "Fizz" } $0 % 5 == 0 { printf "Buzz" } $0 % 3 != 0 && $0 % 5 != 0 { printf $0 } { printf "n" }
  • 60.
    echo {1..100} |tr ' ' 'n' | awk ' $0 % 3 == 0 { printf "Fizz" } $0 % 5 == 0 { printf "Buzz" } $0 % 3 != 0 && $0 % 5 != 0 { printf $0 } { printf "n" } '
  • 61.
    echo {1..100} |tr ' ' 'n' | awk ' $0 % 3 == 0 { printf "Fizz" } $0 % 5 == 0 { printf "Buzz" } $0 % 3 != 0 && $0 % 5 != 0 { printf $0 } { printf "n" } ' | diff - expected && echo Pass
  • 62.
  • 63.
    We instituted arigorous regression test for all of the features of AWK. Any of the three of us who put in a new feature into the language [...], first had to write a test for the new feature. Alfred Aho http://www.computerworld.com.au/article/216844/a-z_programming_languages_awk/
  • 64.
    Red Write a failingtest for a new feature Green Write enough code to pass the test Refactor Refine code and tests Test-First Cycle
  • 65.
    Red Write a failingtest for a new feature Green Write enough code to pass the test Test-First Dumbed Down
  • 67.
    assert fizzbuzz(1) =='1' def fizzbuzz(n): return '1'
  • 68.
    assert fizzbuzz(1) =='1' assert fizzbuzz(2) == '2' def fizzbuzz(n): if n == 1: return '1' return '2'
  • 69.
    assert fizzbuzz(1) =='1' assert fizzbuzz(2) == '2' assert fizzbuzz(3) == 'Fizz' def fizzbuzz(n): if n == 1: return '1' if n == 2: return '2' return 'Fizz'
  • 70.
    assert fizzbuzz(1) =='1' assert fizzbuzz(2) == '2' assert fizzbuzz(3) == 'Fizz' assert fizzbuzz(4) == '4' assert fizzbuzz(5) == 'Buzz' assert fizzbuzz(6) == 'Fizz' assert fizzbuzz(7) == '7' assert fizzbuzz(8) == '8' assert fizzbuzz(9) == 'Fizz' assert fizzbuzz(10) == 'Buzz' assert fizzbuzz(11) == '11' assert fizzbuzz(12) == 'Fizz' assert fizzbuzz(13) == '13' assert fizzbuzz(14) == '14' assert fizzbuzz(15) == 'FizzBuzz' def fizzbuzz(n): if n == 1: return '1' if n == 2: return '2' if n == 3: return 'Fizz' if n == 4: return '4' if n == 5: return 'Buzz' if n == 6: return 'Fizz' if n == 7: return '7' if n == 8: return '8' if n == 9: return 'Fizz' if n == 10: return 'Buzz' if n == 11: return '11' if n == 12: return 'Fizz' if n == 13: return '13' if n == 14: return '14' return 'FizzBuzz'
  • 71.
    assert fizzbuzz(1) =='1' assert fizzbuzz(2) == '2' assert fizzbuzz(3) == 'Fizz' assert fizzbuzz(4) == '4' assert fizzbuzz(5) == 'Buzz' assert fizzbuzz(6) == 'Fizz' assert fizzbuzz(7) == '7' assert fizzbuzz(8) == '8' assert fizzbuzz(9) == 'Fizz' assert fizzbuzz(10) == 'Buzz' assert fizzbuzz(11) == '11' assert fizzbuzz(12) == 'Fizz' assert fizzbuzz(13) == '13' assert fizzbuzz(14) == '14' assert fizzbuzz(15) == 'FizzBuzz' ... assert fizzbuzz(98) == '98' assert fizzbuzz(99) == 'Fizz' assert fizzbuzz(100) == 'Buzz' def fizzbuzz(n): if n == 1: return '1' if n == 2: return '2' if n == 3: return 'Fizz' if n == 4: return '4' if n == 5: return 'Buzz' if n == 6: return 'Fizz' if n == 7: return '7' if n == 8: return '8' if n == 9: return 'Fizz' if n == 10: return 'Buzz' if n == 11: return '11' if n == 12: return 'Fizz' if n == 13: return '13' if n == 14: return '14' if n == 15: return 'FizzBuzz' ... if n == 98: return '98' if n == 99: return 'Fizz' return 'Buzz'
  • 72.
    def fizzbuzz(n): if n== 1: return '1' if n == 2: return '2' if n == 3: return 'Fizz' if n == 4: return '4' if n == 5: return 'Buzz' if n == 6: return 'Fizz' if n == 7: return '7' if n == 8: return '8' if n == 9: return 'Fizz' if n == 10: return 'Buzz' if n == 11: return '11' if n == 12: return 'Fizz' if n == 13: return '13' if n == 14: return '14' if n == 15: return 'FizzBuzz' ... if n == 98: return '98' if n == 99: return 'Fizz' if n == 100: return 'Buzz'
  • 73.
    def fizzbuzz(n): return { 1:lambda: '1', 2: lambda: '2', 3: lambda: 'Fizz', 4: lambda: '4', 5: lambda: 'Buzz', 6: lambda: 'Fizz', 7: lambda: '7', 8: lambda: '8', 9: lambda: 'Fizz', 10: lambda: 'Buzz', 11: lambda: '11', 12: lambda: 'Fizz', 13: lambda: '13', 14: lambda: '14', 15: lambda: 'FizzBuzz', ... 98: lambda: '98', 99: lambda: 'Fizz', 100: lambda: 'Buzz' }[n]()
  • 74.
    def fizzbuzz(n): return { 1:'1', 2: '2', 3: 'Fizz', 4: '4', 5: 'Buzz', 6: 'Fizz', 7: '7', 8: '8', 9: 'Fizz', 10: 'Buzz', 11: '11', 12: 'Fizz', 13: '13', 14: '14', 15: 'FizzBuzz', ... 98: '98', 99: 'Fizz', 100: 'Buzz' }[n]
  • 75.
  • 76.
    Red Write a failingtest for a new feature Green Write enough code to pass the test Refactor Refine code and tests Test-First Cycle
  • 77.
    Plan Establish hypothesis, goal orwork tasks Do Carry out plan Study Review what has been done against plan (a.k.a. Check) Act Revise approach or artefacts based on study Deming/Shewhart Cycle
  • 78.
    Write Create or extenda test case for new behaviour — as it's new, the test fails Reify Implement so that the test passes Reflect Is there something in the code or tests that could be improved? Refactor Make it so! Test-First Cycle
  • 79.
    actual = [fizzbuzz(n)for n in range(1, 101)] truths = [ every result is 'Fizz', 'Buzz', 'FizzBuzz' or a decimal string, every decimal result corresponds to its ordinal position, every third result contains 'Fizz', every fifth result contains 'Buzz', every fifteenth result is 'FizzBuzz', the ordinal position of every 'Fizz' result is divisible by 3, the ordinal position of every 'Buzz' result is divisible by 5, the ordinal position of every 'FizzBuzz' result is divisible by 15 ] assert all(truths)
  • 80.
    actual = [fizzbuzz(n)for n in range(1, 101)] truths = [ all(a in {'Fizz', 'Buzz', 'FizzBuzz'} or a.isdecimal() for a in actual), all(int(a) == n for n, a in enumerate(actual, 1) if a.isdecimal()), all('Fizz' in a for a in actual[2::3]), all('Buzz' in a for a in actual[4::5]), all(a == 'FizzBuzz' for a in actual[14::15]), all(n % 3 == 0 for n, a in enumerate(actual, 1) if a == 'Fizz'), all(n % 5 == 0 for n, a in enumerate(actual, 1) if a == 'Buzz'), all(n % 15 == 0 for n, a in enumerate(actual, 1) if a == 'FizzBuzz') ] assert all(truths)
  • 84.
    A work ofart is the unique result of a unique temperament. Oscar Wilde
  • 88.
  • 89.
  • 90.
    bi-quinary coded decimal,noun ▪ A system of representing numbers based on counting in fives, with an additional indicator to show whether the count is in the first or second half of the decimal range, i.e., whether the number represented is in the range 0–4 or 5–9 (or in the range 1–5 or 6–10). ▪ This system is found in many abacus systems, with paired columns of counters (normally aligned) representing each bi- quinary range. ▪ The Roman numeral system is also a form of bi-quinary coded decimal.
  • 95.
    proc roman numerals= (int year) string: skip;
  • 96.
    assert (roman numerals(1) = “I”)
  • 97.
    proc roman numerals= (int year) string: “I”;
  • 98.
    assert (roman numerals(1) = “I”); assert (roman numerals (5) = “V”)
  • 99.
    proc roman numerals= (int year) string: if year = 5 then “V” else “I” fi;
  • 100.
    assert (roman numerals(1) = “I”); assert (roman numerals (5) = “V”); assert (roman numerals (10) = “X”)
  • 101.
    proc roman numerals= (int year) string: if year = 10 then “X” elif year = 5 then “V” else “I” fi;
  • 102.
    assert (roman numerals(1) = “I”); assert (roman numerals (5) = “V”); assert (roman numerals (10) = “X”); assert (roman numerals (50) = “L”); assert (roman numerals (100) = “C”); assert (roman numerals (500) = “D”); assert (roman numerals (1000) = “M”)
  • 103.
    proc roman numerals= (int year) string: if year = 1000 then “M” elif year = 500 then “D” elif year = 100 then “C” elif year = 50 then “L” elif year = 10 then “X” elif year = 5 then “V” else “I” fi;
  • 104.
    [] struct (intvalue, string letters) mapping = ( (1000, “M”), (500, “D”), (100, “C”), (50, “L”), (10, “X”), (5, “V”), (1, “I”) );
  • 105.
    proc roman numerals= (int year) string: begin string result := ""; for entry from lwb mapping to upb mapping do if value of mapping[entry] = year then result := letters of mapping[entry] fi od; result end;
  • 106.
    proc roman numerals= (int year) string: ( string result := ""; for entry from lwb mapping to upb mapping do if value of mapping[entry] = year then result := letters of mapping[entry] fi od; result );
  • 107.
    [] proposition romannumerals spec = ( ("Decimal positions correspond to numerals", ((1, "I"), (10, "X"), (100, "C"), (1000, "M"))), ("Quinary values correspond to numerals", ((5, "V"), (50, "L"), (500, "D"))) );
  • 109.
    [] proposition romannumerals spec = ( ("Decimal positions correspond to numerals", ((1, "I"), (10, "X"), (100, "C"), (1000, "M"))), ("Quinary intervals correspond to numerals", ((5, "V"), (50, "L"), (500, "D"))) ); test (roman numerals, roman numerals spec)
  • 110.
    mode test =struct (int input, string expected); mode proposition = struct (string name, flex [1:0] test tests);
  • 111.
    proc test =(proc (int) string function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec[entry]); string report := "", separator := " failed:"; [] test tests = tests of spec[entry]; for test from lwb tests to upb tests do int input = input of tests[test]; string expected = expected of tests[test]; string actual = function (input); if actual /= expected then report +:= separator + " for " + whole (input, 0) + " expected " + expected + " but was " + actual separator := “,” fi od; print (if report = "" then (new line) else (new line, report, new line) fi) od;
  • 112.
    [] proposition romannumerals spec = ( ("Decimal positions correspond to numerals", ((1, "I"), (10, "X"), (100, "C"), (1000, "M"))), ("Quinary intervals correspond to numerals", ((5, "V"), (50, "L"), (500, "D"))), ("Multiples of decimals are additive", ((2, "II"), (30, "XXX"), (200, "CC"), (4000, "MMMM"))) );
  • 113.
    proc roman numerals= (int year) string: ( string result := ""; int value = year; for entry from lwb mapping to upb mapping do if value mod value of mapping[entry] = 0 then while value > 0 do result +:= letters of mapping[entry]; value -:= value of mapping[entry] od fi od; result );
  • 114.
    [] proposition romannumerals spec = ( ("Decimal positions correspond to numerals", ((1, "I"), (10, "X"), (100, "C"), (1000, "M"))), ("Quinary intervals correspond to numerals", ((5, "V"), (50, "L"), (500, "D"))), ("Multiples of decimals are additive", ((2, "II"), (30, "XXX"), (200, "CC"), (4000, "MMMM"))), ("Non-multiples of decimals are additive", ((6, "VI"), (23, "XXIII"), (273, "CCLXXIII"), (1500, "MD"))) );
  • 115.
    proc roman numerals= (int year) string: ( string result := ""; int value = year; for entry from lwb mapping to upb mapping do while value >= value of mapping[entry] do result +:= letters of mapping[entry]; value -:= value of mapping[entry] od od; result );
  • 116.
    [] proposition romannumerals spec = ( ("Decimal positions correspond to numerals", ((1, "I"), (10, "X"), (100, "C"), (1000, "M"))), ("Quinary intervals correspond to numerals", ((5, "V"), (50, "L"), (500, "D"))), ("Multiples of decimals are additive", ((2, "II"), (30, "XXX"), (200, "CC"), (4000, "MMMM"))), ("Non-multiples of decimals are additive", ((6, "VI"), (23, "XXIII"), (273, "CCLXXIII"), (1500, "MD"))), ("Numeral predecessors are subtractive", ((4, "IV"), (9, "IX"), (40, "XL"), (90, "XC"), (400, "CD"), (900, "CM"))) );
  • 117.
    [] struct (intvalue, string letters) mapping = ( (1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), (100, "C"), (90, "XC"), (50, "L"), (40, "XL"), (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I") );
  • 118.
    [] proposition romannumerals spec = ( ("Decimal positions correspond to numerals", ((1, "I"), (10, "X"), (100, "C"), (1000, "M"))), ("Quinary intervals correspond to numerals", ((5, "V"), (50, "L"), (500, "D"))), ("Multiples of decimals are additive", ((2, "II"), (30, "XXX"), (200, "CC"), (4000, "MMMM"))), ("Non-multiples of decimals are additive", ((6, "VI"), (23, "XXIII"), (273, "CCLXXIII"), (1500, "MD"))), ("Numeral predecessors are subtractive", ((4, "IV"), (9, "IX"), (40, "XL"), (90, "XC"), (400, "CD"), (900, "CM"))), ("Subtractive predecessors are additive", ((14, "XIV"), (42, "XLII"), (1968, "MCMLXVIII"))) );
  • 132.
    We could, ofcourse, use any notation we want; do not laugh at notations; invent them, they are powerful. In fact, mathematics is, to a large extent, invention of better notations. Richard Feynman
  • 133.
    $ ./roman 42 XLII $cat roman printf %$1s | tr ' ' 'I' | sed ' s/IIIII/V/g s/IIII/IV/ s/VV/X/g s/VIV/IX/ s/XXXXX/L/g s/XXXX/XL/ s/LL/C/g s/LXL/XC/ s/CCCCC/D/g s/CCCC/CD/ s/DD/M/g s/DCD/CM/ ' echo
  • 134.
    Style is time’sfool. Form is time’s student. Stewart Brand