sexta-feira, 3 de outubro de 2008

segunda-feira, 8 de setembro de 2008

[Livro] Sobrevivi para Contar

Esse livro segue a mesma linha de "muito longe de casa", ou seja, é a auto-biografia de uma pessoa comum que se vê repentinamente lutando pela sobrevivência na África contemporânea. O interessante é que tais genocídios, verdadeiros holocaustos, continuam se sucedendo sem que se desperte nenhuma reação, ou mesmo interesse, no mundo "ocidental civilizado". Aparentemente, essas vidas não possuem importância em virtude de seu reduzido valor econômico.

Muito longe de casa trata da guerra civil em Serra Leoa, na visão do adolescente Ishmael Beah, que é recrutado como menino-soldado, vivendo todo o horor da guerra. O conflito mal era noticiado e não houve auxílio da ONU. Resultado final: a luta durou 10 anos, morreram 5,4 milhões de pessoas e só terminou com a intervenção do exército do Congo. 

Por sua vez, "Sobrevivi para contar" conta a história de Immaculée Ilibagiza, uma jovem que passou nada menos que 100 dias escondida num banheiro minúsculo com outras 6 mulheres para escapar do genocídio de sua minoria étnica em Ruanda no ano de 1994. Não houve nenhuma resposta da ONU, nenhuma intervenção ou qualquer auxílio externo. Resultado: o extermínio de cerca de 1 milhão de pessoas da minoria tutsi (80% dessa população) pela maioria hutu. Tal conflito é retratato com primazia no filme Hotel Ruanda (2004). O conflito somente é encerrado quando exilados tutsis (exilados durante a fuga em massa do último genocídio) invadem o país, a partir de Uganda, e derrubam o governo hutu que conduzia o genocídio. Por falar nisso, a salvação vem da mesma Uganda de Idi Amin (conhecido pelas alcunhas de "açougueiro de Kampala" e "senhor do horror", com seus hábitos de comer carne humana...), retratado de forma ultra-light em O último Rei da Escócia (2007).

Qualquer semelhança entre os conflitos pode não ser mera coincidência! Ambos os livros são  importantes por trazerem a pauta um problema que simplemente não se discute. Afinal, o genocídio nos conflitos citados superam o total de mortos do holocausto judeu na segunda guerra. As atrocidades praticados na "Mama África", para qualquer instabilidade política, evidenciam uma tendência de indiferença e pervesidade da raça humana. A receita é muito simples: instabilidade política (ausência de um processo democrático consolidado), pouca educação e falta de recursos econômicos. Os ingredientes são poucos, mas a receita mostra o pior da humanidade, principalmente se aliados a questões raciais. Neste cenário, facilmente surgem grupos ursupando o poder para expropriação de riquezas, e fazendo isso as custas de extermínios. Perceba que não existe uma razão para o problema ser exclusivamente africano: isso aconteceria da mesma forma nos países de primeiro mundo se as mesmas condições estivessem presentes. Uma evidência clara disso é a total indiferença a tais genocídios. Ou seja, os mesmos podem ser aceitos com surpreendente naturalidade (i.e. desde que não existam interesses econômicos em contrário). Triste mas verdadeiro!

Quando li muito longe de casa, o livro me tocou pela linguagem simples, direta e tocantemente honesta. Sem ideologias, floreamentos ou eufemismos: apenas a realidade. Esse não é o caso de sobrevivi para contar. A tocante história de sobrevivência, e seu relevante contexto histórico, são postos em segundo plano para dar lugar a um discurso religioso. Em diversos momentos, percebe-se claramente que sua narrativa é forçada para convergir às convicções religiosas da autora, no que beira a pregação pura e simples. Em certos momentos parece muito um livro de auto-ajuda de baixa qualidade. No entanto, em se tendo a boa vontade de relevar tais aspectos e de se concentrar na história em segundo plano, percebe-se que o livro consiste de um relato fabuloso de uma sobrevivente. Uma história a ser conhecida e disseminada como um alerta a todos.

Embora não tenha lido pessoalmente, outras fontes de informação são o livro "Gostaríamos de informá-lo de que amanhã seremos mortos com nossas famílias" de Philip Gourevitch (também disponível em edição de bolso) e os documentários Ghosts of Rwanda (2004) e Shake Hands with the Devil: The Journey of Roméo Dallaire (2004).

terça-feira, 2 de setembro de 2008

[Opinião] Os dinossauros são coisa do diabo!


"Os dinossauros são criações do demônio!"

Parece de sacanagem, mas é coisa de evangélico! Cortesia do seminarista Carlos Alberto de Souza Magalhães e do "Dr." (em verdade mestre) Carlos Gama Michel. Além de atribuir uma origem demoníaca aos dinossauros, o autor ainda discute que sua extinção foi causada pelo dilúvio... Confira mais essa pérola pelo original em PDF ou por sua transcrição neste site.

Só para fomentar, segue um trecho muito interessante sobre a disseminação dos dinossauros e a geologia da Terra ao final do período Cretáceo:

Os ossos desses animais (os dinossauros) são encontrados em todos os continentes. Isto indica que popularam a terra toda. Apesar da teoria de continentes ligados antes do dilúvio que possibilitariam a ocupação destes pelos dinossauros, outra teoria é apresentada como susceptível de probabilidade pelo Doutor Ritter. Ele diz que a distribuição de animais terrestres a partir de um ponto radiante no oriente médio, como admitem os criacionistas, pode ser explicada por pontes terrestres unindo continentes ou unindo continentes a ilhas adjacentes. A simples reconstituição das enormes massas de gelo que uma vez se acumularam no Hemisfério Norte faria o nível dos oceanos descer 90 metros. Segundo boas fontes, isto seria suficiente para estabelecer um bom número de pontes terrestres, inclusive a ligação da Ásia com a América, e assim resolver um grande problema da distribuição de animais...




Abaixo, corajosas incurções minhas junto aos famigerados "seres infernais" nos museus de história natural de Londres e de NY!! O enxofre estava no ar!! hehehe...





Vale sempre remeter a discussão prévia "Criacionismo e intolerância religiosa"...

segunda-feira, 18 de agosto de 2008

[Cool] Large Hadron Collider Rap

Te cuida Eminen, senão a matéria escura te pega... :D

Muito bom! Recomendo mesmo!

terça-feira, 12 de agosto de 2008

[Música] Flores secas





Flores secas

Flores secas não despedaçam corações
Mas uma rosa abre todas as portas
Quem não diz eu te amo
Não leva pra cama um sonho

Quem está ao seu lado
Talvez não saiba o seu jogo
Quem prepara esse bolo
Talvez não jogue o seu dado

Quem está ao seu lado
Talvez não saiba o seu jogo
Quem devolve em dobro
Talvez não jogue o seu dado

Canções de amor fazem sucesso
Mulheres nuas dão IBOPE
A bandeira desordem e progresso
Como um aceno de boa sorte



Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Porque Neuma!
Disco: A pergunta que não quer calar (2001) [independente]
Ouça mais: MP3Tube

quarta-feira, 6 de agosto de 2008

[Música] Lençois ao Vento





Lençois ao Vento

Tenho forças para caminhar, mas não para erguer o mundo
Tenho forças para respirar, mas não para o absurdo
Se lembra de quando sabíamos de tudo
Me venda uma passagem pelo muro
E voam nossos lençóis
Nos campos, giram girassóis no escuro

Já não sei mais falar o que sinto
Sofrer pra que? Tomamos absinto
Jurar com sangue? Espero que estanque!
Pra ser sincero, estamos tão distantes

Eu vou partir pros braços de uma qualquer
Eu vou deixar a solidão te acompanhar
Quem sabe amar talvez saiba te magoar
No telefone, os risos de outra você vai ouvir

Ingratidão: moeda que eu pago
Pro seu velório eu fiz um réquiem arretado
Porque no amor sempre alguém dança no final
Se apreveitamos, então não foi de todo mal...

De todo o mal que eu fiz...
De todo o mal que eu fiz...
De todo o mal que eu fiz...



Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Porque Neuma!
Disco: A pergunta que não quer calar (2001) [independente]
Ouça mais: MP3Tube




E para o bom saudosismo de todos dos tempos da república! Um raríssimo vídeo gravado com uma webcam (de baixa resolução) e microfone ambiente!! Aproximadamente em setembro de 2001! Grande abraço a todos!



domingo, 27 de julho de 2008

[Música] Sampa (cover)






Sampa

(Caetano Veloso Cover - Ao vivo)



Letras: Cartano Veloso
Música: Cartano Veloso
Arranjo: Porque Neuma!
Ouça mais: MP3Tube

quinta-feira, 17 de julho de 2008

[Música] Eu quis me perder




Eu quis me perder

Ao ver olhos seguindo os meus
Pensei ser paixão
Se quis ter nos meus braços,
Colher os teus lábios,
Pétala por pétala

Eu quis me perder
Eu quis me perder
Eu quis me perder
E perdi...
Kiss me, baby...

Menina, quando estou contigo,
Tenho medo de ser eu mesmo
E ainda sim ser pouco
E quando eu digo essas palavras
É que espero que tu saibas que
Não são só palavras

Eu quis me perder
Eu quis me perder
Eu quis me perder
E perdi...
Kiss me, baby...



Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Porque Neuma!
Disco: A pergunta que não quer calar (2001) [independente]
Ouça mais: MP3Tube

segunda-feira, 7 de julho de 2008

[Música] Brado Retumbante





Brado Retumbante

Quem vai saber o que você sentiu naquele dia
Queria uma banho mas a água estava muito fria
Você lavou o rosto
Cortou o seu cabelo
Olhava a pia, mas o rosto estava no espelho

Ouvira um brado heróico
Um brado retumbante!

Você saiu bem cedo a procura de um emprego
Parou num bar, bebeu um pouco e acabou num beco
Você bebeu a grana, mas pediu uma grama
Cuidado filho, senão você acaba entrando em cana...

Ouvira um brado heróico
Um brado retumbante!



Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Porque Neuma!
Disco: A pergunta que não quer calar (2001) [independente]
Ouça mais: MP3Tube

quinta-feira, 26 de junho de 2008

[Música] A Vida por Diamantes




A Vida por Diamantes

Só estende as mãos para receber
Sua lei: ganhar nunca perder
Mantêm com as mãos seu coração
O próprio ladrão
Correndo com a solução
Não sabe parar para ver
Juntando a lei pra conquistar poder

E eu não sei ligar
Pra quem não quer saber
O que é o amor
Pra quem não quer sentir
Morrer de dor
Olhando para si e para mais ninguém

Futuro para construir
Render mais que investir
Comprar para acumular o que é seu
Não sabe ter sem possuir
Contenta-se com o que restou
Joga na cara o que fez e desfaz

E só não esconde a dor e frustação
De quem correu e não chegou a lugar algum
Que vá... Pra que voltou? Pra que?



Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Porque Neuma!
Disco: A pergunta que não quer calar (2001) [independente]
Ouça mais: MP3Tube

domingo, 15 de junho de 2008

[Música] Beijos Aperitivos





Beijos Aperitivos

Beijos Aperitivos
Sem prato principal
Não deixam gosto na boca
Como o segundo no dia
Uma eternidade
E ao mesmo tempo
Não valem de nada

Nem com poema vai...
Ela só dá pra trás...
Diz que ainda não...
Eu não agüento mais...

A chamo de meu bem...
Pra ela tanto faz...
Diz que ainda não...
Eu não agüento mais...



Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Porque Neuma!
Disco: A pergunta que não quer calar (2001) [independente]
Ouça mais: MP3Tube

terça-feira, 3 de junho de 2008

[Música] Todos




Todos (AoVivo)

Todos estão me chamando
Por todos os verbos
Pelo meu nome estão
Por todos os cantos
Não sei não... para onde ir...
Estagnado... estão ao meu lado...
Todos contra mim!

Estão rindo, debochando
A gritar tornando-me grande
Estou confuso, desorientado
Ao meu lado
Não há ninguém...



Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Porque Neuma!
Disco: A pergunta que não quer calar (2001) [independente]
Ouça mais: MP3Tube

quinta-feira, 8 de maio de 2008

[Aspie] Napoleão Dinamite: um heroi asperger?

Poster de napoleão dinamite Recentemente assisti o filme "Napoleão Dinamite" na TV a cabo (procure por "Napoleon Dynamite" na programação) e fiquei impressionado! O filme é completamente desconhecido no Brasil (nunca passou nos cinemas e é virtualmente muito difícil de alugar ou comprar, tendo sido parcamente distribuído apenas em DVD no final de 2006), mas possui uma particulariedade muito importante: os seus personagens centrais apresentam sintomas claros da Síndrome de Asperger.

O filme não tem a menor intenção de esclarecer o problema (nem toca no assunto), mas com certeza é muito interessante para se identificar em alguns comportamentos e rir dos próprios problemas (o que de longe é a melhor postura)! O grande segredo para apreciar o filme é não se ofender com as idiossincrasias do Napoleão, mas reconhecer-se no seu esteriótipo. Além do mais, o Napoleão é o grande heroi da história! :D

Na verdade o filme é de humor negro (i.e. politicamente incorreto), bem ao estilo das produções da MTV, sendo classificado como "comédia dramática" no Brasil. O roteirista e diretor é o Jared Hess, o mesmo de "Nacho Libre".


O filme é de 2004, e ao contrário do Brasil, provocou muita identificação ao redor do mundo. São inúmeros os fans do filme que o referem como "um verdadeiro meio de vida". O ponto fundamental é que o heroi da trama apresenta as idiossincrasias características da síndrome de Asperger (atitudes e reações completamente "alienígenas" para as pessoas normais), mas enfrenta a vida com muita coragem em nome do que considera certo e das pessoas que gosta. Esta coragem e superação do Napoleão comove as pessoas em geral. Essa popularidade fica evidente nas crianças com fantasias e bonecos dos personagens do filme. Desta forma, o filme (mesmo de humor negro) é um hino a diferença e deveria ser visto por todos. Passa longe de ser apenas mais um entre os milhares de filmes sobre adolescentes no colégio, ou ainda, de ser apenas uma escárnio delirante sem sentido como os filmes do Tom Green... Esse filme tem "alma"...

Como bem resume Flávia Yacubian, Napoleão é "descompassado, em todos os sentidos, com qualquer possível atitude razoável que um garoto normal pode ter" (assim como são percebidos os portadores da SA). Dentre as atitudes estranhas do personagem, Flávia discute: jogar um boneco preso por uma linha de anzol para ser arrastado pelo ônibus, guardar comida no bolso, praticar dance moves de duas décadas atrás, usar botas de neve num calor absurdo, apoiar o amigo na entrega de um bolo para conquistar uma patricinha, comprar uma peruca de mulher para o mesmo amigo quando este raspou a cabeça por impulso num dia de calor... Mas, vamos parar neste ponto: ele comprou uma peruca para o amigo com o dinheiro ganho depois de 6 horas manipulando galinhas imundas. Não só isso, mas pelo mesmo amigo ele dançou na frente de todo o colégio e enfrentou o malvado da escola. Em outros momentos do filme ele vai conversar com as garotas, não admite ser roubado na escola, enfrenta as pessoas de sua família, tenta até mesmo viajar no tempo por seu tio egoísta e convida uma das mais bonitas da escola para o baile...

Um aspecto importante é que percebe-se que Napoleão "tenta simular" atitutes "normais" de um adolescente revoltado, como forma de proteção, mas faz isso sem perder o orgulho de suas habilidades, dos seus interesses e de tudo o mais que o torna único. Desde seu terno até seu esporte preferido.

Inclusive, a dança de napoleão para a música Canned Heat do Jamiroquai é um dos pontos altos do filme (abaixo) e, por sua demonstração de coragem, ele vira uma espécie de herói. Existem inúmeros vídeos (1, 2, 3, 4, 5) no youtube imitando seus passos de dança e até mesmo uma propaganda do IPod... As camisetas "vote for pedro" também viraram uma mania e podem ser compradas pela Internet. Enfim, não deixe de ver... :D

segunda-feira, 5 de maio de 2008

[Aspie] Aspie Quiz

Foi publicada a tradução para o português que realizei do Aspie Quiz. Ao contrários dos usuais "testes de Internet", este é um trabalho sério conduzido por Leif Ekblad sobre a avaliação de perfis do espectro altista, focado na síndrome de Asperger.

O "quiz" consiste de um sistema especialista baseado em coeficientes de correlação com diversos perfis de neuro-diversidade tais como dislexia, esquizo-típicos, etc... (veja a metodologia em http://www.rdos.net/eng/aspeval/).

Assim como eu, Leif trabalha e pesquisa na área de tecnologia mas tem colaboração com outras linhas, e particular interesse pela síndrome de Asperger (por razões óbvias). Estive me correspondendo com o mesmo, e estou inclusive ajudando livremente em um artigo a ser submetido, provavelmente próximo mês, em uma revista Elsevier de psiquiatria.

Neste ponto, gostaria de convidar a todos (inclusive indivíduos neurotípicos), e principalmente as pessoas diagnosticadas clinicamente com síndrome de asperger, a participar da pesquisa. Quanto mais pessoas realizarem o teste, melhor sua calibração e seu desempenho na análise preliminar de pessoas com a síndrome.

Outro aspecto interessante é que o teste seja repetido ao longo dos anos de forma a avaliar a progressão dos portadores.

Por faver, distribuam amplamente o link para o teste: http://www.rdos.net/br/.

domingo, 4 de maio de 2008

[Opinião] Ressonância em metrônomos

Eis um belíssimo exemplo de ressonância em ondas planas.



Pessoalmente, fico sempre fascinado com a beleza da natureza.

quinta-feira, 1 de maio de 2008

[Opinião] Sexo, Drogas e... Matemática

Encontrei um "interessante" artigo no New York Times sobre sexualidade (The Myth, the Math, the Sex). No mesmo, o autor refere que "pesquisadores britânicos" levantaram que, em média, os homens ingleses declaram terem tido 12,7 parceiros heterosexuais durante a vida, enquanto as mulheres apenas 6,5.

Tal estatística vai de acordo com a noção estereótipada que os homens são mais promícuos, pois procuram ter o máximo de parceiras para disseminar seus genes, enquanto as mulheres são mais reclusas pois o alto investimento da maternidade faz mais adequado ter um parceiro fixo, que ajude a criar a prole...

Ou seja, os velhos papeis do "garanhão" e da "moça de família". Correto?

Errado! Se as amostras foram representativas na mesma população e as relações são heterosexuais (i.e. um homem e uma mulher), então devem existir 12,7/6,5 = 1,95 mulheres para cada homem. Como a probabilidade de nascimento é de 50% para cada sexo, a conta não fecha!



Matematicamete, o número médio de parceiros heterosexuais durante a vida deve ser o mesmo para ambos o sexos!



Logo, a pesquisa está errada! (e o mito da recatada retração sexual feminina derrubado!)

Verdade seja dita, não consegui encontrar a tal pesquisa britânica referida no artigo! Como não há nenhuma referência além de "pesquisadores ingleses" (sabe-se lá o que quer dizer isso...), desconfiei da fidelidade desses dados...

Porém, antes de queimar de vez a Impresa pela falta de coerência em prover rastreabilidade das informações, encontrei o artigo FRYAR,C.D. et al., "Drug use and sexual behaviors reported by adults: United States, 1999-2002", Adv Data, v.384, n. 23, p.1-14, 2007. Neste último artigo, os homens americanos declaram terem tido 7 parceiros heterosexuais durante a vida, enquanto as mulheres apenas 4. Dessa forma, deveriam existir 7/4= 1,75 mulheres para cada homem. Por sua vez, este resultado rastreável converge com a tal "pesquisa britânica"! Assim, realmente existe algo de muito errado!

No artigo no New York Times, o doutor Fryar se defende dizendo que os homens podem ter tido relações sexuais fora do país (e.g. em viagens) ou com prostitutas (que não entraram na amostra). Ou ainda, logicamente, que os homens notoriamente super-estimam o número de parceiras enquanto as mulheres notoriamente sub-estimam! Pessoalmente, acho esta última hipótese muito mais plausível!!!

Mas nem tudo está perdido! Também encontrei este excelente artigo Gómez-Gardeñes, J., et al. "Spreading of sexually transmitted diseases in heterosexual populations", PNAS, v. 105, n.5, p.1399-1404, 2008, que apresenta distribuições similares para as distribuições de parceiros ao longo da vida entre homens e mulheres (inclusive para Suécia, Reino Unido e Zimbabue, e com resultados semelhantes nos três países!!!). Ou seja, é possível fazer esta pesquisa com resultados coerentes!

Dai levanto as seguintes hipóteses para a distroção de FRYAR et al. (2007):
  • A amostra da população não foi adequada.
  • Não houve um treinamento prévio dos entrevistados sobre a definição de um "parceiro sexual" (e.g. um parceiro de um único intercurso ou um namorado estável a mais de um ano...).
  • Os americanos mentem muito... hehehehehe...
Ademais, estatisticamente, sua namorada teve o mesmo número de parceiros que você... Podes crer! :D

quarta-feira, 30 de abril de 2008

[Aspie] Colaboração: Guia de Sobrevivência para Portadores da Síndrome de Asperger

Eis uma excelente notícia! O portal universo autista deixou disponível hoje o material produzido no post anterior. É edificante poder ajudar a disseminar esse conhecimento. Fico realmente muito feliz com isso! Novamente fica a chamada para a divulgação do material [PDF] [DOC] (de forma a que o conhecimento cheque a quem pecisa).

domingo, 27 de abril de 2008

[Aspie] Guia de sobrevivência para portadores da síndrome de Asperger

A Simone está com um aluno Asperger na sala. Dai me sensibilizei e gastei a tarde traduzindo o guia da sobrevivência para portadores de Asperger do Marc Segar.

Valeu a pena porque ficou bom! Tomei a liberdade de acrescentar algo por minha conta, do pouco que aprendi da vida. Fico muito feliz de poder ajudar um menino de 9 anos. A Simone vai imprimir e deixar disponível (sem forçar). Vejamos se ele se interessa! Eu sei que foi feito com todo o carinho!




Por favor, distribuam amplamente este material [PDF] [DOC].



Ele contêm um legado muito importante e pode ajudar muitas pessoas. Se eu tivesse tido acesso a essa informação quando criança, minha vida tinha sido muito mais fácil.

[Música] Amor em pedaços

Eis mais um vídeo em homenagem ao "antológico" Porque Neuma! No caso, desta música eu não participei (é uma pena!). Foi composta pelo Paulo e o Alex em Belo Horizonte, após a diáspora da banda!!! Fica uma homenagem a nova fase de todos. hehehehehe... [enjoy!]




Amor em Pedaços

Ouro, prataria, teus colares espalhados,
espelho partido, teu pulso ferido.
Teu corpo caido ao lado.
Um sentimento infantil de que nada...
Nada faz sentido!

Teu desespero foi, e ainda é,
ter que se agarrar a quem fingiu
E como um fantasma, passou pela parede.
E tu... Tu quebraste a cara!

E se cantasses um prece, ah...
E se os anjos te alçassem alto, alto...
E se tocasse o telefone o que dirias?

Pois quem semeia vento há que colher poeiras.
Jogar-se do precipício nunca vale a pena.
Nós somos frágeis mas ainda temos chance.
Você pediu uma canção, pois agora dançe!

E se cantasses um prece, ah...
E se os anjos te alçassem alto, alto...
E se tocasse o telefone o que dirias?


(eu te amo!)



Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Alex "Brasil" e Flávio Mateus

Ademais:

Lembrem-se, Ginger Rogers fez tudo Fred Astaire fez, mas para trás e de salto alto.
Faith Whittlesey

sábado, 26 de abril de 2008

[Opinião] Criacionismo e intolerância religiosa

Este post é decorrente da inquietude em mim gerada por um vídeo enviado por um amigo, apresentado abaixo.



O vídeo, muito bem produzido por sinal, apresenta a ciência (em particular, a teoria da evolução das espécies de Darwin) como opressora e inflexível a opniões divergentes (em particular, ao criacionismo defendido por católicos evangélicos). Nele, a "era da ciência" e a "era das máquinas" são vistas como tiranos que deve ser combatidos pois acarretarão no fim das religiões e da liberdade. Neste escopo, o autor questiona o "fato" de que os PhDs devem ser ouvidos cegamente, e qualquer opnião diversa deve ser excluída! A grande questão aqui é que o vídeo (além do fato de estar em inglês) é bem feito e tem potencial para gerar desinformação.

Não é estranho de se imaginar que tal vídeo tenha relação com a opnião expressa por este outro criacionista, que defende o dogma da criação do homem ao referenciar o pensamento crítico por "síndrome de lúcifer", com citações bíblicas inclusive.

Neste contexto, sou um PhD em engenharia biomédica, logo um dos famigerados "opressores". Dentre as minhas atividades, nos últimos 3 semestres chequei a orientar a incrível soma de cerca de 100 monografias de trabalhos de conclusão de curso em nível superior (fora o trabalho, aulas e demais orientados). Algo que me marcou foi que realmente pude passar os fundamentos do método científico para muitas pessoas (algo que realmente só se constroi ao realizar um trabalho científico) e percebi claramente a modificação do seu pensamento: fixou-se a importância do questionamento e da fiabilidade da informação. Estas pessoas vão levar tais princípios para suas vidas!

Afinal, dentre outras coisas, um dos fundamentos da ciência é o método socrático! Tal príncipio discute a descontrução do pensamento mítico pela ironia, e a indução da razão pelo questionamento e diálogo como caminho para a verdade.

Neste contexto, Sócrates discute que deve-se, de forma não ofensiva, mostrar ao interlocutor o absurdo de suas idéias evidenciando as contradições e incoerências lógicas do discurso através do diálogo aberto (exatamente o oposto sugerido pelo vídeo, que mostra a ciência como intolerante). Desta forma, a ironia (i.e. evidenciamento das contradições) é um instrumento para a construção de idéias livres de presupostos superficiais ou preconceitos.

Na discursão sobre criacionismo e a teoria da evolução das espécies, argumenta-se:

1) Não existem evidências materiais da criação divina defendida pela teologia judaico-cristã (ou por qualquer outra tradição religiosa), apenas os escritos antigos.

2) A evolução e a abiogênese são apoiados em evidências:

  • Bioquímicas: o surgimento da vida a partir da matéria inanimada (abiogênese) expressa na Hipótese Oparin-Haldane ou Hipótese Heterotrófica é comprovada pelo experimento de Urey-Miller de 1953.
  • Arqueológicas: a evolução das espécies é evidenciada pela existência dos fosséis, objeto de estudo da palenteologia (lembra dos dinossauros em Jurasic Park?!). Quanto à origem das espécies e do homem em particular, todos os processos de avaliação da idade dos fósseis tanto animais como do próprio homem e de seus precursores mais imediatos apontam números totalmente incompatíveis com os fixados pelos textos religiosos.
  • Genéticas: a evolução das espécies é evidenciada pela existência da mutação do DNA e pela seleção natural de genes, comprovada pelos estudos de Ronald Fisher (que desenvolveu a linguagem matemática e a seleção natural nos termos essenciais dos processos genéticos), J. B. S. Haldane (que introduziu o conceito de "custo" da seleção natural), Sewall Wright (que elucidou a natureza da seleção e da adaptação), Theodosius Dobzhansky (que estabeleceu a idéia de que mutações, ao criarem diversidade genética, supriam o material bruto para a seleção natural), William Hamilton (que concebeu a seleção parentada), Ernst Mayr (que reconheceu a importância chave do isolamento reprodutivo para a especiação). Tais estudos são verificáveis nos contextos de genética de populações, biologia celular, botânica, zoologia, sociobiologia e ecologia.
  • Computacionais: a evolução das espécies é evidenciada pelas soluções evolutivas, em particular aos algoritmos genéticos. Pessoalmente, acho que nada mais visual neste sentido do que o projeto golem (excelente para leigos!).
  • Antropológicas e sociológicas: pelos mecanismos de seleção artificial em populações para aptidão econômica e social, demonstrando matemáticamente causas genéticas para comportamentos como seleção consangüínea (kin selection), altruísmo, especiação e os memes. Esta nova área do conhecimento vêm sendo referida por sociobiologia (portal). Um dos ramos interessantes desta linha de pesquisa é a psicologia evolutiva.
  • Biológicas: Sua aplicação pode ser observada em diversos processos, particularmente de forma mais evidente na cladística e na a biologia do desenvolvimento (i.e. estudo do desenvolvimento embrionário).
  • Matemáticas e econômicas: A seleção natural é aplicada nos mecanismos de equilíbrio econômico (teoria da escolha racional), baseados na teoria dos jogos. A teoria dos jogos, fundamentada nos matemáticos e economistas John von Neumann e Oskar Morgenstern e que também inclui as contribuições de John Harsanyi, John Nash, Howard Raiffa, Thomas C. Schelling e Herbert Simon. Esta formulação também tem aplicações em filosofia e ciência política, ética e jornalismo.
  • Cosmológicas e geológicas: Embora não relacionadas com a evolução, a cosmologia, astrofísica e geologia também atestam pela inveracidade científica do mito de criação do universo pela teologia judaico-cristã (na qual se insere a criação divina da vida e da própria espécie humana), assumindo seu início pelo Big Bang.
Desta forma, a negação da evolução envolve a recusa em aceitar uma boa parte das ciências naturais, principalmente as descrições da história do planeta e da vida.

Dentre as hipotéses (1) e (2) reina uma questão de bom senso (assim como assumido pela navalha de Ockham)!

A recente discussão do criacionismo por grupos evangélicos é decorrente da estratégia da cunha (ao qual se insere o vídeo motivador deste post), defendendo o criacionismo pelo design inteligente, que consiste de uma pseudo-ciência (classifica-se como pseudo-ciência por não apresentar evidências materiais ou seguir o método científico). Especula-se que este movimento faça parte de uma estratégia política de grupos conservadores norte-americanos (particularmente do sul dos Estados Unidos), obtendo favorecimento eleitoral ao subsidiar a agenda social conservadora em uma ampla gama de assuntos defendidos por grupos evangélicos incluindo aborto, eutanásia, sexualidade e outros movimentos de reforma social.

Neste ponto, não tanto como pesquisador (acho que o tal título de D.Sc. me concede tal denominação), mas como humanista e cidadão consciente (de visão liberal e social-democrática) me vejo na obrigação de desmistificar e desconstruir a desinformação causada pelos dogmas criacionistas e do design inteligente, ainda mais tendo em vista a implicação política e social implícita. No Brasil, o problema não é menos sério, conforme o post anterior.

Neste ponto, me insurjo em convocar as demais pessoas de bom senso, que acreditem na humanidade, a empregar esforços para conter a intolerância e fundamentalismo religioso sempre que o mesmos:
  • Ameaçem as liberdades democráticas: e.g. discriminação ou resarciamento da liberdade de crença contra praticantes de cambomblé por grupos evangélicos pentecostais;
  • Incitem a violência, o preconceito e a intolerância: e.g. conflito palestino, etc;
  • Impuserem a exploração social/econômica do indivíduo ou a perda de sua qualidade de vida em proveito evidente de terceiros: e.g. instituições que induzem doações ou cobram dízimos - principalmente de pessoas com um salário ou menos - sem apresentar prestações de contas abertas e públicas (demostrativos de usos e fontes) que mostrem claramente o uso do dinheiro - Igreja Universal, Assembléia de Deus, etc.
  • Travestirem informações como científicas de forma a obter credibilidade: e.g. espiritismo, design inteligente/criacionismo, cientologia, noergologia, homeopatia, astrologia, radioestesia, e demais pseudociências esotéricas. Note que este problema assume uma dimensão muito mais preocupante na medida em que tais "áreas do conhecimento" alcançam o ensino superior formal, com o apoio do estado inclusive.
  • Incidam na separação entre estado e igreja: e.g. pressão contra pesquisa de células tronco no Brasil.

No entanto, cabe discutir que deve-se haver um total respeito pela liberdade de crença e o livre arbítrio em qualquer situação, cabendo apenas a intervenção e esclarecimento sobre aspectos negativos do fundamentalismo religioso (principalmente nos contextos descritos acima). Desta forma, a conclusão sobre o tema a ser discutida com os criacionistas supracitados deve serguir um formato geral semelhante a:


"Você tem todo o direito de ter suas crenças e não pretendo contestá-las! Você pode acreditar em Deus e que o mesmo criou o homem se assim o quiser, mas deve concordar que isto claramente não é uma verdade científica! Sua aceitação destes dogmas baseia-se apenas em sua fé, e não na lógica e nos fatos. As evidências mostram que a evolução das espécies é real e a vida se originou pela abiogênese. É possível crer em Deus e entender a ciência, desde que não se tente misturá-los ou conflitá-los e que não se obrigem terceiros aos dogmas, especialmente terceiros de outras crenças. A crença em Deus é uma verdade pessoal (cada um tem o seu) e a ciência é uma verdade universal (a natureza é a mesma para todos)!"


Observe-se um ponto fundamental no discurso acima: a sutileza e a não ofensividade. Deve-se sempre evitar a negação simples e direta do dogma, pois o bloqueio emocional (que normalmente acontece em conflitos diretos) dificulta, ou mesmo impede, o pensamento crítico. Desta forma, a apresentação das inevitáveis contradições do dogma sobre a lógica racional deve seguir uma linha de discurso sutil, polida e bem construída (nunca ofensiva ou destrutiva).

Note que a questão aqui não é o absurdo das idéais prosposta pelos dogmas dos fundamentalistas religiosos, mas o sequinte exercício: "Como você poderia abordar estes indivídios, de forma delicada, a fim de desconstruir sua desinformação (minimizando seu o estrago) e ainda incutir nessas pessoas o pensamento crítico?". Note que o exercício desta dialética é realmente muito difícil!

Finalmente, vale lembrar que a própria existência das religiões, e do próprio comportamento social humano, é decorrente de mecanismos genéticos e da seleção natural, ou seja, não cabe a ciência a sua destruição, uma vez que é um processo natural em si, mas o seu esclarecimento e conciliação para fins de evolução do conhecimento e da própria humanidade.

quinta-feira, 24 de abril de 2008

[Artigo] A pseudociência nas universidades brasileiras

Eis um excelente artigo que, apesar de carente de citação, traz a tona uma questão de suma importância: a legitimação da pseudociência no país.

REIS, W.P., "A Pseudociência nas Universidades Brasileiras", Proceedings of Ibero-American Conference on Critical Thinking, Buenos Aires, 2005.

Read this doc on Scribd: A pseudociência nas universidades


O autor colabora com o Projeto Ockham e o blog "Dragão da Garagem", com excelentes discursões sobre pensamento crítico.

Particularmente, recomendo o último post "o problema das virgens" em que o mesmo autor discute a "questão das 27 virgens no paraíso mulçumano", trazendo uma pespectiva etimológica inusitada para a questão.

sexta-feira, 18 de abril de 2008

[Música] A última dança

Eis uma pérola do tempos da república! Como estou "de molho" estes dias, acabei por fazer esta pequena colagem no movie maker com alguns vídeos do youtube! Para o bom saudosismo de todos! Muita depressão e melancolia numa melodia simplesmente delicada (cortesia dos gênios Paulo e Alex). Grande abraço a todos e muitas saudades! [enjoy!]





A última dança

Os olhos da morte fitaram os meus de tao perto...
Eu fiquei sem jeito...
Toquei nos lábios dela com o dedo do silêncio.
Ao toque de lábios tão frios
Bailamos pela noite adentro
E de tão perdido, no vazio,
eu esqueci do tempo
E dos resquícios de vida que ainda havia em mim. . .
havia em mim. . .
havia em mim. . .
havia em mim. . .


Bailando com a morte no salão do mundo
Eu perco a vida de vista e me Afundo. . .
E me Afundo. . .
E me Afundo. . .

Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Porque Neuma!
Disco: A pergunta que não quer calar (2001) [independente]







sábado, 12 de abril de 2008

[Pessoal] Assim caminha a humanidade?

Eis um fato curioso. Fui a praia. Algumas vezes até.

Fui a praia. Banal por demais até.

Parece até poesia, mas não é.

Na areia haviam parasitas, onde enfiei meu pé.

Pois os parasitas (se chamavam "larvas migrans") infectaram a pele de bactérias, dai meu pé inchou no domingo passado (se chama "celulite": pra mim isso era coisa de perna de mulher, mas parece que é mais sério que isso). Fui no hospital e lá fiquei: foi internação na hora, pois a tal "celulite" pode evoluir para uma infecção generalizada (se chama "sepsis", e tem muita gente que morre disso!) e assim estive no Hospital São Mateus essa semana inteira (i.e. 5 dias com 2 antibióticos na veia). A dose era tão alta que me deixava grogue (eu não sabia que antibióticos faziam isso). Hoje tive alta (graças a Deus, pois não ia suportar outra punção na veia: tenho trauma disso e morro de medo - de tremer todo e bater os dentes - e pra piorar tive uma flebite de leve, mas esse foi o "açucar" desse caldo! Meu medo é da agulha! hehehehehe...).


A cima e ao lado seguem fotos tiradas já em casa, hoje de manhã, do meu pé "novo de novo" (acredite: está MUITO melhor). Em verdade, o perigo maior já passou (i.e. dessa eu não morro), mas como dá pra imaginar ainda vou ficar mais uns 15 dias literalmente "com o pé pra cima". Pior que até já desencanei e não estou ansioso com isso. Creio ser isto o mais importante dada a inevitabilidade do mundo (i.e. "relaxa e goza" hehehhee...).

Ademais, não produzi nada (nem fiz nada interessante) no hospital, pois a sonolência da medicação, o desamparo do desconhecimento da data de alta hospitalar e a "sombra constante" de novas punções na veia, meio que me desmotivaram (como dizia meu velho, "não tinha élan"*). Assim a única coisa que tenho para falar hoje é da minha própria história. hehehehehe... E sendo esta uma história, há de haver uma moral (ou várias morais, pois nenhuma é, em absoluto, absoluta...):
  • Use botas "sete léguas" na praia (ou pelo menos não enterre o pé na areia - o que era um discreto costume meu, enquanto tomava um cervejinha na praia - uma "viagem" do tipo "contato com a terra, com a natureza, etc.").
  • Não leve o cachorro para a praia, oh FDP! Ou pelo menos recolha os produtos finais!
  • Eu sou um "cara de sorte"! :D

Bem, parece que assim caminha a humanidade! Menos eu, que por enquanto, não vou a lugar algum! hehehehhehe...

* Uma pesquisa rápida na wikipédia esclarece que "élan vital" ou "força vital" foi uma teoria equivocada para a evolução, do começo do século passado, que atribuia a vida a um fluído mítico - sendo a base de inspiração para a "força" de Star Wars. Esperar o que do velhão: ele chama "cinema" de "cinemascope"! Falando nisso ele me trouxe umas muletas para usar esses dias. Brigadão pai, não sei o que faria sem você. Te amo!

sábado, 5 de abril de 2008

[Livro] Contos plausíveis


Segundo João Cabral de Melo Neto, "Carlos Drummond de Andrade mostra que ser poeta não significava ser sonhador, e que a ironia e a prosa cabem dentro da poesia". De acordo!

Este livro é realmente inusitado! Antes de mais nada, porque me foi emprestado pela Ana "da elétrica" ("da elétrica" não porque a ela fosse hiperativa, mas porque cursamos engenharia juntos na boa e velha universidade estadual de Campinas! Bons tempos!!!!) que reencontrei depois de muitos anos.

Mas o livro também "faz por onde". São contos curtos e independentes: cada um com menos de uma página (um chega a ter 3 linhas). Perfeito para quem não tem saco de ler textos longos! São extremamente divertidos, onde cada final garante uma boa risada. O texto exercita de forma primorosa dois princípios básicos: simplicidade e lógica (no meu entender, duas das grandes virtudes universais). Deveria ser usado nas escolas para ensinar redação e bom senso (isso se ensina?).

Verdade seja dia: o escencial é que me diverti demais lendo esse livro, o que foi um problema pois acabou quase imediatamente, me deixando "orfão". A grande "sacada" vem por conta de uma implícita crítica irônica à pretensão literária, com finais perfeitamente lógicos à situações fantasiosas (dái o nome contos plausíveis). Desta forma, clichês são satirizados com um final comum, gerando uma surpresa e uma boa risada. Na verdade, a identificação com o livro foi tão grande, em seu culto a simplicidade e racionalidade (i.e. simplicity is beautiful), que perguntei ao bom e velho google se o Drummond não era engenheiro. Mas era farmacêutico!

Para dar o gostinho, eis um conto plausível "pseudo-aleatório":


Abotoaduras


O maior fabricante de abotoaduras de punho fechou a indústria depois de convencer-se de que é infinitamente reduzido o número de camisas de manga comprida à disposição da humanidade. E, mais, que os exemplares deste gênero, ainda existentes, são providos de botões, dispensando abotoaduras.


