quarta-feira, 24 de junho de 2020

Criar seu próprio pacote de R

Criar pacotes é importante para o reuso e compartilhamento de funcionalidades. Vamos utilizar a biblioteca devtools, que a propósito tem uma cheat sheet excelente, além de livros sobre o assunto. Aqui vamos citar apenas os passos necessários para criação de uma biblioteca minimamente. 

Primeiro passo, instalar o pacote devtools (caso não tenha):
install.packages('devtools')
Segundo passo, iniciar um projeto de biblioteca
devtools::create('path/to/folder')
Este comando criará os arquivos DESCRIPTION e NAMESPACE, além da pasta R dentro da sua pasta do projeto. Esta é a estrutura mínima de um pacote. Agora crie um arquivo.R, substituindo arquivo pelo nome que preferir e nele implemente as suas funções
# Uma função bem simples apenas para exemplificar
# '@export
myFunction <- function(x,y)x*y
A documentação do pacote é feita com a biblioteca roxigen2, as suas tags além de permitirem a geração automática da doc também permite-nos lançar mão de recursos da lib devtools que facilitam o processo de criação. Os pacotes devtools e roxygen2 não são obrigatórios para a criação de pacotes, mas facilitam bem o processo. Não escrevo aqui sobre as tags de documentação, segue o link da doc oficial. Contudo é importante falar sobre a tag @export, ela indica para a lib devtools que aquela função marcada deve ser anotada no arquivo NAMESPACE para exportação. As funções que não são anotadas com @export permanecem privadas ao escopo do script. Então utilizamos dois comandos, um para gerar a doc e atualizar NAMESPACE. O seguinte faz o build do pacote.
devtools::document()
devtools::build()

sexta-feira, 12 de junho de 2020

renv & docker

Um projeto pode incluir muita bibliotecas, e estas podem ter n versões. O controle de dependências é fundamental para o correto funcionamento de nossas aplicações. Neste cenário entra o pacote renv . Mas não vamos falar muito sobre ele, e sim mostrar uma solução simples para montar nossas aplicações em containers Docker isolando a aplicação e garantindo que os pacotes corretos serão instalados. Observação importante: Não devemos copiar a pasta renv de dentro do nosso projeto, apenas o arquivo renv.lock.

terça-feira, 11 de julho de 2017

Knockout.js currency formatter.

Aqui trabalhando com knockout.js, criando um custom binding para manter os valores de inputs em formato de Moeda.

quinta-feira, 9 de fevereiro de 2017

Atualizando Select com Knockout.js

Utilizando knockout.js como atualizar a lista de um select à partir da escolha em outro select? Pra muitos pode ser simples de cara, mas vou adimitir: para mim não foi, fui complicando às coisas ao invés de simplificar, quebrei um pouco a cabeça com isso e não tive bons resultados. Até que, lendo um post de um blog que falava sobre observables computed me veio a iluminação! E resolvi partilhar vai que ajudo alguém. Suponhamos uma aplicação na qual serão escolhidos items, estes itens estão organizados em categorias. Em uma lista seleciono a categoria, e à partir da minha seleção uma segunda lista é abastecida com as opções daquela categoria. Vou ser sincero, Pra começar vejamos uns dados de exemplo:
var produtos = [
 {
  grupo:"higiene pessoal",
  itens:[{'nome':'creme dental','valor':6.95},
                       {'nome':'shampoo','valor':12.49}]
 },
 {
  grupo:"material de limpeza",
  itens:[{'nome':'sabão em pó 2kg','valor':13.80},
                       {'nome':'detergente 500ml','valor':2.80}]
 },
 {
  grupo:"padaria",
  itens:[{'nome':'biscoito de polvilho 500g','valor':4.5},
                       {'nome':'pão de forma integral','valor':8.35}]
 }
];
A seguir nosso html:

<label>Categoria:</label><select data-bind="options:produtos,
      optionsText:'grupo',
      value:categoriaEscolhida,
      optionsCaption:'categoria...'"></select>
    <label>Produto:</label><select data-bind="options:itens,
      optionsText:'nome',
      value:itenEscolhido,
      optionsCaption:'Escolha o item'"></select>


