Python scripting

Talvez pode ser útil para alguém :).

Este script pega a lista de músicas do mpd, seleciona um playlist aleatório, e coloca no ipod shuffle.


#!/usr/bin/python

import os,random

# ipod mountpoint - must be mounted!
MOUNTPOINT="/mnt/ipod"

def get_files():
    '''Reads the list of mp3 files from mpd database'''
    data = open(".mpd.db").readlines()
    files = []
    for l in data:
        fields = l.strip().split(":",2)
        if len(fields) < 2:
            continue
        if fields[0] == "file":
            files.append(fields[1].strip())
    return files

def get_free_space():
    '''Gets available space from IPOD partition'''
    line = os.popen("df -k %s | awk '{print $4}'" % MOUNTPOINT).readlines()[-1]
    return int(line)

def fullcp(file, target):
    '''copies file and directory structure'''
    os.system('tar cf - "%s" | (cd %s && tar xf -)' % (file, target))

if __name__ == "__main__":
    try:
        os.mkdir("%s/mp3" % MOUNTPOINT)
    except:
        print "Not creating %s/mp3!" % MOUNTPOINT
    files = get_files()
    freespace = get_free_space()
    while 1:
        # pega arquivo aleatorio
        pos = random.randint(0, len(files))
        curfile = files[pos]
        del files[pos]
        # determina o tamanho
        res = os.stat(curfile)
        size = res[6] / 1000
        if freespace - size < 1:
            break
        freespace -= size
        # copia
        print "Copying [%8dK left]: %s" % (freespace, curfile)
        fullcp(curfile, "%s/mp3/" % MOUNTPOINT)

É melhor usar ele junto com Shuffle-DB.

office.open(3)

Acabou de sair a versão beta do OpenOffice 3.

Muita gente já escreveu sobre isso, com opiniões variando entre “é a salvação do universo” e “e daí??”; agora eu queria falar a minha opinião, que não é nenhuma das duas.

Primeiro, vamos relembrar um pouco a situação como ela estava a alguns poucos anos atrás (vou comparar a evolução do OpenOffice com o Microsoft Office… porque todos os outros pacotes de Office, seja de IBM, de Corel, da SUN, ou de qualquer outra empresa perdem significativamente para o próprio OpenOffice. Temos o Google Docs, mas, obviamente, é um caso a parte!).

Na época que não tinha OpenOffice 1.0, e só tinha os milestones que - com muita sorte - até funcionavam e abriam alguns (poucos e seletos) arquivos do office. Você acha que o OpenOffice hoje em dia é lento?? Ha-ha. Instale algum dos milestones antigos - ou o 1.0 mesmo para ver a diferença. A maior vantagem dessas primeiras versões é que era possível abrir e editar uma grande parte dos arquivos de Microsoft Office. Obviamente, não todos, mas muitos. Nem isso não era possível antes (abiword? koffice? staroffice, siagoffice? prefiro não comentar).

A versão 1.0 foi um marco gigante - foi uma versão estável (na medida do possível), multi-plataforma, completamente livre e que abria a maior parte dos documentos existentes. Mais uma vez - não absolutamente todos, mas a grande maioria. Abrir lentamente, com interface diferente, com diversos problemas de layout, posicionamento e funcionamento, mas.. ela funcionava!

A versão 1.1 melhorou significamente o problema de desempenho, e essas melhorias continuaram com todas as versões posteriores. Versão 2 (e suas sub-versões) introduziu nova interface, suporte a ODF e desempenho muito melhor. E logo-logo vamos ter a versão 3.0.

O que é possível notar nessa evolução das versões?? Primeiramente, o número de reclamações caiu significativamente! Vejamos:

  • Interface diferente: com o lançamento de Microsoft Office 2007 esta reclamação perdeu completamente o sentido. OpenOffice é muito mais parecido com as versões antigas do Office de que o próprio software de microsoft…
  • Suporte incompleto a documentos de office: por mais reclamações que é possível encontrar sobre isso, tem que aceitar que o número de problemas de compatibilidade decresceu absurdamente nos últimos anos. Antes era sorte ter um documento .doc(.ppt, .xls) que abriria corretamente no OpenOffice. Hoje, em contra-partida, é difícil achar um documento com problemas. Chega a casos curiosos, onde OpenOffice consegue abrir documentos que travam o próprio Microsoft Office :), e a própria Microsoft assume isso (obviamente, não publicamente :) ).
  • Desempenho inadequado: esta afirmação também perdeu o sentido ao avaliarmos o Microsoft Office 2007.
  • Falta de funcionalidades: o OpenOffice ainda não implementa todas as 100% das funcionalidades que o Microsoft Office oferece. Porém… você conhece alguém que usa TODOS os recursos do Word?? Pois é, as funcionalidades presentes são mais de que adequadas…
  • e assim por diante..

