goncin@wordpress.com:~$ _

Linux, programação e toda sorte de nerdices

Arquivos Mensais: dezembro 2010

Meu ambiente de trabalho em 7 itens

Não sei direito onde a coisa começou. Recebi do Alexandre Gaigalas (@alganet) e, num segundo momento, também do Bruno Roberto Gomes (@brgomes) a incumbência de compartilhar 7 itens do meu ambiente de trabalho. Tanto um quanto o outro já escreveu sobre o mesmo tema, tendo recebido a tarefa de outras pessoas. Pesquisei um pouco a respeito, e descobri no blog do Duodraco que a ideia é fazer disso um meme. Então vamos lá. 🙂

Meu ambiente de trabalho. Não reparem a bagunça :P

Meu ambiente de trabalho. Não reparem a bagunça 😛

1) Um Ubuntu altamente personalizado

Há cerca de um ano, encarei o desafio de abandonar o Windows como plataforma de desenvolvimento e usar Linux para esse propósito. Escolhi a distribuição Ubuntu, que já usava nos meus computadores pessoais e com a qual já estava familiarizado.

Como gosto de deixar as coisas bem do meu jeito, meu Ubuntu, ao menos visualmente, em nada se parece com uma instalação recém-feita desse sistema operacional. Entre as personalizações que costumo fazer na interface, estão:

  • a troca do tema padrão (atualmente, uso o tema Orta com os ícones Faenza);
  • a redução para apenas um painel, o inferior, e o utilização do Docky na parte superior da tela para lançamento de aplicativos;
  • o applet Cardápio no lugar do tradicional menu do GNOME; e
  • o applet Dockbarx em substituição à lista de janelas/tarefas.

Minha instalação corrente começou na versão Karmic Koala (9.10), foi atualizada para a Lucid Lynx (10.04 LTS) e, no momento, corresponde à versão mais atual do SO, Maverick Meerkat (10.10). Tudo isso sem precisar formatar, comprovando a estabilidade do ambiente. Um ano, três versões e tudo rodando redondo. Exceto, é claro, quando eu tento fazer alguma atualização bleeding edge e ferro alguma coisa – a maior vítima é o driver da placa de vídeo. Mas #SouDev e não desisto nunca, daqui a pouco ponho o sistema de volta pra funcionar.

2) Netbeans para desenvolvimento PHP

Sempre estive em busca do IDE perfeito e open source (ou, pelo menos, freeware) para desenvolver em PHP (havia até um post meu sobre isso numa rede do Ning, mas todo mundo sabe o que aconteceu…). A meu ver, o estado da arte em termos de ambiente integrada para essa linguagem ainda não foi atingido. Contudo, o Netbeans evoluiu rapidamente e é, nos dias atuais, o que mais se aproxima do Olimpo. Tem, como vantagens, o fato de ser open source, multiplataforma (ainda que “multiplataforma”, aqui, seja sinônimo de Java) e relativamente leve, consideradas as circunstâncias. Por outro lado, ser baseado em Java, após a aquisição da Sun pela Oracle, é algo no mínimo temerário. Não por acaso, aguardo ansiosamente que o KDevelop com suporte a PHP amadureça e se torne logo utilizável. Pelo que já vi deste último, vem coisa boa por aí.

Netbeans IDE 7.0 Beta

Netbeans IDE 7.0 Beta

Quem estiver interessado no meu esquema (escuro) de cores para o Netbeans, pode baixá-lo aqui e importá-lo em Ferramentas > Opções > Importar (no canto inferior esquerdo do diálogo).

3) Wine, PlayOnLinux e Winetricks

Esta tríade de utilitários permite executar no Linux muitos programas da plataforma Windows. Se o Wine é uma camada de tradução das bibliotecas de runtime do Windows, o PlayOnLinux é um front-end que, por intermédio de scripts, automatiza a instalação de vários aplicativos comuns (algumas versões do Microsoft Office e do Photoshop, por exemplo), embora seu foco seja a instalação de jogos. Por seu turno, o Winetricks é um script que localiza, baixa e instala muitas das dependências mais recorrentes de programas Windows, como as fontes TrueType da Microsoft, os MDAC, os runtimes do Visual Basic e do Visual C++, etc.

