hasenj blog

Doing away with captcha

Posted in webdev by hasen on 19/09/2009

I don’t include any form of captcha in anything I develop, mainly because I never took the time to invest into figuring out how to do it. But also because I really *hate* captchas. Also, my audience is largely composed of non-geeks and a captcha would be too confusing. So for me, putting captcha is a no-no.

So what do I do? How do I get away with it? Some people have described methods that revolve around a combination of css/javascript:
Honeypot Captha, Javascript Captcha

The way I do it, is simpler in a sense; it doesn’t even have a concept of captcha. I simply do everything in javascript. There’s no submit button, so there’s nothing for bots to do anyway.

I use a regular button with an onclick event that’s attached to a javascript function.


function submit_form()
{
    jQuery.ajax({
            "type": "POST", // or GET, or even PUT or DELETE
            "url": 'action_url', // The url you wish to send the data to, the url you'd put in the "action" attribute on the form tag
            "data": jQuery("form#the-form").serialize(), // The data you'll send. You need to get the form somehow. Easiest way is to give it an id.
            "dataType": "json", // Only put this if the server sends the response in json format
            "success": function(data, textStatus) // server responded with http status 200
            { 
                // do success stuff, this is the happy case
            },
            "error": function(req, textStatus, errorThrown) // maybe HTTP 404 or HTTP 500
            {
                // something went wrong. let the user know, or something
            },
            "complete": function(req, textStatus) // This one always gets called anyway
            {
                // cleanup after yourself
            }  // careful: if you put a comma here, IE6 will fail
        });
}

At first glance this might not seem so simple, but if you’re doing everything as ajax, then this is just a natural part of it.

You can add action="javascript:return false;" inside the `form` tag, just in case.

The reason why spambots can’t get through is simple: they don’t know what to do. There’s no url in the “action” attribute on the form tag. There’s no submit button. Most importantly, most spambots don’t have javascript.

While it’s possible that some spambots will have javascript, they still won’t know what to do since there’s no submit button. They might try to guess what button to click, or maybe they’ll just click all of them, but that would still be easy to circumvent. You can add a hidden button (that regular users won’t see) that disabled the real send button, so if a spambot tries to click every button it finds, it would likely hit the wrong button and then never be able to send the form.

Though unfortunately, if someone is targeting your site specifically, this kind of thing won’t work.

Advertisements

Best way to get round edges in IE

Posted in webdev by hasen on 12/09/2009

I’m sure we’ve all struggled with it too much with this issue. IE just doesn’t support any css property to render round edges.

The best solution, ultimate best solution, it to just give up and let IE users see sharp edges. Of course, add the border-radius property to the css style sheet, maybe a future version of IE will support that property.

But yeah, save yourself and your audience all the trouble.

Any method to support round corners in IE6 will either result in a mentanence nightmare or a sub-optimal user experience. You’ll either create too much boilerplate code (nested divs, extra css, tables, etc) and/or the user will have to download extra data (javascript, background image, etc). You’ll possibly slow down the page too, if you have a script that injects the boilerplate code after the page loads.

Possibly related link:
http://giveupandusetables.com/

## EDIT

Actually, as it turned out, This is the best way to round cross-browser round corners: http://www.malsup.com/jquery/corner/

IE6 doesn’t run onclick events in “option” tags

Posted in webdev by hasen on 05/09/2009

You have an ajax drop-down menu, something like this:

 
  <select>
    <option onclick="do_fancy_stuff();">Fancy Stuff</option>
    <option onclick="do_cool_stuff();">Cool Stuff</option>
    <option onclick="remove_ugliness();">Remove Ugliness</option>
  </select>

Because you’re a sane human being, you don’t use IE6 as your browser, you only have it running inside a virtual machine called “winxp”, or something like that. When you want to test your page on IE6 you type “vboxmanage startvm winxp” on the command line.

Anyway, so you check your site on IE6 and you discover that selecting an item from the menu doesn’t do anything! You wonder why and you google it, and (you get here? naa) in my case I came across this: http://www.ozzu.com/website-design-forum/option-onclick-internet-explorer-t55560.html

It provides a good explanation but I don’t think the solution is the best out there. It pretty much requires re-writing everything and re-arranging your events so that what function to call depends on the index of the option.

Oh wait, did I mention what the problem is? IE6 doesn’t care if the option tag has an onclick event. The only way to make something happen when you select something from the list is to put an onchange event on the *select* tag. and you’ll have to use `this.selectedIndex`, or `this[this.selectedIndex]` to get the option that was selected. The suggested solution over there is to use a function that gets the index passed to it as an integer and then decide what to do based on the value of that integer. But that’s not really a good idea IMHO.

