[jabá] Treinamento Python e Django
Postado por Osvaldo Santana
A Triveos está lançando o seu treinamento de Desenvolvimento Web Ágil com Python e Django e por isso pega carona nesse conceituado blog (que por coincidência é um dos sócios da Triveos) para anunciar este lançamento.
Eu não costumo fazer esse tipo de post (jabá) por aqui mas este é um caso especial por dois motivos: o produto anunciado foi criado pela minha empresa (como eu já havia dito); e porque que até o momento são poucas as empresas que ministram esse curso no Brasil.
Esse treinamento é o primeiro entre muitos que planejamos desenvolver no próximo ano sempre com algumas características:
- treinamentos in-company — isso nos dá mobilidade e permite que o treinamento seja ministrado em qualquer lugar do Brasil e não somente no eixo Rio-São Paulo.
- treinamentos de curta duração — achamos que tecnologias precisam ser simples e que se elas forem realmente simples não seria necessário investir meses num treinamento. O treinamento de Python e Django precisa de 5 dias apenas para ser ministrado com grande tranquilidade para pessoas que já desenvolvem em alguma linguagem OO.
- treinamentos personalizáveis — a linha principal do treinamento é mantida mas algumas modificações podem ser feitas para adequar o treinamento aos requisitos das empresas. Exemplos: dedicar um tempo do treinamento à implantação do Django, apresentar alguma biblioteca Javascript para desenvolvimento de RIAs, ministrar só o módulo Django, etc.
- materiais de qualidade — nada de apostilas contendo só slides impressos. Disponibilização de todo o material usado em aula (Slides, repositório de códigos, etc).
- instrutores qualificados — não posso falar muito mais sobre isso. Sou um dos instrutores :D
Quem tiver interesse no treinamento pode entrar em contato com a gente através do site ou diretamente comigo.
Update: Pessoal, não tinha ficado claro mas, a Triveos só trabalha com treinamentos in-company, ou seja, não temos infra-estrutura para ministrar esse treinamento em nossa empresa. Fazemos isso dentro da sua empresa (ou da empresa onde você trabalha). De qualquer maneira estamos avaliando um modo de atender às demandas que estão surgindo.
[offtopic] Corinthians no Orkut
Postado por Osvaldo Santana
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)
Home, End, Page Up and Page Down configuration for Mac (Snow Leopard)
Postado por Osvaldo Santana
Terminal.app
Enter “Terminal->Preferences->Settings->Keyboard“, and change the following options:
Vi Mode
Home: \033[H End: \033[F PageUp: \033[5~ PageDown: \033[6~
Emacs Mode
Home: \033[1~ End: \033[4~ PageUp: \033[5~ PageDown: \033[6~
Bash/Readline
Edit your ~/.inputrc and add the following lines:
Common settings
# Be 8 bit clean. set input-meta on set output-meta on set convert-meta off # allow the use of the Delete/Insert keys "\e[3~": delete-char "\e[2~": quoted-insert # mappings for "page up" and "page down" # to step to the beginning/end # of the history "\e[5~": beginning-of-history "\e[6~": end-of-history
Vim mode settings
# Vi mode set editing-mode vi set keymap vi # allow the use of the Home/End keys "\e[H": beginning-of-line "\e[F": end-of-line
Emacs mode settings
# allow the use of the Home/End keys "\e[1~": beginning-of-line "\e[4~": end-of-line
Vim
Edit the file ~/.vimrc and add the following options:
Terminal configured with Vi mode
map [H imap [H map [F imap [F map [5~ imap [5~ map [6~ imap [6~
Terminal configured with Emacs mode
map [1~ imap [1~ map [4~ imap [4~ map [5~ imap [5~ map [6~ imap [6~
Cocoa Keybindings
Put the following lines in ~/Library/KeyBindings/DefaultKeyBinding.dict:
{
/* home */
"\UF729" = "moveToBeginningOfLine:";
"$\UF729" = "moveToBeginningOfLineAndModifySelection:";
/* end */
"\UF72B" = "moveToEndOfLine:";
"$\UF72B" = "moveToEndOfLineAndModifySelection:";
/* page up */
"\UF72C" = "pageUp:";
"$\UF72C" = "pageUpAndModifySelection:";
/* page down */
"\UF72D" = "pageDown:";
"$\UF72D" = "pageDownAndModifySelection:";
}
Firefox
Install the following Firefox extension.
References
- http://serverfault.com/questions/73013/vim-keyboard-remap-on-snow-leopard-macos-10-6/73248#73248
- http://tech.inhelsinki.nl/gnu_developement_under_mac_os_x/
- http://heisencoder.net/2008/11/keyfixer-04-for-firefox-and-thunderbird.html
- http://fdiv.net/2007/05/12/keybindings-in-macosx-terminal-app/
É mais fácil pedir desculpas do que permissão
Postado por Osvaldo Santana
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, basestring): raise TypeError, 'Bolacha.request, parameter url must be ' \ 'a string. Got %s' % repr(url) if not isinstance(method, basestring): raise TypeError, 'Bolacha.request, parameter method must be ' \ 'a string. Got %s' % repr(method) if method not in HTTP_METHODS: raise TypeError, 'Bolacha.request, parameter method must be ' \ 'a valid HTTP method. Got %s. %s' % (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 basestring() 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, 'Bolacha.request, parameter method must be ' \ 'a valid HTTP method. Got %s. %s' % (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. :)
PythonBrasil [5]
Postado por Osvaldo Santana
Os preparativos para a 5ª edição do encontro brasileiro da comunidade Python já estão a todo vapor (o evento era conhecido anteriormente como PyConBrasil).
A PythonBrasil[5] acontecerá em Caxias do Sul – RS nos dias 10, 11 e 12 de setembro no campus da Universidade de Caxias do Sul (UCS).
As inscrições já estão abertas e é possível adquirí-los com o desconto máximo até o dia 07 de agosto. Depois disso os valores vão aumentando. Estudante, membros da Associação Python Brasil, da Abraweb e da SBC contam ainda com descontos.
Além das inscrições a Chamada para Trabalhos também estará aberta até o dia 26 de Julho (domingo agora! Não perca tempo!) para palestras e treinamentos.
Eu, como não podia deixar de ser, participei de todas as edições da conferência e posso dizer: é fantástico. O encontro com os amigos, as palestras surpreendentes e a interação com o público (que é fácil por conta do tamanho do evento) fazem esse evento único.
Gostaria de pedir pros leitores do meu blog que ajudem na divulgação do mesmo. Vocês encontrarão o material para isso no próprio site.
Dicas para um bom programa em Python
Postado por Osvaldo Santana
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.
Empreendedores 2.0
Postado por Osvaldo Santana
Como todos já sabem eu abri uma empresa para levar adiante uns projetos voltados para a Web (chamada de Web 2.0 pelos mais “antenados”).
Eu ainda estou longe de chegar no estágio alcançado pelos empresários que conheci, neste fim-de-semana durante o FMDS, mas mesmo assim foi legal conhecê-los aprender algumas coisas com seus acertos e tropeços.
Eu desconhecia uma grande parte dos projetos brasileiros apresentados durante o evento e por essa razão fiquei surpreso com a qualidade deles. Vou listar alguns:
- Pagestacker – é um site para bookmark on-line. Faz algumas coisas que o del.icio.us não faz, outras que o del.icio.us faz (de forma diferente). Tudo no visual do Pagestacker é simples, agradável e fácil de usar. A diferença fundamental, que eu notei, entre o del.icio.us e o Pagestacker é que no primeiro existe um foco nas tags para organizar os bookmarks e no segundo a ênfase fica no sistema de busca.
- Compra3 – projeto desenvolvido por uma empresa de Curitiba que cria um sistema para compras coletivas que gera descontos para compras em volumes nos sites mais conhecidos de comércio eletrônico brasileiro. Fiquei impressionado pelas experiências que eles tiveram e que os levaram a reeditar o negócio diversas vezes. Dicas preciosas sairam da apresentação deles.
- Amanaie – o pessoal da Amanaie trabalha com desenvolvimento de aplicações para sites sociais. Na apresentação eles focaram no OpenSocial, que é utilizado por diversos sites sociais tais como Orkut, hi5, etc. Eles também trabalham com aplicações para a plataforma do Facebook. Através deles conheci o Michael Nicklas que é um norte-americano que veio para o Brasil aprender sobre o mercado de startups e de capital de risco.
- BroguiBlogs – é uma plataforma para blogs que funciona nos moldes do Wordpress.com (eles até usam o mesmo software) mas com foco na facilidade para usuários que estão entrando no mundo dos blogs. Tirei uma lição valiosa com eles (e com a apresentação do Pagestacker) sobre o temor que eu tinha de lançar um serviço que não fosse inédito na Web. A apresentação de ambos me mostrou que se você fizer algo bacana as pessoas usarão. Mesmo se não for algo inédito.
- Videolog / Tivi – o pessoal do Videolog/Tivi era a turma mais ‘veterana’ do evento. Eu honestamente não conhecia o Videolog (O Tivi é um projeto recém-lançado deles para criação de emissoras de TV on-line com vídeos do Videolog, Youtube, …) e fiquei absurdamente espantado com a qualidade dos serviços. Sério. Pra entenderem o que estou dizendo acessem o Youtube e depois acessem o site deles. Façam o mesmo para vídeos em HD.
- Power – esse eu não vi durante o evento mas achei bem legal. É um unificador de grafo social (as conexões que você tem nas mais diversas redes sociais).
Com essa lista já é possível ver que o evento foi animal. Mas a história não acaba por aí. Logo depois do evento o Alexandre Fugita do blog Techbits lançou o Techcrunch brasileiro: Startupi. Neste blog o Fugita e mais alguns colaboradores tentarão reunir esse universo das startups e seus vizinhos (ex. ventures) nos moldes do que o Techcrunch faz nos Estados Unidos.
Se tudo der certo, e eu me dedicar um pouco mais na execução dos projetos que estão pendentes por aqui, logo logo estarei nesta lista também :)
PyConBrasil 2009 na sua cidade. O prazo está acabando!
Postado por Osvaldo Santana
Dia 10 de novembro termina o prazo para envio das candidaturas à cidade-sede da PyConBrasil 2009!
Se você mora numa cidade com uma comunidade pythônica entusiasmada, com uma boa infra-estrutura para sediar o evento e gostaria de ver reunida a ‘nata’ do Python no Brasil (e no mundo) é a sua chance de candidatá-la para sediar a próxima edição do maior evento de Python da América Latina!
Para candidatar é fácil. Basta preencher um formulário e seguir as dicas do Manual do Big Kahuna que as suas chances aumentam.
Os critérios para escolha da cidade variam bastante entre os participantes da banca de avaliação mas parece haver um consenso de que passam por:
- Participação, importância do Big Kahuna na comunidade e sua capacidade de coordenação
- Força do GruPy local
- Disposição de ambos para trabalhar duro durante quase um ano na organização do evento
- “Potencial pythonico” da cidade (quantos desenvolvedores python conseguiremos ‘converter’)
- Infra-estrutura pro evento
- Infra-estrutura da cidade-sede (transporte, acesso aéreo/terrestre)
- Mais alguns outros critérios que, com certeza, esqueci…
Os resultados serão divulgados no dia 25 de novembro. A banca de avaliação ainda não foi formada mas logo que tivermos mais detalhes eu aviso por aqui.
GP Brasil 2008 de F1, eu também fui…
Postado por Osvaldo Santana
Então… desde o começo do ano eu estava planejando essa viagem. Pra ser honesto estou planejando isso desde o ano passado mas só comprei os ingressos no começo deste ano.
E então chegou o tão esperado fim-de-semana e eu fui ver uma das corridas mais emocionantes das últimas décadas.
Pra ser perfeita precisava ter 10 gotas a menos de chuva no final. Tá ok… talvez alguns milhares de gotas a menos fossem o necessário para que a Toyota do Glock não perdesse tanto rendimento na última curva.
Eu fiquei no setor “G” da pista de Interlagos. O setor “G” ocupa todo o espaço da reta oposta. Estava lotado.

Interlagos vista de um helicóptero…
Mas vamos começar pelo sábado. Dia de treino e classificação.
Chegamos no autódromo para assistir ao treino da manhã e sentamos bem no meio do setor “G” de onde conseguíamos ver a saída dos boxes e bem ao longe o fim da reta onde, obviamente, tinha uma curva :)
Se esse negócio de ficar arrepiado é coisa de boiola o barulho de um F1 ‘enviada’ qualquer macho. Escutá-los reduzindo a marcha no fim da reta então faz os boiolas virarem mulher.
Algo que você só escuta lá: quando reduzem a marcha você consegue ouvir alguns ‘estouros’ do motor e um ronco grave que mostra que alí dentro tem um motor de verdade e não uma negócio qualquer que ‘grita fino’.

McLaren saindo dos boxes para volta de aquecimento
Os carros correm tanto que a foto acima deve ter sido a vigésima tentativa. Não lembro se essa McLaren era do Hamilton ou do Kovalainen. Só lembro que era saída dos boxes (não era velocidade máxima).
Terminado o treino da manhã já dava pra ver que o Massa estava bem e que o Hamilton estava na cola dele.
Algumas atividades acontecem nos intervalos entre um treino e outro. Corrida de Porches, Fórmula BMW, corrida de Masserati (muito massa), e o desfile de alguns endinheirados que pagam para fazer test-drive de Porches dentro de Interlagos. Passam com umas mulheres bonitas na carona, dirigindo um Porshe e acenando para a torcida na arquibancada.
Aliás, esse negócio de “dinheiro” lá é muito sério. Helicóptero trazendo gente para o autódromo de minuto em minuto, cerveja a R$4,50 (sem direito a profissional do sexo), espetinho de carne por R$4,00 (que se compra por R$0,50 aqui perto de casa) e o ingresso mais barato custa R$300 (antecipado) para um dia e te dá direito a frequentar um banheiro químico com uma bela vista de ’submarinos’ boiando. Lamentável.
Lojinhas da Ferrari com souvenirs fazem a gente babar…

Boné da Ferrari: R$100, Pin: R$10, Sacolinha de plástico com emblema da escuderia: Não tem preço.
… e comprar :)
E tudo isso só no dia do treino… Aliás no treino classificatório o Massa ficou com a pole position e o Hamilton só em quarto. Bom pro inglês que não precisava mais do que isso pra ser campeão do mundo.
Ah! E o dia estava extremamente ensolarado e quente. Ano que vem (sim, eu vou lá em 2009) eu vou passar protetor solar mesmo se a corrida for noturna. Não é legal ficar assim:
Para ir para a corrida, no domingo, acordamos de madrugada porque queríamos ficar bem à esquerda do setor “G” de onde era possível ver todo o “S do Senna”, local onde muitas vezes uma corrida, e nesse caso o campeonato, se decide.
Das 7hs da manhã quando chegamos à arquibancada até as 15hs quando começaria a corrida passa-se um longo período sentado, no sol, na chuva, entediado, etc. A chatisse só diminui um quando tem as ‘atividades paralelas’ como a corrida de fórmula BMW, Masserati e G3.
Aí os pilotos fazem uma volta em cima de um caminhão…
… depois eles saem um a um para a configuração do grid (o Felipe sobe 5 marchas num espaço de 100m da marca branca no chão)…
…e então, no momento da volta de apresentação, despenca uma chuva forte em Interlagos. Só o suficiente para molhar a pista.
O Safety Car dá uma volta na pista pra verificar como ela ficou e então a direção de prova opta por atrasar a largada em 10 minutos.
Eu perdi as fotos e o vídeo da largada porque estava tão ansioso com o momento que apertei todos os botões errados do meu celular :)
Mas a única coisa que aconteceu no “S do Senna” foi um estranhamento entre Nakagima, Couthard e Piquezinho que forçou a entrada do Safety Car na pista.
Manja como eles estão devagar…
Depois disso eu não tirei mais fotos nem fiz mais vídeos pois precisava acompanhar a corrida (num autódromo você é quem fica responsável por ‘trocar de câmera’ para saber o que está acontecendo).
Quando o Felipe Massa passou pela linha de chegada o setor “G” inteiro começou a pular e a gritar “Campeão!”… O Felipe então para o carro na entrada da reta oposta para pegar algo (devia ser uma bandeira) com os fiscais de prova e então no som da rádio Band News (que é a locução oficial no autódromo) começa a gritar: “Hamilton Campeão! Hamilton é Campeão!” e eu não entendo mais nada…
O Massa, então, passa na nossa frente e o setor “G” começa a esmurecer… todos começam a perguntar entre si o que tinha acontecido afinal…
O único trecho que não é visível no setor “G” é justamente o ponto onde o Hamilton ultrapassou o Glock.
A torcida então começa a gritar o nome do Massa… e eu vou embora… na chuva. Muita chuva.
Dicas pro ano que vem:
- Comprar ingresso pro setor M (mas só se for numerada)
- Levar capa de chuva
- Levar uma TV portátil
- Levar uma câmera com 12x de zoom
- Levar um binóculo
- Levar litros de protetor solar
- Não perder o cartão de crédito
- Levar guarda-sol ou um sombreiro
Tem umas fotos ‘bônus’ no meu flickr.
Latinoware 2008, eu fui…
Postado por Osvaldo Santana
Como sempre faço quando vou à um evento vou relatar aqui a minha primeira experiência participando da Latinoware 2008.
A decisão sobre a minha participação só foi tomada dois dias antes do evento pois quem iria patrocinar a minha viagem (INdT) conseguiu viabilizar o treinamento de Python para Maemo bem em cima da hora. Participei apenas do primeiro dia do evento.
Cheguei em Foz do Iguaçu na quinta-feira (30/10/2008) de madrugada e tinha um serviço de transfer no aeroporto para carregar os palestrantes até os hotéis onde ficariam hospedados. O meu nome não constava na lista mas isso era justificável por minha decisão tardia. De qualquer maneira bastou uma conversa rápida com o responsável pelo transporte e eu já estava dentro da Van em direção ao hotel.
Quando cheguei no hotel avistei uma placa avisando que um ônibus passaria lá às 8hs da manhã em direção à Latinoware. Às 7h30 eu estava na frente do hotel juntamente com mais 3 outras pessoas que também iriam para o evento.
Desistimos de esperar às 8h30 e dividimos um taxi até o local do evento. Descobri depois que o ônibus sequer havia passado no hotel.
Ao chegar no posto de credenciamento que estava instalado num estacionamento de Itaipu avistamos as filas para pegar crachás. Me dirigi à fila de crachás para “Palestrantes, Imprensa e Autoridades”.
A fila estava pequena (umas 8 pessoas) mas não andou 1 milímetro sequer até que um dos organizadores nos retirou da fila para entregar os crachás que estavam com ele. Mas o meu crachá, afinal, não estava com ele e tive que me contentar com um crachá em branco onde preenchi à mão o meu nome e RG.
Os palestrantes então deveriam entrar num ônibus que estava estacionado ao nosso lado pois seriamos levados até o “Parque Tecnológico de Itaipu” onde a estrutura do evento estava montada.
Esperamos por mais alguns minutos (que pareceram horas) até que um grande amigo meu entra pela porta do ônibus e comenta algo que eu já havia notado: “Esse é o evento mais desorganizado dentre todos os de informática dos quais já participei.” Note que em meu caso e no dele isso significa muitos eventos.
O ônibus saiu com lotação total de pessoas sentadas e em pé. Detalhe: faltavam poucos minutos para as atividades do evento começarem e uma parte considerável dos palestrantes ainda estava em um ônibus saindo da área de credenciamento.
Poucos metros dali o ônibus para e todos que estavam de pé tiveram que trocar de ônibus. A troca foi feita sob a vigilância atenta de um dos seguranças de Itaipu que olhava atentamente para nossos crachás preenchidos à mão para ver se não detectava alguma fraude :D Eita segurança…
Finalmente nos salões onde as atividades do evento iriam ocorrer tratei logo de ir para a sala de palestrantes ou para o stand da Associação Python Brasil para me conectar à Internet e terminar o material do meu treinamento…
Vencida a falta de sinalização do lugar fui até a sala de palestrantes mas ela já estava completamente lotada.
Fui então à caça do stand da APyB e ao chegar lá descobri que o ponto de rede estava com problemas. A sorte foi que o Ramiro levou um roteador wireless para conectar no ponto de rede do pessoal do Debian Brasil.
O almoço era razoável e foi ‘di grátis’. Servido apenas até as 14hs fez com que os instrutores dos mini-cursos da manhã tivessem que improvisar suas refeições já que seus treinamentos eram de 4hs (sem intervalo) e terminariam somente às 15hs.
No meu treinamento deu quase tudo certo. Mas nesse caso específico a culpa pelas falahas foram majoritariamente minhas (o ambiente necessário para o treinemento não estava instalado nas máquinas do laboratório pois eu não havia feito a solicitação em tempo hábil). Faltou um flip-chart/quadro branco na sala de aula também.
Terminado o treinamento fui dar uma bisbilhotada no pessoal da Robótica Livre que estava montando plaquinhas Severino sob a orientação do Prof. Paulo Gonçalves. O Severino é uma implementação brasileira do Arduino. Queria ter ficado lá mas tive que ir para a palestra de abertura e depois para um coquetel no mirante de Itaipu onde veríamos o acendimento das luzes da barragem. Um show que eu recomendo. Itaipu é uma daquelas coisas que temos pra mostrar as virtudes do nosso povo.

Aquele quadrado no centro é um prédio de 6 andares
Já o coquetel… Eu comi dois “canapés” minguados e não bebi nada (nem água). E os canapés foram doados pelo Ramiro que se comoveu com a minha fome :)
Depois do coquetel voltamos para o hotel onde eu dormi um pouco até ir para o aeroporto embarcar de volta para Curitiba onde iria preparar minha ida para São Paulo (desta vez de carro) GP Brasil de F1. Sobre isso eu conto no próximo post.







![PythonBrasil[5]](http://www.pythonbrasil.org.br/2009/saiba-mais/apoio-divulgue/pythonbrasil-halfbanner.gif)




