Developer, geek, deejay, biker e etecetaras afins


Texto

Maio 9, 2014
@ 10:00 am
Link permanente

PyPadawan #2: list comprehensions. Como e quando (não?) usá-las

Python trouxe de Haskell uma funcionalidade que acredito ser uma das mais úteis quando se quer um código enxuto sem perder seus superpoderes de programador: list comprehensions.

List o que?

List Comprehensions. Oferece uma forma concisa de declarar listas. Usualmente sua criação consiste na filtragem ou transformação de outros objetos iteráveis ou sequências. A sintaxe, em um primeiro momento parece estranha, mas depois ela faz muito sentido. O básico pode ser declarado da seguinte forma (não muito útil, pois devolveria uma lista igual a original):

nova_lista = [elemento for elemento in outro_iteraval]

Aplicar filtragens torna o seu uso muito mais interessante:

nova_lista = [elemento for elemento in outro_iteravel if condicao]

O exemplo acima produziria uma nova_lista contendo elementos de outro_iteravel que satisfaçam uma determinada condicao.

Também é possível aplicar transformações para gerar uma nova lista:

nova_lista = [transformar(elemento) for elemento in outro_iteravel]

O exemplo acima utiliza uma função qualquer para transformar() o elemento obtivo na iteração de outro_iteravel. Também é possível combinar os processos de filtragem e transformação:

nova_lista = [transformar(elemento) for elemento in outro_iteravel if condicao]

Na prática

É extremamente comum o ato de criar listas baseadas em transformações ou filtragem de outras listas. Sem utilizar list comprehensions este trabalho seria feito, por 99,98% dos programadores que conheço utilizando uma estrutura de código parecida:

  1. Iniciar uma lista vazia
  2. Iterar sobre a lista original
  3. Filtrar ou transformar um item da lista original
  4. Inserir o item na lista, anteriormente vazia

Algo parecido com a estrutura abaixo:

nums = range(50)
pares = []
for n in nums:
    if n % 2 == 0:
        pares.append(n)

Código legível, claro e sem muita frescura. Em minha experiência, estes são ótimos candidatos para tirar vantagens de list comprehensions:

nums = range(50)
pares = [n for n in nums if n % 2 == 0]

Apesar o trecho de código acima fazer a exatamente a mesma coisa que o anterior, as vantagens que tenho em utilizar este tipo de estrutura de código está além do fato de reduzir o número de linhas de código. Erros de declaração de variáveis de conteúdo “vazios” são eliminados, visto que o processo de declarar-iterar-preencher torna-se único.

Quando não usar?

O processo de filtragem/transformação para criar novas listas pode ser tão simples quanto o exemplo acima, ou ser muito mais elaborado. Quando me deparo com casos em que as condições de filtragem ou ou transformação são complicadas demais ou que acredito que devam ser mais explícitas, acabo por optar pela estrutura tradicional de declarar-iterar-preencher:

nums = range(50)
foos = []
for n in nums:
    if (n % 2 == 0 and n/n**2 == 0) or n > n**3:
         foos.append(n)
Nota:

O exemplo acima é odioso, fútil e apenas para exemplo. Não tente isso em casa, porém eu não usaria condições deste tipo em uma list comprehension.


Link

Maio 6, 2014
@ 10:00 am
Link permanente

lazy.sh: Agilizando git-flow »

Uma série de aliases para otimizar a interação com os comandos de git-flow. Feito à quatro mãos com o @jaysonsantos, fruto da preguiça em gerar releases/hotfixes ;)


Texto

Maio 2, 2014
@ 10:02 am
Link permanente

PyPadawan #1: Intro to Data Science

Ultimamente tenho me interessado muito sobre Data Science, Big Data e muitos outros termos que pipocaram nos últimos tempos em engenharia de software. Apesar de não me apegar aos termos e ver que há muito hype sobre eles, os conceitos despertam muito mesmo minha curiosidade e vontade de aprender mais sobre estatística e análise de dados.

Hello World

A primeira barreira que encontrei até aqui é que não há modo fácil de iniciar em em computação científica tal como começamos com programação de computadores em geral. O clássico Hello World que existe nos manuais de qualquer linguagem de programação é geralmente mais complexo e exige, no mínimo um conjunto de conhecimentos e ferramentas cujo material é difícil de ser encontrado, ou de ser entendido, pois utilizam notações e jargões muito peculiares.