– Trabalhei a vida inteira no setor – lastimava-se – e almejava legar a meus filhos a tradição das abotoaduras de punho, como requinte terminal de uma camisa digna desse nome. Os fatos ergueram-se contra mim. Não posso mais produzir abotoaduras de punho para camisas sem punho ou de punho abastardado por míseros botões de plástico.


Concluiu que é o fim da civilização e ia enforcar-se numa camisa esporte, estampada, quando esta, movida por vento súbito, saiu pelos ares, qual bandeira solta. E era tão bonito o esvoaçar do pano bigarreado, tão graciosas as evoluções que o homem resolveu desistir da morte e aplicar sua fortuna em uma indústria colossal de camisas de manga curta.

quinta-feira, 3 de abril de 2008

[.NET] Comunicador simples com .NET remoting


Os componentes das APIs .Net Remoting e Java RMI (Remote Method Invocation) provêm funcionalidades para desenvolvimento de sistemas distribuídos, permitindo a chamada remota de procedimentos (i.e. de forma semelhante à RPC, no entanto, sobre o paradigma OO). Neste contexo, os métodos invocados podem ser de processos distindos na mesma estação ou em estações diversas (i.e. máquinas virtuais distintas).

Tal tecnologia também é fundamental para a integração de sistemas, sendo um alternativa aos webservices em contextos onde a performance é crítica. De forma geral, a grande vantagem sobre um implementação a nível de sockets é que se dispensa o desenvolvimento de todo um protocolo de comunicação.
Para o desenvolvimento de uma aplicação cliente-servidor sobre estas APIs, deve-se definir a interface de serviços a serem oferecidos pelo objeto servidor. Os serviços especificados pela interface remota deverão ser implementados através de classes concretas. Com a interface estabelecida e o serviço implementado, é finalmente possível criar as aplicações cliente e servidor, sendo necessário apenas o registro do serviço para que as APIs citadas encapsulem toda a serialização e transferências das mensagens.

Neste artigo apresenta-se uma aplicação "chat" simples sobre a API .Net Remoting da plataforma .NET 2.0, onde diversos clientes contectam-se a um servidor para enviar mensagens aos outros participantes. Desta forma, a solução será dividada em 3 projetos:
  • assembly "MessagerCore" (DLL): contendo toda a lógica da aplicação.

  • aplicação console "MessagerServer": com responsabilidade de ser o mediador de mensagens e servidor da aplicação .Net Remoting

  • aplicação Windows Forms "MessagerClient": com responsabilidade de interface dos usuários e cliente .Net Remoting
Neste aspecto, inicia-se pelo desenvolvimento do assembly "MessagerCore" (DLL), através da definição das interfaces do serviço. Foram definidas as interfaces IChatter (representa o usuário cliente do chat) e IChatServer (representa o mediador de mensagens). Na interface IChatter, o método MessageArrived(string message) dispara o evento IncomingMessage para tratamento no cliente.

Interface IChatter
namespace net.jorgealbuquerque.Messager.Core
{
public interface IChatter
{
// Recupera o nome do usuário do chat
string Name { get; }
// Dispara o evento IncomingMessage para tratamento no cliente
void MessageArrived(string message);
}
}

Na interface IChatServer, os métodos RegisterChatter e UnRegisterChatter registram, respectivamente, o ingresso e abandono do cliente no chat. Por sua vez, o método AddMessage(IChatter sender, string message) representa o envio da mensagem.

Interface IChatServer
namespace net.jorgealbuquerque.Messager.Core
{
public interface IChatServer
{
// Ingressa no chat
void RegisterChatter(IChatter chatter);
// Abandona o chat
void UnRegisterChatter(IChatter chatter);
// Envia mensagem
void AddMessage(IChatter sender, string message);
}
}
Uma vez definidas as interfaces do serviço remoto, pode-se construir suas classes concretas. Nestes contexto, a classe Chatter (realização de IChatter) poderia ser implementada na assembly cliente e a classe ChatServer (realização de IChatServer) poderia ser implementada no servidor. No entanto, foi realizada a opção de manter toda a lógica no assembly "MessagerCore", de forma a prover apenas lógica de apresentação nas aplicações cliente e servidor. Tal escolha quebra um pouco as o design pattern observer, mas separa eficientemetne as camadas de negócios e apresentação. Observe, no entanto, que não existe nenhuma dependência entre os namespaces do cliente e servidor.

A classe Chatter estende MarshalByRefObject, o que permite a sua serialização e manipulação remota pela API .NET remoting. Note ainda que o método MessageArrived(string message) ativa o evento IncomingMessage.

Classe Chatter
using System;
using System.Runtime.Remoting;
using net.jorgealbuquerque.Messager.Core;
namespace net.jorgealbuquerque.Messager.Client
{
public class Chatter : MarshalByRefObject, IChatter
{
public Chatter(string name)
{
_Name = name;
}
public event IncomingMessageEventHandler IncomingMessage;
public delegate void IncomingMessageEventHandler(string Message);
private string _Name;
public string Name
{
get { return _Name; }
}
public void MessageArrived(string message)
{
if (this.IncomingMessage != null)
this.IncomingMessage(message);
}
}
}


De forma semelhante, o servidor também estende MarshalByRefObject. Neste contexto, o método UpdateObsevers(string message) realiza a atualização de todos os clientes, segundo o design pattern observer, por meio do evento IncomingMessage.


Classe ChatServer
using System;
using System.Runtime.Remoting;
using net.jorgealbuquerque.Messager.Core;
using System.Collections.Generic;
namespace net.jorgealbuquerque.Messager.Server
{
public class ChatServer : MarshalByRefObject, IChatServer
{
private List _Chatters = new List();
public override object InitializeLifetimeService()
{
return null;
}
private void UpdateObsevers(string message)
{
foreach (IChatter observer in _Chatters)
observer.MessageArrived(message);
//Console.WriteLine(message);
}
public void AddMessage(IChatter chatter, string message)
{
if (string.IsNullOrEmpty(message))
return;
UpdateObsevers(string.Format("{0}) {1} disse: {2}",
DateTime.Now.ToLongTimeString(),
chatter.Name, message));
}
public void RegisterChatter(IChatter chatter)
{
_Chatters.Add(chatter);
UpdateObsevers(
string.Format("{0}) Usuário {1} entrou.",
DateTime.Now.ToLongTimeString(), chatter.Name));
}
public void UnRegisterChatter(IChatter chatter)
{
_Chatters.Remove(chatter);
UpdateObsevers(
string.Format("{0}) Usuário {1} saiu.",
DateTime.Now.ToLongTimeString(), chatter.Name));
}
}
}
Finalmente, a lógica de registro e conexão dos servidor e cliente foram encapsulados nas classes de serviço abaixo. A classe ServerChannelService apresenta registro para intanciação remota do ChatServer como Singleton (i.e. apenas um mediator para todos os clientes). Por sua vez, a classe ClienteChannelService mostra a chamada remota propriamente dita da mesma classe pela construção Activator.GetObject().

Classe ServerChannelService
using System;
using System.Runtime.Remoting;
using net.jorgealbuquerque.Messager.Core;
namespace net.jorgealbuquerque.Messager.Server
{
public class ServerChannelService
{
public ServerChannelService(int port)
{
new RemotingTcpServicesHelper().ServerRegisterChannel("ChatServer", port);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(ChatServer), "ChatServer", WellKnownObjectMode.Singleton);
}
}
}


Classe ClientChannelService
using System;
using net.jorgealbuquerque.Messager.Core;
namespace net.jorgealbuquerque.Messager.Client
{
public class ClientChannelService
{
IChatServer _ChatServer = null;
public ClientChannelService(string url, int port)
{
new RemotingTcpServicesHelper().ClientRegisterChannel("ChatServer", port);
string uri = string.Format("tcp://{0}:{1}/ChatServer", url, port);
_ChatServer = (IChatServer)Activator.GetObject(typeof(IChatServer), uri);
}
public IChatServer ChatServer
{
get { return _ChatServer; }
}
}
}

Ambos os serviços consomem a classe RemotingTcpServicesHelper, responsável pelo registro do canal de comunicação TCP entre servidor e cliente. No caso, esta implementação foi definida de forma a alterar o nível de segurança da instanciação de objetos remotos para "Full" (o padrão do framework 1.1 em diante é "low", o que impossibilita a troca de objetos serializados).

