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. :)

Jan 12
Arduino, agora tenho um!
Posted by Flávio Ribeiro in Eletrônica, Programação, Sistemas Embarcados on 01 12th, 2009| icon35 Comments »

Olá pessoas!

Para iniciar o ano com o pé direito irei escrever sobre o presente de aniversário que me dei, um Arduino Duemilanove! Ele chegou já tem uns dias, mas como pedi junto com um amigo e a encomenda chegou lá só pude pegar hoje.

Já haviamos comentado sobre essa plataforma, e inclusive o trabalho final da disciplina de Arquitetura de Computadores - sim, esse dirigivel que estou escrevendo aqui no blog e ainda estou devendo 2 posts - motivou a gente ainda mais a entrar nesse mundo da eletrônica, que, por enquanto, é apenas um hobby.

Entramos em uma lista de discussão de pessoas que estão se divertindo com eletrônica e principalmente com arduino chamada hardhacking e lá vimos uma thread que indicava uma loja pra comprar o duemilanove. Compramos e em cerca de 10~15 dias o arduino já estava na casa do meu amigo.

Esse é meu arduino, em minhas mãos :)

Só não gostei de uma coisa, não vieram cabos (de alimentação e USB) e apesar do ambiente ser facilmente baixado na internet, eu ia ficar feliz se viesse um cdzinho personalizado :-) Tive que ir agora no Manaíra Shopping e comprei um USB da Clone por apenas R$3,00.

Sobre valores, os dois duemilanove ficaram por $58,80 e o frete ficou por $7.20. Não tivemos problemas com alfândega e etc.

Agora é ter idéias legais pra brincar com ele. Inicialmente vou tentar usar o módulo sonar da tato que compramos pra o dirigível e não conseguimos “regular” ele direitinho. Pelo pouco que vi, o A\D do arduino é bem abstraído e funciona muito bem, ou seja, as coisas ficarão mais faceis com o sonar.

Misturando arduino com sonar pode até sair algum robôzinho de sumô, ou um que desvia de obstáculos..

PS: Só pra deixar registrado, o módulo sonar da tato não tem datasheet e o ’suporte’ que me deram não valeu de nada.  :P

Dec 20
Minidirigível Microcontrolado
Posted by Flávio Ribeiro in Eletrônica on 12 20th, 2008| icon3No Comments »

Não, esse não é o nosso :-)

Hoje, já quase de férias da faculdade, vou tentar cumprir com parte da promessa que fiz e  pretendo comecar uma série de posts que vai relatar o processo de desenvolvimento de um minidirigível microcontrolado (também conhecido como zeppelin), que por sinal ainda não chegou ao fim. O Minidirigível está sendo produzido por mim e mais 3 amigos da faculdade; André Nascimento, Pedro de Assis e Nathália Brunet, e o objetivo final seria uma apresentação para a disciplina de Arquitetura de Computadores do curso que fazemos.

Sim, antes que se pense que essa foto é o resultado final, NÃO, esse ai NÃO É o nosso. Coloquei ai só pra ilustrar, e como o esquema de caption nesse tema do blog tá quebrado to botando esse parágrafo mesmo.

Tivemos vários entraves e um prazo muito curto pra fazer tudo funcionar. O prazo se encurtou ainda mais ao sabermos que as lojas de eletrônica daqui de João Pessoa não tinham quase nenhum componente que precisávamos (pra variar ¬¬), e ai partimos pra pesquisas e contatos na internet.

Vou organizar essa série de posts assim:

  • Minidirigivel Microcontrolado I : Vou publicar como foi feita a parte física do trabalho. Vai envolver basicamente o que foi usado pra fazer a gôndola, parte de baixo do dirigível que abriga os motores, hastes e o ‘cérebro’ do dirigível que no nosso caso é um microcontrolador PIC 16F877.
  • Minidirigivel Microcontrolado II : Parte de inteligência do dirigível (note as aspas em negrito na palavra inteligência :-)). Detalhar o processo de programação, desde o velho hello world pisca-led usando o PIC16F877 até o algoritmo completo que por sinal não foi complexo de ser feito, e o pic ficou bastante sub-utilizado.
  • Minidirigivel Microcontrolado III : Enquanto eu vou escrevendo os posts acima, vou reportando os problemas ainda não solucionados que enfrentamos. Esse último post é justamente o último pq pretendo escrever ele quando tudo já estiver funcionando, e ai aponto como foram solucionados os problemas reportados.

Esse post marca também uma nova categoria no blog, chamada Eletrônica. Tenho planos de me presentear no Natal com uma coisa que deve gerar muitos posts nessa categoria no ano que vem e por isso resolvi criar logo.

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. :)

Dec 3
Novidades
Posted by Flávio Ribeiro in Pessoal on 12 3rd, 2008| icon31 Comment »

Quase um mês sem pisar aqui direito, venho fazer esse post apenas para avisar que muito provavelmente semana que vem voltarei a escrever bastante aqui.

