Posts de October, 2011

[Francisco Souza] Go solution of the Dining philosophers problem

Monday, October 31st, 2011

Solution for the dining philosophers problem using the Go programming language.

[Francisco Souza] Go solution for the Dining philosophers problem

Sunday, October 30th, 2011

I spent part of the sunday solving the Dining Philosophers using Go. The given solution is based in the description for the problem present in The Little Book of Semaphores:

The Dining Philosophers Problem was proposed by Dijkstra in 1965, when dinosaurs ruled the earth. It appears in a number of variations, but the standard features are a table with five plates, five forks (or chopsticks) and a big bowl of spaghetti.

There are some constraints:

  • Only one philosopher can hold a fork at a time
  • It must be impossible for a deadlock to occur
  • It must be impossible for a philosopher to starve waiting for a fork
  • It must be possible for more than one philosopher to eat at the same time

No more talk, here is my solution for the problem:

package main

import (    "fmt"    "sync"    "time")

type Fork struct {    sync.Mutex}

type Table struct {    philosophers chan Philosopher    forks []*Fork}

func NewTable(forks int) *Table {    t := new(Table)    t.philosophers = make(chan Philosopher, forks - 1)    t.forks = make([]*Fork, forks)    for i := 0; i < forks; i++ {        t.forks[i] = new(Fork)    }    return t}

func (t *Table) PushPhilosopher(p Philosopher) {    p.table = t    t.philosophers <- p}

func (t *Table) PopPhilosopher() Philosopher {    p := <-t.philosophers    p.table = nil    return p}

func (t *Table) RightFork(philosopherIndex int) *Fork {    f := t.forks[philosopherIndex]    return f}

func (t *Table) LeftFork(philosopherIndex int) *Fork {    f := t.forks[(philosopherIndex + 1) % len(t.forks)]    return f}

type Philosopher struct {    name string    index int    table *Table    fed chan int}

func (p Philosopher) Think() {    fmt.Printf("%s is thinking...\n", p.name)    time.Sleep(3e9)    p.table.PushPhilosopher(p)}

func (p Philosopher) Eat() {    p.GetForks()    fmt.Printf("%s is eating...\n", p.name)    time.Sleep(3e9)    p.PutForks()    p.table.PopPhilosopher()    p.fed <- 1}

func (p Philosopher) GetForks() {    rightFork := p.table.RightFork(p.index)    rightFork.Lock()

    leftFork := p.table.LeftFork(p.index)    leftFork.Lock()}

func (p Philosopher) PutForks() {    rightFork := p.table.RightFork(p.index)    rightFork.Unlock()

    leftFork := p.table.LeftFork(p.index)    leftFork.Unlock()}

func main() {    table := NewTable(5)    philosophers := []Philosopher{        Philosopher{"Thomas Nagel", 0, table, make(chan int)},        Philosopher{"Elizabeth Anscombe", 1, table, make(chan int)},        Philosopher{"Martin Heidegger", 2, table, make(chan int)},        Philosopher{"Peter Lombard", 3, table, make(chan int)},        Philosopher{"Gottfried Leibniz", 4, table, make(chan int)},    }

    for {        for _, p := range philosophers {            go func(p Philosopher){                p.Think()                p.Eat()            }(p)        }

        for _, p := range philosophers {            <-p.fed            fmt.Printf("%s was fed.\n", p.name)        }    }

}

Any feedback is very welcome.

[Francisco Souza] Go solution for the Dining philosophers problem

Sunday, October 30th, 2011

I spent part of the sunday solving the Dining Philosophers using Go. The given solution is based in the description for the problem present in The Little Book of Semaphores:

The Dining Philosophers Problem was proposed by Dijkstra in 1965, when dinosaurs ruled the earth. It appears in a number of variations, but the standard features are a table with five plates, five forks (or chopsticks) and a big bowl of spaghetti.

There are some constraints:

  • Only one philosopher can hold a fork at a time
  • It must be impossible for a deadlock to occur
  • It must be impossible for a philosopher to starve waiting for a fork
  • It must be possible for more than one philosopher to eat at the same time