For me, the solution is quite simple:


  <select onchange="this[this.selectedIndex].onclick()"> {# gotta hate IE6 #}

This will force IE6 to activate the onclick event handler on the options (assuming they all have an onclick handler). The problem of course is that in Firefox this will run onclick twice. So, we have to put this inside some sort of a conditional structure that checks if we’re in IE6. My solution is basically this:


<script type="text/javascript">IE6 = false;</script>
<!--[if IE 6]> <script type="text/javascript"> IE6 = true; </script> <![endif]-->
<select onchange="if(IE6) this[this.selectedIndex].onclick()"> {# gotta hate IE6 .. even more now #}
    <option onclick="do_fancy_stuff();">Fancy Stuff</option>
    <option onclick="do_cool_stuff();">Cool Stuff</option>
    <option onclick="remove_ugliness();">Remove Ugliness</option>
 </select>

Of course, it’s best to put this snippet

<script type="text/javascript">IE6 = false;</script>
<!--[if IE 6]> <script type="text/javascript"> IE6 = true; </script> <![endif]-->

somewhere (in your setup) so that it’s included in every single page.

UPDATE:

Actually, it turns out this applies to all version of IE, not just IE6.

Strange hibernation problem in Xubuntu

Posted in linux by hasen on 31/08/2009

I’ve been having a problem with my xubuntu when it hibernates automatically after running out of battery power. The problem is, it doesn’t wake up properly. It gets stuck at some point, and it stops dead there.

Today when I woke it up I choose the recovery mode option from the grub menu so it shows the boot info in text mode (instead of showing the xubuntu splash). The last line before it locks up said:

Suspending console(s) (use no_console_suspend to debug)

So, I tried to hibernate manually and wake up with this option on. To be honest I didn’t really know how to “use” this option; I just wrote it in the grub loader in the spot where you can add extra parameters. This time it booted fine, but I got a feeling maybe it had nothing to do with that. So I hibernated manually again but this time let it wakeup normally; and it did. It woke up normally just find.

So, I figured the problem only happens when it automatically hibernates from low battery. I went to the xfce-power-manager preferences (by right clicking on the battery icon in the systray (notification area)) and tried to see if something is causing that. I noticed the monitor is set to turn off in 5 minutes when on running on battery power.

Well, it’s not just a turn off option. There are three settings for the monitor when running on battery power:


Stand by after: [ x minutes ]
Suspend after: [ x minutes ]
Turn off after: [ x minutes ]

They were all set to like 5 or 10 minutes. This smelled bad for me: how do I turn the monitor back on?? So I just disabled them all (by setting them to 0 minutes which means never).

Then I took let the laptop run on battery power until it ran out and hibernated itself. I plugged it back and woke it up, and it woke up just fine.

I think the culprit was these monitor settings which I turned off.

How I switched to linux

Posted in Uncategorized by hasen on 31/08/2009

I recently switched to linux, the story of how I switched is somewhat similar to how I switched from IE to firefox. At first, I just wanted to see what all this firefox fuss is all about, so I installed it and kept at the side, using it only from time to time to try and experiment with it. There were quite a few problems with it at the time, but it grew up alot since then. Over time I kept using it more and more and using IE less and less, until I made it my default browser.

With linux, I had a previous experiment with it about four or five years ago. At the time it was Fedora 3 or 4 (I forgot), and I had several driver problems. Overall it wasn’t polished enough for me. It was actually a pretty horrible experience and it made me hate linux and hate all those die-hard linux fans and their evangelism.

Recently though, I wanted to try linux once again. This time I chose linux mint. I heared alot about ubuntu but when I tried it in a virtual machine it looked ugly. The default theme is ugly. The default font rendering settings are ugly. The orange-brownish theme is ugly. It’s the opposite of modern: it’s the color of dust and sand for God’s sake!! What’s worse, it lacks essential things like mp3 codecs. It made me feel, dude, see, linux is still as cumbersome to use as ever. Why do they expect some one totally new to linux to be able to figure out on his own to type “sudo apt-get install ubuntu-restricted-extras” is beyond me. Linux Mint came with better defaults: it had the non-free extras out of the box. It also has a better default theme and color scheme.

So, after playing with it for a while inside a virtual machine, I decided to install it on my hard drive and have a dual boot system. Soon after, my windows install got hit by a virus. I struggled with it but I managed to remove it (to the best of my knowledge). However unfortunately (or fortunately) windows went into “OMG-NOT-GENUINE” mode and refused to do anything useful (restricted mode). I wanted to fix it but after a bit of a struggle, I thought to myself, you know what, screw you M$, I don’t want your OS.
Basically, after that I spent some time to get comfortable with my new Linux OS and familiarize myself with all the various UI aspects, etc. After a while, I finally decided to remove the “C:\Windows” directory, or, /media/disk/Windows, as linux refers to it ;)

And that’s how I moved to linux: windows got hit by a virus that rendered it unusable, and meanwhile I was getting familiar with linux. The virus came in just at the right time to finally force me to make the move.

Now, I can’t live without the genius package system from Debian. Truly one-click installation; nothing can beat that.

To setup a development environment in linux, it only takes a few packages. Suppose you want to develop an application in PyQt4. You need python and pyqt. No problem, look for the corresponding packages, it’s really easy :)
Want to do it in windows? Well, it’s not *that* easy. You have to manually download stuff and go through the installation. While the typical next>next>finish wizard is not that bad, it’s not very convenient having to go to 10 different websites and downloading 10 different installers. Sometimes there are no installers; for instance, setuptools for python 2.6 has no windows installer wizard.

Anyway, linux mint 7’s default setup wasn’t exactly what I wanted, but it was a decent starting point for me to go from it and customize my system the way I want to. I ended up installing xfce and using it as the default desktop environment. I also did away with the mint menu and the various mint tools. I essentially installed the xubuntu-desktop package. So now I refer to my linux as Xubuntu; not mint.

Why I won’t use D for my next project

Posted in hacking, rant by hasen on 11/08/2009

I used to follow the D programming language closely, I thought it has some really great ideas, and it could potentially replace C++,

I’ve had an idea for a new project for a while now, and I started working on a proof of concept, which I wrote in D, and while the language syntax is great, I’m afraid I’m going to have to switch to another language. Before I say why I won’t use D, I want to mention why I wanted to use D in the first place:

I considered using Python, but I want to create an application that’s usable by ordinary people who are not programming nerds. I know I can convert the project into a windows application with tools like py2exe, but that will create a huge executable; not a good thing.

C++ is too complicated, I just hate the language.
Java is too bloated and complicated, I hate the language, and its environment, and the monster that’s called Eclipse.

C is certainly a lot less complicated than C++, but it’s old and its age shows. Though still, I might end up using it.

