Corinthians no Orkut

Meus amigos sabem que sou corintiano. Torcedor que acompanha o time, assiste aos jogos (menos no estádio por questões de segurança), veste a camisa e tudo o mais. Também sabem que trabalho com desenvolvimento de software e que sou heavy user de Internet.

Graças a esses contatos na rede fui um dos primeiros brasileiros a receber um convite para participar de um site novo do Google conhecido por “Orkut”. Era uma época onde comíamos dezenas (centenas até) de “donut’s” que não eram entregues aos servidores.

Os primeiros usuários do Orkut no Brasil estavam localizados no Sul (majoritariamente Porto Alegre) e em São Paulo (majoritariamente na Capital). A primeira comunidade que eu criei foi a “Corinthians” quanto só existia a do Internacional e do Grêmio. Sério! As primeiras comunidades de time de futebol do Brasil foram a do Colorado e a do Tricolor Gaúcho. Depois que eu criei a comunidade do Corinthians abriram as porteiras do Orkut (podiamos usá-lo sem convites) e outras comunidades foram criadas.

Como era de se esperar as comunidades do Flamengo e do Corinthians cresceram mais do que as outras. Mas a comunidade do Corinthians, contradizendo certas pesquisas feitas por cariocas, sempre teve mais membros do que a do Flamengo.

Como era de se esperar não demorou muito para começar as pixações. As ferramentas de moderação e de administração de comunidades do Orkut se limitavam à aprovação um a um dos inscritos na comunidade e a exclusão dos baderneiros (sem opção de banir).

A coisa ficou “feia” quando chegamos a 600.000 integrantes e uma média de 300 novos inscritos por *dia*. Todos devidamente moderados somente por mim num processo que me obrigava a visitar perfil por perfil dos novos usuários para ver se o usuário já não estava em outra comunidade de time de futebol (o torcedor entra pra comunidade do seu clube antes de entrar na dos clubes adversários para pixar).

Não dava mais. Eu passava o dia inteiro mexendo só com isso num trabalho não-remunerado (ter uma comunidade desse tamanho, naquela época, não rendia dinheiro algum).

Chegou a hora de tomar algumas medidas: pedir ajuda na moderação e criar regras para lidar com os arruaceiros que chegavam às centenas após um jogo.

Chamei meus amigos corintianos Érico (que torce pro Juventus nas horas vagas) e Márcio Medrado para me ajudar na moderação. Na época só um usuário podia administrar uma comunidade. Criamos o usuário “Gilmar Giovanelli” para essa função e distribuímos a senha entre nós. Esse problema estava resolvido faltava resolver o problema das pixações.

Entrei em contato com os moderadores das comunidades do Flamengo, Palmeiras, Santos e São Paulo pra perguntar a eles como faziam para resolver o problema dos “ataques” e me disseram que lidavam com aquilo caso-a-caso numa hercúlea tarefa de enxugar gelo. Exatamente o que estávamos fazendo.

Conversa vai, conversa vem, sugeri criar regras comunitárias válidas para todas as nossas comunidades. Essas regras eram discutidas na comunidade “Clube dos 13”.

A regra mais importante dizia que quando, por exemplo, um flamenguista invadia a comunidade do Corinthians para tumultuar ele era banido da comunidade do Corinthians e uma solicitação era feita no Clube dos 13 para ele ser banido da comunidade do seu próprio clube. Isso funcionou lindamente por muito tempo. Só não sei se ainda funciona.

Chegamos a 800.000 membros, a segunda maior comunidade da categoria “Sports & Recreations” do Orkut. Só perdiamos para “Eu adoro praia” (concorrência desleal :D). Os outros seguiam: Flamengo, São Paulo, Palmeiras e Santos.

Mas a história teve um final triste: por conta de um bug no Orkut (um?) as comunidades perderam os moderadores e uma mensagem “become a moderator” surgiu na comunidade do Corinthians (na do Flamengo também). No caso do Flamengo um usuário pegou a moderação e transferiu devolta para o antigo dono. No nosso caso o usuário que assumiu a moderação brigou com alguns membros porque não queria devolvê-la ao “Gilmar” e apagou a comunidade.

Tentamos de todas as formas contatos com a equipe do Orkut para pegar devolta a comunidade mas nada feito.

Não demorou muito e outra comunidade Corinthians foi criada. As pessoas foram voltando, mas mesmo assim não era mais “aquela” comunidade. O lado bom disso: o trabalho era grande, difícil e não-remunerado. Tiramos um peso muito grande das costas.

Por outro lado, imagina a “influência” que teríamos hoje, em tempos de “Marketing Social”, ter uma comunidade com cerca de um milhão de membros? 🙂

(PS. esse post surgiu a partir da minha ideia de recriar a comunidade Corinthians no novo Orkut. Mas para isso eu preciso de um convite :P)

publicado
Categorizado como Geral

É mais fácil pedir desculpas do que permissão

Diferente do que escrevi no post Dicas para um bom programa em Python, onde eu dou dicas de como proceder para ter um programa Python melhor, desta vez vou falar sobre um estilo que prefiro. Não quero dizer que estou certo ou errado, apenas que prefiro assim.

It’s easier to ask forgiveness than it is to get permission

Grace Hopper

Recentemente, dentro do tempo que me sobrava, comecei a desenvolver uma biblioteca pra fazer requisições HTTP para uma API REST. Essa biblioteca seria usada para criar testes automatizados do projeto que iremos começar a desenvolver aqui na empresa.

Essa biblioteca faria basicamente o mesmo que a httplib e httplib2 do Python mas com algumas conveniências: (de)serialização de JSON/XML, conteúdo calculado no momento da request (ex. assinatura da requisição), e uma classe “TestCase-like” com funções que auxiliassem no desenvolvimento de testes.

