May 10

Olá pessoas,

Tirando a poeira aqui do blog pra anunciar meu novo toy project cujo anuncio deveria ser feito só quando eu tivesse algum resultado concreto, mas com o animo na evolução de hoje resolvi publicar logo.

Tenho atualizado o meu twitter bem mais vezes que esse blog pela facilidade que é twittar (principalmente quando você tem um plugin pra seu browser como eu). Lá fico sempre atualizando sobre o que estou fazendo, como as coisas no projeto estão indo, referências a sites onde aprendi a usar o motor de passo, transistores, etc.

Como você leu no fim do parágrafo anterior, o meu novo projeto é relacionado a robótica e microeletrônica. A idéia principal é fazer o meu arduino se comunicar com dispositivos móveis como celulares symbian e internet tablets através de qualquer protocolo, seja ele “wired” ou não.

Pra comecar a brincadeira comprei um módulo bluetooth chamado BlueSMIRF Gold que implementa toda a stack bluetooth e para integrar ao seu arduino basta você ligar o TX do BlueSMIRF no RX do arduino, e o RX no TX do mesmo. Ligando também o pino Vcc do módulo em uma tensão de 5v (que pode ser o pino 5v do arduino) e o GND no terra, você já pode parear o bluesmirf com seu computador e abstrair a conexão bluetooth como sendo uma porta serial, simples assim. Pretendo fazer um outro post ou um artigo no site do marmota detalhando a ligação desse módulo assim que aprender mais sobre ele.

Sim, e antes que eu me esqueca, eu terminei pagando muito caro por esse BlueSmirf. Fora os 60 dólares do módulo, paguei 30 dólares pela entrega e ainda tive o azar do módulo ter parado na Receita. Lá se foram mais 120 reais de imposto, e no fim eu não quis nem somar as despesas e saber quanto o bichinho saiu pra mim.

Comprei também um ProtoShieldBR do gaúcho Rafael Quines que fez um excelente trabalho no desenvolvimento desse shield. A idéia básica do ProtoShieldBR é ser uma plaquinha de propósitos gerais, cheias de barramento onde você vai posicionando os seus componentes da maneira que achar melhor - estilo protoboard - só que em cima do seu arduino. Se não fosse o meu ferro de solda de 5 reais as soldas teriam ficado bem bonitinhas e o resultado final teria sido mais bacana.

Voltando pra os objetivos do toy project; O pontapé inicial do Marmota é fazer um carrinho de controle remoto controlado por um celular s60 através do bluetooth usando python. A parte “física” do carro já tá pronta e hoje consegui comandá-lo via bluetooth usando pySerial no meu notebook. Já fiz também a interface da aplicação PyS60, faltando só criar a classe de socket bluetooth do celular. Falta também dar uma regulada no motor de passo responsável pelo direcionamento do carro, mais algumas colas e soldas, e rodas emborrachadas pra ter uma tração maior com o chão.

Tenho já algumas idéias de interação do arduino com internet tablets, andei pesquisando sobre shields ethernet e até vi que já fizeram um webserver simples pra ele. Já pensou você controlando luzes, alarmes, cameras de vigilância e etc tudo no seu browser aonde você estiver e o arduino do outro lado dando conta de tudo? Show de bola.

Pra finalizar, quem quiser debater, ajudar, dar mais idéias e etc, dê uma lida no site do Marmota. Prometo atualizar ele com fotos, videos e códigos tanto do lado arduino como a aplicação pys60 do lado mobile quando esse primeiro projeto for finalizado. Quem quiser acompanhar mais de perto os passos pra finalização desse projeto, siga-me no twitter!

É isso, até a próxima pessoal :)

Apr 2
PyS60 Console Bluetooth no Linux
Posted by Flávio Ribeiro in Programação, Python on 04 2nd, 2009| icon32 Comments »

O desenvolvimento de aplicações em Python para celulares Symbian - além de ser muito divertido - pode ser a forma mais ágil de se fazer algo útil em pouco tempo.

O port do interpretador possibilita você a usar a camera, GPS, SMS e outros componentes do seu celular com algo em torno de 2~4 linhas.

Mas existe um problema. Pra você testar suas aplicações no ciclo de desenvolvimento precisa ter um MS Windows pra instalar o SDK. Uma outra solução muito adotada entre o pessoal que usa linux é usar o interpretador python do celular no computador, via bluetooth.