D seems just perfect, the syntax is nice, build tools are nice, it should be able to produce a small executable, and working with it should be a pleasure.

BUT, here are the problems:

I put a lot of effort into creating an environment for programming in D on windows. I downloaded DSSS and Tango, and also Tangobos. I also downloaded gtkD since I want a GUI for this project of mine. Setting these things up to work together is not exactly a very easy task; but still it wasn’t too difficult on windows. Though still, it’s not a very easy or pleasant task.

Recently I switched to Linux, and setting up a D environment in linux proved to be quite the hassle, that I essentially gave up on it. While I was able to install dmd with no problem, I didn’t know how to install DSSS. I tried with apt-get, but the DSSS I got expects to find gdc, when I have dmd.

Why is it so hard to setup a development environment for D? This is a problem, not only because it will cause me a headache, but it could put-off many potential/would-be contributors.

Also, I was considering switching from GTK+ to Qt, however the QtD project is also difficult to install, even on windows.

Above all, one of the main reasons I love(d) D is because its syntax and features and build system should theoretically make working with it a pleasure; but … it’s not a pleasure at all!! So why even bother? If it’s gonna cause more pain than pleasure, then I might as well work in C++, at least it’s well supported.

Do I wish to see D succeed? Yes.
Would I love to contribute to its success? Sure!
Am I gonna make sacrifices for it as if it was my religion? No.

I didn’t really explain in detail why installing D and setting up its dependencies is complicated, but those who’ve worked with it should have a good idea of why that is the case.

My entire point is: why the hell, after 10 years of development, is it still so dam hard to setup a D development environment on linux? Stop thinking about crazy new features for D2 and work on making sure that D1 (the original D) is well supported across-platforms. The way I see it, D is slowly turning into vaporware.

While this is an exaggeration, it will eventually die if the author(s) don’t make it their priority to make D usable with the least amount of hassle that’s possible, instead of cramming new features into D2.

Thoughts on the OOP and abstraction “crap”

Posted in rant by hasen on 05/07/2009

I used to believe firmly in Object Oriented Programming methedology, not because I’ve had any experience with it, but because the professor who taught my class about it sounded like he really knows what he’s taking about (I’m sure he does, and I still have a lot of respect for him).

However, judging from my own experience, OOP is not always the answer. Hell, it’s the thing to avoid most of the time!

Let me first explain what’s the OOP crap I’m talking about, because there are many definitions of what OOP is, so to make sure you’re on the same page as I am, OOP means:

– High cohesion: every class should be responsible for a single task only, and it should do it well.

– Low coupling: different parts of the application should not be highly coupled/interwined together.

Now, in principle, this is all well, but in practice, if you apply high cohesion, you end up with high coupling.

Think about it, if every class is so simple and so small, then every class is utterly useless by itself, because it doesn’t do anything! Therefore, to do anything useful, many objects must interact together. Even simple tasks become very complex.

Think about reading a file in Java, I’ve done it several times but I keep forgetting how to do it. What was it? First you create an object that reads chunks of a file as raw bytes, then you wrap it in a buffer, then a buffer reader, then a text buffer reader? or some nonsense like that.

That, my friends, is a Horrible Way To Program!

This is related to my previous rant about Django.

With everything chopped down into tiny simple classes, the task of adding new functionality becomes immensely complex, and also the act of changing an existing functionality. Because the interactions between objects are so complicated.

I’m not saying that you shouldn’t use abstraction, no, do it, but do it sanely. Do make classes/function simple, but don’t make them dumb and useless. Make them simple to use, simple to read, to interface to, but don’t make them stupid.

Linus made a comment about micro-kernels, in which he describes why they are so damn difficult to implement: you don’t have a single thing that is a kernel, you just have many tiny components that do simple things, which results in a system that needs many complex interactions between these components, and that’s something that’s very hard to get right and very difficult to debug. (every wonder why the Hurd kernel is taking so damn long??)

That’s exactly what it is: if you simplify the individual components too much, you’ll get a very complex system that’s unmaintainable.

It’s better to start with something that “just works” even if it looks like spaghetti at first, as long as you keep refactoring, you can end up with a reasonable abstraction, where functions and/or objects are simple, but not too simple to the point of being utterly useless.

Making a fancy window in wxPython

Posted in hacking by hasen on 14/04/2009

I’m pretty much a n00b when it comes to GUI programming. The truth of the matter is, I *hate* to program a GUI by assembling its parts together inside code. I mean, things like:

  • prepare an app object
  • prepare a window object
  • prepare a panel object (or several thereof)
  • prepare a sizer (layout manager) object (or several thereof)
  • sepcify initial sizes and dimensions
  • bind events
  • etc etc ..

Of course, this is an excuse for procrastination.

Also the fact that there are several frameworks outthere (wxwidgets, qt, etc) cause further confusion.

Anyway, for varios reasons, I’m trying to experiment with wxPython (the python interface to wxWidgets). And also for some reasons which I won’t go through, I wanted to make a “fancy” sort of window (like launchy’s window):

  • Has round corners
  • Maybe some transparency
  • Draggable around
  • No standard windows frames, buttons, etc
  • always on top

I’ll go through making each requirement of those, but since I’m a n00b myself, and just started, maybe I’m doing something simple in an overly complex way, so please let me know if you spot such issues with this post.

I’ll start with the easier stuff: always on top, no frames buttons etc, and some transparency.

First of all, read ZetCode’s “First Steps” tutorial for a very basic structure of an “app” that consists of a single window (frame)

So, Here’s a basic “empty” application, with nothing more than a window.

import wx

class FancyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title='Fancy')
        self.Show(True)

app = wx.App()
f = FancyFrame()
app.MainLoop()