Eu tinha só algumas idéias do que essa biblioteca faria e quase nada de código quando vi o lançamento do Bolacha, desenvolvido pelo Gabriel Falcão, no Planeta Globo.com. Guardei o link pra conferir depois pois poderia ser útil para o que eu queria fazer.

Ontem eu tive um tempo para analisar e vi que ele não só seria útil como já fazia a parte mais essencial do que eu precisava (requisições GET/POST/PUT/DELETE/…).

Como o projeto esta hospedado no github.com tratei logo de fazer um fork para criar as outras funcionalidades que eu precisava. Código legal, código simples, código bem feito, mas… quando encontrei os primeiros…

def request(self, url, method, body=None, headers=None):
  if not isinstance(url, str):
    raise TypeError(f'Bolacha.request, parameter url must be a string. Got {url}')

  if not isinstance(method, str):
    raise TypeError(f'Bolacha.request, parameter method must be a string. Got {method}')

  if method not in HTTP_METHODS:
    raise ValueError(f'Bolacha.request, parameter method must be a valid HTTP method. Got {method}. {RFC_LOCATION}')
  
  # ...continua

… notei que o estilo do Gabriel divergia do meu. Nada errado com isso. Tanto que, mesmo assim, continuarei a usar e melhorar o Bolacha mantendo (dentro do possível) o mesmo estilo original do autor para que ele possa aceitar minhas contribuições.

O que não gosto desse estilo é que, com ele, sempre estamos pedindo permissão, ou seja, verificando de antemão alguma informação no lugar de usá-la imediatamente e, só em caso de erro, considerá-las inválida. Nesse caso estamos adicionando um overhead desnecessário (muito pequeno neste exemplo) até mesmo para casos de uso correto do método.

Outro problema que temos nesse estilo reside no fato de que estamos usando o mecanismo de herança da linguagem como um sistema de criação de interface para o objeto. Se eu quiser passar um objeto que se comporta exatamente como uma string mas que não seja uma classe derivada de str para o método .request() acima eu não vou poder.

Eu removeria todas as verificações de isinstance() e deixaria o código assim:

def request(self, url, method, body=None, headers=None):
  if method not in HTTP_METHODS:
    raise TypeError(f'Bolacha.request, parameter method must be a valid HTTP method. Got {method}. {RFC_LOCATION}')
  # ... continua

Mais adiante nesse código vemos o uso de uma função chamada is_file() que é implementada da seguinte forma:

def is_file(obj):
  return hasattr(obj, 'read') and callable(obj.read)

Mais uma vez, nada de errado. Mas também não é muito o meu estilo. No meu estilo essa função sequer existiria porque, mais adiante, quando fosse necessário usar obj que, no código em questão, pode ser uma string ou um file object, eu faria algo assim:

try:
  lines.extend(encode_file(obj))
except AttributeError:
  lines.extend(['...'])

Mais uma vez eu quero deixar claro que é só uma questão de diferença de estilo e que eu usei o código do Bolacha somente para ilustrar essa diferença. Dentro do estilo do Gabriel o código está perfeito (tá, não existe código perfeito, mas o dele tá muito bom).

Como leitura complementar sobre essas diferenças eu recomendo o artigo isinstance() considered harmful, Duck Typing, Permission and Forgiveness e PEP-3119 – Introducing Abstract Base Classes (funcionalidade de suporte ao estilo usado no Bolacha).

Por último, ao meu estilo, gostaria de pedir desculpas ao Gabriel Falcão por ter usado o código do Bolacha para ilustrar esse artigo sem permissão. 🙂

publicado
Categorizado como Geral

Dicas para um bom programa em Python

Foto: Olivier H (https://www.flickr.com/photos/olivierh/)

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.

Esse artigo é uma espécie resumo com boas práticas de programação Python que utilizo no meu dia-a-dia.

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 ("Imprime dados na tela. "
              "Deixará de ser comando "
              "no Python 3.0")
   elif comando == "assert":
      return ("Certifica se uma condição é "
              "verdadeira e gera uma excessão "
              "em caso contrário")
   elif comando == "...":
      pass # ...
   else:
      raise InvalidCommand(f"Comando {comando} inválido.")

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.

Update: pequena correção sugerida pelo Francisco nos comentários: s/Classe/_Classe/.

publicado
Categorizado como Geral

“Cagadas” homéricas (ou YA-meme?)

Durante toda a minha carreira “computeira” eu cometi alguns erros absurdos (cagadas?) que eu gostaria de compartilhar com vocês neste post.

Vou listá-las aqui na esperança de que outros façam o mesmo e que, com isso, o meu sentimento de culpa por tamanhas “obras” fique menor.

killall foobar

Certo dia, quando trabalhava na GVT, eu estava numa sessão telnet em um servidor de produção PA-RISC que rodava um HP-UX. Estava logado como root e precisava matar alguns processos que estavam prejudicando o funcionamento da máquina (consumindo CPU, memória, load alto, etc).

Meu conhecimento de Unix até aquele momento era de ter mexido muito com Linux ao ponto de saber usar com maestria o comando killall. Foi então o que eu usei para matar tais processos.

Assim que eu apertei “enter” surgiu uma mensagem de que o servidor iria se desligar em X segundos. Entrei em pânico.

Pois bem… apesar de ser um ‘fera de killall’ eu nunca tinha lido o trecho da manpage deste comando que dizia (no Linux):

Be warned that typing killall name may not have
the desired effect on non-Linux systems, especially
when done by a privileged user.

O que aconteceu? O killall do HP-UX envia um sinal para todos os processos da máquina e é usado pelo comando shutdown para matar todos os processos em execução.

Foi assim que eu desliguei, pela primeira vez, um servidor em produção de uma grande empresa de telefonia praticamente parei as vendas da empresa por pelo menos 1 hora (uma máquina dessas leva cerca de 20 minutos para voltar pro ar + acertos de configuração perdidos por causa do reboot).

delete from tabelao;

Mais uma vez na GVT… coitados…

Eu estava desenvolvendo um programinha que fazia acesso ao banco de dados Oracle e para isso eu constantemente testava algumas queries, inserts e deletes nas tabelas de um banco de dados que ficava no ambiente de desenvolvimento da empresa.

Nos bancos de dados do ambiente de desenvolvimento a gente encontrava um subconjunto dos dados do ambiente de produção e podíamos manipulá-los com tranquilidade porque uma vez por dia/semana as bases eram repopuladas com dados oriundos do ambiente de produção.

Em certo momento eu precisava deletar todos os registros de uma tabela (cerca de 50 registros) da base de dados do ambiente de desenvolvimento e rodei um:

delete from tabela;

Fiz os testes que precisava fazer sem rodar um commit e no final fiz um rollback.

Neste intervalo de tempo ocorreu um problema que exigiu minha atenção em um dos servidores de produção e esse servidor era justamente o servidor ‘equivalente’ ao de desenvolvimento onde eu estava trabalhando. Resolvi o problema do servidor rapidamente e voltei para o desenvolvimento.

Aí é que está o problema… o meu cérebro trocou de servidor mas meus dedos não e no fim eu rodei um delete from tabela; no servidor de produção da empresa 😀

O estrago teria sido pequeno se tal tabela não tivesse centenas de milhares de registros fazendo com que o Oracle praticamente parasse de responder à requisições até que ocorresse uma falha de “estouro de segmento de rollback” (falha que demorou pra acontecer porque as configurações do Oracle eram muito ‘generosas’).

Seria muito difícil acontecer do estrago ser grande. Para que isso ocorresse a falha que ocorreu não poderia acontecer e depois do delete eu ainda precisaria dar um commit.

Se isso tivesse acontecido eu teria mudado de profissão 🙂

/home/osvaldo/icons

Essa foi no meu “início de carreira” com Linux. Eu trabalhava na Conectiva (atual Mandriva) e fiquei responsável por criar um sistema de “temas” para o Conectiva Linux 5.

Os temas deveriam funcionar igualmente no Gnome, KDE e no WindowMaker que, até então, era o WM que eu usava.

Fiz os pacotes, scripts, configurações e enviei para a máquina de integração (mapi). Dei essa tarefa como terminada e passei para as próximas.

Lançado o Conectiva 5 o sistema “explodiu” nas máquinas dos usuários e o sistema de temas não funcionava como deveria em todas as máquinas que usavam o WindowMaker .

Ao analisar o problema vi que no arquivo de configuração do WindowMaker tinha um “/home/osvaldo” no caminho de busca de imagens e ícones que causava a ‘quebra’.

Resultado: as coisas funcionavam perfeitamente na minha máquina e em todas as outras máquinas do mundo que tivessem um usuário “osvaldo”.

Esse foi um bug entre os vários desse sistema de temas que criei e que futuramente (por razões óbvias) foi abandonado.

Se você ainda tem um Conectiva 5 para instalar por aí faça o teste. 😀

Off-topic

Alguns, talvez, ainda não saibam mas eu vivi um período em que queria largar da área de informática e virar publicitário (ok, eu era jovem).

Neste período “publicitário” da minha vida eu trabalhei em uma agência de propaganda chamada DLMRozani e lá nós fazíamos toda a mídia local das várias Lojas Americanas do país (a conta nacional era da agência Talent).

A mídia local inclui anúncios televisivos (para as afiliadas locais), anúncios em jornais locais e aqueles folhetinhos de ofertas que todos já devem ter visto.

Num desses folhetos onde anunciamos carne de 1ª à R$3,90/kg quando o preço correto era algo como R$13,90/kg (não lembro detalhes da oferta).

A sorte que era uma dessas “ofertas relâmpago” (válidas por 1 hora), mas o fato é que vendemos 400kg de carne em 1 hora. Filas se formaram em volta do quarteirão das Lojas Americanas e caminhões não paravam de chegar trazendo carne para ser vendida (aquele blablabla de “enquanto durarem os estoques” não tem muito amparo legal pelo código de consumidor).

Só para contextualizar: nesta época as Lojas Americanas tinham lojas que funcionavam como supermercado em várias cidades do Brasil. Essa operação foi vendida posteriormente para um grupo francês chamado Stoc.

Finalizando

Se eu lembrar de mais algumas “cagadas” eu volto a atualizar esse post mas acho que essas foram as maiores.

E vocês? Fizeram alguma dessas já?

publicado
Categorizado como Geral

I Has Arduino!

Hoje de manhã chegou uma encomenda pelo correio que eu estava esperando a muito tempo: meu Arduino 🙂 Quando eu tinha uns 9/10 anos de idade eu adorava ‘brincar com eletrônica’ com um amigo meu que tinha uma oficina em seu quintal. Todo dia depois da aula a gente jogava Atari na minha casa e depois ia para o “laboratório” dele montar os projetos que saiam nas revistas Experiências e Brincadeiras com Eletrônica Júnior ou na Be-a-Bá da Eletrônica.

Certo dia esse amigo meu me chamou na casa dele porque ele tinha acabado de ganhar um computador. Era um MSX Expert 1.1 da Gradiente completamente sem acessórios. Quando ele ligou o computador e começaram os primeiros acordes do cartucho de demonstração (Ligue-se ao Expert) eu pensei: “É isso o que eu quero pra minha vida”.

Era exatamente um desses

O processo de programação na época era +/- assim:

10 CLS
20 ON ERROR GOTO 70
30 PRINT "DESLIGANDO O ATARI DA TV E LIGANDO O EXPERT"
40 PRINT "COPIANDO PROGRAMA DO LIVRO..."
50 PRINT "EXECUTANDO O PROGRAMA (RUN)"
60 PRINT "PARABENS! DELIGUE O COMPUTADOR E PERCA TUDO"
70 END
80 PRINT "CORRIGE OS ERROS"
90 GOTO 50
RUN

Mas não foi pra falar disso que eu criei esse post. Vamos voltar ao assunto.

Enquanto morava em Recife o Elvis Pfützenreuter me deu alguns componentes eletrônicos que ele tinha comprado para usar em uma maquete de ferromodelismo que ele tinha desistido de continuar. Isso me fez lembrar de como era bom o cheiro de solda e decidi retomar a eletrônica como Hobby.

Ainda estou aprendendo!

Assim como na computação as coisas evoluiram nos últimos anos com a eletrônica também. Então “aquela” eletrônica que eu conhecia onde a gente usava só uns transistores, uns resistores, uns capacitores, etc… se transformou em algo muito parecido com… informática!

“Brincar” com eletrônica nos dias de hoje quase sempre te levará a usar um microcontrolador, ou seja, você terá um chip programável com software para trabalhar.

E é aí que o Arduino entra na história.

O Arduino é um hardware com especificação livre e possui várias implementações diferentes mas todas elas possuem um microcontrolador Atmel instalado. Como o projeto é aberto existem diversas extensões e projetos que usam ele tal no universo do software livre.

A idéia do hardware livre é tão semelhante à do software livre que existem comunidades formadas em torno destes projetos. As idéias se intercalam também. Para ver isso basta olhar para a IDE utilizada para programar o Arduino. Usa o GCC como compilador e a IDE tem uma implementação livre feita em Java.

Se você, como eu, tem interesse nesse universo e quiser adquirir uma placa Arduino pra ‘brincar’ é só fazer uma visita no site da Symphony e comprar um. O modelo que eu tenho aqui é o de 16K:

I Haz Ardooino!

Update: Esqueci de agradecer ao Blog do Jê que é um dos “praticantes de Arduino” no Brasil e notíciou o lançamento da placa pela Symphony (que tornou a compra mais $acessível$)

publicado
Categorizado como Geral

Cross-compiling fácil fácil

Como eu já contei no post anterior no meu novo trabalho a gente tem que lidar com cross-compiling (compilação cruzada) o tempo todo. A idéia da compilação cruzada é simples: você compila um programa P em uma plataforma A e o binário produzido deverá rodar em uma plataforma B.

O conceito é simples, o seu funcionamento na teoria também. Para compilar um típico programa Linux em um computador x86 para rodar na plataforma ARM bastaria ter o toolchain, que é o conjunto de ferramentas que engloba o binutils (onde fica o linker) o gcc (onde fica o compilador C/C++) e em algumas bibliotecas básicas já como binários ARM (a libc é uma delas).

O problema do ovo e da galinha dificulta um pouco a construção de um toolchain (você precisa compilar o compilador) mas não é incomum que esses toolchains já sejam distribuídos com a plataforma ‘alvo’, logo, esse problema não é muito grande.

Com cross-toolchain já instalado a teoria diz que bastariam os seguintes comandos (assumindo que a nossa plataforma alvo seja ARM) para compilar um programa:

$ ./configure --host=arm-linux
$ make
$ make install

Com algumas pequenas variações disso conseguiríamos fazer a compilação cruzada de ‘todo o Linux’, mas na prática a teoria não funciona… 🙂

O que acontece é que um grande percentual das aplicações (regra e não exceção) simplesmente ignora o fato de que no futuro elas serão submetidas à compilação cruzada e simplesmente não funcionam nessas circunstâncias.

O Python é um desses programas. O interpretador compila perfeitamente, mas as extensões em C da biblioteca padrão não. O problema é que o Python usa o módulo distutils para executar tal tarefa e o mesmo é feito em Python. Neste caso precisamos de um Python ARM para executar a segunda fase do processo de build. Como executar um Python ARM em uma máquina x86?

Uma das maneiras é compilar primeiro um interpretador Python x86, renomeá-lo para algo como ‘hostpython‘, depois compilar um interpretador Python para ARM e aplicar uns patches no Makefile.in do Python para que ele chame o ‘hostpython‘ para compilar as extensões C. Mas os efeitos colaterais dessa solução são enormes porque existem extensões que usam bibliotecas do sistema (OpenSSL, Socket, SQLite, …) e o distutils não irá procurá-las no lugar correto pois não sabe o que é compilação cruzada.

Aí então entra uma técnica de transparência de CPU que aprendi a fazer com a turma do projeto Scratchbox (aperfeiçoada pela turma do projeto Mamona) que é bem simples e permite fazer compilação cruzada sem modificar nada nas aplicações que estão sendo compiladas.

A idéia é usar o binfmt do Linux para dizer que todos os binários ARM deverão ser executados pelo qemu (pegadinha 1: esse qemu deve ser estático e estar instalado dentro do chroot no path definido nas configurações do binfmt) e criar um ambiente chroot com tais binários.

Dentro desse ambiente todos os binários ARM rodam com o qemu e todos os binários x86 rodam nativamente na sua plataforma (assumindo que ela é x86) sem que você sequer note a diferença entre o funcionamento deles. Desta forma podemos colocar então o nosso cross-toolchain dentro desse chroot fingindo ser um toolchain nativo ARM (tem uma pegadinha aqui: esse toolchain precisa ser estático e não dinâmico pois as bibliotecas nesse nosso ambiente são ARM e não mais x86).

Você está me perguntando “porque não compilar um toolchain nativo pra rodar dentro desse chroot“? Só por questão de velocidade. O gcc rodaria muito devagar sendo emulado pelo qemu.

Agora é só sair compilando os programas normalmente. Mesmo aqueles que não estão preparados para compilação cruzada:

$ ./configure
$ make
$ make install

Neste exato momento estou compilando o SQLite3 (após ter terminado o OpenSSL) dentro do ambiente chroot com binários ARM (XScale) que rodam emulados pelo qemu. Tudo isso para que no final eu tenha um Python com Pygame 100% funcional.

Ok. Agora é a hora das notícias ruins:

  • O qemu não emula 100% das syscalls, logo, você poderá esbarrar com uma das famigeradas mensagens “Unsuported syscall XX“. Nestes casos verifique se já não existe um patch que implementa o suporte à essa syscall no qemu e recompile-o (lembrando que o qemu precisa ser estático).
  • O qemu não lida muito bem com threads, logo, se os scripts de build do seu programa testam threads eles podem quebrar (ou bloquear). Neste caso a sugestão é: retire esses testes dos scripts e assuma que sua plataforma tem sim (ou não) suporte à threads.
  • Lembre-se sempre que o kernel não é emulado pelo qemu! Se o seu programa usa ferramentas como o uname, por exemplo, ele irá retornar informações da sua plataforma nativa e não da plataforma emulada. Desenvolvimento para o kernel também não é muito viável.
  • Pode acontecer da tua aplicação quebrar ‘silenciosamente’. Lembre-se que pode ser o qemu quebrando e ocultando a real causa do problema. Nesses casos utilize as funções de depuração do qemu.
  • Lembre-se de ter o /proc e o /sys montados dentro do seu chroot. Alguns programas usam as informações disponíveis nesse lugar para a sua construção. Lembre-se também que esse /proc e /sys são da sua plataforma nativa e não da plataforma emulada, logo, eles poderão fornecer informações incorretas.
  • Dica: tenha a sua área de trabalho ($HOME) montada via mount --bind dentro de seu chroot para que você possa ter vários chroots compartilhando o mesmo $HOME.
publicado
Categorizado como Geral

Ambiente Isolado para Python com virtualenv

Foto: Yuko Honda (https://www.flickr.com/photos/yukop/)

Boa parte do meu dia-a-dia de desenvolvedor é gasto em proramando em Python. Gosto de estar sempre atualizado com o que há de novo para essa linguagem e para isso saio instalando tudo o que aparece para para experimentar. Além de Python o Linux também faz parte da minha vida e uso ele quase 100% do meu tempo (em vias de mudar para o OS X).

O conteúdo deste artigo está desatualizado e ele é mantido aqui apenas por motivos históricos.

A plataforma Python, de uns tempos pra cá, vêm padronizando os arquivos Eggs para distribuição de aplicações e bibliotecas. Em conjunto com o PyPI (Python Package Index) e o utilitário easy_install (que é parte do framework setuptools) é possível instalar componentes Python com apenas um comando.

A facilidade para instalar esses pacotes é enorme mas removê-los é chato porque envolve a edição de alguns arquivos texto, e ter permissão de escrita no diretório de bibliotecas do Python (permissão que também é necessária para a instalar o pacote).

Cada pacote instalado acrescenta uma entrada ao sys.path do Python fazendo com que o tempo para importar um módulo aumente um pouco mais (cada uma dessas entradas é consultada em busca do módulo e se você der uma olhada na saída do strace verá que a procura por um módulo envolve vários passos).

O Linux que eu uso (Ubuntu) precisa ter um ambiente Python estável, já que grande parte de suas aplicações roda em cima dessa linguagem, ou seja, danificar esse ambiente pode atrapalhar todo o funcionamento do sistema.

Isso tudo junto com o fato de que adoro experimentar as novidades do mundo Python faziam com que meu Python ficasse totalmente poluído com versões bleeding edge de bibliotecas que muitas vezes são incompatíveis com as versões “oficialmente suportadas” pelo pessoal que faz o Ubuntu.

Seria necessário um jeito fácil de se criar ambientes isolados do Python usando como base a própria instalação do sistema para que eu pudesse fazer esses testes e experiências sem danificá-lo. Não ficar replicando cópias de Python pela máquina também seria interessante.

E então surge a solução…

Parece engraçado mas no mesmo dia que perdi horas “arrumando” o Python em meu computador eu li no blog do Ian Bicking que ele tinha desenvolvido um programinha que fazia exatamente o que eu precisava: o virtualenv.

O uso do virtualenv é extremamente simples e direto. Basta instalar, executar e ativar.

Instalação

Se você está usando Ubuntu ou Debian:

sudo apt-get install python-setuptools
sudo easy_install virtualenv

Se não está:

wget http://peak.telecommunity.com/dist/ez_setup.py
sudo python ez_setup.py

Criando o ambiente

Para criar um ambiente basta executar o virtualenv e passar como parâmetro o nome do diretório onde tal ambiente será instalado:

virtualenv meu_python

Esse comando irá criar um diretório chamado meu_python com os diretórios:

  • bin – executável do interpretador, o script easy_install e o arquivo activate que será usado para “ativar” o ambiente. Quando o ambiente está “ativo” os executáveis dos aplicativos Python são instalados aqui também.
  • lib – a árvore com links simbólicos e/ou cópias de todos os módulos e bibliotecas do Python. Quando esse ambiente está “ativo” os módulos e pacotes serão sempre instalados dentro desse diretório.
  • include – dentro desse diretório estão os links simbólicos para todos os headers do Python que são necessários para se compilar extensões escritas em C para ele.

Ativando o ambiente para usar

Para usar esse ambiente recém-criado é necessário ativá-lo. para isso basta executar o seguinte comando:

source meu_python/bin/activate

Esse comando irá adicionar o diretório meu_python/bin no PATH da sua sessão e mudar o prompt para que você possa distinguir visualmente quando este ambiente está ativo.

Atenção: O virtualenv não cria o link simbólico python -> python2.5, portanto, se precisar dele você terá que criá-lo à mão com o seguinte comando

(cd meu_python/bin; ln -s python2.5 python; hash -r)

Depois disso é só sair instalando as coisas sem a menor preocupação.

PS. Eu não testei o virtualenv no Windows nem no Mac OS X mas no site do projeto é possível notar que tem gente usando ele também nessas duas plataformas, portanto, eu acho que ele também funcione corretamente nelas.

publicado
Categorizado como Geral

$oftware Livr€

Pra não dar muito trabalho pra escrever esse artigo não vou ficar fazendo links para a discussão que se iniciou com um post sobre o modelos de negócios com SL. Para quem quiser mais detalhes sigam os links do br-linux.org.

Esse artigo é antigo e já não reflete a minha opinião pessoal. Mantive aqui apenas para registro histórico.

A referência que fiz ao meu apelido ‘xiita’ induz o leitor a entender que isso é sinônimo de ‘radical’. O tempo e o estudo me mostraram que nada poderia estar mais longe da verdade. Xiitas são uma vertente do islamismo e, como tal, prega a tolerância e a paz.

Osvaldo

O Software Livre apareceu na minha vida a partir do ano 2000 quando fui contratado pela Conectiva S/A (Mandriva) para integrar a equipe de P&D e trabalhar no desenvolvimento do Conectiva Linux. Poderia dizer que eu já mexia com isso antes mas estaria exagerando já que o máximo que eu fazia era disponibilizar os códigos fonte de meus softwares (feitos em Clipper Summer’87 :)) para meus clientes. São só 8 anos mas tempo o suficiente para entender e ver muitas coisas acontecerem.

De 2000 pra cá passei por muitas empreitadas e passei por lugares onde recebi apelido de ‘xiita’ (por causa do entusiasmo pelo SL) e sou tratado como ‘traidor do movimento’ quando digo que sonho em ter um Apple rodando OS X.

Fazendo uma retrospectiva por todos esses 8 anos eu posso perceber uma certa coerência entre meus ideais e minhas atitudes. Evidentemente algumas idéias mudaram e outras atitudes também mas a essência permaneceu a mesma: Eu gosto de software bom.

Ser livre ou proprietário é só um dos critérios (importantes) que uso para avaliar a qualidade de um software. Se eu gosto de um software proprietário e acho que o valor cobrado por ele é correto eu certamente pagarei. Já comprei licenças de software para meu antigo Palm, licença para o Nero Burning ROM, anti-vírus NOD32, e até mesmo a do Windows OEM que veio com meu Notebook (nesse caso eu não acho o software bom, mas ele era necessário para rodar o Nero :))… mas jamais comprarei uma licença do Microsoft Office (detalhe: sou fanático por planilhas eletrônicas desde o 1-2-3 e acho o Excel a melhor planilha que existe atualmente).

