A Função Gama e o Surgimento do Fatorial

O conceito de fatorial (n!) foi organizado pela primeira vez em 1808 por Cristian Kramp (1760-1826), mas a curiosa notação (!) foi cunhada por Francisco de Borja Garção (1759-1829). Aparentemente, a notação foi utilizada involuntariamente em um livro daquele autor para expressar surpresa ou estupefação por um determinado resultado, mas a “notação” foi bem aceita entre os europeus.

n! = n . (n – 1) . (n – 2) . (n – 3)!

A palavra factura comunica um trabalho que foi realizado. O fatorial de 3 é 3.2.1 porque esses números trabalharam juntos para que o produto numérico deles totalize 6. Você sabe como surgiu o fatorial? Ele é o resultado da integração por partes de uma sequência numérica utilizada em uma integral especial:

Essa integral recebe o nome de Função Gama (Γ(n)). A função foi batizada por Legendre (1752-1833) em 1811, mas a Função Gama, assim como a Função Beta, que não será tratada nesse artigo, foram encontradas por Euler (1707-1783) em 1729 quando ele pesquisava movimentos harmônicos [1]. Euler comunicou sua descoberta ao professor Golbach:

(…) encontrei duas integrais interessantes que persistem em aparecer nos meus estudos. É impressionante, Goldbach, a beleza e simplicidade desses objetos (…)

As maiores contribuições para o tema foram dadas por Weierstrass (1815-1897) e Sofia Kovalevskaya (1850-1891).Vou resolver a integral para n=1 e apenas apresentarei o resultado de mais alguns valores de n, pois a mecânica da resolução é a mesma. Se você quiser resolver a integral para n>1, basta definir que o polinômio é v’ e a exponencial é u na integração por partes. Normalmente, numa integral desse tipo, assumiria-se que u é o polinômio, pois é mais simples derivá-lo. Talvez tenha sido por isso que o fatorial foi descoberto.

Utilizando a Integração por partes:

Para:

v = x0 → v’ = x1
u’ = e-x → u = -e-x

Encontramos o seguinte resultado:

Se você quiser ver uma prova do porquê 00 = 1, recomendo que você veja esse artigo. Perceba a série de resultados de gama para valores de n variando de 1 à 4:

Percebeu o padrão relacionado aos valores numéricos que multiplicam as integrais? Vamos substituir a integral pela notação:

Γ(1) = 1
Γ(2) = 1.Γ(1)
Γ(3) = 2.Γ(2)
Γ(4) = 3.Γ(3)

Vamos desdobrar recursivamente até Γ(1):

Γ(1) = 1
Γ(2) = 1.Γ(1)
Γ(3) = 2.1.Γ(1)
Γ(4) = 3.2.1.Γ(1)

Por fim, vamos substituir Γ(1):

Γ(1) = 1
Γ(2) = 1
Γ(3) = 2.1
Γ(4) = 3.2.1

Daí, extraímos a seguinte relação entre o fatorial e a Função Gama:

n! = Γ(n+1) e n! = nΓ(n)

A Função Gama Γ(n) e o Fatorial de Números Fracionários

Quando vi um fatorial pela primeira vez na escola, achei muito interessante, mas da forma como ele foi apresentado pela professora, aceitei como fato que aqueles números só poderiam pertencer ao conjunto dos inteiros (Z). Na verdade, a integral gama permite que descubramos os fatoriais de números irracionais, o que inevitavelmente significa que qualquer número real (ℜ) possui fatorial. Aqui, vou desenvolver um caso muito interessante, que é:

0,5!

Logo no início já notamos um problema: o fatorial de um número n para n ∈ Z finaliza em 1 quando vamos decrementando até 0 lembrando que 0!=1. Primeiro, vamos desenvolver a Função Gama em sua forma relacionada ao fatorial, pois o fatorial de um número n é Γ(n+1):

0,5! = Γ(0,5+1)
0,5! = Γ(1,5)

Mesmo assim, ainda não resolvemos o problema do ponto de parada, pois se começamos em 1,5, o próximo número com o qual gama trabalhará necessariamente será 0,5. Sendo assim, precisamos calcular Γ(0,5), mas utilizaremos a integral gama:

O resultado dessa integral é muito importante:

Γ(0,5) = 1,772454 = √Π

Sabendo o valor de Γ(0,5), podemos voltar ao problema e resolvê-lo sem precisar recorrer às integrais:

n! = nΓ(n)
0,5! = 0,5.Γ(0,5)
0,5! = 0,5.√Π

De forma análoga:

1,5! = 1,5.0,5.√Π
2,5! = 2,5.1,5.0,5.√Π
3,5! = 3,5.2,5.1,5.0,5.√Π
4,5! = 4,5.3,5.2,5.1,5.0,5.√Π
(…)

Exemplo de Uso da Função Gama

Para finalizar, vamos demonstrar, com um exemplo do material do Curso Prandiano, módulo P2, como a função gama minimiza a complexidade de uma integral. A ideia é modificar o problema para que a integral se encaixe na integral gama e, dessa forma, possamos resolvê-la como um fatorial. Modificar um problema é uma boa estratégia. Fiz algo similar quando estava estudando a Função W de Lambert: modifiquei o problema para encaixá-lo no “template” da função W e resolver a equação transcendental com um método de aproximação.

Dá pra resolver essa integral diretamente? Sim, mas vai ser trabalhoso. Se você modificar a integral para deixá-la parecida com a integral gama, tudo ficará mais fácil:

y = x/2 ∴ x = 2y

Para y = 0 → x = 0
Para y = ∞ → x = ∞

dy/dx = dy = ½ dx

Conhecendo a operacionalidade da Função Gama, fica fácil resolver esse tipo de integral.

Referências

1. RICIERI, Aguinaldo P. Derivada Fracionária, Transformada e Laplace e Outros Bichos. Editora Prandiano, São Paulo, 1993. pg 63

Anúncios
Categorias:Matemática

Iniciando com o Gulp

O JavaScript, que anos atrás um colega chamou de “linguagem do demônio”, é uma das linguagens de programação mais populares. Há alguns anos o Javascript cresceu em importância quando passou a ser utilizado também do lado do servidor. Um dos grandes responsáveis por isso foi o Node.js.

O Node.js, que é um JavaScript runtime environment, ou simplesmente um interpretador de código Javascript, permite que JavaScript possa rodar em nossos computadores sem a presença de um navegador. Com ele, os programadores podem criar aplicações escaláveis capazes de manipular milhares de conexões simultâneas.

Um das coisas legais que vêm com o Node.js é o NPM (Node Package Manager), que é o gerenciador de pacotes do Node.js. Um pacote no Node.js contém todos os arquivos (dependências) que compõem um determinado módulo. Módulos são bibliotecas JavaScript que podem ser incluídas em um projeto. Node.js e NPM são dependências do Gulp.

O Gulp é uma ferramenta que centraliza e gerencia muitas tarefas para nós, como por exemplo:

1. Subir um servidor
2. Recarregar o navegador automaticamente quando um arquivo é salvo
3. Utilizar pré-processadores como Sass ou LESS
4. Otimizar CSS, JavaScript e imagens

Essa ferramenta de automação é independente de plataforma, tem integração com muitas IDEs e desenvolvedores podem utilizá-la com PHP, .NET, Node.js, Java e outros. A simplicidade da API facilita o aprendizado e o uso e há muitos módulos disponíveis para muitas tarefas que em geral você precisa gastar um tempo precioso para fazer.

