Planeta PythonBrasil

July 02, 2009

Gustavo Niemeyer

Screwing up Python compatibility: unicode(), str(), and bytes()

Backwards and forwards compatibility is an art. In the very basic and generic form, it consists in organizing the introduction of new concepts while allowing people to maintain existing assets working. In some cases, the new concepts introduced are disruptive, in the sense that they prevent the original form of the asset to be preserved completely, and then some careful consideration has to be done for creating a migration path which is technically viable, and which at the same time helps people keeping the process in mind. A great example of what not to do when introducing such disruptive changes has happened in Python recently.

Up to Python 2.5, any strings you put within normal quotes (without a leading character marker in front of it) would be considered to be of the type str, which originally was used for both binary data and textual data, but in modern times it was seen as the type to be used for binary data only. For textual information, the unicode type has been introduced in Python 2.0, and it provides easy access to all the goodness of Unicode. Besides converting to and from str, it’s also possible to use Unicode literals in the code by preceding the quotes with a leading u character.

This evolution has happened quite cleanly, but it introduced one problem: these two types were both seen as the main way to input textual data in one point in time, and the language syntax clearly makes it very easy to use either type interchangeably. Sounds good in theory, but the types are not interchangeable, and what is worse: in many cases the problem is only seen at runtime when incompatible data passes through the code. This is what gives form to the interminable UnicodeDecodeError problem you may have heard about. So what can be done about this? Enter Python 3.0.

In Python 3.0 an attempt is being made to sanitize this, by promoting the unicode type to a more prominent position, removing the original str type, and introducing a similar but incompatible bytes type which is more clearly oriented towards binary data.

So far so good. The motivation is good, the target goal is a good one too. As usual, the details may complicate things a bit. Before we go into what was actually done, let’s look at an ideal scenario for such an incompatible change.

As mentioned above, when introducing disruptive changes like this, we want a good migration path, and we want to help people keeping the procedure in mind, so that they do the right thing even though they’re not spending too many brain cycles on it. Here is a suggested schema of what might have happened to achieve the above goal: in Python 2.6, introduce the bytes type, with exactly the same semantics of what will be seen in Python 3.0. During 2.6, encourage people to migrate str references in their code to either the previously existent unicode type, when dealing with textual data, or to the new bytes type, when handling binary data. When 3.0 comes along, simply kill the old str types, and we’re done. People can easily write code in 2.6 which supports 3.0, and if they see a reference to str they know something must be done. No big deal, and apparently quite straightforward.

Now, let’s see how to do it in a bad way.

Python 2.6 introduces the bytes type, but it’s not actually a new type. It’s simply an alias to the existing str type. This means that if you write code to support bytes in 2.6, you are actually not writing code which is compatible with Python 3.0. Why on earth would someone introduce an alias on 2.6 which will generate incompatible code with 3.0 is beyond me. It must be some kind of anti-migration pattern. Then, Python 3.0 renames unicode to str, and kills the old str. So, the result is quite bad: Python 3.0 has both str and bytes, and they both mean something else than they did on 2.6, which is the first version which supposedly should help migration, and not a single one of the three types from 2.6 got their names and semantics preserved in 3.0. In fact, just unicode exists at all, and it has a different name.

There you go. I’ve heard people learn better from counter-examples. Here we have a good one to keep in mind and avoid repeating.

por Gustavo Niemeyer em 02 de July de 2009 às 15:50

July 01, 2009

Kodumaro

Ponteiro opaco

GCC Muitas vezes programadores de C++ e Java confundem encapsulamento com ocultação, o que não é a intenção da orientação a objetos.

No entanto, o contrário da ocultação, a exposição, também não é desejável para o encapsulamento, pois causa uma confusão entre interface e implementação.

Em C++, a declaração de uma classe força a exposição de sua estrutura privada. Um exemplo bem simples:
class X {
public:
X(int);
~X();

int get(void) const;

private:
int value;
}


Neste exemplo insanamente simples, é possível ver a estrutura privada da classe X, o que no caso não é um problema muito sério, mas em casos ligeiramente mais complexos, é possível corromper o encapsulamento.

Uma forma de resolver o problema é usando um design pattern¹ chamado ponteiro opaco ou Pimpl.

A ideia é que a classe de interface seja apenas uma moldura (wrapper) para a classe de implementação. A classe de implementação é declarada no corpo da classe de interface, mas nada é exposto ali.

A classe de implementação vai ser finalmente implementada no arquivo onde os métodos da classe de interface são implementados. Os métodos da classe de interface então simplemente chamam os métodos da classe de implementação.

Voltemos ao exemplo… o arquivo de cabeçalho de nossa classe (x.h por exemplo) passa a ser:
class X {
class Ximpl;

public:
X(int);
~X();

int get(void) const;

private:
Ximpl *pimpl;
}


Como é possível ver, nada da implementação está exposto.

Então a classe de implementação é finalmente definida no arquivo de implementação (x.cc):
class X::Ximpl {
public:
Ximpl(int);
~Ximpl();

int get(void) const;

private:
int value;

}


O resto do código fica:
X::X(int value): pimpl(new X::Ximpl(value)) {
// Nada mais a fazer
}

X::Ximpl::Ximpl(int value): value(value) {
// Nada mais a fazer
}

X::~X() {
delete this->pimpl;
}

X::Ximpl::~Ximpl() {
// Nada mais a fazer
}

X::get(void) const {
return this->pimpl->get();
}

X::Ximpl::get(void) const {
return this->value;
}


É claro que é um pattern extremamente desconfortável, pois é preciso implementar cada método duas vezes, uma para a classe de interface, outra para a classe de implementação… e há sim formas melhores de fazer isso.

Mas Pimpl funciona, é uma saída viável e pode salvar sua vida. =D

[]'s
Cacilhas, La Batalema


¹ Design patterns: antes que me crucifiquem por usar esta expressão fora do mundinho pequeno de Java, a definição de design pattern é «um jeito formal de documentar a solução para um problema de desenvolvimento», o que define corretamente ponteiro opaco.

por noreply@blogger.com (La Batalema) em 01 de July de 2009 às 22:01

Eventos da APyB

Conferência PythonBrasil[5]

A Conferência PythonBrasil[5] acontecerá de 10 a 12 de Setembro de 2009 na UCS, em Caxias do Sul/RS. Nos encontramos na Serra Gaúcha!

por marcoandre em 01 de July de 2009 às 06:05

Noticias da APyB

Aberto o processo de seleção da sede da PythonBrasil[6]

Estão abertas as inscrições para o processo de seleção da sede da PythonBrasil[6], em 2010. O prazo vai até 6 de setembro de 2009 e o anúncio da cidade escolhida será feito durante a quinta edição do evento.

por marcoandre em 01 de July de 2009 às 03:46

Gustavo Niemeyer

My iPhone for an Android!

Yes, you’ve heard it right. I’ll exchange a legally unlocked iPhone 3G for a recent Android phone such as the Samsung Galaxy or the HTC Hero, and will pay the difference back! (street price minus 30% of devaluation for the used iPhone 3G).

I got an iPhone some time ago to learn the concepts introduced in the platform, and get a feeling of how it works out in practice. I’m happy I did it, since the hands on experience is worthwhile. But the experience is done, and even though I have positive things to say about the platform, the omnipotent and arrogant position of Apple with developers kills any chance of any further involvement I could have with the platform. I’m upset enough with it that I don’t want to see my wife using the device either.

There are many things in Apple’s behavior which are a source of arguments, and interminable flamewars, and most of the times I can see both sides of the story. For instance, when people pay a premium to get the hardware, some feel like it’s just throwing money away, but if there is good engineering behind it, well.. I understand people may want to pay the premium to get that exclusive product they like. That said, being so incredibly arrogant in the marketplace, and with developers, which theoretically should be their most precious partners, since they sustain the platform going, is something I can’t tolerate.

I know.. who am I. Just a random guy that actually gave them some money for one of their products. But I’m also a guy that won’t be buying their upgraded phones, and will be spreading the word to make people realize what a terrible future it will be if Apple ever dominates the marketplace. Even you’re not a developer, it’s a good idea to ponder carefully about this behavior. It tells a lot about how far they go to defend their own interests, and what kind of lock in they intend to get you into.

Finally, compare that to a nice open source operating system on which multiple first class vendors are cooperating. Sheeshh.. easy choice for me.

por Gustavo Niemeyer em 01 de July de 2009 às 02:50

June 28, 2009

Kodumaro

Variaridade

GCC Uma função variádica variária – em inglês variadic, variable arity, aridade¹ variável – é aquela que suporta uma quantidade variável de parâmetros.

Muitas linguagens suportam funções variárias, aliás de forma bem simples. Python usa o operador * para indicar quantidade variável de parâmetros, Lua usa o operador ... e Common Lisp o operador &rest.

Outras linguagens podem ser ainda mais simples, como por exemplo Perl, onde toda função é variária e os parâmetros são recebidos na lista @_, tradicionalmente capturados por shift.

Java não suporta funções verdadeiramente variárias devido a sua limitação forçada de tipagem, no entanto é possível simular com o uso de Object e casting («vazamento» na falta de uma tradução melhor):
void myFunction(Object... args) {
// Código do método

}


Funções variárias em C/C++


C/C++ usa o cabeçalho stdarg.h para suporte a funções variárias.

O exemplo apresentado na Wikipédia é bastante simples: uma função printargs que recebe uma quantidade arbitrária de números inteiros, encerrando com -1 (ou qualquer número negativo em nosso exemplo), e os exibe na saída padrão.

Precisamos incluir dois cabeçalhos em C++, cstdarg para suporte a funções variária e cstdio para exibir o resultado:
#include <cstdio>
#include <cstdarg>


Ou, em C:
#include <stdio.h>
#include <stdarg.h>


A assinatura da função fica assim:
void printargs(int arg1, ...) {


Para acesso aos parâmetros múltiplos é usado um objeto va_list:
    va_list args;


A função va_start() inicializa o objeto. Ela recebe dois parâmetros: o objeto va_list e o nome do último argumento antes da lista:
    va_start(args, arg1);


Portanto é preciso haver pelo menos um argumento antes da lista variável. Podemos então exibir o primeiro parâmetro, recebido no argumento arg1:
    printf("%d", arg1);


A função va_arg() retorna o argumento seguinte. Ela recebe como parâmetros o objeto va_list e o tipo do parâmetro da lista a ser recuperado.

O tipo precisar ser plenamente promovido, ou seja, ponteiro, inteiro, ponto flutuante ou precisão dupla. Outros tipos, como char precisam sofrer casting, como por exemplo (não faz parte do código de printargs):
char c = static_cast<char>(va_arg(va, int));


Continuando o código, podemos agora reiterar sobre os resultados de va_arg() até encontrarmos o valor de parada negativo:
    int arg;
while((arg = va_arg(args, int)) >= 0)
printf(" %d", arg);


Após o fim da reiteração dos parâmetros obtidos do objeto va_list através de va_arg(), é preciso encerrar o objeto:
    va_end(arg);
printf("\n");
}


Caso você queira restringir o formato de entrada da função, isso é possível usando __attribute__ em sua declaração. Por exemplo, se a função log() recebe o nível de log como primeiro parâmetro, uma string de formatação como segundo parâmetro (2) e os parâmetros variáveis a partir do terceiro (3), com formato similar ao da função printf(), isso é feito com a seguinte assinatura:
extern void
log(int level, cons char *fmt, ...)
__attribute__((format(printf, 2, 3)));


As opções para format() são printf, scanf, strftime e strfmon. Veja Declaring Attributes of Functions da documentação do GCC.

[]'s
Cacilhas, La Batalema


¹Aridade: em Matemática é o número de operandos de uma função.

por noreply@blogger.com (La Batalema) em 28 de June de 2009 às 22:10

June 24, 2009

Gustavo Niemeyer

Are you ready for the mobile revolution?

Are you? I’m not entirely sure I am, even though I think about this a lot.

If you’re of the tech-savvy kind, you’re certainly aware of the great capabilities that the new mobile phone generation is bringing: Internet connection, a quite decent browser, GPS, camera, etc. But, really.. did you stop to think about what’s going on? This phone generation is still relatively expensive today, but they’re here to stay, and in just a few years, they’ll be commonplace.

Now, let’s forget about ourselves for a moment, and think about what mass adoption of a quite capable generic computer with full internet connectivity 24h a day being carried with its owner means for the world? Remember, the number of mobile phone users in the world is several times superior to the number of computers, and most of the computers are in the so called first world.

