Pequeno experimento em Forth

# deve chegar até *

Recentemente comecei a brincar um pouco com Forth, uma linguagem de programação onde todo o estado — até onde eu aprendi — é armazenado numa pilha. Para isso estou utilizando o livro Starting Forth.

Fiz um pequeno programa para ver como eu conseguiria armazenar o estado de um jogo simples utilizando apenas uma pilha (duas, tecnicamente). Você pode encontrar o código completo no github, mas aqui vai o núcleo dele:


: INSTRUCTIONS
    ." UTILIZE J (BAIXO) K (CIMA) L (DIREITA) H (ESQUERDA) PARA SE MOVER "
    CR ;

: RENDER-COORDINATE ( fx fy px py cx cy )
    4DUP MATCH-COORDINATES IF 35 EMIT DROP DROP ELSE
         >R >R 2OVER R> R> MATCH-COORDINATES IF 42 EMIT ELSE
	 32 EMIT
    THEN THEN ;
: RENDER-LINE ( fx fy px py ly )
    >R MAX-X MIN-X DO I J RENDER-COORDINATE LOOP R> DROP CR ;
: RENDER ( fx fy px py )
    PAGE MAX-Y MIN-Y DO I RENDER-LINE LOOP ;
: CHECK-WIN ( fx fy px py )
    4DUP MATCH-COORDINATES ;
: GAME-LOGIC ( fx fy px py )
    RENDER CHECK-WIN IF ." VOCÊ VENCEU!! " 2DROP 2DROP QUIT ELSE INSTRUCTIONS THEN ;

Na pilha ficam os valores que representam as coordenadas do jogador e da comida: (FoodX FoodY PlayerX PlayerY), e eventualmente as coordenadas sendo renderizadas. O jogador é exibido como “#” (35 EMIT), enquanto a comida é exibida como “*” (42 EMIT). Se as coordenadas do jogador baterem com as coordenadas da comida, o jogo acaba.

Auditorium: Sistema de Agendamento de Auditórios

O Auditorium é um sistema de agendamento de auditórios feito sob demanda para o CEULJI/Ulbra por mim e pelo Valdeir Cesconeto, nas matérias de Tópicos Especiais III e Desenvolvimento WEB. Conta com um sistema de permissões em três níveis (administrador, secretária, coordenador), notificações em tempo real, além de um chat.

O sistema começou a ser utilizado semana passada, ainda em fase de testes. As imagens abaixo são da versão 1.0, que é o estado em que ele foi apresentado como trabalho final nas disciplinas mencionadas no parágrafo anterior; muitas mudanças foram feitas desde então.

Você pode encontrar o código e mais detalhes no repositório no Github.

Criei um servidor de emails

Semana passada eu criei um servidor de emails utilizando o iRedMail, e agora posso receber emails em contato@evandromurilo.com, por exemplo. O servidor é uma instância EC2 na Amazon AWS rodando Ubuntu 16.04.

Ainda não personalizei o visual, mas já configurei o certificado TLS, além de todos os registros DNS necessários (MX, SPF, DKIM, DMARC). O RoundCube me surpreendeu bastante, acho até que prefiro acessar o email por meio dele do que por IMAP através do Outlook, por exemplo.

MPanel (componente para Java Swing)

MPanel é uma subclasse do JPanel, que age como um gerenciador de layout. A ideia é ter um visual parecido com o que você conseguiria utilizando uma série de BoxLayouts, mas com a facilidade de um GridLayout. É no fundo um JPanel com um BoxLayout na vertical e uma série de JPanels com BoxLayouts na horizontal.

Exemplo:

cm

MPanel panel = new MPanel();
panel.setMargin(15, 15);
panel.defaultVGap = 5;
panel.defaultHGap = 15;
panel.lblSize = new Dimension(170, 30);

panel.add(0, lblNome, txtNome);
panel.add(1, 0, 15, 15, lblTotalV, txtTotalV);
panel.add(2, lblC);
panel.add(3, 0, 15, 15, rb1, rb2, rb3, rb4);
panel.add(4, lblValorC, txtValorC);
panel.add(5, lblS, txtS);
panel.add(6, 0, 15, 15, lblSC, txtSC);
panel.add(7, btnCalc);

panel.render();
add(panel);

Para obter mais detalhes, acesse o repositório no Github.

Watson Conversation

Eu e o Valdeir Cesconeto estamos criando um chatbot sobre o CEULJI/Ulbra utilizando o Watson Conversation, um serviço da IBM, para o trabalho final da disciplina de Inteligência Artificial, que é ministrada pelo professor Jones. Estamos ficando bastante satisfeitos com o resultado, ainda mais por ser nossa primeira tentativa de fazer algo do tipo.

Watson Conversation

Algoritmos de busca em grafo em Ruby

Parecido com o parser de grafos que fiz em C, só que este funciona com grafos valorados. Implementei breadth-first search (busca em amplitude), depth-first search (busca em profundidade) e o algoritmo de Dijkstra. Está tudo no repositório graph_ruby, junto com a minha primeira tentativa de gerar documentação com o rdoc.

Script para renomear PDFs

Meu primeiro script em Ruby que faz algo útil, feito para ser utilizado a partir do shell. Utilizei a biblioteca pdf-reader. Só funciona se o pdf tiver informações de título e autor. Por padrão ele renomeia o pdf para o formato “título [autor]”, se quiser mudar é só alterar a linha 15.

Exemplo de uso (tenta renomear todos os arquivos pdf do diretório atual):
ruby pdf_rename.rb *.pdf

require 'pdf-reader'

if ARGV.empty?
    puts "Usage: ruby pdf_rename.rb 'file.pdf'"
    exit 1
end

ARGV.each do |arg|
    filename = arg
    nfilename = ""

    begin
        PDF::Reader.open(filename) do |reader|
            if reader.info[:Author] && reader.info[:Title]
                nfilename = reader.info[:Title] + " [" + reader.info[:Author] + "].pdf"
            end
        end
    rescue
        puts "Could not read PDF '#{filename}'."
        next
    end

    if nfilename != ""
        begin
            File.rename(filename, nfilename)
        rescue
            puts "Could not rename file '#{filename}' to '#{nfilename}'."
            next
        end
    else
        puts "Could not extract author and title information from PDF '#{filename}'."
        next
    end
end

Repositórios atualizados

Nota

Fiquei 4 dias sem internet no meu computador e acabei quase reescrevendo todos os meus repositórios:

  • a hash table agora usa void * no lugar de double para os valores (para mais flexibilidade);
  • adicionei uma implementação de lista encadeada ao repositório m;
  • o parser de grafos agora tem mais funções de busca, utiliza a nova implementação de lista encadeada e foi adicionado um programa que pode ser utilizado para testar se uma configuração de grafo está correta;
  • o parser de gramáticas livres de contexto agora utiliza a hash table para guardar as definições, além de também fazer uso da implementação de lista encadeada.
(este post é patrocinado pelo Valdeir, que me emprestou um adaptador wifi USB)

Gerador de Nuvens de Palavras

Apresentei em um trabalho na disciplina de I.A., junto com o Valdeir Cesconeto, um script em Python que gera uma nuvem de palavras customizada a partir de um tema qualquer escolhido pelo usuário. Para isso utilizamos as bibliotecas wikipedia e word_cloud, além de fazer um web scraping do Google Imagens. O código precisa de revisões antes de ser postado, mas gostei do resultado e por isso já deixo aqui algumas das minhas imagens geradas favoritas.