logo
Links | Contato | Busca no site | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog


Talvez você ache interessante ver a lista dos melhores posts organizados por categoria, ou uma lista com todos eles.

Meu caso com o Python, parte 2

continuação da parte 1

Com essa minha experiência com Python cheguei à uma conclusão interessante. Sou um apaixonado por programação e suas linguagens, não necessariamente apaixonado por C++. A parte do meu cérebro que responde pelo C++ se sente um pouco traída, já que a exclusividade acaba. Mas a parte que cuida do bom senso fica cada dia mais feliz. Não sendo eu somente um fanático programador C++, passo cada dia mais a confiar na minha (possível) imparcialidade e bom senso quando o assunto é programação. E minha parte C++ fica mais feliz ainda por isso ser uma evidência de que escolhi o C++ não porque é algo complicado somente para nerds e escovadores de bit, e sim porque tem suas inúmeras qualidades e é, indiscutívelmente, a melhor ferramenta disponível para determinados tipos de projetos. Eu sempre escrevi sobre usar a melhor ferramenta disponível para sua tarefa. Mas talvez minha relutância em usar algo que não C++ falava contra mim, apesar de fazer todo o sentido. Tudo resolvido agora. :-)

Ouvi uma história uma vez que resume tudo:

Imagine um carro de Formula 1. O volante é muito sensível. Quando você pisa no acelerador, ele arranca e você cola no banco. Se você não freia com cuidado, é quase arremessado para fora do carro. Ele é desconfortável, apertado, faz bastante barulho. Só que ele é o mais rápido que existe. Coisa para profissionais. Assim é o C++.

Coisa para profissionais. Quando você treina bastante, é o melhor carro do mundo. Mas usar um Formula 1 para fazer compras, no trânsito de São Paulo, não é viável. É muito legal, é muito divertido, mas pouco viável.

Lembre-se: não é lei do mínimo esforço. É a lei de o esforço necessário, de não desperdiçar o esforço. É sobre isso a frase "usar a ferramenta certa para o problema certo". Note que não estou dizendo que só percebi isso graças ao Python, mas digamos que o Python me parece o melhor carro de passeio que existe para fazer compras no supermercado... :-)

Algumas coisas que eu gostei muito no Python em relação ao C++ e aos wannabes (C#/Java):

  • O ciclo while(1){arruma-compila-debuga} quase desaparece. Você vai escrevendo código no console e testando, em runtime ou não. Funcionou? Copia do console e cola no fontes, um trecho de código já testado.
  • A linguagem é muito legível e simples. Em alguns casos, é uma especificação que roda e funciona. Por isso que existe bastante gente escrevendo protótipos em Python e depois refazendo tudo em C++, depois que o conceito está testado. Eu sou um deles :-)
  • Batteries Included. Quase tudo que você precisa vem na distribuição padrão (como o .NET Framework e as bibliotecas Java, só que com um pouco a mais). Precisa fazer profiling? A distribuição padrão tem 3. Unit Test? Sim, na distribuição padrão. Web Server em Python? Sim também. Regex? Threads? SMTP? XML-RPC? Sockets? Criptografia? XML? Biblioteca de Log? HTTP com tratamento de Cookies? Sim.

E, claro, encontrei também defeitos:

  • Um código feito em Python é bem legível, o que faz com que muito programadores Python relevem a importância dos comentários no código. Minha opinião sobre isso não muda, independente da linguagem.
  • Não existe livro avançado de Python. Estou acostumado com C++, onde existe muitos livros avançados. Os de Python ou são tutoriais ou cookbooks.
  • Sim, é lento em runtime (geralmente mais do que C# ou Java, mas nem sempre). Mas extremamente produtivo (muito mais do que C# ou Java). Ou seja, é bem usado quando não se precisa de performance ou quando o tempo de I/O ou rede é tão grande em relação ao resto do processo que o tempo da linguagem se torna quase desprezível.

Minha opinião pode não valer muito em termos de convencer as pessoas sobre o que o Python pode oferecer. Mas acredito que a opinião do Google, Nasa, ILM, YouTube e outros deve valer um pouco mais. :-)

Pronto, confessei, eu tenho outra (linguagem). Nem foi tão difícil quanto eu pensava...

