Django captcha app

Thousand thanks to Martin Winkler for making an ultra-useful captcha app for django here. It’s super-easy to use although if you want to use it with Django 1.1 you need to modify it first.

I made the patch for Django 1.1 compatibility, which can be downloaded here.

I also made some other patches to remove md5 deprecation warning (here) and to fix a font-loading bug if you use the app with Subversion/git/some other VCS (here).

UPDATE: It seems that Martin’s site does no longer exist, so I put the Martin’s originals along with all my patches on github.

Understanding Currying with Scala

The first time I learned about currying is when I tried Haskell. Back then, I thought that currying is just a gimmick, nice but has no practical use. How wrong was I. Of course, Haskell code examples must be glaringly showing me some cool uses of currying back then. It must be me who was lost, too busy trying to grasp the unfamiliar syntax and missed the lights.

Then, several days ago I started to play with Scala. Actually the first time I encountered Scala was even before that, but my first impression was, well, unimpressed, just because I saw type declarations scattered here and there (yes, I’m a duck-man). Fortunately for the second “date”, I was able to see through those nasty ugliness (I insist :p).

The following code is taken from Scala by Example, a quicksort implementation:

<code>
def sort(xs: Array[Int]): Array[Int] = {
    if (xs.length <= 1) xs
    else {
        val pivot = xs(xs.length / 2)
        Array.concat(
            sort(xs filter (pivot >)),
            xs filter (pivot ==),
            sort(xs filter (pivot <))
        )
    }
}
</code>

The line 6-8 provoked my thought:

<code>
    sort(xs filter (pivot >)),
    xs filter (pivot ==),
    sort(xs filter (pivot <)))
</code>

That’s, like, ultra-neat! At first I thought it was just syntactic sugar, but how does it work? Well it does involve syntactic sugar: in scala, xs filter something is syntactic sugar for xs.filter(something). OK but how about the something part? It turned out that in Scala many operators are actually method, so x < y is really x.<(y). Neat. One puzzle remain: the pivot <, pivot ==, and pivot >. Another syntactic sugar? I thought so, but I couldn’t find the explanation. It looks unfinished. Yeah, like missing the argument. Like, wait, what was that gimmicky thing I in Haskell again?

Whoa, currying!
That partially-applied-function-returns-function thing!

So, pivot < means pivot.<() and since < needs one argument but given none, it instead returns another function that accepts the missing argument: the number to be compared. So the something given to filter is a function. Now that makes sense. Puzzle solved. Scala is cool.

And currying rocks!

Calculating Combinations in Erlang

One day, I tried to solve some problems on Project Euler that involve combination. I did it using erlang and produced a nice “by-product” in the form of erlang function that generates combinations of all elements in a list.

Here it is:

combos(1, L) -> [[X] || X <-L];
combos(K, L) when K == length(L) -> [L];
combos(K, [H|T]) ->
    [[H | Subcombos] || Subcombos <- combos(K-1, T)]
    ++(combos(K, T)).

combos(L) ->
    lists:foldl(
        fun(K, Acc) -> Acc++(combos(K, L)) end,
        [[]],
        lists:seq(1, length(L))
    ).

Explanation:

Choosing one item from [a b c] gives us choices of [a] [b] or [c]. So for 1-combination:
combos(1, [a,b,c]) = [[a],[b],[c]]

combos(1, L) -> [[X] || X <-L];

Next, choosing 3 items from [a b c] gives us only one choice: [abc]. So, for K-combination where K equals length of the list:
combos(3, [a,b,c]) = [[a,b,c]]

combos(K, L) when K == length(L) -> [L];

Now, choosing 3 items from [a b c d e] gives us these choices:
a and two more from [b c d e], plus
b and two more from [c d e], plus
c and two more from [d e].
combos(3, [a,b,c,d,e]) =
[a,b,d],
[a,b,e],
[a,c,d],
[a,c,e],
[a,d,e],
[b,c,d],
[b,c,e],
[b,d,e],
[c,d,e]]

combos(K, [H|T]) ->
    [[H | Subcombos] || Subcombos <- combos(K-1, T)]
    ++(combos(K, T)).

Finally, to get all combinations, simply do 1-combination through (list’s length)-combination:

combos(L) ->
    lists:foldl(
        fun(K, Acc) -> Acc++(combos(K, L)) end,
        [[]],
        lists:seq(1, length(L))
    ).

which gives final output:

combos([a,b,c,d]) =
[[],
 [a],
 [b],
 [c],
 [d],
 [a,b],
 [a,c],
 [a,d],
 [b,c],
 [b,d],
 [c,d],
 [a,b,c],
 [a,b,d],
 [a,c,d],
 [b,c,d],
 [a,b,c,d]]

 

I use empty list as starting accumulator for the reduce step because empty list is a valid combination (to choose none is a choice).

PS: Seth Ladd’s implementation here seems to perform faster especially on long list.

smtplib: SmtpServerDisconnected caused by too long [to_addrs]

One day my bulk-mailer python script threw (I mean raised) SmtpServerDisconnected error, it surely was smtplib’s “fault”. So I tried to make it send_mail only to my own address. The error gone. Means that it should be caused by it having too many recipients.

So instead of sending to [VeryLongList], i made it to send_mail for each in [VeryLongList] instead. And it successfully sent the spam notification mails.

Installing GIMP-Python on Windows

PhotoComix made an ultra-great package here. Great thanks! Read the detailed instructions there.

Here’s the summary:

  1. Download the PhotoComix’s package. While waiting for the download to finish, you can do step #2.
  2. Uninstall gimp if it is already installed.
  3. Extract the downloaded photocomix’s package.
  4. Install the python (python-2.5.2.msi)
  5. Reboot.
  6. Install the gtk (gtk-2.12.9-win32-1.exe)
  7. Install the pycairo (pycairo-1.4.12-1.win32-py2.5.exe)
  8. Install the pygobject (pygobject-2.14.1-1.win32-py2.5.exe)
  9. Install the pygtk (pygtk-2.12.1-2.win32-py2.5.exe)
  10. Reboot. (yes, again)
  11. (Re-) install gimp.

Happy gimp-pythoning,

Slice Image using GIMP

  1. Put some guides on the image using Image*Guides (if there is no Guides on Image menu, you need to install gimp-python). Tips: you can use Rectangle Select first, then Guides*New Guides from Selection, add more as needed. When using Guides*New Guide, move your mouse to find out the coordinate on the bottom-left corner.
  2. Filters*Web*Slice (again, if it’s not there, install gimp-python).
  3. The created HTML is just snippet, not complete HTML. Use it as your starting point.

You can read the explanation of each option on Slice dialog box here.

Happy slicing,