This implies that not only will everyone have access to the world in their pockets, which is already quite amazing by itself, but that a large number of people will have access to the Internet at all for the first time with their mobiles. Besides the several social impacts that these changes will bring, there are also many other interesting consequences. As simple examples, the most common client to many web services will be mobile phones, and many people will learn to use a touch screen interface of the mobile to interact with the world before ever having used a desktop computer for that.

I find that amazing, and this is happening right now, in front of our eyes.

por Gustavo Niemeyer em 24 de June de 2009 às 00:58

June 22, 2009

Ricbit

As batalhas do magenta

Convencer as pessoas de que o magenta existe foi uma batalha, mas certamente não a única batalha pela qual a cor passou. O magenta é uma cor mais sofrida que o flicts; na verdade a própria origem do magenta foi em uma batalha!

Originalmente, a cor #FF00FF era chamada de fúcsia, em homenagem a uma singela florzinha que tem essa cor. Mas em 1859 houve uma sangrenta batalha entre franceses e austríacos, tão intensa que pintou o chão de sangue. Essa batalha aconteceu na cidade italiana de Magenta, e desde então aquele tom da cor de sangue ficou conhecido como magenta.

A batalha mais recente do magenta é contra outra injustiça cometida pelo povo que não conhece física. Dessa vez a abobrinha veio de um designer coreano, que bolou uma caneta-scanner especial para desenhistas. Se você quiser pintar uma maçã com a aparência similar a uma maçã real, basta usar a ponta-scanner da caneta para capturar o tom RGB exato da fruta, e na outra ponta a caneta mistura as proporções exatas de tintas (vermelhas, verdes e azuis) que reproduzem aquele tom. A idéia da caneta até é legal, mas do jeito que foi bolada, não funciona.


O problema da caneta, é claro, são as tintas. Para entender por que elas são um problema, precisamos relembrar a definição de cor do Kandel: "Cor é uma experiência subjetiva relacionada à composição espectral da luz que atinge o olho". Ou seja, segundo essa definição, a única coisa que pode ter cor é luz. Como tinta não é luz, logo tinta não pode ter cor.

A maneira correta de caracterizar uma tinta é através da sua refletância, ou seja, a relação entre luz absorvida e refletida para um dado comprimento de onda. A cor da tinta não depende apenas de suas características intrínsecas, mas também da luz que incide sobre ela.

Você pode fazer um experimento simples para verificar isso. Primeiro pegue dois pedaços de pano, branco e vermelho, e um lightsaber bicolor, azul e vermelho (se você não tem um lightsaber bicolor, eis uma boa desculpa pra comprar um!). Veja agora como a cor do tecido depende da luz incidente:

Luz ambiente (branca)

Luz vermelha

Luz azul

Agora dá pra ver claramente: o tecido "branco" na verdade reflete toda a luz que chega, então ele só é branco quando a luz é branca. Se a luz for vermelha, o tecido fica vermelho, se a luz for azul, o tecido fica azul.

Já o tecido "vermelho", na verdade, absorve todos os comprimentos de onda, menos o vermelho. Tanto faz se a luz é branca ou vermelha, o resultado é o mesmo: só o vermelho é refletido. Já quando a luz é azul, sem componente vermelho nenhum, o resultado é que ele fica com aparência praticamente preta, pois não tem nada pra refletir. O diagrama abaixo mostra o que aconteceu:


Agora fica claro porque a escolha de cores do designer coreano é falha. As tintas que ele escolheu (vermelho, verde e azul) não podem ser misturadas! Vejamos: uma tinta vermelha, na verdade, absorve o verde e azul, refletindo só o vermelho. Uma tinta verde, na verdade, absorve o vermelho e o azul, refletindo só o verde. Se você misturar o vermelho com o verde, a tinta resultante vai absorver o vermelho, o azul e o verde, ou seja, não vai refletir nada. Uma mistura de tintas vermelhas e verdes, em proporções iguais, dá uma tinta preta.

Quem já trocou cartuchos de impressora jato de tinta sabe qual a solução para esse problema. Basta escolher outras cores: amarelo, ciano... e magenta! Essas sim são tintas que podem ser misturadas. Confira: uma tinta magenta, na verdade, absorve o verde. Uma tinta ciano, na verdade, absorve o vermelho. Se você misturar magenta com ciano, o resultado absorve o verde e o vermelho, ou seja, só sobra azul. Tinta magenta com tinta ciano dá tinta azul.


Essas tríades de cores são chamadas de cores primárias. Vermelho, verde e azul são as cores primárias aditivas, aquelas que você usa com emissores de luz, como lâmpadas e LEDs. Ciano, magenta e amarelo são as cores primárias subtrativas, aquelas que você usa com tintas.

Por fim, isso nos leva a mais uma batalha do magenta. "Peraí, minha professora na escolinha disse que as cores primárias são vermelho, azul e amarelo"! Hum, foi mal, mas a sua professora te ensinou errado (deve ter sido a mesma professora que ensinava que se a órbita da Terra era elíptica, então o inverno é quando a Terra está mais longe do Sol). Ela não sabia diferenciar magenta de vermelho, nem ciano de azul.

Uma dúvida mais sutil é "Ah, mas eu misturava vermelho, azul e amarelo, e conseguia fazer todas as cores"! Sim, sim, essas cores formam uma base no espaço das cores subtrativas, o problema é que não é uma base ortogonal. Se você fizesse uma impressora com essas cores, um dos tubinhos de tinta iria acabar mais rápido. Por isso também que impressoras tem um quarto tubo com tinta preta: para escurecer um tom é mais barato adicionar preto que misturar tinta dos três outros tubos.

Conclusão da história toda: não subestime o magenta! Apesar de ser sistematicamente ignorada, é uma cor com muitas utilidades :)

por noreply@blogger.com (ricbit) em 22 de June de 2009 às 14:21

June 18, 2009

Pythonologia

Dicas para um bom programa em Python

Oi pessoal, desta vez eu vou pular as ‘desculpas’ por ter demorado tanto para postar aqui no blog e vamos direto ao assunto.

Recentemente eu tenho trabalhado bastante com Python (dã!) desenvolvendo projetos de diversos tipos e resolvi escrever aqui sobre algumas coisas que pratico enquanto desenvolvo.

Código mais robusto

Deu certo ou errado?

O que você faz quando acontece algo errado na execução do seu método? O que você responde à requisição que lhe foi feita?

Eu tenho visto em muito código por aí os desenvolvedores retornando valores sentinela (None, null, 0, -1, etc.) para avisar que algo incorreto aconteceu na execução do método.

def f(arg):
   if not arg:
      return None
   return [ "resultado", "de", "um", "processamento"  ]

Algumas linguagens de programação não possuem estruturas de tratamento de exceção e, neste caso, o uso de sentinelas é válido. Mas quando a linguagem de programação te disponibiliza essa funcionalidade é bom usá-la.

def f(arg):
   if not arg:
      raise ValueError("Argumento Invalido")
   return [ "resultado", "de", "um", "processamento"  ]

Deixem as exceções fluirem.

Isso mesmo. A menos que você saiba exatamente o que você deve fazer quando uma exceção aparece deixe-a exceção “subir”. Pode ser que “lá em cima” alguém saiba cuidar dela adequadamente.

Quando não fazemos isso estamos ocultando informação importante para os usuários do nosso código (sejam eles usuários, outros desenvolvedores ou nós mesmos).

def f():
   try:
      return conecta()
   except ExcecaoQueDeveriaSerErro:
      return None

Quando eu implemento esse tipo de método/função eu faço assim (na verdade eu não implementaria f() e chamaria conecta()):

def f():
   return conecta()

O que seu método/função retorna?

Código que eu encontrei recentemente:

def get_fulanos():
   q = Q("select * from patuleia where alcunha like 'fulano%'")
   ret = [ str(fulano['nome']) for fulano in q ]
   if len(ret) == 1:
      return ret[0]
   return ret

Perceberam o que está errado? O seu método retorna uma lista de Fulanos ou retorna Fulano?

Isso está conceitualmente errado e pode fazer você perder horas preciosas do seu dia tentando achar um bug causado por esse tipo de código.

Aconteceu comigo. Note que str() implementa uma interface de sequence da mesma forma que list(). Então o erro passa silenciosamente no caso abaixo:

old_fulanos = [ "Ze Ruela", "Ze Mane" ]
old_fulanos.extend(get_fulanos())
print old_fulanos

Rodando esse código você vai obter ['Ze Ruela', 'Ze Mane', 'q', 'u', 'a', 'c', 'k'] sendo que, em mais de 90% dos casos, o que você gostaria de ter seria: ['Ze Ruela', 'Ze Mane', 'quack'].

“Nada” é diferente de “alguma coisa”.

Essa dica é só uma complementação da primeira e da segunda dica.

Quando o seu método/função retorna uma collection (seqüência, conjunto, hash, etc) vazia você deve retorná-la vazia e não um valor sentinela (como None). Isso facilita a vida de quem vai usar o seu método/função:

def vazio():
   return []
 
for elemento in vazio():
   pass #... faz algo se o conjunto contiver dados ...

Se você retorna um valor sentinela:

def vazio():
   return None
 
elementos = vazio()
if elementos:
   for elemento in elementos:
      pass # ...

Notou que tivemos que criar uma variável com o resultado da operação (para não precisar chamá-la duas vezes) e tratar a sentinela com um “if“? Se eu esqueço de tratar a sentinela meu programa vai quebrar.

Lembre-se sempre que uma collection vazia tem valor booleano “False“.

Todo ‘elif‘ tem um irmão ‘else‘.

Sempre que você precisar usar uma construção if/elif coloque uma cláusula ‘else‘.

Além de usar a cláusula ‘else‘ eu geralmente faço com que ela gere uma exceção. Desta forma eu sou obrigado a trabalhar todas as possibilidades nos ‘if/elif‘ evitando ocultar uma situação que pode ser inválida.

class InvalidCommand(Exception):
   pass
 
