1. Fibonacci

フィボナッチ数

  1. テストファースト

  2. アサートファースト

  3. 仮実装

  4. 三角測量

  5. 明白な実装

  6. リファクタリング

1.1. テストファースト

[21]:
import unittest
class FibonacciTest(unittest.TestCase):
  pass

unittest.main(argv=[''],exit=False)

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK
[21]:
<unittest.main.TestProgram at 0x10eb70050>

1.2. アサートファースト

[22]:
import unittest
class FibonacciTest(unittest.TestCase):
  def test_function(self):
    self.assertEqual(fib(0),0)

unittest.main(argv=[''],exit=False)
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
[22]:
<unittest.main.TestProgram at 0x10ebd4490>

1.3. 仮実装

[23]:
import unittest

def fib(n):
  return 0

class FibonacciTest(unittest.TestCase):
  def test_function(self):
    self.assertEqual(fib(0),0)

unittest.main(argv=[''],exit=False)
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
[23]:
<unittest.main.TestProgram at 0x10ebb8350>

1.4. 三角測量

[24]:
import unittest

def fib(n):
  return 0

class FibonacciTest(unittest.TestCase):
  def test_function(self):
    self.assertEqual(fib(0),0)
    self.assertEqual(fib(1),1)

unittest.main(argv=[''],exit=False)
F
======================================================================
FAIL: test_function (__main__.FibonacciTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython-input-24-7b690d9000c7>", line 10, in test_function
    self.assertEqual(fib(1),1)
AssertionError: 0 != 1

----------------------------------------------------------------------
Ran 1 test in 0.002s

FAILED (failures=1)
[24]:
<unittest.main.TestProgram at 0x10eba6450>

1.5. 明白な実装

[25]:
import unittest

def fib(n):
  result = n
  if n == 0:
    result = 0
  return result

class FibonacciTest(unittest.TestCase):
  def test_function(self):
    self.assertEqual(fib(0),0)
    self.assertEqual(fib(1),1)

unittest.main(argv=[''],exit=False)
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
[25]:
<unittest.main.TestProgram at 0x10ebd63d0>
[26]:
import unittest

def fib(n):
  result = n
  if n == 0:
    result = 0
  elif n == 1:
    result = 1
  else:
    result = (n - 2) + (n -1)
  return result

class FibonacciTest(unittest.TestCase):
  def test_function(self):
    self.assertEqual(fib(0),0)
    self.assertEqual(fib(1),1)
    self.assertEqual(fib(2),1)

unittest.main(argv=[''],exit=False)
.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK
[26]:
<unittest.main.TestProgram at 0x10eba6d90>
[27]:
import unittest

def fib(n):
  result = n
  if n == 0:
    result = 0
  elif n == 1:
    result = 1
  else:
    result = fib(n - 2) + fib(n -1)
  return result

class FibonacciTest(unittest.TestCase):
  def test_function(self):
    self.assertEqual(fib(0),0)
    self.assertEqual(fib(1),1)
    self.assertEqual(fib(2),1)
    self.assertEqual(fib(3),2)
    self.assertEqual(fib(4),3)
    self.assertEqual(fib(10),55)

unittest.main(argv=[''],exit=False)
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
[27]:
<unittest.main.TestProgram at 0x10ebe6690>

1.6. リファクタリング

[28]:
import unittest

def fib(n):
  if n == 0: return 0
  if n == 1: return 1
  return fib(n - 2) + fib(n -1)

class FibonacciTest(unittest.TestCase):
  def test_function(self):
    self.assertEqual(fib(0),0)
    self.assertEqual(fib(1),1)
    self.assertEqual(fib(2),1)
    self.assertEqual(fib(3),2)
    self.assertEqual(fib(4),3)
    self.assertEqual(fib(10),55)

unittest.main(argv=[''],exit=False)
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
[28]:
<unittest.main.TestProgram at 0x10eb2a790>
[29]:
import unittest

def fib(n):
  next = lambda n: fib(n - 2) + fib(n -1)
  if n == 0: return 0
  if n == 1: return 1
  return next(n)

class FibonacciTest(unittest.TestCase):
  def test_function(self):
    self.assertEqual(fib(0),0)
    self.assertEqual(fib(1),1)
    self.assertEqual(fib(2),1)
    self.assertEqual(fib(3),2)
    self.assertEqual(fib(4),3)
    self.assertEqual(fib(10),55)

unittest.main(argv=[''],exit=False)
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
[29]:
<unittest.main.TestProgram at 0x10eb93610>
[30]:
import unittest

def fib(n):
  next = lambda n: fib(n - 2) + fib(n -1)
  if n == 0: return 0
  if n == 1: return 1
  return next(n)

class FibonacciTest(unittest.TestCase):
  def test_function(self):
    test_patterns = [
                     (0,0),
                     (1,1),
                     (2,1),
                     (3,2),
                     (4,3),
                     (10,55)
    ]

    for arge, expect in test_patterns:
      self.assertEqual(fib(arge), expect)

unittest.main(argv=[''],exit=False)
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
[30]:
<unittest.main.TestProgram at 0x10eb93550>
[31]:
import unittest

def fib(n):
  next = lambda n: fib(n - 2) + fib(n -1)
  if n == 0: return 0
  if n == 1: return 1
  return next(n)

class FibonacciTest(unittest.TestCase):
  def test_function(self):
    test_patterns = [
                     (0,0),
                     (1,1),
                     (2,1),
                     (3,2),
                     (4,3),
                     (10,55)
    ]
    for arge, expect in test_patterns:
      with self.subTest(arge=arge, expect=expect):
        self.assertEqual(fib(arge), expect)

unittest.main(argv=[''],exit=False)
.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK
[31]:
<unittest.main.TestProgram at 0x10ebfa6d0>
[32]:
import unittest

def fib(n):
  next = lambda n: fib(n - 2) + fib(n -1)
  if n == 0: return 0
  if n == 1: return 1
  return next(n)

class FibonacciTest(unittest.TestCase):
  def test_function(self):
    test_patterns = [
                     (0,0),
                     (1,1),
                     (2,1),
                     (3,2),
                     (4,3),
                     (10,55)
    ]
    for arge, expect in test_patterns:
      with self.subTest(arge=arge, expect=expect):
        self.assertEqual(fib(arge), expect)

unittest.main(argv=[''],exit=False)
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
[32]:
<unittest.main.TestProgram at 0x10ebee210>
[45]:
import unittest
class FibonacciTest(unittest.TestCase):
  def test_function(self):
    self.assertEqual(fib(0),0)

unittest.main(argv=[''],exit=False)

.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK
[45]:
<unittest.main.TestProgram at 0x10ec3c690>