E por último nosso código javascript:
var MarketModel = function(){
 this.produtos = ko.observableArray(produtos);
 this.categoriaEscolhida = ko.observable(this.produtos()[0]);
 this.itens = ko.computed(function(){
  return this.categoriaEscolhida().itens;
 },this);
};
A mágica acontece no observable do tipo computed. Resumidamente, pois a documentação é muito clara, computed é um campo calculado que sempre será atualizado quando as variáveis observáveis das quais ele depende forem atualizadas.Assim, toda vez que categoriaEscolhida for atualizada, itens também será. Simples assim.

segunda-feira, 19 de dezembro de 2016

Impressão com NodeJS

Esta é uma simples solução para quando temos uma aplicação de Intranet com NodeJS, e que gera documentos que precisam ser impressos, contudo os usuários desta intranet compartilham uma única impressora conectada ao e instalada no servidor.
Vamos utilizar o pacote printer. Para instalar basta
 npm install -g node-gyp
 npm install printer --msvs_version=2013
Continuando com a simplicidade, agora vamos a um exemplo:

var fs = require('fs');
var printer = require("printer");
fs.readFile("teste.pdf", 'utf8', function(err, file){
  if (err) throw err;
  console.log("Trying to print...");
  printer.printDirect({data:file,
      type: 'PDF',
      success:function(jobID){
 console.log("Trabalho enviado à impressora - ID: "+jobID);
      },
      error:function(err){
 console.log(err);
      }
  });
});

Neste exemplo utilizamos um pdf qualquer para ser impresso na impressora configurada como padrão. Existem várias opções customizáveis, acho válido citar que os dados podem vir de um arquivo ou de uma string. Você pode por exemplo utilizar renderizadores de templates em html como handlebars e passar a string diretamente para impressão. Você pode adicionar um parâmetro printer com o nome de uma impressora que não seja a padrão se houver mais de uma conectada ao servidor. Pois então, esta foi uma pequena dica!

quarta-feira, 20 de abril de 2016

Validação Customizada de Formulários com Angular

Angular facilita a organização de nossas aplicações em tudo, inclusive na validação de formulários. Porém nenhum framework existente cobre a necessidade de todos os programadores. Com certeza em algum momento você vai querer adicionar alguma funcionalidade à sua aplicação que não é coberta pelo framework. No presente post eu quero inserir uma validação para cpf de um input em meu formulário e não quebrar a validação de angular e não ter de fazer gambiarras. Vamos lá, faremos isto utilizando directives. Para executar esta tarefa me baseei no Post de Ben Lesh e na documentação oficial. 
O pulo do gato é bem descrito por Ben Lesh, utilizando a função $setValidity pertencente ao ngModelController definimos se o valor de um ngModel de determinado campo é válido ou não. Vale à pena conhecer a documentação de ngModelController.

Vamos ao código:
 
dir.directive("cpfValidate", function(){
 return{
  // iremos utilizar a diretiva como atributo
  restrict: 'A', 
  // o elemento a ser validado deve conter o atributo ng-model
  require: 'ngModel',
  link: function(scope, elem, attr, ctrl) {
   /*
    $parser é um array de funções para sanitizar os dados,
    aqui eu adiciono a minha função de validação.
   */
   ctrl.$parsers.unshift(function(value) {
    /* 
     TestaCPF é uma função qualquer para testar um cpf 
     você pode implementar a sua ou copiar na internet.
    */
    var valid = TestaCPF(value);
    ctrl.$setValidity('cpfValidate', valid);
    // se for válido retorno valid, else retorna undefined.
    return valid ? value : undefined;
   });
  }
 };
});

segunda-feira, 11 de maio de 2015

Estatísticas, R e Java - JRI

Bom neste post, quero apresentar de forma simples como pedir ao R para realizar alguns cálculos e retornar o resultado para uma aplicação em Java.


Vamos ao código:

 Rengine re = new Rengine("--vanilla");
public REXP eval(String c) throws Exception{

 REXP r = rengine.eval(c);

 if(r == null){

 rengine.eval("traceback()");

 throw new Exception("Não teve retorno!!!");

 }

return r;

}
Aqui o que temos é uma função que encapsula a avaliação para o caso.

CMake, RInside, Rcpp e R