Qual é a conclusão que dá para tirar, avaliando as versões atuais de OpenOffice??

Elas oferecem todas as funcionalidade que a absoluta maioria dos usuários precisam. Nem sempre do jeito idéntico ao Microsoft Office; nem sempre com a mesma interface; e nem sempre com todas as variações, mas oferecem!

E quanto a desempenho.. Seguindo os conselhos básicos localizaveis facilmente no google (desligar java, diminuir o cache, diminuir o uso de memória; otimizar o carregamento; desativar funcionalidades avançadas, etc) é possível melhorar o tempo de execução inicial em mais de 10x, e uso de memória em mais de 4x (eu comprovei isso com projetos que fizemos com Intel e Ardence em 2004-2005; inclusive tem até publicações da Intel sobre isso - as de Ardence continuam sendo sob n.d.a. até onde eu sei :)). Mas, se alguém tiver curiosidade, fiquem a vontade para perguntar por aqui mesmo!

Bem.. passando por esta introdução pequena ;), o que vamos ver na nova versão de OpenOffice?

  • Suporte a Mac OS X - bastante interessante, porque vai ser possível rodar o OpenOffice em cima de MAC sem precisar de servidor X.
  • Suporte a ODF 1.2 e OOXML - preciso falar alguma coisa?? :)
  • Suporte a PDFs editáveis - conhece algum outro escritório que permite isso?
  • Suporte a macros em VBA - uma das maiores limitações atuais foi a execução de macros voltados para Microsoft Office. Não mais.
  • Suporte a extensions - extensions fizeram do firefox o browser tão popular o quanto ele é hoje em dia. Enquanto plugins para OpenOffice existem já faz alguns anos, nunca foi simples ou intuitivo instalar e usar eles. Acredito que agora isso vai ser resolvido definitivamente.
  • Melhor suporte a multi-midia - suporte a reprodução de sons em background, suporte a múltiplos monitores, melhor suporte para CSV, HTML, melhor na renderização de fontes; melhorias na edição de imagens, e assim por diante. A lista é grande.
  • Novas funcionalidades - novas possibilidades relacionadas a planilhas, formulas, gráficos, renderização de páginas WEB, etc
  • e muitos outras melhorias menos significativas

O que dá para extrair de tudo disso? É simples - o desenvolvimento do OpenOffice é feito de forma evolucionária, e não revolucionária. O que acontece é que ele fica melhor e melhor gradativamente, e não visa fazer milagres de uma hora para outra. É bom isso? Sim, porque é possível ver o que podemos esperar das próximas versões. Isso tem lados negativos? Claro, porque sempre vamos ver comentários do tipo “office não está evoluindo”, “versão 2 é parecida com 1″, “microsoft é mais diferente”…

O resto vamos ver logo, na versão 3.0 do OpenOffice :).

Distributed Version Control