Note that we’re subclassing Frame. I suppose it’s also possible to achieve this functionality without subclassing it, but this is the way I’m doing it, so .. there.

The result is the following:

Empty normal window

Empty normal window

Nothing fancy yet.

Now, make it always on to, and without any borders or controls, it’s really simple: just supply a “styles” parameter to the frame constructor.

You can see a list of styles here: http://docs.wxwidgets.org/2.6/wx_wxframe.html

We’ll use these styles:

wx.CLIP_CHILDREN | wx.STAY_ON_TOP | wx.NO_BORDER | wx.FRAME_SHAPED

By simple specifying some style other than the default, we already lost all the default stuff (the title bar and the minimize/maximize/close buttons).

import wx

class FancyFrame(wx.Frame):
    def __init__(self):
        style = ( wx.CLIP_CHILDREN | wx.STAY_ON_TOP |
                  wx.NO_BORDER | wx.FRAME_SHAPED  )
        wx.Frame.__init__(self, None, title='Fancy', style = style)
        self.Show(True)

app = wx.App()
f = FancyFrame()
app.MainLoop()

So now we have .. nothing! Just a gray rectangle! You might wonder, how are we gonna close that? Well, for now you can use alt-F4

Let’s add transparency too, it’s just a single line of code:

self.SetTransparent( value )

The value is from 0 to 255, with 0 being completely transparent, and 255 being competely opaque. Let’s use 220

import wx

class FancyFrame(wx.Frame):
    def __init__(self):
        style = ( wx.CLIP_CHILDREN | wx.STAY_ON_TOP |
                  wx.NO_BORDER | wx.FRAME_SHAPED  )
        wx.Frame.__init__(self, None, title='Fancy', style = style)
        self.SetTransparent( 220 )
        self.Show(True)

app = wx.App()
f = FancyFrame()
app.MainLoop()

Now, we have a transparent gray box!

Well, it’d be nice if we can close it with somethign other than alt-F4. That’s simple, we’ll just need an event handler for keyboard events. We’ll also add a wx.FRAME_NO_TASKBAR style so our “fancy” window doesn’t appear on the task bar. (is that evil?)

import wx

class FancyFrame(wx.Frame):
    def __init__(self):
        style = ( wx.CLIP_CHILDREN | wx.STAY_ON_TOP | wx.FRAME_NO_TASKBAR |
                  wx.NO_BORDER | wx.FRAME_SHAPED  )
        wx.Frame.__init__(self, None, title='Fancy', style = style)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
        self.SetTransparent( 220 )
        self.Show(True)
    def OnKeyDown(self, event):
        """quit if user press q or Esc"""
        if event.GetKeyCode() == 27 or event.GetKeyCode() == ord('Q'): #27 is Esc
            self.Close(force=True)
        else:
            event.Skip()

app = wx.App()
f = FancyFrame()
app.MainLoop()

So now there’s no taskbar, and q or Esc can quit.

Now we want to be able to move it around by just dragging it with the mouse. Again, we need an event handle for mouse movements. Dragging is really simple: when we start dragging, we record the relative position of the mouse. While we’re draging, we move the window so that the relative position of the mouse always stays the same.

There are several ways to implement this, I’ve seen code that uses two handlers: one for when the mouse is clicked, another handler for when moving the mouse. for me, I find it simpler to handle it all in one function that handles wx.EVT_MOTION, here’s the handler: (note that the event recieved is a MouseEvent )

#in ctor
        self.Bind(wx.EVT_MOTION, self.OnMouse)
#in class def:
    def OnMouse(self, event):
        """implement dragging"""
        if not event.Dragging():
            self._dragPos = None
            return
        self.CaptureMouse()
        if not self._dragPos:
            self._dragPos = event.GetPosition()
        else:
            pos = event.GetPosition()
            displacement = self._dragPos - pos
            self.SetPosition( self.GetPosition() - displacement )

This will make the window draggable.

So far, this is what we have:

import wx

class FancyFrame(wx.Frame):
    def __init__(self):
        style = ( wx.CLIP_CHILDREN | wx.STAY_ON_TOP | wx.FRAME_NO_TASKBAR |
                  wx.NO_BORDER | wx.FRAME_SHAPED  )
        wx.Frame.__init__(self, None, title='Fancy', style = style)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
        self.Bind(wx.EVT_MOTION, self.OnMouse)
        self.SetTransparent( 220 )
        self.Show(True)

    def OnKeyDown(self, event):
        """quit if user press q or Esc"""
        if event.GetKeyCode() == 27 or event.GetKeyCode() == ord('Q'): #27 is Esc
            self.Close(force=True)
        else:
            event.Skip()

    def OnMouse(self, event):
        """implement dragging"""
        if not event.Dragging():
            self._dragPos = None
            return
        self.CaptureMouse()
        if not self._dragPos:
            self._dragPos = event.GetPosition()
        else:
            pos = event.GetPosition()
            displacement = self._dragPos - pos
            self.SetPosition( self.GetPosition() - displacement )

app = wx.App()
f = FancyFrame()
app.MainLoop()
Transparent Draggable "window" with no titlebar or taskbar button

Transparent Draggable Gray Box

The snapshot doesn’t make much sense, but it’s there for completeness’ sake.

Now the part that’s a bit tougher and more problomatic: giving it a decent shape.

We passed a wx.FRAME_SHAPED style to the wx.Frame ctor, so that we can set the frame’s shape. To set the shape, we call SetShape and pass it a Region object. We want to construct a region object that is basically a rectangle with round corners. The easiest way to set such a shape is from a bitmap. We can get such a bitmap from an image file, but that’s not the only way. Infact, I specifically want to be able to do that without any external media file. I asked on stackoverflow but no one gave me an answer, so I had to dig on my own.