Eu também tenho alguns softwares piratas rodando na máquina com Windows (principalmente a alternativa ao GIMP :P) e isso é algo que me deixa desconfortável pois sou daqueles radicais que acham que pirataria é contravenção. Prometo adquirir esse software assim que surgir uma promoção para estudante (ele é muito caro mas vale o preço).

O critério do software bom serve para definir minhas escolhas no uso de um software mas faço toda a força do mundo para que os softwares que desenvolvo sejam Livres ou, no mínimo, OpenSource. Mesmo que seja um software desenvolvido no trabalho. Meu histórico de desenvolvimento de sofware livre é pequeno e nenhum deles “emplacou” mas isso não fez com que eu deixasse de acreditar no modelo pois, afinal, eu os desenvolvo principalmente para os meus propósitos (ou para os propósitos da empresa onde trabalho). Se outros acharem útil e quiserem colaborar ótimo mas caso contrário está bom também.

É muito difícil ganhar dinheiro desenvolvendo e vendendo software livre e quando esse dinheiro começa a entrar nunca estará na mesma proporção da entrada financeira de um software proprietário. Mas ao tentar ganhar a vida “vendendo” software o autor precisará muito mais do que código para se sustentar. Ele precisará de muita criatividade, muita paciência, um bom planejamento, uma pitada de sorte e uma visão realista do mundo.