Para poder baixar as dependências do Gulp, você primeiro deve baixar e instalar o Node.js e o NPM. Depois de instalados, crie uma variável de ambiente que aponte para o diretório de instalação do Node.js apenas para facilitar o uso via linha de comando. O NPM também será instalado, mas se você quiser apenas atualizá-lo, rode o comando abaixo supondo que você esteja no Windows:

Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force
npm install -g npm-windows-upgrade
npm-windows-upgrade

Exemplo 1

Vamos começar com um exemplo bem simples para apresentar o Gulp e depois vamos fazer alguma coisa mais interessante. Primeiro, remova as versões antigas do Gulp que por ventura estejam instaladas na sua máquina:

npm rm --global gulp 

Instale o gulp-cli, que é um utilitário de linha de comando para o Gulp:

npm install --global gulp-cli

Acesse a pasta do seu projeto e instale o Gulp e suas dependências apenas para o seu projeto (devDependencies) com o parâmetros “–save-dev”. Pelo que li, é uma boa prática manter as dependências do projeto locais e não globais:

rm -rf node_modules/
npm install --save-dev gulp gulp-util

Execute o comando abaixo para criar um arquivo package.json com os dados do projeto:

npm init

Se você já possuía um arquivo package.json na raiz do projeto, basta baixar as dependências que já estão descritas nele:

npm install --save-dev

Crie um arquivo chamado gulpfile.js no diretório raiz do seu projeto com o seguinte conteúdo:

var gulp  = require('gulp');
var gutil = require('gulp-util');

gulp.task('teste', function() {
  return gutil.log('Teste!')
});

Acesse o diretório onde está aquele arquivo e execute o comando abaixo. Obs: se a task que você criou se chamasse “default”, você não precisaria identificá-la ao executar o comando:

$gulp teste

Após a execução do comando, algo assim será exibido no console:

[09:41:07] Using gulpfile gulpfile.js
[09:41:07] Starting 'teste'...
[09:41:07] Teste!
[09:41:07] Finished 'teste' after 4.24 ms

Exemplo 2

Agora, vamos fazer um exemplo mais interessante que mostrará um pouco mais do poder do Gulp. Faremos minificação de JavaScripts, CSS e imagens PNG e também modificaremos o nome dos CSS minificado com o gulp-cachebust para evitar o cache do navegador. A documentação e os exemplos de uso dos módulos abaixo podem ser encontrados no repositório do NPM. No diretório do projeto, execute o comando abaixo para baixar as dependências:

npm install --save-dev gulp gulp-util gulp-concat gulp-uglify gulp-imagemin gulp-sourcemaps del gulp-cssnano gulp-cachebust imagemin-optipng gulp-copy
var gulp = require('gulp');
var gutil = require('gulp-util');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var imagemin = require('gulp-imagemin');
var sourcemaps = require('gulp-sourcemaps');
var del = require('del');
var cssnano = require('gulp-cssnano');
var CacheBuster = require('gulp-cachebust');
var cachebust = new CacheBuster();
var imageminOptipng = require('imagemin-optipng');
var gulpCopy = require('gulp-copy');
 
var paths = {
  scripts: ['src/main/webapp/resources/js/**/*.js'],
  images: 'src/main/webapp/resources/img/**/*.png',
  css: 'src/main/webapp/resources/css/**/*',
  htmls: 'src/main/webapp/paginas/**/*.{html,xhtml}'
};

gulp.task('clean', function() {
  return del(['build']);
});
 
gulp.task('htmls', ['clean'], function() {
  console.log(paths.build_dir + 'paginas');
  return gulp.src(paths.htmls)
    .pipe(gulp.dest(paths.build_dir + 'paginas'));
});

gulp.task('scripts', ['clean'], function() {
  return gulp.src(paths.scripts)
    .pipe(sourcemaps.init())
    .pipe(uglify())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(paths.build_dir + 'resources/js'));
});

gulp.task('css', ['clean'], function() {
    return gulp.src(paths.css)
		.pipe(cssnano({safe : true}))
		.pipe(cachebust.resources())
        .pipe(gulp.dest(paths.build_dir + 'resources/css'));
});
 
gulp.task('images', ['clean'], function() {
  return gulp.src(paths.images)
    .pipe(imagemin({optimizationLevel: 5}))
	.pipe(imagemin({use: [imageminOptipng()]}))
    .pipe(gulp.dest(paths.build_dir + 'resources/img'));
});

gulp.task('watch', function() {
  gulp.watch(paths.scripts, ['scripts']);
  gulp.watch(paths.css, ['css']);
  gulp.watch(paths.images, ['images']);
  gulp.watch(paths.html, ['paginas']);
});
 
