Dica de Python: glob

On 16 de agosto de 2010, in Sem categoria, by elcio

Um módulo Python pequeno, com uma única função muito simples, mas que você precisa conhecer é o glob. O que ele faz é obter uma listagem de diretório:

import glob
files=glob.glob('*')

O que equivale a:

import os
files=os.listdir('.')

Porém o glob é muito poderoso. Podemos fazer:

glob.glob('*.mad')

Ou:

glob.glob('../pasta/*')

Fica a dica.

Tagged with:
 

Parallel Python

On 5 de abril de 2010, in Sem categoria, by elcio

Embora seu computador possa ter dois, quatro, oito ou até dezesseis núcleos de processamento, o Python só usa um deles de cada vez (mesmo trabalhando com threads). Parallel Python resolve o problema. Um exemplo simples, para você entender como funciona:

ppserver = pp.Server(ppservers=())
job1 = ppserver.submit(funcao_demorada, (), (), ())
job2 = ppserver.submit(funcao_demorada, (), (), ())
print job1()+job2()

Os quatro argumentos do método submit são: a função que será executada, os argumentos passados a ela, as funções que ele pode chamar e os módulos dos quais ela depende. Veja um exemplo de como chamar com esses parâmetros:

ppserver = pp.Server(ppservers=())
job1 = ppserver.submit(funcao_demorada, (44,),
                        (sub_funcao,), ("sys","math",))
job2 = ppserver.submit(funcao_demorada, (25,),
                        (sub_funcao,), ("sys","math",))
print job1()+job2()

Divirta-se!

Desafio de programação: resolvendo Lights Off

On 30 de março de 2010, in Sem categoria, by elcio

Fiz essa versão do clássico joguinho Lights Off:

O jogo é simples, e o objetivo é apenas apagar todas as luzes. Por curiosidade, fiz também o algoritmo que resolve o jogo:

O desafio está lançado. O primeiro que colocar nos comentários a URL de uma página com um botão “solve” como o meu ganha uma entrada para o Codeshow. Importante:

  1. Vale o primeiro comentário. Mesmo que você comente de madrugada e eu demore a moderar, ganha quem comentar primeiro.
  2. O solucionador tem que ser escrito em Javascript. Você pode copiar minha versão do jogo e desenvolver em cima dela.
  3. Não pode resolver na base da tentativa e erro. Tem que ser uma boa solução, que resolva qualquer estado do tabuleiro em 20 passos ou menos.

Divirtam-se!

(O pessoal da Visie, se quiser participar, pode. Só não vai ganhar nada ;-) )

Tagged with:
 

utf8_decode em Javascript

On 1 de março de 2010, in Geral, by elcio

Navegando por aí, acabei esbarrando no blog do meu amigo Marcos Rossow (nossa, quanto tempo!)

E encontrei esse post: JavaScript UTF-8 Decode, com um código tirado daqui: JavaScript utf8_decode.

Tem duas coisas que me incomodam nessa abordagem. A primeira é essa mania que muita gente tem, particularmente programadores PHP, de tratar UTF-8 como um “código alienígena” e ISO-8859-1 como normal e padrão. Alô, ISO-8859-1 é usado por parte do mundo. Não dá para escrever hebraico, mandarim, japonês, árabe ou russo com isso. ISO-8859-1 é uma das diversas tabelas de caracteres que existem mundo afora. E Unicode é a única maneira sensata de escrever um sistema que possa ser usado aqui e na China.

A segunda coisa que me incomoda é a quantidade de código. Não testei profundamente, mas tenho a impressão de que o código abaixo resolve o problema:

function utf8_decode(t){
  return decodeURIComponent(escape(t))
}
Tagged with:
 

Hein?

On 10 de fevereiro de 2010, in Sem categoria, by elcio

Trecho de código legado (ASP) que pegamos aqui:

if len(request("price")) = 3 then
    valorTotal = left(request("price"),1)
elseif len(request("price")) = 4 then
    valorTotal = left(request("price"),2)
elseif len(request("price")) = 5 then
    valorTotal = left(request("price"),3)
end if

Jênio.

Tagged with:
 

Brincando com a API do twitter

On 26 de dezembro de 2008, in Sem categoria, by elcio

Resolvi experimentar um pouco a Twitter API. É linda, do jeito que toda API deveria ser. É REST, muito fácil de entender e colocar para funcionar, e devolve dados em XML, JSON, RSS e ATOM.

Essa simplicidade permite interagir com a API usando ferramentas simples da linha de comando do Unix, como o wget e a cURL. Para nossos exemplos, vamos usar cURL. Se você usa Ubuntu, antes de começar faça:

sudo apt-get install curl

Para fazer um simples post, por exemplo, você pode digitar, em seu terminal:

curl -u seu_username:sua_senha -d status="Twittando do terminal. Aprendi com o Elcio: http://blog.elcio.com.br/brincando-com-a-api-do-twitter/" http://twitter.com/statuses/update.json

É isso mesmo, meninos e meninas, é só um post com autenticação, mais nada. RESTful, simples e elegante, deixar qualquer SOAP no chinelo. Inspirador para qualquer um que precise projetar uma API. Isso retorna dados em JSON. Se você quiser os mesmos dados em XML, ATOM ou RSS, basta mudar a extensão na url.

Agora vamos automatizar isso. Eu criei um arquivo /usr/local/bin/twitter com o seguinte conteúdo:

source $HOME/.twitter
curl -u $user:$password -d status="$@" http://twitter.com/statuses/update.json

Naturalmente, criei o arquivo como root e dei permissão de execução para todos os usuários. Agora, no diretório de cada usuário, basta criar um arquivo .twitter com o seguinte conteúdo:

user=seu_username
password=sua_senha

Pronto, tendo feito isso, qualquer usuário que tenha o arquivo .twitter em seu home pode twittar do terminal com:

twitter "Twittando do terminal, aprendi com o Elcio: http://blog.elcio.com.br/brincando-com-a-api-do-twitter/"

Simples e indolor, agora você pode automatizar suas twittadas com shell script. Pode, por exemplo, twittar toda vez que seu servidor baleiar, ou agendar twits com cron.

Search API

A Search API também é espetacularmente simples, dê uma olhada. Fiz a UPBox usando a Twitter Search API, por exemplo, com 22 linhas de código.

Tagged with:
 

Fuja da complexidade

On 2 de novembro de 2008, in Sem categoria, by elcio

Abri o OpenOffice Writer, mandei gravar uma macro, escrevi “teste”, selecionei e pintei de vermelho. Olha o código gerado:

sub Main
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Text"
args1(0).Value = "teste"
dispatcher.executeDispatch(document, ".uno:InsertText", "", 0, args1())
rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:SelectAll", "", 0, Array())
rem ----------------------------------------------------------------------
dim args3(0) as new com.sun.star.beans.PropertyValue
args3(0).Name = "FontColor"
args3(0).Value = 16711680
dispatcher.executeDispatch(document, ".uno:FontColor", "", 0, args3())
end sub

Há muito código complexo por aí. Nesse caso, para invocar os métodos dos objetos do OpenOffice, é preciso usar um objeto dispatcher, chamando executeDispatcher, e passando o objeto, o nome do método e um array de argumentos. Que espécie de sadismo leva alguém a projetar uma solução como essa? Vale lembrar o que diz o Zen do Python:

Se uma implementação é difícil de explicar, é uma idéia ruim.

Outro exemplo interessantíssimo é o protocolo SOAP. Se você precisar construir um serviço SOAP do zero, dê uma investigada na documentação que você vai ter que ler. Compare com a documentação do protocolo XML-RPC, para ter uma idéia.

Meninos, o tio vai ensinar um segredo a vocês, a complexidade se reproduz assexuadamente. Há muito código complexo demais por aí. Se você encontrar indícios de complexidade hoje, corte antes que ela se reproduza, porque ela tende a fugir do controle. Cada vez que você deixa uma implementação complexa num componente de um sistema, você está complicando um pouquinho todos os pontos do sistema que usam aquele. Os resultados ruins são exponenciais. Por mais talentoso que você seja, se deixar a complexidade se enraizar e crescer, vai chegar um momento em que a lógica vai “jogar a toalha” e você vai começar a programar na base da tentativa e erro.

Lembre-se, então, partes simples, conectadas por interfaces simples. Complicado é errado, feio e mau, faz você entregar atrasado e com bugs. E, se precisar de inspiração, abra o Python e digite:

import this

Tagged with:
 

Data errada no Javascript? Bug?

On 11 de setembro de 2008, in Sem categoria, by elcio

Um amigo me escreveu agora para mostrar algo muito curioso. Abra sua Firebug, ou qualquer outro lugar onde você roda Javascript, e teste:

new Date(2008,8,11)

Você deve ter como retorno um objeto de data, que se impresso mostra:

Thu Sep 11 2008 00:00:00 GMT-0300 (BRT)

Porque setembro e não agosto, você pode se perguntar. É porque em Javascript, assim com na maioria das linguagens de programação, arrays começam com zero, então faz sentido que contadores também comecem com zero. Assim, janeiro é o mês zero, e se você precisar construir um array com os nomes dos meses, janeiro será o primeiro do array. Faz todo o sentido.

Agora, o que não faz sentido. Tente:

new Date(2008,9,12)

Aqui no meu sistema eu obtive:

Sat Oct 11 2008 23:00:00 GMT-0300 (BRT)

Ou seja, uma hora mais cedo. O que será isso? Correção para o horário de verão? Se é, em que regra se baseia? Os horários de verão no Brasil mudam todo ano, e dependem de em que estado você está.

Alguém tem alguma dica?

Tagged with:
 

Não entre em pânico

On 31 de março de 2008, in Sem categoria, by elcio

Você está usando um terminal conectado a um servidor Unix quando as coisas começam a se comportar de maneira estranha. Depois de algum tempo você descobre o problema. Vai até a mesa de um programador novato e descobre que ele, como root, digitou:

# cd
# rm -rf *

O sujeito percebeu a burrada antes de apagar os diretórios /usr e /users. Nesse caso, /users continha os diretórios home. Mas todo o resto do sistema se foi, incluindo /dev, /etc e /bin.

O que você faria? Para complicar as coisas, esta história aconteceu há um bocado de tempo, numa VAX. Ou seja, não era só fazer um boot com um live-CD, fazer um backup dos dados dos usuários e reinstalar o sistema.

O que fazer? Não entrar em pânico. Uma história e tanto.

Tagged with:
 

Dicas de shell: Greg's Wiki Bash Pitfalls

On 26 de março de 2008, in Sem categoria, by elcio

No Greg’s Wiki você encontra os Bash Pitfalls, uma lista de problemas comuns entre os programadores bash iniciantes.

Encontrei vários dos meus erros comuns lá. E aprendi um bocado.

Tagged with:
 

Divirta-se: Puzzles do Wendel

On 23 de janeiro de 2008, in Sem categoria, by elcio

Exercício de lógica. Esses Puzzles do Wendel me fizeram perder um tempão! Boa diversão, depois conte para a gente aqui nos comentários até onde você foi. IMPORTANTE: não escreva as respostas, senão você estraga a brincadeira dos outros.

Tagged with: