In Appreciation: Termux

I’ve been playing with Termux quite a bit in the last couple of days. Being able to do development-any development-while standing on the train is an awesome feeling. I think the site undersells what it is-it’s your compiler in your pocket. It’s ssh in your pocket. I’m redoing my website on my phone (the mobile experience is crap at the moment) by editing the sources in vim, then hosting it locally with Python.

Beware of side effects on default arguments

Check out this quick interactive session:

Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def f(y, x={}):
...   print x
...   if y:
...     x['y'] = True
... 
>>> f(False)
{}
>>> f(False, {'x': True})
{'x': True}
>>> f(True, {'x': True})
{'x': True}
>>> f(False)
{}
>>> f(True)
{}
>>> f(False)
{'y': True}
>>> f(True, {'x': True})
{'x': True}
>>> f(False)
{'y': True}

What’s wrong with this picture? Notice that when I call f(True) we assign something to the default argument x. When we call f again, it replaces the default x = {} with the previous value of x!

I suppose the moral of the story here is that in order to avoid side effects, you should not mess with arguments you’re passing in, even if they’re just the default arguments.

Python list comprehensions

If, like me, you learned python and programming at the same time, you may have missed out on advanced features that, while awesome in python, won’t carry over to other languages you’ll “graduate” to using. One of these features is a list comprehension. It lets you in a compact (and readable) way write loops that take a list and return a list, and does not require lambda syntax. They let you write this:

list_squared = []
for x in [1, 2, 3, 4, 5]:
    list_squared.append(x ** 2)

like this:

[x ** 2 for x in [1, 2, 3, 4, 5]]

This really shines when you’re transforming and extracting data – you can also stick an ‘if’ at the end, turning this:

odds_squared = []
for x in [1, 2, 3, 4, 5]:
    if x % 2:
        odds_squared.append(x ** 2)

into this

[x ** 2 for x in [1, 2, 3, 4, 5] if x % 2]

It might not be a huge improvement in amount of code (or LOC, since you’ll want to break complex list comprehensions across multiple lines) but it saves you from potential mistakes, typing ‘append’, and (importantly) having to declare and use another variable name. I consider that a win.

If you found this post exciting, generator expressions will blow your mind.