gulp.task('dist', ['watch', scripts', 'css', 'images', 'htmls']);

Essa task “watch” fica escutando os diretório de origem e, caso ocorra alguma alteração, as tasks são reexecutadas automaticamente.

Maven Integrado ao Gulp

É bem simples executar targets de um POM à partir de um script Gulp. Instale o módulo abaixo:

npm install --save-dev gulp-maven-integration

Adicione as tasks abaixo. A task package que definimos abaixo pode ser modificada para executar todas as demais tasks que você tenha no script:

var mavenTask = require('gulp-maven-integration');

gulp.task('package', function() {
   return mavenTask('Build', 'clean compile package -DskipTests');
});

Gulp Integrado ao Maven

É possível acionar o Gulp à partir do Maven. Basta adicionar um plugin no seu POM:

<plugins>
	(...)
	<plugin>
	  <groupId>com.github.eirslett</groupId>
	  <artifactId>frontend-maven-plugin</artifactId>
	  <version>1.6</version>
	    <dependencies>
	        <dependency>
	            <groupId>org.codehaus.plexus</groupId>
	            <artifactId>plexus-utils</artifactId>
	            <version>2.1</version>
	        </dependency>
	    </dependencies>

	    <executions>
	        <execution>
	          <id>gulp dist</id>
	          <goals>
	              <goal>gulp</goal>
	          </goals>
	          <configuration>
	              <arguments>dist</arguments>
	          </configuration>
	      </execution>
		</executions>
	</plugin>
</plugins>

Em um ambiente com integração contínua, você vai querer adicionar algumas tags execution para que o Node.js e o NPM sejam baixados e instalados antes da execução. Li em vários lugares que uma boa prática para uso do Gulp é instalar os pacotes com –save-dev para que todas as dependências fiquem específicas para aquele script do Gulp. Vamos supor que a rede da sua empresa não seja muito confiável ou que sua empresa limite bastante o seu uso. Se isso acontecer, seria mais produtivo baixar todas as dependências em um local e criar links simbólicos para lá.

Se você quiser fazer o deploy local just for fun, vamos fazer algumas “adaptações” no ambiente. Misteriosamente, ao que parece, o Maven assume que o Gulp foi instalado em modo local, ou seja, ele pressupõe que no mesmo diretório do POM deve estar o diretório de instalação do Node e o diretório node_modules. Você pode adicionar a tag abaixo para especificar o local de instalação do Node:

<configuration>
	<installDirectory>${NODE_HOME}</installDirectory>
</configuration>

Isso funciona para o diretório de instalação do Node, mas não para o node_modules, pois o Maven, ainda misteriosamente, assume que esteja na mesma hierarquia do Node. Resolvi criando um ponto de junção no Windows, que é um link simbólico para um diretório que atua como um alias para aquele diretório onde está o POM e o gulpfile. Isso é equivalente a fazer um hardlink em sistemas Unix.

mklink /j node ${NODE_HOME}
mklink /j node_modules ${NODE_modules}

Por fim, execute o Maven:

{MAVEN_HOME}\bin\mvn clean compile package

Referências

1. [https://www.devmedia.com.br/tdd-continuo-em-javascript-com-node-js-e-gulp/32467]

Categorias:Programação

O Pássaro de Ouro

Os Irmão Grimm, Jacob (1785-1863) e Wilhelm (1786-1859) foram acadêmicos alemães, mas ficaram mais conhecidos pelas histórias maravilhosas que legaram às gerações seguintes. Esses contos são uma fusão muito interessante entre a criatividade dos irmãos e as pesquisas que realizaram sobre a cultura e a língua dos povos europeus.

Figura 1 – Irmãos Grimm

Dentre os 200 contos dos Grimm estão a Branca de Neve, o Príncipe Sapo, João e Maria e muitas outras histórias bastante conhecidas, mas me lembro de um conto não tão conhecido que marcou minha infância: O Pássaro de Ouro.

Publicado em 1812, O Pássaro de Ouro conta a história de um rapaz, o mais jovem de três irmãos filhos do jardineiro do palácio, que saiu em uma aventura para encontrar o ladrão que toda noite roubava uma maçã de ouro da árvore do rei: um pássaro de ouro. Nessa aventura, sempre auxiliado por uma sábia raposa, o jovem enfrenta vários percalços: quando ele segue o conselho da raposa, ele consegue vencer o desafio ou a tarefa sem problemas, mas quando ele age por impulso e não segue a recomendação da conselheira, ele acaba piorando a situação. Ao final, não sem antes ser traído por seus irmãos e obedecer o último pedido da raposa, ele recebe uma recompensa maior do que o pássaro de ouro.

Segue abaixo a história completa. Você vai perceber que, diferente do padrão Disney e das muitas adaptações que os contos dos Grimm sofreram para teatro e cinema, há elementos um tanto depressivos nessa história que tornam o final não tão feliz assim. Adaptei a história para contá-la para minha filha e ela gostou bastante. Como a princesa da história não tinha nome, minha filha a batizou de Helena.

Figura 2 – Conto: O Pássaro de Ouro

O Pássaro de Ouro

Era uma vez um rei que tinha um belo jardim, e no jardim havia uma árvore que produzia maçãs de ouro. Essas maçãs eram sempre contadas, e na época que elas começavam a amadurecer descobriu-se que todas as noites faltava uma. O rei ficou muito bravo com isso e mandou que o jardineiro ficasse de vigília todas as noites debaixo da árvore.

O jardineiro colocou seu filho mais velho para olhar, mas, por volta da meia noite ele caiu no sono, e quando era de manhã, mais uma maçã estava faltando. Então, foi pedido ao segundo filho que vigiasse, mas, quando deu meia noite ele também dormiu e na manhã seguinte outra maçã estava faltando. Então, o terceiro filho se ofereceu para ficar de vigília, mas o jardineiro a princípio não queria isso, temendo que algo de mal pudesse lhe acontecer, todavia, no final ele concordou, e o jovem rapaz ficou debaixo da árvore vigiando.

Quando o relógio deu doze badaladas ele ouviu um barulho de folhas se mexendo, e um pássaro, que era todo de ouro, veio voando, e quando ele bateu uma das maçãs com o seu bico, o filho do jardineiro deu um pulo e atirou uma flecha nele. Mas a flecha não causou nenhum ferimento ao pássaro, apenas derrubou uma pena de sua cauda, e depois ele fugiu.

Figura 3 – O filho do jardineiro descobre quem roubava as maçãs de ouro

A pena de ouro foi levada para o rei de manhã, e todo o conselho foi convocado para uma reunião. Todos concordaram que ela valia mais do que todas as riquezas do reino: mas o rei disse, “Uma pena não tem utilidade para mim, eu preciso do pássaro inteiro.”

Então, o filho mais velho do jardineiro pôs-se a caminho e pensou em encontrar o pássaro de ouro muito facilmente, e quando ele tinha andado uma parte do caminho, ele chegou a uma floresta, e ao lado da floresta ele viu uma raposa sentada, então, ele pegou o seu arco e se preparou para atirar nela. Então, a raposa disse, “Não me mate, porque eu lhe darei um bom conselho; eu sei o que você procura, e que você precisa encontrar o pássaro de ouro.”

“À noitinha você chegará numa aldeia, e quando você estiver lá, você verá duas estalagens uma de frente para a outra, uma delas é muito agradável e linda de se ver, não entre nela, mas, passe a noite na outra, embora ela possa parecer muito simples e pobre.”

Mas o filho pensou consigo mesmo:

“Ora, o que um animal como este pode saber sobre esse assunto?” Então, ele atirou uma flecha na raposa, mas errou o alvo, e ela levantou seu rabo acima do traseiro e fugiu para a floresta.

Então, ele seguiu o seu caminho, e à noitinha ele chegou na aldeia onde havia duas estalagens, e em uma delas as pessoas estavam cantando, e dançando, e festejando, mas, a outra parecia muito suja e pobre.

“Eu seria um tolo,” disse ele, “se eu ficasse nesse lugar imundo, e não me hospedasse nesse lugar encantador”, então, ele foi para a casa bonita, e comeu e bebeu a vontade, e esqueceu do pássaro, e do lugar onde morava também.

O tempo passou, e como o filho mais velho não voltava, e ninguém mais tinha notícias dele, o segundo filho decidiu partir, e o mesmo aconteceu. Ele encontrou a raposa, que lhe deu o bom conselho, mas quando ele chegou nas duas hospedarias, o seu irmão mais velho estava na janela onde estavam fazendo uma folia, e gritou para que ele entrasse, ele não conseguiu resistir à tentação, e entrou, e se esqueceu do pássaro de ouro e do lugar onde morava do mesmo jeito.

O tempo passou novamente, e o filho mais jovem também desejou partir para tentar a sorte e procurar o pássaro de ouro, mas o seu pai não quis nem saber disso durante muito tempo, pois, ele gostava muito do seu filho, e tinha medo que a má sorte pudesse surpreendê-lo também, e não deixou que ele partisse.

Todavia, finalmente o pai concordou que o filho partisse, porque ele não tinha sossego em casa, e quando ele chegou à floresta, ele encontrou a raposa, e ouviu dela o mesmo conselho. Ele, porém, agradeceu à raposa, e não confiou na sorte como seus dois irmãos haviam feito, então, a raposa disse, “Sente no meu rabo, e você irá mais rápido.”

Então, ele sentou, e a raposa começou a correr, e eles foram pra longe tão rápidos que o cabelo dele assobiava com o vento.

Quando eles chegaram à aldeia, o filho seguiu o conselho da raposa, e sem olhar no entorno, entrou na estalagem pobre e passou lá a noite toda muito a vontade. De manhãzinha, veio a raposa novamente e se encontrou com ele quando ele se preparava para partir, e disse:

“Vá direto por este caminho, até você chegar num castelo, e diante do castelo você verá uma tropa inteira de soldados dormindo profundamente e roncando: não ligue para eles, mas, entre no castelo e vá andando e andando até você chegar num lugar, onde o pássaro de ouro fica sentado numa gaiola de madeira, perto dela há uma linda gaiola de ouro, mas não tente pegar o pássaro fora da gaiola mais pobre e coloque-o na gaiola mais bonita, caso contrário você se arrependerá.

Então, a raposa esticou o seu rabo novamente, e o jovem rapaz se sentou nele, e eles caminharam tão velozmente que o cabelo dele assobiava ao vento.

Diante do portão do castelo tudo era como a raposa havia falado: então, o filho entrou e encontrou a sala onde o pássaro de ouro ficava dependurado numa gaiola de madeira, e debaixo dela havia uma gaiola de ouro, e as três maçãs de ouro que haviam sido perdidas estavam bem ali. Então, ele pensou consigo mesmo: “seria muita incoerência levar um pássaro tão belo nesta gaiola simples”, então, ele abriu a porta, pegou o pássaro e o colocou dentro da gaiola de ouro.

Mas o pássaro de um um grito tão alto que todos os soldados acordaram, e eles o levaram como prisioneiro e o conduziram diante do rei. Na manhã seguinte a corte se reuniu para julgá-lo, e depois que todos tinham sido ouvidos, ele foi sentenciado a morte, a menos que ele trouxesse ao rei o cavalo de ouro que podia voar tão veloz como o vento, e se ele conseguisse isso, ele poderia ficar com o pássaro de ouro como se fosse dele.

De modo que, mais uma vez ele partiu de viagem, soluçando e muito aflito, quando subitamente, a raposa, sua amiga, encontrou-se com ele e disse:

“Você entende agora o que aconteceu por você não ter ouvido o meu conselho. Mesmo assim, eu vou lhe dizer como encontrar o cavalo de ouro, se você fizer tudo que eu lhe pedir.”

“Você deve ir reto neste caminho até você chegar a um castelo onde o cavalo está em seu estábulo, ao lado do cavalo estará um cavaleiro dormindo profundamente e roncando, pegue o cavalo em silêncio, mas, não se esqueça de colocar a sela de couro nele, e não a de ouro que está próxima dele.” Então, o filho sentou no rabo da raposa, e ela correu tão veloz que o cabelo dele assobiava ao vento.

Tudo foi bem, e o cavaleiro estava roncando com a mão em cima da sela de ouro. Mas, quando o filho olhou para o cavalo, ele pensou que seria uma pena colocar a sela de couro nele. “Eu colocarei nele a sela boa,” disse ele, “tenho certeza que ele merece.” E quando ele foi pegar a sela de ouro o cavaleiro acordou e gritou tão alto, que todos os guardas correram e o levaram prisioneiro, e na manhã seguinte ele novamente foi levado diante da corte para ser julgado, e foi sentenciado a morte.

Mas ficou definido, que, se ele conseguisse trazer a bela princesa até ali, ele poderia viver, e o pássaro e o cavalo seriam dele como se ele fosse o dono deles.

Então, ele seguiu a sua jornada muito triste, mas a velha raposa se aproximou e disse: “Porquê você não fez o que eu mandei? Se você tivesse me ouvido, você poderia ter ficado tanto com o pássaro como com o cavalo, no entanto, vou lhe dar mais um conselho. Siga direto por este caminho e de manhãzinha você chegará ao castelo.”

“À meia-noite a princesa costuma ir para a casa de banho, vá até ela e dê um beijo nela, e ela permitirá que você a leve embora, mas cuidado para que ela não te peça permissão para ir e pedir a autorização do seu pai e da sua mãe.”

Então, a raposa esticou o rabo, e eles correram tão rápido que o cabelo dele assobiava com o vento novamente.

Quando eles chegaram ao castelo, tudo aconteceu como a raposa havia falado, e à meia-noite o jovem rapaz viu a princesa que estava indo ao banho e deu um beijo nela, e ela concordou em fugir com ele, mas implorou chorando que ele permitisse que ela pedisse autorização de seus pais.

A princípio ele recusou, mas ela continuava chorando, e caiu aos seus pés, até que finalmente ele concordou, mas, no momento que ela chegou à casa do seu pai, os guardas acordaram e ele foi levado para a prisão novamente.

Então, ele foi levado diante do rei, e o rei disse: “Você jamais terá a minha filha a menos que em oito dias você remova a colina que impede a visão da minha janela.” Ora, esta colina era tão grande que o mundo inteiro não conseguiria removê-la: e tendo ele trabalhado durante sete dias, e tinha feito muito pouco, a raposa veio e disse:

Deite-se e vá dormir, eu farei o trabalho para você.” E de manhã, quando ele acordou, a colina não estava mais lá; então, ele foi feliz até o rei, e disse-lhe que agora que a colina tinha sido removida o rei devia lhe dar a princesa.

Então, o rei foi obrigado a cumprir a sua palavra, e lá foram o jovem rapaz e a princesa, e a raposa veio e disse para ele:

“Nós conseguiremos os três: a princesa, o cavalo e o pássaro.”

“Ah!,” disse o rapaz, “isso seria ótimo, mas, como você pretende conseguir isso?”

“Se você me escutar,” disse a raposa, “isso será feito.” Quando você chegar ao rei, e ele perguntar pela bela princesa, você deve dizer: “Aqui está ela!” Então, ele ficará muito feliz, e você montará no cavalo de ouro que eles vão dar a você, e estenderás a tua mão para se despedir deles; mas despeça-se da princesa por último. Depois suba ela rapidamente no cavalo atrás de você, bata com as esporas na lateral do cavalo, e fuja a galope o mais rápido que puder.”

Tudo deu certo, então, a raposa disse: “Quando você chegar ao castelo onde está o pássaro, eu ficarei com a princesa na porta, e você vai entrar e falar com o rei, e quando ele vir que é o cavalo que ele procura, ele trará o pássaro, mas, você deve continuar sentado, e dizer que você quer dar uma olhada nele, para verificar se ele é o verdadeiro pássaro de ouro, e você o pega em suas mãos e sai a galope.”

Isto, também, aconteceu como disse a raposa; eles levaram o pássaro, a princesa montou novamente, e ele foram a galope pela grande floresta. Então, a raposa veio e disse: “Peço para que você me mate, e corte a minha cabeça, e os meus pés.” Mas o jovem se recusou a fazer isso, então, a raposa disse: Não vou te ajudar mais te dando conselhos: mas cuidado com duas coisas, não resgates ninguém da forca, e não sente-se nas margens de nenhum rio.” Então, lá foi ele. “Bem,” pensou o jovem rapaz, “não é difícil cumprir o que a raposa pediu.”

Figura 4 – A recompensa do jovem jardineiro

Ele continuou a cavalgar com a princesa, até que finalmente chegou na aldeia onde ele tinha deixado seus dois irmãos. E lá ele ouviu um grande barulho e muito tumulto, e quando ele perguntou o que estava acontecendo, as pessoas disseram:

“Dois homens vão ser enforcados.” E quando ele chegou perto, ele viu que os dois homens eram seus irmãos, que tinham se tornado ladrões, então, ele disse:

“Será que eles não podem serem salvos de jeito nenhum?” Mas as pessoas diziam: “Não,” a menos que ele desse todo dinheiro que tinha para comprar a liberdade dos malandros.” Então, ele não parou para pensar no assunto e pagou o resgate, e seus irmãos foram libertados, e voltaram com ele para casa.

E quando ele chegou na floresta onde a raposa os havia avistado da primeira vez, estava tão fresco e agradável que os dois irmãos disseram: “Vamos nos sentar na margem do rio, e descansar um pouco, para comer e beber.” Então, ele disse:

“Sim,” e esqueceu o conselho da raposa, e se sentou na margem do rio, e como ele não suspeitava de nada, eles vieram por trás, e o atiram ladeira abaixo, e pegaram a princesa, o cavalo e o pássaro, e foram para casa ao encontro do rei, o amo deles, e disseram:

Tudo isso nós conseguimos com nosso próprio trabalho.” Então, houve muito regozijo, mas o cavalo não comeu, o pássaro não cantou e a princesa chorava muito.

O filho mais jovem caiu no fundo do leito do rio: por sorte o rio estava quase seco, mas os seus ossos estavam todos quebrados, e a ladeira era tão íngreme que ele não encontrou uma maneira de sair de lá. Então, a velha raposa apareceu mais uma vez, e o repreendeu por não ter ouvido os seus conselhos, caso contrário, nenhum mal lhe teria acontecido.

“Todavia,” disse ela, “não posso lhe deixar aqui, portanto, segure no meu rabo e não solte.” Então, ela o retirou do rio, e disse para ele, quando ele subiu a ladeira: “Os seus irmãos estão de vigília para te matar, caso te encontrem no reino.” Então, ele se vestiu como um aldeão pobre, e foi escondido até à corte do rei, e mal havia atravessado os portões quando o cavalo começou a comer, e o pássaro a cantar, e a princesa parou de chorar.

Pouco tempo depois, ele foi caminhar um dia na floresta, e a velha raposa o encontrou, e implorou para ele com lágrimas nos olhos para que a matasse, cortasse a sua cabeça e os seus pés. E finalmente ele fez o que ela pediu, e nesse instante a raposa se transformou num homem, que era o irmão da princesa, e que havia desaparecido há muitos e muitos anos atrás.

Figura 5 – A Raposa – o irmão desaparecido da princesa

Categorias:Geral

A Lei de Benford e a Estatística do Ladrão

Você sabe que toda sujeira conta uma história. Aquele tênis sujo de lama, por exemplo, conta a história dos seus passeios do final de semana. Aquela camiseta branca suja de molho conta algo sobre o almoço de domingo. Você sabia que há matemática na sujeira? Em 1981, Simon Newcomb (1835-1909) verificou que tabelas de logaritmos comuns estavam mais sujas nas primeiras páginas, o que indicava que o dígito 1 era mais utilizado que o dígito 9 [1] – essas tabelas eram ordenas de forma crescente do log(1) até o log(9). Frank Benford (1883-1948) retomou o assunto e publicou um artigo em 1938. Ele analisou muitos livros contendo tabelas logaritmicas em bibliotecas públicas e de diferentes universidades americanas. Após verificar os resultados, a estatística do primeiro dígito tomou forma.

Figura 1 – Simon Newcomb

Figura 2 – Frank Benford

O que é o tal primeiro dígito? Observe essa sequência numérica aleatória:

654,52 – 4569,03 – 9,84 – 52,88 – 97251,01

Nessa sequência, há um número que começa com o dígito 4, um com 5, um com 6 e dois com 9. Esse é o objeto de interesse da lei de Benford. Benford percebeu que quando o primeiro dígito era observado em conjuntos formados por muitos números desde que os números fossem compostos de pelo menos três dígitos, a frequência de aparição dos números convergia para uma escala logarítmica: a frequência de cada número era a diferença entre o logaritmo do próximo número e do número observado:

Esses números foram classificados como Números Anômalos e daí nasceu a generalização que deu corpo à famosa Lei de Benford:

P(d) = log(d+1) – log(d) = log[(d+1)/d]

Essa lei prevê que os dígitos de 1 à 9, quando aparecem como o primeiro dígito do conjunto de números que forma um espaço amostral consideravelmente extenso, têm uma frequência própria e previsível de aparição. É esperado que o número 1, por exemplo, apareça como primeiro dígito por volta de 30% do espaço amostral, o que equivale ao log(2). O número 9 deve aparecer como primeiro dígito algo em torno de 4,58% do espaço amostral, o que equivale à log(1 + 1/9). Esses números, em princípio, não fazem sentido algum, mas aparentemente o comportamento observado por Newcomb/Benford nas tabelas logaritimicas pode ser observado em outros fenômenos da natureza e a Lei é bastante aplicada hoje em dia na detecção de fraudes [2] inclusive nas eleições brasileiras, por exemplo.

A Prova Matemática da Lei de Benford

No artigo original [1], Benford utilizou a escala logarítmica para explicar o comportamento observado. Como não foi exatamente uma descoberta que tenha partido de um processo semiótico, me parece que faltou parte da matemática. Para entender matematicamente a descoberta de Benford/Newcomb, vamos relembrar o conceito de probabilidade, que é a base daquela Lei:

P = n(E) / n(Ω)

Onde:

P: probabilidade de um evento ocorrer
E: o evento cuja probabilidade se quer conhecer
Ω: o espaço amostral que contém o evento

Vamos analisar o lançamento de uma moeda ao ar:

E1: sair cara
E2: sair coroa
Ω: 2

Sendo assim, uma moeda lançada ao ar tem 50% (1/2) de chances de cair cara e outros 50% (1/2) de chances de cair coroa, pois o evento é a face apresentada e o espaço amostral é a quantidade de faces. Agora, vamos observar o conjunto dos algarismos indo-arábicos:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9
E0: sair o número 0
E1: sair o número 1

E5: sair o número 5

E9: sair o número 9
Ω: 10

Qual é a probabilidade de sortearmos o número 1? 10% (1/10). E o número 5? 10% (1/10). E qualquer número dessa sequência? 10% (1/10). Isso não prova nada uma vez que sabemos que a probabilidade de sortear qualquer número nessa sequência é igual – não há nada que evidencie a relevância de um número perante os demais – e a soma de todas as probabilidades deve ser igual à 1 (100%):

P(0) = 1/10 = 0,1 = 10%
P(1) = 1/10 = 0,1 = 10%
P(2) = 1/10 = 0,1 = 10%
P(3) = 1/10 = 0,1 = 10%
P(4) = 1/10 = 0,1 = 10%
P(5) = 1/10 = 0,1 = 10%
P(6) = 1/10 = 0,1 = 10%
P(7) = 1/10 = 0,1 = 10%
P(8) = 1/10 = 0,1 = 10%
P(9) = 1/10 = 0,1 = 10%

Fazendo a prova:

P(n) = P(0) + P(1) + P(2) + P(3) + … + P(9)
P(n) = 0,1 + 0,1 + 0,1 + 0,1 + … + 0,1
P(n) = 1 = 100%

Para explicar o fenômeno que Benford observou, precisamos trabalhar esse “1/10”, que é o percentual de cada dígito frente aos demais dígitos, com o objetivo de reescrever aquele valor em função do dígito observado e utilizar uma transformação logarítmica para diminuir o viés da distribuição à luz da proporção entre os objetos que a compõe. O uso de logaritmo faz bastante sentido, pois queremos observar o comportamento de determinados dígitos em um espaço amostral composto por muitos números.

O prof. Ricieri, em aula, desdobrou a Lei de Benford, mas ainda assim faltou aquele começo da matemática que citei; os traços iniciais. Utilizei mereologia para trabalhar a proporção “1/10” com o objetivo proposto e conectei o resultado com o desdobramento do professor para P(5), mas poderia ser qualquer outro dígito. Fiz uma articulação bem simples, mas você poderia trabalhar a forma logaritimica do número (n = 10log(n)) e fazer outras manipulações:

P(5) = 1/10
P(5) = (6-5)/10
P(5) = 6/10 – 5/10
P(5) = log(6)/log(10) – log(5)/log(10)
P(5) = log(6)/1 – log(5)/1
P(5) = log(6) – log(5)

A parte importante é o “1”, que ao ser rescrito como uma subtração (d+1 – d), já fez com que a Lei de Benford se apresentasse no horizonte. Articulando logaritmos de base 10 e utilizando a propriedade da divisão, obtive a premissa que procurava para conectar aquele traço semiótico ao desdobramento do professor:

P(5) = log(6) – log(5)
P(5) = log(6/5)
P(5) = log[(5+1)/5]
P(5) = log(5/5 + 1/5)
P(5) = log(1 + 1/5)

Agora, vamos generalizar essa descoberta trocando o dígito observado por “d”:

P(d) = [log(d+1) – log(d)]/[log(10) – log(1)]
P(d) = log[(d+1)/d] / log(10/1)
P(d) = log(d/d + 1/d) / log(10)
P(d) = log(1 + 1/d)

Assim, provamos matematicamente a Lei de Benford:

P(d) = log(1 + 1/d)

Por fim, apliquemos o que descobrimos aos demais dígitos de 1 à 9:

P(1) = log(1 + 1/1)
P(2) = log(1 + 1/2)
P(3) = log(1 + 1/3)
P(4) = log(1 + 1/4)
P(5) = log(1 + 1/5)
P(6) = log(1 + 1/6)
P(7) = log(1 + 1/7)
P(8) = log(1 + 1/8)
P(9) = log(1 + 1/9)

Perceba que descartei o P(0), pois a divisão por 0 e o log(0) são indeterminados:

P(0) = log(1 + 1/0) indeterminado!

Isso faz sentido, pois como estamos estudando a estatística do primeiro dígito, o zero à esquerda tem que ser descartado para não inflacionar os resultados. Note que agora a distribuição de cada número difere do “1/10” originalmente observado e corrobora com o fenômeno que Benford observou:

P(1) = log(1 + 1/1) = 0,30103 = 30,103%
P(2) = log(1 + 1/2) = 0,17609 = 17,609%
P(3) = log(1 + 1/3) = 0,12494 = 12,494%
P(4) = log(1 + 1/4) = 0,09691 = 9,6910%
P(5) = log(1 + 1/5) = 0,07918 = 7,9180%
P(6) = log(1 + 1/6) = 0,06695 = 6,6950%
P(7) = log(1 + 1/7) = 0,05799 = 5,7990%
P(8) = log(1 + 1/8) = 0,05116 = 5,1160%
P(9) = log(1 + 1/9) = 0,04576 = 4,5760%

Se você somar todos esses valores, verá que o resultado continua sendo 1:

P(n) = P(1) + P(2) + P(3) + … + P(9)
P(n) = 0,30103 + 0,17609 + 0,12494 + … + 0,04576
P(n) = 1 = 100%

Exemplo 1: A Sequência de Fibonacci

Na sequência de Fibonacci, cada número é a soma dos dois números que o antecedem:

F(0) = 0
F(1) = 1
F(2) = 1 + 0 = 1
F(3) = 1 + 1 = 2
F(4) = 2 + 1 = 3
F(5) = 3 + 2 = 5
F(6) = 5 + 3 = 8
F(n) = F(n-1) + F(n-2)

Com Java 8 é bem simples gerar uma sequência de Fibonacci. Vamos gerar uma sequência de 80 números:

UnaryOperator<Long[]> operator = p 
   -> new Long[] { p[1], p[0] + p[1] };
Function<Long[], Long> consumer = c 
   -> c[0];
List<Long> sequencia = Stream.iterate(new Long[] { 1L, 1L }, operator)
   .limit(80).map(consumer)
   .collect(Collectors.toList());
sequencia.stream().forEach(p -> System.out.println(p));

Vamos comparar o primeiro dígito com Benford:

Como você pode observar, cada dígito apareceu em uma frequência muito próxima daquela prevista por Benford em um espaço amostral de 80 valores.

A Estatística do Ladrão

Em uma aula do módulo P(3) do Curso Prandiano, o professor Ricieri contou que utilizou a “estatística do ladrão” em uma palestra que ministrou para empresários do comércio. Dias antes da palestra, ele pediu que os empresários trouxessem dois conjuntos de 1000 notas fiscais: uma original e a outra manipulada por eles. Utilizando a Lei de Benford, o professor foi capaz de apontar, em todos os casos, qual dos dois conjuntos era o original e qual era o maquiado e quais dígitos iniciais foram manipulados.

Apresentar a Lei de Benford como a estatística do ladrão tem um forte apelo emocional junto ao empresariado, pois ela toca onde mais lhes dói: no bolso. O professor contou, naquela mesma aula, que uma antiga aluna aplicou a Lei na análise de alguns milhares de cupons fiscais emitidos no posto de gasolina do tio dela. Os resultados apontavam que o número 5 estava inflacionado e ela concluiu que “havia roubo”, mas o professor a lembrou de que postos de gasolina têm o peculiar “cinquentão”, que há alguns anos era o “vintão”. É comum, principalmente entre os motoristas mais velhos, pedir para abastecer um valor fixo, como R$50,00, e isso faz com que o espaço amostral fique enviesado.

A Lei de Benford, quando utilizada para análise de valores financeiros, diz se os percentuais estão ou não de acordo com o esperado, mas daí a inferir, baseado apenas em Benford, que há desvios, pode ser um grande erro. Sempre é mais seguro verificar o que causou o desvio dos valores observados antes de concluir o que quer que seja.

Exemplo 2: Análise de Doações para Campanhas Eleitorais

Vamos utilizar uma massa de dados real para aplicar a Lei de Benford. Inspirado pelo atual processo eleitoral, o mais importante da história do Brasil, e no depoimento de um especialista que afirmou, baseado na Lei de Benford, que a probabilidade de ter ocorrido fraude nas últimas eleições presidenciais brasileiras foi de 73,14%, escolhi, “aleatoriamente”, os valores doados por pessoas físicas declarados pelo PT (Partido dos Trabalhadores) para a campanha de 2014 ao governo do Estado de São Paulo do então candidato Alexandre Padilha. Só existiam 899 registros no sistema do TSE, o que é pouco para aplicar a Lei, pois o ideal é que tivéssemos milhares de registros, mas essa quantidade serve para verificarmos algumas coisas:

DÍGITO BENFORD PT
1 30,103 34,483
2 17,609 25,584
3 12,494 9,455
4 9,691 4,449
5 7,918 5,228
6 6,695 5,451
7 5,799 6,007
8 5,116 4,004
9 4,576 5,339


Como você pode observar, os dígitos de 1 à 5 são dissonantes em relação à Benford, mas os maiores problemas estão nos dígitos 2 e 4: o dígito 2 está inflacionado e o dígito 4 é deficitário. Não estou afirmando que os dados foram maquiados, pois como informei é necessário um conjunto realmente grande de valores para que a Lei se aplique. Nesse caso, o resultado observado indica que os números informados devem ser revisados, pois podem ter sido lançados erroneamente.

Referências

1. BENFORD, Frank. The Law of Anomalous Numbers. Proceedings of the American Philosophical Society, Vol. 78, N. 4 (31/03/1938), pg 551-572, American Philosophical Society. Disponível em: [https://kupdf.net/download/the-law-of-anomalous-numbers_58c67f5adc0d60c64e33902b_pdf]. Acessado em 01/10/2018.
2. FEWSTER, R. M. A Simple Explanation of Benford’s Law. The American Statistician, Vol. 63, N. 1, Teachers Corner. Disponível em: [https://www.stat.auckland.ac.nz/~fewster/RFewster_Benford.pdf]. Acessado em 02/10/2018.
3. MONOLITO NIMBUS: o conhecimento está em toda parte. LEI DE BENFORD. Disponível em: [https://www.monolitonimbus.com.br/lei-de-benford/]. Acessado em 02/10/2018

Como Apresentar a Hierarquia de Subordinação de Registros no Oracle

Vamos supor que sua empresa tenha a seguinte estrutura organizacional:

Analisando um nível abaixo da categoria gerente, é fácil saber quem são os coordenados. Analisando um nível abaixo da categoria coordenador, é fácil descobrir quem são os funcionários, mas do ponto de vista do nível gerencial não há uma forma direta de chegar aos funcionários sem passar por cada coordenador. Suponha, por exemplo, que você queira saber quais são todos os funcionários de uma gerência. Em um banco de dados, seria necessário fazer uma espécie de auto-relacionamento recursivo ou algum tipo de “planificação” na estrutura organizacional para fazer um mapeamento 1:N no banco de dados:

A primeira solução seria difícil de manter. A segunda solução não é performática e uma consulta com IN apresenta limitações em certos SGBDs, como o Oracle. Descobri que o Oracle tem algumas funções auxiliares que emulam aquela primeira solução de forma nativa. Exploremos essas funções com um exemplo: vamos criar uma tabela chamada funcionário e populá-la com o organograma apresentado:

CREATE TABLE TBL_FUNCIONARIO (
   PK_FUNCIONARIO NUMBER(10) NOT NULL, 
   NM_NOME VARCHAR2(64) NOT NULL, 
   NM_CARGO VARCHAR2(64) NOT NULL, 
   FK_FUNCIONARIO_SUP NUMBER(10) NULL, 
   CONSTRAINT PK_FUNC PRIMARY KEY (PK_FUNCIONARIO),
   CONSTRAINT FK_FUNC_SUP FOREIGN KEY (FK_FUNCIONARIO_SUP) 
     REFERENCES TBL_FUNCIONARIO(PK_FUNCIONARIO)
);

INSERT INTO TBL_FUNCIONARIO
(PK_FUNCIONARIO, NM_NOME, NM_CARGO, FK_FUNCIONARIO_SUP)
VALUES (1, 'JOAO', 'GERENTE', NULL);

INSERT INTO TBL_FUNCIONARIO
(PK_FUNCIONARIO, NM_NOME, NM_CARGO, FK_FUNCIONARIO_SUP)
VALUES (2, 'MARIO', 'COORDENADOR', 1);

INSERT INTO TBL_FUNCIONARIO
(PK_FUNCIONARIO, NM_NOME, NM_CARGO, FK_FUNCIONARIO_SUP)
VALUES (3, 'PEDRO', 'COORDENADOR', 1);

INSERT INTO TBL_FUNCIONARIO
(PK_FUNCIONARIO, NM_NOME, NM_CARGO, FK_FUNCIONARIO_SUP)
VALUES (4, 'RICARDO', 'FUNCIONARIO', 2);

INSERT INTO TBL_FUNCIONARIO
(PK_FUNCIONARIO, NM_NOME, NM_CARGO, FK_FUNCIONARIO_SUP)
VALUES (5, 'MARCELO', 'FUNCIONARIO', 2);

INSERT INTO TBL_FUNCIONARIO
(PK_FUNCIONARIO, NM_NOME, NM_CARGO, FK_FUNCIONARIO_SUP)
VALUES (6, 'ROBERTO', 'FUNCIONARIO', 2);

INSERT INTO TBL_FUNCIONARIO
(PK_FUNCIONARIO, NM_NOME, NM_CARGO, FK_FUNCIONARIO_SUP)
VALUES (7, 'DANIEL', 'FUNCIONARIO', 3);

A tabela populada ficou assim:

PK_FUNCIONARIO NM_NOME NM_CARGO FK_FUNCIONARIO_SUP
1 JOAO GERENTE
2 MARIO COORDENADOR 1
3 PEDRO COORDENADOR 1
4 RICARDO FUNCIONARIO 2
5 MARCELO FUNCIONARIO 2
6 ROBERTO FUNCIONARIO 2
7 DANIEL FUNCIONARIO 3

Em seguida, vamos conhecer as funções que serão utilizadas para obter o resultado desejado. O operador PRIOR é necessário nas queries hierárquicas, que são aquelas que possuem a condição CONNECT BY: ela identifica qual coluna relaciona o registro filho ao seu pai.

Quando uma coluna é qualifica com o operador CONNECT_BY_ROOT, o Oracle retorna os dados do registro pai e cada relacionamento pai-filho é definido, ou seja, para cada registro, uma lista de todos os registros filhos, até o último nível abaixo (desde que não limitado pelo comando LEVEL N), é retornada.

A função SYS_CONNECT_BY_PATH não é necessária quando se utiliza o CONNECT_BY_ROOT, mas ela é útil para retornar toda a hierarquia ascendente de um determinado registro concatenada por algum caractere que você defina.

A consulta abaixo conecta todos os elementos apresentados para retornar a hierarquia organizacional de todos os funcionários:

  SELECT 
     CONNECT_BY_ROOT USU.PK_FUNCIONARIO AS PK_SUP_BASE
     ,SYS_CONNECT_BY_PATH (USU.NM_NOME, '/') AS PATH_NOME
     ,USU.FK_FUNCIONARIO_SUP AS FK_SUP
     ,USU.PK_FUNCIONARIO AS PK_FUNC
     ,USU.NM_NOME
  FROM TBL_FUNCIONARIO USU
  CONNECT BY PRIOR USU.PK_FUNCIONARIO = USU.FK_FUNCIONARIO_SUP
  ORDER BY PK_SUP_BASE;
PK_SUP_BASE PATH_NOME FK_SUP PK_FUNC NM_NOME
1 /JOAO 1 JOAO
1 /JOAO/MARIO 1 2 MARIO
1 /JOAO/MARIO/RICARDO 2 4 RICARDO
1 /JOAO/PEDRO/DANIEL 3 7 DANIEL
1 /JOAO/PEDRO 1 3 PEDRO
1 /JOAO/MARIO/MARCELO 2 5 MARCELO
1 /JOAO/MARIO/ROBERTO 2 6 ROBERTO
2 /MARIO/MARCELO 2 5 MARCELO
2 /MARIO/ROBERTO 2 6 ROBERTO
2 /MARIO 1 2 MARIO
2 /MARIO/RICARDO 2 4 RICARDO
3 /PEDRO/DANIEL 3 7 DANIEL
3 /PEDRO 1 3 PEDRO
4 /RICARDO 2 4 RICARDO
5 /MARCELO 2 5 MARCELO
6 /ROBERTO 2 6 ROBERTO
7 /DANIEL 3 7 DANIEL

Por fim, para trazer todos os funcionários da gerência do JOAO, basta aplicar a restrição abaixo:

SELECT * FROM (
  SELECT 
     CONNECT_BY_ROOT USU.PK_FUNCIONARIO AS PK_SUP_BASE
     ,SYS_CONNECT_BY_PATH (USU.NM_NOME, '/') AS PATH_NOME
     ,USU.FK_FUNCIONARIO_SUP AS FK_SUP
     ,USU.PK_FUNCIONARIO AS PK_FUNC
     ,USU.NM_NOME
  FROM TBL_FUNCIONARIO USU
  CONNECT BY PRIOR USU.PK_FUNCIONARIO = USU.FK_FUNCIONARIO_SUP
  ORDER BY PK_SUP_BASE
)
WHERE PK_SUP_BASE  = 1 ;
Categorias:banco de dados

O Valor do Conhecimento

No livro Você de Exatas – Nem Tudo Está Perdido, o Professor Ricieri contou uma história para ilustrar como é fundamental e poderoso aquilo que os alunos aprendem. Quando o problema que resolvemos exige muito conhecimento, mas é resolvido em pouco tempo, os empresários acreditam que os profissionais cobram preços altos demais. Comparado a que?

O professor tinha um colega consultor especializado em bicos injetores de maçaricos. Esse colega foi chamado com urgência em uma fábrica para descobrir porque oito dos vinte maçaricos apresentavam consumo exagerado de combustível. O consultor olhou, pensou não mais do que trinta segundos, pediu um martelo para o empresário, deu duas marteladas em cada um dos oito maçaricos e disse que o problema estava resolvido. Uma semana depois, verificou-se que o consumo de combustível desses oito maçaricos realmente havia diminuído. O consultor mandou a conta e o empresário não gostou do valor, pois aquele foi um trabalho cuja solução demorou menos de trinta segundos:

– Não acredito que o Sr. tenha a coragem de cobrar-me tanto por aquelas batidas!

– É exatamente este o valor do meu trabalho.

– Mas é muito caro! O Sr. só trabalhou 30 segundos!

– Só o que Dr. se esqueceu o quanto estudei para poder dar aquelas batidinhas certeiras que reduzirão o consumo de combustível toda semana.

Essa conversa reflete o quanto um profissional deve estudar para exercer sua especialidade com eficiência. Os empresários deveriam saber que o valor investido em uma atividade intelectual está mais relacionado à natureza e à criticidade do problema, ao retorno do investimento e ao nível técnico do profissional do que ao tempo gasto para dar uma solução. Se o consultor tivesse demorado 30 dias ao invés de 30 segundos para resolver o problema, provavelmente o empresário não questionaria o valor pedido, mas naquele caso, com certeza, o especialista demonstraria falta de capacidade técnica e/ou falta de caráter.

Referências

1. RICIERI, Aguinaldo P. Você de Exatas – Nem Tudo Está Perdido. Editora Prandiano, São Paulo, 1989. pgs 36-37

Categorias:Atitude

Criação de Virtual Hosts no Apache

No artigo Como Alterar o Tema da Aplicação Dinamicamente com JSF, expliquei os recursos que o JSF oferece para trocar o skin da aplicação conforme a URL digitada. Para testar, bastava modificar o arquivo hosts da sua máquina e configurar o seu navegador para que ele não utilize proxy para resolver endereços locais:

127.0.0.1  marketing.atitudereflexiva.com.br  financeiro.atitudereflexiva.com.br
localhost  marketing.atitudereflexiva.com.br  financeiro.atitudereflexiva.com.br

Qual o problema de se fazer essa configuração? Grosso modo, para efeito de testes, nenhum. Tá, se você estiver utilizando um servidor de aplicação, a porta configurada para requisições http é exibida na URL. No caso, a porta padrão do http é 8080:

http://marketing.atitudereflexiva.com.br:8080/aplicacao/

Para “esconder” a porta, você deve utilizar um servidor HTTP, como o velho Apache. Em ambiente de desenvolvimento é meio chato configurar o Apache como serviço. Por isso, vamos utilizar o XAMPP, que dentre outras coisas permite administrar o Apache de forma descomplicada.

Vamos configurar dois virtualhosts no Apache e redirecionar a porta 80 para o servidor de aplicação que estiver escutando a porta 8080. Esse redirecionamento pode ser feito no arquivo httpd.conf:

RedirectMatch ^/$ $1/aplicacao/

A instrução abaixo também funciona com a diferença de que o Apache se “lembra” do conteúdo capturado pela expressão regular entre parênteses e permite que acessemos cada uma delas com $1, $2, $3 e etc:

RedirectMatch ^(.*)/$ $1/aplicacao/

Porém, como queremos fazer apenas um redirecionamento simples e não uma reescrita de URL, podemos fazer o redirecionamento com uma instrução válida apenas para o virtual host criado. A vantagem de fazer dessa forma é que tudo que diz respeito ao virtual host fica em uma tag específica e não espalhada por outros lugares. Então, vamos configurar os virtual hosts no arquivo httpd-vhosts.conf:

<VirtualHost marketing.atitudereflexiva.com.br:80>
    ProxyRequests Off
    ProxyPass "/aplicacao/"  "http://marketing.atitudereflexiva.com.br:8080/aplicacao/"
    ProxyPassReverse "/aplicacao/"  "http://marketing.atitudereflexiva.com.br:8080/aplicacao/"
    Redirect "/" "http://marketing.atitudereflexiva.com.br/aplicacao/"
</VirtualHost>

<VirtualHost financeiro.atitudereflexiva.com.br:80>
    ProxyRequests Off
    ProxyPass "/aplicacao/"  "http://financeiro.atitudereflexiva.com.br:8080/aplicacao/"
    ProxyPassReverse "/aplicacao/"  "http://financeiro.atitudereflexiva.com.br:8080/aplicacao/"
    Redirect "/" "http://financeiro.atitudereflexiva.com.br/aplicacao/"
</VirtualHost>

Se você precisar disponibilizar algum recurso local para aquela URL, pode utilizar um DocumentRoot:

<VirtualHost financeiro.atitudereflexiva.com.br:80>
    ProxyRequests Off
    ProxyPass "/aplicacao/"  "http://financeiro.atitudereflexiva.com.br:8080/aplicacao/"
    ProxyPassReverse "/aplicacao/"  "http://financeiro.atitudereflexiva.com.br:8080/aplicacao/"
    Redirect "/" "http://financeiro.atitudereflexiva.com.br/aplicacao/"
    <Directory /home/storage/www/financeiro>
        Require all granted
        Options FollowSymLinks
        AllowOverride AuthConfig FileInfo
        Order allow,deny
        Allow from all
    </Directory>
    DocumentRoot /home/storage/www/financeiro
    Header set Access-Control-Allow-Origin "*"
    Header always set Access-Control-Allow-Methods "POST, PUT, GET, DELETE, OPTIONS"
    Header always set Access-Control-Allow-Headers "Content-Type"
</VirtualHost>

Os headers são necessários para evitar o problema de cross-origin HTTP requests no caso de arquivos javascript que tentam acessar o diretório que compartilhamos conforme descrito aqui. Segui as configurações desse fórum e para o meu caso funcionou. Quando você digitar a URL abaixo:

http://marketing.atitudereflexiva.com.br

O Apache fará um proxy interno para a porta que o servidor de aplicação espera e um redirecionamento específico para o contexto da aplicação:

http://marketing.atitudereflexiva.com.br/aplicacao

Se você estiver utilizando o JBoss, pode configurar sua aplicação para responder no “/” sem necessidade de digitar o contexto. Assim, não será necessário que o Apache faça quaisquer tipos de redirecionamentos.

Referências

1. [https://www.linode.com/docs/web-servers/apache-tips-and-tricks/redirect-urls-with-the-apache-web-server/]
2. [https://www.linode.com/docs/web-servers/apache-tips-and-tricks/rewrite-urls-with-modrewrite-and-apache/]
3. [https://www.devside.net/wamp-server/how-to-redirect-root-url-to-another-sub-directory-or-url]
4. [https://serverfault.com/questions/909200/htaccess-redirect-non-www-http-with-full-url]
5. [https://stackoverflow.com/questions/38175538/redirect-exact-url-to-another-url]
6. [https://alvinalexander.com/web/apache-redirectmatch-examples-wildcard-301]
7. [http://foundationphp.com/tutorials/apache_vhosts.php]
8. [https://serversforhackers.com/c/configuring-apache-virtual-hosts]

Categorias:Infraestrutura