How to create a transparent background in HTML

4 Sep

Hey!

These days in my job I have to create a block in HTML that have content but with transparent background.

My first attempt was try to use opacity in CSS, but this doesn’t work well because the content will get transparent too.

So I realized I have to use transparent png. But how to create it? I don’t have much experience using graphical editors so I googled a little and found a very nice generator:

http://www.codevu.com/pixelgen/

So, show me the code:

<html>
<style>
body {
background:#000;
}
#transp {
  background: url('pixelGen.png'); /* pixelGen is the name of file generated by codavu generator */
}
</style>
<body>
	<div id="transp">
		<h1>content</h1>
	</div>
</body>
</html>

Tags: , , , , ,

GSoC 2011

27 Jun

This year I got accepted in Google Summer of Code 2011. My project consists in build three new charts to Javascript Infovis Toolkit.

Charts:

  • scatter charts
  • line charts
  • radar charts

Currently, I’m finishing Scatter Charts, fixing some animation issues (animation is already working). You can see Scatter Charts branch here and you can follow my project here.

Tags: , , ,

Explicando iterables, generators e yield no python

12 Apr

Ontem o arthursribeiro perguntou no canal da #ufcg como funcionava o yield do python. Me lembrei quando eu estava iniciando que também tive essa dúvida e tenho certeza que é muito comum entre iniciantes então estou aqui explicando.

Iterables

O primeiro passo para se entender o yield é entender o que são iterables. Um objeto é iterable quando você pode percorrer seus valores usando um “for valor in objeto”.

>>> lista = ['d', 'i', 'o', 'f', 'e', 'h', 'e', 'r']
>>> for letra in lista:
...   print letra
...
d
i
o
f
e
h
e
r

Outra maneira de criar iterables é usando list comprehension:

lista = [letra for letra in "diofeher"]

Geralmente para ser iterable, o objeto precisa ter implementado o método __iter__. Uma regra a essa exceção é a string, que não tem esse método mágico, mas que pode iterada usando seu __getitem__. Uma boa maneira de saber se um objeto é iterável ou não:

>>> iter([1,2,3])
<listiterator object at 0x1004cdc50>
>>> iter('diofeher')
<iterator object at 0x1004cdcd0>
>>> iter(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> iter(False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'bool' object is not iterable
>>> iter(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not iterable

Se o objeto for iterável, ele é retornado. Se não, a exceção TypeError é levantada.

Iterables são úteis porque você pode iterá-los quantas vezes quiser. Uma desvantagem do seu uso é que ele mantém TODA a lista em memória, o que pode não ser útil para grandes listas. É aí que entram os generators.

Generators

Generators são iterables, a diferença é que seus valores são lidos apenas quando é necessário. Pode-se dizer que iterables normais tem eager evalution e generators tem lazy evalution.

>>> gerador = (letra for letra in "diofeher")
>>> gerador.next()
'd'
>>> gerador.next()
'i'
>>> for letra in gerador:
...   print letra
...
o
f
e
h
e
r
>>> gerador.next()
Traceback (most recent call last):
  File "", line 1, in
StopIteration

No exemplo acima usei o generator expression para criar o generator. Você pode percorrer pelos valores de um generator usando o método next(); Ele vai retornar cada valor do generator por vez, até chegar no final; Chegando no fim, se você tenta usar o next(), ele vai levantar uma exceção chamada StopIteration.

Com generators e iterables explicados, posso chegar na dúvida inicial: yield.

Yield

Yield funciona mais ou menos como um return, com a diferença que ele retorna um generator.

>>> def gerador():
...   for i in range(10):
...     yield i * 2
... 
>>> gera = gerador()
>>> print gera
<generator object gerador at 0x1004c8960>
>>> gera.next()
0
>>> gera.next()
2
>>> for i in gera:
...   print i
... 
4
6
8
10
12
14
16
18

Entendendo como funciona por debaixo dos panos (a parte difícil):
Quando você usa a função desse jeito, o código da função não é rodado; O que é retornado é o objeto generator, para o código ser executado somente quando você chama next() ou usa um for no objeto.
Na primeira vez que a sua função for rodada, ela vai rodar do começo e parar até tocar no primeiro yield. Após tocar no primeiro yield, ela vai continuar do ponto que foi parado até achar o próximo yield. Quando não for achado um yield, a exceção StopIteration é lançada. Essa explicação fica melhor vista na função abaixo:

>>> def test():
...   yield 1
...   for i in range(3):
...     yield i
... 
>>> testing = test()
>>> testing.next()
1
>>> testing.next()
0
>>> testing.next()
1
>>> testing.next()
2
>>> testing.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Tags: , , ,

Rodando testes automaticamente no Django

7 Apr

Olá pessoal, hoje vou mostrar como rodar os testes automaticamente depois que algum arquivo for modificado no projeto. Tive essa necessidade pois sou muito esquecido e após ter feito vários testes para um projeto, sempre esquecia de rodá-los após modificar o código fonte.

Primeiro é necessário instalar o tdaemon:

pip install -e git://github.com/johnpaulett/tdaemon.git#egg=tdaemon

O tdaemon fica checando o diretório em que ele foi executado e se for vista alguma mudança de arquivo, ele roda os testes automaticamente.

Para rodar o tdaemon:

tdaemon --test-program=django

Na opção –test-program você especifica a suíte de testes que seu projeto roda, no meu caso, Django. As outras opções disponíveis são: nose, py (py.test), symfony, jelix e django.
Com o comando acima a janela do terminal ficará rodando com o mainloop do tdaemon e os testes serão rodados de acordo com a mudança nos arquivos.

Para melhorar isso é possível usar o NoseGrowl no OS X para mostrar as notificações no Growl (dã):

hg clone http://bitbucket.org/crankycoder/nosegrowl
cd nosegrowl/nose-growl
python setup.py install

Com o nosegrowl instalado, é só rodar o tdaemon com o seguinte comando:

tdaemon --test-program=django --custom-args="--with-growl"

Note que é possível colocar o nome de aplicações específicas no teste da seguinte maneira:

tdaemon --test-program=django --custom-args="app1 app2 app3 --with-growl"

Tags: , , , , , ,

Usando o widget de data do django admin em formulários customizados

4 Apr

Uma função que muitas pessoas querem é colocar o widget de data do django em formulários customizados (ou fora do admin). Para se fazer isso, vamos considerar o seguinte formulário:

from django import forms
from django.contrib.admin import widgets

class DateForm(forms.Form):
    datetime_object = forms.DateField()
    date_object = forms.DateTimeField()
    time_object = forms.TimeField()
    def __init__(self, *args, **kwargs):
        super(DateForm, self).__init__(*args, **kwargs)
        self.fields['datetime_object'].widget = widgets.AdminSplitDateTime()
        self.fields['date_object'].widget = widgets.AdminDateWidget()
        self.fields['time_object'].widget = widgets.AdminTimeWidget()

Agora já temos os widgets de data em cada elemento do formulário. Porém, ainda falta adicionar os JS no template, para poder usar de seus “efeitos”:
(Considerando que o ADMIN_MEDIA_PREFIX é /admin_media/)

{% load adminmedia %}

Tags: , , ,

Brainfuck – When you see it, you will shit bricks

4 Apr

Ontem tava sem nada para fazer e resolvi brincar um pouco com os problemas dos Google Code Jam anteriores. Vendo as soluções feitas por outras pessoas, acabei vendo a de um cara que fez em Brainfuck. Brainfuck, WTF???

Brainfuck é uma linguagem que foi criada em 1992 por Urban Müller, com o objetivo de ter o menor compilador existente. Ela implementa seus comandos de outra linguagem esotérica, chamada “P. Essa linguagem é Turing completa.

Seu funcionamento é o seguinte: O compilador separa cerca de 30000 células de memória para o programa acessar (versões mais atuais de compiladores chegam a ter apenas 5000). Todas as células estão com o valor zero, e você tem um ponteiro que começa na posição inicial. Você pode usar esse ponteiro para movimentá-lo pelas células e então ter o funcionamento do seu programa.

A linguagem possui oito comandos, são eles:

> – acrescenta uma posição de célula de memória ao ponteiro.

< – diminui uma posição célula de memória ao ponteiro.

+ – aumenta o valor da posição que o ponteiro está.

- – diminui o valor da posição em que o ponteiro está.

[ - itera por uma posição até a mesma chegar a 0.

] – indica o final da iteração

, – permite a entrada de um caractere. (getchar em C).

. – imprime na tela o valor atual do ponteiro.

Depois de toda essa conversa, chegou a hora do “show me the code”:

Resolvi escrever um “I love you” :P

++++++++++[>+++++++>++++++++++>+++++++++++>++++++++++++>+++
<<<<<-]>+++.>>>>++.<<<++++++++.>+.+++++++.<-------.>>>.<+.<-------.++++++.>>+.
<<<<<+++++++++++.

Agora identado para melhor compreensão:

+++++ +++++
[
> +++++ ++ add 7 to cell 1
> +++++ +++++ add 10 to cell 2
> +++++ +++++ + add 11 to cell 3
> +++++ +++++ ++ add 12 to cell 4
> +++ add 3 to cell 5
<<<<< - ] > +++ .          print 'I'
>>>> ++ .        print ' '
<<< ++++++++ .   print 'l'
> + .            print 'o'
+++++++ .        print 'v'
< ------- .      print 'e' 
>>> .            print ' '
< + .            print 'y'
< ------- .      print 'o' ++++++ .         print 'u' >> + .           print '!'
<<<<< +++++++++++  .

Na primeira linha, aumentei o contador da célula 0 para 10, que vai ser o número de iterações pelo loop. Usando a tabela ASCII, juntei os caracteres que tem a representação decimal próximos (exemplo: o é 111 e u é 117). No final da iteração, diminuimos o contador, até chegar a zero, o que determina o final da iteração. Então, a célula 1 ficou com valor de 70, a célula 2 de 100, a célula 3 de 110, a célula 4 de 120 e a célula 5 de 30.

Depois da iteração, é só ir mudando de uma célula para a outra, e adicionando os valores que forem necessários (na célula 3 temos 110, então adicionamos 1 para poder imprimir um caractere ASCII ‘o’). Se algum valor tiver maior, é só dimunuir com – e quando chegar no código do caractere, é só imprimir!

Espero que isso deixe a cabeça de muita gente louca ;)

Tags: , ,

Dicas para tornar seus sites mais rápidos

4 Apr

Esse post foi inspirado por um livro que li sobre performance em websites. Seu nome é “High Performance Websites” e ele foi escrito por um desenvolvedor do Yahoo. Para quem é desenvolvedor de front-end sua leitura é indispensável. Resolvi publicar aqui no blog algumas dessas formas de otimização e explicar o porquê de cada.
1 – Fazer poucas requisições HTTP

Pesquisas mostram que mais de 80% do carregamento de uma página é gasto no front-end. Então diminuir o número de componentes para consequentemente ter menos requisições é uma boa. Para fazer isso, utilizam-se praticamente duas técnicas, chamadas de Image Maps e CSS Sprites.

Nos Image Maps utilizamos uma imagem e mapeamos seus pontos. A imagem precisa ser contínua, como uma barra de navegação. Essa tarefa de marcar os pontos é muito suscetível a erros e é cansativa, por isso recomenda-se o uso de CSS Sprites. Com ele, juntam-se todas as imagens estáticas que compõem a estrutura do site e cada pedaço da imagem é colocado como fundo de um bloco e reposicionado usando background-position. Não se preocupe, algumas ferramentas online fazem isso para você, como o http://csssprites.com/

2 – Comprimir usando GZIP

A partir do HTTP 1.1 os browser implementaram um cabeçalho chamado Accept-Encoding. Isso significa que o servidor pode mandar um arquivo comprimido com deflate ou gzip (mais popular) que o browser conseguirá descomprimir. Essa compressão geralmente diminui o tamanho do arquivo em 70%. O único contra do Gzip é usá-lo em arquivos já comprimidos, tais como mp3, jpg, pdf entre outros, pois como esses arquivos tem sua compressão própria a compressão com gzip pode até aumentar o tamanho do arquivo. Ele é recomendando principalmente em arquivos de texto plano, tais como HTML, CSS e Javascript.

3 – Tornar o CSS e o JS externos

Com o CSS e o JS externos você diminui o tamanho do seu documento HTML e aumenta em duas requisições HTTP (considerando um arquivo para cada). Como isso pode ser bom, de acordo com 1 (Diminuir requisições HTTP)? Com os arquivos externos, você pode cachear-los, diminuindo consideravelmente o tempo de carregamento. Geralmente fazendo isso se tem um desempenho melhor nos sites. A única exceção para esse ponto são em páginas que geralmente são acessadas apenas uma vez (tais como páginas de home), tornando o cache inútil.

4 – Colocar o CSS no topo

Quando o browser está renderizando a página, ele renderiza na ordem que vai encontrando os elementos no seu html. O maior problema de colocar o CSS no final da página é que os browsers evitam de renderizar para não ter que renderizar novamente depois que acharem o CSS. Isso vai deixar uma página branca para o usuário, até que o CSS seja renderizado.

Uma coisa que muita gente acha é que fazendo isso a página terá um tempo de carregamento mais rápido. Mas NÃO, o tempo de carregamento não é diferente. A única coisa que muda é a visualização por parte do usuário pois com o CSS no topo, ele pode navegar na página já com um feedback visual. Simples, né?

5 – Colocar o JS no rodapé

A regra geral é que são feitos dois downloads paralelos por domínio quando uma página é acessada. Colocar o script no head ou no meio da página HTML vai paralisar os downloads paralelos enquanto somente o script é carregado. Somente evite colocá-los no rodapé se eles contiverem alguma função como document.write, por exemplo.

6 – Colocar um cabeçalho Expires nos arquivos

Ao acessar um site pela primeira vez, seu browser faz um requisição de uma página para o servidor. O servidor processa e retorna uma página para você. O browser começa a fazer requisições dos outros arquivos que estão lá (imagens, CSS, scripts) até carregar tudo.

Na segunda vez que você acessa o site, o carregamento é bem mais rápido, certo? Isso acontece porque o browser mantêm em cache os arquivos do site e logicamente o carregamento é bem mais rápido. Mas isso ainda pode ser melhorado.

Desse modelo que citei anteriormente, o browser ainda precisa fazer um GET condicional, para saber se o arquivo mudou (geralmente essa comparação é feita com a data de última modificação, mas também pode ser feita de outros jeitos, como com E-tags) e então o servidor retorna uma requisição 304 (arquivo não modificado). Se colocar um cabeçalho Expires nos seus arquivos, o browser não precisa fazer esse GET condicional no servidor, deixando o carregamento ainda mais rápido.

7 – Minificar arquivos JS e CSS

A técnica de minificar se constitui em tirar espaços desnecessários (espaços, tabulações, linhas em branco) e comentários dos arquivos, diminuindo consideravelmente seu tamanho.
Um dos que eu gosto de usar é o YUI Compressor.

Essas são somente algumas formas. Existem várias outras, e muitas estão nesse livro que citei no começo do post. Eu repito, se você é desenvolvedor web, não deixe de ler o livro. E aproveite também seu amigo Google para se aprofundar no assunto. :)

Tags:

Follow

Get every new post delivered to your Inbox.