Só um pequeno resumo de vantagens e desvantagens de sistemas de controle de versões distribuídos que eu já cheguei a usar.

  • SVN + SVK - parecido com SVN, tem os mesmos problemas que ele (cria um monte de diretórios, etc). Na minha opinião, não tem muito uso prático - é melhor usar soluções distribuídas mesmo (bzr, git ou mercurial), porque todas elas tem gateways para SVN propriamente dito.
  • BZR - acho que é o meu favorito para a maioria das coisas. Facil de usar (o mais fácil de todos, na minha opinião), rápido - principalmente nas últimas versões, extensível. Os meus maiores problemas com ele foi o desempenho (que foi resolvido na versão 1.0), e o tratamento de arquivos binários grandes - ele fazia questão de colocar o commit inteiro na memória, em formato ASCII ainda. Ou seja, para fazer commit de 100MB ele usava 2GB de RAM. Mas aparentemente, isso foi arrumado recentemente.
  • GIT - extremamente poderoso, rápido e eficiente.Em contra-partida, ele tem milhares de comandos, sub-comandos, parâmetros e opções. Se você aprender tudo com ele, ele é o melhor. Entretanto, eu vivo me perdendo na hora de fazer coisas mais complexas (tipo, fazer um cherry-pick de um repositório remoto em um branch diferente). Por outro lado, só ele que permite fazer cherry-pick de forma fácil (para quem está por fora - cherry-pick permite você pegar um commit independente e embutir ele em outro branch. Se isso não fez sentido para você, provavelmente você não precisa dele :)). A melhor coisa do GIT para mim é o suporte dele para multiplos branches locais, no mesmo diretório. E a velocidade, é claro. Porém, a complexidade dele acaba complicando demais a vida as vezes.
  • Mercurial - parecido com o BZR e GIT. Atualmente suporta branches e cherry-picks também (de forma diferente). Ele suporta queues de patches também nativamente - mas, como nunca precisei disso, não posso falar muito detalhes. Fora isso, nunca cheguei a mexer muito com ele (mas, para quem tiver interesse, tem um tutorial interessante aqui). A escolha entre ele, bzr e git muitas vezes é questão de religião mesmo :).
  • DARCS - bastante interessante, e diferente de todos os outros sistemas. Basicamente, todo o mecanismo de commits e diferenças entre versões dele é baseado em filas de patches, aplicados em determinada ordem. A filosofia dele também é parecida com GIT - ele visa manter controle do conteúdo, e não da estrutura de versões. Isso tem lados bons (o mesmo conteúdo pode migrar de um lugar para outro - arquivo, diretório, etc) e ruins (se alguém fez essa migração, você não vai ter controle exato sobre o que foi feito).
  • GNU ARCH - acredito que hoje em dia ele tem mais interesse histórico de que prático. Muito mais complexo de usar (se bem que, comparando com GIT, acho que dá uma briga boa). As ideias dele são utilizadas em outros sistemas de controle de versões distribuídas, mas ele em si - pelo que eu sei - está parado. Eu cheguei a usar ele faz alguns anos, mas desisti logo devido à complexidade dele.
  • MONOTONE - também em desuso nos últimos tempos, o MONOTONE serviu como inspiração para GIT. Fora isso, nunca vi ninguém usar ele, então não tenho opinião formada sobre ele.

Além disso, tem diversas outras soluções caseiras (com svn, cvs (eca..), etc) que fazem a mesma coisa que DRCS’es usando algumas gambiarras (hehehe). Mas eu fico entre BZR e GIT na maioria dos casos.

Decorators em python

Por alguns meses fiquei pensando - para que servem os decorators em python? Ultimamente é fácil ver código do tipo:
@algum_metodo
def function(params):
____...

Aí hoje finalmente decidi descobrir como que isso funciona, e para que serve.

Em poucas palavras - realmente, decoratos são bem úteis. Eles não introduzem muitas novidades na linguagem, mas possibilitam evitar duplicação de código, e facilitar a implementação.

Por exemplo, suponhamos que precisamos rastrear todas as chamadas a uma de terminada função. Quais são as alternativas que temos?

  • Mudar a função para ela fazer um print toda vez que ela é executada, e toda vez que ela termina;
  • Fazer um wrapper para essa função;
  • Usar um decorator.

Vamos pensar em uma função bem simples:
def minhafunc(s):
____print "<< %s >> " % s

Como que poderiamos fazer o wrapper para esta função esta função? Por exemplo:
def wrapper(func):
____print "entrando na func!"
____ret = func()
____print "saindo da func!"
____return ret

result = wrapper(minhafunc())
Obviamente, isso funciona.. Mas para funções bem simples.

Um outro jeito seria transformar função automaticamente:
def logger(func):
____def wrapper(param):
________print "entrando na func!"
________ret = func(param)
________print "saindo da func!"
________return ret
____return wrapper

minhafunc = logger(minhafunc)

E agora vem a parte “mágica”. Decorators simplesmente permitem com que você evite a transformação de python em LISP, tirando a necessidade de empacotamento explícito dessas funções. Em outras palavras:

@logger
def minhafunc():
...

faz a mesma coisa que:
minhafunc = logger(minhafunc)

só que logo após a declaração da função.

Só isso :). É claro, que tem várias outras utilidades os decorators - facilitar o uso de threads em PyGTK; facilitar desenvolvimento de código sincronizado, etc.

Sem falar que fica bem mais legível o código:
@synchronized
@logged
def minhafunc():
____....

P.S.: O wordpress, para variar, deixa zoado o código.. Mas logo-logo este site vai migrar para Django. Desde que aprendi a mexer com ele, a minha opinião sobre os frameworks web mudou.. e muito! :)