Assim, mesmo que você não teste sua apliação toda de uma vez, dá pra criar funções dentro do interpretador e testar pedaços do seu código.

Já existem dezenas de posts explicando como fazer essa façanha, mas aqui vou tentar fazer de uma forma mais simples.

Criei um arquivo chamado bluetooth.sh com o seguinte conteúdo:

#!/bin/sh

/etc/init.d/bluetooth start
sdptool add –channel=2 SP
sudo rfcomm listen /dev/rfcomm0 2

Agora, com o dongle bluetooth espetado no seu computador e devidamente registrado, apenas execute o script de root:

root@doritos:/home/flavio# chmod a+x bluetooth.sh; sh bluetooth.sh
* Starting Bluetooth                                            [ OK ]
Serial Port service registered
Waiting for connection on channel 2

Pronto, agora no seu celular, ative o bluetooth e abra o interpretador. Ao apertar Select\Opções vai aparecer:

Selecione o Bluetooth Console e procure pelo seu computador. Depois da primeira vez que seu celular tiver conectado ao computador ele vai gravar seu PC como ‘Default Host’, e a partir da segunda vez ele vai perguntar se você quer conectar ao Default Host ou se é a outro.

Eu, particularmente, sempre busco por outros, mesmo querendo conectar ao meu PC, porque vinha notando erros quando tentava conectar com o Default Host. Buscando por outros, de alguma forma a conexão estabiliza mais rapidamente quando seleciono o meu PC já achado pelo PyS60.

Quando o celular achar o seu computador e você selecionar ele, o terminal que estava aguardando por conexões depois da execução do nosso bluetooth.sh vai mostrar o seguinte:

root@doritos:/home/flavio# chmod a+x bluetooth.sh; sh bluetooth.sh
* Starting Bluetooth                                            [ OK ]
Serial Port service registered
Waiting for connection on channel 2

Connection from 00:18:42:9B:8D:65 to /dev/rfcomm0
Press CTRL-C for hangup

Olhe pra tela do seu celular, o PyS60 deve dizer que a conexão está OK.

Agora, com o minicom instalado no seu computador, abra um outro terminal e digite:

minicom -s

Vá em configuração da Porta Serial e sete o Dispositivo Serial para /dev/rfcomm0. Verifique se o Bps/Paridade/Bits está 9600 8N1, e se não tiver configure pra ficar dessa forma.

Pronto, agora quando você apertar em Sair no menu de configurações do minicom ele vai inicializar a leitura do dispositivo registrado em rfcomm0.

Agora é só testar seus códigos. Aqui tem alguns exemplos de testes a serem feitos no seu celular.

Com um dongle bluetooth desses genéricos (pra não dizer do mais barato) e um Ubuntu Linux 8.04 aqui no meu computador, foi preciso reinstalar o libbluetooth com o pacote do Debian Puro. Então se você estiver tendo problemas ao final desse post sem conseguir conectar seu celular ao seu linux, tente reinstalar seu bluetooth com essa biblioteca.

Feb 19
Iteradores em Python
Posted by Flávio Ribeiro in Programação, Python on 02 19th, 2009| icon32 Comments »

Durante o curso discutimos um pouco sobre implementação dos chamados ‘métodos mágicos’ de python. Ao invés de interfaces, python adota protocolos a serem seguidos para que objetos criados por você programador obedeça alguns comportamentos, e é por ai que python implementa polimorfismo.

Vejamos por exemplo a função len():

>>> string = ‘flavio’
>>> len(string)
6
>>> lista = ['flavio',21,'ifpb']
>>> len(lista)
3

Ela tem a capacidade de retornar o tamanho de um objeto, mas não de qualquer objeto:

>>> a = 3
>>> len(a)
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
TypeError: object of type ‘int’ has no len()

Se você quiser que seu próprio objeto consiga retornar o tamanho ou comprimento de algo pela função len() basta você escrever o método mágico __len__ na sua classe. Imagine que você tem uma classe Pessoa e quer saber a altura das pessoas através do len():

>>> class Pessoa(object):
…     def __init__(self, altura=0):
…             self.altura = altura
…     def __len__(self):
…             return self.altura

>>> Flavio = Pessoa(184)
>>> len(Flavio)
184

Legal, né? Agora, pra não fugir muito o escopo desse post, vamos aos iteradores. Um iterador é basicamente um objeto que pode ser incrementado e decrementado, ser ‘percorrido’. A palavra iterar significa repetir algo algumas vezes. No  python 3 uma função muito utilizada nos laços for, a range(), que antes retornava uma lista (que por sua vez é iteravel) nas versões 2.x agora se comporta como a antiga xrange(), retornando um objeto em si que tem a capacidade de iterar.

