Tips and tricks I learned at PyCon 2017

This was my first PyCon, and it was a lot of fun! I wanted to write about my four favorite talks, and some 'tricks' I learned from them.

First is Decorators Unwrapped, by Katie Silverio. While I'm comfortable with decorators, I thought some of her silly 'useless' decorators were good examples. For instance, her no_op decorator, which is basically the identity.
from typing import Callable

def no_op(func: Callable) -> Callable:
    # do nothing
    return func
Another concept I hadn't really thought about was where *args and **kwargs come from in the following simple example, which calls the original function on some supplied arguments (it basically does the same thing as that above).
from typing import Any
from functools import wraps

def args_kwargs(func: Callable) -> Callable:

    def new_function(*args, **kwargs) -> Any:
        res = func(*args, **kwargs)
        return res

    return new_function
Note that *args and **kwargs aren't actually passed until you call the function; the decorator itself takes only the function, so it's basically the same as
def foo(*args: Any, **kwargs: Any) -> None: 
    print(args, kwargs)

args_kwargs(foo)('some arguments')

# ('some arguments',) {}
In other words, we get a new function object back that accepts *args and **kwargs. Moreover, although Silverio didn't include it in her talk (and justly so), nesting more functions allows one to include arguments for the decorator as well.
def html_decorator_with_args(tag: str ='div', pprint: bool =False) -> Callable:
    def decorate(func: Callable) -> Callable:
        def new_func(*args, **kwargs) -> str:
            res = func(*args, **kwargs)
            new_line = '<' + tag + '>' + res + '</' + tag + '>'
            if pprint:
            return new_line
        return new_func
    return decorate

@html_decorator_with_args(tag='div', pprint=True)
def new(*args, **kwargs) -> str:
    return 'This is the decorator in action!'


# <div><p>This is the decorator in action!</p></div>
Without decorator syntax, this is the same as
html_decorator_with_args(tag='div', pprint=True)(html_decorator_with_args(tag='p')(new))()
which is quite horrifying to read. As I wrote about a few posts ago, this is starting to touch on the concept of currying.

Next is Static Types for Python, by Jukka Lehtosalo and David Fisher. I liked this talk because they gave an introduction to MyPy, which I had heard of previously, but never used. It has the ability to check typing in your code and let you know if there are any 'holes' (i.e. if something hasn't been annotated or types are mismatched). Because types aren't enforced in Python 3.6, it's nice sometimes to check if what you've labeled is actually correct. [EDIT (5.22.17)] I actually used MyPy to type check the code in this post, and found that I've been using incorrect types for a while, so I'd highly suggest this to others !

Grok the GIL: Write Fast And Thread Safe Python, by A Jesse Jiryu Davis was also really fascinating. His talk was by and far the most straightforward explanation of what the GIL is in Python, why it's there and how we can use it to our advantage. Moreover, he explains the difference between concurrency and processes with extremely simple examples.

A while back I used the module Pathos for parallel processing on images, but I now see that it's not at all necessary. Given some careful thought, I probably could have accomplished the same using os.fork.

Last, but certainly not least, was Readability Counts, by Trey Hunner. He gives a lot of clear examples in his talk, my favorite being tuple unpacking in for-loops as opposed to accessing values by index. For example,
# this sucks
sc = {}
for i in csv_data:
    sc[i[0]] = i[1]

# this is _much_ easier to understand
state_capitals = {}
for state, capital, _* in state_csv_data:
    state_capitals[state] = capital

He also suggests using context managers and Python's with-syntax, as opposed to try-finally blocks. I might add that Stop Writing Classes, one of the suggested additional sources, was a really great watch.

Altogether it was an interesting conference, and well-worth the 2600 mile journey to attend!