Recentemente comecei a experimentar os pacotes RInside e Rcpp para R, que permitem programar em C++ para R e também trazer o R para "dentro" de aplicações em C++. Falando em C++, gosto muito de utilizar o CMake para gerar meus makefiles, contudo com o CMakeLists.txt presente juntos aos códigos exemplo que vem junto com RInside não foi possível compilar os programas. Você pode ver este script aqui.. Eram reportados alguns erros, e, tentando contorná-los identifiquei um que parece ser o suficiente . Mesmo não sendo o intuito deste post falar sobre cmake quero compartilhar a idéia de RInside e CMake funcionam muito bem. Vamos lá: o que eu fiz foi trocar o nome da variável na linha 87 de ${RINSIDELIBS_l} para ${RINSIDELIBS} e pronto.
Bons projetos

segunda-feira, 13 de janeiro de 2014

Chamando o R dentro de uma aplicação Java com JRI e Eclipse


  1. Motivação
  2. JRI
    1. Download e Instalação
    2. Configuração
      1. Linux
      2. Windows( a fazer )
    3. Execução

1.Motivação

Você quer fazer um software que utilize o R como motor mas que tenha uma interface usável por usuários não habituados ao ambiente R. Existem algumas bibliotecas em C e Java que permitem que você chame o R dentro de suas aplicações. Aqui vou mostrar como utilizo o JRI para Java. Porém, tive dificuldades para fazer as coisas funcionarem, e você talvez também esteja tendo problemas. Aqui pretendo então dizer passo a passo como fiz.

2.JRI


  2.1.Download e Instalação

Entre no R e digite e execute a linha a abaixo. O ideal é executar o R como administrador, se possível.

install.package('rJava')

  2.2.Configuração

     2.2.1 Linux

É necessário definir algumas variáveis de ambiente. Utilizando seu editor de texto preferido você abrirá o arquivo '.profile' que está na seu home e adicionará algumas linhas.

Obs: O arquivo '.profile' é invisível ao explorador de arquivo, você deve configurar o explorador para exibir arquivos ocultos, ou simplesmente abra um terminal e digite: 'gedit .profile' .

Obs: não digite as aspas

Caso você não queira editar o .profile basta digitar estas linhas toda vez que reiniciar o PC. (não recomendo)

Após editar o .profile é necessário reiniciar a máquina.


As linhas a serem adicionadas são estas a seguir(lembre de checar estes caminhos na sua máquina):

export R_HOME=/usr/lib/R # "Este é o caminho para a pasta que contém a instalação do R, e não caminho para o executável!"

Se tiver dúvida sobre o caminho, no terminal digite: R RHOME

export LD_LIBRARY_PATH=/usr/lib/R/site-library/rJava/jri/

export CLASSPATH=.: /usr/lib/R/site-library/rJava/jri/

2.2.2 Windows

Neste sistema operacional, temos de definir algumas variáveis de ambiente:
  • Caminho para o executável do R
  • Caminho para a jri.dll

3 Execução

Para executar darei alguns detalhes para o as IDEs Netbeans e eclipse.

quinta-feira, 20 de junho de 2013

Weka e Android - Serialization

Mais um problema que tive e custei a encontrar uma solução na internet. Encontrei foi muita gente com a mesma dúvida. Bem, o problema foi o seguinte, criei um app para Android que deveria classificar o usuário quanto ao risco de desenvolver cáries segundo algumas informações fornecidas pelo mesmo. Este modelo de classificação foi gerado por um software muito conhecido, o Weka. O Weka é um software desenvolvido em Java que lhe dá a possibilidade salvar os modelos gerados serializados em um arquivo. O meu plano então era adicionar a biblioteca do Weka  ao meu app, carregar o modelo na memória do dispositivo e então deserializar o modelo e aplicá-lo sobre os dados. Porém eis que não deu certo, uma exceção chata pipocando o tempo todo. Pesquisando sobre serialização entendi o problema: A versão que serializa tem de ser a mesma que deserializa. Se quem implementou as classes não declarou no código um número serial explicitamente durante o desenvolvimento, no momento da compilação então é atribuído este valor e então versões diferentes terão números diferentes. Eu estava utilizando uma versão do Weka no PC e outra no app. Assim se você está tendo este problema na hora de deserializar, tenta essa dica e é provável que vá resolver.

sábado, 15 de junho de 2013

Android, Adicionando arquivos ".jar" externos.