No Python 2.X:

>>> type(xrange(3))
<type ‘xrange’>
>>> type(range(3))
<type ‘list’>

No Python 3000 (Py3k, Python 3):

>>> type(range(10))
<class ‘range’>
>>> xrange(10)
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
NameError: name ‘xrange’ is not defined

Sabendo já sobre métodos mágicos e o que são iteradores chegou a hora de criar um iterador mesmo, na real. Para você ter um iterador, basta que você crie um método mágico chamado __iter__() retornando a própria instância e um outro método chamado next(), onde as coisas vão realmente acontecer a cada iteração.

Como sou péssimo com exemplos vou simplificar e criar apenas uma classe que gera a velha conhecida dos programadores, ou pelo menos das pessoas que pagaram introdução aos algoritmos: Fibonacci.

  1.  
  2. class Fibonacci(object):
  3. def __init__(self):
  4. self.a = 0
  5. self.b = 1
  6. def __iter__(self):
  7. return self
  8. def next(self):
  9. self.a, self.b = self.b, self.a+self.b
  10. return self.a
  11.  

Pronto, agora podemos iterar em cima do nosso proprio objeto!

>>> fib = Fibonacci()
>>> for num in fib:
…     if num < 150:
…             print num,
…     else:
…             break

1 1 2 3 5 8 13 21 34 55 89 144

Sim, e esse plugin de colorir sintaxe já tá me irritando, engoliu a identação, quebras de linha e etc. Quem usar algum plugin melhor favor me avisar nos comentários!

Jan 25
MiniCurso: Introdução a Python
Posted by Flávio Ribeiro in Programação, Python on 01 25th, 2009| icon31 Comment »

Olá,

Aqui vão os slides do minicurso de introdução a linguagem de programação Python que ministrei na Avaty!, empresa voltada para soluções em mobilidade e sistemas embarcados (e que usa python em uma de suas soluções) na qual estou trabalhando no momento.

Os slides estão disponiveis para download aqui também, e espero que gostem. :)

Jan 14
Extendendo Python com C
Posted by Flávio Ribeiro in Programação, Python on 01 14th, 2009| icon39 Comments »

Aqui estou novamente, agora tentando mostrar pra vocês como fazer C conversar com Python. Ao invés de explicar passo a passo como fazer e repetir um monte de documentação que já está no oráculo google, vou simplesmente colar um exemplo com algumas funções e comentários.

Esse exemplo pode servir como template pra o que você está tentando fazer.

Primeiro abra um arquivo chamado avatymodule.c. É convenção sempre usar o nome ‘module’ depois do real nome do módulo. Se você for chamar o módulo de tuxcool, o nome do arquivo deverá ser tuxcoolmodule.c.

