Effective Python Book Club

Effective Python Book Club

March 30, 2016: Chapters 1 & 2

Attending

  • @Cliff Dyer (Deactivated)

  • @Brian Jacobel (Unlicensed)

  • @akivaR (Deactivated)

  • @Brian Wilson (Deactivated)

  • @Andy Armstrong (Deactivated)

  • @Renzo Lucioni (Deactivated)

  • @Ned Batchelder (Deactivated)

  • @Eric Fischer (Deactivated)

  • @Nimisha Asthagiri (Deactivated)

  • @Sandy Student (Deactivated)

Notes

  • Item 2:

    • double-underscore is not for private variables.

  • Item 3:

    • How to handle native strings?

      • from __future__ import unicode_literal & silence when needed (variable behavior between files (yuck))

      • lint native strings

      • have coercion functions

    • Needs engineering education

  • Item 5: slice

    • Is it bad that it is forgiving?

      • Sometimes it's useful

      • Maybe there should be a failfast version.

  • Item 10: enumerate

    • Very useful

    • Takes initial index!  Cool!

  • Item 11: zip

    • Makes Akiva nervous, because it has weird behavior with different length strings

    • zip_longest does the longer one (padding with Nones)

  • Item 12:

    • Renzo disagrees

    • should we avoid else blocks.

    • "If a feature is rare and somewhat surprising, you shouldn't use it." – Akiva

    • Alternative is good: break loop out into a separate function

    • Use with comment to describe behavior.

  • Item 14: Avoid None

    • not var is a source of bugs because None and 0 are both false

    • It's fairly useful for containers (lists, dicts, strings, etc.)

  • Item 15: Closures

    • Accessing non-locals: create a class

    • Use nonlocals as read only

  • Item 16: consider generators instead of lists

    • small lists are fine

    • generators can be problematic.  See Item 17.

    • we don't do much of this

    • generators are awesome

    • custom containers are awesomer

  • Item 17: be defensive when iterating over sequences twice.

    • iter(foo) is iter(foo)

      • different from iter(foo) is foo?

    • convert to list if you hit this kind of error and don't want to refactor into a custom container.

  • Item 21: keyword only args

    • Nimisha does not recommend using **kwargs to enforce keyword-only args, because it makes the code ugly and hard to read

      • Sometimes it's useful anyway

Not Discussed

  • Item 1: Know which version of Python you're using

  • Item 4: Write helper functions instead of complex expressions

  • Item 6: avoid using start, end, and stride in a single slice

    • I think we did discuss this, at least obliquely.  I didn't capture notes.

  • Item 7: Use list comprehensions instead of map and filter

  • Item 8: Avoid more than two expressions in list comprehensions

  • Item 9: Consider generator expressions for large comprehensions

  • Item 13: Take advantage of each block in try/except/else/finally

  • Item 18: Reduce visual noise with variable positional arguments

  • Item 19: Provide optional behavior with keyword arguments

  • Item 20: Use None and docstrings to specify dynamic default arguments

April 6, 2016 Notes: Chapter 3

Attending

@Cliff Dyer (Deactivated) @Eric Fischer (Deactivated)

Notes:

  • Item 26: Mixins

    • Good to see practice formalized

    • No __init__ was a new practice for us.  Would add cleanliness to some code.

  • Item 28: collections.abc

    • Fluently pythonic objects are great.  We should do more of them.  This makes it easy.

 

April 20, 2016 Notes: Chapter 5

Attending

@Cliff Dyer (Deactivated) @Eric Fischer (Deactivated) @Ned Batchelder (Deactivated) @Renzo Lucioni (Deactivated) @Michael Katz (Deactivated) @Nimisha Asthagiri (Deactivated) @akivaR (Deactivated)

Notes

  • Coroutines: Confusing example.  What is the benefit?

    • Separates dumb client and smart server

    • Probably not the kind of thing we want to write in edX production code (probably)

  • concurrent.futures

    • Allows you to send data in chunks

  • When to use threads vs. concurrent.futures:

    • lower level – to implement different patterns of work.

  • subprocess doesn't let you interact with the called process.  Use pyexpect ( ?)

    • subprocess creates two threads to deal with I&O, 

  • LMS Grading has a five day timeout before getting hard-killed. 

    • This should be parallelizable.

 

April 27, 2016 Notes: Chapter 6

Attending: @Eric Fischer (Deactivated) @akivaR (Deactivated) @Ned Batchelder (Deactivated) @Sandy Student (Deactivated)

Notes

  • Fairly uncontroversial overall, good to know how these modules work

  • Addition from Ned: don't forget that __exit__() has a chance to look at thrown exception, it's not just a finally (self.assertRaises in unit tests)

  • Would have been nice to see an example of PyPI utilities, like https://pypi.python.org/pypi/arrow

May 4, 2016 Notes: Chapter 7 Collaboration

Attending: @Eric Fischer (Deactivated) @Renzo Lucioni (Deactivated) @Cliff Dyer (Deactivated)

Notes:

  • None taken

May 4, 2016 Notes: Chapter 7 Collaboration

Attending: @Cliff Dyer (Deactivated) @Sandy Student (Deactivated) @Eric Fischer (Deactivated) @Michael Katz (Deactivated)

Notes:

  • Use a debugger (like pdb, Item 57).  Scott says so.

    • There are pdb alternatives rpdb, pydb, etc. that do remote debugging.

  • reprs are handy.  Create them when you need them, and include in your commit.

  • Profiling: Is there a graphical profiler?  SnakeViz seems to be the thing.