PSPad editor rodando via Wine

PSPad editor rodando via Wine

Dessa forma, consigo trabalhar, no Ubuntu, com alguns bons programas feitos para a plataforma do Tio Bill, tais como o PSPad, o EMS SQL Manager 2010 for MySQL e o EMS SQL Manager 2008 for SQL Server.

4) Firefox com WebDeveloper Toolbar e outras extensões

Como desenvolvedor web, tenho um bom número de navegadores instalados (o Infernet Explorer roda na VM, veja mais abaixo). Meu navegador principal continua sendo o Firefox, porque muitas de suas extensões ainda não encontram paralelos para o Google Chrome – apesar de todos os predicados deste. Dentre as extensões que mais utilizo, estão a WebDeveloper Toolbar e a DownThemAll!. Um recurso nativo particularmente interessante do navegador, para mim, é o Console de Erros Javascript – pego muitos erros por ele, sem sequer precisar acionar o Firebug.

Firefox com WebDeveloper Toolbar em ação

Firefox com WebDeveloper Toolbar em ação

5) VMWare Player

OK, esse não é open source, é só freeware. Trabalho uma Instituição de Ensino Superior com foco em Ciências Sociais Aplicadas, ou, traduzindo, o povo daqui adora uma planilha. E, para manter a compatibilidade, eu, o único linuxista dessas bandas, não posso viver só de OpenOffice.org. Necessito utilizar o Microsoft Office, versão 2010, adquirida pela Instituição e que (ainda) não consegui instalar via Wine. Há outras cositas também que me forçam a ter um ambiente Windows à disposição, como Photoshop, Delphi (para alguns sistemas legados) e Crystal Reports.

Durante muito tempo, deixei o VirtualBox , da Sun Oracle, encarregado das minhas máquinas virtuais. Sem embargo, dois fatores fizeram com que eu passasse a utilizar o VMWare Player: (1) este divide o disco virtual em vários arquivos, facilitando o processo de backup e (2) com ele, os efeitos visuais funcionam, ao contrário do que ocorria com o VirtualBox. Pode parecer frescura, mas, para mim, os efeitos visuais são fundamentais, principalmente quanto a testá-los em outras distros Linux e versões futuras do Ubuntu, coisa que faço com frequência. Além do mais, suspender e recuperar uma VM mostrou-se sensivelmente mais rápido no VMWare Player, relativamente ao VirtualBox.

VMWare Player rodando Windows 7

VMWare Player rodando Windows 7

6) Gnome-RDP Remmina

UPDATE: seguindo o conselho do visitante BlueHood, expresso em seu comentário mais abaixo, acabei por trocar o Gnome-RDP pelo Remmina, até então desconhecido para mim. Vale a pena conhecê-lo! =D

Há muitos servidores rodando Windows Server aqui. E a rede toda é baseada no Active Directory. Felizmente, o Ubuntu conta com ferramentas para acesso remoto a máquinas Windows utilizando o protocolo RDP (mais conhecido por “Terminal Services”). O Gnome-RDP Remmina é simples, objetivo, e cumpre muito bem o seu papel, e ademais suporta também os protocolos VNC, SFTP e SSH. Para quem utiliza KDE, o utilitário equivalente é o KRDC.

O Remmina acessando um servidor Windows via Terminal Services

O Remmina acessando um servidor Windows via Terminal Services

7) The Gimp

OK, OK, passo longe de ser um designer. Mas nem por isso estou livre de usar softwares de edição gráfica. Tenho o Photoshop instalado na VM, e <vergonha-propria mode="on"> desse programa sei utilizar menos de 1% do seu potencial </vergonha-propria>.

Quando a tarefa com imagens não é complexa o bastante para justificar a subida da VM à memória, faço uso do Gimp, sempre em Single-Window mode. Com ele, consigo fazer as coisas mais triviais, como redimensionamento e conversão de formatos, recortes e strokes. Enfim, no quesito “software gráfico” sou um mero principiante, em início de aprendizado, esperando absorver novas habilidades à medida que as necessidades surjam.

The Gimp e o meu papel de parede atual

The Gimp e o meu papel de parede atual

Bonus track: Terminal + Guake

Nenhum desenvolvedor que se preze deve temer a linha de comando. Algumas tarefas (como, por exemplo, atualizar o Ubuntu) são muito mais simples via terminal. E o Guake, uma quase-unanimidade, torna a praticidade do terminal ainda mais prática, se é que me entendem. Após instalado e carregado, basta um F12 para que uma janela de terminal se descortine com elegância à frente de seus olhos.

O Guake trabalhando

O Guake trabalhando

Passando a bola adiante

Para manter o espírito do meme, passo a bola para o Francisco Prado (@fr_prado), o Henrique Lobo Weissmann (@loboweissmann), o Bruno Bemfica (@CodeAddicted) e o Fábio Vedovelli (@vedovelli). Compartilhem sua forma de trabalho, pessoal! 🙂

Anúncios

Aprendendo a pensar com expressões regulares

Vivendo e aprendendo. Parece não haver máxima mais certeira quando se trata da vida de um #SouDev 😉 .

No meu último post, no qual tratei sobre normalização de nomes próprios, eu havia utilizado uma expressão regular para testar se determinada parte de um nome corresponde a um numeral romano. Antes de encontrar a expressão regular para fazer o teste, eu já estava quebrando a cabeça para escrever uma rotina para fazer a mesmíssima tarefa. Eis o que eu pensava em fazer:

  • Testar se a substring continha apenas caracteres válidos para números romanos – no caso, ‘I’, ‘V’, ‘X’, ‘C’, ‘D’ e ‘M’. Essa era a parte fácil.
  • Determinar se os ditos caracteres estavam na ordem e na quantidade corretas para representar um número romano válido – e era aí que a porca torcia o rabo.

Pelo meu método de raciocínio costumeiro, essa rotina teria alguns loops e outros tantos ifs, e, com certeza, não teria menos que dez linhas de código PHP. Ao pesquisar sobre a estrutura dos números romanos, deparei-me com a expressão regular que você pode observar na linha 18 da listagem daquele post (e que foi utilizada na linha 100). Com ela, resolvi meu problema em uma única linha.

Se eu havia sido esperto nessa parte do código, cometi uma sobrinhagem na parte em que eu precisava substituir todas os espaços duplos por espaços simples. Desde sempre, utilizei um laço para substituir todas as ocorrências de dois espaços por um único espaço, até que não houvesse mais nenhum daqueles. Desta forma:

<?php
while(mb_strpos($nome, self::NN_ESPACO_DUPLO) != false)
      $nome = mb_ereg_replace(self::NN_ESPACO_DUPLO, self::NN_ESPACO, $nome);

Isso funciona assim: se houver quatro espaços contíguos, na primeira passagem esses quatro tornar-se-ão dois. Somente na segunda passagem é que esses dois espaços serão reduzidos a apenas um, que é o resultado desejado. Quanto mais espaços contíguos, mais repetições serão necessárias.

E tudo isso se resolve, de forma muito mais elegante e eficiente, também com uma expressão regular, e em uma única instrução. E o melhor: independentemente da quantidade de espaços contíguos.

<?php
$nome = mb_ereg_replace('\s+', ' ', $nome);

A mágica reside na expressão regular \s+. O que ela significa? \s encontra espaços em branco, e o modificador + indica uma ou mais ocorrências. Era tudo o que eu precisava. E já corrigi o código do post anterior.

As expressões regulares, ao mesmo tempo que encantam com seu poder, também costumam assustar pela sua relativa complexidade. Antes de continuar, vale um definição do que são expressões regulares, provida pela Wikipédia:

Em ciência da computação, uma expressão regular (ou o estrangeirismo regex, abreviação do inglês regular expression) provê uma forma concisa e flexível de identificar cadeias de caracteres de interesse, como caracteres particulares, palavras ou padrões de caracteres. Expressões regulares são escritas numa linguagem formal que pode ser interpretada por um processador de expressão regular, um programa que ou serve um gerador de analisador sintático ou examina o texto e identifica partes que casam com a especificação dada.