No more talk, here is my solution for the problem:

package main

import (    "fmt"    "sync"    "time")

type Fork struct {    sync.Mutex}

type Table struct {    philosophers chan Philosopher    forks []*Fork}

func NewTable(forks int) *Table {    t := new(Table)    t.philosophers = make(chan Philosopher, forks - 1)    t.forks = make([]*Fork, forks)    for i := 0; i < forks; i++ {        t.forks[i] = new(Fork)    }    return t}

func (t *Table) PushPhilosopher(p Philosopher) {    p.table = t    t.philosophers <- p}

func (t *Table) PopPhilosopher() Philosopher {    p := <-t.philosophers    p.table = nil    return p}

func (t *Table) RightFork(philosopherIndex int) *Fork {    f := t.forks[philosopherIndex]    return f}

func (t *Table) LeftFork(philosopherIndex int) *Fork {    f := t.forks[(philosopherIndex + 1) % len(t.forks)]    return f}

type Philosopher struct {    name string    index int    table *Table    fed chan int}

func (p Philosopher) Think() {    fmt.Printf("%s is thinking...\n", p.name)    time.Sleep(3e9)    p.table.PushPhilosopher(p)}

func (p Philosopher) Eat() {    p.GetForks()    fmt.Printf("%s is eating...\n", p.name)    time.Sleep(3e9)    p.PutForks()    p.table.PopPhilosopher()    p.fed <- 1}

func (p Philosopher) GetForks() {    rightFork := p.table.RightFork(p.index)    rightFork.Lock()

    leftFork := p.table.LeftFork(p.index)    leftFork.Lock()}

func (p Philosopher) PutForks() {    rightFork := p.table.RightFork(p.index)    rightFork.Unlock()

    leftFork := p.table.LeftFork(p.index)    leftFork.Unlock()}

func main() {    table := NewTable(5)    philosophers := []Philosopher{        Philosopher{"Thomas Nagel", 0, table, make(chan int)},        Philosopher{"Elizabeth Anscombe", 1, table, make(chan int)},        Philosopher{"Martin Heidegger", 2, table, make(chan int)},        Philosopher{"Peter Lombard", 3, table, make(chan int)},        Philosopher{"Gottfried Leibniz", 4, table, make(chan int)},    }

    for {        for _, p := range philosophers {            go func(p Philosopher){                p.Think()                p.Eat()            }(p)        }

        for _, p := range philosophers {            <-p.fed            fmt.Printf("%s was fed.\n", p.name)        }    }

}

Any feedback is very welcome.

[Tiago Peczenyj] YAPC::Brasil 2011 Yet Another Perl Conference

Monday, October 24th, 2011

É com muita satisfação que venho anunciar que a grade de palestras do YAPC::Brasil 2011 já está no ar (minha palestra será sábado)!

http://www.yapcbrasil.org.br/2011/schedule

Esse ano o evento contará ainda com ninguém menos que *brian d foy* como keynote, em sua segunda visita ao Brasil! Brian é o criador da primeira comunidade Perl Mongers do mundo e autor/co-autor de diversos livros de Perl, como “Learning Perl” (o livro da lhama), “Mastering Perl” e “Effective Perl Programming”.

Demais palestras contém temas muito bacanas como Webdev, TDD, OpenData, JavaScript, Facebook e muito mais, em dois dias inteiros regados de palestras de qualidade para todos os níveis de conhecimento.

Mas… dois dias? Não eram três?

Sim, e essa é mais uma novidade: na sexta-feira, dia 4, teremos um mini-curso de UM DIA INTEIRO com o tema “Effective Perl Programming”, ministrado pelo próprio brian d foy!

http://www.yapcbrasil.org.br/2011/minicurso.html

Não fique fora dessa! As vagas são limitadas, então acesse o link e inscreva-se já!

[Igor Sobreira] Change object after saving all inlines in Django Admin

Wednesday, October 19th, 2011

