June 11, 2010

Threads in Java

"Dining Philosophers" problem solved with Java and Semaphores.

import java.util.concurrent.Semaphore;
import java.util.Random;
import java.util.Vector;

public class Philosopher extends Thread
{
    private static final Random rand = new Random();
    private static int event=0;
    private static String binary="";
    private int id;
    private Semaphore sem;
    private static Vector vector = new Vector();

    public Philosopher(int i, Semaphore s)
    {
        id = i;
        sem = s;
        binary = binary + "0";
    }

    private void busy()
    {
        try
        {
            sleep(rand.nextInt(1000));
        } catch (InterruptedException e){}
    }

    private void thinking()
    {
        String str = "Philosopher " + id + " is thinking";
        vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
        event++;
        busy();
    }

    private void eating()
    {
        String str ="Philosopher " + id + " is hungry and is trying to pick up his chopsticks";
        vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
        event++;
        busy();
        str = "Philosopher " + id + " is eating";
        this.oneToBinary(id);
        vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
        event++;
        busy();
        str = "Philosopher " + id + " finished eating, and puts away his chopsticks";
        this.zeroToBinary(id);
        vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
        event++;
    }

    private Object[] addToObject(long t, int i,String s ){
        Object[] o = new Object[4];
        o[3] = s;
        o[2] = i;
        o[1] = binary;
        o[0] = t;
        return o;
    }

    private void oneToBinary(int i){
        binary = binary.substring(0,i) + "1" + binary.substring(i+1);
    }

    private void zeroToBinary(int i){
        binary = binary.substring(0,i) + "0" + binary.substring(i+1);
    }

    @Override
    public void run()
    {
        for (int i = 0; i < 10; ++i)
        {
            thinking();
            try
            {
                sem.acquire();
            } catch (InterruptedException e){}
            eating();
            sem.release();
        }
    }

    public static void main(String[] args)
    {
        final int N = 5;
        Semaphore sem = new Semaphore(N, true);
        Philosopher[] philosopher = new Philosopher[N];

        // Start the philosophers
        for (int i = 0; i < N; i++) {
          philosopher[i] = new Philosopher(i, sem);
          philosopher[i].start();
        }
        // Wait for them to finish
        for (int i = 0; i < N; i++) {
          try {
            philosopher[i].join();
          } catch(InterruptedException ex) {
            return;
          }
        }

        for (int i = 0; i < vector.size(); i++) {
            Object[] o = vector.get(i);
            System.out.printf("%d %d %s %s\n", o[0], o[2], o[1], o[3]);
        }
    }
}

June 8, 2010

Tip of the Day #2 - pointers

Remember
int* ptr;
*ptr = 10;
#but
ptr = new int;
#without ampersand and dereference !!

June 7, 2010

Constant pointers, pointers to constants ?

What is the difference between:
float fVar = 3.14;
const float* ptr1 = &fVar;
and:
float fVar = 3.14;
float* const ptr2 = &fVar;
? The first one is pointer to constant value, so we can't change the value of variable the pointer points to :
*ptr1 = 10;
The second one in contrary is a constant pointer to a value, and because of that we can't readdress it to point at different variable :
float fVar2;
*ptr2 = &fVar2;

June 3, 2010

Django Contrib Revealed - Flatpages

Very often while creating big portals there are static pages just wasting your time to be created. Django has a solution for this problem also - the Flatpages application inside Contribution package. This application allows you to manage such static pages from django-admin, and it let's you create templates using Django's template system. How to get started ?
- Add 'django.contrib.flatpages' to INSTALLED_APPS. Also you need to have django.contrib.sites activated since flatpages depend on this package.
- Add 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware' to MIDDLEWARE_CLASSES.
This is how the flatpage model looks like :
from django.db import models
from django.contrib.sites.models import Site

class FlatPage(models.Model):
    url = models.CharField(max_length=100, db_index=True)
    title = models.CharField(max_length=200)
    content = models.TextField(blank=True)
    enable_comments = models.BooleanField()
    template_name = models.ChorField(max_length=70, blank=True)
    registration_required = models.BooleanField()
    sites = models.ManyToManyField(Site)
Okay so everything looks clear here I guess. For every flatpage we can specify either custom template, or use flatpages/default.html template (still creating the default template is also our responsibility !). Flatpage templates get a single context variable passed - flatpage, so we can use the Flatpage object's fields ie. {{ flatpage.title }}, {{ flatpage.content }}. Simple, but can spare lots of time :)

May 28, 2010

Django Contrib Revealed - Sites

Ok so the first element from django.contirbution I'm goin to write here about will be Sites package. What is Sites used for and what it's all about anyway ?
Let's say you have two sites connected together and sharing one database (i.e. community portal, and news site). You're using one login and authentication system there, one folder with uploaded pictures but different views for sites and different templates.
In settings file, community site has ID of 1 and news site's ID is equal to 2. How we would now build shared News model for both sites ?
from django.db import models
from django.contrib.sites.models import Site
from django.contrib.sites.managers import currentSiteManager

class News(models.Model):
    title = models.CharField(max_length=100)
    # ...
    site = models.ForeignKey(Site)
    objects = models.Manager()
    current_site = CurrentSiteManager()
As we can see from the code, we must add a field related to Site model in our class declaration (in this example it is many-to-one relationship). We can also notice two managers. The default objects is well known to us. It just serves .objects.all() . And for the second one it's a built in manager for serving objects specific to each site. So now News.objects.all() gives us all news (for example to feeds), and News.current_site.all() will return only News from current site. One thing to remember is that if our site-related field has different name than 'site' in CurrentSiteManager we need to specify this handler :
current_site = CurrentSiteManager('site_related_field')
And now for the views :
from django.conf.import settings

def simple_view(request):
    if settings.SITE_ID == 1:
        # code here
    else:
        # code here
But as you can see it's not the cleanest solution. It would be better if we had current site stored somewhere for the future use. Also, there is no need for refering to settings each time, because every Site model has a method .get_current() :
from django.contrib.sites.models import Site

def simple_view(request):
    current_site = Site.objects.get_current()
    #here we're using one of Site models field - domain.
    if current_site.domain == 'example.com':
        #code here
    else:
        # code here
Just to finish things up. Other field of Site model is name (which returns name of current site). And if you still prefere to use settings instead of get_current method, here's the code for that :
from django.conf import settings
from django.contrib.sites.models import Site

def simple_view(request):
    current_site = Site.objects.get(id=settings.SITE_ID)
    #here we're using one of Site models field - domain.
    if current_site.id == 1:
        #code here
    else:
        # code here
stat4u