por Flavio Coelho (noreply@blogger.com) em 18 de March de 2010 às 12:37
Planeta PythonBrasil por Flavio Coelho (noreply@blogger.com) em 18 de March de 2010 às 12:37
Just a quick post to get me started at blogging again.
Over the last year (wow, time flies by!) I’ve been working at Canonical, as part of the Landscape team. This is a very diverse team with lots of different skills, and somehow I found myself naturally gravitating towards working more closely on frontend-related issues, of which I could highlight writing YUI3 widgets, speeding up page loading experience and creating a nice testing infrastructure. There’s a ton of things I could write about that, and I really plan to. But today’s entry will be pretty short.
As part of a brain-break task I fixed some of our Javascript tests today so that they would run on Google Chrome. We haven’t been targeting Chrome so far, but that might change soon, driven by Google Analytics stats of people using Landscape.
But, the thing that really caught my attention was the difference in speed between Chrome and Firefox.
For comparison:
Google Chrome 5.0.307.7 beta
$ BROWSER=google-chrome ./bin/test -1vpc --layer=JsTestDriverLayer Running tests at level 1 Running canonical.testing.javascript.JsTestDriverLayer tests: Set up canonical.testing.javascript.JsTestDriverLayer in 1.020 seconds. Running: Ran 318 tests with 0 failures and 0 errors in 9.545 seconds. Tearing down left over layers: Tear down canonical.testing.javascript.JsTestDriverLayer in 0.366 seconds.
Firefox 3.6.3pre
$ BROWSER=firefox ./bin/test -1vpc --layer=JsTestDriverLayer Running tests at level 1 Running canonical.testing.javascript.JsTestDriverLayer tests: Set up canonical.testing.javascript.JsTestDriverLayer in 1.014 seconds. Running: Ran 318 tests with 0 failures and 0 errors in 15.032 seconds. Tearing down left over layers: Tear down canonical.testing.javascript.JsTestDriverLayer in 0.349 seconds.
Firefox 3.7a3pre
$ BROWSER=firefox-3.7 ./bin/test -1vpc --layer=JsTestDriverLayer Running tests at level 1 Running canonical.testing.javascript.JsTestDriverLayer tests: Set up canonical.testing.javascript.JsTestDriverLayer in 0.804 seconds. Running: Ran 318 tests with 0 failures and 0 errors in 13.433 seconds. Tearing down left over layers: Tear down canonical.testing.javascript.JsTestDriverLayer in 0.379 seconds.
Disclaimer: Both instances of Firefox were started with the “-safe-mode” flag, which disables all plugins and extensions. Also, as they say around here at Canonical: NOT A METRIC. But interesting still.
If you look closely at this post you might find some hints about things we’ve been working on and which I hope to write about, in addition to general tips and tricks about page speed optimization from experiences in both Landscape and Launchpad.
por Eduardo Willians (noreply@blogger.com) em 17 de March de 2010 às 22:41
Há um tempo eu ensinei aqui como fazer o Mac falar. O Linux também faz. Instala aí:
$ sudo apt-get install espeak
Daí é só mandar:
$ espeak "Luke, I am your father."
E fala português também:
$ espeak -v pt "Luke, eu sou seu pai."
Com -f arquivo.txt, ele lê o texto de um arquivo. Com -w arquivo.wav, ele salva o áudio num arquivo. E pode ser comandado via ssh.
Consegue imaginar utilidades para isso?
TEMPLATE_DIRS = ( "/home/html/project/templates",)
MEDIA_ROOT = "/home/html/project/appmedia/"
import os
SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(SITE_ROOT, 'appmedia')
TEMPLATE_DIRS = ( os.path.join(SITE_ROOT, 'templates'),)
TEMPLATE_CONTEXT_PROCESSORS = ('django.core.context_processors.request',
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media"
)
<img src="/site/midia/imagens/logo.jpg" />
<img src="{{MEDIA_URL}}imagens/logo.jpg" />
from django.conf.urls.defaults import *
urlpatterns = patterns('produtos.views',
(r'^$', 'inicio',),
(r'^cadastro/$', 'cadastro'),
(r'^(?P\d+)/$', 'detalhe'),
(r'^(?P\d+)/comprar/$', 'comprar'),
(r'^carrinho/$', 'carrinho'),
)
<a href="/produtos/">Lista</a> - <a href="/produtos/cadastro">Novo</a> - <a href="/carrinho/">Carrinho de compras</a>
<ul>{%for p in produtos%}
<li><a href="/produtos/{{p.id}}/">{{p.nome}}</a></li>
{%endfor%} </ul>
from django.conf.urls.defaults import *
urlpatterns = patterns('produtos.views',
url(r'^$', 'inicio', name='produto-home'),
url(r'^cadastro/$', 'cadastro', name='produto-novo'),
url(r'^(?P\d+)/$', 'detalhe', name='produto-exibe'),
url(r'^(?P\d+)/comprar/$', 'comprar', name='produto-compra'),
url(r'^carrinho/$', 'carrinho', name='produto-carrinho'),
)
<a href="{%url produto-home %}">Lista</a> - <a href="{%url produto-novo %}">Novo</a> - <a href="{%url produto-carrinho%}">Carrinho de compras</a>
<ul>
{%for p in produtos%}
<li><a href="{%url produto-exibe p.id %}">{{p.nome}}</a></li>
{%endfor%} </ul>
class Receita(models.Model):
data_publicacao = models.DateTimeField(auto_now_add=True)
nome = models.CharField(max_length=100)
categoria = models.ForeignKey(Categoria, null=True)
destaque = models.BooleanField(u"Destaque?")
class Meta:
ordering = ['-data_publicacao']
get_latest_by = 'data_publicacao'
def __unicode__(self):
return self.nome
def get_absolute_url(self):
return reverse('produto-exibe', args=[self.id])
<ul>
{%for p in produtos%}
<li><a href="{{p.get_absolute_url}}/">{{p.nome}}</a></li>
{%endfor%}
</ul>

por Marcos Daniel Petry (marcospetry@gmail.com) em 16 de March de 2010 às 23:31
In the past weeks ProFUSION coworker Gustavo Padovan was hacking on bluetooth support for Enlightenment ecosystem using the BlueZ stack.
This module follows my previous ConnMan module and is built upon the same base. Since BlueZ and ConnMan are both developed by almost the same developer group, the DBus APIs are very similar. The current module is quite simple, yet useful and allows pairing devices. The idea is to further extend it to be a full Bluetooth Agent, allowing different authentication and authorization methods, maybe go even further and send files using the OBEX protocol.
The infrastructure is available as ebluez inside e_dbus, so it is easily accessible to all EFL applications. The infrastructure exposes just a handful methods that were required by the module, but it is easily extensible as most methods are similar and the helpers do most of work, just need to specify the method names and convert types.
ProFUSION is also working on oFono support. Stay tuned to see the module João Paulo is cooking, the e_dbus code is already in SVN.
por Gustavo Sverzut Barbieri em 12 de March de 2010 às 23:27
por Eduardo Willians (noreply@blogger.com) em 11 de March de 2010 às 13:48
Aqui na empresa temos duas contas de FTP contratadas no nosso plano de hospedagem para usarmos como espaço de backup. As duas contas tem um espaço limitado e toda semana eu preciso monitorar quanto espaço estamos usando, para evitar erros no script de backup. Para facilitar esse controle eu criei um pequeno script Python para navegar em todas as pastas e me dizer quanto espaço estou usando. O script ficou assim:
Agora é só colocar no crontab e receber diariamente o espaço utilizado.
Fontes:
http://www.vivaolinux.com.br/script/navegador-ftp
http://code.rivers.pro/python-function-to-convert-bytes-to-kbmbgb/
Scott Moser has just announced this week that the new Ubuntu images which boot out of an EBS-based root filesystem in EC2, and thus will persist across reboots, are available for testing.
As usual with something that just left the oven and is explicitly labeled for testing purposes, there was a minor bug in the first iteration of images which was even mentioned in the announcement itself. The bug, if not worked around as specified in the announcement, will prevent the image from rebooting.
Having an bootable EBS image which can’t reboot is a quite interesting (and ironic) problem. You have an image which persists, but suddenly you have no way to see what is inside the image anymore because you can’t boot it. Naturally, even if the said bug didn’t exist in the first place, it’s fairly easy to get into such a situation accidentally if you’re fiddling with the image configuration.
So, in this post we’ll see how to recover from a situation where a bootable EBS image can’t boot.
Getting started
To start this up, we’ll boot one of the EBS images which Scott mentioned in his announcement: ami-8bec03e2. As we see in the output of ec2-describe-images, this is an EBS-based image for i386:
% ec2-describe-images ami-8bec03e2
IMAGE ami-8bec03e2 099720109477/ebs/ubuntu-images-testing/ubuntu-lucid-daily-i386-server-20100305 099720109477 available public i386 machine aki-3fdb3756 ebs
BLOCKDEVICEMAPPING /dev/sda1 snap-f1efd098 15
Let’s run this image. Remember to replace the value passed in the -k command line option with your own key pair name.
% ec2-run-instances -k gsg-keypair ami-8bec03e2
RESERVATION r-9e4615f6 626886203892 default
INSTANCE i-e3e33a88 ami-8bec03e2 pending gsg-keypair 0 m1.small 2010-03-09T20:04:12+0000 us-east-1c aki-3fdb3756 monitoring-disabled ebs
There we go. We got an instance allocated in the availability zone us-east-1c. It’s important to keep track of this information, since EBS volumes are zone-specific.
As part of the above command, we must have been allocated an EBS volume automatically, and it should be attached to the instance we just started. We can investigate it with the ec2-describe-volumes command:
% ec2-describe-volumes
VOLUME vol-edca1684 15 snap-f1efd098 us-east-1c in-use 2010-03-09T20:04:20+0000
ATTACHMENT vol-edca1684 i-e3e33a88 /dev/sda1 attached 2010-03-09T20:04:24+0000
Now, we’ll get into the running instance and do some arbitrary modifications, just as a way to demonstrate that the data we don’t want to lose actually survives the recovering operation. Note that the domain name is obtained with the ec2-describe-instances command.
% ssh -i ~/.ssh/id_dsa_gsg-keypair ubuntu@ec2-184-73-51-147.compute-1.amazonaws.com
(…)ubuntu@domU-12-31-39-0E-A0-03:~$ echo “Important data” > important-data
ubuntu@domU-12-31-39-0E-A0-03:~$ ls -l important-data
-rw-r–r– 1 ubuntu ubuntu 15 Mar 9 20:15 important-dataubuntu@domU-12-31-39-0E-A0-03:~$ sudo reboot
Broadcast message from ubuntu@domU-12-31-39-0E-A0-03
(/dev/pts/0) at 20:18 …
The system is going down for reboot NOW!
Note that we didn’t actually fix the problem reported by Scott, so our machine won’t really reboot. If we wait a while, we can even see that the problem is exactly what was reported in the announcement (note it really takes a bit for the output to be synced up):
% ec2-get-console-output i-e3e33a88 | tail -4
mount: special device ephemeral0 does not exist
mountall: mount /mnt [294] terminated with status 32
mountall: Filesystem could not be mounted: /mnt
Alright, now what? Machine is dead.. and can’t reboot. How do we get to our important data?
Fixing the problem
The first thing we do is to stop the instance. Do not terminate it, or you’ll lose the EBS volume! After stopping it, we’ll detach the EBS volume that was being used as the root filesystem, so that we can attach somewhere else.
% ec2-stop-instances i-e3e33a88
INSTANCE i-e3e33a88 running stopping% ec2-detach-volume vol-edca1684
ATTACHMENT vol-edca1684 i-e3e33a88 /dev/sda1 detaching 2010-03-09T20:04:22+0000
Now, we need to attach this volume in an image which actually boots, so that we can fix it. For this experiment, we’ll pick one of the daily Lucid images, but we could use any other working image really. Just remind that the image must be running in the same availability zone as our previous instance, since the EBS volume won’t be accessible otherwise.
% ec2-run-instances -k gsg-keypair -z us-east-1c ami-b5f619dc
RESERVATION r-967427fe 626886203892 default
INSTANCE i-fd08d196 ami-b5f619dc pending gsg-keypair 0 m1.small 2010-03-09T21:10:11+0000 us-east-1c aki-3fdb3756 monitoring-disabled instance-store% ec2-attach-volume vol-edca1684 -i i-fd08d196 -d /dev/sdh1
ATTACHMENT vol-edca1684 i-fd08d196 /dev/sdh1 attaching 2010-03-09T21:10:51+0000
With the instance running and the EBS root device attached with an alternative device name, we can then login to fix the original problem which prevented the image from booting correctly. In our case, we’ll simply do what Scott suggested in the announcement.
% ssh -i ~/.ssh/id_dsa_gsg-keypair ubuntu@ec2-204-236-194-196.compute-1.amazonaws.com
(…)
$ mkdir ebs-root
$ sudo mount /dev/sdh1 ebs-root
$ sudo sed -i ’s/^ephemeral0/#ephemeral0/’ ebs-root/etc/fstab
$ sudo umount ebs-root
$ logout
Connection to ec2-204-236-194-196.compute-1.amazonaws.com closed.
Done! Our EBS volume is now correct, and it should boot alright. We’ll detach the volume from the temporary instance we created, and will reattach it back to the old bootable EBS instance which is stopped. Note that we won’t yet terminate the temporary instance, because we may need it in case something else is still wrong, and we are already paying to use it for the hour anyway. We just have to remind ourselves to terminate it once we’re fully done.
% ec2-detach-volume vol-edca1684
ATTACHMENT vol-edca1684 i-fd08d196 /dev/sdh1 detaching 2010-03-09T21:10:51+0000% ec2-attach-volume vol-edca1684 -i i-e3e33a88 -d /dev/sda1
ATTACHMENT vol-edca1684 i-e3e33a88 /dev/sda1 attaching 2010-03-09T21:24:55+0000% ec2-describe-volumes vol-edca1684
VOLUME vol-edca1684 15 snap-f1efd098 us-east-1c in-use 2010-03-09T20:04:20+0000
ATTACHMENT vol-edca1684 i-e3e33a88 /dev/sda1 attached 2010-03-09T21:24:55+0000
Okay! It should all be good now. It’s time to restart our instance, and see if it is working. Note that since you stopped and started the instance, the public domain name most probably has changed, and thus we need to find it out again with ec2-describe-instances once the instance is running.
% ec2-start-instances i-e3e33a88
INSTANCE i-e3e33a88 stopped pending% ec2-describe-instances i-e3e33a88
RESERVATION r-9e4615f6 626886203892 default
INSTANCE i-e3e33a88 ami-8bec03e2 ec2-184-73-72-214.compute-1.amazonaws.com domU-12-31-39-03-B8-21.compute-1.internal running gsg-keypair 0 m1.small 2010-03-09T21:28:43+0000 us-east-1c aki-3fdb3756 monitoring-disabled 184.73.72.214 10.249.187.207 ebs
BLOCKDEVICE /dev/sda1 vol-edca1684 2010-03-09T21:24:55.000Z% ssh -i ~/.ssh/id_dsa_gsg-keypair ubuntu@ec2-184-73-72-214.compute-1.amazonaws.com
(…)
$ cat important-data
Important data$ logout
Connection to ec2-184-73-72-214.compute-1.amazonaws.com closed.
It worked, and our important data is still there!
Don’t forget to kill the temporary instance you’ve used to fix it after you’re comfortable with the result:
% ec2-terminate-instances i-fd08d196
INSTANCE i-fd08d196 running shutting-down
Conclusion
Concluding, in this post we have seen how to fix a bootable EBS machine which can’t actually boot. The technique consists of detaching the volume from the stopped instance, attaching it to a temporary instance, fixing the image, and then reattaching it back to the original image. This back and forth of EBS volumes is quite useful in many circumstances, so keep it in your tool belt.
Em 2007 dois pesquisadores britânicos teorizaram um dispositivo que eles chamaram de ”alçapão de arco-íris”, sendo um dispositivo composto por uma lente
que seria responsável pela reflexão, dispersão e refração de um feixe de luz para o interior do artefato que teria uma placa com várias camadas de espelhos de metamateriais que poderia capturar o feixe de luz, não permitindo sua dispersão:

Stopping light in metamaterials: the trapped rainbow
Na época vários grupos ao redor do mundo, acreditando na teoria trabalharam alucinadamente tentando criar um protótipo funcional deste dispositivo e no final de 2009 um grupo de pesquisadores americanos conseguiu obter sucesso e com um aparato muito simples provaram o conceito da “armadilha de arco-íris”, demonstrando que os físicos britânicos estavam certos:
Rainbow trapped for the first time
Quando comentei este feito com um colega pela primeira vez, logo que via a notícia na semana que ela foi publicada na New Scientist, ele fez aquele clássico comentário: este pessoal não tem nada mais importante para fazer?
Bem, esta técnica poderá ser útil para armazenar informações de forma puramente ótica, algo que irá revolucionar a computação (e talvez a vida) no futuro, eliminando a necessidade de conversões de sinais óticos em eletrônicos, facilitando o processo de manipulação de fótons e proporcionando a criação de meios de armazenamento de informações revolucionário. E considerando que em 2009 também surgiu o primeiro processador quântico fotônico autêntico podemos elucubrar que parte do futuro da computação está na fotônica e esta nova descoberta é certamento um grande marco.
Quer algo mais útil do que isto?
Ruminando e divagando sobre este assunto com um amigo este final de semana, ele lembrou do filme Minority Report e de um cartão de armazenamento que parecia que as imagens estavam armazenadas de modo fotônico, visto que elas podiam ser parcialmente vistas sem mesmo estar no seu respectivo driver de leitura.
Com a evolução das pesquisas do grafeno, dos metamateriais e outros daqui a alguns anos silício será coisa do passado, se bobear armazenamento magnético também e por consequencias do entrelaçamento quântico a velocidade da luz irá parecer velocidade tartarugal, imaginou como será a computação e o futuro das telecomunicações?

No final de 2008, escrevi um post onde eu brincava que em 2050 “telepatia sintética” seria coisa do passado, bom, o DARPA tem financiado pesquisas nesta área e isto
da tem a ver com ESP, visto que a tecnologia é puramente baseada em neurociência e telecomunicações, sendo-se que o artefato que possibilitará tal feito é puramente um dispositivo de neuroengenharia, área que tende a evoluir muito no futuro e aposto que vários dos “neuroengenheiros” serão nascerão a partir do fascínio pelos brinquedos Mindflex e o Star Wars Force Trainer.
Mas o quê a armadilha de arco-íris e a q-telepatia tem em comum? A resposta é: computação quântica. A neuroengenharia continuará presente, porém o processador quântico será peça fundamental.
E breve, os neurohackers já não serão mais atores da ficção cyberpunk e sim do novo contexto neurotecnológico do balaio de gato que será o admirável mundo novo da computação, fico imaginando a segunda (ou será terceira?) geração que será os q-neurohackers.
por noreply@blogger.com (Ricardo Bittencourt) em 07 de March de 2010 às 03:00