Ao passo que o clássico Hello World não é tão trivial para iniciar com computação científica, há bons materiais voltados para iniciantes aparecendo por ai. O Udacity está já há algum tempo com uma trilha de cursos online gratuitos sobre ciência da computação e um deles é justamente sobre computação científica: Intro do Data Science.

É um bom começo para quem quer se aventurar em Machine Learning, análise e transformação de dados brutos em algo com significado e que ajude a solucionar problemas do dia a dia, não somente voltados a produtos de informação - redes sociais, sistemas de recomendação, análise de comportamento, predição, soluções para o transito e etc.

O curso utiliza Python com algumas ferramentas realmente interessantes, em especial Pandas, que fornece entre outras coisas, estruturas para manipulação de dados muito intuitivas e mesmo quem não tem base fundamental em estatística ou na linguagem R se sente muito confortável em modelar e analisar dados. Algumas leituras interessantes para quem quer começar a se aventurar em Data Science com Python:

Tricky part

Tive alguns problemas até conseguir configurar meus ambientes, MacOSX e Ubuntu Linux e testar alguns dos exercícios propostos pelo curso. Por isso listo aqui algumas dicas para evitar problemas de compilação (em especial para SciPy e StatsModels)

Os detalhes de instalação aqui descritos consideram apenas a versão 2.x da linguagem. Ainda não me arrisquei a configurar um ambiente puramente Python 3.x pois muitas bibliotecas ainda não suportam completamente a versão da linguagem.

MacOSX

  1. Utilize brew doctor. Elimine inconsistências de instalação e corrija seu ambiente. Alguns pacotes estavam desatualizados, além de alguma bagunça com instalações de Python feitas fora do HomeBrew, links quebrados…uma bagunça. A melhor coisa é começar com a casa arrumada
  2. brew update e brew upgrade antes de começar a configurar seu ambiente. Novamente, limpe a casa.
  3. Atualize seu XCode e Command Line Tools. Pode demorar, mas pelo menos vai te poupar muito trabalho, pois trás um número imenso de vantagens enquanto tenta compilar suas dependências.
  4. Instale o pacote swig. Tive muitos problemas de compilação do SciPy e após repassar muitas linhas de log, isso foi suficiente para instalação ocorrer sem problemas: brew install swig
  5. Use virtualenv. Eu não sou muito fã de misturar dependências de projetos. Apesar da instalação das bibliotecas para computação científica ser um pouco demorada, ainda acho que vale a pena separá-las por meio de ambientes virtuais no Python
$ brew update && brew upgrade  
$ brew install swig gfortran
$ brew cleanup  

Ubuntu Linux (14.04 LTS)

Minha experiência para configurar o ambiente em Ubuntu Linux apresentou quase os mesmos problemas que a instalação no MacOSX. Para ter um ambiente que evite os erros de compilação do SciPy ou StatsModels, as seguintes dependências precisaram ser instaladas:

$ [sudo] apt-get install python-dev libblas-dev liblapack-dev build-essential

Instalação

As instruções abaixo são basicamente as mesmas tanto para MacOSX quanto para Ubuntu Linux. Após alguns minutos você terá um ambiente configurado e pronto para brincar com dados em volume e complexidade maiores. Recomendo instalar uma biblioteca por vez, pois o volume de dados gerados no log de compilação/instalação é grande e entender o que acontece em cada etapa ajuda na hora de resolver potenciais problemas.

$ cd  
$ mkdir datascience-into  
$ cd datascience-intro
$ virtualenv .venv
$ source .venv/bin/activate
$ pip install numpy
$ ... aguarde ...
$ pip install scipy
$ ... aguarde ...
$ pip install pandas
$ ... aguarde ...
$ pip install patsy
$ ... aguarde ...
$ pip install statsmodels
$ ... aguarde ...
$ pip install ipython

IPython é opcional, mas é um aditivo muito valioso, principalmente porque adiciona funcionalidades que facilitam a vida de qualquer padawan na linguagem. Vale a pena investir algum tempo aprendendo como tirar proveito da ferramenta.

Referências


Texto

abr. 25, 2014
@ 4:16 pm
Link permanente

PyPadawan #0

