O que é?

A extensão Imagick é uma extensão para PHP para criação e modificação de imagens, que usa a API ImageMagick. Está disponível através do PECL ou, apenas para Windows, no site do seu criador, Mikko Koppanen. A API ImageMagick, que é de instalação obrigatória, está disponível no site oficial, para vários sistemas operativos.

Em relação à extensão GD2, bastante comum, o Imagick é mais rápido nalgumas das operações mais comuns: redimensionamentos, filtro sharpen, rotações, cortes, etc. Além disso, tal como está no nome, aplica alguma magia nalgumas operações: sombreados, cantos arredondados, composição de texto e imagem… Apesar de nada disto ser inacessível à extensão GD2, no Imagick será possível fazer a maior parte destas operações em poucas linhas – nalgumas operações, apenas uma linha!

Recentemente, inserido num projecto extenso – e não quero falar sobre isso! – uma das fases consistia em dividir um círculo em fatias, de forma dinâmica. O grafismo é relativamente simples, basta usar uns lineTo’s e uns curveTo’s, tudo pintalgado com uns fills, e a coisa ia fluida. Quanto à matemática inerente, também me parecia bastante simples, basicamente é dividir um círculo completo pelo número de fatias.

O Actionscript, como quase todas as linguagens de programação, trabalha em radianos, o que acaba por ser, até, intuitivo. Aprende-se para aí no 7º ano que um círculo são 2 x PI, que corresponde aos 360 graus. Posto isto, o código era, aparentemente, trivial e croquetes:

// gráfico onde vamos desenhar as fatias
var gfx:Graphics = container.graphics;
// raio da tarte
var raio:Number = oMeuRaio;
// angulo de cada fatia
var angulo:Number = (Math.PI * 2) / numFatias;

// i é incrementado o angulo correspondente às fatias a cada passagem
for(var i:Number = 0; i < (Math.PI * 2); i += angulo)
{
    // mover para o centro do círculo
    gfx.moveTo(0, 0);
    // linha até ao limite da tarte
    gfx.lineTo(raio * Math.cos(i), raio * Math.sin(i));
}

Parece bastante simples e intuitivo, certo? Durante algumas horas, a coisa rolou maravilhosamente. Até que reparei que, nalgumas situações, era desenhada uma fatia extra por cima da primeira. Uma das situações onde isso acontecia era quando a quantidade de fatias era igual a seis. Alguns trace’s mais tarde, dei com o gato e, depois de praguejar durante alguns minutos contra a Adobe, a solução foi feita com um mínimo de esforço. Mas vamos ao gatinho primeiro…

Adoro datas. Sério, é uma das áreas mais fascinantes da programação. Se não acreditam, vejam lá o filme que foi o chamado bug do ano 2000. Até arranjaram um acrónimo fixolas e tudo: Y2K. Mas sobre isso falarei noutro dia, ou então não – até porque vem aí um problema bem mais grave em 2038 (a que alguns já chamam Y2K38 – c’mon, really?).

Aqui há dias relembraram-me o quanto eu gosto de datas. Um tipo – que eu não conheço de lado nenhum – pediu ajuda num fórum para fazer uma função em C que calculasse o número de dias entre duas datas; provavelmente, e tendo em consideração o pedido, para um trabalho da escola, ou coisa que o valha. Devo dizer que fui um bocadinho totó e disponibilizei logo ali a função inteira, quando a ideia de um fórum não é fazer por, mas sim ajudar a fazer.

Seja como for, só me decidi ajudá-lo por considerar o problema interessante; não é algo que seja muito comum hoje em dia, até porque a maior parte das linguagens de programação tem bibliotecas específicas para trabalhar com datas, e esta função é disponibilizada de forma directa. Além disso, vi que as orientações que já lhe tinham dado não eram, nem de perto, nem de longe, o mais eficaz que se podia ser. O problema no meio disto tudo, como não podia deixar de ser, é a existência ou não de anos bissextos no intervalo. Como Arthur C. Clarke colocou de forma hilariante em 3001 – Odisseia Final, “um dia, um dos menores erros de Deus será corrigido e o ano terá 12 meses de 30 dias exactamente iguais”.

Para finalizar a primeira fase desta minha incursão pelas tries, vamos agora colocá-la a fazer alguma coisa de útil. Convenhamos que verificar se uma palavra existe ou não é trabalho fraquinho, tendo em consideração as potencialidades desta estrutura de dados. E uma dessas potencialidades é precisamente construir listagens a partir de verificações parciais. Estas podem servir para auto-completar palavras (como nos telemóveis, motores de busca) e para sistemas de correcção ortográfica, com listas de palavras semelhantes a palavras erradas, isto é, não constantes da lista. A implementação específica deste tipo de sistema está fora do âmbito desta posta, visto que não é trabalho específico da trie; esta, apenas devolve uma lista de palavras partindo de uma incompleta, usando wildcards1.

Começando pelo caso do wildcard ‘?’, correspondente a um caracter naquela posição, uma aproximação naïve seria iterar por todas as letras do alfabeto, incluindo as acentuadas, colocá-las na posição correcta e verificar a existência das palavras resultantes na trie. Salta à vista a inocência deste processo: em primeiro lugar, iterar por todos os caracteres possíveis para a posição incluiria muito mais do que os 26 normais do alfabeto – só em caracteres com diacríticos, seria bem mais do dobro; em segundo lugar, a ocorrência de palavras que obviamente não existem, com quatro consoantes seguidas, por exemplo; em terceiro e último lugar, quando quiséssemos implementar a pesquisa com o wildcard ‘*’, representando vários caracteres, os nossos problemas aumentariam exponencialmente.

Ao reler esta minha posta de ontem, lembrei-me das embedded resources, que costumam ser usadas para a localização de aplicações, mas que nada impede que sejam usadas para transportar o que quer que seja. Embeber um ficheiro de texto seria trivial, e as vantagens seriam potencialmente animadoras – ao arrancar a aplicação, a framework carrega muito mais depressa as resources junto com o executável do que o StreamReader consegue ler um ficheiro externo.

Embeber um ficheiro no Visual Studio é do mais simples que há: no menu de contexto do projecto, escolher a opção Properties, depois a aba Resources. Se não existirem resources, clicar no link que estará bem visível no meio da página, e escolher Add New Text File do dropdown Add Resource.

Visual Studio 2008 - Resources

À pala desta discussão no P@P, fui relembrado, dos confins da memória, desta estrutura: trie. Isto é daquelas coisas que se aprende em Algoritmos e Estruturas de Dados e depois, se não se trabalhar especificamente em motores de busca, gestão documental ou coisa que o valha, nunca mais se vai usar. E assim se perde nos interstícios da memória uma excelente estrutura.

O problema em causa - que não é exactamente o motivo pelo qual me reinteressei pelas tries, mas isso fica para outro dia - era a criação dum sistema que "sugira soluções para palavras cruzadas ou problemas equivalentes". Um dos primeiros passos é, como é lógico, criar um dicionário de palavras passível de ser pesquisado. A Universidade do Minho tem disponível um ficheiro de texto com quase 700.000 palavras (link inválido, neste momento), só faltava mesmo carregá-las e usá-las.

As primeiras respostas a esse tópico foram precisamente no sentido das tries, mas a minha primeira reacção foi trocar a dificuldade de implementação e debugging por uma certa penalidade em tempo de execução na pesquisa, usando um simples array com as palavras e pesquisa binária. Força do hábito.

Depois de levar nas beiças de alguns membros, cá fiz uns testes; acontece que "certa penalidade na pesquisa" era bem mais do que eu tinha previsto ao início - cerca de 9 vezes mais lento, e nem sequer estava a contemplar pesquisas parciais (e também não vai ser nesta posta que me debruçarei sobre isso). Seja então uma trie.

Quando em ambiente web, são várias as soluções para persistência de dados em bases de dados relacionais: desde os mais famosos MySQL, PostgreSQL, SQL Server até verdadeiros monstros poderosíssimos, como Oracle. Mas quando nos viramos para aplicações desktop, já não é bem assim.

Há várias soluções: o supra citado SQL Server, ficheiros MDB do Access… Mas todas têm certos requisitos no sistema onde correm; no mínimo dos mínimos, precisarão da biblioteca de acesso correspondente. Mesmo neste último caso, que já não é mau (SQL Server, por exemplo, requer mesmo a instalação do dito na máquina onde corre – uma versão lite, é certo, mas tem que se instalar), a biblioteca atinge, normalmente, vários  MB.

Na sequência deste post, várias pessoas1 chamaram-me a atenção de algo básico: faltava o valor das apostas na estrutura. Básico, básico, básico.

Podia ter cedido ao caminho mais fácil: apenas uma entidade, com o preço das apostas simples, devidamente localizado. Depois, calculava o valor das apostas múltiplas desdobrando cada múltipla nas suas componentes simples. Mas, quanto mais pensava no assunto, menos correcta me parecia a abordagem. Já ouvi falar de concursos – e não sei se é verdade – em que há vários tipos de apostas simples. Por exemplo, um concurso com três jogos, em que as pessoas escolhem (imaginemos) cinco números de um pote e um número de apenas um dos outros dois potes; há aqui duas apostas simples distintas: cinco do pote A mais um do pote B e cinco do pote A mais um do pote C. Outra razão que me surgiu depois, esta de ordem bem mais prática, seria o acesso directo, sem cálculos, aos preços das múltiplas, com o bónus de poder controlar que apostas são válidas, entre simples e múltiplas, para um dado concurso.

Como tal, o diagrama entidade-associação foi modificado e colocado no respectivo projecto da categoria Jogos de Loto. A imagem que acompanhava o post precedente a este foi retirada, para não existirem confusões e passa a estar só no projecto, que é bem melhor de gerir.

1 a razão pela qual as pessoas – pelo menos, estas quatro – preferem mandar um e-mail ao invés de comentar aqui no blog é algo que me ultrapassa…

Comentários Nenhum comentário Continuar a ler Continuar a ler »

Modelo de processo de desenvolvimento RAD (Rapid Application Development), fase 2: Modelagem dos Dados. É isto que nos ensinam na escola, desde o primeiro momento. E é isto que tantas vezes esquecemos no nosso dia-a-dia de programadores. Not this time.

Quando comecei a desenvolver aplicações para jogos de loto, estas eram extremamente restritivas, apenas para o Euromilhões ou apenas para o Totoloto… Qualquer outro concurso obrigaria a uma reestruturação do código e a uma nova release do software, exclusiva para esse concurso. Como é bom de ver, isso é um bocadinho estúpido – a menos que se tenha em mente uma estratégia de venda ou de branding: continua a ser estúpido dum ponto de vista de desenvolvimento, mas é uma excelente ideia a nível de marketing, sempre são mais produtos para vender. Como não é o meu caso, esqueçam: é só estúpido.

O código, passo a passo, foi sendo melhorado para ser escalável, como deveria ter sido desde o início. O mesmo foi acontecendo à estrutura de dados, abstraindo cada vez mais a mesma duma visão centrada num dado concurso, primeiro, e nos concursos portugueses, depois. Se do Euromilhões para o Totoloto, por exemplo, já há diferenças de estruturação (o Euromilhões é, na realidade, constituído por dois jogos, por exemplo), para totolotarias de outros países havia diferenças abismais. Por exemplo, há uma totolotaria nos Estados Unidos cuja última bola sorteada tem um significado especial e deve ser tratada como um jogo à parte, à semelhança das estrelas no nosso conhecido Euromilhões. Mas há um catch: essa bola é do mesmo pote de onde saíram as outras (cinco ou seis… ou sete, não sei bem). E isto, ainda a procissão vai no adro…

Como já falei aqui, o Wordpress não é a peça central do DreamsInCode. Isso, na altura, levantou alguns problemas de integração. Resolvidos que foram, não me preocupei mais.

À pala da brincadeira com os endereços “humanos” (aqui e aqui), que são usados nos projectos aqui no DreamsInCode, andei a monitorizar-lhes o comportamento no sitemap via Google Webmaster Tools. Qual não é a minha surpresa ao verificar que todas as páginas eram reportadas como 404 Not Found, excepto as do blog. Como é que era possível, se eu via as páginas perfeitamente, em vários browsers e em várias ligações. Olhando para o painel Net do Firebug, certinho, direitinho: lá estava o 404 a olhar para mim, em conjunto com todos os dados da página. WTF?!

 Categorias
 Arquivo
 Projectos em Destaque
 Últimas Postas no Blog
 Últimos Comentários do Blog