Já tenho posts mais ou menos escritos - na minha cabeça - sobre o que estou fazendo atualmente na ServiceNet (middleware para terminais PoS), sobre um grupo de usuários Python criado recentemente aqui na Paraíba (Grupy-PB), sobre a libgmail do Python e também pretendo fazer uma série de posts explicando sobre um trabalho que estamos fazendo no Cefet para a disciplina de Arquitetura de Computadores que na verdade passou de um simples trabalho universitário para um desafio; um minidirigível microcontrolado.

Agora que já divulguei aqui fico com a responsabilidade de escrever pelo menos metade desses posts daqui para o fim do ano.

Enfim, até breve. :)

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.

Nov 6
Tirinha #03
Posted by Flávio Ribeiro in Tirinhas on 11 6th, 2008| icon3No Comments »

huahuauhauhahuahu pego do xkcd.com, mas visto nos itens compartilhados do Google Reader!

Nov 4
Alterando o MOTD do Ubuntu Server
Posted by Flávio Ribeiro in Linux on 11 4th, 2008| icon31 Comment »

Pra quem não sabe o que é, o MOTD (Message of the day) é aquela mensagenzinha que aparece sempre que você se loga no SSH ou faz login no modo texto. É algo mais ou menos assim:

flavio@localhost’s password:
Linux doritos 2.6.24-21-generic #1 SMP Tue Oct 21 23:43:45 UTC 2008 i686

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To access official Ubuntu documentation, please visit:
http://help.ubuntu.com/
Last login: Tue Nov  4 16:05:15 2008 from localhost
flavio@doritos:~$

Para alterar esses textos, não basta editar o /etc/motd (isso no Ubuntu Server). Fiz algumas mudanças nele e essas alterações foram resetadas ao reiniciar o servidor. Foi ai que vi que o /etc/motd é apenas um link para /var/run/motd. Então, para alterar de verdade o MOTD no Ubuntu Server você precisa editar é o /var/run/motd.

Mas se você quiser tirar a linha Last Login, já é nas configurações do ssh:

flavio@doritos:/var/www$ cat /etc/ssh/sshd_config | grep PrintLastLog
PrintLastLog yes
flavio@doritos:/var/www$

Pronto, trocou nessa linha yes por no e a linha Last Login ao logar por SSH não vai aparecer mais, apesar de eu recomendar deixar ela sempre aparente.

Recomendo também um ASCII Generator pra você fazer firulas no MOTD: http://www.network-science.de/ascii/

Oct 11
Mudança nas Diversões
Posted by Flávio Ribeiro in Pessoal on 10 11th, 2008| icon31 Comment »

Depois que passei da etapa 3º-ano-vestibular e vim morar em João Pessoa, muitas coisas mudaram na minha vida. Algumas pessoais, outras profissionais, meus interesses, minhas diversões… e é sobre as mudanças na forma como me divirto que venho falar nesse post.

Quando menor, fui uma pessoa muito ativa, que sempre gosta muito de esportes e pouco de tv, videogame e jogos de computador. Preferia passar dias e mais dias jogando tênis, futebol, viajando pra campeonatos, etc. Achava que assistir televisão era uma perca preciosa de tempo, e o espirito de competição sempre me acompanhava, os desafios me divertiam bastante.

Aos poucos fui me apegando mais ao computador e a forma como as novidades tecnologicas aconteciam, e após o vestibular entrei ainda mais nesse mundo. Foi ai que notei a mudança.

Ainda não sou fã de televisão, assisto cerca de 10 a 20 minutos a noite que é pra me dar sono. Mas, em compensação, meu Transmission (programinha de torrents nativo do ubuntu) passa quase que 24hrs/7dias ativo baixando filmes e… desenhos animados. É, depois de velho, agora que comecei a curtir desenhos. A propósito, vocês já assistiram Afro Samurai? Assisti um pedacinho na Mtv e no instante que acabou corri pra baixar todos os episódios! Recomendo! :) (agora deixa eu passar pro próximo paragrafo, esse ta muito nerd.)

Quando novo também tinha videogame, tive um Master System e logo depois um Mega Drive III, que custou todas as minhas economias e as do meu irmão também. Mas…. a diversão não se compara aos campeonatos de Winning Eleven (tá.. não é winning eleven mesmo, é Bomba Patch, um “fork” piratão do Winning Eleven com o Galvão Bueno transmitindo tudo.. ÊÊÊ \o/) que acontecem aqui frequentemente.  Antigamente preferia uma partida de tênis de mesa. Viu como as coisas mudam?

Isso sem falar das excelentes partidas de Counter-Strike no final do expediente no trabalho! :)

Não levem tão a sério esse post, só quis deixar registrado aqui a reflexão que fiz assim que acordei hoje e ainda me lembrei que perdi a final do ultimo campeonato de Bomba Patch antes de ontem.

Acho que o espirito de desafios ainda me acompanha, são os desafios em si que mudaram.

Ps: Pronto Raissa, atualizei. :)

« Previous Entries Next Entries »