Creio que isso esclarece (quase) tudo, mas vou colocar as coisas em termos mais práticos. A palavra regular provém do latim regula, -ae, que significa, ao mesmo tempo, regra e régua. Isso permite afirmar que as expressões regulares têm aplicação quando precisamos encontrar ou extrair ocorrências de caracteres de um texto, no qual ditos caracteres obedecem a determinados padrões (regra) e/ou se encontram em posições previsíveis (régua). E texto, nesse sentido, significa tanto um campo de número de telefone quanto uma cadeia com alguns milhares de caracteres.

Portanto, da próxima vez em que você precisar encontrar ou extrair determinadas substrings de um texto, e seu código começar a ficar mais complexo do que deveria, considere utilizar expressões regulares. Todas as linguagens importantes, hoje em dia, têm algum tipo de suporte a elas. É o tipo de conhecimento que vale o tempo em que se investe nele – uma hora gasta para aprendê-las pode poupar algumas de trabalho brabo 😛 .

Para aprender:

Normalizando nomes próprios com PHP

Salve, pessoal! Para compensar minha relativa inatividade nos últimos tempos, volto hoje com um post mais denso, que acredito e espero que seja útil a toda a comunidade #SouDev.

Vou tratar sobre normalização de nomes próprios. Norma… o quê? 😕

O problema

Algo que sempre achei horroroso em bancos de dados é a falta de padrão na capitalização (uso de letras maiúsculas e minúsculas) em nomes próprios – sejam de pessoas, logradouros ou localidades. Sobrinhos, geralmente, gravam no BD esses dados como foram coletados ou digitados, e programadores preguiçosos, no mais das vezes, limitam-se a aplicar um strtoupper() ou equivalente e entopem o cadastro com LETRAS MAIÚSCULAS. Na sinceridade, não sei qual das duas situações deixa o banco mais feio. O uso indiscriminado de letras maiúsculas, vale lembrar, cansa os olhos e dificulta a leitura após um certo tempo.

Já vi um caso em que a “saída” foi o uso de ucfirst() puro e simples. Menos mau, mas tão indolente quanto.

Fazer uma normalização, transformando “JOSÉ DA SILVA PEREIRA E SOUZA” em “José da Silva Pereira e Souza” não é uma tarefa difícil, desde que o desenvolvedor esteja atento a alguns detalhes.

A solução

Criei uma classe com um método estático em PHP (para não fugir ao paradigma da orientação a objetos) para propor minha solução. Expliquei, tanto quanto pude, todas as etapas nos comentários do código. Trata-se, em última instância, da implementação de um algoritmo relativamente simples, que não deve oferecer dificuldades para ser portado para outras linguagens. Se você utiliza PHP, de agora em diante aplique GUtils::normalizarNome($nome) e tenha um cadastro mais bonitinho e legível! 😛 Se não, implemente a ideia em sua linguagem favorita. 😉

<?php
/**
 * Classe contêiner para métodos estáticos de utilidades variadas
 *
 * @author goncin (goncin ARROBA gmail PONTO com)
 */
class GUtils {

  /**
   * Constantes definidas para melhor legibilidade do código. O prefixo NN_ indica que
   * seu uso está relacionado ao método público e estático normalizarNome().
   */
  const NN_PONTO = '\.';
  const NN_PONTO_ESPACO = '. ';
  const NN_ESPACO = ' ';
  const NN_REGEX_MULTIPLOS_ESPACOS = '\s+';
  const NN_REGEX_NUMERO_ROMANO =
    '^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$';

