(blog ‘lucindo)

um dia eu aprendo a programar

Arquivo da categoria ‘programação’

Como tomar decisões

Agora pouco, no IM:

trajber: vou pedir ajuda ao meu querido PC
trajber: mauro@trajber:~$ python
Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import random
>>> print random.randint(0,1)
trajber: 0 = ignorar
trajber: 1 = comer
trajber: ok ?
trajber: 0
>>>
trajber: foi justo…

Outro também fez algo parecido: http://twitter.com/igorrs/status/896944758

Sem comentários »

ACE_Task-like em Python

Nos últmos dias me reanimei a voltar a postar nesse blog.

Estou tentando mudar para Python como a minha principal linguagem de script, mas ainda preciso aprender a programar direito nessa linguagem. Enquanto isso não acontece, eu fico replicando código de outros lugares, como a cópia de pobre da ACE_Task abaixo:

import threading, Queue, signal

class Task(object):
    def __init__(self):
        self.queue = Queue.Queue(0)

    def __worker(self):
        while True:
            item = self.queue.get()
            self.process(item)
            self.queue.task_done()

    def __start(self):
        thread = threading.Thread(target=self.__worker)
        thread.setDaemon(True)
        thread.start()

    def activate(self, threads):
        for thread in xrange(threads):
            self.__start()
        signal.signal(signal.SIGINT, signal.SIG_DFL)

    def put(self, item):
        self.queue.put(item)

    def wait(self):
        self.queue.join()

    def process(self, item):
        pass

class task(Task):
    def __init__(self, func):
        Task.__init__(self)
        self.process = func

A única coisa pytônica do código é o decorator do final.

Bom, um exemplo de uso: digamos que você é um spammer e quer mandar vários emails. Você tem um arquivo em que cada linha tem as seguintes informações: servidor; email; subject; mensagem. Tudo separado por ponto e vírgula.

Usando o decorator acima o código ficaria mais ou menos assim (usando 100 threads):

from __future__ import with_statement
from task import task
import smtplib, sys

@task
def send_spam(item):
    server, toaddr, subject, msg = item.strip().split(‘;’)
    fromaddr = ’spammer@evil.org’
    message = (“From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s”
               % (fromaddr, toaddr, subject, msg))
    try:
        smtp = smtplib.SMTP(server)
        smtp.sendmail(fromaddr, toaddr, message)
    except Exception:
        pass

def process_file(filename):
    send_spam.activate(100)
    with open(filename) as file:
        map(lambda line: send_spam.put(line), file.readlines())
    send_spam.wait()

if __name__ == ‘__main__’:
    process_file(sys.argv[1])

Coloquei esse exemplo porque não tinha um melhor… é apenas um exemplo, não um programa de verdade, ok? :-P

Download: task.py

To do: reescrever em Python 2.6 usando Multiprocessos

2 comentários »

HT-AJAX e jQuery

HT-AJAX (documentação aqui) é uma extenção do Hunchentoot que permite exportar suas funções lisp de modo que elas podem ser acessadas via JavaScript, usando AJAX. Um pequeno exemplo de uso dessa biblioteca está nesse post.

HT-AJAX suporta vários AJAX processors, como Prototype e Dojo, mas não jQuery. Então fiz um pequeno patch adicionando suporte a jQuery.

Download: ht-ajax_0.0.7-jquery.patch

Aplicando o patch (SBCL):

$ cd ~/.sbcl/site/ht-ajax_0.0.7
$ wget http://lucindo.com.br/lisp/ht-ajax_0.0.7-jquery.patch
$ cat ht-ajax_0.0.7-jquery.patch | patch -p0
$ sbcl
* (require :asdf)
* (asdf:oos 'asdf:compile-op :ht-ajax)
Sem comentários »

About State

State: you’re doing it wrong!

Two options for lispers:

  • Purely functional Lisps (subset of CL or something like Clojure, LFE, etc)
  • Cells!!!
1 comentário »

State: you’re doing it wrong

I’m completely convinced that mutable objects and the whole approach that is sort of implied by the design of Java, C#, Python, all the languages that followed along this path, is very much the wrong way to do most things… it is ok to do somethings, but it’s the wrong way to do most things.
Mutable objects are the new spaghetti code, and by that I mean that you eventually, with mutable objects, create an intractable mess, and encapsulation does not get rid off that, encapsulation just means: well, I’m in charge of this mess. But the real mess comes from this network you create of objects that can change, and your inability to look at the state of a system and understand how you got there, how to get there to test it next time… so it’s hard to understand the program… it’s very hard to test it. I think that’s interesting in telling all the emphasis on test driven design. I think people are driven to this because they know their systems are completely intractable…

Rich Hickey - Screencast: Clojure Concurrency (”transcrição” do minuto 21 ao 23)



3 comentários »

The Zen of Python

marvin:~ lucindo$ python
Python 2.5.2 (r252:60911, Apr 26 2008, 14:32:15)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
>>>
Sem comentários »

Para lembrar sempre

Just to remember

Sem comentários »

Hunchentoot e REST, parte 2: suporte a ETags

Bom, esse post é mais um snippet de como implementar um serviço REST usando Hunchentoot. Dessa vez adicionei suporte a ETags no código do outro post. Ficou assim o tratamendo das requisições:

(defvar *data-id* “e8d8993494ffc11:b8e”)
(defun get-data-id (target)
  “get the last id for requested data”
  *data-id*)

(defmethod handle :around (request-method)
  “ETag support for all methods”
  (let ((data-id (get-data-id (script-name)))
        (last-id (header-in :If-None-Match)))
    (setf (header-out :ETag) data-id)
    (if (and last-id (equalp last-id data-id))
        (setf (return-code) +http-not-modified+)
        (call-next-method))))

Fazendo um request normal:

GET /rest HTTP/1.1
Host: eddie

HTTP/1.1 200 OK
Content-Length: 3
Content-Type: text/html; charset=iso-8859-1
Date: Sun, 27 Apr 2008 20:07:53 GMT
Server: Hunchentoot 0.15.6
Etag: e8d8993494ffc11:b8e

GET

Agora o cliente passando o ETag:

GET /rest HTTP/1.1
Host: eddie
If-None-Match: e8d8993494ffc11:b8e

HTTP/1.1 304 Not Modified

Suportar ETags é muito fácil e se o cliente do seu serviço souber usar é muito útil para os dois.

Download: rest.lisp

3 comentários »

Testes unitários

As to your real question, the idea of immediate compilation and “unit tests” appeals to me only rarely, when I’m feeling my way in a totally unknown environment and need feedback about what works and what doesn’t. Otherwise, lots of time is wasted on activities that I simply never need to perform or even think about. Nothing needs to be “mocked up.”

Donald Knuth em entrevista a InformIT

Sem comentários »

Mudança de planos

python - python

Sem comentários »

Próxima Página »