<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Agile and Test-Driven Development
TDD Worked Example
Robert Haines, University of Manchester, UK
Adapted from "Test-Driven Development By Example", Kent Beck
Introduction
Very simple example
Implement a function to return the nth number in the Fibonacci sequence
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...
http
Step1:  Step 1
Step2:  Step 1
Step3:  Step 2
Step4:  Step 2
Step5:  Step 3
Step6:  Step 3
Step7:  Step 4
Step8:  Step 5
Step9:  Step 5
Step10:  Pause
How many tests are we going to write?
Just how big is the set of if statements going to get if we carry on like this?
Where do we stop?
Remember
Step11:  Step 7
Step12:  Step 8
<ASSISTANT_TASK:>
Python Code:
import unittest
def run_tests():
    suite = unittest.TestLoader().loadTestsFromTestCase(TestFibonacci)
    unittest.TextTestRunner().run(suite)
Explanation: Agile and Test-Driven Development
TDD Worked Example
Robert Haines, University of Manchester, UK
Adapted from "Test-Driven Development By Example", Kent Beck
Introduction
Very simple example
Implement a function to return the nth number in the Fibonacci sequence
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...
http://oeis.org/A000045
$
F_0 = 0, \
F_1 = 1, \
F_n = F_{n-1} + F_{n-2}
$
Step 0a: Local python setup
You need to do this if you're using python on the command line.
Create two directories
src
test
Add the src directory to PYTHONPATH
 $ export PYTHONPATH=`pwd`/src
Step 0b: IPython setup
You need to do this if you're using this IPython Notebook.
The run_tests() method, below, is called at the end of each step to run the tests.
End of explanation
class TestFibonacci(unittest.TestCase):
    def test_fibonacci(self):
        self.assertEqual(0, fibonacci(0), "fibonacci(0) should equal 0")
run_tests()
Explanation: Step 1: Write a test (and run it)
End of explanation
def fibonacci(n):
    return 0
run_tests()
Explanation: Step 1: Implement and re-test
End of explanation
class TestFibonacci(unittest.TestCase):
    def test_fibonacci(self):
        self.assertEqual(0, fibonacci(0), "fibonacci(0) should equal 0")
        self.assertEqual(1, fibonacci(1), "fibonacci(1) should equal 1")
run_tests()
Explanation: Step 2: Write a test (and run it)
End of explanation
def fibonacci(n):
    if n == 0: return 0
    return 1
run_tests()
Explanation: Step 2: Implement and re-test
End of explanation
class TestFibonacci(unittest.TestCase):
    def test_fibonacci(self):
        self.assertEqual(0, fibonacci(0), "fibonacci(0) should equal 0")
        self.assertEqual(1, fibonacci(1), "fibonacci(1) should equal 1")
        self.assertEqual(1, fibonacci(2), "fibonacci(2) should equal 1")
run_tests()
Explanation: Step 3: Write a test (and run it)
End of explanation
class TestFibonacci(unittest.TestCase):
    def test_fibonacci(self):
        self.assertEqual(0, fibonacci(0), "fibonacci(0) should equal 0")
        self.assertEqual(1, fibonacci(1), "fibonacci(1) should equal 1")
        self.assertEqual(1, fibonacci(2), "fibonacci(2) should equal 1")
        self.assertEqual(2, fibonacci(3), "fibonacci(3) should equal 2")
run_tests()
Explanation: Step 3: It works!
The current code outputs 1 whenever n is not 0. So this behaviour is correct.
Step 4: Write a test (and run it)
End of explanation
def fibonacci(n):
    if n == 0: return 0
    if n <= 2: return 1
    return 2
run_tests()
Explanation: Step 4: Implement and re-test
End of explanation
class TestFibonacci(unittest.TestCase):
    def test_fibonacci(self):
        self.assertEqual(0, fibonacci(0), "fibonacci(0) should equal 0")
        self.assertEqual(1, fibonacci(1), "fibonacci(1) should equal 1")
        self.assertEqual(1, fibonacci(2), "fibonacci(2) should equal 1")
        self.assertEqual(2, fibonacci(3), "fibonacci(3) should equal 2")
        self.assertEqual(3, fibonacci(4), "fibonacci(4) should equal 3")
run_tests()
Explanation: Step 5: Write a test (and run it)
End of explanation
def fibonacci(n):
    if n == 0: return 0
    if n <= 2: return 1
    if n == 3: return 2
    return 3
run_tests()
Explanation: Step 5: Implement and re-test
End of explanation
def fibonacci(n):
    if n == 0: return 0
    if n <= 2: return 1
    if n == 3: return 2
    return 2 + 1
run_tests()
Explanation: Pause
How many tests are we going to write?
Just how big is the set of if statements going to get if we carry on like this?
Where do we stop?
Remember:
$
F_0 = 0, \
F_1 = 1, \
F_n = F_{n-1} + F_{n-2}
$
Can we reflect that in the code?
Step 6: Refactor and test
End of explanation
def fibonacci(n):
    if n == 0: return 0
    if n <= 2: return 1
    return fibonacci(n - 1) + fibonacci(n - 2)
run_tests()
Explanation: Step 7: Refactor and test
End of explanation
def fibonacci(n):
    if n == 0: return 0
    if n == 1: return 1
    return fibonacci(n - 1) + fibonacci(n - 2)
run_tests()
Explanation: Step 8: Refactor and test (and done)
End of explanation
<END_TASK>