   /**
   * Normaliza o nome próprio dado, aplicando a capitalização correta de acordo
   * com as regras e exceções definidas no código.
   * POR UMA DECISÃO DE PROJETO, FORAM UTILIZADAS FUNÇÕES MULTIBYTE (MB_) SEMPRE
   * QUE POSSÍVEL, PARA GARANTIR SUA USABILIDADE EM STRINGS UNICODE.
   * @param string $nome O nome a ser normalizado
   * @return string O nome devidamente normalizado
   */
  public static function normalizarNome($nome) {

    /*
     * A primeira tarefa da normalização é lidar com partes do nome que
     * porventura estejam abreviadas,considerando-se para tanto a existência de
     * pontos finais (p. ex. JOÃO A. DA SILVA, onde "A." é uma parte abreviada).
     * Dado que mais à frente dividiremos o nome em partes tomando em
     * consideração o caracter de espaço (" "), precisamos garantir que haja um
     * espaço após o ponto. Fazemos isso substituindo todas as ocorrências do
     * ponto por uma sequência de ponto e espaço.
     */
    $nome = mb_ereg_replace(self::NN_PONTO, self::NN_PONTO_ESPACO, $nome);

    /*
     * O procedimento anterior, ou mesmo a digitação errônea, podem ter
     * introduzido espaços múltiplos entre as partes do nome, o que é totalmente
     * indesejado. Para corrigir essa questão, utilizamos uma substituição
     * baseada em expressão regular, a qual trocará todas as ocorrências de
     * espaços múltiplos por espaços simples.
     */
    $nome = mb_ereg_replace(self::NN_REGEX_MULTIPLOS_ESPACOS, self::NN_ESPACO,
      $nome);

    /*
     * Isso feito, podemos fazer a capitalização "bruta", deixando cada parte do
     * nome com a primeira letra maiúscula e as demais minúsculas. Assim,
     * JOÃO DA SILVA => João Da Silva.
     */
    $nome = mb_convert_case($nome, MB_CASE_TITLE, mb_detect_encoding($nome));

    /*
     * Nesse ponto, dividimos o nome em partes, para trabalhar com cada uma
     * delas separadamente.
     */
    $partesNome = mb_split(self::NN_ESPACO, $nome);

    /*
     * A seguir, são definidas as exceções à regra de capitalização. Como
     * sabemos, alguns conectivos e preposições da língua portuguesa e de outras
     * línguas jamais são utilizadas com a primeira letra maiúscula.
     * Essa lista de exceções baseia-se na minha experiência pessoal, e pode ser
     * adaptada, expandida ou mesmo reduzida conforme as necessidades de cada
     * caso.
     */
    $excecoes = array(
      'de', 'di', 'do', 'da', 'dos', 'das', 'dello', 'della',
      'dalla', 'dal', 'del', 'e', 'em', 'na', 'no', 'nas', 'nos', 'van', 'von',
      'y'
    );

    for($i = 0; $i < count($partesNome); ++$i) {

      /*
       * Verificamos cada parte do nome contra a lista de exceções. Caso haja
       * correspondência, a parte do nome em questão é convertida para letras
       * minúsculas.
       */
      foreach($excecoes as $excecao)
        if(mb_strtolower($partesNome[$i]) == mb_strtolower($excecao))
          $partesNome[$i] = $excecao;

      /*
       * Uma situação rara em nomes de pessoas, mas bastante comum em nomes de
       * logradouros, é a presença de numerais romanos, os quais, como é sabido,
       * são utilizados em letras MAIÚSCULAS.
       * No site
       * http://htmlcoderhelper.com/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression/,
       * encontrei uma expressão regular para a identificação dos ditos
       * numerais. Com isso, basta testar se há uma correspondência e, em caso
       * positivo, passar a parte do nome para MAIÚSCULAS. Assim, o que antes
       * era "Av. Papa João Xxiii" passa para "Av. Papa João XXIII".
       */
      if(mb_ereg_match(self::NN_REGEX_NUMERO_ROMANO,
        mb_strtoupper($partesNome[$i])))
        $partesNome[$i] = mb_strtoupper($partesNome[$i]);
    }

    /*
     * Finalmente, basta juntar novamente todas as partes do nome, colocando um
     * espaço entre elas.
     */
    return implode(self::NN_ESPACO, $partesNome);

  }

}
const NN_PONTO = ‘\.’;
const NN_PONTO_ESPACO = ‘. ‘;
const NN_ESPACO = ‘ ‘;
const NN_REGEX_MULTIPLOS_ESPACOS = ‘\s+’;
const NN_REGEX_NUMERO_ROMANO =
‘^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$’;
%d blogueiros gostam disto: