Washing a peanut oil stain makes two concentric peanut oil stains.
You’ve wronged me, jar of natural peanut butter. I scoff at the partially hydrogenated oils and added sugars of your pasty cousins, but you have taken oil separation too far. I was opening you, when you spilled upon my cloth chair. Who will look at the stain you left and believe for a moment that it is anything but semen? You have soiled my name (and my furniture), and I have no recourse besides a duel. When the soapy water dries, we will see who is the better man, my cylindrical friend.
Carbon isn’t carbon dioxide.
This new Firefox extension posts all of your tabs to A Few URLs. Here’s what it looks like:
Installation instructions: clickety click.
Sneeze Steve, The Great Pizza Orientation Test:
The dividing line was exactly 90 degrees up the middle, but mushrooms were on the left!
No, no, no! Try looking from the pizza’s perspective. The pepperoni is on the left, looking out at the eater.
Figure 1. Pizza’s-eye view of a crowd.
Also, The Sneeze’s new tagline should be “Left half zine. Right half blog. Bottom half not good with fractions.” Not only is it self-referential and confusing, it has innuendo from “bottom half.”
I love this exchange from a Reddit comment thread. Logic overcomes trolls, idiots, and grammar Nazis.
- whose gay?
- your gay
WikiHow > Categories > Communications> English Grammar
since we’re all being conan teh grammarians, it’s also “who’s” and not “whose”.
As in: “who is gay?”
So… he got it right then?
Whose gay (is it)? (It is) your gay.
You should be able to get In Rainbows, but don’t count on that link working today.
Sixth Python post in three weeks, woo!
Python FAQ: “be creative with dividing the work up between multiple processes rather than multiple threads.”
I wrote a library that takes a list of functions and their parameters, executes them all in parallel child processes, and returns the results. It’s called procs.
Suppose you have parallelizable code that looks like this:
result1 = slow_function(5, 'hello', foo=3.14) result2 = slower_function(x=10, y=3)
With procs, instead of calling it directly, you make process specifications that almost look like the call:
from procs import * proc1 = proc(slow_function, 5, 'hello', foo=3.14) proc2 = proc(slower_function, x=10, y=3)
Then call them:
results = call([proc1, proc2]) result1, result2 = tuple(results)
results, in the example above, is a generator that yields the results of the functions in the order they were passed to call. They are yielded as soon as they are ready, but in order. This has its upside and downside:
- It’s really simple. You can write regular, serial Python code, then say “do these things at the same time”, and go back to the serial style. You don’t have to write any specialized code.
call([slow_proc, fast_proc]), you can get the first value from the result generator before the second process finishes, but if a process finishes while processes ahead of it are still executing, code that uses it will have to wait.
In the likely case that one function is called several times with different parameters, procs also provides
pmap, which is a map function interface to procs calling. This will be used in the next example.
Really using procs
Let’s see how it fares on a Wide Finder benchmark. I started with Fredrik Lundh’s wf-6.py, removed more code than I added in, and got the expected slightly slower result. My laptop runs his code in about 0.64 time, negligible clock, mine in about 0.64 time, 0.01 clock. Since it’s more suited to the way procs works, I create a process for each chunk right away. For the given dataset, 4 worker processes are running on my 2 CPU cores.
In my version, all of Fredrik’s parallelization code is taken out, and replaced with:
import procs from functools import partial result = procs.pmap(partial(process, FILE), getchunks(FILE, 50*1024*1024))
Notice how nicely functional code can be parallelized—my wide finder can be converted to a serial finder by changing the above lines to:
from functools import partial result = map(partial(process, FILE), getchunks(FILE, 50*1024*1024))
If you have some serial code like this, procs might be able to easily widen it.
Procs doesn’t handle exceptions yet. If a child process fails, it zombifies with no indication that anything went wrong.
There are probably other bugs. Please tell me.
- It works!
- It’s not the answer for all concurrency problems, but it’s a nice way to introduce some map/reduce-style parallelization on a medium scale (one machine, but non-trivial).
- Don’t use procs for anything real until exception handling works.
If you are interested in procs, please email me or leave comments with bug reports, patches, and such. I don’t know enough about this problem to put out something I’d call 1.0 by myself, but if Open Source Happens, I think we could have something good.
Update 2007-10-11: Exception handling added.
This PEP proposes to introduce a syntax to declare the encoding of
a Python source file. The encoding information is then used by the
Python parser to interpret the file using the given encoding.
I wonder if this will work:
#!/usr/bin/env python # coding: rot-13 vzcbeg flf qrs uryyb(jbeyq='World', svyr=flf.fgqbhg): cevag >> svyr, 'Hello', jbeyq PNGPU = h'''Havpbqr fgevatf ner nyfb ebg-13, ohg olgr fgevatf ner whfg olgrf, fb ner abg rapbqrq nybat jvgu gur bgure fbhepr pbqr.''' uryyb() uryyb(h'Oehab') cevag PNGPU
Yes, you can write Python in rot-13, with one catch: strings are just bytes, so they don’t get encoded. Unicode strings are encoded with the rest of it.
That’s sufficiently murky. Next order of business is to write even more obscure code:
#!/usr/bin/env python # coding: base64 cGFzcw==
Rats! Even though
'whatever'.encode('base64') is perfectly valid Python, this didn’t fly. Given what I saw from the rot-13 example, I was interested to see how strings would work with base64 Python. Alas, even this simplest test, just the Python
pass statement, a no-op, was a syntax error.
Competent, my ass.