Classe RemotingTcpServicesHelper
using System;
using System.Collections.Generic;
using System.Runtime.Remoting.Channels;
using System.Runtime.Serialization.Formatters;
using System.Collections;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting;
using net.jorgealbuquerque.Messager.Server;
namespace net.jorgealbuquerque.Messager.Core
{
public class RemotingTcpServicesHelper
{
public void ClientRegisterChannel(string serviceName, int port)
{
if (ChannelServices.GetChannel(serviceName) != null)
return;
IDictionary props = new Hashtable();
props["name"] = serviceName;
props["port"] = 0;
props["bindTo"] = "127.0.0.1";
props["typeFilterLevel"] = TypeFilterLevel.Full;
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientprovider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
TcpChannel channel = new TcpChannel(props, clientprovider, serverProvider);
ChannelServices.RegisterChannel(channel, false);
}
public void ServerRegisterChannel(string serviceName, int port)
{
if (ChannelServices.GetChannel(serviceName) != null)
return;
IDictionary props = new Hashtable();
props["name"] = serviceName;
props["port"] = port;
props["bindTo"] = "127.0.0.1";
props["typeFilterLevel"] = TypeFilterLevel.Full;
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
TcpChannel channel = new TcpChannel(props, null, serverProvider);
ChannelServices.RegisterChannel(channel, false);
}
}
}

Finalmente, encerra-se o desenvolvimento do assembly "MessagerCore", passando-se a construção da aplicação servidora pelo projeto console "MessagerServer":

MessagerServer
using System;
using System.Collections.Generic;
using net.jorgealbuquerque.Messager.Server;
namespace net.jorgealbuquerque.Messager.MessagerServer
{
class Program
{
static void Main(string[] args)
{
int port = 8080;
ServerChannelService service = new ServerChannelService(port);
Console.WriteLine("O servidor de mensagens está ativo na porta {0}", port);
Console.WriteLine("Pressine enter para parar o servidor...");
Console.ReadLine();
}
}
}

Observa-se a total abstração da lógica de negócios na camada de apresentação do servidor. Da mesma forma, apresenta-se o código fonte do único formulário (frmMain) para a aplicação cliente Windows Forms.

frmMain.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using net.jorgealbuquerque.Messager.Core;
using net.jorgealbuquerque.Messager.Client;
using System.Threading;
namespace net.jorgealbuquerque.Messager.MessagerClient
{
public partial class frmMain : Form
{
private Chatter _Chatter;
private IChatServer _ChatServer;
public frmMain()
{
InitializeComponent();
}
private void InitServer()
{
_Chatter = new Chatter(txtName.Text);
ClientChannelService service = new ClientChannelService(
txtServerHost.Text,
Int32.Parse(txtServerPort.Text));
_ChatServer = service.ChatServer;
_Chatter.IncomingMessage += new
Chatter.IncomingMessageEventHandler(Chatter_IncomingMessage);
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
if (_ChatServer != null)
_ChatServer.UnRegisterChatter(_Chatter);
}
catch
{
this.Dispose();
}
}
private void SendMessageToServer()
{
string texto = txtMessage.Text;
txtMessage.Text = string.Empty;
if (_ChatServer == null _Chatter == null string.IsNullOrEmpty(texto))
return;
_ChatServer.AddMessage(_Chatter, texto);
}
private void Chatter_IncomingMessage(string Message)
{
txtChat.Text = txtChat.Text + Message + "\r\n";
}
private void Send()
{
try
{
new Thread(new ThreadStart(this.SendMessageToServer)).Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Register()
{
if (string.IsNullOrEmpty(txtName.Text))
{
MessageBox.Show("Nome inválido!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
InitServer();
_ChatServer.RegisterChatter(_Chatter);
pnlLogin.Visible = false;
pnlMain.Visible = true;
this.Text = string.Format("Usuário: {0}", txtName.Text);
}
catch (System.Net.Sockets.SocketException exSocket)
{
MessageBox.Show("Servidor não encontrado: " + exSocket.ErrorCode, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnSend_Click(object sender, EventArgs e)
{
Send();
}
private void txtMessage_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == Convert.ToChar(13))
Send();
}
private void btnRegister_Click(object sender, EventArgs e)
{
Register();
}
private void txtName_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == Convert.ToChar(13))
Register();
}
}
}

O formulário foi divido em 2 panels (pnlLogin e pnlMain), responsáveis pelo login no servidor e pela interface principal do chat. Finalmente, apresenta-se o construtor da aplicação, onde é definido a flag CheckForIllegalCrossThreadCalls = false. Tal opção permite a chamada dos componentes do formulário por múltiplas threads.

Program.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace net.jorgealbuquerque.Messager.MessagerClient
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
frmMain.CheckForIllegalCrossThreadCalls = false;
Application.Run(new frmMain());
}
}
}

domingo, 30 de março de 2008

[ASP.NET] Componentizando o upload de imagens na camada de negócios

Um problema usual em aplicações ASP.NET é o envio de imagens. Esta necessidade é plenamente suprida pelo componente nativo ASP.NET FileUpload. Tal "WebControl", apresenta um TextBox e um botão "Browse", que encapsula a manipulação da stream da imagem durante o PostBack.

A figura ao lado apresenta-se um aplicação "mock" para envio de imagens. Abaixo segue o código em C# para o delegate do evento OnClick() do botão “Enviar”.

protected void btnEnviar_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
// Recupera dados da imagem
string fileName = FileUpload1.FileName;
string filePath = Page.MapPath("~") + Path.DirectorySeparatorChar +
"images" + Path.DirectorySeparatorChar + fileName;
byte[] data = FileUpload1.FileBytes;
// Escreve a imagem em disco
FileStream writer = new FileStream(filePath, FileMode.Create);
writer.Write(data, 0, data.Length);
writer.Close();
// Apresenta a imagem salva na tela
lblFileName.Text = "Arquivo enviado: " + fileName;
Image1.ImageUrl = "~/images/" + fileName;
Image1.Visible = true;
}
else
{
lblFileName.Text = string.Empty;
Image1.Visible = false;
}
}


No entanto, pode-se criticar esta implementação por quebrar a separação em camadas, uma vez que a lógica de manipulação da imagem está inserida no modelo da camada de apresentação (o arquivo .aspx.cs representa o model MVC). Desta forma se propõe o serviço abaixo a ser encapsulado em um assembly (dll) a parte para fins de reuso.

interface IUploader

using System;
namespace net.jorgealbuquerque.Services.Uploader
{
public interface IUploader
{
string BaseDir { get; set; }
System.Drawing.Size ThurmbnailSize { get; set; }
bool CreateThumbnails { get; set; }
string GetImageDirectory();
void Upload(string fileName, System.IO.Stream data);
void Upload(string fileName, byte[] data);
void Delete(string fileName);
void CreateThumbnail(string fileName);
}
}


classe UploaderService
using System;
using System.IO;
namespace net.jorgealbuquerque.Services.Uploader
{
public class UploaderService: IUploader
{
private bool _CreateThumbnails = true;
public bool CreateThumbnails
{
get { return _CreateThumbnails; }
set { _CreateThumbnails = value; }
}
private Size _ThurmbnailSize = new Size(64, 64);
public Size ThurmbnailSize
{
get { return _ThurmbnailSize; }
set
{
Size size = value;
if (size == null)
throw new ArgumentNullException("O tamanho do thurmbnail não pode ser nulo.");
if (size.Height < 5 || size.Width < 5)
throw new ArgumentException("O tamanho do thurmbnail inválido!");
_ThurmbnailSize = size;
}
}
private string _baseDir = "images";
public string BaseDir
{
get { return _baseDir; }
set
{
string dir = value;
if (string.IsNullOrEmpty(dir))
throw new ArgumentException("Nome de diretório base inválido!");
dir = dir.Replace('/', ' ');
dir = dir.Replace('\\', ' ');
dir = dir.Trim();
_baseDir = dir;
}
}
public string GetImageDirectory()
{
return AppDomain.CurrentDomain.BaseDirectory +
_baseDir + Path.DirectorySeparatorChar;
}
protected void Validate(string fileName)
{
if (string.IsNullOrEmpty(fileName))
throw new ArgumentException("nome de arquivo inválido!");
string ext = Path.GetExtension(fileName).ToLower();
if (ext != ".jpg" && ext != ".gif" &&
ext != ".bmp" && ext != ".png" && ext != ".tif")
throw new ArgumentException("extensão de arquivo inválida!");
string dir = GetImageDirectory();
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
}
public void Upload(string fileName, byte[] data)
{
Validate(fileName);
FileStream writer = new FileStream(GetImageDirectory() + fileName,
FileMode.Create);
writer.Write(data, 0, data.Length);
writer.Close();
if (_CreateThumbnails)
CreateThumbnail(fileName);
}
public void Upload(string fileName, Stream data)
{
byte[] buffer = new byte[data.Length];
data.Write(buffer, 0, (int)data.Length);
Upload(fileName, buffer);
buffer = null;
GC.SuppressFinalize(buffer);
if (_CreateThumbnails)
CreateThumbnail(fileName);
}
public void Delete(string fileName)
{
string filePath = GetImageDirectory() + fileName;
if (File.Exists(filePath))
File.Delete(filePath);
string thumbnailPath = GetImageDirectory() + "thumb_" + fileName;
if (File.Exists(thumbnailPath))
File.Delete(thumbnailPath);
}
public void CreateThumbnail(string fileName)
{
string thumbnailName = "thumb_" + fileName;
string filePath = GetImageDirectory() + fileName;
string thumbnailPath = GetImageDirectory() + thumbnailName;
System.Drawing.Image img = System.Drawing.Image.FromFile(filePath);
System.Drawing.Image thumbnail = img.GetThumbnailImage(
_ThurmbnailSize.Width,
_ThurmbnailSize.Height,
new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback),
IntPtr.Zero);
thumbnail.Save(thumbnailPath);
}
protected bool ThumbnailCallback()
{
return true;
}
}
}

Finalmente, sugere-se uma fábrica concreta que permita um ponto de junção para a evolução do componente:

classe UploaderServiceFactory

using System;
namespace net.jorgealbuquerque.Services.Uploader
{
public class UploaderServiceFactory
{
private UploaderServiceFactory() { }
private static UploaderServiceFactory _instance;
public static UploaderServiceFactory GetInstance()
{
if (_instance == null)
_instance = new UploaderServiceFactory();
return _instance;
}
public IUploader GetUploader()
{
return new UploaderService();
}
}
}



Desta forma, o delegate do evento OnClick() seria reescrito da forma abaixo. Observa-se a separação entre lógica de negócios e apresentação.

protected void btnEnviar_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
UploaderServiceFactory().GetInstance().GetUploader().
Upload(FileUpload1.FileName, FileUpload1.FileBytes);
lblFileName.Text = "Arquivo enviado: " + FileUpload1.FileName;
Image1.ImageUrl = "~/imagens/" + FileUpload1.FileName;
Image1.Visible = true;
}
else
{
lblFileName.Text = string.Empty;
Image1.Visible = false;
}
}

Note ainda que o componente pode ser igualmente empregado em contexto Windows Forms sem qualquer adaptação, ampliando seu potencial de reuso. De forma a tornar mais evidente a separação em camadas obtida pelo componente descrito, propõe-se a persistência do cadastro de imagens. Neste contexto, definiu-se a camada de persistência conforme a figura ao lado através de um componente DataSet "tipado", de acordo com o modelo proposto pela Microsoft. Por sua vez, o serviço da camada de negócios também segue as recomendações da empresa, sendo apresentado abaixo:

using System;
using System.IO;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.ComponentModel;
using net.jorgealbuquerque.Sample.Dao;
using net.jorgealbuquerque.Sample.Dao.DataSet1TableAdapters;
using net.jorgealbuquerque.Services.Uploader;
namespace net.jorgealbuquerque.Sample.Services
{
[System.ComponentModel.DataObject]
public class ManterImagesService
{
private static ImageDAO _DAO = null;
protected ImageDAO DAO
{
get
{
if (_DAO == null)
_DAO = new ImageDAO();
return _DAO;
}
}
public void Upload(FileUpload fileUpload, string comentario)
{
UploaderServiceFactory.GetInstance().GetUploader().
Upload(fileUpload.FileName, fileUpload.FileBytes);
Insert(fileUpload.FileName, DateTime.Now, comentario);
}
public void Upload(byte[] imageStream, string nome, string comentario)
{
UploaderServiceFactory.GetInstance().GetUploader().
Upload(nome, imageStream);
Insert(nome, DateTime.Now, comentario);
}
public void Upload(Stream imageStream, string nome, string comentario)
{
UploaderServiceFactory.GetInstance().GetUploader().
Upload(nome, imageStream);
Insert(nome, DateTime.Now, comentario);
}
[System.ComponentModel.DataObjectMethod(DataObjectMethodType.Select, true)]
public DataSetLisier.ImageDataTable GetAll()
{
return DAO.GetAll();
}
[System.ComponentModel.DataObjectMethod(DataObjectMethodType.Select, false)]
public DataSetLisier.ImageDataTable GetByID(int ID)
{
if (ID < -1)
throw new ArgumentException("ID inválido!");
return DAO.GetByID(ID);
}
public DataSetLisier.ImageRow GetRowByID(int ID)
{
DataSetLisier.ImageDataTable tbl = GetByID(ID);
if (tbl.Count != 1)
throw new ArgumentException("Imagem não encontrada!");
return (DataSetLisier.ImageRow)tbl.Rows[0];
}
[System.ComponentModel.DataObjectMethod(DataObjectMethodType.Delete, true)]
public void Delete(int ID)
{
if (ID < 0)
throw new ArgumentException("ID inválido!");
DataSetLisier.ImageRow img = GetRowByID(ID);
if (img == null)
throw new ArgumentException("imagem não cadastrada!");
UploaderServiceFactory.GetInstance().GetUploader().Delete(img.nome);
int linhas = DAO.Delete(ID);
if (linhas != 1)
throw new OperationCanceledException("Erro excluindo imagem!");
}
protected void ValidaDados(string nome, DateTime data, string comentario)
{
if (string.IsNullOrEmpty(nome))
throw new ArgumentException("nome de arquivo inválido!");
}
[System.ComponentModel.DataObjectMethod(DataObjectMethodType.Insert, true)]
public void Insert(string nome, DateTime data, string comentario)
{
ValidaDados(nome, data, comentario);
int linhas = DAO.Insert(nome, data, comentario);
if (linhas != 1)
throw new OperationCanceledException("Erro inserindo imagem!");
}
[System.ComponentModel.DataObjectMethod(DataObjectMethodType.Insert, false)]
public void Insert(DataSetLisier.ImageRow row)
{
if (row == null)
throw new OperationCanceledException("Imagem não pode ser nula!");
Insert(row.nome, row.data, row.comentario);
}
[System.ComponentModel.DataObjectMethod(DataObjectMethodType.Update, true)]
public void Update(string nome, DateTime data, string comentario, int ID)
{
// Regra de negocio: nome e data da imagem
// nao podem ser alterados pela interface!
DataSetLisier.ImageRow row = GetRowByID(ID);
if (row == null)
throw new OperationCanceledException("Imagem não cadastrada!");
int linhas = DAO.Update(row.nome, row.data, comentario, ID);
if (linhas != 1)
throw new OperationCanceledException("Erro alterando imagem!");
}
[System.ComponentModel.DataObjectMethod(DataObjectMethodType.Update, false)]
public void Update(DataSetLisier.ImageRow row)
{
if (row == null)
throw new OperationCanceledException("A imagem não pode ser nula!");
ValidaDados(row.nome, row.data, row.comentario);
int linhas = DAO.Update(row);
if (linhas != 1)
throw new OperationCanceledException("Erro alterando imagem!");
}
}
}

Vale resaltar novamente que a classe de serviço descrita acima deve ser encapsulada em um assembly (dll) a parte, sendo plenamente compatível com aplicações Windows Forms, o que demonstra a separação em camadas. Desta, pode-se evoluir o mock inicial para a pequena aplicação abaixo.



Onde novo delegate do botão "Enviar" é apresentado abaixo, onde fica ainda mais evidente a separação em camadas entre as lógicas de apresentação, negócios e persistência:


protected void btnEnviar_Click(object sender, EventArgs e)
{
new ManterImagesService().Upload(FileUploader1, txtComentario.Text);
ImageGridView.DataBind();
}