So we need a bitmap of a roned-corner rectangle, where do we get that without a file? Well, I found that you can draw a bitmap without a file using a MemoryDC. Basically, you bind the memory dc to an empty bitmap, draw some stuff on the memorydc, then when you unbind it from the bitmap, all the stuff that we drew will be on the bitmap. All DC objects had a DrawRoundedRectangle method.

So, now we can get a bitmap object that has a rounded rectangle drawn on it. To get that into a shape (region), we must first set a color mask for the bitmap, where the areas that have the color mask are to be transparent, and thus not part of the region.

The process to get that shape involves quite a bit of code, so we’ll put it into its own function, which takes a width, height, and radius:

def GetRoundBitmap( w, h, r ):
    maskColor = wx.Color(0,0,0)
    shownColor = wx.Color(5,5,5)
    b = wx.EmptyBitmap(w,h)
    dc = wx.MemoryDC(b)
    dc.SetBrush(wx.Brush(maskColor))
    dc.DrawRectangle(0,0,w,h)
    dc.SetBrush(wx.Brush(shownColor))
    dc.SetPen(wx.Pen(shownColor))
    dc.DrawRoundedRectangle(0,0,w,h,r)
    dc.SelectObject(wx.NullBitmap)
    b.SetMaskColour(maskColor)
    return b

def GetRoundShape( w, h, r ):
    return wx.RegionFromBitmap( GetRoundBitmap(w,h,r) )

Now, we have a region, we need to apply it to the window. To do that, we have to call SetShape, but apparently there’s a little trick involved in order to achieve cross-platformity. In windows, we set the shape in the constructor, while in GTK we set it on the event of the window creation.

#in ctor:
        if wx.Platform == '__WXGTK__':
            self.Bind(wx.EVT_WINDOW_CREATE, self.SetRoundShape)
        else:
            self.SetRoundShape()        

#in class body:
    def SetRoundShape(self, event=None):
        w, h = self.GetSizeTuple()
        self.SetShape(GetRoundShape( w,h, 10 ) )

So there, this makes the window rounded. Note however that we hard-coded the radius of the rounded corner, which is generally a bad idea.

Round corners (somewhat rough)

Round corners (somewhat rough)

The problem is that the edges are rough, I don’t know how to properly fix this, so I’ll try to hide it by drawing a border.

We’ll need to handle Paint events and draw whatever we want in there:

For painting, we just get a PaintDC to the window, and draw a rounded rectangle on the entire window with a pen (border) and a brush (backgrond)

#in ctor:
        self.Bind(wx.EVT_PAINT, self.OnPaint)
#in class body:
    def OnPaint(self, event):
        dc = wx.PaintDC(self)
        dc = wx.GCDC(dc)
        w, h = self.GetSizeTuple()
        r = 10
        dc.SetPen( wx.Pen("#806666", width = 2 ) )
        dc.SetBrush( wx.Brush("#80A0B0") )
        dc.DrawRoundedRectangle( 0,0,w,h,r )

The GCDC makes the drawing anti-aliased. (I tried to use it when making the shape but it didn’t work, or I didn’t know how to properly make it work).

For an additonal touch, we’ll call SetPosition() so the window starts somehwere in the middle of the screen rather than the top left corner

import wx

def GetRoundBitmap( w, h, r ):
    maskColor = wx.Color(0,0,0)
    shownColor = wx.Color(5,5,5)
    b = wx.EmptyBitmap(w,h)
    dc = wx.MemoryDC(b)
    dc.SetBrush(wx.Brush(maskColor))
    dc.DrawRectangle(0,0,w,h)
    dc.SetBrush(wx.Brush(shownColor))
    dc.SetPen(wx.Pen(shownColor))
    dc.DrawRoundedRectangle(0,0,w,h,r)
    dc.SelectObject(wx.NullBitmap)
    b.SetMaskColour(maskColor)
    return b

def GetRoundShape( w, h, r ):
    return wx.RegionFromBitmap( GetRoundBitmap(w,h,r) )

class FancyFrame(wx.Frame):
    def __init__(self):
        style = ( wx.CLIP_CHILDREN | wx.STAY_ON_TOP | wx.FRAME_NO_TASKBAR |
                  wx.NO_BORDER | wx.FRAME_SHAPED  )
        wx.Frame.__init__(self, None, title='Fancy', style = style)
        self.SetSize( (300, 120) )
        self.SetPosition( (400,300) )
        self.SetTransparent( 220 )

        self.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
        self.Bind(wx.EVT_MOTION, self.OnMouse)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        if wx.Platform == '__WXGTK__':
            self.Bind(wx.EVT_WINDOW_CREATE, self.SetRoundShape)
        else:
            self.SetRoundShape()

        self.Show(True)

    def SetRoundShape(self, event=None):
        w, h = self.GetSizeTuple()
        self.SetShape(GetRoundShape( w,h, 10 ) )

    def OnPaint(self, event):
        dc = wx.PaintDC(self)
        dc = wx.GCDC(dc)
        w, h = self.GetSizeTuple()
        r = 10
        dc.SetPen( wx.Pen("#806666", width = 2 ) )
        dc.SetBrush( wx.Brush("#80A0B0") )
        dc.DrawRoundedRectangle( 0,0,w,h,r )

    def OnKeyDown(self, event):
        """quit if user press q or Esc"""
        if event.GetKeyCode() == 27 or event.GetKeyCode() == ord('Q'): #27 is Esc
            self.Close(force=True)
        else:
            event.Skip()

    def OnMouse(self, event):
        """implement dragging"""
        if not event.Dragging():
            self._dragPos = None
            return
        self.CaptureMouse()
        if not self._dragPos:
            self._dragPos = event.GetPosition()
        else:
            pos = event.GetPosition()
            displacement = self._dragPos - pos
            self.SetPosition( self.GetPosition() - displacement )