def minihelp(comando):
   if comando == "print":
      return u"""Imprime dados na tela.
                 Deixará de ser comando no Python 3.0"""
   elif comando == "assert":
      return u"""Certifica se uma condição é
               verdadeira e gera uma excessão em caso contrário"
   elif comando == "...":
      pass # ...
   else:
      raise InvalidCommand(u"Comando %s inválido." % (comando,))

Eu gosto dessa prática mas isso não significa que você deva seguí-la sempre. Existem situações onde ter um “valor default” é necessário e nestes casos o uso do else sem levantar exceção se faz necessário.

if comando == "if":
   print "Vai usar elif?"
elif comando == "elif":
   print "Muito bem. Agora falta o else"
else:
   print "Pronto. Agora está bom."

“Pythonismos”

Use mais atributos públicos do que atributos protegidos (”_“).

Programadores acostumados com Java utilizam muito as cláusulas ‘private‘ e ‘protected‘ para encapsular os atributos de um objeto para logo depois implementarem os getters e setters para acessar esses atributos.

Essa prática é aconselhada em Java porque em algum momento do futuro você, talvez, precise validar esses dados ou retornar valores calculados. Nestes casos os programadores apenas implementam essa lógica nos métodos que acessam o atributo privado.

Mas em Python isso não é necessário. Em Python você pode transformar seu atributo público em uma “property” que não muda a forma de se acessar o atributo e permite o acrescimo de lógica ao acesso do mesmo.

Evite usar “__“.

Por convenção, em Python, todo método ou atributo iniciado com um “_” é considerado privado (equivalente ao protected em Java) e não deve ser acessado de fora da classe mesmo sendo possível fazê-lo.

Dito isso parece meio óbvio que não precisamos usar “__” para dificultar ainda mais o acesso à esse atributo/método. Além disso o uso do “__” traz alguns incoveninentes para quem quer derivar a sua classe e acessar este método/atributo já que o Python o renomeia acrescentando o nome da classe ao seu nome (__attr vira Classe__attr).

Não sobrescreva builtins.

Python disponibiliza várias funções e classes builtins que facilitam muito o uso da linguagem e economizam digitação. Mas esses builtins tem nomes muito “comuns” e frequentemente a gente usa os nomes dos builtins como nomes de identificadores. Eu mesmo vivo (vivia) fazendo isso.

O problema é que em certos momentos alguns problemas podem acontecer quando você tenta chamar um buitin que já não é mais um builtin. Na maioria das vezes o problema “explode” logo e você rapidamente conserta mas em alguns casos você pode perder muitas horas tentando achá-lo.

Algumas pessoas usam um “_” no fim do nome do identificador (ex. “id” vira “id_”) mas eu acho isso um pouco feio então uso só quando não encontro uma alternativa melhor.

Vou colocar aqui uma tabela de equivalências que eu costumo usar para substituir o nome dos builtins mais comumente sobrescritos:

  • id – ident, key
  • type – kind, format
  • object – obj
  • list – plural (lista de element vira elements)
  • file – fd, file_handler
  • dict – dic, hashmap
  • str – text, msg

Análise estática economiza seu tempo.

Eu uso o pylint, mas conheço algumas pessoas que preferem o pyflakes ou o PyChecker.

A dica é essa: usar um programinha de análise estática como esses pode diminuir consideravelmente aqueles errinhos chatos de sintaxe, ou de digitação. Pode limpar os ‘import’ desnecessários do seu software, etc, etc.

É lógico que esse tipo de ferramenta não substitui uma boa política de testes mas é um bom complemento para ela.

Challenge yourself

Máximo de 3 níveis de indentação. (ou 4 se estiver dentro de uma classe)

Ao se esforçar para que seu código não fique muito aninhado você está trabalhando melhor a implementação dos seus métodos e funções. Nem sempre é possível (ou aconselhável) restringir tanto o nível de identação do seu código mas muitas vezes isso melhora a sua implementação.

Máximo de 2 indireções.

Recebeu um objeto como parâmetro? Chame apenas métodos dele e evite ao máximo chamar métodos do retorno desses objetos:

def f(obj):
    obj.metodo() # legal!
    obj.metodo().outro_metodo() # ruim!

Quando você chama um método pra um objeto retornado por outro método você está aumentando o acoplamento entre as classes envolvidas impedindo que uma delas seja substituída (ou reimplementada) ‘impunemente’.

Essa regrinha é uma das regrinhas da Lei de Demeter.

Máximo de 0 ‘if/elif/else’s.

Polimorfismo é isso. No mundo OO ideal, perfeito e utópico praticamente não precisaríamos do comando “if” e usaríamos somente polimorfismo. Mas… como não conseguimos isso tão facilmente* devemos, ao menos, usar o “if” com moderação.

Conclusão

Esta é uma lista incompleta de dicas para programadores Python. Se futuramente eu lembrar ou aprender algo novo eu volto aqui para falar sobre o assunto.

Alguns desenvolvedores podem não concordar com as dicas. Neste caso eles podem enriquecer ainda mais esse texto argumentando sobre o as suas restrições no espaço para comentários.

Se você tiver alguma dica para compartilhar com a gente coloque nos comentários. Se ela for boa mesmo eu coloco ela no corpo principal do blog.

* eu mesmo só consegui fazer uma aplicação OO funcional sem usar um único if. Era uma implementação do joguinho de adivinhação de animais (aquele que pergunta “Vive na água? (s/n)”) em Smalltalk.

por Osvaldo Santana em 18 de June de 2009 às 03:47

June 16, 2009

Blog da Liberiun

Lavar as mãos

A quase 2.000 anos atrás, Pilatos lavou as mãos para se livrar de uma decisão difícil na sua vida. A 100 anos atrás, em um hospital em Viena, Dr. Semmelweis demonstrou que lavar as mãos rotineiramente é imprescindível para prevenir doenças infecto-contagiosas. Hoje os médicos pedem para que todos lavemos as mãos para evitar a nova gripe suína. Agora me fale a verdade: Quantas vezes você já foi no seu fast-food favorito e comeu as batatas fritas com suas mãos e nem lembrou antes de passar no lavatório?

Na programação também é assim: Diversos aspectos que tornariam nossos códigos mais eficientes ou simplesmente mais legíveis são esquecidos em troca de diminuir algums segundos no tempo de desenvolvimento. E o resultado é claro: Dores de cabeça, febre alta e dores de garganta de tanto gritar com seu própio código.

Precisamos "lavar as mãos" antes de programar! E como lembrar nunca é pouco, vão umas dicas básicas para mantermos nossos códigos limpos e organizados:

1- Identar o código corretamente: Sei que no python somos obrigados a identar corretamente o código, mas quando chega na camada de visualização da nossa aplicação web, muita gente esquece que HTML também se identa... assim como XML e qualquer linguagem de marcação, script etc.

2- Declare variáveis com nomes que fazem sentido! X, Y, Z, I, C, A são letras bem bacanas, mas quando vemos um:

for x in y:
   z+=x[c]*a
não fazemos a mínima idéia do que se trata. Ficaria muito mais simples se fosse:

for aluno in classe:
  soma_notas += aluno[nota]*peso
Fica bem mais claro, e muito mais fácil de corrigir eventuais erros.

3- Escreva códigos simples. Não tente em apenas 1 método resolver todos os problemas da humanidade. Divida para conquistar, sempre que possível.

4- Evite condicionais e loops extremamente longos. Isso deixa o código mais difícil de corrigir, por exemplo:

if correto:
      === trocentas instruções ===
      return resultado
else:
     return erro
ficaria muito mais claro:
if not correto:
   return erro

=== segue as trocentas instruções normalmente ===
5- IF dentro de IF que ta dentro de outro IF que fica dentro de um FOR também não é uma boa idéia! Tente sempre se limitar no máximo a 3 identações, sempre que chegar a algo maior que isso verifique se esse código não pode ser simplificado.

6- Evite copiar e colar! Sempre tente isolar códigos similares em funções ou métodos de forma a diminuirmos a repetição do código, e a possível repetição de um bug.

7- Comente seu código! Comentários ajudam os desenvolvedores a entender códigos mais complexos e até aonde alguma coisa ainda está incompleta ou precisa ser melhorada.

8- Não abuse dos comentários!! Comentar é bom, mas comentar demais só atrapalha. Códigos bem escritos evitam comentários.

9- Não misture seu código! Lembre-se que aonde é visualização precisamos de visualização, e aonde é lógica precisamos de lógica. Evite programar no HTML e desenhar interface em Python.

10- E por fim: Teste. Sempre teste. Se modificou um código teste. Por mais simples que seja sua modificação sempre teste. Se já soubessemos de antemão se nosso código fosse dar problemas não existiria bugs em nenhum programa.

Essas foram minhas dicas e espero que você as pratique sempre. Sei que a maioria das pessoas já sabem dessas coisas, mas não adianta nada conhecer e não colocar em prática.

Abraço a todos e não esqueçam de lavar as mãos!

por Thomaz Reis em 16 de June de 2009 às 21:36

June 13, 2009

Devlog

Pylons 0.97 lançado

http://pylonshq.com/articles/archives/2009/2/pylons_097_released

Após um grande tempo de espera, foi lançada a versão 0.97 do framework web Pylons As principais mudanças:

  1. Agora o WebOb é usado para objetos de requisição e resposta
  2. Melhorias de performance na inicialização de objetos
  3. Atualização do Beaker e do Routes
  4. Melhorias e otimizações nos middlewares

O site do Pylons passou por algumas mudanças algumas semanas atrás, ficou bem bonito e mais organizado. Agora existe uma nova documentação gerada com o Sphinx, e um livro está disponível online, o que deve minimizar os problemas que tinha a documentação. O novo site do Pylons usa o CouchDB como backend, e seu código está disponível em http://bitbucket.org/bbangert/kai/overview/

por Walter Cruz em 13 de June de 2009 às 18:52

June 09, 2009

Noticias da APyB

PythonBrasil 5: Definidos os palestrantes internacionais

Jacob Kaplan-Moss e Colin Winter serão os palestrantes internacionais convidados para a Conferência Python Brasil 5.

por marcoandre em 09 de June de 2009 às 14:54

June 05, 2009

Sidnei da Silva

A Look At The Landscape, After Five Months


Over the past few months, friends and family have been very curious about how my new job is going, and it’s been hard to stop for a moment and go into detail about it. I’ve been simply nodding and saying “It’s fine”.

This is an attempt at summarizing all the activity that happened in the last five months, though it’s far from being a short summary. If I had to pick a two words to describe my first five months at Canonical, it would be “Pure Awesomeness“. For a more detailed view, grab a cup of joe or your favorite other beverage and keep on reading.

Today is a special day. Exactly five months ago, on January 5th, I joined Canonical to work on the Landscape project.

It has been quite a ride so far, with two sprints with the Landscape team, AllHands and UDS in Barcelona just a week ago, and lots of excitement about the future. Saying that I’m completely stunned by the work everyone at Canonical has been putting together and how much the teams have grown in the last few months doesn’t do enough justice to it.

At AllHands and UDS we got a short preview of the things that are coming out in the next cycle and beyond. An example of that is the newly formed Design and User Experience (DUX) team which will not only be focusing on Ubuntu itself, but on many other areas across Canonical and the whole Open Source community in general.

At UDS, the DUX team had a special ‘booth’ where any person from any project could walk to them and get advice about their personal or favorite application. One person which has favorably used such advice already was Seif Lofty, from Gnome Zeitgeist. I met Seif during breakfast at the first day of UDS and I cannot describe how excited he was about simply *being* at UDS. And he was certainly twice as happy when he left.

Another person I had the joy to meet was David Siegel, of Gnome Do fame. We teamed during AllHands on the infamous “Fun In The Woods” activity, which had some people walking like zombies on the day after.

Even more importantly, I was able to meet many many more other colleagues from different teams and wrap up some loose ends from tasks that I got started during the first couple months. I’m definitely impressed by the amount of plain brilliant people that are part of Canonical as of today.

In a sense, being at a Canonical event is very much like being at a Plone conference. Everyone seems to be very receptive about new ideas and very friendly and laid back. And as a bonus, I was able to exercise my (not so secret now) power of throwing some crazy ideas around and see how they influence people. And man, I’m already impressed by the outcomes, just a week after the fact.

To me, this has been the most rewarding thing so far, to be able make big contributions not in lines of code, but in ideas that can make a concrete difference in the hands of the right people. This is something that can only be possible at a company the size Canonical is at the moment, where it’s just big enough that you can grab a mind or two to push an agenda without affecting the rest of the team and still small enough that you can influence decisions.

As my colleague Jamu would best describe, “I’m PUMPED!”. :)

But that’s not all. Software-wise, I was able to make some big contributions too. The Landscape team just finished a 6 month development cycle that brought many cool features to life. I’m really happy with that, and specially with the speed that this team can get features from the black board into reality. It’s also a much different environment than what I was used to, with very well-defined and refined processes for ensuring the overall quality of anything that is produced. One process that I’m specially enjoying is the requirement for two positive reviews before landing a branch. I hope to talk more about that soon (that is, sooner than 5 months from now *wink*).

As for my role in the team, it is quite different than what I’m used to. I’ve been focusing a lot on the UI aspects of Landscape, on ways to make things more obvious and more streamlined. I’ve been also writing a ton of Javascript, and collaborating with other teams to define better policies for Javascript testing in general. And finally, we will now have a person from the DUX team dedicated to working with us, which will push work on the Landscape UI even further.

I also had the chance of interacting with the Launchpad team, which has a much more refined process due to the size of their team. Over at Launchpad, I started a branch back in mid-December, even before starting at Canonical, to allow Launchpad to use the Chameleon Template Engine.

That was another wild ride, and during the course of this project I was able to contribute tons of fixes upstream to Malthe Borch to make Chameleon even more compatible with plain old ZPT. In fact, it is so compatible at the moment that due to the magic of z3c.ptcompat Launchpad will be able to run *both* Chameleon and ZPT with the flip of an environment variable. Even more stunning, the changes required to code were minimal, basically changing imports to use z3c.ptcompat, and in templates we’ve had to fix some non-XHTML compliant ones and remove unused i18n tags. I am happy to announce that this branch will soon be merged (it was submitted to PQM, successfully accepted and is waiting to land the buildbot queue). The bad news is that not all tests pass at the moment with Chameleon enabled, but we will be dogfooding and fixing those tests as we go. It was too much pain already to maintain a nearly 6 month old branch outside the main tree. ;)

I am really interested in many of the things that the Launchpad team is doing, process-wise. The PQM seems like a very nice idea for a bigger team like theirs, though it would probably be useful to our smaller team in Landscape too, and to others in general. Hopefully I will get a chance to explore it more and talk about it during the upcoming FISL 10, in Porto Alegre.

Lastly, but not least important, I’m also working on getting nightly builds of the Bzr Installer for Windows rolling, and a more streamlined process for the official builds. Karl Fogel, of Producing OSS fame, and our Launchpad Ombudsman is making sure I keep my promises about that, which is yet another great incentive.

All in all, there’s of course a ton of things I forgot to talk about and which happened in the last 5 months, but this post is already getting too long so I will stop right here and save some of the meat for a future one. Stay tuned!

por Sidnei da Silva em 05 de June de 2009 às 20:27

June 02, 2009

Luciano Ramalho

O diabo da acentuação (2)

Com a explosão da Internet, ficou sem sentido continuar usando sistemas de codificação de caracteres diferentes em cada parte do mundo. Mas para unificar, seria preciso uma codificação que não ia caber em um byte. Então a primeira tentativa foi usar dois bytes, o que permite códigos de \x0000 a \xFFFF, ou seja, 65536 caracteres distintos. Era o que propunham as primeiras versões do padrão Unicode. E assim várias linguagens, inclusive Java, adotaram uma representação interna de strings onde cada caractere equivale a dois bytes.

Outra idéia errada: 1 caractere == 2 bytes



Eu aprendi o que era Unicode estudando Java, e sempre achei normal que um caractere Unicode fosse representado por dois bytes em Java, numa codificação chamada UCS2. Até que em 2006 eu comecei a estudar a linguagem Ruby, e constatei que o suporte a Unicode em Ruby era mais primitivo que em Python. Fiquei surpreso porque o criador de Ruby, Yukihiro Matsumoto, é japonês, e a linguagem é muito popular no Japão.

Mas a propaganda aqui no ocidente é que o Unicode veio para resolver o problema das línguas orientais, então porque faltava um bom suporte em Ruby? Quem pesquisar um pouco o assunto vai descobrir que as primeiras versões do Unicode foram rejeitadas pelo chineses, japoneses e coreanos! Os principais motivos foram (1) a unificação de certos ideogramas que embora visualmente parecidos queriam dizer coisas diferentes e (2) a falta de uma especificação de como estender a codificação para além dos 2 bytes. O segundo ponto é interessante: quando se usa um alfabeto, uma nova palavra é apenas um novo arranjo das mesmas letras; mas em chinês, uma nova palavra pode ser um novo ideograma.

Para resolver este problema, é preciso abstrair um pouco mais...

Unicode é uma tabela de codepoints



O foco do padrão Unicode não é estabelecer uma relação entre caracteres e bytes, e sim uma relação entre caracteres e códigos numéricos chamados codepoints. Como estes codepoints serão representados na memória ou em um arquivo é uma questão secundária, até porque diferentes aplicações vão exigir diferentes representações: um formato bom para transmitir pode ser ruim para processar, por exemplo.

Na documentação do Unicode, os codepoints são identificados por números hexadecimais com o prefixo 'U+'. Veja uma pequena amostra de codepoints e caracteres:

U+6C23 氣 CJK UNIFIED IDEOGRAPH-6C23

U+06BF ڿ ARABIC LETTER TCHEH WITH DOT ABOVE

U+2620 ☠ SKULL AND CROSSBONES

U+0D0B ഋ MALAYALAM LETTER VOCALIC R

U+4DF1 ䷱ HEXAGRAM FOR THE CAULDRON

O texto eu caixa alta em cada linha acima é o atributo "name" do caractere, segundo a tabela Unicode. Além de letras de vários idiomas, o Unicode inclui também símbolos matemáticos, naipes do baralho e até hexagramas do I-Ching.

Vale a pena explorar o site oficial do Unicode, em particular as code charts (tabelas de código) onde os milhares de caracteres aparecem agrupados por idioma ou assunto.

por Luciano Ramalho (noreply@blogger.com) em 02 de June de 2009 às 21:05

O diabo da acentuação

Estamos no meio de uma imensa migração para Unicode, aquela terra prometida onde caracteres acentuados são cidadãos de primeira classe, e até o conceito da energia interior qi pode ser representado na forma original: 氣.

Enquanto não chegamos lá, reina a confusão na terra da acentuação. Em fóruns de programadores a gente vê muita gente perdida, procurando e oferecendo soluções baseadas mais em superstição e mitos do que em razão e fatos.

Este é o primeiro de uma série de posts para tentar esclarecer essa bagunça.

codificação: neste assunto, codicação não tem nada a ver com cifras ou código-fonte. Uma codificação é apenas uma forma de representar caracteres através de códigos numéricos, para armazenagem em computadores digitais.


A idéia errada: 1 caractere == 1 byte



A computação nasceu em países que falam inglês, um idioma onde se usam apenas as 26 letras de A a Z, sem acentos nem cedilhas [1]. Além disso, a memória das máquinas era muito limitada, então depois de alguma briga entre fabricantes americanos e usuários europeus se estabeleceu a idéia equivocada de que um byte corresponde a um caractere.

Essa idéia simplista gerou codificações como esta (clique na figura para ampliar):



Esta figura na verdade representa uma série de gambiarras, uma em cima da outra. Para começar, a faixa preta representa caracteres projetados para controlar um teletipo, um equipamento mais obsoleto até que um mimeógrafo. Por exemplo, o caractere '\x0C' [2], serve para avançar uma folha no papel e o '\x07' é o BELL, faz o teletipo tocar um sino para chamar a atenção do operador!

Apenas três destes caracteres de controle são largamente utilizados hoje: o HORIZONTAL TAB ('\x09'), o LINE FEED ('\x0a') e o CARRIAGE RETURN ('\x0d'). Os 32 caracteres de controle, bem como a faixa azul, formam o padrão ASCII (pronuncia-se ásqui, e não ásqui-2), totalizando 128 caracteres.

A faixa verde é a tabela ISO-8859-1, também conhecida como Latin-1, uma das várias tabelas de caracteres criadas na norma ISO-8859 para padronizar conjuntos de caracteres alfabéticos. Na tabela Latin-1 aparecem todos os caracteres usados nos idiomas da Europa ocidental. A mesma norma ISO inclui outras tabelas, como a ISO-8859-2 (Latin-2), para idiomas da Europa oriental (como Polonês, Tcheco e Húngaro) e a ISO-8859-5 que contém letras do alfabeto cirílico usado na Russia, Bulgaria, Sérvia etc. [3]

As duas fileiras vermelhas são um "puxadinho" feito pela Microsoft. A norma ISO-8859 reservava estas 32 posições para ainda mais caracteres de controle, que nunca "pegaram", então a Microsoft inventou um padrão chamado "CP-1252" [4] que é basicamente a combinação de ASCII com Latin-1 e mais 27 símbolos como o € (euro) o • (bullet) e as aspas assimétricas “assim” que tanto atrapalham a nossa vida de programadores.

Muitos aplicativos, especialmente no mundo Windows, alegam usar a codificação ISO-8859-1 mas na verdade usam CP-1252, violando a lei de Postel [5]. Isso causa alguma confusão porque se você tenta ler um arquivo CP-1252 como se fosse ISO-8859-1, seu programa não vai saber o que fazer com os €, •, “aspas” etc. Mas o inverso não causa problemas: você sempre pode ler um ISO-8859-1 como se fosse CP-1252, porque o primeiro é um sub-conjunto do segundo.

E o 氣?



Realmente não tem espaço naquela tabela para o caractere chinês do "qi" e os outros milhares de caracteres chineses, japoneses, coreanos, ou para dezenas de idiomas que não usam o alfabeto latino, como árabe, hebraico, tailandês e sânscrito. Essa constatação acabou com o princípio de que "1 byte == 1 caractere", e nos conduziu ao Unicode, tema do próximo post.




[1] na verdade, isso já é uma simplificação; qualquer dicionário de inglês tem a palavra façade (fachada), escrita assim mesmo, com cedilha; a palavra virou até um termo técnico em engenharia de software, pois é o nome de um dos padrões de projeto originais.


[2] \x0C é hexadecimal, em decimal seria 12


[3] a ISO-8859-1 (Latin-1) continua importante até hoje, mas a ISO-8859-5 "não pegou". Os russos preferem outros padrões, como KOI-7 ou KOI-8.


[4] conhecido também como "codepage 1252" ou oficialmente "Windows-1252"


[5] "Seja liberal no que aceita conservador no que envia". Procure "Postel Law" no Google e aprenda um princípio realmente importante e útil para a engenharia e para a vida em sociedade.

por Luciano Ramalho (noreply@blogger.com) em 02 de June de 2009 às 20:29

May 29, 2009

Marco André Lopes Mendes

SCS2009 - Mehran Misaghi

Palestra apresentada por Mehran Misaghi na SCS2009 - Semana de Computação da SOCIESC, no dia 18/05/2009.

por Marco André Lopes Mendes (noreply@blogger.com) em 29 de May de 2009 às 07:41

May 28, 2009

Marcos Petry

Busca full-text do mysql no django

Essa semana tive que implementar em um dos meus projetos um sistema de busca full-text. como estou utilizando o Mysql, ele possui um mecanismo de pesquisa integrado. Há outras bibliotecas de pesquisa como o Lucene, Xapian e Sphinx e todas elas possuem modulos para integra-las ao Django(django-search-lucene, djapian e django-sphinx ) mas no meu caso, como estou utilizando uma hospedagem compartilhada, tenho certas restrições para instalar algumas bibliotecas, portanto tive que partir para esta alternativa.

Bom, vamos ao que é necessário para funcionar a busca:

digamos que você possui um model de noticias:
class Artigo(models.Model):
data_publicacao = models.DateTimeField("Data de Publicação", default=datetime.now)
titulo = models.CharField(max_length=200)
slug = models.SlugField()
texto = models.TextField("Texto da noticia")

class Meta:
ordering = ['-data_publicacao']
get_latest_by = 'data_publicacao'

def __unicode__(self):
return self.titulo


Como esperado, o código acima vai gerar um tabela no banco, mas, para a busca funcionar corretamente, teremos que criar "no braço" um índice fulltext para efetuar a busca. Como estamos utilizando o mecanismo de busca do próprio banco. O índice será atualizado automaticamente quando registros são inseridos, atualizados, ou excluídos, de modo que os resultados da pesquisa nunca estarão desatualizada. A declaração CREATE INDEX é utilizado para criar o índice:
CREATE FULLTEXT INDEX fti_noticias_artigo ON noticias_artigo(titulo,texto)


Bom agora teremos que estender esta funcionalidade ao ORM do Django e criar um manager para o model em que você quer fazer a busca. Para isso simplesmente copie este código no seu models, ou melhor, coloque em um arquivos separado, já que você poderá aproveitá-lo em outros models!

Agora, chame o manager do código, atribuindo ao atributo objects (ou qualquer outro que você criar) passando como parâmetro os campos que você indexou no mysql:
objects = SearchManager(('titulo', 'texto'))


e está pronto!

agora para realizar alguma busca utilize o seguinte comando:

Artigo.objects.search('minha busca')


o método search executará uma consulta, verificando se a string que você enviou se encontra em um dos campos que você estabeleceu no seu SearchManager.

algo mais ou menos assim:
SELECT titulo, data_publicacao, slug, texto, MATCH(titulo, texto) AGAINST ('minha busca')
AS `relevance`
FROM noticias_artigo
WHERE MATCH(titulo, texto) AGAINST ('minha busca')


O seu manager também inclui um campo extra na sua consulta chamado relevance, que é o indice de relevância da sua pesquisa. Desse modo é possivel efetuar uma ordenacão através deste campo.

Artigo.objects.search('minha busca').order_by('relevance')


bom era isso! qualquer duvida, reclamação, ou colaboração de código, é só comentar!

por Marcos Daniel Petry (marcospetry@gmail.com) em 28 de May de 2009 às 15:16

Aprenda Python

Livro Python para desenvolvedores

Ótima iniciativa do Luiz Eduardo Borges de escrever um livro de Python em português.Colei na íntegra a mensagem de lançamento do livro:------- Início -------"Python para desenvolvedores" é o primeiro livro livre sobre Python em português a ser distribuído sob a licença Creative Commons (Atribuição-Uso Não-Comercial-Compartilhamento pela mesma Licença 2.5 Brasil)."Python para Desenvolvedores",

por Vinicius Assef (noreply@blogger.com) em 28 de May de 2009 às 02:59

May 27, 2009

Marco André Lopes Mendes

Cópia de segurança e sincronização com o Dropbox


Dropbox é uma ferramenta que facilita fazer cópias de segurança de arquivos de um computador e a sincronização entre diversos computadores, mesmo que utilizem sistemas operacionais diferentes. Existem no momento versões para Windows, Mac e Linux.

Mas afinal o que é o Dropbox e o que ele tem de tão especial? A vantagem inicial é permitir que se faça uma cópia de segurança de um conjunto de dados de forma transparente. Basta copiar os arquivos para uma pasta previamente definida e o conteúdo é automaticamente sincronizado com a pasta do servidor. Estes dados ficam disponíveis e podem ser acessados a partir de qualquer navegador web. Desta forma, ele substitui com algumas vantagens as cópias feitas com dispositivos USB, o envio de arquivos por email e mesmo as cópias por ssh ou rsync.

No meu caso, tenho meus documentos pessoais e de trabalho sincronizados entre meus dois computadores e disponíveis sempre que eu preciso. Recentemente, comecei a editar um documento na minha estação de trabalho em casa. Mais tarde, sentei com minha mulher no sofá da sala e finalizei o documento a partir do notebook, sem ter que carregar o arquivo de um pra outro. Tenho utilizado também para deixar sempre à mão artigos e outros textos que posso ler sempre que sobra um tempo. Fotos e vídeos copiados da máquina digital acabam indo pra esta pasta também, pra depois ir pro seu lugar de armazenamento definitivo.

O grande potencial do Dropbox se revela quando o instalamos em diversos computadores, utilizando a mesma conta. Quando isto é feito, qualquer modificação realizada em uma das pastas é automaticamente sincronizada na web e, a partir de lá, para os demais computadores. Quem utiliza computadores diferentes no trabalho e em casa, sabe o quanto isto pode ser útil. Usuários de netbooks que mantém estações de trabalho ou notebooks para trabalhos mais pesados podem se beneficiar da ferramenta também. Outro uso interessante é na sincronização de pastas quando se utiliza máquinas virtuais no mesmo computador.

Um dos problemas que pode-se perceber no uso da ferramenta é no uso do link de Internet. Isto pode ser bem visível na sincronização inicial, ou quando copia-se arquivos muito grandes. Se você tem um bom link, não deve ser preocupar com isso. Outro situação que pode gerar um problema ocorre quando se apaga um arquivo de um lugar, e ele é apagado de todos. Desta forma, faça sempre uma cópia de segurança de seus dados mais inportantes. Por fim, à medida que vamos nos acostumando com o uso dele, o limite de 2 GB pode tornar-se um problema.

Se você quer começar a usar o Dropbox, o primeiro passo é criar uma conta, clicando aqui. O processo de criação da conta é muito rápido e simples. Ao criar uma conta, são fornecidos 2 GB de espaço. Ao criar a partir do link fornecido aqui, você me ajudará a ganhar mais 250 MB de espaço. O limite máximo por conta é de 3 GB. Para conhecer melhor o Dropbox, é possível assistir a um tour no site.

A instalação é bastante simples, e consiste em baixar e executar o arquivo de instalação para Windows, Mac ou Linux a partir da página de instalação do Dropbox. No caso do Linux, existem pacotes para algumas versões de Ubuntu e Fedora, além da possibilidade de adicionar os repositórios no Ubuntu. Neste caso, você será avisado quando houverem atualizações do programa.

Se você já utiliza o Dropbox, que tal contar o que você faz com ele? Se vocẽ não usa e quer saber mais, entre em contato também. Para obter uma conta e começar a utilizar o Dropbox, agora mesmo, clique aqui.

por Marco André Lopes Mendes (noreply@blogger.com) em 27 de May de 2009 às 19:52

SCS2009 - Relato final, vídeos e fotos

A SCS2009 foi um sucesso. Tivemos um bom público durante todo os dias, muita interação com os palestrantes e minicursos lotados de pessoas interessadas.

Os vídeos das palestras já estão disponíveis e quem não assistiu ao vivo tem a chance de ver agora. As fotos também estão disponíveis e dão uma idéia do que aconteceu nos quatro dias de evento. Quem quiser ler todas as postagens relacionadas pode acessar meu blog e conferir. Além disso, você pode ler e postar um comentário pelo twitter, ou aqui mesmo, na área de comentários.

por Marco André Lopes Mendes (noreply@blogger.com) em 27 de May de 2009 às 13:07

Meu roteiro de instalacao do Ubuntu

Este artigo descreve o meu roteiro de atualização dos meus computadores pessoais com o Ubuntu. Eu costumo instalar muitos programas, seja para testar ou mesmo para usar nas aulas que ministro. Assim, a cada seis meses, quando sai uma versão nova do Ubuntu, costumo fazer uma reinstalação completa desses computadores. Eu também costumo adaptar esses computadores ao meu gosto, e sempre que os reinstalo, preciso sair à procura das modificações que havia feito.

Sendo assim, resolvi anotar cuidadosamente cada modificação feita na instalação do Ubuntu 9.04, conhecido como Jaunty Jackalope. Estes roteiro fo criado pensando nas minhas necessidades, porém acredito que muitas das configurações aqui descritas podem ser úteis para outras pessoas. Percebi também que muitas configurações que eu fazia, vieram por padrão nesta versão do Ubuntu.

Se você tem dúvidas, correções a fazer ou outras configurações a sugerir, envie um comentário. Terei prazer em ler e responder.

Configurações do firefox:
- Tirar barra de favoritos
- Mudar ícones para pequenos
- Colocar ícone de "Nova aba"
- Colocar página inicial: http://google.com/ig
- Adicionar Pesquisas: http://mycroft.mozdev.org/
-- MercadoLivre, Youtube, Torrenttab







Configurações do ambiente de trabalho:

- Colocar ícones na barra superior: terminal e gedit
- Retirar ícones: help e evolution
- Colocar lista de abas na barra superior
- Retirar barra inferior
- Mudar tema e papel de parede
- Habilitar efeitos








- Baixar e instalar o Ubuntu perfeito

Instalar extensões do Firefox:
- Adblock Plus
- Better GReader
- Colt
- Delicious
- Download Helper
- Forecastfox l10n
- Google Preview

- noScript
- Twitterfox

- Ubuntu Firefox Modifications
Screenlets
- Relogio, Calendário, Temperatura do processador

Fonte Monaco
- Instalar a fonte:
cd /usr/share/fonts/truetype
sudo mkdir myfonts
cd myfonts
sudo cp /dados/downloads/Monaco_Linux.ttf .
sudo chown root.root *.ttf
sudo mkfontdir
cd ..
fc-cache

Configurações de Terminal:
- Histórico do bash: adicionar:
export HISTSIZE=5000
- Alias: descomentar linhas de .bashrc

- .inputrc:


set completion-ignore-case On
"\e[B": history-search-forward
"\e[A": history-search-backward


Vi
set completion-ignore-case On
"\e[B": history-search-forward
"\e[A": history-search-backward

sudo aptitude install vim-full

Latex:
sudo aptitude install texlive texlive-humanities latex-beamer abntex aspell-pt-br \
gedit-plugins rubber texmaker

Webcam:
sudo aptitude install cheese

Man colorido
- instalar most
- sudo update-alternatives --config pager

Configurar Skype
- A definir: como fazer o mic interno funcionar

Python:
sudo aptitude install ipython
- baixar e instalar o wind-ide-101

Gedit:
- ativar plugins e modificar configurações (pendente)
- Utilizar fonte Monaco
- instalar plugins: latex open_terminal better_python_console
- gedit-latex-plugin_0.1.3.1-2~0ubuntuitdev1_i386.deb

Gnome-do:
sudo aptitude install gnome-do gnome-do-plugins

Nautilus:
sudo aptitude install nautilus-open-terminal
- baixar e instalar
-- nautilus-send-gmail_0.1.1-1_all.deb
-- nautilus-rename-exif-date_0.1.1-1_all.deb - trocar linhas:
-- Alterar o programa /usr/lib/nautilus/extensions-2.0/python/nautilus-rename-exif-date.py
def menu_activate_cb(self, menu, names):
"""Called when the user selects the menu. Rename the selected files."""
for path in names:
img_file = open(path, "rb")
tags = EXIF.process_file(img_file)
date = str(tags["EXIF DateTimeOriginal"]).replace(":", "-", 2)
date = date.replace(":", "", 1)
date = date.replace(":", "", 1)
date = date.replace(":", "",1)
date = date.replace(" ", "-",1)

dir_name = os.path.split(path)[0]
file_name = os.path.split(path)[1]
parts = file_name.split(".")
if len(parts) == 1:
extension = ""
else:
extension = "." + parts[-1].lower()
os.rename(path, dir_name + "/" + date + extension)
Adicionar scripts a ~/.gnome2/nautilus-scripts (menu de contexto)

Picasa:
# Google
Adicionar ao /etc/sources.list:
deb http://dl.google.com/linux/deb/ stable non-free deb http://dl.google.com/linux/deb/ testing non-free sudo aptitude install picasa
Links simbólicos para pastas: ln -s destino
aulas -> /dados/MARCOANDRE/aulas/
documentos -> /dados/documentos/
imagens -> /dados/imagens/
musicas -> /dados/musicas/
videos -> /dados/videos/

Ativar o CTRL+ALT+BACKSPACE:
sudo vi /etc/X11/xorg.conf
Section "ServerFlags"
Option "DontZap" "false" EndSection

Impressora Brother do IST:
sudo aptitude install brother-cups-wrapper-laser

DVD:
sudo aptitude install dvdrip devede

Jpilot:
sudo aptitude install jpilot jpilot-plugins jpilot-backup jppy-jpilot-plugins

Diff:
sudo aptitude install meld

Gcompris:
sudo aptitude install gcompris-sound-ptbr

IRC:
sudo aptitude install xchat
- Modificar encoding para utf-8
- Usar fonte Monaco

Desinstalar:
-sudo aptitude remove evolution ekiga

Instalar:
- amule
- gparted
- powertop

Quebra-cabeça:
- instalar xij:
sudo aptitude install xjig -criar script quebra_cabeca:
#!/bin/bash eog $1 & xjig -side p -h 6 -ww 320 -file $1 &
- colocar na pasta de scripts do Nautilus
cp /usr/local/bin/puzzle /home/marco/.gnome2/nautilus-scripts/

por Marco André Lopes Mendes (noreply@blogger.com) em 27 de May de 2009 às 12:53

May 26, 2009

Aprenda Python

Criando dicionários com uma sintaxe mais prática

Em python, um dicionário é o mesmo que um array associativo em PHP. Ou seja, uma lista indexada por chaves (keys) que podem ser strings e apontam para valores.Para criar um dicionário, a sintaxe é:d = {'fruta': 'goiaba', 'dia': 'sabado', 'nome': 'maria'}Um jeito diferente de criar o mesmo dicionário é usando o construtor dict(), assim:d = dict([('fruta', 'goiaba'), ('dia', 'sabado'), ('nome', '

por Vinicius Assef (noreply@blogger.com) em 26 de May de 2009 às 00:10

May 25, 2009

Marco André Lopes Mendes

Teste de Nerd do G1

Fiz mais um teste de Nerd, este do G1. Tirei 85, um pouco mais do que tirei antes. Estou em forma. Segue a prova:

E você, também é nerd? Faça o teste e comente aqui.

Links relacionados:

por Marco André Lopes Mendes (noreply@blogger.com) em 25 de May de 2009 às 11:58

Arthur Furlan

Hello world, again

merlin Yep, that's the second time I post a "Hello world" entry here. The reason is that I recently moved my domain from an account at Bluehost to a VPS at Linode. So, first of all, I would like to introduce you to merlin, my new VPS. :)

As I'm the sysadmin behind my server now, I decided to not install mod-php here and then I had to change my blog engine. I used to run Wordpress for years and now I'm running django-diario, a wonderful blog engine for django made by Brazilian djanglers.

About this new version of my old blog, you may have noticed that it has only this post... That's right, I removed the old stuff (in fact I just didn't migrate them from Wordpress) and I intend to start translating and re-posting a small part of them as soon as possible. If you want to see here any specific post from my old blog, please, let me know.

As you can see now I'm writing in English and I used to write in Portuguese... I'm not a professional English writer, so you won't be a lucky guy if you find some bugs around here and if you do find something, please, let me know about it and I will gladly fix it.

You'll probably see at here lots of posts about python and debian. This time I'll also try to write more often and in small chunks. :)

I think that's all...

25 de May de 2009 às 07:06

May 24, 2009

Marco André Lopes Mendes

SCS2009 - As fotos do evento

De 18 a 22 de maio de 2009, aconteceu a Semana de Computação da SOCIESC, com palestras e minicursos. As fotos estão disponíveis abaixo.


Link para as fotos

Links relacionados:
Todos as postagens sobre a SCS2009


por Marco André Lopes Mendes (noreply@blogger.com) em 24 de May de 2009 às 20:04

SCS2009 - Alcir

Palestra apresentada pelo acadêmico Alcir na SCS2009 - Semana de Computação da SOCIESC, no dia 21/05/2009.

por Marco André Lopes Mendes (noreply@blogger.com) em 24 de May de 2009 às 19:58

SCS2009 - Marcus Silva

Palestra apresentada por Marcus Silva na SCS2009 - Semana de Computação da SOCIESC, no dia 21/05/2009.

por Marco André Lopes Mendes (noreply@blogger.com) em 24 de May de 2009 às 19:58

SCS2009 - Leandro Godinho

Palestra apresentada pelo acadêmico Leandro Godinho na SCS2009 - Semana de Computação da SOCIESC, no dia 21/05/2009.

por Marco André Lopes Mendes (noreply@blogger.com) em 24 de May de 2009 às 19:58

SCS2009 - Céu Games

Palestra apresentada pela Céu Games na SCS2009 - Semana de Computação da SOCIESC, no dia 21/05/2009.

por Marco André Lopes Mendes (noreply@blogger.com) em 24 de May de 2009 às 19:58

May 22, 2009

Marco André Lopes Mendes

SCS2009 - Fernado Paes

Palestra apresentada por Fernando Paes na SCS2009 - Semana de Computação da SOCIESC, no dia 19/05/2009.

por Marco André Lopes Mendes (noreply@blogger.com) em 22 de May de 2009 às 16:10

SCS2009 - Julio Monteiro

Palestra ministrada por Júlio Monteiro na SCS2009 - Semana de Computação da SOCIESC, no dia 19/05/2009.

por Marco André Lopes Mendes (noreply@blogger.com) em 22 de May de 2009 às 06:53

SCS2009 - MIC e Rafael Mendes

Palestra apresentada pelos alunos do MIC e por Rafael Mendes na SCS2009 - Semana de Computação da SOCIESC, no dia 19/05/2009.

por Marco André Lopes Mendes (noreply@blogger.com) em 22 de May de 2009 às 06:53

SCS2009 - Luciano Ramalho 2/2

Parte 2 de 2 da palestra apresentada por Luciano Ramalho na SCS2009 - Semana de Computação da SOCIESC, no dia 18/05/2009.

por Marco André Lopes Mendes (noreply@blogger.com) em 22 de May de 2009 às 04:17

SCS2009 - Semana de Computação da SOCIESC 2009

De 18 a 21 de maio de 2009, acontecerá na SOCIESC, Campus Marquês de Olinda, em Joinville/SC, a Semana de computação da SOCIESC (SCS2009). A programação inclui palestras com professores, profissionais da área de Tecnologia da Infomação e personalidades da comunidade de software livre. Teremos ainda apresentações de acadêmicos e egressos dos cursos. Na quarta-feira, a noite será reservada para minicursos. Para se inscrever nos minicursos, basta preencher o formulário. A SCS2009 é aberta ao público e todos são convidados a participar.

Quem quiser acompanhar ou comentar o evento pelo Twitter, utilize a tag #scs2009.

Abaixo, a programação do evento:



Para se inscrever nos minicursos, preencha o formulário abaixo:



Serviço:
O que: Semana de Computação da SOCIESC 2009
Quando: de 18 a 21 de maio de 2009 (segunda a quinta-feira), de 19:15 até 22:45
Onde: SOCIESC, Campus Marquês de Olinda, Rua Gothard Kaesemodel, 833, Joinville - SC
Quanto: gratuito
Quem pode participar: aberto ao público
Informações: 47 3461-0517

Leia outros textos publicados aqui sobre a SOCIESC.

por Marco André Lopes Mendes (noreply@blogger.com) em 22 de May de 2009 às 04:13

SCS2009 - Luciano Ramalho 1/2

Parte 1 de 2 da palestra apresentada por Luciano Ramalho na SCS2009 - Semana de Computação da SOCIESC, no dia 18/05/2009.

por Marco André Lopes Mendes (noreply@blogger.com) em 22 de May de 2009 às 04:11

May 16, 2009

Bruno Gola

São Paulo Python User Group - May Meeting

Every month the GruPy-SP members get together to discuss, chat and/or code.

This month we will meet to watch/present some lightning talks and to talk about our participation at the Fórum Internacional de Software Livre (FISL 10).

The meeting will be hold at the SP HackLab, May 23. More details (in pt-br): GruPy-SP wiki.

See you there :-)

por Bruno Gola em 16 de May de 2009 às 13:29

Gustavo Niemeyer

Changing people or changing rules

In my previous post I made an open statement which I’d like to clarify a bit further:

(…) when the rules don’t work for people, the rules should be changed, not the people.

This leaves a lot of room for personal interpretation of what was actually meant, and TIm Hoffman pointed that out nicely with the following questioning in a comment:

I wonder when the rule is important enough to change the people though. For instance [, if your] development process is oriented to TDD and people don’t write the tests or do the job poorly will you change them then?

This is indeed a nice scenario to explore the idea. If it happens at some point that a team claims to be using TDD, but if in practice no developer actually writes tests first, the rules are clearly not working. If everyone in the team hates doing TDD, enforcing it most probably won’t show its intended benefits, and that was the heart of my comment. You can’t simply keep the rule as is if no one follows it, unless you don’t really care about the outcome of the rule.

One interesting point, though, is that when you have a high level of influence over the environment in which people are, it may be possible to tweak the rules or the processes to adapt to reality, and tweaking the processes may change the way that people feel about the rules as a consequence (arguably, changing people as a side effect).

As a more concrete example, if I found myself in the described scenario, I’d try to understand why TDD is not working, and would try to discuss with the team to see how we should change the process so that it starts to work for us somehow. Maybe what would be needed is more discussion to show the value of TDD, and perhaps some pair programming with people that do TDD very well so that the joy of doing it becomes more visible.

In either case, I wouldn’t be simply asking people “Everyone has to do TDD from now on!“, I’d be tweaking the process so that it feels better and more natural to people. Then, if nothing similar works either, well, let’s change the rule. I’d try to use more conventional unit testing or some other system which people do follow more naturally and that presents similar benefits.

por Gustavo Niemeyer em 16 de May de 2009 às 13:02

May 15, 2009

Marco André Lopes Mendes

Palestras ministradas pelo Luciano Ramalho

No dia 18 de maio de 2009, Luciano Ramalho ministrará uma palestra na SOCIESC, abrindo a Semana da Computação 2009. Luciano Ramalho é presidente da Associação Python Brasil para o período de 2007 a 2009 e foi um dos três indicados na categoria Personalidade do Ano do Prêmio Info de 2008. Como forma de aquecimento, separei algumas palestras ministradas por ele, ou que ele participou e que estão disponíveis na Internet.:

Palestra relâmpago na Pycon 2009, em Chicago (a dele é a terceira, começando por volta de 6:15):

Link do vídeo

Orientação a Objetos em Python, na PyConBrasil 2008, em 18/10/2008:

Link do vídeo

Uma arquitetura de componentes em Python, no Grupy-SP, em 11/12/2007:

Link do vídeo

Sobre a Associação Python Brasil, na PyConBrasil 3, em 31/08/2007:

Link do vídeo

Django X Plone X Grok, na PyConBrasil 3, em 31/08/2007 :

Link do vídeo

Painel: Software livre no governo brasileiro, na PyConBrasil 3, em 31/08/2007:

Link do vídeo

Se alguém encontrar outras, envie um comentário e eu as incluo aqui. Após o evento, pretendo disponibilizar também a palestra que será apresentada na SOCIESC.

Textos relacionados:

por Marco André Lopes Mendes (noreply@blogger.com) em 15 de May de 2009 às 18:43

Senra em: a trajetória de um profissional da computação

Em 06 de agosto de 2008, tivemos o prazer de receber na SOCIESC o mestre Rodrigo Dias Arruda Senra. A palestra, entitulada "A trajetória de um Profissional da Computação - Confissões de um hacker tupiniquim", foi apresentada aos alunos de computação da SOCIESC. Abaixo, a primeira parte da palestra, de um total de dois:


Link do vídeo

Na palestra, Rodrigo Senra falou da sua experiência acadêmica e profissional e também do envolvimento com a comunidade de software livre e com a comunidade Python, no Brasil e no mundo. Vale lembrar que foi dele a primeira tradução para o português do Tutorial de Python e foi ele também o organizador da primeira edição da PyCon Brasil.

por Marco André Lopes Mendes (noreply@blogger.com) em 15 de May de 2009 às 17:52

Gustavo Niemeyer

Class member access control: enforcement vs. convention

For a long time I’ve been an advocate of Python’s notion of controlling access to private and protected members (attributes, methods, etc) with conventions, by simply naming them like “_name”, with an initial underline.  Even though Python does support the “__name” (with double underscore) for “private” members (this actually mangles the name rather than hiding it), you’ll notice that even this is rarely used in practice, and the largely agreed mantra is that convention should be enough and thus one underscore suffices. This always resonated quite well with me, since I generally prefer to handle situations by agreement rather than enforcement. Well, I’m now changing my opinion.that this works well for this purpose, at least in certain situations.

This methodology may work quite well in situations where the code scope is within a very controlled environment, with one or more teams which follow strictly a single development guideline, and have the power to refactor the affected code base somewhat easily when the original decisions are too limiting.

Having worked on a few major projects now, and some of them being libraries which are used by several teams within the same company or outside, I now perceive that people very often take shortcuts over these decisions for getting their job done quickly. It’s way easier to simply read the code and get to the private guts of a library than to try to get agreement over the right way to do something, or sending a patch with a suggested change which was carefully architected.

Many people by now are probably thinking: “Well, that’s their problem, isn’t it? If their code base breaks on the next upgrade they’ll get burden and won’t be able to upgrade cleanly.”, and I can honestly understand this feeling, since I shared it. But, for a number of reasons, I now understand that this isn’t just their problem, it’s very much my problem too.

Most importantly, on any serious software, these problems will usually come back to the implementors, and many times the problem will have a much larger magnitude by then than they had at the time a change could have been done “the right way” on the implementation, because code dependent on the private bits will have settled.

Most people are optimist by nature and believe that the implementation won’t change, but, of course, one of the reasons why private information is made private in the first place is exactly because the implementor believes that having the freedom to change these details in the future is important, and not rarely there’s already a plan of evolution in place for these private pieces, which may include revamping the implementation entirely for scalability or for other goals.

In the best case, the careless people will get burden on the upgrade and will ask for support or simply won’t upgrade silently, and both cases hurt implementors, because providing support for broken software takes time and energy, and amazingly can even hurt the software image. Lack of upgrades also means more ancient versions in the wild to give support for. Besides these, in the worst case scenario, the careless people have enough influence on the affected project to cause as much burden on it as if the private data was public in the first place.

As much as I’m a believer in handling situation by agreement rather than enforcement, I’m also a believer that when the rules don’t work for people, the rules should be changed, not the people. So my positioning now is that the language supported access constraints (public, protected, private), as available in languages like Java and C++, are a better alternative when compared to convention as used today in Python, since they provide an additional layer of encouragement for people to not break the rules carelessly, and that helps in the maintenance and reuse of software that has greater visibility.

por Gustavo Niemeyer em 15 de May de 2009 às 09:26

May 14, 2009

Kodumaro

Um «Olá Mundo!» pequenininho

tcl.jpg Como este blog estava muito parado, resolvi postar um «Olá Mundo!» com janela de duas linhas em Tcl/Tk:
wm title . Hello
grid [ button .bt -text { Olá Mundo! } -command exit ]


Se preferir, pode ser criado um script autoexecutável acrescentando o hash-bang:
#!/bin/sh
#\
exec wish "$0" "$@"

wm title . Hello
grid [ button .bt -text { Olá Mundo! } -command exit ]


[]'s
Cacilhas, La Batalema

por noreply@blogger.com (La Batalema) em 14 de May de 2009 às 22:03

May 11, 2009

Allan Garcia

Como instalar o Ruby on Rails no Ubuntu 8.10

Estive pesquisando esses dias sobre o Rails (www.rubyonrails.org) e não existe um jeito muito fácil de instalar a versão mais nova do Rails (2.3), no Ubuntu 8.10, sem meter a mão na massa um pouco. Depois de vários testes percebi um caminho menos traumático.

Um “erro” comum é o “Invalid Rdoc Format”, devido a defasagem do Rdoc em relação ao Rake, e quando se tenta instalar o Rake este dispara o “Warning” mencionado.

Eis o “quicktour” que utilizei:

Instalar o pacote inicial do ruby

$ sudo aptitude install ruby ruby-dev libruby libreadline-ruby libopenssl-ruby irb ri rdoc

Instalar o suporte a sqlite3, padrão para o Rails 2.3

$ sudo aptitude install libsqlite3-ruby

Instalar o rubygems a partir do fonte

$ wget http://rubyforge.org/frs/download.php/56227/rubygems-1.3.3.tgz
$ tar -zxvf rubygems-1.3.3.tgz
$ cd rubygems-1.3.3
$ sudo ruby setup.rb
$ cd /usr/local/bin
$ sudo ln -s /usr/bin/gem1.8 gem

Atualizar o rdoc para não dar o erro mencionado acima

$ sudo gem install rdoc

Instalar o Rails

$ sudo gem install rails

Para iniciar rapidamente um projeto Rails e testar se está tudo funcionando faça

$ cd ~
$ rails projeto
$ cd projeto
$ ruby script/server

Agora acesse no seu browser http://localhost:3000

por Allan Garcia em 11 de May de 2009 às 15:46

May 10, 2009

Flavio Ribeiro

Marmota: making arduino and mobile devices talk

Olá pessoas,

Tirando a poeira aqui do blog pra anunciar meu novo toy project cujo anuncio deveria ser feito só quando eu tivesse algum resultado concreto, mas com o animo na evolução de hoje resolvi publicar logo.

Tenho atualizado o meu twitter bem mais vezes que esse blog pela facilidade que é twittar (principalmente quando você tem um plugin pra seu browser como eu). Lá fico sempre atualizando sobre o que estou fazendo, como as coisas no projeto estão indo, referências a sites onde aprendi a usar o motor de passo, transistores, etc.

Como você leu no fim do parágrafo anterior, o meu novo projeto é relacionado a robótica e microeletrônica. A idéia principal é fazer o meu arduino se comunicar com dispositivos móveis como celulares symbian e internet tablets através de qualquer protocolo, seja ele “wired” ou não.

Pra comecar a brincadeira comprei um módulo bluetooth chamado BlueSMIRF Gold que implementa toda a stack bluetooth e para integrar ao seu arduino basta você ligar o TX do BlueSMIRF no RX do arduino, e o RX no TX do mesmo. Ligando também o pino Vcc do módulo em uma tensão de 5v (que pode ser o pino 5v do arduino) e o GND no terra, você já pode parear o bluesmirf com seu computador e abstrair a conexão bluetooth como sendo uma porta serial, simples assim. Pretendo fazer um outro post ou um artigo no site do marmota detalhando a ligação desse módulo assim que aprender mais sobre ele.

Sim, e antes que eu me esqueca, eu terminei pagando muito caro por esse BlueSmirf. Fora os 60 dólares do módulo, paguei 30 dólares pela entrega e ainda tive o azar do módulo ter parado na Receita. Lá se foram mais 120 reais de imposto, e no fim eu não quis nem somar as despesas e saber quanto o bichinho saiu pra mim.

Comprei também um ProtoShieldBR do gaúcho Rafael Quines que fez um excelente trabalho no desenvolvimento desse shield. A idéia básica do ProtoShieldBR é ser uma plaquinha de propósitos gerais, cheias de barramento onde você vai posicionando os seus componentes da maneira que achar melhor - estilo protoboard - só que em cima do seu arduino. Se não fosse o meu ferro de solda de 5 reais as soldas teriam ficado bem bonitinhas e o resultado final teria sido mais bacana.

Voltando pra os objetivos do toy project; O pontapé inicial do Marmota é fazer um carrinho de controle remoto controlado por um celular s60 através do bluetooth usando python. A parte “física” do carro já tá pronta e hoje consegui comandá-lo via bluetooth usando pySerial no meu notebook. Já fiz também a interface da aplicação PyS60, faltando só criar a classe de socket bluetooth do celular. Falta também dar uma regulada no motor de passo responsável pelo direcionamento do carro, mais algumas colas e soldas, e rodas emborrachadas pra ter uma tração maior com o chão.

Tenho já algumas idéias de interação do arduino com internet tablets, andei pesquisando sobre shields ethernet e até vi que já fizeram um webserver simples pra ele. Já pensou você controlando luzes, alarmes, cameras de vigilância e etc tudo no seu browser aonde você estiver e o arduino do outro lado dando conta de tudo? Show de bola.

Pra finalizar, quem quiser debater, ajudar, dar mais idéias e etc, dê uma lida no site do Marmota. Prometo atualizar ele com fotos, videos e códigos tanto do lado arduino como a aplicação pys60 do lado mobile quando esse primeiro projeto for finalizado. Quem quiser acompanhar mais de perto os passos pra finalização desse projeto, siga-me no twitter!

É isso, até a próxima pessoal :)

por Flávio Ribeiro em 10 de May de 2009 às 19:15

May 08, 2009

Marco André Lopes Mendes

Entrevista na Rádio Globo: Segurança na Internet

Participei do programa do Jota Martins na Rádio Globo hoje, dia 04 de abril de 2009. O tema era Segurança na Internet. Falamos sobre vírus, cavalos de tróia, formas de se proteger, configuração ideal do computador e assuntos relacionados. Acredito que a entrevista possa servir para você ou ser compartilhada com outras pessoas, que tenham dúvidas sobre este assunto.

A entrevista foi feita pelo telefone, então a minha voz está um pouco mais baixa que a dele, mas dá pra entender bem. Ela durou 14 minutos, e o arquivo tem aproximadamente 13 MB.

Coloquei a entrevista no Internet Archive. Dá pra ouvir online ou baixar pra ouvir no computador, no carro ou no mp3 player.


por Marco André Lopes Mendes (noreply@blogger.com) em 08 de May de 2009 às 21:42

Vídeos do Bossa Conference estão disponíveis

Os vídeos do Bossa Conference 2009 estão disponíveis para assitir online:



Não tenho certeza se todos os vídeos já estão disponíveis, mas já tem muita coisa.

por Marco André Lopes Mendes (noreply@blogger.com) em 08 de May de 2009 às 21:41

Em que linguagem Charlie está programando?

No episódio 20 da quinta temporada de Numb3rs (E05S20), Charlie está tentando resolver um problema utilizando uma implementação do algoritmo de Dijkstra. Fiquei intrigado e fui olhar de perto o código, que é o que segue:

Clique na imagem para ampliar

Que linguagem é esta, utilizada por ele para implementar o algoritmo? Será que é uma linguagem real ou inventaram para este episódio? Se você sabe ou tem uma idéia, poste um comentário.

por Marco André Lopes Mendes (noreply@blogger.com) em 08 de May de 2009 às 21:41

May 06, 2009

Blog da Liberiun

"Code Completion" em Python

Olá Pessoal!

Primeiro quero me apresentar: Sou Thomaz, novato aqui na Liberiun e pretendo utilizar esse espaço para compartilhar umas dicas interessantes com todos.

Essa dica, apesar de muitos já conhecerem, ainda existem as pessoas que sofrem sem utilizar o querido "code completion" no interpretador Python.

A coisa é bem simples, basta abrir uma sessão python e digitar:

>>> import readline
>>> readline.parse_and_bind("tab: complete")
>>>

Pronto! agora pressione a tecla tab e veja a mágica ;)

>>>
Display all 161 possibilities? (y or n)

Muita gente gosta de deixar isso no bashrc para ficar sempre salvo, eu prefiro criar um script com o seguinte conteúdo:

PYTHONSTARTUP=<(echo 'import readline, rlcompleter; readline.parse_and_bind("tab: complete")') python

salvar esse script em /usr/bin/py e dar permissão de execução para ele (chmod +x /usr/bin/py)
ai toda vez que precisar do shell interativo basta chamar "py" no terminal e pronto ;)

Agora vai ficar muito mais fácil utilizar aquela biblioteca obscura com aqueles métodos complexos sem precisar decorar um monte de nomes estranhos ;)

E de brinde vai outra dica: lembre-se sempre de usar o comando "help(método.obscuro)"! Isso ajuda e muito :)

por Thomaz Reis em 06 de May de 2009 às 12:18

May 05, 2009

Blog da Liberiun

Zine + Plone + wsgi = www.liberiun.com

Um dos maiores desafios da criação de Portais Corporativos é a integração de serviços. Na era pré wsgi e deliverance, tinhamos que escrever muitos "corretivos" para integrar uma aplicação e com a dupla wsgi/deliverance isso tudo mudou.

A Liberiun que vem usando essa dobradinha a um bom tempo e seus frutos são inegáveis!

O antigo blog da Liberiun era feito utilizando uma solução caseira, e atendia a nossa demanda parcialmente, de forma que estudamos muito a sua mudança. Estudos aqui, estudos ali, e escolhemos o Zine para ser nossa aplicação de blog do portal.

A escolha do Zine foi em função de ele ser uma aplicação Python, ser padrão WSGI e ter um skin muito tranquilo para trabalhar com o Deliverance.

Em resumo: Nós estamos utilizando Zine para blogs e novas integrações serão feitas!

Até mais,

Fábio Rizzo
Vice-Presidente Executivo
fabiorizzo@liberiun.com

por Fabio Rizzo em 05 de May de 2009 às 03:32

May 04, 2009

Blog da Liberiun

Desenvolvendo sem reload no Zope

Olá, conheço muita gente que não é adepta a idéia de ter que reiniciar o Zope a cada alteração em uma classe Python. Bom a idéia também não me agrada, e inclusive existem muitos desenvolvedores que perdem produtividade com isso, por nem sempre ter uma boa máquina e as vezes esperam 1 minuto para que o Zope restarte. Mas não é mais preciso fazer isto, foi criado um produto que muda este cenário, o plone.reload. Baixe em: http://pypi.python.org/pypi/plone.reload Com ele instalado você pode acessar um painel bem resumido (http://localhost:8080/@@reload), e através dele simular o restart, fazendo o reload do seu código sem o restart do Zope. É isso, como diriam os cearenses: "Olha as coisas melhorando pra nós!" =) Um abraço.

por Rodrigo Castardo em 04 de May de 2009 às 11:51

DCWorkflowGraph

Olá,

falar sobre workflow (BPM) pode fazer sentido para muita gente, mas nem para todos. Nada como ver uma ilustração não.

Uma vez fui desenhar um workflow e uma pessoa me perguntou brincando: "Você acha que eu não consigo entender sem você desenhar?". A resposta foi: "Não, sou eu quem não consigo explicar sem desenhar".

Então se você, como eu, concorda com isso, você vai gostar do DCWorkflowGraph. Ele é apenas um produto que faz um desenho de qualquer workflow que exista no seu Plone Site.

Baixe em: http://plone.org/products/dcworkflowgraph

Ele possui apenas uma dependência, o Graphviz.

Mas a instalação é simples e está no README do Graphviz.

Assim que você instalar vai ver uma nova aba quando visualizar um workflow, é onde vai estar a ilustração.

Um abraço.

por Rodrigo Castardo em 04 de May de 2009 às 11:43

Repositório OpenSource

Olá pessoal,

é um prazer falar sobre o nosso repositório! Temos criado várias soluções e disponibilizado no seguinte endereço: code.liberiun.com:7777/.

Entre as soluções que temos desenvolvido estão:

  • Liberiun Portal Varnish Cache Manager - uma solução de inteligência entre cache e aplicação
  • Liberiun Portal Banner - solução de Banners utilizada em nossos projetos
  • Lineriun Portal Intranet - framework utilizado na criação de Intranets
  • Liberiun Portal Licita - uma solução para portais de utilizam divulgação de licitações
  • Liberiun Portal News - Mailing e Notícias, uma solução para mehorar as suas notícias e enviá-las ao público do seu portal
  • Liberiun Portal Streaming - solução de streaming para portais
  • Liberiun Portal Utils - framework com os métodos utilizados no cotidiano do desenvolvimento de portais

A política de desenvolvimento de software é norteada pela diretiva de desenvolvimento de soluções livres e de código aberto. Mas como isso funciona na prática?

Nós desenvolvemos uma solução, que surge de uma necessidade interna ou externa, e disponibilizamos a solução e seu código fonte, sem a cobrança de licenças.

Os softwares são utilizados em clientes, ou projetos Plone que não tenhamos atuado diretamente. E este uso gera melhorias, uma evolução natural do software, e com frequência somos procurados para implementar melhorias nos softwares. Então se um cliente X paga por esta melhoria, o cliente Y que utiliza a mesma solução também tem esta nova funcionalidade, porém sem custos. E você que pode não necessariamente é cliente da Liberiun, também ganha a nova funcionalidade sem custos.

Este ciclo têm gerado evoluções em várias de nossas soluções. Entre elas as que temos desenvolvido para grande cases.

Tudo está sendo disponibilizado neste repositório, e vou falar em detalhes sobre cada solução nos próximos posts.

Um abraço.

por Rodrigo Castardo em 04 de May de 2009 às 11:41

GloWorm - facilitando a vida do Plone WebDesigner

Olá,

com a chegada do geração Plone 3 um novo conceito apareceu, as famosas Viewlets. São componentes Zope 3 (explico em um post focado neste assunto) utilizados para melhorar alguns aspectos da reenderização de um Portal Plone, como:

  • Performance, implementações Zope 3 são naturalmente mais leves, rápidas (use!);
  • Migração, através das Viewlets você não precisa mais customizar o template principal do Plone (main_template.pt);
  • Gerenciamento via interface, você pode através de um simples clique esconder alguma parte do layout original.
Apesar dos ganhos acima, entre outros benefícios do surgimento das Viewlets, as pessoas que não tinham conhecimento em Zope 3 (se é seu caso, você está atrasado, mais antes tarde do que mais tarde) não se sentiram à vontade em lidar com este novo conceito, e sua implementação.
 
A fim de facilitar a vida das pessoas que lidam com implementações de layout dentro do Plone, foi lançado o GloWorm. Um produto muito interessante que vai aumentar explonencialmente sua produtividade ao implementar um layout no Plone.
 
Como ele funciona? Ele é o Firebug (www.getfirebug.com) para Plone!
 
Isso mesmo, você habilita o GloWorm e sai clicando na página e inspecionando as Viewlets. Com isso:
  • Você pode identificar de maneira rápida que é a Viewlet que implementa aquela parte do layout (seu template e classe);
  • Customizar a Viewlet;
  • Desfazer a customização;
  • Reordenar a Viewlet, colocar ela acima ou abaixo de onde ela está;
  • Reagrupar Viewlets, ao lidar com Viewlets você se depara com o Viewlet Manager, que é quem agrupa as Viewlets, e com o gloWorm você pode colocar o cabeçalho no rodapé.
Bom, agora você já deve estar curioso, então faz um test drive okay?
 
 
Boa diversão!
 
Um abraço.

por Rodrigo Castardo em 04 de May de 2009 às 11:41

Liberiun Portal News

Olá,

uma das soluções que desenvolvemos é o Liberiun Portal News, esta solução surgiu de alguns projetos combinados com necessidades internas.

Vamos a descrição das features da solução:

Um novo tipo Imagem

Que é configurável, você pode:
  • desabilitar a imagem padrão do Plone (para não confundir o usuário final)
  • habilitar a página de direitos autorais (exibida quando a imagem full size é exibida, você concorda e só então pode ver a imagem)

Um novo tipo Notícia
Que basicamente tem habilitada a funcionalidade descrita abaixo 

Organização de Notícias
É um mecanismo automático de organização das notícias, ele (caso acionado, não é padrão) verifica se existe esta estrutura:

2009 (ou ano corrente) > março (ou mês corrente) > dia corrente > aqui é criada a notícia

Caso não exista a estrutura, ele cria a estrutura e depois a notícia. Esta estrutura é configurável, você cria como quiser.

Envio de Newsletter
Ele envia newsletter, e tem algumas configurações.
 
Cadastro

Existe um cadastro para o envio, neste cadastro você escolhe entre 2 tipos de cadastros, um simples (com nome e e-mail) e outro com mais campos(como sexo, idade, estado e cidade), isto para que seja possível efetuar envios segmentando o público alvo

Envio

Você pode dizer quem são:
  • Remetente
  • Assunto do e-mail
  • Imagem de cabeçalho do e-mail
  • O texto do cabeçalho do e-mail
  • O texto do rodapé do e-mail
  • Filtros

Você ainda pode filtrar:
  • As notícias que serão enviadas (por período)
  • O público alvo
  • Periodicidade
Você pode dizer com qual periodicidade você quer que o Portal envie a newsletter

Importação de Notícias Externas
Esse mecanismo é feito justamente para quem tem Notícias em outra plataforma/sistema e agora está usando Plone, porém quer manter seu histórico de notícias no novo Portal. Ele utiliza um arquivo XML com os dados, facilmente gerado, e com estrutura flexível.

Nele você pode apontar:
  • Se a notícia que será importada vai ser importada como a notícia do liberiun.portal.news, ou se vai ser importada como a notícia padrão do Plone
  • Qual é o arquivo XML
  • Se você deseja que as tags HTML que possam existir devem ser removidas
  • Se deseja a criação da estrutura de pastas
  • Qual é a pasta do Portal que vai receber os objetos criados
  • Por último, você mesmo diz qual é a estrutura do XML desejada

Cases

Alguns dos nossos clientes que estão usando:
  • Caixa Econômica Federal
  • Comitê Paraolímpico Brasileiro
  • Direitos da Criança e do Adolescente
  • Hot Site Pequim (Paraolimpíadas)
  • Conselho Federal de Administração
  • Instituto do Patrimônio Histórico e Artístico Nacional (IPHAN)
O produto encontra-se disponível no nosso repositório open source. Você acessá-lo em: http://code.liberiun.com:7777/repositorios/opensource/plone3/eggs/liberiun.portal.news/
 
Sugestões de melhorias são bem vindas.
 
Um abraço.

 

por Rodrigo Castardo em 04 de May de 2009 às 11:39

Inovação e renovação!

Bem vindos ao nosso novo Portal!

Uma das inovações é o novo Portal, que traz uma nova tecnologia o Deliverance (WSGI), e aproveitando a mudança tecnologica renovamos também o layout do Portal.

O Deliverance é um produto que torna desnecessária a criação de uma Skin Plone, o trabalho de integração que fazia o Plone assumir outra característica visual foi exponencialmente resumido. E grande parte do esforço em pequenos e médios Portais se concentrava nisso, porém com o Deliverance isto não acontece mais.

O trabalho com Deliverance baseia-se na idéia mapear os estilos do Plone com os arquivos de aparência do Portal (CSS), o trabalho é simples você tem que dizer ao Deliverance que o estilo portal-column-content do Plone corresponde ao estilo corpo do novo layout (no nosso caso).

São várias as novidades do portal, um destaque maior para as turmas de treinamento é um dos principais, a nova home destaca as informações mais procuradas dentro do Portal, entre outras novas idéias.

Porém o que me deixa mais estusiasmado é o nosso "novo" (entre aspas pois tem quase 1 ano de vida, sem divulgação) Repositório de Produtos Open Source!

Nele existem diversas ferramentas, para Notícias & Newsletter, para Gerenciamento Inteligente de Cache, para Banners, para Sistemas de Licitação, produto para Agendamento de reuniões, produto para Intranets, entre outros.

Todos eles serão divulgados individualmente no nosso novo Portal, vou falar sobre cada uma das features e características contidas em cada um.

Além disso vamos mostrar alguns do nossos Cases (features desenvolvidas, objetivos alcançados, prints de tela, etc ...), um dos mais esperados é a Intranet da Caixa Econômica Federal, que está em desenvolvimento. Um grande projeto que exige inovação e renovação, estamos trabalhando em soluções Open Source para melhorar algumas questões do Plone, isto pois o cenário do Projeto (130 mil usuários e 5000 gestores de conteúdo autenticados através do AD Corporativo) exige uma performance maior do que a existente hoje no Plone, com certeza estamos falando de um dos maiores projetos Plone do Mundo.

Todos os produtos de melhoria tecnológica que estamos fazendo estarão disponíveis no nosso repositório, e vou falar de cada um deles, um post para cada novo produto.

Você já pode acessar nosso repositório em:

code.liberiun.com:7777/

Estamos utilizando o Mercurial (hg) [1] ao invés do habitual Subversion, mas isto é assunto vai ser postado pelo Douglas.

Deixo apenas a dica, um client dele no Windows (um dos motivos do uso, cross plataform), você pode baixar em: bitbucket.org/tortoisehg/stable/wiki/install

Um abraço.

[1]

por Rodrigo Castardo em 04 de May de 2009 às 11:34

Aprenda Python

Por onde começar?

Essa é a dúvida de todo mundo que começa em uma nova linguagem de programação.[inserido em 30/04/2009] Vá por mim, aprenda python e dedique-se ao inglês! ;-)Como Python é interpretado, faça o download para sua plataforma em www.python.org/downloadImportante: o site oficial da linguagem é www.python.org e não .com. Em português, temos o www.python.org.brAgora, vamos tentar "vender o peixe" te

por Vinicius Assef (noreply@blogger.com) em 04 de May de 2009 às 10:44

Blog da Liberiun

Novo site!

A Liberiun está lançando seu novo site e posso dizer que estou muito empolgado com esse lançamento pelos seguintes motivos:

  • Totalmente feito usando Plone 3.2;
  • Totalmente WSGI;
  • Skin implementada em Deliverance;
  • Totalmente acessível (DaSilva) e validado W3C;

A versão do site está baseado no Plone 3.2 e na futura arquitetura do Plone 4, trazendo benefícios nunca antes possíveis para o Plone.

O site ainda tem muitas funcionalidades para serem exibidas, mas isso é assunto para o próximo post.

Fábio Rizzo
Vice-Presidente Executivo
fabiorizzo@liberiun.com

por admin em 04 de May de 2009 às 10:35

April 30, 2009

Aprenda Python

Exemplos com o SyntaxHighlighter

No blog do José Peleteiro eu encontrei um exemplo de código formatado bem bonitinho e resolvi ver o que era.Que maravilha é o SyntaxHighlighter! Simples e objetivo.Agora não preciso mais me preocupar em colocar os exemplos com numeração de linha.Fica aí a dica. ;-)

por Vinicius Assef (noreply@blogger.com) em 30 de April de 2009 às 04:05

Exemplo 1 - Ler arquivo

fones01.py - Lê um arquivo e mostra todo o conteúdo na tela.Esse exemplo faz só isso mesmo.Baixe o fonte e o arquivo texto lido por ele (zipados).""" Le um arquivo texto e mostra o conteudo na tela. """print __doc__f = open('\usr\www\py\\fones.txt')for linha in f: print linha.rstrip()f.close()print '--- fim'Vamos analisar os detalhes desse programa.Linha 3: Execute esse programa e veja que

por Vinicius Assef (noreply@blogger.com) em 30 de April de 2009 às 03:54

Exemplo 2 - Usando string.split()

string_split.py - Separa uma string (registro de dados) em pedaços (campos), usando um delimitador.Aí vai um exemplo prático, para quem lida com importação de dados estilo arquivo csv, com campos separados por um delimitador.""" Separa um registro delimitado, em campos. """print __doc__reg = 'Fabiana Lemos;Rua das Acácias, 780;' +\ 'Centro;Belo Horizonte;MG;(31) 3234-7890;07/12/1978'nome,

por Vinicius Assef (noreply@blogger.com) em 30 de April de 2009 às 03:53

Exemplo 3 - Ler arquivo CSV e mostrar

fones02.py - Lê um arquivo delimitado por ponto-e-vírgula e mostra os campos na tela.Esse exemplo junta os exemplos 1 e 2, usando o pacote csv do Python conforme a orientação do Adam Brandizzi, no exemplo 2.""" Le um arquivo delimitado e mostra os campos na tela. """import csvprint __doc__f = csv.reader(open('fones.txt'), delimiter=';')for [nome,nasc,fone] in f: print 'nome=%s | nasc=%s | fone

por Vinicius Assef (noreply@blogger.com) em 30 de April de 2009 às 03:52