Idéias não faltam para que isso dê certo e muitas empresas espalhadas pelo mundo já comprovam isso, mas no Brasil a coisa ainda é um pouco mais complexa pois uma série de fatores como educação deficiente, preguiça, ‘malandragem/jeitinho’, ‘lei de Gerson’ e muito discurso dificultam o desenvolvimento de um modelo baseado no SL aqui no Brasil.

O próprio autor do manifesto citado no artigo do br-linux.org era um dos que passavam horas escrevendo seus “e-mails-discursos” ao invés de trabalhar no desenvolvimento de seu software. O software que ele desenvolveu também poderia ter sido feito em forma de colaboração para outros projetos (plugin pro Webmin?) mas não foi. Como um desenvolvedor pode querer colaboração para seu projeto se nem ele foi capaz de (ou se interessou em) colaborar com outro projeto?

Com relação à contribuição e à comunidade brasileira de SL: esqueça. A comunidade brasileira de desenvolvedores de SL é quase uma obra de ficção. O brasileiro quer “parasitar” o software livre. Ele quer usar o software “de graça” e não fazê-lo ou melhorá-lo. É evidente que temos grandes excessões mas elas servem apenas para confirmar a regra.

Os brasileiros acham que usar SL e ficar repetindo as palavras do Stallman bastam, mas esquecem que software é feito de código e que sem ele nada vai existir ou melhorar.

Portanto os meus conselhos para quem quiser se envolver com o desenvolvimento de SL são:

  1. colabore com algo que já exista!
  2. se não existir ou não for possível colaborar: faça!
  3. faça mais!
  4. escreva, documente e desenvolva em inglês. Não use a língua portuguesa para não limitar os seus colaboradores a 0.
  5. lance o software (divulgue-o em todos os lugares possíveis).
  6. use-o.
  7. não espere nada em troca.
  8. não espere nada em troca mesmo (principalmente de brasileiros).

Acredite, você será recompensado.

Update: Eu reli o meu texto depois de publicá-lo e percebi que, apesar de ter citado a existência de desenvolvedores brasileiros que colaboram com SL, eu não dei a ênfase necessária (e até peguei um pouco pesado demais). Pois bem, existem desenvolvedores brasileiros de SL e a quantidade deles vêm aumentando recentemente mas navegando por sites especializados como o ohloh.net ou o sf.net é possível ver que ainda falta muito pra gente ser notado no meio das comunidades de SL.

publicado
Categorizado como Geral

Aposentadoria da Python Brasil

Ontem eu me aposentei da moderação da lista de discussões Python Brasil. Quem vai assumir o meu cargo vai ser o meu ajudante Pedro Werneck. E ele, por sua vez, será ajudado pelo recém “contratado” Andrews Medina.