app = wx.App()
f = FancyFrame()
app.MainLoop()
with color and border

with color and border

There you have it, it’s not quiet so fancy, but it should be a good starting point for adding more fancier stuff.

Vim through examples

Posted in hacking, tutorial by hasen on 11/04/2009

I’ve seen several people in varios places (specially stackoverflow) claim that vim increases their productivity by ten folds or whatever.

Now, I remember trying vim once or twice, and it drove me nuts. See, the thing is, with typical text editors, you type text and it’s there. But not so with vim.

In vim, to start typing yo must first press ‘i’ to go to “insert mode”. What a dumb idea, (one is forced to think), who would ever think of making a text editor that works like that? And so you just dismiss vim as an idiotic backward tool that’s still left over from the old days of terminals and main-frame: dumb keyboard, no mouse, dumb terminal screen (no colors!), etc.

But all these people saying that vim is so good, I mean, there must be something to it. So I started investigating into vim, and found this excellent article:

Why, oh WHY do those #?@! nutheads use vim?

Please go and read it! I can’t stress enough how good it is. I mean, FINALLY vim makes (at least) some sense.

The killer in that article are the couple of examples that it presents. *That’s what bought me into vim*. Examples are also a great way of learning something complicated like vim.

I mean, sure, you can google “vim tutorials” and find tons of “manuals” that explain what each key does. But that’s the /booooring/way of learning.

What I like instead is an interactive learning by example. It gives you first hand experience, withot delays, and helps your brain absorb the different concepts step by step (incrementally) by actually applying it directly, as opposed to holding it in your brain (or on a piece of paper, if you like taking notes, which I sorta doubt).

I also found this tutorial where the author pasted his irc chat log where he teaches someone how to edit with vim by example. I also found his tutorial very good.

Since I’m myself starting to learn vim and try to work with it, I thought I’d share my experience and present what I learn as a “vim by example” tutorial (or series of tutorials).

For completeness’ sake, I’ll steal some key points from the “nutheads” article.

The foundational concepts:

The first thing you need to understand about vim is that it’s different from typical text editors. The default mode is not “inserting text”, but “managing the text with commands”. You only enter “insert mode” briefly to insert text, then go back to command mode right away. Notice that “command mode” is called “normal mode”.

The second thing you need to know, is that everything in vim is designed so that you edit text without having to move your hand too much. Moving your hand too much means moving too far away from the “home raw” (the middle raw of the keyboard, asdf .. jkl;). For example, reaching for the mouse is “too much movement”, even reaching for the arrow keys is too much movement. You can do most of the editing tasks in vim without ever moving your right hand too much. The only extra movement that’s un-avoidable is reaching for the ctrl and shift keys. You might also need to reach for Esc, but it’s not unavoidable. (to change from insert mode to normal command mode, you either press Esc or `ctrl-[`, so as yo can see, you /can/ avoid reaching out for the Esc key.

Finally, you need to be fast with the keyboard, and be able to type without looking. You don’t really have to be a touch-typist (I am not anyway), but just be good enough with typing without looking too much (I still look when I type numbers).

Before we start, I want you to edit your vim settings file. On unix, that’s ~/.vimrc, on windows, it’ll be a file called _vimrc in the vim installation directory.

Add this line to what’s already in the file:
set tabstop=4 softtabstop=4 shiftwidth=4 expandtab autoindent cindent number
What is does is use spaces for tabs and makes it 4 spaces. I won’t go into why it does that (I don’t even really know myself, I just kinda googled it!) Also this will set auto indentation on (if it’s not on by default for some reason).  And finally this will make vim show line numbers.

Of course, since you’re just starting with vim (as I assume), you’ll need to edit that file with a text editor that you’re comfortable with, such as notepad++ or whatever else you’re using. Don’t try to be a smartass and use vim to edit that file!

For the rest of this tutorial, we’ll use a file that already has text in it and explore various ways to edit it using vim. Meaning we’ll not start from scratch.

So, first, opening and exiting vim:

I’m personally using gvim 7.2, so if you’re using that, open it from the start menu or using launchy or from your desktop shortcut, what ever. If you’re using the command-line version (please make sure it’s v7.2, not some 5.x or 6.x) then simpy type vim at the command line.

To quit vim right away, type :q!

: is used to enter text commands (different from the typical commands in command mode, and the text commands are referred to as Ex commands).
q is the command for quitting.
! means ignore unsaved changes.

So, the easiest way to quit vim at any time is to type :q! when you’re in command mode. If for any reason you’re not in command mode, just press Esc before typing that.

So if you’re following along but want to stop for some reason and quit vim, you know what to do.

For the purpose of this tutorial, create a text file that has the following text (again, create this file from an editor other than vim, such as notepad++):

//vim example
void main()
{
    std::cout << "ihello vimEsc" << std::end;
    return 0
}

I know there are errors there. It’s on purpose so we can correct them with vim! Now, go ahead an open that file with vim. Just type vim at the terminal followed by the file’s name (assuming you’re in its directory). If you see an empty file instead, that means you didn’t open the file, so quit vim and try again.

Moving around:

You’ll start with the cursor at the top, in command mode (normal mode).

Now, make sure your hand is rested on the home row, with the index finger of the right hand on the ‘j’ key. That key is used to move the cursor down. It’s the down arrow key :)

It may seem weird at first, but don’t we spend most of the time moving the cursor up and down? well, it’s right at your finger tips (literally!) j is down, and k is up. So move the cursor up and down, get yourself used to that.

Now, we want to include iostream library, which we “forgot”! So we need to open a new line below the “vim example” comment.

There are two ways to do that, let’s start with the dumb way:

go up to the first line, press `i` to enter insert mode, press End, then Enter, and start typing the include statement. When done, press Esc to go back to normal mode.

Now, press `u` to undo that, because we’ll do it again but differently.

Pressing End then Enter is the typical way to open new lines in typical text editors. In vim though, there’s a shortcut: press `o` to open a new line and enter insert mode. Now, type the include statement again and press Esc or ctrl-[ to go back to normal mode (command mode).

Or, you can also open a line “above” where the cursor is, using `O` (capital o). You’ll find this pattern repeated through out other commands, where the capital letter does something similar but in reverse or something.

Now, to move left and right, you can use `l` and `h`, but that’s boring and stupid. better use `w` and `b` which move by words.

w moves a word forward
b moves a word back

Try it now, move arond with w and b. Get used to it for a bit.

now, we want to change that void main to int main. so go to that line (with k and j ), move the cursor to the beginning of the line with 0 (zero), and type (in command mode) cw

cw means “change word”. It will delete the word under the cursor and put you in insert mode.

Now, type `int` and press Esc or ctrl-[ to go back to normal mode.

Commands and motions:

What you saw just now is an example of motions and commands that act on motions.

j, k, l, h, w, b are motions. They move the cursor to a new place.

c is a command (change) that acts on motions. When you press c, vim waits for you to tell it which motion to use for it.

The change command, like I said, deletes the text that you moved over with the motion, and puts you in insert mode.

See, if you are standing at the beginning of the phrase “void main”, and press w, the cursor would move to the location of “m”. The cursor moved over the word “void “. So, cw changes that block of text that the cursor moved over.

This is somewhat of a simplification, as it doesn’t always work like this. For instance, cj will delete the current line and the line below it *entirely*, not just from where the cursor was to where it would’ve been by pressing j alone.

Going in insert mode:

As you already saw, `i` is not the only way of entering insert mode. We saw that c{motion} also enters insert mode, after deleting a segment of text. and `o` also enters insert mode, after opening a new line.

Another way is `a`, which enters insert mode after moving the cursor one step forward. You can think of it as inserting “after” the cursor position.

`A` (capital a) moves the cursor to the end of the line and enters insert mode from there. We’ll use this to add the missing semicolon from “return 0”. So, go to the line that says return 0. For fun, move the cursor to the beginning or middle of the line (using h or w) just in case it already was at the end of it.

Now, press `A`, then `;`, then ctrl-[

I hope you’re following along, because it’s pointless to just read this without doing it.

Repeating commands and motions:

Motions can be repeated. For instance, 3w will move the cursor 3 words forward. Also, c2w will change two words.

I’ll list a coupe of extra commands (we won’t be using them right away, but just so you know them):

d is like c, but it doesn’t enter insert mode; it just deletes the segment.

cc will change the entire line, and dd deletes the entire line.

Actually, cc and dd don’t just “delete” the stuff, they also copy it.

You can copy stuff without deleting it, using y. (y stands for yank, which is vim-jargon for copy).
y works just like c and d, but it doesn’t delete the text; just copies it. You can paste it using p. (more on that later inshallah)

2dd will delete 2 lines
5yy will copy five lines
y5w will copy five words

Another command that can be “repeated”: {number}G will go to the line number

3G will go to line 3

:3 also goes t line 3 (in this case it’s not a repeat, it’s an Ex command .. I think so anyway)

pasting can also be repeated:
3p will paste the copied text three times

Going directly to where you want:

Suppose you’re looking at the hello vim string “ihello vimEsc”, and you want to capetalize the h in hello so it becomes Hello

simple, go to the line that contains it (I have it as line 6) by pressing 6G,or :6, or just with j and k,  then go the start of the line, using 0

Now, press `fh`, which means “find h”. This will find the first occurance of the letter h and move the cursor to it. If you happened to have another h before where you want to go, you can repeat this “find” using the semicolon ; which repeats the last `f` motion.

Now, your cursor is on h in ihello, to capetalize it, press the tilde ~ button. This will toggle the case of the letter under the cursor and move the cursor forward. (notice that you didn’t even need to enter insert mode!). This is also repeatable, so 3~ will toggle the case of the next three letters.

F will do the same as f but backwards. Meaning search backward to the first occurance of character c.
t is similar to f but it stops right before the character. T is the same but backwards.
`;` will repeat the last such motion like I already said
`,` will repeat the motion in reverse. So if you did `fh`, then `,` will search backward for h

Saving:

So maybe you know feel like you want to save this file, sure, just type :w in command mode. w is the Ex command for saving, it stands for “write”.

Summary so far:

jkhl — basic navigation
wbe — word level navigation
d/c/y{motion} — delete/change/copy text
p — paste text
u — undo
ctrl-r — redo (I forgot to mention this! oh well)
~ — toggle case
0 — go to line beginning
$ — go to line end
{number}G — go to line number

This is the end of the first part of this tutorial, I hope (inshalla) that other parts will follow soon.

Tagged with: , ,

The problem with Django

Posted in webdev by hasen on 11/04/2009

Frameworks speed your development time at first, but then you often hit a wall. The framework doesn’t do what you want and you have to dig into its internals to figure out how to do what you want, which is often more difficult than writing your own framework from the ground up. — Cal Henderson, Flickr’s Engineering Manager, at a django conference

In many ways Django reminds me a bit of unpacking cool stuff. You download it and are instantly blown away how cool it is. Database just works, templating is awesome, URL routing gives you these incredible neat looking URLs and much more. It’s so cool that many are trying to suddenly do everything with it. And that’s kinda where the problem lays. You are forcing Django to do things it’s not designed for. — Armin Ronacher, in a blog post

I’ve been using Django for about, almost two years, and I came to the same conclusion. Django is amazingly awesome at first, but not so awesome in the long run.

The reason Django is so amazing at first is that it relieves you from having to do the stupid repetitive tasks involved in writing a typical php app: writing an admin interface, writing a class that maps to your db table, and doing all the mappings manually. I’ve had little experience writing a mini-blog like website using php, and it was an exciting experience to build my first web-app ever (it was a school project). However, even though it was exciting, I also didn’t like the thought of having to repeat all that redundant work all the time, so in that regard finding Django was a big relief.

However this awesomeness doesn’t last so long. Soon enough the requirement get complicated, and Django doesn’t wanna do what you want it to do anymore. You’re forced to either wrestle with it, or implement the requirments completely outside django, which kinda defeats the point.

It’s a Framework!

See, one of Django’s problems is that it tries to do everything for you, forcing you in the meantime to adapt to its way of doing things, instead of it adapting itself to you.

Django has an (awesome, btw) automatically generated admin site, and as awesome and incridible as it is, it’s suitable only for data entry. It relieves you from the initial effort of writing the admin interface. You can get started with a simple application by just specifying the models and writing a couple of simple templates, without ever worrying about SQL or writing (an) Admin page(s) for entering you data. But is that really so great? I mean, it gives you a relief in that you don’t have to do it, but at the same time, it’s so simplistic, it’s not the kind of thing that’s suitable for all situations; infact it’s quiet unsuitable for most situations.

I’m writing this blog post right now in wordpress. Have you seen the admin interface? It’s so great, but .. it’s all written in php! Django’s admin interface can never ever come close to this. No matter how much you try to customize it (and there isn’t that much to customize anyway). Of course you can build one from scratch, (in python), but then what’s the point of doing this inside a Django framework? See, when you start doing things outside Django, you realize that you don’t even need django. Not only that, but Django will get in your way because you can’t just do what yo want, you have to do it in a way that pleases Django.

Remember the first quote above from Flicker’s manager? It speeds you up at first, but then you hit a wall and you have to start from scratch again.

I’ve done an ajax admin interface to some application (that shall remain anonymous), and I didn’t use one bit of Django’s forms framework. Why? Because I don’t need to. It’s much easier to write my own forms in html, and my own validation functions, than to constrain my self to the framework.

I kinda forgot t mention this but (as you might have guessed already): Django has a forms framework. I’ve never looked deeply into it, but I can tell it suffers the same issues as the admin interface: it make so many assumptions about your workflaw, and forces you to adapt to /its/ workflow, instead of it adapting itself to yours. Plus, forms are relatively simple to write in plain html (and much easier to customize when you write them that way), why should I spend time to learn a complicated Forms framework? Is it worth it? I doubt that.

The same thing can be said about the template system, and the crazy idea that you have to write a costum tag (read: lexer and parser) for every extra little thing you need. Thank God there’s Jinja!

Anyway I don’t think I need to talk about the pitfalls of Django’s template system much, it’s kinda obvious for anyone who’ve used it. I will just mention that I had *so much pollution* in my python code to cover up for the shortcoming of the template system, and even after I switched to jinja, some of that poison is still lurking somewhere, in some deep dark rusty corners of my code.

Of course, the auth and session middlewares suffer from the same thing: they’re awesome, but not really extensible. At least in the sense that it’d be much easier to roll your own solution from scratch than wrestling with the framework and digging into its internals.

Fragmentation

After a while of working on a website with several “apps”, you come to realize what a mess everything is. Everythign is torn apart. You can view the application as being composed of 3 basic parts:

  • python code
  • template files
  • media files

The media files can be broken down further into: images, javascript, and css; but let’s not get into that, as it’s outside the realm of Django.

The problem is that each of these components lives in a completely different planet. You have a directory for code, a directory for templates, a directory for media. Each directory is in a completely different place from the rest. When you need to make changes to an application, *you have to remember quite a lot of things*, if you *only* remember where each directory was, you’re already using 3 slots in your short term memory. It might not seem like much, but it does get daunting after a while. It becomes a wall that makes you go “oh no, I have to go through that again?”, pushing you to procrastinate, thus making you less productive.

Furthermore, the python code has to be further fragmented according to the specifications and expectations of the framework. You need a urls.py file, models.py, admin.py, views.py (and maybe you tag along with this idiom and create a forms.py, and maybe utils.py, or biznis_logic.py, or whatever)

So if your app has four components (in terms of models), then different pieces that deal with different aspects of each component are fragmented across these files.

Many kinds of changes to the code will require “shotgun surgery”; lots of little changes to lots of files.

This fragmentation is caused by the framework; because it *forces you* to layout all of your files in a certain way; it forces you to adapt to *its* work-flow.

What’s left?

So, so far I’ve dismissed the template engine, the forms framework, the admin interface, and the file layout.

What’s still remaining? The url-mapping, and the ORM.

Well, I recently learned about Werkzeug, so I don’t have to use Django for url-mapping. As for the ORM, there’s SQLAlchemy.

The thing that’s attracting me to Werkzeug is that it (by design) is anti-framework. I haven’t used it for real yet, but that’s the kind of impression it’s giving me.

As for the ORM, I think Django’s ORM is great, but if SQLAlchemy also solves the same problem, then I don’t have to stick to Django just for the ORM. Plus, SQLAlchemy is dedicated to being an ORM, while Django’s ORM is a part of a larger project, therefor I would assume that SQLAlchemy has a better chance of doing things right.

Things I’d like to keep from Django: the pagination module, and the email module; as python’s smtplib just sucks!

Tagged with: , ,