Python tem sido uma das linguagens que mais tenho prazer de trabalhar. Aprendi muito com a linguagem, sua filosofia e amizades formadas de modo que me fez pensar melhor em como resolver problemas em outros ambientes, como php.

Nem tudo são flores, reconheço. Existem muitos pontos da linguagem ou ecossistema que para quem começa a se aventurar, podem não fazer o menor sentido. PyPadawan é antes de mais nada, uma tentativa de fazer com que o meu aprendizado em Python e outras tecnologias seja cada vez mais profundo enquanto compartilho minhas experiências com quem deseja começar a programar, sem perder a parte divertida. Tentarei escrever sempre que possível sobre algum ponto que causa confusão ou que me levou a perder algumas horas de sono para encontrar uma solução.

Hashtag coding

Pra começar, acho que vale a pena compartilhar aquilo que, na prática, pode dar nó na cabeça de quem precisa lidar com caracteres especiais em Strings. Codificação de caracteres sempre foi e será um assunto chato. Felizmente, unicode resolve muito bem a maioria dos problemas que se pode ter em relação a problemas de acentuação.

Se você está realmente começando e já viu # coding: utf-8 no início de algum arquivo .py (ou derivações disso) e não entendeu nada, tenha calma pois há uma razão para isso. Historicamente, Python (Ruby e outras linguagens) utilizam o comentário de codificação # coding: <val> para explicitamente determinar qual a codificação de caracteres que o interpretador utilizará na execução do script. Com isso caracteres não-ASCII podem ser utilizados sem problema em seu arquivo, desde que estes façam parte da tabela de codificação escolhida pelo desenvolvedor. Você tem total liberdade para escolher a codificação de caracteres que melhor se adeque a seu projeto, porém se quer realmente evitar problemas futuros, aqui vão alguns conselhos:

  • Use utf-8
  • Use utf-8
  • Use utf-8

O uso do comentário para explicitamente dizer ao interpretador da linguagem a codificação que um arquivo utiliza foi eliminada na versão 3.x de Python. A versão 2.x de Ruby também elimina esta necessidade, pois tornaram unicode o padrão para seus interpretadores.

Na prática

Uma busca qualquer sobre codificação de caracteres em Python, resulta em um "sem-fim" de publicações que explicam os problemas de codificação de caracteres na linguagem (e reclamações acerca disso). Mesmo assim, nos últimos 2 anos não tive problemas com codificação de caracteres, pois todo o stack de projetos utilizam utf-8 de ponta a ponta.

Um exemplo de código contendo caracteres não-ASCII sem dizer ao interpretador a codificação desejada, geraria uma mensagem de erro:

File "coding.py", line 1 SyntaxError: Non-ASCII character '\xc3' in file coding.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

Geralmente, o que faço para evitar quaisquer problemas, além de ter que pensar nisso é configurar meu editor para sempre iniciar um arquivo .py com # coding: utf-8, mesmo que o script não tenha Strings com caracteres especiais. Uma prática simples, mas que evita dores de cabeça, principalmente quando chegar a hora de integrar com seus bancos de dados.


Link

jun. 11, 2013
@ 12:21 am
Link permanente

Jim Guthrie assina trilha sonora de Below »

Primeiro artigo - de muitos, eu espero - que escrevo para o Jogador 1. Pretendo falar sobre o combo música+games. Espero que gostem.


Texto

jul. 25, 2012
@ 8:44 am
Link permanente

A imaturidade profissional comanda sua equipe. Comanda?

Há algum tempo tive um bate papo com o @rreimberg (iniciado via gtalk e não concluído após uma bela caminhada até o ponto de ônibus) sobre como vejo cada vez mais desenvolvedores - e às vezes, equipes inteiras - serem tão imaturos com relação ao ambiente ao qual estão inseridos; e isso é pior quando acontece também com quem deveria evitar isso: quem lidera, coordena, gerencia…. Fazia um bom tempo que vinha tentando não escrever sobre isso, pois este mesmo amigo de caminhadas vive dizendo que minhas opiniões são, em sua maioria “ofensivas”. Bem, o que posso fazer se (para começar) não consigo deixar de acreditar que existe uma separação entre Programadores e Programadores de Brinquedo - sim, vocês, que têm medo de linha de comando!