Abaixo vai o código do avatymodule.c com alguns comentários:

  1. #include "Python.h"
  2. // Assinatura do nosso modulo
  3. void initavaty(void);
  4. // Função principal que embute o python dentro do C.
  5. main(int argc, char **argv) {
  6. // Inicializa o Interpretador python embutido
  7. Py_Initialize();
  8. // Adiciona o nosso modulo
  9. initavaty();
  10. // Sai do interpretador embutido.
  11. Py_Exit(0);
  12. }
  13. /*
  14. Aqui vão as funções do nosso módulo. Todas que fiz seguiram um modelo.
  15. */
  16. /*
  17. Note que o nome da função sempre vem com [NOME_DO_MODULO]_[NOME_DA_FUNCAO].
  18. Esse metodo apenas da um 'hello world' usando o printf e o print do python.
  19. */
  20. static PyObject *avaty_hello_world(PyObject *self, PyObject* args)
  21. {
  22. printf("[C] Opa, aqui eh C, e usei o printf.\n");
  23. PyRun_SimpleString("import time\n");
  24. PyRun_SimpleString("print '[Py] Aqui eh Python:',time.time()");
  25. printf("\n[C] Aqui é C também.\n");
  26. return Py_None;
  27. }
  28. static PyObject *avaty_argumento_numeros(PyObject *self, PyObject* args)
  29. {
  30. long numero1, numero2, soma;
  31. /* A função PyArg_ParseTuple() é responsável pela transição de argumentos
  32. das funções em python para tipos C.
  33. */
  34. if (!PyArg_ParseTuple(args, "ll:addi", &numero1, &numero2)) {
  35. return NULL;
  36. }
  37. // Note que já trato numero1 e numero2 como long C.
  38. printf("[C] Primeiro Argumento: %d\n",numero1);
  39. printf("[C] Segundo Argumento: %d\n",numero2);
  40. soma = numero1 + numero2;
  41. // Transformando e retornando o resultado da soma em um long Python.
  42. return PyLong_FromUnsignedLong(soma);
  43. }
  44. static PyObject *avaty_argumento_string(PyObject *self, PyObject* args)
  45. {
  46. char *str1, str2[15] = "str_c";
  47. if (!PyArg_ParseTuple(args, "s:addi", &str1)) {
  48. return NULL;
  49. }
  50. printf("[C] Recebido array de caracteres: %s\n",str1);
  51. printf("[C] Contatenacao usando strcat() com: %s\n",str2);
  52. strcat(str2, str1);
  53. printf("[C] Retornando resultado pra objeto string python: %s\n",str2);
  54. return PyString_FromString(str2);
  55. }
  56. /*
  57. Aqui vai uma estrutura com todas as funções dos módulos. Observe que é convenção usar
  58. o nome da função python igual a função C.
  59. */
  60. static PyMethodDef avaty_methods[] = {
  61. {"hello_world",avaty_hello_world,METH_NOARGS, "Documentação do hello world!"},
  62. {"argumento_numeros",avaty_argumento_numeros,METH_VARARGS, "Documentação do argumento_numeros"},
  63. {"argumento_string",avaty_argumento_string,METH_VARARGS, "Documentação do argumento_numeros"},
  64. {NULL, NULL} //sentinela
  65. };
  66. /*
  67. Função para importar o módulo dentro do interpretador embutido, que foi inicializado no main.
  68. */
  69. void initavaty(void)
  70. {
  71. PyImport_AddModule("avaty");
  72. Py_InitModule("avaty", avaty_methods);
  73. }
  74.  

Calma, calma. Eu sei que o highlight ficou uma bosta e você não tá conseguindo entender nada. Coloquei o código aqui no pastebin.com e aqui pra você baixar também.

Agora, tudo que você precisa fazer é gerar um script de build, que nesse exemplo chamarei de buildscript.py (gostou do nome? :) )

flavio@avaty:~/dev/bindings$ cat buildscript.py
from distutils.core import setup, Extension

setup(name=”avaty”, version=”1.0″, ext_modules=[Extension("avaty", ["avatymodule.c"])])

flavio@avaty:~/dev/bindings$

Pronto, agora é só dar:

flavio@avaty:~/dev/bindings$ python buildscript.py build_ext -i
running build_ext
building ‘avaty’ extension
gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-i686-2.5/avatymodule.o -o avaty.so
flavio@avaty:~/dev/bindings$ file avaty.so
avaty.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped

Note que um avaty.so vai ter sido criado. Agora é só experimentar se o negócio funcionou mesmo:

flavio@avaty:~/dev/bindings$ python
Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import avaty
>>> dir(avaty)
['__doc__', '__file__', '__name__', 'argumento_numeros', 'argumento_string', 'hello_world']
>>> avaty.hello_world()
[C] Opa, aqui eh C, e usei o printf.
[Py] Aqui eh Python: 1231955166.34

[C] Aqui é C também.
>>> avaty.argumento_numeros(4,30)
[C] Primeiro Argumento: 4
[C] Segundo Argumento: 30
34L
>>> retorno = avaty.argumento_string(”_to_py”)
[C] Recebido array de caracteres: _to_py
[C] Contatenacao usando strcat() com: str_c
[C] Retornando resultado pra objeto string python: str_c_to_py
>>> print retorno
str_c_to_py
>>> print type(retorno)
<type ’str’>
>>>

Ainda preciso olhar melhor o argumento format da função PyArg_ParseTuple() mas acredito que o conteúdo desse post já serve como pontapé inicial pra muita gente. :)

Pra finalizar, indico a leitura da Python/C API, pra facilitar no uso de funções de transformação de valores C <-> Python.

UPDATE: O link pra download do modulo agora funciona. :)

Dec 18
PyMedia no Ubuntu 8.10
Posted by Flávio Ribeiro in Linux, Python on 12 18th, 2008| icon3No Comments »

