[PYTHON] [Refactoring Catalog] Change function declaration

Book Refactoring-Safely Improve Existing Code, 2nd Edition

Or Web version (although it is the complete version), A complementary Refactoring Catalog is available.

What is this

Sample code for books and catalogs is JavaScript, Here is a sample code for refactoring in Python based on the catalog

I will leave the detailed explanation to the book and show it with a glue like "Let's do this here"

Catalog: Change Function Declaration

https://refactoring.com/catalog/changeFunctionDeclaration.html

Initial code, JavaScript version


function circum(radius) {
  return 2 * Math.PI * radius;
}

After refactoring


function circumference(radius) {
  return 2 * Math.PI * radius;
}

Python version

Initial code


import numpy as np
def circum(radius):
  return 2 * np.pi * radius

Test code

Test code, triangulation


from unittest import TestCase
import numpy as np
class TestCatalog(TestCase):
  def test_circum_10(self):
    self.assertEqual(circum(10), 20*np.pi)
  def test_circum_20(self):
    self.assertEqual(circum(20), 40*np.pi)

Let's go here

Add internal function


import numpy as np
def circum(radius):
  def circumference(radius): # add
    return 2 * np.pi * radius # add
  return 2 * np.pi * radius

Use internal functions


import numpy as np
def circum(radius):
  def circumference(radius):
    return 2 * np.pi * radius
  return circumference(radius) # edit

Externalize functions, extract variables


import numpy as np
def circum(radius):
  return circumference(radius)
def circumference(radius): # move
  return 2 * np.pi * radius # move

Change the test target


from unittest import TestCase
import numpy as np
class TestCatalog(TestCase):
  def test_circum_10(self):
    self.assertEqual(circumference(10), 20*np.pi) # edit
  def test_circum_20(self):
    self.assertEqual(circumference(20), 40*np.pi) # edit

Remove unused functions


import numpy as np
def circumference(radius):
  return 2 * np.pi * radius

It's done

I think changes like this example can be helped by the editor's refactoring feature, You can safely refactor the addition and removal of arguments with the same procedure.

Example of changing arguments

A case where you want to correct the fact that you use only a part of the object, but you are passing the entire object as an argument.

Initial code, JavaScript version


function inNewEngland(aCustomer) {
  return ["MA", "CT", "ME", "VT", "NH", "RI"].includes(aCustomer.address.state);
}

After refactoring


function inNewEngland(stateCode) {
  return ["MA", "CT", "ME", "VT", "NH", "RI"].includes(stateCode);
}

Python version

Initial code


def inNewEngland(aCustomer):
  return aCustomer.address.state in ["MA", "CT", "ME", "VT", "NH", "RI"]

Test code

Test code


from unittest import TestCase
from collections import namedtuple
class TestCatalog(TestCase):
  def test_inNewEngland(self):
    address = namedtuple("address", "state")
    aCustomer = namedtuple("aCustomer", "address")
    customer = aCustomer(address("MA"))
    self.assertTrue(inNewEngland(customer))

Let's go here

Extracting variables


def inNewEngland(aCustomer):
  stateCode = aCustomer.address.state # add
  return stateCode in ["MA", "CT", "ME", "VT", "NH", "RI"] # edit

Function extraction


def inNewEngland(aCustomer):
  stateCode = aCustomer.address.state
  return xxinNewEngland(stateCode) # edit
def xxinNewEngland(stateCode): # add
  return stateCode in ["MA", "CT", "ME", "VT", "NH", "RI"] # add

Variable inlining


def inNewEngland(aCustomer):
  return xxinNewEngland(aCustomer.address.state) # edit
def xxinNewEngland(stateCode):
  return stateCode in ["MA", "CT", "ME", "VT", "NH", "RI"]

Change the test target


from unittest import TestCase
from collections import namedtuple
class TestCatalog(TestCase):
  def test_inNewEngland(self):
    address = namedtuple("address", "state")
    aCustomer = namedtuple("aCustomer", "address")
    customer = aCustomer(address("MA"))
    self.assertTrue(xxinNewEngland(customer.address.state)) # edit

Remove unused functions and rename functions


def inNewEngland(stateCode):
  return stateCode in ["MA", "CT", "ME", "VT", "NH", "RI"]

It's done

I jumped a little at the end, but I hope that the function of the editor will help me to change the function name.

that's all

reference

[(Youtube) Martin Fowler-Refactoring Catalog-Change Function Declaration @ Tommy109Martin Fowler-Refactoring Catalog-Change from Reference to Value](http://www.youtube.com/ watch? v = KzStiWzLwg4)

Recommended Posts

[Refactoring Catalog] Change function declaration
[Refactoring Catalog] Change from reference to value