por noreply@blogger.com (Cacilhας, La Batalema) em 05 de March de 2010 às 18:23
Pretendia esperar esperar mais uns dias para postar com mais profundidade, mas estou tão deslumbrado com Mongo que vou postar com apenas dois dias de estudo.por Eduardo Willians (noreply@blogger.com) em 05 de March de 2010 às 13:56
por noreply@blogger.com (Ricardo Bittencourt) em 03 de March de 2010 às 01:27
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))
}
Há atualmente na Computação uma onda de adoção de bancos de dados não-relacionais, comumente chamados NoSQL.mongo:bash$ mongo
MongoDB shell version: 1.2.2
url: test
connecting to: test
type "help" for help
>/srv/mongodb/etc/mongodb.conf, você pode especificar isso na linha de comando do cliente:bash$ mongo --port 27018--host.use:> use mydb-u (usuário) e -p (senha), ou já do prompt do interpretador:> use admin
> db.auth('admin', 'ra35EG/dz');> help> db.help();foo:> db.foo.help();> show dbs> show collections> show users> db.addUser('admin', 'ra35EG/dz');> db.auth('admin', 'ra35EG/dz');> db.foo.find();> db.foo.drop();> db.dropDatabase();foo da base mydb:> use mydb
> var j = { name: 'mongo' };
> var t = { x: 3 };
> db.foo.save(j);
> db.foo.save(t);
> db.foo.find();
{ "_id" : ObjectId("4b8949d9cd50237b8573833b"), "name" : "mongo" }
{ "_id" : ObjectId("4b8949dbcd50237b8573833c"), "x" : 3 }_id é criado automaticamente e é a chave primária.j:> j = db.foo.findOne({ name: 'mongo' });
> db.foo.remove(j);> db.foo.drop();> for (var i=0; i<100; ++i) db.foo.save({ x: i, y: i*i });x variando de zero a noventa e nove e y igual a seu quadrado:> db.foo.find();
{ "_id" : ObjectId("4b894c05cd50237b8573833e"), "x" : 0, "y" : 0 }
{ "_id" : ObjectId("4b894c05cd50237b8573833f"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("4b894c05cd50237b85738340"), "x" : 2, "y" : 4 }
{ "_id" : ObjectId("4b894c05cd50237b85738341"), "x" : 3, "y" : 9 }
{ "_id" : ObjectId("4b894c05cd50237b85738342"), "x" : 4, "y" : 16 }
{ "_id" : ObjectId("4b894c05cd50237b85738343"), "x" : 5, "y" : 25 }
{ "_id" : ObjectId("4b894c05cd50237b85738344"), "x" : 6, "y" : 36 }
{ "_id" : ObjectId("4b894c05cd50237b85738345"), "x" : 7, "y" : 49 }
{ "_id" : ObjectId("4b894c05cd50237b85738346"), "x" : 8, "y" : 64 }
{ "_id" : ObjectId("4b894c05cd50237b85738347"), "x" : 9, "y" : 81 }
{ "_id" : ObjectId("4b894c05cd50237b85738348"), "x" : 10, "y" : 100 }
{ "_id" : ObjectId("4b894c05cd50237b85738349"), "x" : 11, "y" : 121 }
{ "_id" : ObjectId("4b894c05cd50237b8573834a"), "x" : 12, "y" : 144 }
{ "_id" : ObjectId("4b894c05cd50237b8573834b"), "x" : 13, "y" : 169 }
{ "_id" : ObjectId("4b894c05cd50237b8573834c"), "x" : 14, "y" : 196 }
{ "_id" : ObjectId("4b894c05cd50237b8573834d"), "x" : 15, "y" : 225 }
{ "_id" : ObjectId("4b894c05cd50237b8573834e"), "x" : 16, "y" : 256 }
{ "_id" : ObjectId("4b894c05cd50237b8573834f"), "x" : 17, "y" : 289 }
{ "_id" : ObjectId("4b894c05cd50237b85738350"), "x" : 18, "y" : 324 }
{ "_id" : ObjectId("4b894c05cd50237b85738351"), "x" : 19, "y" : 361 }
has more> db.foo.find().count();
100> db.foo.find().limit(5);
{ "_id" : ObjectId("4b894c05cd50237b8573833e"), "x" : 0, "y" : 0 }
{ "_id" : ObjectId("4b894c05cd50237b8573833f"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("4b894c05cd50237b85738340"), "x" : 2, "y" : 4 }
{ "_id" : ObjectId("4b894c05cd50237b85738341"), "x" : 3, "y" : 9 }> db.foo.find().skip(5).limit(5);
{ "_id" : ObjectId("4b894c05cd50237b85738343"), "x" : 5, "y" : 25 }
{ "_id" : ObjectId("4b894c05cd50237b85738344"), "x" : 6, "y" : 36 }
{ "_id" : ObjectId("4b894c05cd50237b85738345"), "x" : 7, "y" : 49 }
{ "_id" : ObjectId("4b894c05cd50237b85738346"), "x" : 8, "y" : 64 }
{ "_id" : ObjectId("4b894c05cd50237b85738347"), "x" : 9, "y" : 81 }x vinte e quatro:> var e = db.foo.findOne({ x: 24 });
> print(e.y);
576
> print(tojson(e));
{ "_id" : ObjectId("4b894c05cd50237b85738356"), "x" : 24, "y" : 576 }x maior que cinquenta:> db.foo.find('this.x > 50');
{ "_id" : ObjectId("4b894c05cd50237b85738371"), "x" : 51, "y" : 2601 }
{ "_id" : ObjectId("4b894c05cd50237b85738372"), "x" : 52, "y" : 2704 }
{ "_id" : ObjectId("4b894c05cd50237b85738373"), "x" : 53, "y" : 2809 }
{ "_id" : ObjectId("4b894c05cd50237b85738374"), "x" : 54, "y" : 2916 }
{ "_id" : ObjectId("4b894c05cd50237b85738375"), "x" : 55, "y" : 3025 }
{ "_id" : ObjectId("4b894c05cd50237b85738376"), "x" : 56, "y" : 3136 }
{ "_id" : ObjectId("4b894c05cd50237b85738377"), "x" : 57, "y" : 3249 }
{ "_id" : ObjectId("4b894c05cd50237b85738378"), "x" : 58, "y" : 3364 }
{ "_id" : ObjectId("4b894c05cd50237b85738379"), "x" : 59, "y" : 3481 }
{ "_id" : ObjectId("4b894c05cd50237b8573837a"), "x" : 60, "y" : 3600 }
{ "_id" : ObjectId("4b894c05cd50237b8573837b"), "x" : 61, "y" : 3721 }
{ "_id" : ObjectId("4b894c05cd50237b8573837c"), "x" : 62, "y" : 3844 }
{ "_id" : ObjectId("4b894c05cd50237b8573837d"), "x" : 63, "y" : 3969 }
{ "_id" : ObjectId("4b894c05cd50237b8573837e"), "x" : 64, "y" : 4096 }
{ "_id" : ObjectId("4b894c05cd50237b8573837f"), "x" : 65, "y" : 4225 }
{ "_id" : ObjectId("4b894c05cd50237b85738380"), "x" : 66, "y" : 4356 }
{ "_id" : ObjectId("4b894c05cd50237b85738381"), "x" : 67, "y" : 4489 }
{ "_id" : ObjectId("4b894c05cd50237b85738382"), "x" : 68, "y" : 4624 }
{ "_id" : ObjectId("4b894c05cd50237b85738383"), "x" : 69, "y" : 4761 }
{ "_id" : ObjectId("4b894c05cd50237b85738384"), "x" : 70, "y" : 4900 }
has more$gt:> db.foo.find({ x: { $gt: 50 } });x entre vinte e três e vinte e seis, inclusive:> db.foo.find('23 <= this.x && this.x <= 26');> db.foo.find({ x: { $gte: 23, $lte: 26 } });$lt – menor que$gt – maior que$lte – menor ou igual a$gte – maior ou igual a$ne – diferente de$in – está em (recebe uma lista)$nin – não está em$mod – resto igual a (recebe uma lista onde o primeiro valor é o divisor e o segundo o resto)$exists – contém ou não o atributo$not – negação de uma condiçãosort. Por exemplo, para ordenar de modo descrescente pelo atributo y:> db.foo.find().sort({ y: -1 });> db.foo.find({ name: /^mon.o$/i });x:> db.foo.ensureIndex({ x: 1 });_id possui índice por padrão.GROUP_BY de SQL. Para tanto veja a documentação oficial.easy_install foi muito simples:bash$ sudo easy_install -U pymongodb.auth() do MongoDB ter sido traduzido como db.authenticate() em Python, o que me fez perder alguns segundos tentando entender por que não funcionava.por noreply@blogger.com (Cacilhας, La Batalema) em 27 de February de 2010 às 17:44
por Eduardo Willians (noreply@blogger.com) em 26 de February de 2010 às 15:17
por Flavio Coelho (noreply@blogger.com) em 26 de February de 2010 às 11:16
Kodumaro agora no Twitter!por noreply@blogger.com (Cacilhας, La Batalema) em 25 de February de 2010 às 17:38
Num dos testes antigos do PySide, havia uma inocente linha de código com QFile().metaObject().methodCount(), que na nova versão estava causando uma falha de segmentação dentro da Qt. O que estava acontecendo era que o QMetaObject retornado pelo metaObject() estava sendo apagado pelo QFile() criado, invalidando a área de memória que methodCount() tentava acessar. Agora por que diabos ele estava sendo deletado, já que eu chamava o método direto nele? A resposta está no modo como o CPython é implementado, sendo uma máquina virtual de pilha.
Usando o módulo dis nessa linha, temos o seguinte resultado:
0 LOAD_GLOBAL 0 (QFile)
3 CALL_FUNCTION 0
6 LOAD_ATTR 1 (metaObject)
9 CALL_FUNCTION 0
12 LOAD_ATTR 2 (foo)
15 CALL_FUNCTION 0
18 POP_TOP
19 LOAD_CONST 0 (None)
22 RETURN_VALUE
Dissecando instrução por instrução e seus efeitos na pilha, vamos assumir que esteja inicialmente vazia. Apenas as 4 primeiras instrução são necessárias:
Ou seja, devido essas instruções, não se pode garantir que um objeto criado anonimamente numa chamada de metodo e usado imediatamente irá estar “vivo” em chamadas subsequentes.
Vale notar que esse problema aparece em outras implementações de Python baseadas no CPython, como o Stackless e o Unladen Swallow. Implementações que usam outros tipos de máquina virtual como o Jython, IronPython e Pypy não sofrem desse problema.
Em novembro de 2009 publiquei minhas impressões sobre o CouchDB, já que estou desde então estudando banco de dados NoSQL para aplicações bem específicas. Permaneci por alguns meses estudando o CouchDB, que é mantido pela Apache Foundation e realizei diversos testes. O banco de dados se demonstrou bem eficiente para o modelo de aplicação que estou trabalhando, no caso a performance foi bem superior ao MySQL, já que tenho um volume de informações enorme e o fato de trabalhar com documentos — para esta minha aplicação específica — foi o que me chamou a atenção para um banco de dados estilo NoSQL.
Resolvi dar uma espiadinha em outro banco de dados no mesmo estilo, o MongoDB. Instalei no meu ambiente e realizei os mesmos testes. No CouchDB demorei muito tempo para realizar algumas operações simples, enquanto que no MongoDB, realizei os mesmos procedimentos de maneira mais rápida e sem me enroscar nas configurações e na manutenção do banco. Em termos de performance — no caso da minha aplicação — os dois bancos se mostraram praticamente iguais.
Embora o CouchDB também tenha bibliotecas para trabalhar em Python, a do MongoDB parece ser mais simples e direta. Pelo menos me identifiquei melhor com sua biblioteca e consegui adaptar minha aplicação rapidamente para trabalhar com o MongoDB, descartando o tempo que levei para o aprendizado e leitura das documentações, demorei menos tempo para desenvolver um script totalmente funcional para MongoDB do que para CouchDB. Isso não quer dizer que o CouchDB seja ruim e ainda não tenho o volume de informações necessárias para fazer um benchmark ou dar opinião sobre qual é melhor.
É muito simples trabalhar em Python com o MongoDB, veja um exemplo:
#!/usr/bin/python
from pymongo import Connection
import datetime
con = Connection('localhost', 27017)
db = con['teste01']
user = {"nome":"Fulano",
"sobrenome":"de Tal",
"email":"fulano@detal.net",
"data_inclusao": datetime.datetime.now()}
# Insere
users = db.users
users.insert(user)
O código acima cria um banco no MongoDB (veja as instruções para instalação e veja também a documentação Python para MongoDB) e insere um registro no dict user para o banco de dados. Como o trabalho é feito em um banco de dados não relacional, não há necessidades de definir o layout da tabela. O layout é definido à medida que os documentos são definidos e é flexível, podendo ser alterada a qualquer momento.
A pesquisa na base de dados pode ser feita com o seguinte código:
#!/usr/bin/python
from pymongo import Connection
con = Connection('localhost', 27017)
db = con['teste01']
# Pesquisa um só
users = db.users
a = users.find_one({"email":"fulano@detal.net"})
print a
# Pesquisa varios
for u in users.find():
print u['nome'], u['email']
Entre o CouchDB e o MongoDB eu me identifiquei mais com o segundo. Consegui fazer as tarefas de forma mais rápida e eficiente. Mas o primeiro também é um ótimo banco, merece ser estudado. Provavelmente continuarei meus estudos e desenvolvendo a pesquisa em cima do MongoDB, pois tem uma documentação um pouco melhor e mais ferramentas para trabalhar na base de dados.
O próximo passo é integrar uma aplicação Django no MongoDB. Mas isso é motivo para outro post!
por Eduardo Willians (noreply@blogger.com) em 19 de February de 2010 às 18:42
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.
por Eduardo Willians (noreply@blogger.com) em 10 de February de 2010 às 11:17
por noreply@blogger.com (Ricardo Bittencourt) em 07 de February de 2010 às 18:16
Criei agora um pequeno script para resolver um problema meu, um exportador de base de dados MySQL para arquivos CSV. Resolvi compartilhar:
Para baixar, você vai precisar do git. No Ubuntu, para instalar, faça:
$ sudo apt-get install git-core
Depois, para baixar:
$ git clone git@github.com:elcio/mysql2csv.git
Isso vai criar a pasta mysql2csv, com o script dentro. Você pode copiá-lo para a pasta /usr/local/bin/ e dar permissão de execução se for usar com muita freqüência:
$ cd mysql2csv
$ sudo cp mysql2csv.py /usr/local/bin/mysql2csv
$ sudo chmod +x /usr/local/bin/mysql2csv
Se fizer isso, vai poder chamar, em qualquer diretório:
$ mysql2csv host user passwd dbname
Código simples, mas que pode ser útil para alguém não ter que escrevê-lo de novo (arquivo runcached.py):
import os,time
cachepath='cache'
timeout=360
def runcached(cmd):
filename=os.path.join(cachepath,str(hash(cmd)))
if os.path.isfile(filename):
if time.time()-os.path.getmtime(filename)<timeout:
return open(filename).read()
t=os.popen(cmd).read()
open(filename,'w').write(t)
return t
A função runcached roda comandos do sistema operacional, e faz cache do resultado por 6 minutos. Para alterar o tempo do cache, basta mudar a variável timeout. Por exemplo, para cachear por 10 horas:
import runcached
runcached.timeout=36000
r=runcached('lynx --source http://www.tableless.com.br')
Apesar de extremamente prazeroso (ou às vezes nem tanto) acompanhar mailists e foruns nem sempre é tarefa fácil, seja pelo rumo que certas discussões geram, pela falta de tempo ou às vezes pela questão do foco. Acredito eu, que eventualmente todos vêem um assunto que é meio (ou inteiramente) off-topic sendo tratado com certo pudor, mas que você gostaria que a discussão evoluísse mas a própria lista e a netiqueta não permite.
Alguns dizem que a relação entre arquiteto e programador é de confiança e compreensão, arquitetos não confiam em programadores e estes não compreendem os arquitetos!
Esta afirmação pode parecer exagerada (como de fato é) mas recentemente identifiquei exatamente esta situação numa reunião onde o foco era NoSQL, atritos à parte, na hora pensei que este é um assunto que merece ser profundamente e adequadamente discutido e difundido e ver ele restrito a censura ou limite dos off topics era algo cruel, e isto me fez lembrar de algumas conversas que tive, sendo uma delas com o Pedro Lamarão (figura carimbada do grupo C & C++ Brasil) num happy hour e outra com o Jack Ganssle (quando ele esteve no Brasil para o workshop que o Portal Embarcados promoveu sobre Engenharia de Software) no qual o foco de ambas conversas foi o estímulo e a iniciativa. Pra ser sincero, foi com este foco que convidamos o Felipe Tonello para palestrar no VI Encontro de Programadores do grupo C & C++ Brasil (que vai ocorrer no próximo sábado dia 06/02/2010) para falar sobre seu projeto RoboQT, é com esta abordagem em mente pensei que era necessários fazer algo em ralação ao NoSQL…
Como muitos sabem:
DBMS != SQL
SQL != Evil
NoSQL != Paraíso
Para aqueles que apreciam o assunto e desejam discuti-los sem a preocupação de criar “OFF TOPICS”, com o propósito de criar um canal
independente (de linguagens de programação e DBMS) destinada para a discussão de Banco (não bando) de Dados não relacionais - NF², NF2, N1NF (non first normal form) , MRNN (Modelo Relacional Não-Normalizado) também conhecidos como nested relational, dimensional, multivalue, free-form, schemaless porém mais populares como NoSQL (Not Only SQL) criei a lista MRNN-Brasil:
http://groups.google.com/group/MRNN-Brasil
O foco é tratar o assunto sem pudores de abordagens acadêmicas,
profissionais ou produtos podendo ser tratado tanto BigTable (???),
Dynomite, Riak, Cassandra, CouchDB, HBase, Sherpa, Voldemort, Tokyo
Cabinet, MongoDB como as bibliotecas das mais diversas linguagens, sejam elas C, C++, Python, ERlang, Go, Haskell, Ruby, Brainfuck ou Whitespace ou até novas iniciativas; seja do ponto de vista de arquitetura, programação, segurança ou o que for, mas obviamente relacionado com MRNNs.
Talvez eu não tenha procurado direito, mas como eu não havia encontrado nada semelhante em Pt-BR, resolvi tomar esta iniciativa.
A escolha de um nome do vernáculo foi em razão de que NoSQL não intui muito para o que ele realmente representa (Not Only SQL) e esta NÃO é uma lista não para aqueles que relacionam SQL com algo do mal e NoSQL dá impressão de ser uma campanha anti-SQL; mesmo que no fundo esta ”buzzword” não (?!?!) signifique isto e após estímulo (indireto) do Luciano Ramalho (que é um entusiasta do assunto tanto quanto ele é de Python) acabei adotando o nome MRNN-Brasil ao invés de NoSQL-Brasil.
Espero que iniciativa possa ser útil para a comunidade.
Não posso deixar de divulgar a grande iniciativa do Luiz Eduardo Borges em disponibilizar a segunda versão do livro Python para Desenvolvedores sob licença Creative Commons. Ainda não li todo o livro, mas pelo índice já dá para perceber que é um grande material, leitura indispensável para programadores de outras linguagens que desejam conhecer Python ou até mesmo programadores Python que desejam aperfeiçoar seus conhecimentos.
Uma leitura técnica como esta, além de revigorante é bastante inspiradora. Por mais experiência que alguém tenha sobre uma determinada tecnologia, ao ler um ótimo material como este, é possível aprender novas técnicas ou melhorar procedimentos já utilizados. Então vale muito a leitura, além de tudo está sob licença CC.
O download do livro pode ser feito na página Python para Desenvolvedores no próprio site do Ark4n ou se tiver alguma dificuldade no download, fiz um mirror do livro. Clique aqui para baixar do mirror.
Final de ano, num rancho a beira-rio, curtindo o feriadão com a família, meus primos tiveram a idéia de fazer uma festa (que para minha surpresa havia sido
preparada com boa antecedência) com direito a vários badulaques e inclusive com lightsticks (à volonté como diria os franceses ou à la vonté como nós abrasileiramos e gostamos de dizer) que sempre dá um tom alegre a festas noturnas e sempre leva a criançada (e inclusive vários marmanjos) a brincar diante das lâmpadas ultra-violetas, devido aos agradáveis efeitos visuais que tal combinação produz, sendo sempre um bom elemento para complementar a diversão.
Após a festa e em momento oportuno, meu sábio tio José, que tem uma curiosidade que eu muito aprecio, me fez a seguinte pergunta:
- O que faz estas pulseiras brilharem? Elas são realmente de neon?
Estes são um daqueles momentos que você sente imenso prazer, afinal perguntaram algo do que eu sabia responder e pelo qual naquele momento eu estava pensando por razões que vocês irão descobrir abaixo. Sem contar que com certas pessoas é sempre prazeiroso compartilhar um pouco de erudição ou como alguns preferem chamar, um pouco de cultura inútil para desopilar o fígado; apesar que se tratando de cultura eu nunca a acho inútil, mesmo que seja para filosofar sobre o bater de asas das borboletas do ponto de vista entomológico, neural, da física tratando da teoria do caos, da perspectiva cinematográfica comentando sobre criativo filme “efeito borboleta” ou poético lembrando por exemplo da famosa pretensão de Mhuammad Ali de “float like a butterfly, sting like a bee“. Mas dependendo do contexto isto pode ser um porre para quem está participando e ninguém gosta de ser desagradável, mas este não era o caso.
O neon é um gás nobre incolor, abundante no universo, mas presente em pequena quantidade no ar atmosférico, ele foi descoberto pelos químicos britânicos Morris Travers (que eu sempre confundo com Tavares) e William Ramsay no século 19, os mesmos que descobriram o gás xenônio e o criptônio; que apesar do nome krypton nada tem a ver com a saga de Kal-EL.
Segundo gás nobre mais leve, com um alto poder de refrigeração, 40 vezes maior que do hélio líquido e três vezes maior que o hidrogênio líquido, ele não está presente no light-stick!!!
A tradução de ligh-stick é “bastão luminoso”, mas sei lá por que cargas d’água (talvez pela mesma razão que vulgarizaram a expressão francesa à volonté para à la vonté) o mercado abrasileirou o nome para bastão de neon ou pulseira de neon, devido a sutil semelhança com as lâmpadas de neon, porém não é o gás nobre o responsável pela fonte de energia luminosa deste artefato, mas sim uma reação que ocorre com o cyalume (que está no bastão) similar e mais barato que ao luminol. No caso do luminol, ele reage com cobre e ferro, e como há ferro na hemoglobina, o luminol é vastamente empregado por equipes de investigação forense (como de CSI) para investigações criminais.
O que presenciamos no ligh-tstick (e nas cenas de CSI quando eles encontram sangue em algum local ou objeto) é o efeito conhecido como luminescência (nome com origem no latim “lumem”) que é a emissão de luz através por estímulo de radiação ionizante, luz ou reação onde uma energia química é transformada em energia luminosa. Na realidade quando o efeito é obtido através de algum composto químico sintético, como no caso do light-stick, ele é chamado de quimiluminescência e, apesar de não ser o caso, se fosse produzido por um organismo vivo ele seria chamado de bioluminescência sendo-se que há vários outros tipos de luminescência.
Voltando ao bastão.
No caso deste, normalmente há um solução de cyalume com uma ampola de vidro contendo uma solução de peróxido de hidrogênio (água oxigenada 35%) e quando o bastão é dobrado a ampola é quebrada, as soluções são misturadas o luminol começa a ser oxigenado e a quimiluminescência começa a ocorrer e fazer a alegria da galera. A duração do efeito depende da temperatura do local, sendo-se que temperaturas baixas são mais propícias para sua durabilidade, portanto colocar a pulseira na geladeira tende a prologar o efeito mas ele não se eternizará ou fará a efeito ocorrer novamente.
Vale lembrar que apesar de ser um efeito estudado a centenas de anos, com grandes evoluções no último século, este é um fenômeno não totalmente compreendido plenamente ainda sendo alvo de estudos e pesquisas.
No caso da bioluminescência, normalmente o substrato de uma proteína
denominada luciferina (nome com origem no latim “lucifer” que significa “que ilumina”) é oxidada por uma enzima, denominada luciferase. Nesta reação há o consumo de uma molécula de trifosfato de adenosina (ATP) que excita energéticamente a luciferina e proporciona a geração de energia luminosa através da liberação da energia química.
A luminescência tem atraído o interesse do homem desde o princípio de sua existência, visto que do Pernambuco à China, os primeiros registros e pirilampos, fenômeno que Aristóteles (384 – 322 A.C) descreveu como “luz
fria”. Em 1669, o médico H. Brandt criou a “phosphorus mirabilis”, que era uma reação que utiliza uma propriedade do fósforo quando exposto ao oxigênio do ar em certas circunstâncias e por esta reação ele obtia a “quimiluminescência” (termo que fui criado 200 anos depois), mas Brandt que era um alquimista na época não compreendia exatamente o que ele estava fazendo, apenas o que ele estava conseguindo; o fascínio das pessoas para quem ele apresentava seu experimento alquimista.
Talvez seja este fascínio (o a intenção de fascinar) que fez James Cameron
inserir na história de Avatar, a luminescência e a bioluminescência em Pandora como uma propriedade de todo organismo deste planeta, dos animais aos pequenes Woodsprites, as sementes de Utraya “Mokri”, e a Árvore das Almas, com propriedades místicas.
Quando meu tio Zé perguntou-me sobre o bastão de luz, a pouco eu estava lembrando da carinha de alegria de minhas sobrinhas ao brincar com os bastões de luz, sobre o fascínio da luminescência na humanidade e sobre o belo efeito que James Cameron conseguiu com Avatar, portanto nem preciso dizer o quanto achei oportuno a pergunta dele; porém confesso que na hora puxei um pouco o freio de mão e não externei toda minha viagem.
E por falar em viagem e para finalizar, vejam só o que este maluco fez com um bocado destes bastões:
Alerta, Cyalume é tóxico e além disto como comentei acima, há vidro nos bastões, portanto não façam isto em casa!
Namastê!
O core de organização de eventos do grupo C & C++ Brasil, com colaboração da Liga dos Programadores Indepentes mais alguns colaboradores e com apoio da galera do hashtag #ccppbrasil_meetings estão trabalhando na remotada dos eventos do grupo C & C++ Brasil para 2010, sendo-se que o primeiro evento será o encontro de programadores que está programado para o dia 06 de fevereiro de 2010 em São Paulo.
A programação ainda não está fechada mas há propostas de palestras sobre concorrência para C++, robótica, programação segura entre outras.
Maiores detalhes em http://www.ccppbrasil.org/wiki/Grupo:Encontro_VI
Está em planejamento também um encontro do pessoal de Porto Alegre.
Em breve será divulgado uma previsão de agenda para 2010.
Bons códigos e nos vemos lá!
Namastê!
Epónymos era a figura que atribuía o nome a uma cidade na grécia clássica. Eponímia é o nome que dela deriva. Este conceito generalizou-se ao batismo de técnicas, objetos, atributos, invenções seja por vias diretas ou indiretas, sendo considerada a forma suprema de reconhecimento da atividade de um pesquisador.
Quando eu era adolescente e morava lá em Santa Fé do Sul (proporcionalmente 105.18 Km mais distante de São Paulo e 3.7840092199092412 vezes menor que Barbarcena) numa época em que eu realizava um curso técnico em eletrônica, com grande freqüência eu conversava com o (bom amigo) Batata sobre física, eletricidade, válvulas raras, RF, a vida, o universo e tudo mais; num destes bate-papo logo após uma desopilação hepática ele me comentou que quem deveria ser creditado pelo invento do rádio deveria ter sido o Padre Landell, um gaúcho que foi padre católico e um notável inventor e não Marconi ; físico italiano que plagiando estudos apresentandos pelo Nikola Tesla em 1899 apresentou ao mundo que Pe.Landell já havia apresentado em 1893 para um pequeno público em Campinas. Também foi o Batata que me revelou que o verdadeiro inventor do telefone teria sido Elisha Gray e não Alexander Graham Bell, quando eu solicitei suas “fontes” ele sacou de seu arquivo duas revistas Saber Eletrônica que relatavam estes fatos. Quando terminei de ler os artigos comentei: “Isto sim é pilantragem” e o Batata soltou uma que (na época) eu não entendi:
- “Isto sim é a apoteose da irresponsabilidade consciente” e tomei nota desta frase na hora, pois achei um “insight” muito inspirado…
Fiquei bastante curioso sobre estes fatos, infelizmente naquela época (década de 80) minhas fontes de pesquisas mais confiáveis diziam que os inventores da primeira aeronave havia sido os irmãos Orville e Wilbur Wright. Estas informações não mudaram minha vida, mas me tornaram um assíduo leitor na revista Saber Eletrônica por alguns anos como também me estimularam a pesquisar (eventualmente) sobre a história das invenções e das ciências.
Nestas primeiras pesquisas, percebi que muitas invenções passaram por disputas de paternidade, mas nem sempre a disputa tinha motivações financeira, como por exemplo foi o caso de Bob Kearn retratado no filme Flash of Genius. Um caso mais popular foi o exemplo da lâmpada que teve como primeiro inventor Joseph Swan mas Thomas Edison levou os créditos, porém foi quem melhor explorou a invenção, tendo inventado o sistema elétrico com rede de distribuição de energia, geradores de energia e todo um universo que viabilizou a comercialização da eletricidade, conseguindo explorar melhor a invenção. Caso similar ao telefone visto que Bell explorou muito bem “sua” invenção e as redes telefônicas. Porém, no caso dele vamos dizer que se aplica a máxima do batata visto que Bell se inspirou no trabalho de Johann Philipp Reis, descobriu o trabalho de Stephen Gray (que em 1729 teorizou um telefone funcional) comprou (a preço de banana) protótipos de Antonio Meucci, ouviu boatos do aparelho de Christian Ørsted e quando ficou sabendo que Elisha Gray (que era alguém com quem ele sabia que devia-se preocupar) iria registrar a patente de um telefone funcional, Bell subornou um funcionário do escritório de patentes e “conseguiu” registrar a patente do telefone primeiro, mas em 2002 a suprema corte americana reconheceu o trabalho de Antonio Meucci por ter sido o verdadeiro inventor do telefone; decisão justa mas tardia, afinal Meucci faleceu no século 19. No caso do rádio, entre aqueles que se proclamaram pais da invenção havia Nikola Tesla, Alexander Popov, Reginald Fessenden, Pe.Landell de Moura; em 1943 a Suprema Corte dos Estados Unidos concedeu a Tesla a Patente 763,772 creditando a ele a invenção do rádio, talvez porque era o único que ainda havia algum representante ativo nesta luta, pois analisando historicamente o Pe.Landell Moura foi quem conseguiu primeiro. Felizmente hoje Landell é mais conhecido no Brasil, sendo patrono dos radiamadores brasileiros sendo conhecido como um dos pioneiros na invenção da TV, ele foi o inventor do telefone sem fio, da comunicação via portadora ótica e entre outros campos ele é conhecido mundialmente por seu pioneirismo na bioeletrografia porém quanto ao rádio…
Numa destas pesquisas encontrei a palavra eponímia (acho que) pela primeira vez. Um exemplo de eponímia é a Salmonella, que tem origem do sobrenome do Dr.Daniel Elmer Salmon, mas que na realidade ela foi descoberta por Theobald Smith. Ué, como assim? De forma simplista, olha a máxima do batata aí novamente.
Num acaso, em 1992 li uma nota que Joel Cohen havia escrito um artigo no qual ele revelava que a “lei da eponímia de Stigler” foi muitas vezes formulada antes de Stigler a ter sequer nomeado. Mas o que era esta tal lei? Infelizmente era 1992, não consegui encontrar nada nas bibliotecas que eu tinha acesso e eu estava procurando nos lugares errados.
Poucos anos depois, ao acaso, descobri que a chamada Lei – da mesonímia ou eponímia – de Stigler afirmava que “no scientific discovery is named after its original discoverer” (nenhuma descoberta científica é designada com o nome do seu descobridor original) bem, neste momento comecei a pensar, nenhuma? Stigler chegou a esta conclusão observando várias descobertas, na área de economia e ciências, sendo-se que este trabalho proporcionou a ele o Nobel de Economia em 1982. Porém, se Cohen estava correto, até a lei de Stigler era vítima dela própria; ao menos ela era coerente. E ali senti que eu estava començando a aprender os nomes dos bois.
E eu ainda tinha aquela dúvida: todas? Obviamente que não podia ser todas, mas o quanto ela se aplicava? Qual ciência era mais suscetível? Porque esta tipo de situação era tolerada? Não há uma única resposta, cada caso é um história.
Alguns anos depois, felizmente já com a internet, resolvi pesquisar a origem de algo que a muito tempo eu tinha curiosidade e o que descobri foi interessante:
Em 1949, John Paul Stapp, um Ph.D, médico e coronel da USAF (nascido na Bahia em 1910) pioneiro nos estudos dos efeitos das forças de aceleração e desaceleração no organismo humano, que havia sido selecionado dois anos antes como “cobaia” de testes para medir a resistência humana a grandes acelerações, consegui bateu o recorde mundial de aceleração mas não pôde festejar o feito. Isto porquê os acelerômetros do trenó-foguete simplesmente não funcionaram. P. da vida, Stapp solicitou ao engenheiro responsável pelas medições - o então capitão Edward Murphy Jr. - uma análise para identificar a falha. Logo eles descobriram que um técnico ligara os circuitos do veículo ao contrário. No relatório de análise do problema, Murphy anotou: “Se há mais de uma forma de fazer um trabalho e uma dessas formas redundará em desastre, então alguém fará o trabalho dessa forma”.
Dr. Stapp popularizou a expressão ao comentar em uma entrevista a jornalistas, o diagnóstico de Murphy, atribuindo ao fato de que ninguém saiu ferido dos testes por levarem em conta a Lei de Murphy e explicou as variáveis que integravam a assertiva, ante ao risco de erro e consequente catástrofe.
Enfim, quem a popularizou foi Stapp e o seu autor (mesmo que atormentado por isto) sempre recebeu os méritos. Assim quando tive contato com as origens da folclórica e emblemática a Lei de Murphy minha primeira observação foi que a Lei de Stigler não se aplica a ela. Imagino que esta seja uma daquelas citações desgastadas que ninguém mais aguenta, mas como já dizia Nelson Rodrigues “toda unaminidade é burra”. Mas o que mostrou-se mais evidente é que a Lei de Murphy é mais poderosa que a Lei de Stigler! rs
Outro dia, já em 2010, lendo o post Newton e os Universos Paralelos vi uma referência ao clássico embate Newton vs Hooke, que sempre me faz lembrar do embate Newton vs Leibniz . Muitas vezes a fama indevida ou a prova da Lei de Stigler ocorre de forma involuntária, no caso do Cálculo, não há eponímia, mas houve literalmente “a apoteose da irresponsabilidade consciente”, enfim, houve a pilantragem de Newton. Com o tempo descobri que o Batata não havia sido original, que a frase que me deslumbrou era do Carlos Imperial e ele omitiu, mas comparado ao que Newton fez isto não foi nada!
Apenas para contextualizar:
Isaac Newton fez descobertas elementares em gravitação, óptica, mecânica, dinâmica celeste e matemática! Era um cientista. Já Leibniz, pai do termo função, era um filósofo e se interessava por lingüística, história, direito, diplomacia, política, economia, teologia, biologia, geologia, matemática, filosofia e metafísica, sendo considerado como o último gênio universal e inclusive um virtuoso atleta.
Leibniz publicou o seu trabalho sobre Cálculo antes de Newton. Quando Newton teve acesso, ele ficou bastante irritado e temendo críticas, principalmente advindas de Robert Hooke, com quem não tinha muita afinidade desde quando ele publicou seu trabalho sobre ótica e que na ocasião era o presidente da Royal Society, Newton preferiu adotar uma estratégia vitriólica para “defender” seus interesses.
Quando Hooke faleceu, Newton tornou-se uma espécie de presidente vitalício da Royal Society, da qual Leibniz também era membro. Desta forma, ainda inconformado por ter perdido o bonde do Cálculo, com um aliado escocês, John Kell, começou a provocar Leibniz como plagiador. Muito irritado com esta história, ele enviou ofícios violentos à Royal Society para provar que ele, sim, inventara o Cálculo Diferencial e Integral (até hoje são usadas as notações de Leibniz – por exemplo, o famoso dy/dx). Diante daquela querela entre titãs e como sói acontecer, criou-se um comitê para investigar a questão. Esse comitê foi formado em quase sua totalidade por membros pró Newton. Em tempo recorde ficou pronto um relatório conferindo a Newton a prioridade da invenção. Mais tarde foi descoberto um rascunho desse relatório manuscrito por Newton! Na realidade, com o tempo descobriu-se que quase todos os artigos que foram escritos ” atacando” Leibniz foram apenas publicados em nomes de outros cientistas da época, mas foram escritos por Newton (tsc). Newton recebeu o título de Sir, faleceu em 31 de março de 1727 e foi sepultado na Abadia de Westminster, em Londres, entre os reis do Império Britânico. Apesar de suas mentiras e desvios de caráter, ele foi evidentemente um gênio, preguiçoso e ardiloso, porém sagaz e extremamente inteligente.
Todavia, a filosofia de Leibniz contribuiu para o que hoje chamamos de física moderna. Ele trabalhou com lógica simbólica, aperfeiçoou uma primitiva máquina de calcular e foi precursor da aritmética binária, base dos atuais computadores. Leibniz morreu em Hanover no dia 14 de novembro de 1716.
A melhor síntese desta história que eu já encontrei, do qual me apropriei de parte do texto está no trabalho Newton vs Leibinniz de Adalberto Nascimento, porém esta história é contada em vários livros.
Comentando sobre alguns destes assuntos no twitter com o @AlanJumpi e o @Feutestoun, surgiu um insight de escrever este post (ou algo parecido) foi quando comentei da Lei de Stigler e logo alguém me comentou que a @cyberdecker havia escrito a pouco tempo o post breve panorama da estatística e lei de Stigler que li gostei muito, sinceramente recomendo. Na sequência surgiu a idéia de debatermos tudo isto com mais algum tempero de nerdices num bar, numa divagação imaginei que o local ideal seria o bar & restaurante no fim do universo, logo pensei: como será uma ressaca de Pan-Galactic Gargle Blaster?
Saideira: por falar em aritmética binária, grandes gênios, inventores, absurdos e polêmicas sobre patentes, lembrei de uma clássica história onde em 1948 quando tentaram patentear as portas lógicas digitais, a U.S.Patents a negaram pois Nicola Tesla já a detinha desde a virada do século. Esta foi uma contribuição indireta de Tesla extremamente valiosa, visto que este monopólio certamente iria gerar um absurdo atraso tecnológico.
Ps: Ainda pensando nestes sci-fi drinks, como será uma ressaca de “Romulan Ale“? Bom, esta divagação incidental e um pouco (ou muito mais) sobre curiosidades sobre Tesla, Landell e história da ciência ficam para outro(s) post(s) que após quebrar o jejum, nas próximas aplicarei as técnicas de jack.
Namastê!
por Luciano Ramalho (noreply@blogger.com) em 19 de January de 2010 às 06:23
por Luciano Ramalho (noreply@blogger.com) em 18 de January de 2010 às 14:57
por noreply@blogger.com (Ricardo Bittencourt) em 17 de January de 2010 às 22:32
Hoje um amigo meu veio falar comigo de uma brincadeira velha – e que eu não conhecia – chamada FizzBuzz.putStr (concat [if (mod x 15)==0 then "fizzbuzz\n" else if (mod x 3)==0 then "fizz\n" else if (mod x 5)==0 then "buzz\n" else (show x) ++ "\n" | x <- [1..100]])print "\n".join('fizzbuzz' if x%15==0 else 'fizz' if x%3==0 else 'buzz' if x%5==0 else str(x) for x in xrange(1, 101))print +(fizz)[$_%3] . (buzz)[$_%5] || $_, $/ for 1..100;(format t "~{~A~%~}" (loop for x from 1 to 100 collect (if (= (mod x 15) 0) "fizzbuzz" (if (= (mod x 3) 0) "fizz" (if (= (mod x 5) 0) "buzz" x)))))por noreply@blogger.com (Cacilhας, La Batalema) em 15 de January de 2010 às 00:13
Passei a última semana no IPAE, aqui. É o colégio em que fiz o segundo grau (faz tempo!), um lugar fantástico, ao pé de uma montanha, região com paisagens inacreditáveis. Me hospedei no colégio com minha família, para matar saudades, e todos os dias saíamos para visitar algum lugar em Petrópolis ou Teresópolis.
Há catorze anos, quando estudei lá, telefonava para minha família uma vez por semana apenas, pois os interurbanos eram muito caros. Dessa vez, estava conectado via rede 3G o tempo todo. O mundo mudou muito rápido em catorze anos. Ponto para o 3G da Claro, que funcionou em todo lugar onde fui, inclusive em todo o trajeto paulista (Dutra, Carvalho Pinto, Ayrton Senna) e em boa parte do estado do Rio de Janeiro. Na região de Itatiaia virou 2G, mas continuou funcionando.
Antes de sair para viajar, usávamos o Google Maps e a Wikimapia para encontrar os pontos de interesse. O problema? Depois de encontrar o ponto de interesse, meu sobrinho tinha que digitar os endereços no GPS para obter a rota. E quando o ponto de interesse ficava no meio de uma estrada, o jeito era navegar à mão no GPS até o lugar, arrastando o mapa para cá e para lá.
Será que só eu sofri com isso? Vocês, meus bem informados leitores, conhecem algum aparelho de GPS que fale com a web, através de alguma integração maluca? O ideal seria GPRS. Seria muito interessante se, enquanto estou dirigindo, um passageiro pudesse pegar o GPS e ver a navegação acontecendo sobre a Wikimapia, por exemplo. Alguém já viu isso? Alguma idéia de como fazer?
Meu amigo Henrique Bastos publicou hoje um artigo entitulado Ajude a mostrar a PythonBrasil na PyCon 2010.Salve Pythonistas!
De 19 a 21 de fevereiro será realizada a PyCon, em Atlanta nos Estados Unidos. Como alguns de vocês já sabem, participarei do evento apresentando a palestra #78 entitulada «Small acts make great revolutions».
Esta apresentação será uma evolução da palestra relâmpago que fiz na PythonBrasil[5] em Caxias do Sul, onde tento difundir os conceitos por trás das iniciativas que vêm movimentando a comunidade no Rio de Janeiro.
No entanto, falar só do que acontece no Rio me parece muito pouco para uma oportunidade dessas. Quero muito aproveitar a PyCon para mostrar o grande desenvolvimento da Comunidade Python no Brasil. Pessoasfantásticas estão fazendo as coisas acontecerem em Terras Brasilis. E a exemplo do que fiz no FISL 10, pretendo continuar na linha de tentar evidenciar que na nossa comunidade, o todo é muito maior do que a soma das partes. Mas para isto, eu preciso da ajuda de vocês.
Para poder falar com propriedade sobre a Comunidade Python no Brasil, precisamos traçar o perfil do nosso grupo. Por isso, preparei um rápido questionário online que ajudará a levantar informações sobre nossa comunidade. Ele está disponível em: http://henriquebastos.wufoo.com/forms/vamos-divulgar-nossa-comunidade-python-na-pycon/
É muito importante que o maior número de pythonistas respondam à pesquisa. Isso vai ajudar muito! Portanto, não economizem nos retweets e espalhem o link da pesquisa por todas as listas de email no Brasil, relacionadas com Python.
Além disso, também estou buscando links para boas fotos em alta resolução, como as tiradas na escadaria da PUC-RS durante o FISL 10 e as fotos «aéreas» da PythonBrasil[4] na UVA etc. Basta publicarem os links para as fotos nos comentários deste post ou me enviar por email.
Obrigado à todos, e vamo que vamo!
[]’s!
por noreply@blogger.com (Cacilhας, La Batalema) em 09 de January de 2010 às 02:07
I’m proud to present you with my last Enlightenment module: ConnMan!
For those unfamiliar with ConnMan, it is a solution to configure and manager your network connections. Unlike NetworkManager, it is very simple and fast, specially for users of it’s DBus API. It will manage everything, including DNS proxy to avoid messing with your /etc/resolv.conf. It also handles WiFi, Ethernet, WiMax, Bluetooth and even Cellular connections easily. For developers using it, it is very simple to use and you just need to use the high level “Service” interface.
In order to make it more useful, I created econnman inside e_dbus that abstracts the DBus API as a nice C interface that matches it perfectly and optimally, keeping objects in sync with server and emitting Ecore_Event whenever things change.
The module is quite simple, yet useful. As seen in the above screenshots, it will list the current status and service name (if module is bigger than 32px), when you mouse over it will show a fancy popup with more details, including error messages and IPv4 addresses. If you click it, you get a simple popup with the current connected service selected and clicking it will disconnect, while clicking a new one will connect to that one. Services requiring password will automatically ask for it, while those that failed to connect will also re-ask your password.
The module nicely exposes the offline mode feature to turn off radios. It integrates well with E17 mode: whenever you change E17 or ConnMan, they will sync with the other.
There is still work to do, mainly focus on the cellular specific needs and also create static services. And I also plan to have an application to allow managing your services, reorder them (that defines the priority) and even switch technologies that are available.
por Gustavo Sverzut Barbieri em 02 de January de 2010 às 23:05
Para uma força inversamente quadrática, a órbita é circular, como esperado pela Lei da Gravidade.
Já uma força inversamente cúbica gera uma espiral. Essa força é fraquinha demais pra manter uma órbita, e o planeta vai aos poucos se afastando.
Uma força inversamente linear demora para estabilizar, mas acaba fazendo uma órbita circular também.
E uma força constante, independente da distância? Ela também termina numa órbita circular, o que pra mim faz sentido. O planeta se move até o ponto onde a força constante é igual à centrípeta.
Agora vamos sacanear e colocar uma força senoidal só pra ver o que acontece. Ele não diverge, mas faz uma órbita muito doida. Provavelmente é um atrator estranho. por noreply@blogger.com (Ricardo Bittencourt) em 02 de January de 2010 às 03:45
National Geographic Wallpaper is a software adapted to Desktop Wallpaper Love with enhancements such as:
A fun afternoon of Christmas

Seaside é um arcabouço (framework) para desenvolvimento de aplicações web para Smalltalk. É descrito pelo próprio autor como um arcabouço herético, por quebrar todas as regras dos gurubash$ gst-load -iI seaside.im Seaside Seaside-Development Seaside-Examplesseaside.im com os pacotes Seaside (Seaside em si), Seaside-Development (ferramentas de desenvolvimento) e Seaside-Examples (exemplos).MyCounter.st.#canBeRoot diz se o componente pode ser registrado como uma aplicação autónoma ou não.#initialize) o atributo count é zerado.#states retorna uma coleção de estados que podem ser retrilhados (backtracked).#renderContentOn: é usado para renderizar a página.#registerAsApplication: registra o componente como aplicação.↑ por ^):" See: http://www.gnu.org/software/smalltalk/manual/html_node/Seaside.html "
Seaside.WAComponent subclass: #MyCounter
instanceVariableNames: 'count'
classVariableNames: ''
poolDictionaries: ''
category: 'Seaside Examples'
!
!MyCounter class methodsFor: 'testing'!
canBeRoot
↑true
!
!
!MyCounter methodsFor: 'initializing'!
initialize
super initialize.
count := 0.
!
!
!MyCounter methodsFor: 'accessing'!
states
↑{ self }
!
!
!MyCounter methodsFor: 'rendering'!
renderContentOn: html
html heading: count.
html anchor
callback: [ count := count + 1 ];
with: '++'.
html space.
html anchor
callback: [ count := count - 1 ];
with: '--'.
!
!
MyCounter registerAsApplication: 'mycounter'.bash$ gst -I seaside.im -S MyCounter.stbash$ gst-remote -I seaside.im --daemonbash$ netstat -ln4 | grep 12345
tcp 0 0 0.0.0.0:12345 0.0.0.0:* LISTENbash$ gst-remote --pidbash$ gst-remote --start=Seasidebash$ gst-remote -I seaside.im --daemon --start=Seasidebash$ gst-remote --stop=Seasidebash$ gst-remote --killSeaside.WAComponent subclass: MyCounter [
| count |
<category: 'Seaside Examples'>
<comment: nil>
MyCounter class >> canBeRoot [
<category: 'testing'>
^true
]
initialize [
<category: 'initializing'>
super initialize.
count := 0
]
states [
<category: 'accessing'>
^{ self }
]
renderContentOn: html [
<category: 'rendering'>
html heading: count.
(html anchor)
callback: [count := count + 1];
with: '++'.
html space.
(html anchor)
callback: [count := count - 1];
with: '--'
]
].
MyCounter registerAsApplication: 'mycounter'.por noreply@blogger.com (Cacilhας, La Batalema) em 22 de December de 2009 às 22:28
por Flavio Coelho (noreply@blogger.com) em 14 de December de 2009 às 09:27
O nose-django é um plugin para o nose com o objetivo rodar testes de aplicações Django.
Com ele é possível criar testes em uma estrutura de arquivos menos engessada que a estrutura imposta pelo Django, sem perder as funcionalidades de testes do framework como fixtures, client e etc.
Outra vantagem do nose-django é a possibilidade de utilizá-lo em conjunto com outros plugins para o nose como o coverage por exemplo.
Mais informações sobre o projeto: http://www.assembla.com/spaces/nosedjango
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:
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.
A reiteração ou iteração é um dos mais efetivos algoritmos para para processamento de sequências, mas sua eficiência não se limita a processamento de conjuntos prontos, essa técnica de algoritmo também pode ser usada para processamento de amostragens em plena coleta.(defun mean ((a-list list))
(/
(apply #'+ a-list)
(length a-list)))(defun update-mean ((the-mean hash-table) (a-list list))
(let ((*count* (+ (gethash 'count the-mean) (length a-list))))
(setf (gethash 'mean the-mean)
(/
(+
(apply #'+ a-list)
(* (gethash 'mean the-mean) (gethash 'count the-mean)))
*count*))
(setf (gethash 'count the-mean) *count*)
the-mean))#s(hash-table :test fasthash-eql (count . 0) (mean . 0))'mean zero (0) e 'count zero (0). O hash será atualizado e retornado:(setq *mean*
(make-hash-table
:initial-contents (list
(cons 'count 0)
(cons 'mean 0))))por noreply@blogger.com (Cacilhας, La Batalema) em 06 de December de 2009 às 15:42
Este artigo descreve o meu roteiro de atualização dos meus computadores
pessoais com o Ubuntu 9.10 Karmic Koala. Eu costumo instalar muitos
programas, seja para testar ou mesmo para usar nas aulas que ministro.
Assim, a cada seis meses, quando sai uma versão nova do Ubuntu, costumo
fazer uma reinstalação completa desses computadores. Eu também costumo
adaptar esses computadores ao meu gosto, e sempre que os reinstalo,
preciso sair à procura das modificações que havia feito.
por Marco André Lopes Mendes (noreply@blogger.com) em 06 de December de 2009 às 12:27
In the last post, we’ve seen some security issues which exist in the Android password manager gbaSafe version 1.1.0a, by analyzing the security description provided in its web site. As described there, even though the system depends on a “master key” which might be secure, the security of the system is seriously compromised by the encouragement of very weak keys (a few digits only) in what is named an “unlock key”, used to encrypt the master key itself. All of that in an application which claims to strongly protect people’s data from unwanted eyes.
In this post, we will play a bit with the Linux-based Android OS to actually explore these security deficiencies, demonstrating that such issues are very real, and that the claims of being hard to unveil the data is unfounded. Since the most serious weakness lies in the key itself, we’ll run a simple brute force attack to try to find arbitrary unlock keys.
This procedure is actually mentioned by the author of gbaSafe himself in the web page, except he overestimates the work involved in producing such a mechanism:
Theoretically, somebody could write a program that tries to decrypt the master key by trying all possible values of the short key (with 4 digits there are only 10000 possibilities), but this would still be much work, as more information about the crypting algorithm is needed (e.g. salt bytes, iteration count).
So let’s get started.
As a first step, we’ll need the Android SDK with a working emulator (I’ve used API level 5, revision 1), and a copy of the application itself. I got a trial version of the application from AndAppStore.com.
The application downloaded is bundled within that .apk file, which is really a .zip file that may be opened up normally with any tool which understands this file format.
Once that’s done, we get access to all the information needed to run the application, including icons, interface layouts, and most importantly in this case, the bytecode which targets the Dalvik VM. This bytecode is the end result of a sequence of translations which happen when the program’s Java source code is compiled, so that’s what we’ll have to fiddle with to figure details of the application we want to investigate.
The bytecode is located inside the classes.dex file, and as expected it’s not easy to read in its native format. Luckily, though, a smart guy has already written a couple of tools, smali and baksmali, which allow people to decompile and recompile that bytecode format to/from something that is much easier to understand.
After downloading these tools, the following command should decompile the file:
$ java -jar baksmali.jar –output classes classes.dex
We now have a classes/ directory full of .smali files.
Before going any further, let’s ponder for a moment about what we want to do. A brute force attack is when we attempt sequentially many possible keys, and given the context already presented, what we’re looking after is to attempt different “unlock keys”. With that in mind, we’ll introduce a very small modification in the application so that it will attempt to enter the unlock key automatically, rather than reporting an error when the key entered in the unlock dialog is invalid.
With that in mind, after some quick research, it looks like the onClick() method within the DlgUnlock.smali file is a pretty good candidate. This is supposedly called when the button in the unlock dialog is clicked, so something interesting about the password being correct or not must happen there.
Before doing anything there, I’ve increased the number of registers in the function to 12, to get some additional registers to play with, and then initialized a register with the value zero, to serve as a monotonically increasing number (our keys!):
.method public onClick(Landroid/view/View;)V
- .registers 9
+ .registers 12
.parameter “view”
+ const/16 v9, 0×0
Then, we have to instruct the program to use these keys rather than whatever is typed in the dialog box. Some lines down, we’ll see a call to the checkUnlockKey() method, which is certainly what we’re looking after. Let’s do this now:
+ :mykey
+ invoke-static {v9}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
+ move-result-object v2
invoke-static {v2}, Lcom/gbizapps/safeA/Crypt;->checkUnlockKey(Ljava/lang/String;)I
Now, what if this key is wrong? We don’t want the master key to be removed as mentioned in the software description. We want to simply attempt the next key. With some analysis, we see that in case of errors, the next couple of lines below the above code will instruct the VM to jump to an error branch. Rather than following up with the normal error logic, we’ll increment the key, and jump back to the above code:
:cond_6c
+ add-int/lit8 v9, v9, 0×1
+ goto :mykey
Now we just have to rebundle this and put it into the emulator. I won’t go over it in too much detail here, since there’s plenty of information available online, but the steps to do that are:
And that’s it, seriously! This would be enough to break the software security if it was working correctly.
Interestingly, though, the software wasn’t working correctly with this change. Instead, it was Force Closing on certain keys. To test it out, use the master key “master key”, and the unlock key “999999″, and then once you close and open the application again, try to unlock it with the key “1175″. Instead of showing an error message, it will break badly.
Now, for the proof of concept to work, I actually had to fix the bug, which felt a bit funny to do given the context.
Looking at the traceback trough adb logcat, I found out that there was a null being dereferenced in the file Crypt.smali, so I fixed the problem by injecting some error checking at this position and jumping the flow into an existing error branch:
+ if-eqz v3, :cond_5a
const-string v4, “ucpmhkexov85MDKhdfdfFGQPYxywq7209fcrqhghjkuiopy”
With this in place came the biggest surprise of the experiment. The keys which were crashing the application were special, in the sense that they actually decode the master key successfully! That’s right: whatever the algorithm is doing, that six-digit “999999″ encrypts the master key in such a way that attempting the “1175″ key works, so even big keys are rendered extremely weak with the logic used to encrypt the master key.
At this point, I added some trivial logic to display the key found with a Toast, just to ensure the whole thing was working correctly:

Note that the key generation implemented above is a bit simplistic, in the sense that it doesn’t attempt keys with leading zeros, but this would be trivial to implement, and my intention here isn’t to actually break any keys for real, but just to show how the promised security in this application is not to be trusted at all. Just the logic above will already be enough for a brute force attack against the application, and has broken all the keys I’ve tried in mere seconds, in a slow emulator.
As a conclusion, if you want to put your data in a secure place, rather than picking an application which promises security because the salt is hidden somewhere or because it’s too much work to figure its logic, pick an open source application with logic which is publicly verifiable and has already had many eyes over it. Chances are that doing something like what was described in this post won’t be so trivial. Then, choose your keys wisely! The most secure application won’t be enough if you pick a bad key.
A versão 1.2.8 do Google App Engine SDK já está disponível para download. O novo release traz muitas melhorias no serviço de Task Queue e no Admin Console, além de várias pequenas correções.
Para mais detalhes:

For some time now I’ve been wanting to research more deeply about the internals of Android. Until now, though, this was just a sentiment. Then, a couple of weeks ago I’ve finally managed to replace my iPhone for an Android phone, and that was the final motivator for me to actually get into learning more about the inner workings of the Linux-based OS.
Now, I just had to pick an actual task for digging into. The Dalvik VM is certainly one of the most innovative and advertised technical details about the OS, so something around it would be a nice start.. some kind of bytecode fiddling perhaps, but what? Luckily, even without trying too hard, I eventually stumbled upon an interesting case for researching upon.
The “victim” of this research is the application gbaSafe version 1.1.0a, which claims to protect user passwords using unbreakable algorithms (how’s that for a hint of a Snake oil case?).
Before we get into some hacking, let’s see some words on the software security by the author himself, and then render some analysis on conceptual issues on it:
The confidential data can only be decrypted if the master key is known. You should choose a long key (at least 16 characters) with mixed case and unreadable text. Of course you cannot enter this key each time you want to access the confidential data, so it is stored in the user settings encrypted with a shorter key (4 to 6 digits) and normally you only have to enter this unlock key. Theoretically it is possible to try all possible values (brute force attack), but then you must use another program, since gbaSafe deletes the encrypted master key from the user settings when you enter the unlock key wrong three times repeatedly, and then you must enter the master key. If you wrote a program to decrypt the master key, you would have to know the algorithm used, the salt bytes and iteration count (used to augment the short unlock key), which are very hard to extract from the binary program module gbaSafe.
If you have some security background, I’m sure that by now you’re already counting the issues on this single paragraph.
The most obvious issue is the fact that there’s a “strong key” and a “weak key”, and the strong key is encrypted with the weak one. This is a very common cryptography sin, as would say my friend and coworker Andreas Hasenack (a security researcher himself). A security system is only as secure as its weakest spot. It obviously makes little difference for an attacker if he has to attempt decrypting a master key or the actual data, since decrypting the master key will give access to the data.
Then, it mentions en passant that the software enforces the use of digits for the weak key. This ensures that the weak key is really weak! Four digits is basically ten thousand attempts, which is absolutely nothing for nowadays’s hardware. This number would move up to about 15 million by simply allowing upper and lowercase letters as well (which isn’t great either, but a few orders of magnitude never hurt in this scenario).
It follows up encouraging people to think that it’s actually hard to figure the algorithm and other implementation details. Considering that there’s absolutely nothing preventing people from getting their hands in the implementation itself, this is in fact asserting that the security mechanism is based on the ignorance of the attacker. Counting on the ignorance of people is bad at all times, and in a security context it’s a major error.
There’s a final security issue in this description which is a bit more subtle, but further analysis on the logic used leaves no doubt. In cryptography, the salt is supposed to increase the work needed in a brute force attack by strengthening the number of bits of the actual passphrase, in a case where the salt is actually unavailable, or at least prevent that a single large word dictionary can be used to attack several encryptions or hashes at once, in a case where the salt is known but variable. In the latter case, it helps because encrypting a single key with two different salts must be done twice, rather than once, so it increases the computational task when attacking multiple items. A salt which is known and does not change across all processed items is worth pretty close to nothing.
So, indeed, considering the many security issues here, this isn’t something I’d store my passwords or credit card numbers on, and I suggest you don’t do it either.
In my next post on this topic I’ll actually implement a trivial brute force attack to prove that these issues are very real, and that, actually, it’s not even hard to break into a security system like this.
The application author has been contacted about this blog post, since he’ll likely want to fix some of these issues.
In Django, you can configure the sitemap of your website using the sitemaps framework and then use this configuration to generate the sitemap.xml. Notwithstanding, the Yahoo! used to support only the urllist.txt type of sitemap and, because of that, I still use to have both (urllist.txt and sitemap.xml) available on my websites.
But, once you have your sitemap configured, why not use it to generate the urllist.txt? I created a view which generates the urllist.txt based on your sitemap configuration, as follows:
# -*- coding: utf-8 -*-
from django.conf import settings
from django.http import HttpResponse
from django.contrib.sites.models import Site
def urllist_from_sitemaps(request, sitemaps):
urllist = []
protocol = getattr(settings, 'PROTOCOL', 'http')
baseurl = u'%s://%s' % (protocol, Site.objects.get_current().domain)
for cls in sitemaps.values():
instance = object.__new__(cls)
for item in instance.items():
urllist.append(baseurl + item.get_absolute_url())
return HttpResponse(u'\n'.join(urllist), mimetype='text/plain')
And now, you just need to configure the urls.py and add the urllist.txt entry:
sitemaps = {
'entries': EntrySitemap,
'tags': TagSitemap,
'archive': ArchiveSitemap,
}
urlpatterns = patterns('',
...
(r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
(r'^urllist.txt$', 'myproj.apps.myapp.views.urllist_from_sitemaps', {'sitemaps': sitemaps}),
...
)
And I think that is all for now...
Update 1: I submitted a patch to be added into the official Sitemaps framework of the Django. The patch is very different of the code in this post and, if you'd like to see it and its code, here it is.
As always: if you found some english bug, warn me and I'll be glad to fix it. :)

Esbarrei com este projeto que achei bastante interessante, como um link às vezes é mais verboso do que mil palavras:
- Droplet

Você que utiliza algum *nix da vida já deve ter passado pelo momento mágico de ter executado o comando make em algum código fonte, não?
O make (GNU make) é uma ferramenta que executa os comandos inclusos dentro de um arquivo. É normalmente utilizado na compilação e instalação de programas.
Uma das vantagens do make é que ele identifica quais partes do programa devem ser recompiladas de acordo com as mudanças efetuadas desde a última compilação.
Dependendo do tamanho do programa pode-se economizar minutos ou horas entre as recompilações, pois não será necessário recompilar o programa inteiro.
Exemplo de uso:
$ make -f arquivo_com_os_comandos
Se você chamar o comando make sem passar nenhum parâmetro ele tentará utilizar o arquivo com nome de Makefile do diretório atual.
É o que normalmente acontece quando você precisa compilar e instalar um programa pelo código fonte.
Se você quiser utilizar o comando make só é necessário criar um arquivo Makefile e dentro dele colocar as instruções que o make deve executar.
Formato do Makefile:
regra: dependências... comandos ...
Os comandos são comandos normais do shell (bash). Pode-se colocar vários comandos, porém devem estar identados com tabulações. Isto é importante, não utilize espaços pois não irá funcionar.
A regra é só um nome para identificar um bloco de comandos. Fazendo uma analogia com programação, a "regra" seria semelhante a uma função.
As dependências são os arquivos necessários para a execução dos comandos da regra, o make irá fazer a verificação deles. Também podem ser outras regras que serão chamadas antes da execução dos comandos. Se houver mais de uma dependência elas devem ser separadas com espaços.
Aqui vai um exemplo de um Makefile que compila um programa em C:
program: gcc -o meuprograma meuprograma.c
Um exemplo com dependências:
program: cod1.c cod2.c lib1.a gcc -c cod1.c cod2.c gcc cod1.o cod2.o lib1.a -o program lib1.a: lib1.c cod3.c gcc -c lib1.c cod3.c ar rcs lib1.a lib1.o cod3.o ranlib lib1.a
Pode-se utilizar variáveis também. A declaração é simples, mas devem ser chamados com a notação "$(variável)". Repare também que elas podem ser concatenadas:
CC=gcc CFLAGS=-O2 CFLAGS=$(CFLAGS) -Wall program: $(CC) $(CFLAGS) -o program program.c
Olha que legal no Makefile a seguir, advinha o que acontece ao executar o comando `make clean' no terminal?
program: program.c
gcc -o program program.c
clean:
rm *.o
rm program
O que aconteceria também se houvesse um arquivo no diretório atual que se chamasse "clean"? O `make clean' não iria executar a lista de comandos da regra. Para evitar este tipo de conflito utilize a regra ".PHONY":
program: program.c
gcc -o program program.c
.PHONY: clean
clean:
rm *.o
rm program
Agora a regra "clean" será executada mesmo se houver um arquivo no diretório atual com mesmo nome.
Some interesting changes have been happening in my professional life, so I wanted to share it here to update friends and also for me to keep track of things over time (at some point I will be older and will certainly laugh at what I called “interesting changes” in the ol’days). Given the goal, I apologize but this may come across as more egocentric than usual, so please feel free to jump over to your next blog post at any time.
It’s been little more than four years since I left Conectiva / Mandriva and joined Canonical, in August of 2005. Shortly after I joined, I had the luck of spending a few months working on the different projects which the company was pushing at the time, including Launchpad, then Bazaar, then a little bit on some projects which didn’t end up seeing much light. It was a great experience by itself, since all of these projects were abundant in talent. Following that, in the beginning of 2006, counting on the trust of people which knew more than I did, I was requested/allowed to lead the development of a brand new project the company wanted to attempt. After a few months of research I had the chance to sit next to Chris Armstrong and Jamu Kakar to bootstrap the development of what is now known as the Landscape distributed systems management project.
Fast forward three and a half years, in mid 2009, and Landscape became a massive project with hundreds of thousands of very well tested lines, sprawling not only a client branch, but also external child projects such as the Storm Object Relational Mapper, in use also by Launchpad and Ubuntu One. In the commercial side of things it looks like Landscape’s life is just starting, with its hosted and standalone versions getting more and more attention from enterprise customers. And the three guys which started the project didn’t do it alone, for sure. The toy project of early 2006 has grown to become a well structured team, with added talent spreading areas such as development, business and QA.
While I wasn’t watching, though, something happened. Facing that great action, my attention was slowly being spread thinly among management, architecture, development, testing, code reviews, meetings, and other tasks, sometimes in areas not entirely related, but very interesting of course. The net result of increased attention sprawl isn’t actually good, though. If it persists, even when the several small tasks may be individually significant, the achievement just doesn’t feel significant given the invested effort as a whole. At least not for someone that truly enjoys being a software architect, and loves to feel that the effort invested in the growth of a significant working software is really helping people out in the same magnitude of that investment. In simpler words, it felt like my position within the team just wasn’t helping the team out the same way it did before, and thus it was time for a change.
Last July an external factor helped to catapult that change. Eucalyptus needed a feature to be released with Ubuntu 9.10, due in October, to greatly simplify the installation of some standard machine images.. an Image Store. It felt like a very tight schedule, even more considering that I hadn’t been doing Java for a while, and Eucalyptus uses some sexy (and useful) new technology called the Google Web Toolkit, something I had to get acquainted with. Two months looked like a tight schedule, and a risky bet overall, but it also felt like a great opportunity to strongly refocus on a task that needed someone’s attention urgently. Again I was blessed with trust I’m thankful for, and by now I’m relieved to look back and perceive that it went alright, certainly thanks to the help of other people like Sidnei da Silva and Mathias Gug. Meanwhile, on the Landscape side, my responsibilities were distributed within the team so that I could be fully engaged on the problem.
Moving this forward a little bit we reach the current date. Right now the Landscape project has a new organizational structure, and it actually feels like it’s moving along quite well. Besides the internal changes, a major organizational change also took place around Landscape over that period, and the planned restructuring led me to my current role. In practice, I’m now engaging into the research of a new concept which I’m hoping to publish openly quite soon, if everything goes well. It’s challenging, it’s exciting, and most importantly, allows me to focus strongly on something which has a great potential (I will stop teasing you now). In addition to this, I’ll definitely be spending some of that time on the progress of Landscape and the Image Store, but mostly from an architectural point of view, since both of these projects will have bright hands taking care of them more closely.
Sit by the fireside if you’re interested in the upcoming chapters of that story.
Wow! Just after my last week post about companies supporting EFL, we were pleased with two more announcements:
por Gustavo Sverzut Barbieri em 23 de November de 2009 às 12:03
por Flavio Coelho (noreply@blogger.com) em 19 de November de 2009 às 07:45