Enquanto não tenho tempo de escrever o que prometi no post passado (e é pq eu ia escrever tudo aquilo antes de terminar o ano.. triste engano :( ) vou colocando dicas para soluções de problemas que encontro no dia-a-dia.

O de hoje foi instalar o pymedia no Ubuntu. Só pra deixar claro, instalei isso em um Ubuntu 8.10, com Python 2.5.2 e PyMedia 1.3.7.3.

Primeiro instale os pacotes necessários (assumindo que você já tem gcc, g++, build-essential e etc):

sudo aptitude install python-dev libogg-dev libvorbis-dev libmp3lame-dev libfaad-dev libasound2-dev

Depois disso, o certo seria basicamente descompactar o pymedia, fazer o build e instalar;

python setup.py build

python setup.py install

Mas foi ai aonde enfrentei um problema:

building ‘pymedia.audio.acodec’ extension
creating build/temp.linux-i686-2.5/audio
creating build/temp.linux-i686-2.5/audio/acodec
creating build/temp.linux-i686-2.5/audio/libavcodec
creating build/temp.linux-i686-2.5/audio/libavcodec/liba52
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -DBUILD_NUM=1862 -DPATH_DEV_DSP=”/dev/dsp” -DPATH_DEV_MIXER=”/dev/mixer” -D_FILE_OFFSET_BITS=64 -DACCEL_DETECT=1 -DHAVE_MMX=1 -DHAVE_LINUX_DVD_STRUCT=1 -DDVD_STRUCT_IN_LINUX_CDROM_H=1 -DCONFIG_VORBIS -DCONFIG_VORBIS -DCONFIG_FAAD -DCONFIG_MP3LAME -DCONFIG_VORBIS -DCONFIG_ALSA -DHAVE_AV_CONFIG_H -DUDF_CACHE=1 -INone -INone -INone -I/usr/include/lame -INone -INone -I/home/flavio/downloads/pymedia-1.3.7.3 -Iaudio/ -I/usr/include/python2.5 -c audio/acodec/acodec.c -o build/temp.linux-i686-2.5/audio/acodec/acodec.o
In file included from audio/acodec/acodec.c:31:
audio/libavcodec/dsputil.h:484: error: static declaration of ‘lrintf’ follows non-static declaration
audio/acodec/acodec.c:249: warning: initialization from incompatible pointer type
audio/acodec/acodec.c: In function ‘ACodec_Encode’:
audio/acodec/acodec.c:668: warning: pointer targets in passing argument 2 of ‘avcodec_encode_audio’ differ in signedness
error: command ‘gcc’ failed with exit status 1

Para “solucionar” esse problema, comentei essa parte de código em [Diretório do pymedia extraído]/audio/libavcodec/dsputil.h :

#ifndef HAVE_LRINTF
/* XXX: add ISOC specific test to avoid specific BSD testing. */
/* better than nothing implementation. */
/* btw, rintf() is existing on fbsd too — alex */
static inline long int lrintf(float x)
{
#ifdef CONFIG_WIN32
/* XXX: incorrect, but make it compile */
return (int)(x);
#else
return (int)(rint(x));
#endif
}
#endif

Estranhei o cast pra int no retorno de uma função declarada como long, mas enfim. Não sei que consequências isso vai causar, mas que o import rolou bonitinho, rolou.

Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import pymedia
>>> dir(pymedia)
['Player', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__path__', '__version__', 'audio', 'getMetaData', 'meta', 'muxer', 'player', 'removable', 'video']
>>>

E pra mim, que não tenho muito tempo livre agora, isso bastou. :)

Nov 8

Durante a SACE 2008 (Semana de Arte, Cultura e Esportes) do CEFET-PB, fui chamado para desenvolver um simples quadro de medalhas. A SACE foi modelada de uma forma que cada curso do CEFET representava algo como um país nas olimpíadas, e ai as medalhas iam sendo acumuladas nas diversas modalidades.

hmm… revisando o post pra publicar, pensei em você que buscou no google por como fazer essa transformação de CDR -> SVG e ia ter que ler esses vários parágrafos inúteis abaixo. Assim, se você é um desses, pule diretamente para o 7º parágrafo, considerando esse como o segundo. :)

A parte de desenvolvimento foi rapidamente desenvolvida usando PSP (Python Server Pages) - iih, que Igor não leia isso - e nem banco de dados em si eu precisei usar (pela simplicidade do quadro, optei por persistir e serializar objetos com pickle mesmo). Um (simples também) painel de controle pra o pessoal do DCE adicionar as medalhas, e uma função de comparação dos atributos do objeto Curso para ajudar o sort() do python a ordenar eles direitinho.