Não generalizo, reconheço que tive oportunidades  de trabalhar ao lado de pessoas incríveis; e sempre que tenho a oportunidade digo diretamente a elas o quanto representam no meu crescimento profissional. Acontece que - quase - sempre me deparo com situações de completa inexperiência técnica e de perfil de liderança nas áreas de gestão. Pode ser que eu seja duro demais, porém vejo que além do requisito óbvio de se possuir um perfil de liderança, nas áreas que envolvem desenvolvimento de software, são imprescindíveis conhecimentos reais de pontos que fazem sim a diferença entre sucesso e fracasso de um projeto; infelizmente estão sempre para “pontos negativos”. Estes pontos envolvem o não conhecimento das ferramentas de gestão de código, como SVN e GIT; acesso remoto via SSH, e no momento - não posso dizer pelo futuro, certo? =P; a falha mais terrível é a de uma pessoa com responsabilidades de estar a frente de uma equipe não conhecer, não estabelecer e não cobrar que um processo formal de deploy seja adotado. E olha que neste caso não chego a ser radical, basta um processo claro (mesmo que desenvolvido internamente pela equipe).

Infelizmente este não é um cenário fácil de mudar, depende muito de cultura organizacional e cabeça aberta de quem está nessa posição de se auto avaliar e começar a correr atrás. Tenho certeza  de que é muito mais comum do que se pensa e é bem provável que a imaturidade comanda sua equipe. Comanda?


Texto

fev. 22, 2012
@ 9:49 pm
Link permanente

Apache: seu servidor web é o Microsoft Word

UPDATE: alguns dados sobre market share de servidores, mostrando que nginx possui pouco mais de 12% de participação em todos os domínios ativos (até Janeiro de 2012): http://goo.gl/KztKo

Vivemos a era do Big Data; a cada dia precisamos de mais espaço para guardar nossas informações e - ao contrário de quando comecei a trabalhar nesta área - espaço em disco é barato, qualquer um consegue alguns terabytes na Santa Efigênia por um preço irrisório. Antes, espaço era o problema, hoje nossos desafios caminham na direção de como gerenciar tantas informações. 

Os velhos métodos, os velhos modelos nunca deixarão de existir, mas é evidente que para novos desafios, precisamos de novas ferramentas. Até pouco tempo atrás, bastava a um desenvolvedor conhecer SQL e alguns poucos sistemas de banco de dados relacionais para que ele tivesse, em suas mãos, ferramentas necessárias para tornar seu dia a dia mais fácil, no que diz respeito ao trato com dados. Hoje, somente SQL não é mais suficiente. Empresas querem resultados - rápidos - e para que um desenvolvedor seja produtivo ele precisa estar atento às mudanças que ocorrem em seu meio. NoSQL não é um conceito novo, mas tem tomado cada vez mais a atenção de grandes empresas, fazendo com que seja uma alternativa viável na entrega de produtos que correspondem à espectativas de clientes, desenvolvedores e usuários.

Se por um lado, bancos de dados caminham para um estado de graça em que veremos, com muito mais frequência, conceitos como o de persistência poliglota, do outro lado os servidores web continuam parados no tempo. Dentre os mais usados hoje está o Apache; construído em uma época em que os problemas da gestão de dados eram diferentes e apesar de sua evolução, não tem sido suficiente para resolvê-los. O problema dessa nossa "era"  relacionado aos servidores web está relacionado a suportar grandes volumes de acesso, com baixo custo - da implantação à manutenção e com baixa dependência de novo hardware.

Ok, é possível escalar aplicações web apenas com Apache? Sim, claro, mas isso traz um ônus para a implantação de novo hardware sempre que o número de acessos aumentar - já vi isso várias vezes e estou vivendo isso em meus projetos atuais. E por conta destes projetos de alta demanda, venho me interessando por novas alternativas ao uso do Apache para entregar aplicações web. Uma das quais vejo um grande potencial é o nginx (engine x). Uma frase de Chris Lea descreve bem a situação em que o Apache se encontra hoje:

Apache is like Microsoft Word; it has a million options but you only need six. Nginx does those six things, and it does five of them 50 times faster than Apache.

Veja bem, deixo claro que não sou fanboy, não gosto de flames, tampouco estou sugerindo a extinção do Apache, mas a situação para a maioria dos projetos que entreguei no último ano não precisavam sequer tocar no Apache. O projeto ao qual estou me dedicando atualmente realmente necessita de uma solução “poliglota” em que seria muito útil ter Nginx e Apache trabalhando juntos - portanto a idéia que defendo é exatamente a de utilizar as ferramentas certas, baseado no tipo de problema a ser enfrentado.

Mas Apache é robusto, consolidado no mercado, mimimi, mimimi

Certa vez, ouvi de um professor, quando falava sobre Node.js, de que ele somente confia em soluções que estejam muito bem conceituadas no mercado, apoiada por empresas de renome e bla, bla bla - nem preciso dizer nada a página inicial do node.js diz tudo. E porque falei nisso? Talvez, você também tenha pavor de versões beta, alpha e software on the edge e apesar de recente, nginx tem um share no mercado de quase 10% e apostaria minhas fichas que até o fim de 2012, estará mais próximo de abocanhar uma fatia maior, alcançando a solução da Microsoft - IIS - com aproximadamente 14% do mercado.  Se o problema é respaldo da indústria, nginx tem de sobra.

Não sou eu quem decide isso…(?)

Não existe panacea na vida e com tecnologia não é diferente, convencer seu chefe/cliente a usar nginx é um passo que exige mostrar os benefícios que ele pode trazer em seus projetos, mas talvez o mais óbvio seja o fato de economizar muito em hardware. Um VPS pode suportar um grande volume de acessos sem problemas e até hoje não conheci nenhum cliente que queira gastar - se puder economizar ele o fará - portanto, dentre todos os fatores este pode ser decisivo. Acredito que as transformações na sociedade só acontecem quando decidimos “mexer nossas bundas” e como profissional, é sua responsabilidade fazer com que avanços sejam percebidos, utilizados e novas técnicas sejam desenvolvidas - questionar também faz parte do aprendizado, aquilo que aprendemos nos livros é válido, mas não é “palavra escrita numa pedra”.


Citação

jan. 17, 2012
@ 1:14 pm
Link permanente

A linha de código mais elegante, que possui o mínimo de bugs, é mais fácil de escrever e fácil para alguém, lendo seu código, entender é aquela que você não escreve. Menos linhas de código é melhor

Tradução livre do que escutei hoje, num vídeo do Paul Hegarty (professor da Stanford). 

Não é a primeira vez que escuto (ou leio) algo parecido, mas me fez pensar sobre muitos projetos ruins que por vezes me aparecem; e penso no amadorismo que se forma por ai. Não sei se a culpa é das instituições (Faculdade, Cursinho S.O.S Bytepog) ou das pessoas, que se acomodam com melhorias de Hardware, das runtimes e seus garbage collectors ultra eficientes e deixam de pensar que mais de 50% da solução não está na máquina e sim no humano.

Por estes (e outros) motivos, talvez desenvolvedores de software devessem estudar como estudam os designers. Propor soluções que não são apenas funcionais, mais que simplesmente bonitas e que nos aproxime do que somos - humanos - e mesmo não sendo um fanboy, reconheço que Steve Jobs sabia disso, há tempos atrás. 


Link

dez. 14, 2011
@ 9:43 pm
Link permanente

Multi Device Design »

ou

Design à prova de futuro 

ou

O que você está esperando para desenvolver para web  sem ser preguiçoso

ou (ainda)

Seja designer uma vez na vida seu programador de merda

Acabei de ler esse texto do Luke Wroblewski, e digo que é uma das coisas mais inspiradoras que li neste mês, principalmente se levar em conta meu interesse recente em mobile.

Comprei e ainda não comecei a ler os livros Responsive Web Design e Mobile First - trabalho, fim de semestre na faculdade e nada é uma desculpa para não ler - e tenho certeza que vou devorá-los antes do Natal.

É uma pena que para muitos programadores a preocupação com design é quase nula. Entender que design está além da existência do profissional especialista, que cuida deste setor na empresa e/ou equipe, torna você - programador - mais que programador; o torna um ser humano, com visão, criatividade e, acima de tudo, paixão pelo que faz. É isso que busco todo dia.


Texto

dez. 4, 2011
@ 9:53 am
Link permanente

12 notas

Conheça seu inimigo

Pra quem desenvolve para web um pesadelo constante está ligado à inconsistência entre navegadores. Se eu for comparar a época em que comecei a desenvolver com o cenário atual, vivemos em uma era bem mais convidativa para o desenvolvimento de forma consistente; à época de guerra entre Netscape e Internet Explorer a coisa era bem mais difícil.

