ArsTechnica on first-world-problems … ehm, Soylent

ArsTechnica has probably the best piece I’ve read covering the meta-problem with Soylent.

Nobody will live off of Soylent for extended periods of time. And even if there were people like that they would be considered  at least as weird or crazy as maybe vegans or people with similarly “limited” diets.

Soylent won’t destroy anything in our food culture that hasn’t been already destroyed. Why would anyone care if you drank Soylent instead of eating your drive-through fast-food alone. Chugging down a glass of Soylent instead of munching a chocolate bar between meetings. The cultural aspect of eating together is moot in those cases. At least Soylent would provide a “nutritiously balanced” choice here.

Yes, people must eat, but people don’t *need* to cook (themselves). And honestly many people don’t. I can’t really see the difference between eating out, just heating things up in a microwave or oven or drinking Soylent for that matter. The cultural aspect of preparing food is lost in those cases anyway. This may be partly because of the next aspect.

Cooking is not as easy as it may sound. It requires following “discrete series of steps guided by a mix of instruction, experience, and intuition” “surrounded with a complex support scaffolding” (I really advise you to read the 2nd page of that article). It is as easy and as necessary for a fairly normal everyday life as is compiling software. (I still believe that cooking is the analog equivalent of programming). I second the argument that as easy and essential it may look to some, it looks equally impenetrable and “magic” to others.

One interesting aspect I’ve not thought of previously was that Soylent may be a way to relieve people with eating disorders of guilt and anxiety when eating the “wrong food”. Since “for people struggling with food-related issues, it can be like a damaging drug that you can never quite quit cold turkey” it may provide an unambiguous food choice that is “satiating without being delicious.” It makes preparing and consuming food quantifiable which was the problem for the last two groups of people in the first place.

I don’t really care if it’s Soylent or something else. If find the possibilities intriguing. It’ll get a lot more interesting once anyone cared to study the long-term effects of consuming Soylent. But I’ll definitely try some once it gets available in Germany. 😉

MagicDict

If you write software in Python you come to a point where you are testing a piece of code that expects a more or less elaborate dictionary as an argument to a function. As a good software developer we want that code properly tested but we want to use minimal fixtures to accomplish that.

So, I was looking for something that behaves like a dictionary, that you can give explicit return values for specific keys and that will give you some sort of a “default” return value when you try to access an “unknown” item (I don’t care what as long as there is no Exception raised (e.g.

KeyError

 )).

My first thought was “why not use MagicMock?” … it’s a useful tool in so many situations.

from mock import MagicMock
m = MagicMock(foo="bar")

But using MagicMock where dict is expected yields unexpected results.

>>> # this works as expected
>>> m.foo
'bar'
>>> # but this doesn't do what you'd expect
>>> m["foo"]
<MagicMock name='mock.__getitem__()' id='4396280016'>

First of all attribute and item access are treated differently. You setup MagicMock using key word arguments (i.e. “dict syntax”), but have to use attributes (i.e. “object syntax”) to access them.

Then I thought to yourself “why not mess with the magic methods?”

__getitem__

  and 

__getattr__

  expect the same arguments anyway. So this should work:

m = MagicMock(foo="bar")
m.__getitem__.side_effect = m.__getattr__

Well? …

>>> m.foo
'bar'
>>> m["foo"]
<MagicMock name='mock.foo' id='4554363920'>

… No!

By this time I thought “I can’t be the first to need this” and started searching in the docs and sure enough they provide an example for this case.

d = dict(foo="bar")

m = MagicMock()
m.__getitem__.side_effect = d.__getitem__

Does it work? …

>>> m["foo"]
'bar'
>>> m["bar"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../env/lib/python2.7/site-packages/mock.py", line 955, in __call__
    return _mock_self._mock_call(*args, **kwargs)
  File ".../env/lib/python2.7/site-packages/mock.py", line 1018, in _mock_call
    ret_val = effect(*args, **kwargs)
KeyError: 'bar'

Well, yes and no. It works as long as you only access those items that you have defined to be in the dictionary. If you try to access any “unknown” item you get a

KeyError

 .

After trying out different things the simplest answer to accomplish what I set out to do seems to be sub-classing defaultdict.

from collections import defaultdict

class MagicDict(defaultdict):
    def __missing__(self, key):
        result = self[key] = MagicDict()
        return result

And? …

>>> m["foo"]
'bar'
>>> m["bar"]
defaultdict(None, {})
>>> m.foo
Traceback (most recent call last):
&nbsp; File "<stdin>", line 1, in <module>
AttributeError: 'MagicDict' object has no attribute 'foo'

Indeed, it is. 😀

Well, not quite. There are still a few comfort features missing (e.g. a proper

__repr__

). The whole, improved and tested code can be found in this Gist:

Google Has Most of My Email Because It Has All of Yours

Benjamin Mako Hill has followed up on an interesting thought: in a world where many people use Gmail, just how many of your daily emails also land on Google’s servers even if you aren’t using their services? … For him it turns out more than 50%. o.O

Double Positive = Negative

A linguistics professor was lecturing to her class one day. “In English,” she said, “A double negative forms a positive. In some languages, though, such as Russian, a double negative is still a negative. However, there is no language wherein a double positive can form a negative.”

A voice from the back of the room piped up, “Yeah . . .right.”

Source: http://www.enginesofmischief.com/makers/evan/humor/doublenegative.html