<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4314281331790852832</id><updated>2011-11-27T23:14:25.953-02:00</updated><category term='Ciência'/><category term='Grupo de Usuários'/><category term='Python'/><category term='Five'/><category term='RelStorage'/><category term='Plone'/><category term='ZODB'/><category term='Linguagem de Programação'/><category term='twitter'/><category term='Social Network Service'/><category term='pythonbrasil'/><category term='Eventos'/><category term='buildout'/><category term='Zope'/><category term='Threads'/><category term='Engenharia de Software'/><category term='Associação Python Brasil'/><category term='Colaboração'/><category term='Manipulação de arquivos'/><category term='Lisp'/><category term='Scheme'/><title type='text'>Python, Zope and Plone Experiments</title><subtitle type='html'>Blog para postar exemplos de código e estudos utilizando a linguagem de programação Python, o framework Zope e o CMS Plone.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://python-blog.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4314281331790852832.post-5603939963609329628</id><published>2011-06-18T21:37:00.007-03:00</published><updated>2011-06-18T22:01:57.315-03:00</updated><title type='text'>18 de junho agora é #dornelesday</title><content type='html'>Hoje é um dia muito especial, pois hoje é dia de homenagear uma grande pessoa: Dorneles Treméa. Pois ele, com seus gestos simples, paciência, perseverança e generosidade, se tornou um exemplo para muitas pessoas, no mundo todo, dentro da comunidade de Software Livre e mais especificamente na comunidade Python e Plone.&lt;br /&gt;&lt;br /&gt;Apesar de ter nos deixado tão jovem, o tempo é relativo, por isso, tenho certeza que ele deixou uma marca profunda na vida de todos que conviveram com ele. Seja pela paz e alegria que ele transmitia, sempre de bom humor nas mais difíceis situações, seja pela disposição eu ajudar quem lhe pedia auxílio, seja pela dedicação que tinha pela sua família.&lt;br /&gt;&lt;br /&gt;Por isso, para mim e para muitas pessoas, o dia 18 de junho é a partir de hoje #dornelesday, que representa um dia para refletir sobre tudo de bom que nosso colega e amigo trouxe para nós com seu exemplo de vida. Que todo dia possamos nos inspirar com esse exemplo e possamos aprender, um pouco que seja, com este legado.&lt;br /&gt;&lt;br /&gt;Na verdade não é fácil seguir seu exemplo, não é fácil ajudar as pessoas como ele ajudava, não é fácil estar sempre de bom humor como ele sempre estava. Mas é por isso que é tão importante essa homenagem, não somente para valorizar o que ele nos trouxe, mas principalmente para conseguir passar esse exemplo adiante, para outras pessoas e assim tornar o mundo em que vivemos um lugar melhor para todos nós.&lt;br /&gt;&lt;br /&gt;Viva o Deo (@dorneles)! Viva o #dorndeleday! Que sua luz continue brilhando forte de onde quer que você esteja, como sempre brilhou por aqui! Agradeço imensamente a oportunidade que tive de conviver contigo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4314281331790852832-5603939963609329628?l=python-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://python-blog.blogspot.com/feeds/5603939963609329628/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4314281331790852832&amp;postID=5603939963609329628' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/5603939963609329628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/5603939963609329628'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/2011/06/18-de-junho-agora-e-dornelesday.html' title='18 de junho agora é #dornelesday'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4314281331790852832.post-2274126312131496305</id><published>2009-08-27T09:50:00.075-03:00</published><updated>2009-08-28T11:47:37.618-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Plone'/><category scheme='http://www.blogger.com/atom/ns#' term='RelStorage'/><category scheme='http://www.blogger.com/atom/ns#' term='ZODB'/><category scheme='http://www.blogger.com/atom/ns#' term='Zope'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>RelStorage: ZODB usando backend relacional (SGDBs)</title><content type='html'>&lt;span style="font-size:180%;"&gt;Introdução&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O &lt;a href="http://docs.zope.org/zodb"&gt;ZODB&lt;/a&gt; (banco de dados orientado à objetos para aplicalções &lt;a href="http://www.python.org.br/"&gt;Python&lt;/a&gt;), originalmente criado como um componente do servidor de Aplicação &lt;a href="http://docs.zope.org/zope2"&gt;Zope2 (&lt;em&gt;Z Object Publishing Environment&lt;/em&gt;)&lt;/a&gt;, foi desenvolvido com o conceito de "Storage Layer", o qual abstrai o tipo de backend responsável pela persistência dos objetos.&lt;br /&gt;&lt;br /&gt;Historicamente, o primeiro Storage Layer desenvolvido para o ZODB foi  FileStorage, que tem como objetivo ser simples e robusto, e por isso armazena todos os objetos e transações um único arquivo de forma sequencial. Para acessar os objetos através do seu caminho na hieraquia de objetos do ZODB (ex: obj2 = root['obj1']['obj2'] ), o FileStorage cria um arquivo auxiliar de índice e que deve estar completamente na memória para que o desempenho seja adequado.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Compartilhando o ZODB&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mais tarde, devido a necessidade de compartilhar um mesmo banco de dados por diversas instâncias de uma aplicação (ou diversas aplicações), foi desenvolvido o &lt;a href="http://docs.zope.org/zodb/zodbguide/zeo.html"&gt;ZEO (Zope Enterprise Objetcts)&lt;/a&gt;, que é composto por um servidor RPC que fornece acesso via rede a um ou mais bancos de dados ZODB em FileStorage.&lt;br /&gt;&lt;br /&gt;Segue abaixo um de acesso ao ZODB com ZEO e ClientStorage retirado do &lt;a href="http://docs.zope.org/zodb/zodbguide/zeo.html"&gt;ZODB Guide&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;ZEO&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ClientStorage&lt;/span&gt;&lt;br /&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;ZODB&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;br /&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;transaction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# modificar essa linha de acordo com a configuração do servidor ZEO&lt;br /&gt;&lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'zeoserver.example.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1975&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ClientStorage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# vamos armazenar uma lista e um dicionário no objeto raiz&lt;span class="c"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'lista'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'dicionario'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# o ZODB é um banco ACID e transacional, é preciso fazer o commit&lt;br /&gt;# no caso do ZOPE, esse commit é automático caso exista uma exceção não tratada&lt;br /&gt;&lt;span class="n"&gt;transaction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Dessa forma, cada instância da aplicação cliente acessa o ZEO usando o Storage Layer  ClientStorage para se concectar ao banco de dados compartilhado pelo servidor ZEO. Para o tratamento de concorrência, o ZEO / ZODB utiliza um mecanismo "otimista" de controle de conflitos entre transações que acessam os mesmo objetos, se um conflito ocorrer, uma exceção do tipo "ConflictError" é levantada para avisar o problema a aplicação cliente.&lt;br /&gt;&lt;br /&gt;O conjunto de ZEO + FileStorage e aplicação cliente (Zope por exemplo) +  ClientStorage permite que os mesmos arquivos de dados ZODB no formato FileStorage sejam acessados simultanemente para  criação de Clusters, muito usados para aumentar o desempenho de sites de alto tráfego que usam Zope/Plone, por exemplo.&lt;br /&gt;&lt;br /&gt;Essa combinação, apesar de ser a única alternativa para "compartilhar" o ZODB por várias instâncias de uma aplicação, possui algumas limitações de escalabilidade e redundância:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;O ZEO é uma aplicação Python e devido ao &lt;a href="http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock"&gt;GIL (Global Lock Interpreter)&lt;/a&gt; ele somente consegue ser escalonado em uma CPU por vez e, por isso, não aproveita melhor os sistemas com vários processadores/núcleos. Essa limitação prejudica a escalabilidade do backend e pode ser percebida quando muitas instâncias da aplicação precisam acessar ou gravar dados ao mesmo tempo.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A Zope Corp possui um  componente proprietário, o &lt;a href="http://www.zope.com/products/zope_replication_services.html"&gt;Zope Replication Services&lt;/a&gt;, que é vendido separadamente para replicação de bases de dados ZODB + FileStorage, possibilitando replicar em tempo real o servidor ZEO, conseguindo então uma solução de alta disponibilidade, porém o custo é alto e proibitivo para a maioria das organizações e situações de uso do ZODB.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Quanto mais objetos no ZODB, maior o arquivo de índice do FileStorage e, em alguns casos de grandes bases de dados, a inicialização pode ser bem demorada, principalmente se for necessário recriar esse índice.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:180%;"&gt;&lt;/span&gt;&lt;span style="font-size:180%;"&gt;Surge o RelStorage&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Foi com objetivo de atacar essas deficiências e seguindo a idéia do BerkeleyStorage, que foi desenvolvido RelStorage (inicialmente chamado de PGStorage) o qual suporta o aramazenamento dos objetos opacos do ZODB (no formato de byte-code python), em bases de dados relacionais.&lt;br /&gt;&lt;br /&gt;Isso significa que esses objetos não podem ser consultados diretamente através do banco de dados relacional (ex: realizando consultas para reltórios), mas apenas pelo ZODB (aplicações Python), o qual ao ser configurado com RelStorage, sabe como recuperar e gravar os objetos, de forma transparente, que estão persistidos em um backend relacional e que substitui o  ZEO + FileStorage na tarefa de compartilhar o ZODB por diversas instâncias da mesma aplicação ou diversas aplicações.&lt;br /&gt;&lt;br /&gt;Atualmente existem "adapters" no RelStorage para armazenar bases de dados ZODB em três diferentes backends relacionais: MySQL, PostgreSQL e Oracle. Novas servidores de banco de dados podem ser integrados atrvés da implementação de um novo adapter.&lt;br /&gt;&lt;br /&gt;Segue um exemplo simples para configuração de um banco de dados ZODB com RelStorage e usando o PostgreSQLAdapter, lembrando que é preciso primeiro criar o banco de dados no PostgreSQL e o RelStorage inicializa as tabelas no primeiro acesso:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import transaction&lt;br /&gt;from ZODB.DB import DB&lt;br /&gt;&lt;br /&gt;from relstorage.relstorage import RelStorage&lt;br /&gt;from relstorage.adapters.postgresql import PostgreSQLAdapter&lt;br /&gt;&lt;br /&gt;# alterar a configuração de acordo com o banco de dados no PostgreSQL&lt;br /&gt;dsn = "dbname='ruda' user='ruda' host='localhost' password='12345'"&lt;br /&gt;&lt;br /&gt;adapter = PostgreSQLAdapter(dsn)&lt;br /&gt;storage = RelStorage(adapter)&lt;br /&gt;db = DB(storage)&lt;br /&gt;conn = db.open()&lt;br /&gt;root = conn.root()&lt;br /&gt;&lt;/code&gt;&lt;pre&gt;# vamos armazenar uma lista e um dicionário no objeto raiz&lt;br /&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'lista'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'dicionario'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;code&gt;transaction.commit()&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Desempenho e Alta Disponibilidade&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Os &lt;a href="http://shane.willowrise.com/archives/relstorage-111-coming-soon/"&gt;testes realizados &lt;/a&gt;por  &lt;a href="http://www.linkedin.com/in/shanehathaway"&gt;Shane Hataway&lt;/a&gt; (criados do RelStorage) indicam que o RelStorage possui um desempenho superiror ao ZEO tanto na leitura quanto na gravação, e que esse ganho aumenta quanto maior concorrência de acesso ao ZODB. É importante notar que é possível fazer um tunning no ZEO que melhora seu desempenho, porém o problema de escalabilidade decorrente do &lt;a href="http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock"&gt;GIL&lt;/a&gt;, tente a tornar o ZEO mais lento em ambientes de alta concorrêcia, como por exemplo sites Zope/Plone que possuem muitas instâncias Zope.&lt;br /&gt;&lt;br /&gt;Além disso, devido ao uso de bases de dados relacionais, as bases de dados ZODB armazenadas com RelStorage podem ser replicadas usando as ferramentas disponíveis em cada SGDB. Por esse motivo, o RelStorage passa a ser uma alternativa interessante para criação de ambientes de alta disponibilidade que usam o ZODB, novamente, grandes portais Zope/Plone são um público em potecial.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Estabilidade, Migração e Integração&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O RelStorage pode ser considerado estável e já está sendo usado em produção por diversos sites, incluindo um grande portal Zope/Plone que usa RelStorage com Oracle e foi um dos patrocinadores da implementação desse novo Storage para ZODB.&lt;br /&gt;&lt;br /&gt;Além disso, RelStorage possui uma excelente cobertura de testes e inclui em sua distribuição uma ferramenta (&lt;a href="http://wiki.zope.org/ZODB/ZODBConvert"&gt;zodbconvert.py&lt;/a&gt;) para migração de bases de dado do formato FileStorage para RelStorage (MySQLAtapter, PostgresSQLAdapter e OracleAdapter) e vice-versa.&lt;br /&gt;&lt;br /&gt;As opções do arquivo de configuração para migração usando zodbconvert.py são semlhantes as  opções usadas na configuração de cada adapter do RelStorage (cada um possui opções distintas).  No caso do PostgreSQL a configuração (migration.conf) seria:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;filestorage&amp;gt;&lt;br /&gt; path /tmp/Data.fs&lt;br /&gt;&amp;lt;/filestorage&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;relstorage&amp;gt;&lt;br /&gt; &amp;lt;postgresql&amp;gt;&lt;br /&gt;   dsn dbname='ruda' user='ruda' host='localhost' password='12345'&lt;br /&gt; &amp;lt;/postgresql&amp;gt;&lt;br /&gt;&amp;lt;/relstorage&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Para realizar a migração, em um ambiente Zope/Plone configurado via &lt;a href="http://www.buildout.org/"&gt;Buildout&lt;/a&gt;, basta executar os seguintes comandos no shell, assumindo a versão 1.2.0b2 do RelStorage:&lt;br /&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt;$ cd meu_diretorio_buildout&lt;br /&gt;$ ./bin/zopepy ./eggs/RelStorage-1.2.0b2-py2.4.egg/relstorage/zodbconvert.py /tmp/migration.conf&lt;/pre&gt; Finalmente, já existe suporte no pacote &lt;a href="http://pypi.python.org/pypi/plone.recipe.zope2instance"&gt;plone.recipe.zope2instance&lt;/a&gt; para que o RelStorage seja configurado com Buildout&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt; para automatização do deploy de aplicações Zope/Plone. Porém, para uso com Plone 2.5 (Zope 2.9) e Plone 3.x (Zope 2.10), é necessário incluir o &lt;a href="http://packages.willowrise.org/"&gt;repositório com versões modificadas do ZODB 3.7 e 3.8&lt;/a&gt; para suportar o RelStorage. Já no Plone 4.x (Zope 2.12) que virá com o &lt;a href="http://pypi.python.org/pypi/ZODB3/3.9.0c1"&gt;ZODB 3.9&lt;/a&gt;, não será preciso usar a versão com patch pois o mesmo já foi aplicado no repositório oficial da nova versão do ZODB.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Conclusão&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Com RelStorage podemos criar ambientes que necessitam de maior desempenho e disponibildiade do ZODB, substituindo o  ZEO e consequentemente algumas de suas limitações. Grandes portais desenvolvidos em Plone podem aproveitar esses recursos, principalmente em ambientes nos quais são usados clusters Zope e que tem o requisito de maior alto desempenho e redundância.&lt;br /&gt;&lt;br /&gt;Embora ainda não exista informações divulgadas sobre sites que usam o RelStorage, incluindo detalhes sobre ganhos de desempenho e escalabilddade que  demostrem claramente as vantagens da sua adoção, dependendo do ambiente a possibilidade de replicação on-line já seria um motivo suficiente para justificar a migração para o RelStorage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4314281331790852832-2274126312131496305?l=python-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://python-blog.blogspot.com/feeds/2274126312131496305/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4314281331790852832&amp;postID=2274126312131496305' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/2274126312131496305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/2274126312131496305'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/2009/08/relstorage-zodb-distribuido-usando.html' title='RelStorage: ZODB usando backend relacional (SGDBs)'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4314281331790852832.post-5662619647451569667</id><published>2009-08-16T22:54:00.004-03:00</published><updated>2009-08-16T23:04:04.694-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><category scheme='http://www.blogger.com/atom/ns#' term='pythonbrasil'/><title type='text'>Python Brasil [5]! Sigam /pythonbrasil no Twitter</title><content type='html'>Essa é rapidinha, mas tem mais de 140 caracteres! :-)&lt;br /&gt;&lt;br /&gt;Para melhor divulgar as informações a respeito da Conferência Python Brasil [5], tanto sobre os preparativos, bem como as dicas, avisos e acontecimentos durante o evento, foi criada a conta &lt;a href="http://twitter.com/pythonbrasil"&gt;@pythonbrasil&lt;/a&gt; no Twitter específica para isso! &lt;br /&gt;&lt;br /&gt;Então..  sigam &lt;a href="http://twitter.com/pythonbrasil"&gt;@pythonbrasil&lt;/a&gt; e nos vemos em Caxias do Sul!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4314281331790852832-5662619647451569667?l=python-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://python-blog.blogspot.com/feeds/5662619647451569667/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4314281331790852832&amp;postID=5662619647451569667' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/5662619647451569667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/5662619647451569667'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/2009/08/python-brasil-5-sigam-pythonbrasil-no.html' title='Python Brasil [5]! Sigam /pythonbrasil no Twitter'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4314281331790852832.post-1862666055497491113</id><published>2009-04-12T22:55:00.006-03:00</published><updated>2009-04-13T00:02:01.496-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Plone'/><category scheme='http://www.blogger.com/atom/ns#' term='buildout'/><category scheme='http://www.blogger.com/atom/ns#' term='Five'/><title type='text'>Como explodir seu buildout com Plone 2.5  e Five 1.4?</title><content type='html'>Já faz algum tempo que a melhor forma de realizar  &lt;span style="font-style: italic;"&gt;deploy&lt;/span&gt; de projetos &lt;a href="http://plone.org/"&gt;Plone&lt;/a&gt;  passou a ser a utilização da ferramenta &lt;a href="http://plone.org/documentation/tutorial/buildout"&gt;zc.buildout&lt;/a&gt;, também chamada apenas de &lt;span style="font-style: italic;"&gt;buildout&lt;/span&gt;. É realmente incrível como ela facilita a tarefa de criar ambientes tanto para produção como desenvolvimento de forma simples, rápida e fácil, mesmo nos mais complexos cenários.&lt;br /&gt;&lt;br /&gt;Tudo isso graças a sua arquitetura, a qual permite a utilização de diferentes receitas (&lt;span style="font-style: italic;"&gt;recipes&lt;/span&gt;), desde que elas sejam publicadas como um pacote &lt;a href="http://www.python.org.br/"&gt;&lt;span style="font-style: italic;"&gt;Python&lt;/span&gt;&lt;/a&gt; no &lt;a href="http://pypi.python.org/pypi"&gt;PyPi&lt;/a&gt;, e assim podem ser reutilizadas por qualquer um que necessite da mesma funcionalidade. Na verdade, o &lt;span style="font-style: italic;"&gt;buildout&lt;/span&gt; pode (e deve) ser usado por quaisquer projetos, não se limitando apenas ao &lt;span style="font-style: italic;"&gt;Zope&lt;/span&gt; e seus compatriotas como o &lt;span style="font-style: italic;"&gt;Plone&lt;/span&gt; e &lt;a href="http://grok.zope.org/"&gt;&lt;span style="font-style: italic;"&gt;Grok&lt;/span&gt;&lt;/a&gt;, e já vem sendo usado em &lt;a href="http://www.stereoplex.com/two-voices/a-django-development-environment-with-zc-buildout"&gt;projetos &lt;span style="font-style: italic;"&gt;Django&lt;/span&gt;&lt;/a&gt; também.&lt;br /&gt;&lt;br /&gt;Porém, existem vantagens e desvantagens de se utilizar o &lt;span style="font-style: italic;"&gt;buildout&lt;/span&gt; para o &lt;span style="font-style: italic;"&gt;deploy&lt;/span&gt; de projetos de &lt;span style="font-style: italic;"&gt;software&lt;/span&gt;. Na minha opinião, as vantagens são muito maiores que as desvantagens. A principal vantagem é a capacidade de se criar ambientes de forma controlada, facéis de serem reproduzidos e estáveis (a depender da configuração usada). E a principal desvantagem é a dependência da ferramenta (&lt;span style="font-style: italic;"&gt;buildout&lt;/span&gt;) sem ter conhecimento de como o &lt;span style="font-style: italic;"&gt;deploy&lt;/span&gt; do ambiente funciona a ponto de poder identificar e reparar as falhas e problemas que ocorrem quando algum conflito, atualização de pacote ou incompatibilidade interferem no seu funcionamento.&lt;br /&gt;&lt;br /&gt;De fato, existem armadilhas que podem ocorrer e acredito que muitos usuários do &lt;span style="font-style: italic;"&gt;buildout&lt;/span&gt; já devem ter odiado ele quando as coisas começam a dar errado e não se sabe por que.  Ontem mesmo que recebi um &lt;span style="font-style: italic;"&gt;email&lt;/span&gt; de um amigo, relatando um problema com o &lt;span style="font-style: italic;"&gt;buildout&lt;/span&gt;, e por incrível coincidência, ele já havia ocorrido comigo, por isso, eu já tinha a solução.&lt;br /&gt;&lt;br /&gt;Foi então que percebi que era hora de compartilhar o problema e a solução a fim de ajudar qualquer um que venha a se deparar com essa situação no futuro. O cenário é o seguinte: instalação do &lt;span style="font-style: italic;"&gt;Plone&lt;/span&gt; 2.5 (e &lt;span style="font-style: italic;"&gt;Zope&lt;/span&gt; 2.9) com &lt;span style="font-style: italic;"&gt;buildout&lt;/span&gt;, porém utilizando o &lt;span style="font-style: italic;"&gt;Five&lt;/span&gt; 1.4 ao invés do &lt;span style="font-style: italic;"&gt;Five&lt;/span&gt; 1.3 que vem originalmente com o &lt;span style="font-style: italic;"&gt;Zope&lt;/span&gt; 2.9.&lt;br /&gt;&lt;br /&gt;A armadilha é a seguinte: quando modificamos a versão do &lt;span style="font-style: italic;"&gt;Five&lt;/span&gt;, não estamos fazendo nada de errado, pois a versão 1.4 foi feita para ser compatível com o &lt;span style="font-style: italic;"&gt;Zope&lt;/span&gt; 2.9. Esse é também um pré requisito para diversos pacotes adicionais do &lt;span style="font-style: italic;"&gt;Plone&lt;/span&gt; que necessitam de funcionlidades da &lt;a href="http://www.muthukadan.net/docs/zca.html"&gt;ZCA&lt;/a&gt; e do Framework &lt;span style="font-style: italic;"&gt;Zope&lt;/span&gt; 3 que não são suportados pela versão 1.3 do &lt;span style="font-style: italic;"&gt;Five&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Porém, a receita de instalação do &lt;span style="font-style: italic;"&gt;Zope&lt;/span&gt; para o &lt;span style="font-style: italic;"&gt;Plone&lt;/span&gt; 2.5 (plone.recipe.zope2instance), não está preparada para essa situação e o sintoma do problema apenas aparece na tentativa de iniciar ou reiniciar a instância, gerando uma falha na localização de algumas diretivas &lt;span style="font-style: italic;"&gt;ZCML&lt;/span&gt;, como por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;   ConfigurationError: ('Unknown directive',&lt;/span&gt; &lt;span style="font-style: italic;"&gt; u'&lt;/span&gt;&lt;a style="font-style: italic;" href="http://namespaces.zope.org/genericsetup" target="_blank"&gt;http://namespaces.zope.org/&lt;wbr&gt;genericsetup&lt;/a&gt;&lt;span style="font-style: italic;"&gt;', u'registerProfile')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;De fato, quando um erro como esse ocorre, fica difícil identificar qual é a real causa. Nesse momento é que odiamos o &lt;span style="font-style: italic;"&gt;buildout&lt;/span&gt; com todas as forças. Mas não se desespere, existe luz no fim do tunel! Ao investigar a situação a fundo descobri uma forma simples, fácil e indolor de evitar quaisquer surpresas em ambientes &lt;span style="font-style: italic;"&gt;Plone&lt;/span&gt; 2.5 com &lt;span style="font-style: italic;"&gt;Five&lt;/span&gt; 1.4, apenas adicionando as seguintes linhas ao seu arquivo buildout.cfg:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;[commands]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; recipe = plone.recipe.command&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;command =&lt;/span&gt; &lt;span style="font-style: italic;"&gt;&lt;br /&gt; cp ${productdistros:location}/Five/skel/site.zcml ${instance:location}/etc&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Não se esqueça também de incluir a seção "commands" depois de "instance" na seção principal do buildout.cfg.&lt;br /&gt;Essa configuração assume que você esteja instalando o &lt;span style="font-style: italic;"&gt;Five&lt;/span&gt; 1.4 em [productdistros] usando seu link para &lt;span style="font-style: italic;"&gt;download&lt;/span&gt; e instalação automática.&lt;br /&gt;&lt;br /&gt;Como pode ser observado pelo trecho acima, estamos usando a receita &lt;a style="font-style: italic;" href="http://pypi.python.org/pypi/plone.recipe.command"&gt;plone.recipe.command &lt;/a&gt;que nos permite executar qualquer tipo de comando &lt;span style="font-style: italic;"&gt;shell&lt;/span&gt; para copiar a versão correta (que vem com o &lt;span style="font-style: italic;"&gt;Five&lt;/span&gt; 1.4) do arquivo &lt;span style="font-style: italic;"&gt;site.zcml&lt;/span&gt; para o diretório &lt;span style="font-style: italic;"&gt;etc&lt;/span&gt; da instância &lt;span style="font-style: italic;"&gt;Zope&lt;/span&gt;. A depender da configuração das suas instâncias, pode ser necessário ajustar o comando, assim como, se você já possui uma versão especial de configuração do arquivo &lt;span style="font-style: italic;"&gt;site.zcml&lt;/span&gt;, o comando também deve ficar diferente.&lt;br /&gt;&lt;br /&gt;Espero que essa dica ajude outras pessoas a conhecer o &lt;span style="font-style: italic;"&gt;buildout&lt;/span&gt; e a resolver e evitar esse tipo de problemas em ambientes com o &lt;span style="font-style: italic;"&gt;Plone&lt;/span&gt; 2.5 e &lt;span style="font-style: italic;"&gt;Five&lt;/span&gt; 1.4, e de quebra, serva como um exemplo de utilização da receita &lt;a style="font-style: italic;" href="http://pypi.python.org/pypi/plone.recipe.command"&gt;plone.recipe.command&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4314281331790852832-1862666055497491113?l=python-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://python-blog.blogspot.com/feeds/1862666055497491113/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4314281331790852832&amp;postID=1862666055497491113' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/1862666055497491113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/1862666055497491113'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/2009/04/como-explodir-seu-buildout-com-plone-25.html' title='Como explodir seu buildout com Plone 2.5  e Five 1.4?'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4314281331790852832.post-372389830596320602</id><published>2008-01-30T11:30:00.000-03:00</published><updated>2008-01-30T13:59:02.952-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Plone'/><category scheme='http://www.blogger.com/atom/ns#' term='Social Network Service'/><title type='text'>Social Network Research and Plone</title><content type='html'>I will have the next 6 months to develop a framework to help fast delivery of S&lt;a href="http://en.wikipedia.org/wiki/Social_networking"&gt;ocial Network Services - SNS&lt;/a&gt;, it's the implementation task of my final work graduate research and has the title: Social Network Services: component based framework. And, because I have been using &lt;a href="http://plone.org/"&gt;Plone&lt;/a&gt; in some projects to deliver Content Management Applications, like: company and community web sites, intranets, etc, in the last three years (ruda_porto IRC nick), I decide to use it as a base system to construct a SNS application framework.&lt;br /&gt;&lt;br /&gt;Of course that is not a simple task, since Social Networks Services Applications can be used for friendship, academic, professional or some kind of specialized networks, but the central point will be study the hole application domain (problem scope) and implement a framework (solution scope) to abstract social network core objects and features in a way it will be easy to extend and integrate with Plone content management core products and other third-part products for things like members, tagging, blog, wiki, audio, video, photos, files and so on.&lt;br /&gt;&lt;br /&gt;The main focus and effort will be in walk forward to make Plone a social oriented application out-of-box installing a core set of packages, thus offering the creation of social networks that share information and content among social actors with Plone. And perhaps implementing a framework that fits academic and Plone community needs at same time is a risk and a great opportunity at same time, using small components help to isolate the general problem in a set of core packages will be a foundation to create Plone social network sites and applications.&lt;br /&gt;&lt;br /&gt;The next step forward in my research is the creation of two questions list, one for end users of SNS sites and other Plone developers and users. The first must help to discover what users like and dislike in some existent SNS sites and so grasp functional requirements. The second is more difficult, but it intent is try to discover functional and non-functional requirements that can made the framework easy to extend and deliver SNS applications when integrated with Plone.&lt;br /&gt;&lt;br /&gt;I'm was waiting an opportunity make all that information public available in the Plone community and after the post from &lt;a href="http://limi.net/articles/18-things-i-wish-were-true-about-plone"&gt;Alexander Limi: 18 Things I Wish Were True About Plone&lt;/a&gt;, talking about social network path for Plone, I decide to make it and try to explain the scope of my research and my vision about Plone social integration and begin a discussion of how it (and other existent projects) can improve Plone social experience.&lt;br /&gt;&lt;br /&gt;Thanks for all folks that spend time contributing to Plone and who are responsible to made this amazing community! I will appreciate all commenting! :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4314281331790852832-372389830596320602?l=python-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://python-blog.blogspot.com/feeds/372389830596320602/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4314281331790852832&amp;postID=372389830596320602' title='5 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/372389830596320602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/372389830596320602'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/2008/01/social-network-research-and-plone.html' title='Social Network Research and Plone'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4314281331790852832.post-6835265243861102595</id><published>2007-10-07T19:35:00.000-03:00</published><updated>2007-10-08T10:34:17.127-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Manipulação de arquivos'/><title type='text'>Manipulando arquivos grandes em Python</title><content type='html'>&lt;span style=";font-family:georgia;font-size:100%;"  &gt;Marcelo Toledo escreveu um &lt;a href="http://blog.marcelotoledo.org/2007/08/10/how-to-write-a-spelling-corrector/"&gt;artigo&lt;/a&gt; comparando a sua implmentação em C de um &lt;a href="http://norvig.com/spell-correct.html"&gt;corretor ortográfico&lt;/a&gt; poposto por &lt;a href="http://norvig.com/"&gt;Peter Norgiv&lt;/a&gt; com a versão original em Python.&lt;br /&gt;&lt;br /&gt;Porém Marcelo Toledo ao realizar essa comparação não levou em consideração que o exemplo desenvolvido por Peter Norvig era apensa um protótipo. Sendo assim, ele resolveu comparar ambos os programas, em C e Python, utilizando arquivos cada vez maiores e ilustrando a diferença de performance entre eles.&lt;br /&gt;&lt;br /&gt;No código de Peter Norvig ele lê o arquivo de uma vez. Dá para imaginar o que acontenceu, baixa performance e "crash" com arquivos maiores de 100M devido a falta de RAM. :-(&lt;br /&gt;Essa é a linha na qual o programa de Peter Norvig lê o arquivo e processa ele:&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;pre  style="font-family:georgia;"&gt;&lt;span style="font-size:100%;"&gt;&lt;blockquote&gt;NWORDS = train(words(file('big.txt').read()))&lt;/blockquote&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style=";font-family:georgia;font-size:100%;"  &gt;Infelizmente Marcelo Toledo não procurou saber qual era o "bug" do código, deixando no ar uma idéia de que C é robusto é Python é uma linguagem não confiável.&lt;br /&gt;&lt;br /&gt;Como eu fui questionado por um colega (Robson Peixoto) sobre o "porque" do problema com o código do corretor ortográfico. Resolvi então escrever um pequeno script que copia arquivos binários da forma correta. E assim fica claro que Python não tem problemas em manipular arquivos maiores que 100MB. ;-)&lt;br /&gt;&lt;br /&gt;Segue um teste de uso do script copyfile.py&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;pre  style="font-family:georgia;"&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-size:100%;"&gt;ruda@zion /tmp $ du -sh livecd-i686-installer-2007.0.iso&lt;br /&gt;416M    livecd-i686-installer-2007.0.iso&lt;br /&gt;&lt;br /&gt;ruda@zion /tmp $ time ./copyfile.py livecd-i686-installer-2007.0&lt;/span&gt;&lt;wbr&gt;&lt;span style="font-size:100%;"&gt;.iso teste.iso&lt;br /&gt;&lt;br /&gt;real    0m39.708s&lt;br /&gt;user    0m4.517s&lt;br /&gt;sys     0m3.747s&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style=";font-family:georgia;font-size:100%;"  &gt;Ou seja, sem usar muita CPU e nem mesmo RAM, esse script demorou 40&lt;br /&gt;segundos para copiar um arquivo de 416MB, ou seja, 10MB/s aproximadamente.&lt;br /&gt;&lt;br /&gt;Abaixo o código do script copyfile.py&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;pre  style="font-family:georgia;"&gt;&lt;span style="font-size:100%;"&gt;&lt;blockquote&gt;#!/bin/env python&lt;br /&gt;# -*- coding: utf-8 -*-&lt;br /&gt;import sys&lt;br /&gt;&lt;br /&gt;try:&lt;br /&gt;   origem = sys.argv[1]&lt;br /&gt;   destino = sys.argv[2]&lt;br /&gt;except IndexError:&lt;br /&gt;   print "Modo de usar: copyfile.py origem destino"&lt;br /&gt;   sys.exit(1)&lt;br /&gt;&lt;br /&gt;#Exemplo de leitura e gravação de arquivos grandes - usando modo binário&lt;br /&gt;input = file(origem, 'rb')&lt;br /&gt;output = file(destino, "wb")&lt;br /&gt;for line in input:&lt;br /&gt;   output.write(line)&lt;br /&gt;&lt;br /&gt;#Fechando os arquivos&lt;br /&gt;input.close()&lt;br /&gt;output.close()&lt;/blockquote&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4314281331790852832-6835265243861102595?l=python-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://python-blog.blogspot.com/feeds/6835265243861102595/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4314281331790852832&amp;postID=6835265243861102595' title='7 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/6835265243861102595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/6835265243861102595'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/2007/10/marcelo-toledo-escreveu-um-artigo.html' title='Manipulando arquivos grandes em Python'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4314281331790852832.post-5686244511262566246</id><published>2007-09-15T15:59:00.000-03:00</published><updated>2007-09-15T16:04:51.070-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Grupo de Usuários'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Grupo de Usuários Python - Bahia</title><content type='html'>Atenção,&lt;br /&gt;&lt;br /&gt;Eu convido todos os baianos de sangue ou de coração (como eu)  e que&lt;br /&gt;adoram Python a participar da criação do Grupo de Usuários Python -&lt;br /&gt;Bahia.&lt;br /&gt;&lt;br /&gt;Essa iniciativa faz parte de um conjunto de ações importantes que a&lt;br /&gt;&lt;a href="http://associacao.pythonbrasil.org/"&gt;Associação Python Brasil&lt;/a&gt; vem coordenando para a divulgação de Python&lt;br /&gt;em todo o território nacional. E visa criar e fortalecer comunidades&lt;br /&gt;as regionais.&lt;br /&gt;&lt;br /&gt;Eu tomei a iniciativa de criar uma lista de discussão para o Grupo de&lt;br /&gt;Usuários Python - Bahia e convido todos os interessados a ingressar&lt;br /&gt;através do endereço:&lt;br /&gt;&lt;br /&gt;&lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://groups.google.com/group/grupy-ba" target="_blank"&gt;http://groups.google.com/group&lt;wbr&gt;/grupy-ba&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A idéia é se organizar para um primeiro encontro no começo de outubro.&lt;br /&gt;Porém também estamos tentando inserir algo sobre Python na programação&lt;br /&gt;do &lt;a href="http://www.ensl.org.br/site/"&gt;II ENSL&lt;/a&gt; que vai ser em Aracaju, e se tivermos vários membros da&lt;br /&gt;comunidade presentes, já seria um ótimo momento para isso. ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4314281331790852832-5686244511262566246?l=python-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://python-blog.blogspot.com/feeds/5686244511262566246/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4314281331790852832&amp;postID=5686244511262566246' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/5686244511262566246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/5686244511262566246'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/2007/09/grupo-de-usurios-python-bahia.html' title='Grupo de Usuários Python - Bahia'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4314281331790852832.post-1826348435365963344</id><published>2007-09-03T17:25:00.000-03:00</published><updated>2007-09-10T01:25:28.944-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Colaboração'/><category scheme='http://www.blogger.com/atom/ns#' term='Ciência'/><category scheme='http://www.blogger.com/atom/ns#' term='Associação Python Brasil'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>PyConBrasil [3] - catalizando a comunidade Python</title><content type='html'>A comunidade de usuários &lt;a href="http://www.pythonbrasil.com.br/"&gt;Python&lt;/a&gt; no Brasil tem muitos motivos para comemorar. Pois além da excelente qualidade da &lt;a href="http://pyconbrasil.com.br/"&gt;PyConBrasil [3]&lt;/a&gt;, tivemos consolidação da &lt;a href="http://associacao.pythonbrasil.org/"&gt;Associação Python Brasil&lt;/a&gt;, criada a três mêses atrás.&lt;br /&gt;&lt;br /&gt;Algumas pessoas envolvidas com Software Livre já brincavam comigo quando eu falava sobre a comunidade Python, com comentários do tipo: "A comunidade Python no Brasil tem apenas um punhado e desenvolvedores". Parece que agora as piadas vão ter que mudar pois esse tipo de comentário vai sair de moda. ;-)&lt;br /&gt;&lt;br /&gt;O que ficou claro durante o evento é como Python tem crescido dentro do mundo acadêmico científico e deve crescer cada vez mais, pois a simplicidade, legibilidade e flexibilidade de Python quando somada a sua ampla bilioteca e a  fácil integração com C e C++ são uma combinação perfeita para esses domínios de aplicação e um público em que o foco não é programar, mas sim desenvolver ferramentas e soluções para problemas da pesquisa científica.&lt;br /&gt;&lt;br /&gt;Apesar de eu ter perdido a palestra de &lt;a href="http://pyconbrasil.com.br/sobre-o-evento/inscricoes/ac49383cf9b4c74b5c0a77aad41bd430"&gt;Flávio Coelho &lt;/a&gt;&lt;a href="http://pyconbrasil.com.br/sobre-o-evento/inscricoes/ac49383cf9b4c74b5c0a77aad41bd430"&gt;- Python na Ciência&lt;/a&gt;, por estar ministrando um treinamento de &lt;a href="http://wiki.zope.org/zope3/Zope3Wiki"&gt;Zope3&lt;/a&gt; durante a manhã de sábado, fiquei sabendo de toda a repercursão e logo que os vídeos do evento estejam disponíveis vou dar uma conferida. Porém JS conseguiu um exemplar do livro &lt;a href="http://www.lulu.com/content/616789"&gt;Computação Científica com Python&lt;/a&gt; e eu aproveitei e li os capítulos iniciais que fazem uma introdução a Python e gostei muito do que vi e recomento.&lt;br /&gt;&lt;br /&gt;Flávio realizou um &lt;a href="http://pyinsci.blogspot.com/2007/09/pyconbrasil03.html"&gt;post em seu blog&lt;/a&gt; sobre o evento e suas impressões da comunidade, comentando sobre a qualidade do evento e o nível das apresentaões em geral e mais especificamente na área científica. Além de observar em relação a receptividade de todos os principais membros da comunidade, o que eu vejo como uma grande virtude que cada um de nós precisa exercitar.&lt;br /&gt;&lt;br /&gt;Eu sempre comento com as pessoas sobre o primeiro contato que tive com a comunidade Python durante o FISL 5.0, no espaço reservado para o encontro das comunidades. Foi ncrível a receptividade de todos,e não foi difícil logo se sentir em casa ao lado de pessoas que eu havia conhecido há algumas horas.&lt;br /&gt;&lt;br /&gt;Esse catalizador humano é fundamental para o fortalecimento da comunidade, usando os eventos de Software Livre em geral e de forma mais específica a PyConBrasil, para aglutinar as pessoas interessadas em trocar suas experiências com o uso da linguagem Python e em trabalhar conjuntamente para a divulgação e promoção da linguagem Python no Brasil e com a associação isso deve melhorar ainda mais.&lt;br /&gt;&lt;br /&gt;Eu agradeço a todos os que já trabalharam de alguma forma em prol desses objetivos, especialmente para aqueles que tem trabalhado muito durantes anos (não vou citar nomes :-)), e espero continuar participando e colaborando de alguma forma, ajudando os novos membros a se sentirem em casa.&lt;br /&gt;&lt;br /&gt;Sejam bem vindos e viva a Associação Python Brasil e não deixem de comparecer PyConBrasil [4] !!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/rudapf/sets/72157601932775976/"&gt;ps: Algumas fotos da confraternização da comunidade.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4314281331790852832-1826348435365963344?l=python-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://python-blog.blogspot.com/feeds/1826348435365963344/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4314281331790852832&amp;postID=1826348435365963344' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/1826348435365963344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/1826348435365963344'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/2007/09/pyconbrasil-3-catalizando-comunidade.html' title='PyConBrasil [3] - catalizando a comunidade Python'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4314281331790852832.post-4121798811516814648</id><published>2007-05-20T20:43:00.000-03:00</published><updated>2007-05-20T22:50:19.053-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eventos'/><category scheme='http://www.blogger.com/atom/ns#' term='Threads'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Threads e Eventos para calcular se um número é primo</title><content type='html'>&lt;span&gt;&lt;span class="S1"&gt;Segue um pequeno programa que fiz para experimentar o uso Threads e Eventos do módulo &lt;a href="http://docs.python.org/lib/module-threading.html"&gt;threading&lt;/a&gt; de Python. A minha idéia foi definir um evento que pode estar ativo ou não e que controla o início e o término do processamento de cada Thread.&lt;br /&gt;&lt;br /&gt;Ao dividir o trabalho de calcular se um número é primo em várias linhas de controle (Threads), teoricamente seria possível melhorar o tempo de processamento.  Porém como essa aplicação é &lt;span style="font-style: italic;"&gt;&lt;a href="http://en.wikipedia.org/wiki/CPU_bound"&gt;CPU bound&lt;/a&gt; &lt;/span&gt;, e como um processo do interpretador Python não permite que suas Threads executem de forma simultânea, cada qual em uma CPU ou núcleo físico, na prática esse exemplo acaba não sendo muito útil para esse caso, a não ser como prova de conceito.&lt;br /&gt;&lt;br /&gt;Se a aplicação trabalhasse com o uso de entrada e saída, ou seja,&lt;span style="font-style: italic;"&gt; &lt;a href="http://en.wikipedia.org/wiki/IO_bound"&gt; IO bound&lt;/a&gt;, &lt;/span&gt;então já seria mais interessante, pois enquanto uma Thread poderia estar bloqueada fazendo a leitura ou gravação em um disco, enviando ou recebendo dados via rede ou esperando o resultado de uma consulta no banco de dados, as outras Threads poderiam estar executando, ocupando mais a CPU e consequentemente diminuindo o tempo total de execução do programa.&lt;br /&gt;&lt;br /&gt;Segue &lt;a href="http://www.gnu.frb.br/Members/ruda/primo.py"&gt;link para acesso ao código&lt;/a&gt;, já que não consegui manter a formatação usando o editor do blogspot ou mesmo carregando o fonte do HTML gerado pelo Scite. :-(&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4314281331790852832-4121798811516814648?l=python-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://python-blog.blogspot.com/feeds/4121798811516814648/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4314281331790852832&amp;postID=4121798811516814648' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/4121798811516814648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/4121798811516814648'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/2007/05/threads-e-eventos-para-calcular-se-um.html' title='Threads e Eventos para calcular se um número é primo'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4314281331790852832.post-943481272096582833</id><published>2007-04-30T16:13:00.000-03:00</published><updated>2007-05-04T14:20:07.964-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linguagem de Programação'/><category scheme='http://www.blogger.com/atom/ns#' term='Scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='Lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='Engenharia de Software'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Python, Scheme e ML - Uma análise comparativa das linguagens de programação</title><content type='html'>Durante o &lt;a href="http://twiki.dcc.ufba.br/bin/view/PSL/FLISOL2007"&gt;FLISOL  Salvador 2007&lt;/a&gt; , evento em que&lt;a href="http://www.gnu.frb.br/noticias/flisol-salvador-2007/"&gt; participei apresentando&lt;/a&gt; uma palestra sobre &lt;a href="http://www.pythonbrasil.com.br/"&gt;Python&lt;/a&gt;, decidi que era hora de começar a escrever. Já fazia mais de um mês que eu havia decidido começar a escrever um blog sobre minhas experiências usando a linguagem &lt;a href="http://www.pythonbrasil.com.br/"&gt;Python,&lt;/a&gt; o servidor de aplicação &lt;a href="http://www.tchezope.org/"&gt;Zope&lt;/a&gt; e CMS &lt;a href="http://www.plone.org/"&gt;Plone&lt;/a&gt;.  O nome já estava registrado:  python-blog.blogspot.com, e o que mais estava faltando? Iniciativa. ;-)&lt;br /&gt;&lt;br /&gt;Na primeira postagem estou publicando um artigo que escrevi juntamente com dois colegas na disciplina de Engenharia e Software I (2006.2). Escrevê-lo me ajudou enxergar o quão poderosas são as linguagens  funcionais e o quanto Python herda desse paradigma. Além disso cheguei a conclusão que as linguagens funcionais deveriam ser mais ensinadas nos cursos de Ciência da Computação, talvez até com primeira linguagem! :-o&lt;br /&gt;&lt;br /&gt;  &lt;style type="text/css"&gt;  &lt;!--   @page { margin: 2cm }   P { margin-bottom: 0.21cm }   H1 { margin-bottom: 0.21cm }   H1.western { font-family: "Arial", sans-serif; font-size: 16pt }   H1.cjk { font-family: "Andale Sans UI", "Arial Unicode MS"; font-size: 16pt }   H1.ctl { font-family: "Andale Sans UI", "Arial Unicode MS"; font-size: 16pt }   H2 { margin-bottom: 0.21cm }   H2.western { font-family: "Arial", sans-serif; font-size: 14pt; font-style: italic }   H2.cjk { font-family: "Andale Sans UI", "Arial Unicode MS"; font-size: 14pt; font-style: italic }   H2.ctl { font-family: "Andale Sans UI", "Arial Unicode MS"; font-size: 14pt; font-style: italic }   TD P { margin-bottom: 0cm }   A:link { color: #0000ff }  --&gt;  &lt;/style&gt;  &lt;h1 class="western"  style="margin-top: 0.2cm; margin-bottom: 0.1cm;font-family:times new roman;" align="center" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);font-size:100%;" &gt;&lt;span style="font-size:16;"&gt;&lt;b&gt;Python, Scheme e ML&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt; &lt;h1 class="western"  style="margin-top: 0.2cm; margin-bottom: 0.1cm;font-family:times new roman;" align="center" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);font-size:100%;" &gt;&lt;span style="font-size:16;"&gt;Uma análise comparativa das linguagens de programação.&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt; &lt;p class="western"  style="margin-top: 0.2cm; margin-bottom: 0.1cm;font-family:times new roman;" align="center" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);font-size:100%;" &gt;&lt;b&gt;Faculdade Ruy Barbosa&lt;/b&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-top: 0.22cm; margin-bottom: 0.11cm;" align="center" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;b&gt;Rudá Porto Filgueiras, Sergio Pacheco, &lt;/b&gt;&lt;/span&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;b&gt;Adrienne Nogueira &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0cm;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0cm;" align="center" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;Disciplina de Engenharia de Software I – 2006.2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0cm;" align="center" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;Curso de Bacharelado em Ciência da Computação – Faculdade Ruy Barbosa(FRB)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0cm;" align="center" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;Rua Theodomiro Batista, 422 – Rio Vermelho – Cep: 41.940-320 – Salvador – BA&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0cm;" align="center" lang="pt-BR"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0cm;" align="center" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;rudazz@gmail.com, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;sergiorpacheco@gmail.com, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;adrieness_eu@yahoo.com.br&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;h2 class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Times New Roman,serif;"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;b&gt;1. Resumo&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt; &lt;p class="western" align="center" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;As linguagens de programação tem uma importância fundamental na nossa capacidade de expressar idéias e resolver problemas. A análise de diferentes linguagens possibilita o avaliação das escolhas realizadas em tempo de projeto, utilizando os critérios e conceitos da Engenharia de Software para  entender as escolhas dos projetistas e o resultado desas escolhas em cada linguagem.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western"&gt;Palavras-chave: Linguagem de Programação, ML, Lisp, Scheme, Python, Projeto de Linguagem&lt;/p&gt; &lt;h2 class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Times New Roman,serif;"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;b&gt;2. Introdução&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt; &lt;p class="western" align="justify"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="text-decoration: none;"&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;span style="font-style: normal;"&gt;&lt;span style="text-decoration: none;"&gt;&lt;span style=""&gt;Esse artigo se propõe a comparar as características de três diferentes linguagens de programação. Scheme e ML são linguagens fundamentadas no paradigma funcional, de amplo uso, possuem diversas implementações e são muito utilizadas na área de matemática, lógica e inteligência artificial. A terceira e última linguagem é Python, que se diferencia por ser de propósito geral, multiparadigma e influenciada pelas lições de design de importantes linguagens, tais como: Ada, Scheme, SmalTalk, Módula 3.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="font-style: normal; text-decoration: none;" align="justify" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; Para realizar esse comparativo, selecionamos algumas características a serem estudadas e comparadas entre as linguagens. Isso nos permitirá avaliar as escolhas realizadas em tempo de projeto e seus benefícios e/ou contra-partidas utilizando os critérios da Engenharia de Software como parâmetro. As características abordadas são: simplicidade global, intruções de controle, suporte para abstração, manipulação de exceções e  verificação de tipos.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;h2 class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Times New Roman,serif;"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;b&gt;3. Simplicidade global&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt; &lt;p class="western" align="justify"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          “&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;A simplicidade global de uma linguagem afeta diretamente a sua legibilidade”, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;i&gt;Sebesta&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;i&gt;(2005)&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;. As linguagens do paradigma funcional se fundamentam na simplicidade do conceito matemático de função, elementos e conjuntos. Em especial Scheme, que no seu projeto tem por objetivo ser minimalista, mantendo número de instruções básicas e palavras reservadas restritas ao mínimo necessário e ao mesmo tempo compatível com LISP.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" align="justify"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt; Python se apoia nas idéias do projeto de Scheme para se manter simples e ao ser comparada com outras linguagens imperativas, em geral, possui menos instruções básicas e palavras reservadas, o que contribui para o seu fácil aprendizado. Assim como Scheme, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;span style="text-decoration: none;"&gt;Python&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt; procura implementar apenas um modo correto de se executar uma determinada operação, isso fortalece a simplicidade e consequentemente a legibilidade da linguagem. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/p&gt; &lt;p class="western" align="justify" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; ML não possui um grau de simplicidade global tão alto quanto Scheme, pois permite a programação imperativa e a declaração de tipos, embora não obrigue essa definição. Scheme não possui tipos de dados e apoia-se na conceito de átomos (elementos) e listas (conjuntos) para abstrair suas estruturas de dados. Todas estas linguagens são de alto nível, com alta capacidade de abstração o que torna essa simplicidade poderosa e expressiva.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;h2 class="western" align="justify" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Times New Roman,serif;"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;b&gt;4.  Instruções de controle&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt; &lt;p class="western" align="justify"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;As instruções de controle são utilizadas para construir desvios e organizar o fluxo da execução dos programas. Nas linguangens imperativas, existem estruturas de controle para realizar a repetição e a seleção de determinados trechos de código a serem executados.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" align="justify"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt; Python possui um conjunto reduzido de estruturas de controle, de forma a reduzir a complexidade da linguagem. Além disso a forma de expressar um &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;i&gt;loop for &lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;span style="font-style: normal;"&gt;para percorer elementos de uma lista ou dicionário ou qualquer objeto que implemente alguns métodos especiais é simples e poderosa. Como ML, Python possui o recurso de compreensão de listas.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" align="justify" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; Scheme e ML possuem instruções de seleção simples as repetições são implementadas através da recursividade. Em Scheme a pilha de recursão não aumenta de acordo com a sua execução, o que garante que o espaço utilizado será constante, tornando a recursão mais segura e eficiente.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" align="justify" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; ML também possui recursos do paradigma imperativo, e por isso, possui instruções de controle semelhantes a linguagem C++, como if, else, case. Além disso seu mecanismo de seleção  baseados em encontro de padrões pode ser utlizado para selecionar parte da função que será executada a depender do valor recebido como parâmetro. &lt;/span&gt;&lt;/span&gt; &lt;/p&gt; &lt;p class="western"&gt;Exemplos:&lt;/p&gt; &lt;table style="color: rgb(0, 0, 0); width: 478px; height: 338px;" border="1" cellpadding="4" cellspacing="0"&gt;  &lt;col width="268"&gt;  &lt;col width="242"&gt;  &lt;tbody&gt;&lt;tr valign="top"&gt;   &lt;td width="268"&gt;    &lt;p class="western" style="margin-bottom: 0cm;" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;Python    – compreensão de listas:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;            lista =    [1, 2, 3 ,4 ,5 ,6 ,7 ,8 ,9, 10]&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;            lista =    [x for x in lista if x % 2 = 0]&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;            [2, ,4    ,6, 8 , 10]&lt;/p&gt;        &lt;p class="western" style="margin-bottom: 0cm;"&gt;Scheme –    condicional e repetição com recursão&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;            (DEFINE    (factorial n)&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;                 (IF    (= n 0)&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;                   1&lt;/p&gt;    &lt;p class="western"&gt;                   (* n (fatorial (- n 1)))))&lt;/p&gt;   &lt;/td&gt;   &lt;td width="242"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;ML    – encontro de padrões:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt; datatype shape =&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;    point&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;  | circle of real&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;  | box of (real *    real)&lt;/p&gt;        &lt;p class="western" style="margin-bottom: 0cm;"&gt; fun area (point) =    0.0&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;     | area (circle    r) = pi * sqr (r)     &lt;/p&gt;    &lt;p class="western"&gt;     | area (box(w,h)) = w * h &lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p class="western" style="margin-bottom: 0cm;"&gt; &lt;/p&gt; &lt;h2 class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Times New Roman,serif;"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;b&gt;5.  Suporte para abstração&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt; &lt;p class="western" align="justify"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt; “A abstração é a capacidade de modelar um problema de maneira a se concentrar nos aspectos importantes para esse sistema ou trecho expecífico de código, omitindo detalhes e facilitando a manipulaçãos das entidades ao separar as definições do que um programa faz, dos detalhes sobre como ele é implementado.”, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;i&gt;Watt, David A. (1989)&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/p&gt; &lt;p class="western" align="justify" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; O suporte para abstração em uma linguagem está relacionado a capacidade de definição de novos tipos de dados abstratos, denominada abstração de dados. Além disso, também está relacionada com a possibilidade de se abstrair um processo utilizando funções e procedimentos no paradigma funcional e imperativo.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" align="justify" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; O paradigma orientado a objetos funde esses dois conceitos ao permitir a definição de classes, com suas propriedades e métodos. E isso possui um impacto importante na capacidade de escrita e na confiabilidade, facilitando o reuso de código e a legibilidade.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" align="justify" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; As linguagens ML, Scheme e Python tratam as funções como tipos de dados de primeira ordem, o que as permite passar uma função como parâmetro de outras funções, armazenar funções como atributos ou elementos de uma estrutura de dados ou lista e também retorná-las como resultado de uma expressão, o que permite a criação de abstrações mais poderosas.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" align="justify"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt; Um exemplo dessa capacidade é o uso da função interna &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;i&gt;map&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;span style="font-style: normal;"&gt; que mapeia os elementos de um conjunto aos elementos de um novo conjunto utilizando uma função que é passada como parâmetro e que será aplicada a cada elemento do conjunto inicial para gerar o novo conjunto.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="font-style: normal;" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;Exemplos:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;table style="color: rgb(0, 0, 0);" border="1" cellpadding="4" cellspacing="0" width="477"&gt;  &lt;col width="141"&gt;  &lt;col width="152"&gt;  &lt;col width="158"&gt;  &lt;tbody&gt;&lt;tr valign="top"&gt;   &lt;td width="141"&gt;    &lt;p class="western" style="margin-bottom: 0cm;" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;ML&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p class="western"&gt;map(sqrt [1, 2, 3, 4])&lt;/p&gt;   &lt;/td&gt;   &lt;td width="152"&gt;    &lt;p class="western" style="margin-bottom: 0cm;" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;Scheme&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p class="western"&gt;(MAP SQRT '(1 2 3 4))&lt;/p&gt;   &lt;/td&gt;   &lt;td width="158"&gt;    &lt;p class="western" style="margin-bottom: 0cm;" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;Python&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;&lt;br /&gt;&lt;/p&gt;    &lt;p class="western"&gt;map(math.sqrt, [1,2,3,4])&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p class="western" style="margin-bottom: 0cm;"&gt; Em todos os exemplos acima o resultado será uma nova lista contendo a raiz quadrada dos elementos da lista passada como parâmentro.&lt;/p&gt;  &lt;h2 class="western" lang="pt-BR"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;i&gt;&lt;b&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Times New Roman,serif;"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;b&gt;6. Verificação de Tipos&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt; &lt;p class="western"&gt;Tradicionalmente na Engenharia de Software o sistema de verificação de tipos de uma linguagem de programação é classificado em dois grupos principais: estaticamente (fortemente) tipadas ou dinâmicamente (fracamente) tipadas. A capacidade de verificação de tipos de uma linguagem afeta diretamente a sua confiabilidade.&lt;br /&gt;&lt;/p&gt;&lt;p class="western"&gt;Porém algumas linguagens, como Python, não se enquadram nesse modelo, pois são dinâmicamente tipadas e ao mesmo tempo fortemente tipadas.  Surgindo então uma diferenciação da definição tradicional onde podemos definir as linguagens como estáticamente ou dinâmicamente tipadas e fortemente ou fracamente tipadas.&lt;br /&gt;&lt;/p&gt; &lt;p class="western"&gt;As linguagens estaticamente tipadas são aquelas no qual toda a variável, função e parâmentros tem um tipo bem definido, declarado pelo programador, e ela realiza a verficação de tipos em tempo de compilação.&lt;/p&gt; &lt;p class="western"&gt; Já nas linguagens dinamicamente tipadas, somente os valores tem tipos de dados definidos (tipos latentes), ou seja, uma variável ou parâmetro não tem um tipo definido e pode conter valores de diferentes tipos em diferentes momentos. Isso implica que a verificação de tipos deve ser  realizada em tempo de execução.&lt;/p&gt; &lt;p class="western"&gt; ML é uma linguagem estaticamente tipada e que possui um sistema de inferência de tipos robusto, tornando opcional a declaração de tipos. Scheme e Python são dinamicamente tipadas e também possuem a inferência dos tipos. Porém em todas elas o sistema de verficação de tipos não realiza a conversão implícita de um tipo de dados para outro, leventando uma exceção quando tipos inconsistentes são utilizados.  &lt;/p&gt; &lt;p class="western"&gt; Python realiza uma nova vinculação de nome e espaço a cada attribuição de valor a uma variável, inferindo o tipo de dados do valor recebido. Além disso ela não possui definição de tipos nos parâmetros de funções ou métodos, deixando a cargo no programador o tratamento dos tipos recebidos e retornados.&lt;br /&gt;&lt;/p&gt; &lt;p class="western"&gt;Exemplos:&lt;/p&gt; &lt;table style="color: rgb(0, 0, 0); width: 485px; height: 142px;" border="1" cellpadding="4" cellspacing="0"&gt;  &lt;col width="180"&gt;  &lt;col width="168"&gt;  &lt;col width="181"&gt;  &lt;tbody&gt;&lt;tr valign="top"&gt;   &lt;td width="180"&gt;    &lt;p class="western" style="margin-bottom: 0cm;" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;Scheme&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;(+ 10 “16”)&lt;/p&gt;    &lt;p class="western"&gt;;The object “16”, passed as the second    argument to integer-add, is not the correct type.&lt;/p&gt;   &lt;/td&gt;   &lt;td width="168"&gt;    &lt;p class="western" style="margin-bottom: 0cm;" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;Python&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;10 + “16”&lt;/p&gt;    &lt;p class="western"&gt;TypeError: unsupported operand type(s) for +:    'int' and 'str'&lt;/p&gt;   &lt;/td&gt;   &lt;td width="181"&gt;    &lt;p class="western" style="margin-bottom: 0cm;" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;ML&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" style="margin-bottom: 0cm;"&gt;10 + “16”;&lt;/p&gt;    &lt;p class="western"&gt;! Type clash: expression of type string cannot    have type int&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p class="western" style="margin-bottom: 0cm;"&gt; Podemos observar que não há a sobrecarga do operador “&lt;i&gt;+”&lt;/i&gt; para concaternar uma string com um inteiro e a exceção levantada é resultado do sistema de verificação de tipos.&lt;/p&gt; &lt;h2 class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Times New Roman,serif;"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;b&gt;7.  Manipulação de exceções&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt; &lt;p class="western" align="justify" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; Durante o desenvolvimento de um programa, diferentes tipos de erros precisam ser previstos e tratados para que se alcance um grau de confiabiliade adequado a cada necessidade, evitanto que o programa seja finalizado de forma inesperada.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" align="justify"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt; Porém, se a linguagem utilizada não suportar nativamente o recurso de manipulação de execeções, quanto mais verificações forem necessárias, mais complexo o código vai ficar, e isso terá um impacto direto na legibilidade e no custo de implementação e manutenção.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" align="justify"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;ML, Scheme e Pyhon tem o suporte nativo ao tratamento de exceções, incluindo a definição de novos tipos de execeção. Scheme tem o suporte a exceções integrado ao seu interpretador de comandos, permitindo que o programador decida o que fazer quando uma exceção não tratada é levantada. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;span style="font-style: normal;"&gt;As exceções em ML sempre são de tipo e podem ter um valor e um efeito associado.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" align="justify"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;Em Python as exceções definidas pelo usuário utilizam o conceito de herança da orientação a objetos. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;i&gt;Exception &lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;span style="font-style: normal;"&gt;é a classe base na qual todas as outras exceções são derivadas. E como existe a unificação entre classes e tipos, e subclasses são subtipos, ao tratar uma exceção de um determinada classe todas as subclasses dessa exceção também serão tratadas.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;h2 class="western" lang="pt-BR"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;i&gt;&lt;b&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Times New Roman,serif;"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;b&gt;8. Conclusão&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt; &lt;p class="western" style="font-style: normal;" align="justify" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; Ao analisar as linguagens e comparar suas características percebemos que as escolhas em realizadas em tempo de projeto determinam as características das linguagens e os domínios para os quais elas serão mais indicadas. &lt;/span&gt;&lt;/span&gt; &lt;/p&gt; &lt;p class="western" style="font-style: normal;" align="justify" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; ML e Scheme por serem fundamentadas no paradigma funcional, possuem uma excelente capacidade de escrita para o domínio da matemático, lógico e para sistemas simbólicos. Python foi desenvolvida para ser uma linguagem de propósito geral e consegue alcançar esse objetivo ao englobar o paradigma funcional, orientado a objetos e imperativo.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="font-style: normal;" align="justify" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; ML possui um alto grau de confiabilidade por ser estaticamente tipada e possuir um mecanismo de exceções nativo e um excelente suporte para abstração. Além disso ML permite o uso de estrturas das linguagens imperativas, aumentando a capacidade de escrita para domínios mistos que utilizem modelos formais e lógicas de negócios.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="font-style: normal;" align="justify" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt; Python possui um grau de flexibilidade muito alto e isso tem impacto na sua confiabilidade, mas que é contrabalanceado com um modelo de objetos elegante, tratamento de exceções nativo e orientado a objetos e alta capacidade de abstração e recursos da programação funcional. A sua capacidade de escrita é alta para domínio de negócios e domínios mistos.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="font-style: normal;" align="justify" lang="pt-BR"&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;Segue abaixo um quadro resumo das características das linguagens:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="western" style="font-style: normal;" align="justify" lang="pt-BR"&gt;            &lt;style type="text/css"&gt;  &lt;!--   @page { margin: 2cm }   TD P { margin-bottom: 0cm }   P { margin-bottom: 0.21cm }  --&gt;  &lt;/style&gt;  &lt;table style="width: 496px; height: 946px; color: rgb(0, 0, 0);" border="1" cellpadding="4" cellspacing="0"&gt;  &lt;col width="78"&gt;  &lt;col width="128"&gt;  &lt;col width="140"&gt;  &lt;col width="130"&gt;  &lt;tbody&gt;&lt;tr valign="top"&gt;   &lt;td width="78"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="128"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;b&gt;ML&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="140"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;b&gt;Scheme&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="130"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;b&gt;Python&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr valign="top"&gt;   &lt;td width="78"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;b&gt;Simplicidade    Global&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="128"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;paradigma    imperativo&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;padronização&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;biblioteca    padrão extensa e inconsistente entre versões&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="140"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Minimalista&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;padronização&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;tipos    de dados latentes&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="130"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Minimalista&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;paradigma    imperativo&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;unificação    entre tipos e classes&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr valign="top"&gt;   &lt;td width="78"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;b&gt;Instruções    de controle&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="128"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;estruturas    semelhante as linguagens imperativas&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;encontro    de padrões&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Compreensão    de listas&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="140"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Recursividade    para repetição&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Recursividade    eficiente&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Estruturas    de seleção simples e múltipla&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="130"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Possui    um conjunto reduzido de estruturas de controle: for, while, if e    with.&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Recursividade    limitada&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Compreensão    de listas&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr valign="top"&gt;   &lt;td width="78"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;b&gt;Suporte    a abstração&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="128"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;tratam    as funções como tipos de dados de primeira ordem&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;programação    funcional&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;estruturas    e registros&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="140"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;tratam    as funções como tipos de dados de primeira ordem&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;programação    funcional&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;listas    dinâmicas&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="130"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Tudo    é objeto e tipo de dado de primeira ordem &lt;/span&gt;    &lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;orientação    a objetos elegante e consistente&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Herança    múltipla&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr valign="top"&gt;   &lt;td width="78"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;b&gt;Verificações    de Tipos&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="128"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Estaticamente    tipada&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;inferência    dos tipos&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;não    realiza a conversão implícita de tipos&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;permite    a declaração do tipo de uma variável&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="140"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Dinâmicamente    tipada&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;inferência    dos tipos&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;não    realiza a conversão implícita de tipos&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;tipos    de dados latentes&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="130"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Dinâmicamente    tipada&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;inferência    dos tipos&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;não    realiza a conversão implícita de tipos&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;tipos    de dados latentes&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" style="margin-left: 0.58cm;" lang="pt-BR"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr valign="top"&gt;   &lt;td width="78"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;b&gt;Manipulação    de Exceções&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="128"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;suporte    nativo ao tratamento de exceções.&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;Exceções    podem conter valores e eventos associados&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td width="140"&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;suporte    nativo ao tratamento de exceções.&lt;/span&gt;&lt;/p&gt;    &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;suporte     implícito  integrado ao interpretador de comandos.&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;&lt;td width="130"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;h2 class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Times New Roman,serif;"&gt;&lt;span style="font-size:130%;"&gt;&lt;i&gt;&lt;b&gt;9. Bibliografia&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt; &lt;p class="western"&gt;SEBESTA, Robert W. , Concepts of Programming Languages 7 ed.&lt;/p&gt; &lt;p class="western" lang="pt-PT"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt;WATT, David A. , Programming Language Concepts and Paradigms 1 ed.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western"&gt;DRAKE, Fred L., editor, Python Reference Manual - &lt;strong&gt;&lt;span style=""&gt;Release 2.5&lt;/span&gt;&lt;/strong&gt;&lt;span style=""&gt;&lt;br /&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style=""&gt;19th September, 2006 &lt;/span&gt;&lt;/strong&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://docs.python.org/ref/ref.html"&gt;&lt;span style=""&gt;http://docs.python.org/ref/ref.html&lt;/span&gt;&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western"&gt;&lt;span lang="en-US"&gt;HARPER, Robert, Programming in Standard ML (WORKING DRAFT OF AUGUST 25, 2006.) - &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://www.cs.cmu.edu/%7Erwh/smlbook/online.pdf"&gt;&lt;span lang="en-US"&gt;http://www.cs.cmu.edu/~rwh/smlbook/online.pdf&lt;/span&gt;&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western"&gt;ABELSON, Harold, &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;span style="font-style: normal;"&gt;Structure and Interpretation  of Computer Programs, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book.html"&gt;&lt;span style="font-size:100%;"&gt;&lt;span lang="pt-BR"&gt;&lt;span style="font-style: normal;"&gt;http://mitpress.mit.edu/sicp/full-text/book/book.html&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" lang="pt-PT"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt;Wikipédia, a enciclopédia livre,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_funcional"&gt;&lt;span style="font-size:85%;"&gt;&lt;span lang="pt-PT"&gt;http://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_funcional&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://en.wikipedia.org/wiki/Python_%28programming_language%29"&gt;&lt;span style="font-size:85%;"&gt;&lt;span lang="pt-PT"&gt;http://en.wikipedia.org/wiki/Python_%28programming_language%29&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;span style="font-size:85%;"&gt;&lt;span lang="pt-PT"&gt;http://en.wikipedia.org/wiki/Scheme_%28programming_language%29&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://en.wikipedia.org/wiki/ML_language"&gt;&lt;span style="font-size:85%;"&gt;&lt;span lang="pt-BR"&gt;http://en.wikipedia.org/wiki/ML_language&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" lang="pt-BR"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt;acessado em 10/11/2006.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="western" style="font-style: normal;" lang="pt-BR"&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4314281331790852832-943481272096582833?l=python-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/943481272096582833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4314281331790852832/posts/default/943481272096582833'/><link rel='alternate' type='text/html' href='http://python-blog.blogspot.com/2007/04/python-scheme-e-ml-uma-anlise.html' title='Python, Scheme e ML - Uma análise comparativa das linguagens de programação'/><author><name>Rudá Porto Filgueiras</name><uri>http://www.blogger.com/profile/10439613799348846612</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_jpF7Z32tHFQ/SeKOD1pCaGI/AAAAAAAAAmk/Hth5eva3nBM/S220/ruda_retrato-ruda-peq.jpg'/></author></entry></feed>