Mas, como esse post não é dedicado a python ou a que tecnologias\idéias foram necessárias para desenvolver o quadro (apesar de que vou adicionar a etiqueta Python nas categorias desse post :D) eu encontrei um problema que julguei mais complicado, a logomarca do Cefet-PB que estava em formato .cdr.

Uso Inkscape para fazer (as poucas) artes que preciso (e só realmente quando preciso meeesmo!), e apesar do Corel Draw e do Inkscape trabalharem com imagens vetoriais, o Corel tem um formato proprietário de arquivos enquanto o Inkscape basicamente gera um .svg, um arquivo XML que descreve as formas bidimensionais desenhadas no editor. Se você não sabe se uma imagem é ou não um desenho vetorial basta dar um zoom nele e ver se os pixels ficam mais aparentes ou se tudo continua com qualidade perfeita. Esse é o principal indicio de que seu desenho é vetorial.

Assim, pensei em refazer a logomarca no Inkscape, tarefa que ia levar um tempinho mas que ia valer a pena, afinal não ia usar essa logomarca apenas nesse quadro de medalhas (hmm será que o simbolo formado por árvores, rios ou coisa assim vai me ajudar no trabalho de Ciências do Ambiente?) e enquanto tentava desenhar a elipse que envolve a logomarca resolvi procurar no Google se existia uma outra maneira de pegar aquele maldito .cdr e trabalhar com ele no Inkscape.

Foi ai que achei o ator principal desse post, o Uniconvertor, ferramenta desenvolvida pela sk1project e que funcionou muito bem aqui. Feita em Python e com muito código (tem um modulo pra cada tipo de desenho, como de gradientes, elipses, retangulos, espiral e etc) bastou eu baixar aqui e usar o easy_install que ela já estava pronta pra ser usada:

flavio@doritos:~$ uniconv
UniConvertor 1.1.3

USAGE: uniconv [INPUT FILE] [OUTPUT FILE]

Converts one vector graphics format to another using sK1 engine.
sK1 Team (http://sk1project.org), copyright (C) 2007,2008 by Igor E. Novikov

Allowed input formats:
AI  - Adobe Illustrator files (postscript based)
CDR - CorelDRAW Graphics files (7-X3,X4 versions)
CDT - CorelDRAW templates files (7-X3,X4 versions)
CCX - Corel Compressed Exchange files
CMX - Corel Presentation Exchange files (CMX1 format)
SVG - Scalable Vector Graphics files
FIG - XFig files
CGM - Computer Graphics Metafile files
AFF - Draw files
WMF - Windows Metafile files
SK  - Sketch/Skencil files
SK1 - sK1 vector graphics files

Allowed output formats:
AI  - Adobe Illustrator files (postscript based)
SVG - Scalable Vector Graphics files
CGM - Computer Graphics Metafile files
WMF - Windows Metafile files
SK  - Sketch/Skencil files
SK1 - sK1 vector graphics files
PDF - Portable Document Format
PS  - PostScript

Example: uniconv drawing.cdr drawing.svg

flavio@doritos:~$

Aí foi fácil. Olha só o exemplo? uniconv logomarca_cefetpb.cdr logocefetpb.svg e txã, a logomarca estava gerada em formato svg. Tudo bem que precisei fazer algumas alterações (a elipse veio preenchida, e alguns pontos foram tratados como linhas ao invés de figuras mesmo) mas funcionou que foi uma beleza.

Sep 5
PyconBrasil 2008, eu vou!
Posted by Flávio Ribeiro in Eventos, Python on 09 5th, 2008| icon3No Comments »

A comunidade python brasileira (pythonbrasil) estará realizando nesse mês a 4ª edição da PyconBrasil (Python Conference Brasil) nos dias 18,19 e 20, no Rio de Janeiro, E EU VOU! :D Pelo que vi na programação muitas palestras irão me interessar, como Desenvolvimento de Jogos em Python , Comunicação Bluetooth entre Python/PyS60 , Integrando Python, C e C++ - Técnicas e
métodos de acessar código em C++
usando Python
, Python e Lego Mindstorms
Programando robôs
e Python em Todos os lugares.

Para os que também vão espero encontrar e conhecer vocês programadores e intusiastas python, e para os que não vão eu prometo fazer um review de tudo que com certeza vou ver de legal por lá! :D