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

Technical Debt - The code monster in your close...

Technical Debt - The code monster in your closet - PyParis 2018

PyParis - November 14, 2018

Technical debt is the code monster hiding in every Python programmer’s closet. If you ignore it, it will terrorize you at night.

I’ve worked at many institutions with many programming languages over the past 12 years. They all have technical debt. Putting on a band-aid and ignoring the real issues can be disastrous. We’ll go through several case studies, review big red flags, and learn how to start chipping away at the problem with confidence.

Nina Zakharenko

November 14, 2018
Tweet

More Decks by Nina Zakharenko

Other Decks in Technology

Transcript

  1. What decisions were made in the past that prevent me

    from getting sh** done today? @nnja
  2. Mistakes I Made Early On 4 Not seeing the value

    in unit tests 4 Not knowing how to say NO to features @nnja
  3. Mistakes I Made Early On 4 Overly optimistic estimates 4

    Putting releases over good design & reusable code @nnja
  4. Time Crunch That project was due yesterday! I'll take a

    shortcut, and clean up the mess tomorrow. @nnja
  5. Lack of understanding 1. Have a problem 2. Look up

    a solution on stackoverflow 3. Copy & paste it into your code 4. ??? 5. Bugs! @nnja
  6. Culture of Despair This is already a heap of trash.

    Will anyone really notice if I add one more thing to the top? @nnja
  7. Code Smells 4 Commented out code 4 Incorrect comments 4

    No tests, or worse: broken tests @nnja
  8. Restore deleted code with git! Find by content: $ git

    log --summary -G'(D|d)jango' Find the commit that deleted a file: ```shell git log --diff-filter=D --summary -- <filename> @nnja
  9. Poor Documentation class OrganicGlutenFreePizzaFactory: def get_dough(self): """ Return amazing, organic,

    GMO and Gluten Free Dough """ # ran out of organic gluten free, use the other stuff. # return 'organic gluten free dough' return 'gmo pesticide processed gluten-full dough' @nnja
  10. Architecture & Design... Smells 4 Parts of the code no

    one wants to touch 4 Brittle codebase -- changing code in one area breaks other parts of the system 4 Severe outages caused by frequent & unexpected bugs @nnja
  11. Good Design -> Implementing new features comes easily Poor Design

    -> New features are shoe- horned into the system @nnja
  12. What exactly does this decorator do? def decorator_evil(func): return False

    @decorator_evil def target(a,b): return a + b >>> target(1,2) TypeError: 'bool' object is not callable >>> target False
  13. 50 Year Old Technology "And we continue to use the

    COBOL programming language, it is extremely difficult to find IT experts who are versed in this language." @nnja
  14. It's not just the IRS 4 Banks & Financial Institutions

    4 Universities 4 Air Traffic Control 4 ... many still use COBOL @nnja
  15. Story Time 4 I used to work in finance. 4

    At the time I was there, all of the banking systems were run on mainframes. 4 The bankers were getting frustrated. They wanted a UI. @nnja
  16. Big Idea! 4 Let’s write a fancy new web front

    end 4 It’ll do ALL the things @nnja
  17. But 4 Rewriting the backend is too expensive 4 It

    already does what we need 4 Let's leave the mainframe as the backend @nnja
  18. Cursors 4 The mainframe would output a text screen from

    a program result, based on a query. 4 The results would be parsed by reading variables from the screen in certain positions. @nnja
  19. Result? 4 The new system was incredibly slow 4 And

    error prone 4 After months of work, the multi-million dollar rewrite was scrapped @nnja
  20. The MVP 4 (Minimum Viable Product) 4 Get the product

    to market as soon as possible @nnja
  21. A Great Idea 4 A successful project that was created

    by a lone developer in a coffee fueled 48 hours. @nnja
  22. There Was a Problem 4 Years went on, but the

    initial code and design didn’t go away. 4 Instead, it became the base for an expanding project, with expanding features. 4 There was never any time to refactor. @nnja
  23. Scope Creep 4 Features that someone thought was a good

    idea one day, stuck around forever. 4 > “In case we need them. Later.” @nnja
  24. Sad Developers 4 Minimal working tests (no time to write

    them). 4 When a release was pushed, something was bound to break. 4 Made everything feel like it was your fault. @nnja
  25. Grinding To a Halt 4 Development time for new features

    skyrocketed 4 The project was deemed too difficult to maintain 4 ... and cancelled. @nnja
  26. Unless something is on fire, or you’re losing money, don't

    merge unreviewed code into master. @nnja
  27. Ended up with twice as many technologies in their stack

    as needed, and twice as big of a mess. @nnja
  28. Sell It To Decision Makers By allocating project time to

    tackling debt, the end result will be less error prone, easier to maintain, and easier to add features to. @nnja
  29. Ski Rental Problem You’re going skiing for an unknown number

    of days. It costs $1 a day to rent, or $20 to buy. Source
  30. Some lingering debt is inevitable. Don't be a perfectionist. Figure

    out the project tolerance, and work with it. @nnja
  31. Refactoring 4 Slow and steady wins the race. 4 The

    end goal is to refactor without breaking existing functionality. @nnja
  32. Refactoring 4 Replace functions and modules incrementally. 4 Test as

    you go. 4 Tests are mandatory at this step. @nnja
  33. Use depreciation patterns Like openstack debtcollector class removed_property(object): """Property descriptor

    that deprecates a property. This works like the ``@property`` descriptor but can be used instead to provide the same functionality and also interact with the :mod:`warnings`module to warn when a property is accessed, set and/or deleted. """ @nnja
  34. Use vulture.py to find dead or unreachable code $ pip

    install vulture $ vulture script.py package/ or $ python -m vulture script.py package/ github.com/jendrikseipp/vulture
  35. sample code def foo(): print("foo") def bar(): print("bar") def baz():

    print("baz") foo() bar() vulture.py output › python -m vulture foo.py foo.py:7: unused function 'baz' (60% confidence)
  36. Shelf Life What's the life expectancy of this project? Longer

    shelf life -> higher debt interest @nnja
  37. Technical debt can be strategic If you don't have to

    pay it off, you got something for nothing. @nnja
  38. Making time for refactoring depends on the size of your

    team, and the size of your problem. @nnja
  39. Guidelines 4 Small 4 Devote a week every 6-8 weeks

    4 Medium 4 Devote a person every 1-4 weeks, rotate 4 Large @nnja
  40. Expect To Be Frustrated The process of cleaning up days

    / months / years of bad code can be analogous with untangling a ball of yarn. Don't give up. @nnja