A Few Words About Singapore, Lah

June 22nd, 2011

It has been nine months since I moved to Singapore and started working for BrandsFever. I remember my collagues taking me to dinner one day. They ordered Tom-yum for me and told me that this is all that I can eat from now on. That was a joke of course.

Singapore is a very expat friendly country. After 10+ years of living in İstanbul, it is almost effortless to survive here. The biggest difficulty I have faced is the cultural difference. I have grown up to believe that I was the eastern guy. Only after living here for a while, I realized that I was western. Without a doubt.

Communication is more indirect and subtle here. Our way of to-the-point talking usually goes overboard, fails to convey your message and you end up where you have started. This was quite frustrating for me at the beginning. I still haven’t mastered the art. But I have come to realize that I am just a guest here, a stranger and therefore I am the one who should learn and to adopt.

I have quoted a dialogue from Outliers below to give you a better idea of what I am writing about:

Kwacang (boss): It's cold and I'm kind of hungry.
(meaning: Why don't you buy a drink or something to eat?)

Mr. Kim (employee): How about having a glass of liquor?
(meaning: I will buy liquor for you)

Kwacang (boss): It's okay. Don't bother.
(meaning: I will accept your offer if you repeat it)

Mr. Kim (employee): You must be hungry. How about going out?
(meaning: I insist upon treating you)

Kwacang (boss): Shall I do so?
(meaning: I accept)

Also there are certain things that will probably catch you off-guard if you are unfamiliar with asian culture. In western world, no sometimes means yes. Here, yes sometimes means no. In fact, for me, yes has just been a polite no more often than not. Possibly because I am such an Ang mo.

Something interesting happened just this morning. When I was riding the elevator the gentleman told me it is floor 3, when it stopped the the third floor. This is kind of like a big gesture here, he saved me from the embarrasment. Because as it usually happens you dash out of the elevator and if it’s not the ground floor you make a fool of yourself. I think this elegance is the defining characteristic of the eastern culture.

Bookmark and Share

Drawing Gradients with PyGame

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

Morphing Characters In Real-life Footage

October 27th, 2010

If you have used Poser or Make Human you must have been bewildered by the power of expressiveness they provide. Just by moving a few sliders you can morph your model into a completely new character. (For those who are not 3D enthusiasts; modelling the changes manually would take hours instead of seconds)

Well, MovieReshape does the same thing on real-life footage. You can morph flesh-and-bone actors in-motion. Watch the video below and pay close attention to how it fits a mesh on the model.

Here is the paper from Max Planck Institute. And if you want to play with 3D morphing I suggest you try Make Human (open source).

Source: gizmodo.com

Bookmark and Share

I Am Discontinuing Telvee

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

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