Archive for the ‘Programming’ Category

Programming is Debating

Thursday, July 14th, 2011

Programming is human activity, but this image still has nothing to do with it.

How difficult is it to start programming? By starting I mean producing real code, be it a personal project or something you will get paid for. But it is not written for the purpose of learning.

Most of the readers of this blog are professional programmers. I am sure for many of you starting was quite easy and natural. But for a lot of people it is an extremely difficult obstacle. I know people, more than 50 people, who studied CS or CE in university but has never written any real code. They get anxious when the possibility presents itself.

The problem with the start is usually the false expectations about programming. There are certain myths about heroic programmers writing incredible programs in impossible conditions with little or no effort. This is of course bullshit. But I have witnessed again and again people setting their expectations about the experience of writing code by these absurd standards. The actual experience inevitably fails to deliver these expectations and the person gives up. This doesn’t have be so. Programming is supposed to be fun.

When we open a book and start reading, the words we see are unlikely the author’s original words. The original, raw content get edited before printing. It is an iterative process. I don’t want to get into the details about publishing1 but beginners should study this process carefully. Because the process of programming is same, sans the magic.

So the act of programming is also an act of debating. You debate with your tests using your code. When all tests pass, the debate is over. When you are making design decisions, no matter how small they are, there is a debate going on between the requirements, the resources and your professional judgement. Therefore it would be unreasonable to expect programming to be a smooth, frictionless process. If you want to start you should be prepared for it.

I would like to share a few pointers that I hope will make the start more predictable if not easier:

  1. Try to find a real problem to work on. Forget about educational/theoretical problems. Solve a real, practical problem. There is one extremely important thing to remember here; the scope of the project must be as small as possible. A series of 2-day projects are much better than a 2 week project.
  2. Start by documenting the usage of the code. Write an example script that imports your hypotetical code and uses its functionality. In other words; design top-down, program bottom-up.
  3. Then flesh out the structure. Create files, classes, functions, comments. Writing code is good for warming-up to write some code.
  4. Divide and conquer. Implement incrementally, accomplish one thing at a time. If a functionality is giving you hard time, try to write something that produces some results but not exactly what you expect. Then continue iterating until you get it right. Don’t wait for the programming muse to come and light the way. Sometimes you need to invent all the wrong implementations before figuring out the correct one.
  5. Never hesitate to ask for help. Programming is debating, why not introduce your peers and mentors into the process. If you are asking for help make sure you have a concrete question. Input, expected output and your current code is usually enough. Even when you don’t have a problem or question, share your work with others and try to get as much feedback as possible.
  6. Do your research. There is no getting around the reading. I would be lying to you if I said otherwise. If you want to win the debate you need to be well prepared. It may be a little overwhelming in the beginning. But as you build up your knowledge (and experience) you will enjoy reading more.

I hope these pointers are helpful. But I think the most important thing to remember is programming is not a mechanical process but it is very human, I call it a debate, some call it art.

1: Nor am I an expert on the subject.

Bookmark and Share

My PyCon APAC 2011 Presentation: Optimizing Media Performance with django_compressor

Tuesday, June 28th, 2011

I have given a presentation about django_compressor at PyCon APAC 2011. Slides are below for everyone to see:

Bookmark and Share

Drawing Gradients with PyGame

Saturday, November 20th, 2010

I have been learning myself some PyGame on my free time. Best way to learn new technologies, I believe, is to develop small project and doing a lot of reading. Everybody seems to agree on the former but most fail to put effort doing the latter.

I needed to draw gradients for the background of my little learning project. First I tried the naive approach: iterating over each pixel and setting the correct value. This takes forever as you could have guessed. I continued my research to find out the close connection between PyGame and NumPy. Yes, fast array operations. My gradient generating code using linspace and tile is below:

def generate_gradient(fromcolor, tocolor, height, width):
    channels = []
    for channel in range(3):
        fromvalue, tovalue = fromcolor[channel], tocolor[channel]
        channels.append(numpy.tile(numpy.linspace(fromvalue, tovalue, width),
                                                                  [height, 1]))
    return numpy.dstack(channels)

I create three 1D arrays for each channel and then tile them to get a 2D array. Then I stack those 2D arrays and get combined (r, g, b) values. Each 1D array contain values linearly sampled between given maximum and minimum values by linspace. I can then blip this array on a surface like this:

gradient = generate_gradient((63, 95, 127), (195, 195, 255), 1024, 600)
pygame.surfarray.blit_array(some_surface, pygame.surfarray.map_array(some_surface, gradient))

This works quite well. But I was curious whether there is a better method, so I did some googling. First I stumbled upon James Tauber’s gradient code. Arrays! I was a bit ashamed not remembering standard library had array module. James Tauber’s code builds an array with the correct values and then writes the image as a PNG file. It also has the ability to generate multi-gradients.

Then I found gradients package for PyGame. This package does much more than linear gradients. It creates a PyGame surface of 1 pixel thickness, fills it with the gradient values and then resizes it.

I made a small test to see which method runs faster. I had to strip file and compression related code from James Tauber’s gradient module. I run a simple method tha just generates a gradient image/array in memory and returns it 10 time, below is the average times:

  • 320×240:
    • numpy: 0.01469659805
    • array: 3.6310561180
    • pygame: 0.0069756984711
  • 800×600:
    • numpy: 0.1323119163
    • array: 19.9719331265
    • pygame: 0.0192141056061

Here numpy is my method above, array is the stripped version of James Tauber’s code and pygame is the gradiends package. If my benchmarking method doesn’t have dramatic errors fastest way to generate linear gradients is to fill a strip with correct values and then to resize it.

Now I’ll go back to work on my learning project.

Bookmark and Share

I Am Discontinuing Telvee

Thursday, September 2nd, 2010

Telvee was originally a Facebook app. It was Burak Büyükdemir‘s idea to create a virtual coffee reading app. Rakı Sofrası was super popular then. We have quickly built and deployed and getting some good results. But the competition wasn’t fair.

When I decided to give this software a fair chance to succeed on its very own domain the only question in my head was; will it pass the test of users? It doesn’t really matter what you have intended the users do with your application. What matters, first, is what they think they’d like to do with it and then whether or not they actually use it.

So I tried and I failed. Two main reasons of this failure are; technical deficiencies and the special way of interaction coffee reading is. Technical deficiencies is the easy one. I couldn’t devote enough time for telvee, especially lately. As a result it doesn’t even have basic stuff like e-mail changing or account deletion. This is 100% my fault. The second reason however is more complicated and there was not much I could do about it. Except one thing I will tell you at the end of this post.

Telvee didn’t pass the user’s test mainly because coffee reading is somewhat private. It’s more of a 1-to-1 communication, while all social applications1 are designed for 1-to-many communication. This was disastrous not only because of the lack of viral growth but also because of the reluctance of users to interact with other users.

An example image of coffee remains telvee generates

An example image of coffee remains telvee generates

I would like to thank everybody who participated and I hope you had some fun playing with it. Telvee domain will soon redirect to this post and I will probably not renew it next time.

I won’t be starting a new experiment soon. I will spend most of my time on my work. Hopefully I will be spending a little more time on free software projects. By the way I would like to note that Telvee has spawned a couple of Django apps: django-inviting & django-simple-friends.

Oh, and the thing I could do better about user experience was to be more agile. I should have either fixed the problem quickly or failed fast. I have no regrets though. This was a unique experience and I have learned a lot.


1: Yes, even the e-mail system and dating sites are designed for 1-to-many communication primarily in mind.

Bookmark and Share

How To Create A Debian VM With Qemu

Wednesday, July 7th, 2010

I would like to post my notes as a little tutorial here. I am usually using these virtual machines as cheap staging servers. The first part of this tutorial, you hopefully need to do only once: creating a fresh Debian system. In the second part we will build on this image to create many different servers.

Creating A Base Debian System

We will create a Qemu machine and install Debian Lenny on it first:

# Download Debian image
wget http://debian.osuosl.org/debian-cdimage/current/i386/iso-cd/debian-504-i386-businesscard.iso

# Create base VM image
qemu-img create -f qcow2 debian.qcow2 2G

Our disk image will have a 2 Gigabyte size limit. You can pick a different size if you need.

Now we need to power on our VM and install Debian:

# Install Debian
qemu -enable-kvm -k tr -cdrom debian-504-i386-businesscard.iso -hda debian.qcow2 -boot d

You don’t need to allocate a large swap disk, 128MB should do just fine for a file/web server. Also I wouldn’t bother creating a seperate partition for /home/.

Next let’s log in as the user (www here) we have created to make final changes:

# logged in as user
dpkg-reconfigure console-data
aptitude install ssh sudo
echo "www ALL=(ALL) ALL" >> /etc/sudoers

At this point you might want to take a backup of debian.qcow2. (Even though we will open it only read-only from now on)

Creating The Actual VM

To save time and space we will use copy-on-write disks and re-use debian.qcow2.

# Create the actual VM's disk
qemu-img create -f qcow2 -o backing_file=debian.qcow2 actual.qcow2

Actually we are done. You can log in to your VM using the following command and start installing/configuring/running:

qemu -enable-kvm -k tr -hda actual.qcow2 -net user -net nic \
                                         -redir tcp:5022::22 \
                                         -redir tcp:9080::80

A few things to note about the command above:

  • -enable-kvm is meaningful only if you have kvm kernel module installed. It improves performance a great deal, so it’s highly recommended.
  • You probably need to change -k tr according to your keyboard’s layout.
  • We are setting up two TCP redirections. 22 is for SSH and 80 is for HTTP. You can add more ports if you need.

Finally, I suggest you to prefer SSHing your VM instead of logging in directly:

# SSH into the VM
ssh -p 5022 www@localhost

I hope some of you find this useful.

Bookmark and Share