Em 07/03/2007 11:48 - Comentários (11)

Link para o download do Visual C++ Toolkit 2003

A Microsoft (tá bom, a área de vendas da Microsoft) tem a PÉSSIMA E ESTÚPIDA mania de achar que quando é lançada uma versão de um software, as versões antigas não são mais necessárias, são péssimas e cheias de defeitos. O próprio Bill Gates falou mal do Office 2000 para tentar vender o 2003, por exemplo.

Tratando-se de compiladores C++, é necessário alguns cuidados para carregar em um EXE uma DLL compilada com uma versão diferente. Muitos projetos open source exigem uma versão específica do compilador. Por mais que o Visual C++ Express 2005 seja melhor do que o Visual C++ Toolkit 2003, algumas pessoas precisam dessa versão específica. Que, é claro, é impossível de achar no site da Microsoft.

Ainda bem que alguma boa alma disponibiliza isso. Download do Visual C++ Toolkit 2003, eu testei, funciona.

Em 23/02/2007 19:00 - Comentários (5)

Artigos sobre Unmanaged Vista

Bons artigos sobre o Windows Vista, em raros casos onde o termo .NET não aparece:

Em 23/02/2007 08:47 - Comentários (0)

Meu caso com o Python, parte 1

Acredito que vocês têm percebido que, além de tudo que eu falo, faço e escrevo usando C++, eu tenho falado bastante sobre Python. Além de falar eu tenho estudado muito Python de um ano pra cá, e em alguns projetos tenho usado mais Python do que C++. Como isso foi uma mudança grande para mim, acho que essa experiência pode ser aproveitada por mais pessoas.

Acredito que a maioria dos programadores usam scripts para automatizar tarefas repetitivas. Para algumas tarefas, talvez teria sido melhor fazer um programa completo e compilado, mas foi mais simples migrar um .BAT para um .VBS (ou usar shell script de uma vez...) e ficar remendando ele resolver o problema. Até que você encontra um grande problema: quando seu script começa a ficar maior e mais complexo, você acaba batendo toda hora nos limites das linguagens (foi isso que me fez pular do VB6 para o C++). Tendo esse problema algumas vezes, e lendo sobre todo o hype em cima das ditas linguagens dinâmicas, resolvi estudar se haviam realmente linguagens de script com mais poder de fogo.

Depois de uma pequena procura cheguei a conclusão que haviam dois candidatos: Python e Ruby. Estudando a linguagem pura e simplesmente, achei o Ruby melhor. Comecei a estudar Ruby enquanto lia mais sobre Python. Mas uma coisa muito importante me fez decidir pelo Python: suporte, literatura e bibliotecas. Apesar do Ruby estar crescendo devido ao Ruby On Rails (e ao ótimo marketing do seu criador), o Python já era usado pelo Google, NASA, e por muita gente no Source Forge. Então, por razões mais mercadológicas que puristas, escolhi o Python.

A melhor forma de se estudar uma linguagem é determinar um projeto e trabalhar nele. Essa história de ficar lendo tutorial e fazendo exercícios simples não é lá de muita valia. Foi então que eu decidi migram um script VBScript que eu usava para compilar meus projetos Visual C++ para Python. Esse script encontrava o número de revisão do Subversion, mudava o arquivo de resource para colocar a revisão no FILEVERSION e compilava o projeto. Resultado: 120 linhas de código VBS se transformaram em 20 linhas de código Python. E o código ficou mais claro e mais eficiente. Percebi que fiz uma boa escolha, e isso me animou a migrar outros scripts para Python e a passar o dia com o console Python aberto para automatizar tarefas simples.

continua...

Em 20/02/2007 06:30 - Comentários (7)

Tutorial de STL, parte 5: algoritmos

Hoje vamos falar sobre os algoritmos da STL (algorithms), que nada mais são que as funções template que efetuam algum tipo de operação sobre os itens de um container. Isso mesmo, os tais algorithms nada mais são do que funções. O que os faz especiais é a programação genérica, que permite que um mesmo algoritmo possa ser aplicado a diversos tipos de containers, sem distinção. Dessa forma, ao invés de cada container prover métodos com o algoritmos necessários, todos eles ficam separados e pode ser aplicados a maioria deles.