Published on: 12/02/2011 11:45h

UPDATE Aug, 2011: This patch added a new hook to ModelAdmin called save_related(). Now you don’t the hack described bellow anymore.


Admin is an awesome Django builtin app to create nice CRUDs for your models, and offers a lot of customizations hooks. You can personalize the templates, perform custom filters, modify newly created objects and if that’s not enough, you can always create your own view to do something it doesn’t by default.

The admin docs are great, I’m not going to explain how it works. The intention here is to show a way to modify an object, after it’s saved, and other objects related to it using inlines are saved too.

Once you’ve configured your admin interface with inlines, you end up with something similar to:

from django.contrib import admin
from fooapp.models import Foo, Related

class RelatedInline(admin.TabularInline):
    model = Related

class FooAdmin(admin.ModelAdmin):
    inlines = [RelatedInline]

admin.site.register(Foo, FooAdmin)

this mean whens you’re adding a Foo, since Related has a foreign key to it, django will display a few forms to add Relateds in the same page.

Imagine you need to do something with the new foo instance that needs to now how many related objects it has. Admin already has methods you can override to do something after Foo is saved, like ModelAdmin.save_model(). See how it works:

class FooAdmin(admin.ModelAdmin):
    inlines = [RelatedInline]

    def save_model(self, request, obj, form, change):
        obj.save()
        # do something with obj.related_set.all()
        # OPS! it's empty!

admin.site.register(Foo, FooAdmin)

the problem here is that save_model() is called before the inlines are saved.

Let’s find out how it works. Open django source code, specifically in django.contrib.admin.options.py go to add_view(), it’s the view called when you are creating an object. As you can see, when the request method is “POST” it goes through all validation, for the main form and all related formsets (your inlines). And if all of then are valid it calls save_model(), then save_formset() for each formset. The interesting piece is shown below:

class ModelAdmin(BaseModelAdmin):

    # ...

    def add_view(self, request, form_url='', extra_context=None):

        # ... all validation here ...

        if all_valid(formsets) and form_validated:
            self.save_model(request, new_object, form, change=False)
            form.save_m2m()
            for formset in formsets:
                self.save_formset(request, form, formset, change=False)

            self.log_addition(request, new_object)
            return self.response_add(request, new_object)

Notice here that the last method it calls is response_add(), and it passes the created object, that’s all we need! If you see the change_view() method (witch it the view called when you’re editing an object) it calls a similar method: response_change().

Now we can solve our problem doing something like this:

class FooAdmin(admin.ModelAdmin):
    inlines = [RelatedInline]

    def response_add(self, request, new_object):
        obj = self.after_saving_model_and_related_inlines(new_object)
        return super(FooAdmin, self).response_add(request, obj)

    def response_change(self, request, obj):
        obj = self.after_saving_model_and_related_inlines(obj)
        return super(FooAdmin, self).response_change(request, obj)

    def after_saving_model_and_related_inlines(self, obj):
        print obj.related_set.all()
        # now we have what we need here... :)         return obj

There are two things to keep in mind when using these methods:

  • They are not documented. So probably it’s not part of the API admin expects you to override. Thankfully django publishes excellent release notes including backwards incompatible changes. And I hope you have good test coverage to know if it will break when you update django :)
  • Their intention is to handle the response of the view, as it docstring says: “Determines the HttpResponse for the add_view stage”. So if you do something there not related to it, it works, wont make much sense if you look at the overall architecture.

Maybe django will add a more specific hook to solve this issue later, but I hope it helps you for now.

By Igor Sobreira

[Igor Sobreira] Adding methods dynamically in Python

Wednesday, October 19th, 2011

Published on: 06/02/2011 20:50h

Given the dynamic nature of Python you can do many things in runtime, like add methods dynamically to an object or class. This is particularly useful when writing unit tests.

Here is the simplest way, adding a method to and object:

class Person(object):
    pass

def play():
    print "i'm playing!"

p = Person()
p.play = play
p.play()