Essa guerra fez com que muita gente tomasse a decisão mais simples, de suportar apenas um navegador, originando a famigerada expressão: “Melhor visualizado em Internet Explorer 6.0 e resolução 800x600”. Eu mesmo já fui obrigado a adotar essa expressão em projetos passados (arrrghh!).

Mas as coisas mudam, a web evolui a uma velocidade impressionante e hoje a guerra está ligada à entregar navegadores cada vez mais aderentes aos padrões e com alto desempenho. Ótimo para quem precisava fazer malabarismos para dar ao usuário uma experiência consistente entre navegadores, mas isso não elimina a necessidade de empregar algum esforço para atingir este objetivo.

Uma das coisas que aprendi ao longo dos anos e que ajudava muito quando o IE6 ainda era um big player, foi “conhecer meu inimigo”.

Conhecer o seu inimigo está relacionado a estudar as limitações do ambiente para o qual se está desenvolvendo, de modo que você não ocupe seu tempo tentando reinventar a roda ou “nadar contra a corrente”. Quando se entende os pontos fracos e fortes de cada navegador, muita coisa pode ser simplificada. Com o Internet Explorer, a idéia era de não usar hacks CSS em hipótese alguma; e há quem duvide que isso seja possível.

Mesmo com um bom suporte de padrões pela maioria dos navegadores modernos, essa idéia de conhecer seu inimigo não é desperdiçada. Ainda existem inconsistências, principalmente se usarmos uma ótica de desenvolvimento para web móvel;  há uma infinidade de aparelhos, navegadores e especificações de suporte a CSS, HTML e JavaScript - e isso não quer dizer que você precisa de um CSS para cada navegador, como também era comum aplicar ao IE6.

Hoje, aplico esse conceito não somente voltado aos navegadores, mas em todo o ambiente em que trabalho. Entendendo as limitações que a HTML, CSS, JavaScript ou qualquer outra tecnologia impõe e abraçá-las como parte do dia a dia, sem tentar subverter seus conceitos para contornar tais limitações. Um exemplo é a maneira como vejo o sistema de herança do JavaScript em relação à alguns anos atrás. Quando se entende o sistema de cadeia de protótipos, é possível usá-lo a seu favor, ao invés de tentar refazer um sistema de herança para que fique mais próximo de linguagens orientadas a classes, tal como Java. Prototype faz isso, e logo que conheci a biblioteca achei interessante poder construir “classes” em JavaScript, mas hoje não tenho o mesmo entusiasmo com este tópico - protótipos funcionam, closures e módulos são padrões bem estabelecidos na comunidade JavaScript e programação funcional é parte da natureza da linguagem. Desta forma, fica a questão: será que é preciso escrever camadas e camadas sobre a linguagem, ou aprender a usar seus recursos e limitações de maneira correta?

Conhecendo seus inimigos!

Algumas referências para ajudar a identificar problemas que podem ser evitados, diminuindo a quantidade de tempo que você passa fazendo hacks ou reinventando a roda.

JavaScript Gardenhttp://bonsaiden.github.com/JavaScript-Garden/ 
Alguns pontos problemáticos do JavaScript, bugs e explicações dos motivos de cada tópico. Também tem muitas dicas sobre o qeu não fazer em JS.

WTFJS  - http://wtfjs.com
Mostra de maneira humorada as coisas bizarras que existem no JavaScript, porém com toda a explicação sobre os problemas e como evitá-los. Você pode ainda contribuir, caso encontre alguma coisa bizarra ainda não relatada.

Explorer Exposed -  http://www.positioniseverything.net/explorer.html
Lista inúmeros bugs (a maioria sobre CSS) do Internet Explorer, explica os motivos e mostra como resolvê-los. Também há neste site uma seção (bem menor) voltada a bugs de outros navegadores.

E claro, uma das melhores (senão a melhor) referência sobre JavaScript está na MDN. Porém muita coisa boa pode ser extraída da MSDN - principalmente para identificar problemas e soluções para Internet Explorer. 

Update:

Se você é adepto de árvores mortas - eu ainda sou - boas fontes para entender como se livrar de alguns problemas em JavaScript são os livros: High Performance JavaScript do Nicholas C. Zakas e Test Driver JavaScript Development, de Christian Johansen