Para tornar os algoritmos genéricos, precisamos primeiro abstrair os containers. Existem duas formas básicas para resolver isso em C++: usando interfaces e funções virtuais, ou fazendo o chamado "polimorfismo em tempo de compilação", usando templates e concepts, onde ter os métodos 100 23848 0 23848 0 0 8158 0 --:--:-- 0:00:02 --:--:-- 40307 das classes com os mesmos nomes já é suficiente. A primeira opção não se enquadra no conceito C++ de "generic programming", e apesar da segunda se enquadrar, não é possível usá-la com os containers STL. Por exemplo, apesar da maioria dos containers oferecer o método push_back, alguns não o fazem (como o std::map).

Como dito na parte 4 dessa série sobre STL, o conceito de iterators existe para abstrair as particularidades do armazenamento de cada container. Dessa forma, a ação de acessar e percorrer os itens de um container se torna igual para a maioria dos containers. Apesar de não ser possível abstrair todas as características de um container, a abstração da forma de acesso aos itens já é suficiente para que os algortimos funcionem. Além disso, isso torna tudo mais flexível, já que permite que você aplique um algoritmos somente em determinados itens de um container.

Como um trecho de código vale muito mais do que uma lei estúpida feita por alguém mal informado, vamos lá:

#include <vector>
#include <algorithm>
#include <assert.h>
 
//
// esse é o nosso algoritmo que soma um número a
// cada item de um container. Note que durante a execução
// o tipo T será o tipo do iterator, e não do container
//
template<typename T >
void soma_num(T begin, T end, int num)
{
  for(T i = begin; i != end ; ++i)
    *i += num;
}
 
 
int main()
{
  std::vector<int> v;
  std::vector<int> l;
  int arr[10];

  for(int a = 0 ; a < 10 ; ++a)
  {
    v.push_back(a);
    l.push_back(a);
    arr[a] = a;
  }
 
  //
  // vamos somar 10 aos número de todos os containers
  //
  soma_num(v.begin(), v.end(), 10);
  soma_num(l.begin(), l.end(), 10);
 
  //
  // somando 10 somente aos 5 primeiros itens do array
  //
  soma_num(arr, arr + 5, 10);
}

Para maioria dos algoritmos, o acesso a todos os itens do container já á mais do que suficiente. A STL contém diversos algoritmos em várias áreas, entre eles:

  • procurar itens dentro de um container (find, find_if)
  • contar itens que atendem a uma determinada condição (count, count_if)
  • cópia de itens entre containers e trechos de containers (copy, copy_n)
  • o famoso map reduce (transform, accumulate)
  • troca de itens (reverse, swap, rotate)
  • operações com std::set, conjuntos (set_union, set_intersection, set_difference)
  • e muitos outros (min, max, random_shuffle, fill generate)

A lista e documentação dos algoritmos pode ser encontrada na página da SGI ou na MSDN. Segue um exemplo de uso dos algoritmos:

int main()
{
  std::vector<int> v1, v2;
 
  for(int a = 0 ; a < 100 ; ++a)
    v1.push_back(a);
 
  //
  // cria um iterator especial que insere um novo
  // items em um container toda vez que houver 
  // uma atribuição. 
  //
  std::back_insert_iterator<std::vector<int>> bi(v2);
 
  //
  // isso faria um v2.push_back(10);
  // *bi = 10;  
  //
 
  //
  // vamos copiar os itens de um container para outro.
  // o algoritmo copy tem duas linhas: é um loop for
  // que copia todos os itens em sequência. Veja os fontes
  // em stl_algo.h
  //
  std::copy(v1.begin(), v1.end(), bi);
 
  //
  // embaralha o v1
  //
  std::random_shuffle(v1.begin(), v1.end());
 
  //
  // ordena v1
  //
  std::sort(v1.begin(), v1.end());
 
  for(int x = 0 ; x < 100 ; ++x)
  {
    assert(v1[x] == v2[x]);
  }
}

Em 13/02/2007 10:26 - Comentários (0)


Posts anteriores >>
rebarba rebarba
  ::::