Problemas ao adicionar arquivos ".jar" aos seus projetos Android? Eu tive esse probleminha, adicionava os ".jar" através da opção build path mas na hora de executar, simplesmente sempre ocorria uma exceção dizendo que não localizava o arquivo. Então encontrei o seguinte POST que solucionou tudo.
Basicamente o que acontece é que a JVM Dalvik não consegue lidar com os ".jar" tradicionais, tendo de convertê-los para um formato próprio, e você precisa fazer com que ele faça isso. Para tal basta copiar o ".jar" a ser incluído na pasta lib do seu projeto, se não houver esta pasta você pode criá-la. Então você acessa o menu build path clicando com o botão direito sobre o nome do projeto e na aba library clique add jar e selecione o ".jar" que você copiou para a pasta lib. Simple assim. Espero que isto possa ajudar muita gente como me ajudou, demorei muito a encontrar alguém que soubesse uma
solução para essa questão.

terça-feira, 27 de setembro de 2011

Android: Preferences

Vamos falar de android.preference. É uma coleção de classes para lidar com o armazenamento de configurações e preferências do usuário, mas também podem servir para guardar a última posição em um jogo, tabela de highscores, e outros dados simples sem a complexidade de um banco de dados. Pensando neste uso é que escrevo este Post. Vamos pensar em um simples contador que pode marcar por exemplo quantas vezes a pessoa bebeu um copo de água ao longo de um dia. As preferências(dados) são armazenadas em um arquivo, e os valores recebem um nome através dos quais serão acessados. Por exemplo:



SharedPreferences mySharedPreferences = getSharedPreferences(COPOS, Activity.PRIVATE);
SharedPreferences.Editor editor;
/* COPOS é o nome do arquivo que guarda as preferências da aplicação
   Modo privado para abertura garante acesso exclusivo à aplicação
*/
mySharedPreferences = getSharedPreferences("COPOS", Activity.PRIVATE);
// buscando um valor de nome copos que é um inteiro
int n_copos = mySharedPreferences.getInt("copos",0);
n_copos++;
// iniciando o processo de atualização
editor = mySharedPreferences.edit();
// alterando o campo copos
editor.putInt("copos", n_copos);
// Salvando a alteração
editor.commit();

Este trecho de código poderia ser utilizado para incrementar um contador copos que ficaria armazenado no arquivo de preferências COPOS. Da mesma forma o valor poderia ser obtido e exibido na tela no final do dia.

Bom este é um exemplo muito simples mas que pode abrir um leque interessante de utilizações para esta classe.

Qualquer dúvidas consultem a documentação e me coloco a disposição.
Até o próximo POST.

sexta-feira, 12 de agosto de 2011

Fieldset com Zend

Bom, Zend_Form tem um decorator com o nome fieldset mas também tem um Element_Form chamado groups que pode funcionar da mesma forma. Todos os elementos de um 'group' são tratados conjuntamente apenas na hora da renderização, ou seja cada elemento pode ser acessado e alterado independentemente, mesmo após ter sido atribuído a um group. Vamos ao que interessa:


// criando um elemento do Zend_Form chamado group
$grupo = new Zend_Form_Element_Text('group');

/* criando um campo de texto com id = nome e outro com id=endereco
estou usando $this pensando que estamos colocando isto dentro de uma classe que estende Zend_Form
*/
$this->addElement('text', 'nome');

$this->addElement('text', 'endereco');

// adicionando o grupo ao form
$this->addElement($grupo);

// adicionando o campo nome e endereco ao grupo
$this->addDisplayGroup(array('nome',endereco), 'groups', array("legend" ="Vendas Financiadas"));

A função addDisplayGroup adiciona então o grupo ao formulário. Esta função tem os seguinte parâmetros:
  • $elementos: um array com o nome de cada elemento que pertencerá ao group.
  • $grupo: nome do group.
  • $options: este parâmetro é opcional, e é um array de opções ou um objeto Zend_Config. 
É isso aí, abraços

    Numa terra muito muito distante...

    Falando sério, minha idéia é trazer soluções para dúvidas minhas, idiotas ou não, quanto à programação em algumas linguagens e partilhá-las com quem interessar. Aceito críticas, dúvidas e sugestões. Vou começar falando do framework Zend, o qual estou utilizando e estudando por conta própria. Se vou falar só de programação? Acho que não, a vida é recheada de problemas que podemos desprogramar, e porque não falar de música, vinhos...