note that play is just a function, it doesn’t receive self. There is no way to p knows that it’s a method. If you need self, you must create a method and then bind to the object:

from types import MethodType

class Person(object):
    def __init__(self, name):
        self.name = name

def play(self):
    print "%s is playing!" % self.name

p = Person("igor")
p.play = MethodType(play, p)
p.play()

In these examples, only the p instance will have play method, other instances of Person won’t. To accomplish this we need to add the method to the class:

class Person(object):
    def __init__(self, name):
        self.name = name

def play(self):
    print "%s is playing!" % self.name

Person.play = play

p1 = Person("igor")
p1.play()

p2 = Person("joh")
p2.play()

note that we don’t need to create a method with types.MethodType here, because all functions in the body of a class will become methods and receive self, unless you explicit say it’s a classmethod or staticmethod.

Adding methods to builtin types

Python doesn’t allow to add methods to builtin types, actually to any type defined in C. The unique way around this is to subclass the type, here is an example:

class UpperList(list):
    pass

def to_upper(self):
    for index, item in enumerate(self):
        self[index] = item.upper()

UpperList.to_upper = to_upper

l = UpperList(['i','g','o','r'])
l.to_upper()
print l

Here is a nice comparison on dynamically adding methods in Python and Ruby.

By Igor Sobreira

[Igor Sobreira] Mocks, Stubs, Fakes and Spies

Wednesday, October 19th, 2011

Published on: 15/12/2010 01:05h

Reading the Continous Delivery book I found a good definition of mocks, fakes, stubs and spies:

  • “Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production. A good example of this is the in-memory database.
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test.
  • Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent.
  • Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don’t expect and are checked during verification to ensure they got all the calls they were expecting.”

This terminology was taken from xUnit Test Patterns book.

I’ve already seen cases where people write lot’s of unit tests, abusing from mock objects, but without good integration and acceptance tests you can’t really guarantee that each scenario is really working as expected.

“It’s very easy to misuse mocks to write tests that are both pointless and fragile, using them simply to assert the specific details of the workings of some code, rather than an assertion of interactions with collaborators.”

A couple links if you want to read more about it:

[Igor Sobreira] Extending the User model in Django

Wednesday, October 19th, 2011

Published on: 11/12/2010 00:20h

Django brings a built-in user authentication system, it includes an User model which has the most common attributes. But in most applications you may need to store additional attributes to users. Django has a way to do this too.

Extending using foreign key

Basically you create your UserProfile model with a OneToOneField to User:

class UserProfile(models.Model):

    user = models.OneToOneField('auth.User')

    bio = models.TextField()

    # ...

and define in on settings.py

AUTH_PROFILE_MODULE = 'accounts.UserProfile'     # app name (dot) model name

From now on your User objects will have a get_profile() method.

I personally can’t see a reason to use this setting (and I hate “getters” methods), you just need to do this:

class UserProfile(models.Model):

    user = models.OneToOneField('auth.User', related_name='profile')

    bio = models.TextField()

    # ...

See the related_name='profile' parameter, now you don’t need the get_profile() method anymore, just use user_instance.profile.

But there is a small problem here, if the user instance don’t have a profile related to it you will receive an ObjectDoesNotExist exception. This happens with get_profile() too. And it’s not good to handle the exception every time you access the profile. The simplest way to solve this is connect to django.db.models.signals.post_save on the User model and create your UserProfile instance related to it

from django.db.models import signals

from accounts.models import UserProfile

def create_user_profile(sender, instance, created, **kwargs):

    if created:

        UserProfile.objects.create(user=instance)

signals.post_save.connect(create_user_profile, sender=User)

Why subclassing User is a bad idea

There are a few reasons I prefer to create user profiles as another model instead of just subclassing the default User. If you think for a while, an user has a lot to do in your site, and there are at a few default steps:

  • first she needs to register, confirm by email, and so on
  • login and logout, change and reset password
  • admins may need to manage groups and permissions, to restrict user actions, offer features to specific groups
  • manage profile, with personal information

