Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Change without changing: Keep your project heal...

Change without changing: Keep your project healthy by refactoring your code

Refactoring is the process of improving code without changing what it does. It's a vital skill for keeping projects healthy and growing. Without it, implementing new features will take more time and effort.

Most teams rarely refactor. Usually, a senior developer removes him or herself from working on new features and refactors the code base as an exercise to reduce technical debt, reduce complexity, or introduce a programming pattern. This practice makes sense to me since refactoring is inherently an intimidating practice. Approaching a screen full of code to improve it—without altering the behavior—is challenging, even with a clear plan. As such, the people best at refactoring tend to be more senior. They are aware of the 60+ refactoring methods, many design patterns, and the scope and behavior of the specific project.

I want to empower developers at every level to improve the code their working on every time they implement a new feature. Doing so should keep the project healthier and reduce the need for extensive refactoring. Attendees will walk away from this talk assured they can use one of two simple techniques to refactor their code.

Chris May

March 17, 2023
Tweet

More Decks by Chris May

Other Decks in Programming

Transcript

  1. everyday superpowers Change without changing Keep your project healthy by

    refactoring your code Chris May—March 17, 2023
  2. everyday superpowers —Alex Ewerlöf https://blog.alexewerlof.com/p/tech-debt-day “Leadership did not care about

    the code quality as long as the stories were delivered on time. Corners were cut, and tests were skipped.”
  3. everyday superpowers What did they do? • The team had

    an honest conversation about the problem. • Developers argued to stop developing new features to clean everything. • Project management (rightly) pushed back. • They negotiated to reserve every other Friday to reduce tech debt.
  4. everyday superpowers —Alex Ewerlöf https://blog.alexewerlof.com/p/tech-debt-day “Initially it was hard to

    defend spending 10% of the team bandwidth on [cleaning our code], but the payback was huge.”
  5. everyday superpowers Refactoring results at 10% • the code quality

    improved • delivered features faster • nearly all "embarrassingly unnecessary incidents” eliminated • enabled them to make better judgment calls when we had to cut corners due to the time constraints • enjoyed their daily work more • inspired other teams to do the same
  6. everyday superpowers Most of us are too focused on 


    getting features out the door. 
 Regularly taking even a small percentage of your time to improve your code can reap huge benefits.
  7. everyday superpowers Most of us are too focused on 


    getting features out the door. 
 Regularly taking even a small percentage of your time to improve your code can reap huge benefits.
  8. everyday superpowers Hi, I’m Chris May! Python technical coach I

    help python developers and teams reach their potential and make an impact through small-group training and educational resources. https://everydaysuperpowers.dev
  9. everyday superpowers Top-down • Were written with less- fl exible

    languages in mind • Are “destinations” you can take your code to
  10. everyday superpowers Over 60 refactoring methods • Change Function Declaration

    • Change Reference to Value • Change Value to Reference • Collapse Hierarchy • Combine Functions into Class • Combine Functions into Transform • Consolidate Conditional Expression • Decompose Conditional • Encapsulate Collection • Encapsulate Record • Encapsulate Variable • Extract Class • Extract Function • Extract Superclass • Extract Variable • Hide Delegate • Inline Class • Inline Function • Inline Variable • Introduce Assertion • Introduce Parameter Object • Introduce Special Case • Move Field • Move Function • Move Statements into Function • Move Statements to Callers • Parameterize Function • Preserve Whole Object • Pull Up Constructor Body • Pull Up Field • Pull Up Method • Push Down Field • Push Down Method • Remove Dead Code • Remove Flag Argument • Remove Middle Man • Remove Setting Method • Remove Subclass • Rename Field • Rename Variable • Replace Command with Function • Replace Conditional 
 with Polymorphism • Replace Constructor with 
 Factory Function • Replace Control Flag with Break • Replace Derived Variable with Query • Replace Error Code with Exception • Replace Exception with Precheck • Replace Function with Command • Replace Inline Code with 
 Function Call • Replace Loop with Pipeline • Replace Magic Literal • Replace Nested Conditional with Guard Clauses • Replace Parameter with Query • Replace Primitive with Object • Replace Query with Parameter • Replace Subclass with Delegate • Replace Superclass with Delegate • Replace Temp with Query • Replace Type Code with Subclasses • Return Modi fi ed Value • Separate Query from Modi fi er • Slide Statements • Split Loop • Split Phase • Split Variable • Substitute Algorithm
  11. everyday superpowers Top-down refactoring boiled down 1. Ensure tests cover

    what you want to change. 2. Duplicate the implementation. 3. Adjust the code as necessary to cover all cases, running tests every time you make a change. 4. Reroute original code to new code, one instance at a time, and run tests. 5. Remove old implementation. 6. Test again.
  12. everyday superpowers Refactoring styles Top-down • Were written with less-

    fl exible languages in mind • Are “destinations” you can take your code to Bottom-up • Starts with your code • A series of small steps allow good design patterns to emerge • Easier to remember
  13. everyday superpowers Refactoring styles Bottom-up • Starts with your code

    • A series of small steps allow good design patterns to emerge • Easier to remember
  14. everyday superpowers The Flocking Rules 1.Identify what to work on

    1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. (Run tests after each step) 1.Create a component (variable, parameter, function, or class) that will resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the differences with a call to the component. 4.Delete any unused code 5.Repeat until the differences are eliminated
  15. everyday superpowers from textwrap import dedent def recite(verse: int) ->

    str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  16. everyday superpowers from textwrap import dedent def recite(verse: int) ->

    str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  17. everyday superpowers from textwrap import dedent def recite(verse: int) ->

    str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  18. everyday superpowers from textwrap import dedent def recite(verse: int) ->

    str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  19. everyday superpowers from textwrap import dedent def recite(verse: int) ->

    str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  20. everyday superpowers from textwrap import dedent def recite(verse: int) ->

    str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  21. everyday superpowers from textwrap import dedent def recite(verse: int) ->

    str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  22. everyday superpowers from textwrap import dedent def recite(verse: int) ->

    str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated verse ??? 1 ` fi rst` 2 `second`
  23. everyday superpowers from textwrap import dedent def recite(verse: int) ->

    str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated verse nth 1 ` fi rst` 2 `second`
  24. everyday superpowers from textwrap import dedent def recite(verse: int) ->

    str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  25. everyday superpowers from textwrap import dedent def nth(): pass def

    recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  26. everyday superpowers from textwrap import dedent def nth(): pass def

    recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  27. everyday superpowers from textwrap import dedent def nth(): return 'first'

    def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  28. everyday superpowers from textwrap import dedent def nth(): return 'first'

    def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  29. everyday superpowers from textwrap import dedent def nth(): return 'first'

    def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent("""\ On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  30. everyday superpowers from textwrap import dedent def nth(): return 'first'

    def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  31. everyday superpowers from textwrap import dedent def nth(): return 'first'

    def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  32. everyday superpowers from textwrap import dedent def nth(): return 'first'

    def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  33. everyday superpowers from textwrap import dedent def nth(): return 'first'

    def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  34. everyday superpowers from textwrap import dedent def nth(): return 'first'

    def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  35. everyday superpowers from textwrap import dedent def nth(number): if number

    == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  36. everyday superpowers from textwrap import dedent def nth(number): if number

    == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  37. everyday superpowers from textwrap import dedent def nth(number = 1):

    if number == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  38. everyday superpowers from textwrap import dedent def nth(number = 1):

    if number == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent("""\ On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  39. everyday superpowers from textwrap import dedent def nth(number = 1):

    if number == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  40. everyday superpowers from textwrap import dedent def nth(number = 1):

    if number == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  41. everyday superpowers from textwrap import dedent def nth(number = 1):

    if number == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  42. everyday superpowers from textwrap import dedent def nth(number = 1):

    if number == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth()} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  43. everyday superpowers from textwrap import dedent def nth(number = 1):

    if number == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  44. everyday superpowers from textwrap import dedent def nth(number = 1):

    if number == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  45. everyday superpowers from textwrap import dedent def nth(number = 1):

    if number == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  46. everyday superpowers from textwrap import dedent def nth(number): if number

    == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  47. everyday superpowers from textwrap import dedent def nth(number): if number

    == 2: return 'second' return 'first' def recite(verse: int) -> str: if verse == 2: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree. """) else: return dedent(f"""\ On the {nth(verse)} day of Christmas my true love gave to me: a Partridge in a Pear Tree. """) 1.Identify what to work on 1.Find the things that are most alike 2.Identify the smallest di ff erence between them 2.Make them identical. 1.Create a component to resolve the variations. 2.Implement code to supply one variation. 3.Replace one of the di ff erences with a call to the component. 4.Delete any unused code 5.Repeat until the di ff erences are eliminated
  48. everyday superpowers @app.get("/prices") async def compute_price( type: str, age: Optional[int]

    = None, date: Optional[datetime.date] = None, ): result = await database.fetch_one( select(base_price_table.c.cost) .where(base_price_table.c.type == type), ) if age and age < 6: return {"cost": 0} else: if type != 'night': holidays = await database.fetch_all(select(holidays_table)) is_holiday = False reduction = 0 for row in holidays: if date: if date == row.holiday: is_holiday = True if not is_holiday and date and date.weekday() == 0: reduction = 35 # TODO apply reduction for others if age and age < 15:
  49. everyday superpowers if date: if date == row.holiday: is_holiday =

    True if not is_holiday and date and date.weekday() == 0: reduction = 35 # TODO apply reduction for others if age and age < 15: return {"cost": math.ceil(result.cost * .7)} else: if not age: cost = result.cost * (1 - reduction / 100) return {"cost": math.ceil(cost)} else: if age > 64: cost = result.cost * .75 * (1 - reduction / 100) return {"cost": math.ceil(cost)} else: cost = result.cost * (1 - reduction / 100) return {"cost": math.ceil(cost)} else: if age and age >= 6: if age and age > 64: return {"cost": math.ceil(result.cost * .4)} else: return result else: return {"cost": 0}
  50. everyday superpowers @app.get("/prices") async def compute_price( type: str, age: Optional[int]

    = None, date: Optional[datetime.date] = None, ): result = await database.fetch_one( select(base_price_table.c.cost) .where(base_price_table.c.type == type), ) if age and age < 6: return {"cost": 0} else: if type != 'night': holidays = await database.fetch_all(select(holidays_table)) is_holiday = False reduction = 0 for row in holidays: if date: if date == row.holiday: is_holiday = True if not is_holiday and date and date.weekday() == 0: reduction = 35 # TODO apply reduction for others if age and age < 15:
  51. everyday superpowers async def compute_price( type: str, age: int =

    AGE_MISSING, date: datetime.date = DATE_MISSING ) -> int: if type == 'night': return await NightTicket(age).price return await NormalTicket(age, date).price class Ticket: ticket_kind = '' async def get_base_price(self): return await get_base_price_for(self.ticket_kind) class NightTicket(Ticket): ticket_kind = 'night' def __init__(self, age: int = AGE_MISSING, date: datetime = DATE_MISSING): self.age = age @property async def price(self): if self.age <= 6: return 0 if self.age > 64: return math.ceil(await self.get_base_price() * .4) return await self.get_base_price()
  52. everyday superpowers if self.age <= 6: return 0 if self.age

    > 64: return math.ceil(await self.get_base_price() * .4) return await self.get_base_price() class NormalTicket(Ticket): ticket_kind = '1day' def __init__(self, age: int = AGE_MISSING, date: datetime.date = DATE_MISSING): self.age = age self.date = date @property async def price(self): if self.age <= 6: return 0 if self.age < 15: return math.ceil(await self.get_base_price() * .7) reduction = 1 - 35 / 100 if await self.is_holiday() else 1 if self.age > 64: return math.ceil(await self.get_base_price() * .75 * reduction) return math.ceil(await self.get_base_price() * reduction) async def is_holiday(self): holidays = {row.holiday for row in await database.fetch_all(select(holidays_table))} return self.date in holidays
  53. everyday superpowers async def compute_price( type: str, age: int =

    AGE_MISSING, date: datetime.date = DATE_MISSING ) -> int: if type == 'night': return await NightTicket(age).price return await NormalTicket(age, date).price class Ticket: ticket_kind = '' async def get_base_price(self): return await get_base_price_for(self.ticket_kind) class NightTicket(Ticket): ticket_kind = 'night' def __init__(self, age: int = AGE_MISSING, date: datetime = DATE_MISSING): self.age = age @property async def price(self): if self.age <= 6: return 0 if self.age > 64: return math.ceil(await self.get_base_price() * .4) return await self.get_base_price()
  54. everyday superpowers async def compute_price( kind: str, age: int =

    AGE_MISSING, date: datetime.date = DATE_MISSING, ): base_price = await get_base_price(kind) if kind == 'night': if age < 6: return 0 if 64 < age: return math.ceil(base_price * .4) return base_price else: if age < 6: return 0 if age < 15: return math.ceil(base_price * .7) price_with_date_discount = ( base_price * await _calculate_date_discount(date) ) if 64 < age: return math.ceil( price_with_date_discount * 0.75 ) else: return math.ceil(price_with_date_discount)
  55. everyday superpowers async def compute_price( kind: str, age: int =

    AGE_MISSING, date: datetime.date = DATE_MISSING, ): base_price = await get_base_price(kind) if kind == 'night': if age < 6: return 0 if 64 < age: return math.ceil(base_price * .4) return base_price else: if age < 6: return 0 if age < 15: return math.ceil(base_price * .7) price_with_date_discount = ( base_price * await _calculate_date_discount(date) ) if 64 < age: return math.ceil( price_with_date_discount * 0.75 ) else: return math.ceil(price_with_date_discount) async def compute_price( type: str, age: int = AGE_MISSING, date: datetime.date = DATE_MISSING ) -> int: if type == 'night': return await NightTicket(age).price return await NormalTicket(age, date).price class Ticket: ticket_kind = '' async def get_base_price(self): return await get_base_price_for(self.ticket_kind) class NightTicket(Ticket): ticket_kind = 'night' def __init__(self, age: int = AGE_MISSING, date: datetime = DATE_MISSING): self.age = age @property async def price(self): if self.age <= 6: return 0 if self.age > 64: return math.ceil(await self.get_base_price() * .4) return await self.get_base_price() class NormalTicket(Ticket): ticket_kind = '1day' def __init__(self, age: int = AGE_MISSING, date: datetime.date = DATE_MISSING): self.age = age self.date = date @property async def price(self): if self.age <= 6: return 0 if self.age < 15: return math.ceil(await self.get_base_price() * .7) reduction = 1 - 35 / 100 if await self.is_holiday() else 1 if self.age > 64: return math.ceil(await self.get_base_price() * .75 * reduction) return math.ceil(await self.get_base_price() * reduction) async def is_holiday(self): holidays = {row.holiday for row in await database.fetch_all(select(holidays_table))} return self.date in holidays
  56. everyday superpowers —Brett Slatkin (author, Principal Software Engineer at Google)

    @ PyConUS 2016 “Great programmers [write code that] makes so much sense… it's so easy to understand.” “[Most stop] at the point where… it works functionally. 
 A great programmer continues on and refactors the 
 code base so that it's easy to understand and the code 
 is obvious.” “They do this because it provides a better foundation for the future... Over the long run, it saves you time.”
  57. everyday superpowers —Hynek Schlawack (creator of attrs and other elegant

    things) “I don’t really think of refactoring as a separate thing. It’s just the result of having tests and thinking about the design of your code all the time.”
  58. everyday superpowers Refactoring results at 10% • the code quality

    improved • delivered features faster • nearly all "embarrassingly unnecessary incidents” eliminated • enabled them to make better judgment calls when we had to cut corners due to the time constraints • enjoyed their daily work more • inspired other teams to do the same
  59. everyday superpowers Refactoring results at 10% • the code quality

    improved • delivered features faster • nearly all "embarrassingly unnecessary incidents” eliminated • enabled them to make better judgment calls when we had to cut corners due to the time constraints • enjoyed their daily work more • inspired other teams to do the same
  60. everyday superpowers How to learn to refactor • Ask a

    Python meetup to do a refactoring night. • Talk to your teammates about it. • Read through a code smell or refactoring method for 
 10 minutes each week. • Practice often.