O ritual de passagem da ferramenta de moderação usada na Python Brasil já foi até concluído.

Quando comecei na lista éramos 134 assinantes e estamos com 2099 agora. Antes éramos só um grupo de amigos e entusiastas. Hoje continuamos amigos e entusiastas mas também somos associados de uma organização formal que vai ter muito mais força para levar adiante os nossos projetos.

Essa aposentadoria é um dos passos rumo à minha redução de atividades na comunidade Python Brasil e de Software Livre em geral. Notem que irei reduzir consideravelmente as minhas atividades mas sempre serei um entusiasta de Python e do Software Livre em geral.

Essa decisão também tem uma relação com a chegada dos meus trinta anos de idade e tomou a sua forma final durante as minhas últimas férias.

Quero diminuir o número de coisas que faço para poder fazer melhor algumas outras coisas que andavam meio abandonadas: cuidar da família, desenvolver um projeto de software que ocupa meus pensamentos há muitos anos e fazer o meu trabalho melhorar aqui na empresa.

publicado
Categorizado como Geral

Desempregado ou despreparado?

Foto: Roswitha Siedelberg (https://www.flickr.com/photos/infatuated/)

Nessa semana a empresa onde trabalho me pediu uma ajuda para conseguir contratar um programador Python com uma certa urgência. Como eu sou o moderador da lista Python Brasil optei por enviar um e-mail ligeiramente diferente para a lista de discussão avisando da oportunidade. O e-mail terminava assim:

Esse artigo é antigo e já não reflete totalmente o meu modo de pensar. Estou mantendo ele aqui apenas por razões históricas.

Requisitos:
 - Desenvolver pra Linux (necessário)
 - Desenvolver em Python (necessário)
 - Saber inglês (necessário)
 - Se divertir programando (necessário)
 - Desenvolver em C/C++ (plus)
 - Desenvolver Gtk+/GNOME (combo plus)
 - Ter estudado ciências ou engenharia da computação (mega-combo plus)
 - Conhecer bem plataforma ARM (qual é o teu telefone?)

A partir daí eu fui recebendo e-mails e mais e-mails com curriculums de candidatos à vaga e pude ver que os erros básicos que já vi em outras oportunidades continuam sendo cometidos.

Pessoal, as coisas que eu vou dizer aqui são sérias e a forma com que vou dizê-las pode ser um tanto contundente. Mas entendam que é para o bem de quem pretende conseguir um trabalho interessante. Algumas pessoas irão se reconhecer no que eu vou dizer abaixo mas para elas eu quero dizer que não é nada pessoal são apenas conselhos de alguém que trabalhou em bons lugares.

Não lamente, corra atrás

Uma quantidade considerável dos e-mails que recebi dessa vez (e de outras vezes) são de lamentação. Algo do tipo “Pôxa, que pena que eu não programo em Python muito bem :(“.

Vamos ser inteligentes. A oferta diz: “Desenvolver em Python (necessário)”. Que parte de “necessário” não foi possível entender do texto? A gente quer um candidato à vaga não uma pessoa precisando de afago.

No lugar de se lamentar por “não saber Python” você deveria é correr atrás de aprender. Nunca gastei um único tostão pra aprender Python, logo, não ter grana não serve como desculpa. Quando aprendi Python trabalhava em dois empregos e ainda tentava fazer uma faculdade. Isso também elimina a falta de tempo como desculpa.

Mesmo que você tenha uma boa desculpa pra não ter aprendido Python você vai ter que pensar sobre o que você realmente quer da sua vida: a vaga ou alimentar sua desculpa.

Se você não tem um bom projeto em Python para trabalhar fique sabendo que tem milhares de projetos de SL esperando pela sua ajuda. Escolha um que te faça feliz e toca o barco.

O salário será aquele que você irá merecer

Um outro tanto de e-mails que recebi tinham a pergunta: “Qual é o salário?” e na oferta estava escrito: “Salário acima da média local”.

Não se pergunta o salário sem você ter sido sequer entrevistado. O salário é a última coisa que se fala com o candidato. Se tá dizendo que é acima da média local significa que é um salário mais alto do que o que você conseguiria por aqui, entende ou quer que eu desenhe?

Sei que isso é utópico e que as “coisas práticas” são importantes, mas você já pensou que a empresa está te contratando para ajudá-la e não para ter mais um valor saindo mensalmente do seu caixa? Já pensou que você será remunerado na mesma proporção da sua contribuição à empresa?

Se você contribui pouco para a empresa X você vai ganhar pouco. Se a empresa Y diz que paga acima da média local significa que você vai ganhar mais que a empresa X mesmo fazendo pouco.

Quando eu tenho vontade de trabalhar numa empresa eu penso na quantidade de coisas legais que eu posso fazer nessa empresa e não em quanto eu vou ganhar. Só no final do processo é que me interesso pela remuneração.

Ofereça-se apenas para vagas que você consegue trabalhar

Esse é o pior tipo. É a famosa metralhadora giratória de curriculums. Parece que o cara tem um filtro no cliente de e-mail que pega e-mails com as palavras “vaga” ou “emprego” e já dá um reply automático com seu curriculum. Quando eu era o dono da empresa e ia contratar eu não só descartava esses curriculums como ainda marcava o nome do indivíduo na lista de “nunca contratar”.

A vaga é para “desenvolvedor” e não para “administrador de redes”! Se você não consegue ler e interpretar um texto com uma oferta de emprego é bem provável que você também não consiga realizar a tarefa para a qual você seria contratado.

Se você quer “mudar de ares” comece a estudar sobre “desenvolvimento” e mande esse tipo de informação no seu curriculum e não que você sabe instalar “postfix”, “manutenção de hardware” ou coisas do tipo.

Se você não sabe se consegue, imagine o contratante

Se você me manda um e-mail dizendo “Eu programo em Python mas não sei se dou conta de fazer o que vocês fazem” eu (no caso a empresa contratante) devo pensar o que?

Se nem você sabe se dá conta imagina eu 🙂 Mesmo que eu te conheça pessoalmente e a gente tenha conversado sobre o trabalho é você quem tem que bater no peito e bradar: “Eu consigo!”.

Então economize o seu tempo e o meu. Se você não tem certeza da sua capacidade não envie e-mail nenhum. Se você sabe que consegue mande direto o seu curriculum e se candidate à vaga.

Analise a vaga em profundidade

Antes de mandar o seu belo curriculum pra uma vaga procure saber mais sobre a empresa. Personalize o seu curriculum de forma a deixá-lo mais atraente para a tal vaga. Seja inteligente e perspicaz ao enviá-la (mas por favor polpe-se ao trabalho de inventar moda).

Eu tenho umas 4 versões do meu curriculum (e uma versão em inglês para cada uma das 4) e sempre pego ele e edito antes de enviá-lo.

Vamos à uma breve análise dos erros que vi:

  • Página 33 de 150: Não rola, né? 🙂 Se não dá pra resumir as coisas que você fez simplesmente elimine alguns dos empregos que você teve e não acrescentam nada ao seu CV. Por exemplo: eu trabalhei 3 anos em uma agência de publicidade como “publicitário” (ênfase nas aspas). Não preciso colocar isso pra uma vaga de desenvolvedor.
  • Olha a foto! Buuu!: Na mensagem tá pedindo “boa aparência”? Se não tá pedindo significa que tua aparência não importa, certo? Se tua aparência não importa a foto não serve pra nada. Pior: e se você for feio? Num eventual “empate” para a vaga a sua feiura pode te eliminar, mesmo em situações onde ela não seria importante.
  • Mexe com Linux? Pega o .doc: Erro primário esse. Se a vaga fosse pra trabalhar na Microsoft você mandaria seu curriculum no formato .odt? Porque você manda um .doc para trabalhar numa empresa que mexe com Linux? Ok, o OpenOffice “abre” esse tipo de arquivo mas o arquivo .doc mostra habilidade em que tipo de ambiente de trabalho? Na dúvida mande um .pdf, um .txt ou, como eu faço, um .html.

Eu também uso esse conselho para dizer aos candidatos: inverta o papel de quem escolhe quem. Invista no seu aprimoramento muito mais do que o exigido pelo “mercado” e apresente-se numa situação onde a empresa quer contratá-lo.

Eu já vi donos e gerentes de empresa fazendo leilão para levar um candidato. Se você é bom o suficiente para estar nessa situação você concordará comigo que é muito mais confortável.

Mas seja honesto ao ser “leiloado”. Não blefe. Eu já vi ótimos programadores que se queimaram em ambas as empresas porque descobriram o blefe. Acabou sem nenhum emprego e com a imagem arranhada em um mercado onde todo mundo se conhece.

Você trabalha no emprego perfeito, me aconselhe profissionalmente

Pessoal, eu não sou o Max Gehringer. O máximo que eu posso dar de dica é para o tipo de trabalho que eu faço. As dicas do Max são legais para casos mais genéricos mas também não precisa levá-lo à sério demais porque senão você acaba virando mais um daqueles candidatos “robôs” cheio de respostas prontas e pré-fabricadas.

Como teve mais de uma pessoa que me perguntou sobre “investir no aprendizado de Python” eu vou falar um pouco sobre esse caso específico:

Invista o seu tempo em algo que te deixa feliz. Se você gosta de programar em Python invista em Python. Se gosta de programar mas não importa a linguagem programe em várias delas.

Se você não gosta de programar? Vai fazer o que você gosta de fazer. Sai fora dessa área. Evite perder o seu tempo e o de outras pessoas que gostam de trabalhar com isso.

E tem outra coisa: usar o trabalho nessa área como meio para ganhar dinheiro para no futuro atuar em outra área menos rentável. Isso é péssimo. Atue na área “menos rentável” e faça-a se tornar rentável.

Pega o meu curriculum praquela vaga do mês passado

Um certo dia eu ofereci uma vaga em uma empresa onde trabalhava que precisava ser preenchida com urgência e recebemos curriculums para essa vaga por mais de 3 meses.

Se você vê que a oferta foi feita à mais de uma semana desiste.

Se tiver uma gota de esperança de que a vaga não foi preenchida ou tem “inside informations” de que a vaga não foi preenchida tudo bem. Mas se não for esse o caso fica a lição pra você ficar mais atento.

publicado
Categorizado como Geral