Django doesn’t handle the first topic, there is a great app to handle registration.

The second and third topics can be done with django.contrib.auth app, this is exactly it’s purpose.

And then you have the forth topic, which is profiles. As you can see, it can be done as a separate app. A user has a profile. So makes sense to have a profile attribute in the User object.

If you split features in apps like this it’s easier to reuse too, that’s the idea of django apps after all! The django-registration is an example. And as you can imagine, there are apps to manage profiles too.

Editing User profile in admin

If you’re using admin you may want to edit the UserProfile fields in the same page as the User fields, and it’s possible using admin inlines. Here is how you admin configuration will look like:

from django.contrib import admin

from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin

from django.contrib.auth.models import User

from accounts.models import UserProfile

class UserProfileInline(admin.TabularInline):

    model = UserProfile

class UserAdmin(DjangoUserAdmin):

    inlines = (UserProfileInline,)

admin.site.unregister(User)

admin.site.register(User, UserAdmin)

Conclusion

As you can see, it quite easy to manage user profiles in django. Although there is a way to hook you profile model in settings.py, you can do it with a simple foreign key. And as usual, there are a few reusable apps around to handle the generic stuff.

By Igor Sobreira

[Igor Sobreira] Slides: Desenvolvimento web com Python e Django

Wednesday, October 19th, 2011

Published on: 08/11/2010 21:23h

Segue os slides da minha palestra Desenvolvimento web com Python e Django.

Apresentei essa palestra no Jatic, na faculdade Facisa em Campina Grande, PB. E também no CITOS, na faculdade Univem, em Marília, SP.

A maior parte da apresentação fala sobre Django, mas também mostra como funciona o WSGI, as maneiras mais comuns de fazer deployment de aplicações em python hoje em dia, configuração de ambiente usando virtualenv, testes…

Desenvolvimento web com python e django

Veja outras aprensentações minhas no Slideshare.

By Igor Sobreira

[Igor Sobreira] Campos numéricos localizados no Django

Wednesday, October 19th, 2011

Published on: 25/09/2010 14:42h

A criação de campos numéricos ficou muito mais fácil no Django na versão 1.2. Imagine o seguinte model:

class Debito(models.Model):

    descricao = models.CharField(max_length=256)

    valor = models.DecimalField(max_digits=10, decimal_places=2)

    def __unicode__(self):

        return self.descricao

E seu registro no admin

admin.site.register(Debito)

Ao tentar cadastrar um valor numérico, por exemplo: 1.450,60, receberíamos um erro já que esse formato não era entendido como numérico. Agora, basta informar que esse campo precisa ser localizado. Como isso é feito no formulário, e não no model, vamos sobrescrever o formulário padrão do admin

class DebitoForm(forms.ModelForm)

    valor = forms.DecimalField(max_digits=10, decimal_places=2, localize=True)

    class Meta:

        model = Debito

class DebitoAdmin(admin.ModelAdmin):

    form = DebitoForm

admin.site.register(Debito, DebitoAdmin)

Note o parâmetro localize no campo DecimalField do formulário.

Estamos quase lá, só precisamos nos certificar de que as seguintes configurações estão no settings.py

USE_L10N = True         # essa é padrão

USE_THOUSAND_SEPARATOR = True

Mas ainda tem um detalhe, se você tentar acessar debito.valor vai receber uma instância da classe decimal.Decimal do python, e ainda terá que formatar manualmente. Felizmente o django já possui uma função pra fazer isso. Para facilitar, você pode adicionar um método no seu model:

from django.utils.formats import number_format

class Debito(models.Model):

    descricao = models.CharField(max_length=256)

    valor = models.DecimalField(max_digits=10, decimal_places=2)

    def __unicode__(self):

        return self.descricao

    @property

    def valor_formatado(self):

        return u"R$ %s" % number_format(self.valor, 2) 

Agora sim, basta acessar debito.valor_formatado.

Confira a documentação para mais detalhes.

Até a próxima!

By Igor Sobreira