terça-feira, 14 de fevereiro de 2017

Cloud programmers






O conceito de programador em nuvem (em inglês, cloud programmer) refere-se à utilização total da memória e das capacidades de raciocínio de um programador por meio de todos os meios de comunicações que estiverem disponíveis para abrir demandas.

O programador em nuvem pode ser acionado de qualquer lugar do mundo, a qualquer hora. Não há necessidade do programador comparecer a um local de trabalho, porque qualquer lugar onde ele possa conectar seu notebook e pegar sinal de celular é um local de trabalho. Você pode abrir demandas para o programador em nuvem remotamente, através da Internet, usando e-mail, mensageria instantânea, Skype, ou qualquer outro programa

O programador em nuvem tem elasticidade. Ele é capaz de aumentar a sua capacidade de resolver problemas de acordo com o aumento da demanda.

O programador em nuvem é multitarefa: ele trabalha em vários projetos simultaneamente. Ele usa várias janelas no seu desktop e vários monitores ao mesmo tempo. Ele codifica usando as mãos, os pés, a voz e os olhos. Enquanto ele desenvolve, atende ao telefone, participa de reuniões, faz relatórios e presta consultoria.

O programador em nuvem é 24X7. Não existe distinção entre vida profissional e vida social. Aliás, não existe vida social. Todos os recursos devem ser direcionados para o atendimento de demandas.

Você não precisa de mais programadores. Basta abrir as demandas para o programador em nuvem e ele automaticamente irá expandir o tempo para terminar dez demandas no período em que ele não conseguiria nem atender a uma.

O programador em nuvem está em algum local elevado, onde não existe necessidade de comida, lazer ou qualquer coisa mundana. Só precisa de um suprimento de oxigênio para o cérebro funcionar.

O programador em nuvem é onipresente. Envolva ele em quantos compromissos você quiser, agende quantas reuniões você precisar. Ele conseguirá tempo infinito para participar de todas as atividades dispensáveis e ainda fazer o seu trabalho.

Não fique preso à tecnologia

Filme: Homem de Ferro 2.
Cena: Tony Stark recebeu alguns objetos pessoais de seu pai Howard Stark, dados por Nick Fury, o diretor da S.H.I.E.L.D. Entre os objetos está uma fita de vídeo, com uma gravação feita em 1974.  Quando seu pai termina a mensagem para a Expo Stark, ele inicia uma outra mensagem para o filho. Nela, Howard diz que está limitado pela tecnologia de sua época, mas que Tony não, e por isso poderá realizar aquilo que ele projetou.

Howard Stark, pai de Tony Stark
Tony está sendo envenenado pelo paladium, o elemento utilizado no reator arc de seu peito, que o mantém vivo, desde que estilhaços de uma bomba se alojaram em seu peito, no Afeganistão. Ele precisa substituir o paladium por outro elemento químico, mas não existe um substituto disponível. A partir da mensagem do pai, Tony descobre que a maquete da Expo Stark é um esquema para a composição de um novo elemento químico. Ele cria um acelerador de partículas, e partir do esquema do pai, cria o novo elemento, que passa a usar em um novo reator.

Quero enfatizar a mensagem de Howard Stark, de que ele estava limitado pela tecnologia da época. Ela vale para o desenvolvimento de software. Nós também limitamos nossos projetos à tecnologia que temos disponível. Na verdade, é ainda pior que isso, ficamos presos a somente um tipo de tecnologia e passamos a criar arquitetura a partir de uma tecnologia existente, em vez de projetar a arquitetura e buscar as tecnologias que a implementam. Ficamos subjugados pelas soluções de software existentes e não inovamos por não desafiar as restrições que elas impõem.

Um arquiteto tem de ousar experimentar. Tem de ter uma atitude Oscar Niemeyer. Já pensaram se Niemeyer ficasse limitado às tecnologias de construção civil para conceber seus projetos. Ele viaja, ousa, depois verifica se é possível. Não sendo possível, pode rever o projeto. Mas ele não tem medo de ousar.

É natural que nos apeguemos ao passado, pois isso gera uma sensação de conforto. Aquilo que já vimos funcionar nos dá mais segurança. Não queremos arriscar, porque o sucesso é esquecido rapidamente, mas o fracasso é lembrado eternamente. Um sucesso não apaga um fracasso. Mas isso é decorrência do medo também, porque o fracasso sempre é uma possibilidade. Faz parte de qualquer empreendimento. Deve constar na avaliação de riscos. Mas não podemos trabalhos com risco zero. Conforme houver capacidade de recuperação, devemos tentar algo novo, algo inesperado.

Os primeiro carros eram parecidos com carruagens, porque esse era o modelo que o homem conhecia à época. Ele tentava criar uma carruagem sem cavalos. A medida que a lembrança das carruagens foi ficando mais distante, o carro começou a se tornar algo completamente diferente da carruagem. Mas mesmo assim, alguns ousavam. Veja a imagem abaixo.

Thomas Edison e um de seus carros elétricos
Um carro elétrico, produzido pelo inventor da lâmpada, Thomas Edison. Na verdade, os carros elétricos existiam desde 1830. Nos Estados Unidos houve uma época em que havia estações de recarga de baterias, no lugar de postos de gasolina. Hoje estamos discutindo a poluição causada pelos veículos a gasolina e uma das barreiras para substitui-los por carros elétricos é a falta de estações de recarga. Depois de quase um século, vemos que Thomas Edison SEMPRE ESTEVE CERTO QUANTO AO CARRO ELÉTRICO. Porque ousou experimentar.

Linux: Como saber quantos arquivos existem um um diretório

O comando abaixo: 

ls -laR | grep -v ^[.dlt] | grep -v ^$ | wc -l

lista todos os arquivos dentro do diretório atual, incluindo todos os seus subdiretórios. 

Você pode fazer o teste em um diretório com poucos arquivos e subdiretórios (que você consiga contar), só pra verificar que funciona mesmo. Eu obtive essa informação no site linuxquestions.org, por meio do usuário w1k0. Como seguramente irei esquecê-lo (tanto o comando quanto o link), registrei aqui para acesso rápido e compartilhado.

PHP e Python para Universitários - aula zero

Segundo o professor Carlos Yujiro Shigue (2009), "o Cálculo Numérico consiste na obtenção de soluções aproximadas de problemas de Álgebra Linear e Não-Linear, Estatística e Análise de Dados, Cálculo Diferencial e Integral e outros métodos matemáticos, utilizando métodos numéricos. Com a popularização de computadores de baixo custo e de alta capacidade de processamento, praticamente todas as atividades de Engenharia tem feito uso cada vez mais intensivo dos métodos e técnicas computacionais na resolução de problemas reais, para os quais as soluções manuais são impraticáveis e/ou imprecisas".

No entanto, o professor também chama a atenção para alguns problemas relacionados à aritmética computacional: 

  • "No computador, geralmente, a quantidade de operações aritméticas que se pode realizar é muito maior do que aquelas realizadas manualmente, de forma que o erro de arredondamento do dispositivo de cálculo se torna importante".
  • "No computador não temos como checar cada operação, tendo em vista a velocidade com elas são realizadas e também pela quantidade, que impossibilita a conferência dos resultados das operações aritméticas".

O professor Shigue mostra um exemplo de problema usando linguagem C:

void main() {
    int i;
    float soma = 0.;
    for(i=1;i<=10000;i++)
        soma = soma + .0001;
    printf("Soma = %10.7f", soma);

Veja, estamos somando 1 milionésimo mil vezes. Bem, 1000 X 0,001 = 1, certo? Por isso, o código acima deveria, teoricamente, imprimir o número 1, com sete zeros na parte fracionária. Mas em vez disso, segundo o professor, ele imprime 1.0000535. Eu fiz um teste criando um programa com o código acima. Compilei com o gcc 5.4.0 em uma máquina com Ubuntu 16.04. É claro que acrescentei no início a importação #include <stdio.h>, que o professor omite em sua nota de aula. Sem essa linha o código não funciona. Bem, eu obtive como resultado exatamente 1.0000535, confirmando o que o professor disse. 

Bem, meus amigos, tenho que lhes dizer que isso não acontece em PHP e Python. Fiz o código equivalente em PHP: 

<?php
$soma = 0;
for($i=1;$i<=10000;$i++)
    $soma = $soma + (float) 0.0001;
printf("Soma = %10.7f", $soma);

Executei esse código com o PHP 7.0.8 e o resultado foi este: 1.0000000

Fiz o código equivalente em Python:

soma = 0.0; 
for i in range(1,10001):
    soma = soma + 0.0001
print "Soma = %10.7f" % soma

Executei esse código com o Python 2.6.5 e o resultado foi este: 1.0000000 Ora, vejam só! PHP e Python são mais precisos que a linguagem C! 

É claro! Eles são escritos em C, mas aprimoram os recursos dela. Bem, para quem achava que PHP e Python não serviam para computação científica, se quiser envie uma mensagem perguntando como se resolvem problemas de matemática computacional com essas duas linguagens livres e podemos publicar outros artigos. Até lá.

Referência: Shigue, C. Y. Notas de Aula. Disponível em http://www.alunos.eel.usp.br/numerico/notas.html. Acesso em 13/04/2011.

Tipagem de Variáveis

Podemos considerar duas classificações para variáveis, uma baseada na manutenção dos tipos de dados existentes e outra baseada na definição de seus tipos. Para a primeira classificação, podemos distinguir dois tipos de variáveis: forte e fraca. Para a segunda temos outros dois: estática e dinâmica. A tipagem forte ocorre quando a linguagem não permite que uma variável tenha seu valor automaticamente alterado para outro tipo para possibilitar uma operação . A tipagem fraca ocorre quando a linguagem permite que uma variável tenha seu valor automaticamente alterado para outro tipo para possibilitar uma operação. A tipagem estática ocorre quando a linguagem obriga a prévia declaração de tipo de uma variável, sendo que uma vez definida, ela não pode mudar de tipo. A tipagem dinâmica ocorre quando a linguagem não obriga a prévia declaração de tipo de uma variável. O tipo é assumido na atribuição de valor à variável, que pode ser por presunção ou forçado com casting. Além disso, é possível modificar o tipo da variável atribuindo-lhe outro valor. 

Com relação a tipagem forte e fraca, podemos ver um exemplo simples utilizando os modos interativos de PHP e Python. Execute o Python no terminal: 

Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

Agora vamos criar duas variáveis. Uma chamada numero1 é um inteiro contendo o número 2. A segunda, chamada numero2 é uma string contendo o texto "3". Em seguida vamos tentar somar o conteúdo das duas variáveis.

>>> numero1 = 2 
>>> numero2 = "3" 
>>> print numero1 + numero2 
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str' 
>>> 

Como você pode ver, ocorreu um erro, pois as variáveis são de tipos diferentes. Ou melhor, não dá para adicionar um tipo inteiro a um string. Agora vamos fazer a mesma coisa em PHP. Primeiro, abra o modo interativo: 

 ~$ php -a 
Interactive mode enabled

php >


Agora tente somar um inteiro com um string: 

php > $numero1 = 2; 
php > $numero2 = '3';
php > print $numero1 + $numero2;

php >

Que interessante. PHP não se voltou para o programador e disse "seu burro, não posso somar um número com um texto!". A partir da operação, ele tomou uma decisão: 'é uma soma aritmética, então os dois operandos tem de ser números. como um deles é texto, vou converter seu conteúdo para inteiro, visto que não o número representado pelo texto não possui casas decimais'. Qual a conclusão que temos? 

Tanto PHP quanto Python possuem tipagem dinâmica. Não precisamos declarar as variáveis, elas assumem um tipo quando recebem um valor. Python, porém, possui tipagem forte. Você não pode executar uma operação se os tipos não forem os especificados pela operação. PHP, por outro lado, tem tipagem fraca. Ele altera o tipo de forma para se ajustar à operação. A tipagem do Python é melhor do que o PHP? Não. É apenas uma questão de abordagem. 

O Python está preocupado em impedir operações indevidas. O PHP, por outro lado, não está sendo conivente com elas, apenas oferece um mecanismo facilitador para o programador, que, se usado de forma indevida, é potencialmente perigoso. Lembre-se de que a mesma faca usada para passar manteiga no pão pode matar uma pessoa. Tudo depende de quem maneja a faca. Um último comentário. Em Python, todas as variáveis contém objetos, ou seja, todos os tipos são classes. Então ao atribuir um valor, a variável referencia um objeto que encapsula aquele valor. PHP, por sua vez, não converte valores automaticamente em objetos. 

Python é melhor do que PHP porque cria objetos pra tudo? Bem, será que você precisa de objetos pra tudo? Não existe melhor linguagem de programação. Existe aquela que é mais adequada para uma determinada aplicação. Utilizar uma única tecnologia para fazer tudo é como usar somente um tipo de material para todas as partes de uma construção. 

Referência: SEBESTA, Robert W. Conceitos de Linguagens de Programação. 5.ed. Porto Alegre. Bookman, 2003.

Segurança no PHP



O PHP é seguro? Essa não é a pergunta certa. A pergunta correta é se o programador PHP codifica de forma segura. Uma aplicação segura nada tem a ver com a linguagem de programação, mas com a arquitetura de software. 

A configuração adequada do ambiente de produção também deve ser uma preocupação. Coisas como deixar mensagens de erro serem vistos pelo usuário ocorrem em aplicações Java, Python, PHP, Ruby e são consequências de uma configuração feita sem preocupação com segurança. 

Para software, não basta performance. É preciso ter capacidade de se defender de ataques. Isso não significa que a aplicação deve ficar invulnerável. Significa que ela deve tornar a vida do atacante um inferno. Para software, não basta ser o Flash. É preciso ser o Superman. Mas saiba que sempre haverá kriptonita. 

Como parte da lenta, gradual e segura recuperação segura de conteúdo para o meu site (provocada pela migração para um novo provedor), estou novamente disponibilizando minha tradução do capítulo 10 do guia de certificação Zend. Esse capítulo é uma amostra grátis obtida na Amazon. Eu só fiz a versão em português. É uma leitura obrigatória para programadores PHP. Você pode obter a tradução aqui.

Para mais informações sobre segurança no PHP, você pode consultar a página do OWASP sobre segurança em PHP.

domingo, 5 de fevereiro de 2017

Criando e aplicando patches com GIT

Você fez um branch de um projeto com GIT e quer submeter um patch.

Veja bem, você não vai empurrar as suas alterações diretamente para o repositório remoto, você irá enviar um arquivo contendo as alterações para alguém aplicá-las, possivelmente, um revisor de código ou o git master.

Após fazer as alterações e executar o git commit, você utiliza o seguinte comando:

git format-patch master --stdout > [nome do arquivo].patch

O argumento master indica que as alterações serão aplicadas no branch master.

Vamos agora pensar do ponto de vista de quem recebe o patch. A pessoa que enviou deve ter explicado em um fórum, lista de discussão e/ou por um relato em um sistema de solicitações de mudança, o que ela fez. Mas você quer saber realmente o que será alterado, antes de aplicar o patch. Você pode ver as alterações antes de aplicá-las com o seguinte comando:

git apply --stat [nome do arquivo].patch

A próxima questão é saber se não haverá problemas em aplicar o patch. Você fazer um teste com o seguinte comando:

git apply --check fix_empty_poster.patch

Tendo certeza de que não haverá problemas, você pode aplicar o patch usando o seguinte comando:

git am --signoff < [nome do arquivo].patch

O argumento --signoff identificará que o commit resultante foi originário de um patch, incluindo o nome de usuário e e-mail que você configurou com git config.

Erros comuns no PostgreSQL II - comparação entre timestamps

Um modo de resolver problema de comparação de datas do tipo timestamp with timezone no PostgreSQL 8.4.8

Estou trabalhando na conversão de um banco MySQL para PostgreSQL. Embora exista uma SQL ANSI, cada banco tem seu dialeto particular. Além disso, há os tipos de dados específicos de cada banco.

Bem, eu tive de passar um campo de data para o tipo timestamp with timezone do PostgreSQL, versão 8.4.8. E na aplicação que usa o banco existem algumas consultas que fazem comparações de data.

Bem, havia uma comparação assim: 'expires_at' > NOW(). O campo expires_at é do tipo timestamp with timezone e a função NOW retorna o dia de hoje como timestamp with timezone também. Então, a princípio, eu estava comparando limão com limão e deveria funcionar.

Mas na execução, o PostgreSQL chiava dizendo que havia uma entrada inválida e apontava o campo expires_at. Peguei a documentação do PostgreSQL, na parte de funções de data e hora, e tentei desvendar o problema. Parecia não ter sentido, pois eu estava comparando coisas iguais.

Consultei um colega antes de submeter essa dúvida a um fórum, para verificar se não era algo trivial e evitar ser massacrado pelos especialistas, fartos de responderem questões perdidas na milésima página de resultados das buscas. Bem, não desvendamos o mistério, mas encontramos uma solução alternativa:

age(expires_at,now()) > interval '1 day'

Quer dizer, em vez de comparar as datas diretamente, eu comparei o intervalo. Mas isso não parecia elegante.

Depois de pensar bastante na mensagem de erro original, fiz um teste. O delimitador do PostgreSQL é apóstrofo. Mas em um paradoxo, coloquei o campo expires_at entre aspas. E funcionou. Por que? Não sei, só sei que foi assim.

Solução:

"expires_at" > now()

Estou contando porque se alguém passar por um problema parecido, há uma solução. Solução, não explicação.

Erros comuns no PostgreSQL - Superusuário sem senha


Você está usando uma distribuição Ubuntu. Acabou de instalar o PostgreSql, phppgadmin e pgadmin III, com o synaptic. Todo empolgado, abre o pgadmin III e tenta se conectar usando o usuário postgres. Certo, você não deveria usar o superusuário, deveria criar um usuário para o banco que vai utilizar. Mas você quer apenas saber se uma aplicação se conecta com o PostgreSQL, não quer modelar um banco de dados para uma situação real.

Bem, se receber esta mensagem:

Um erro ocorreu:

Error connecting to the server: FATAL:  autenticação do tipo password falhou para usuário "postgres"
FATAL:  autenticação do tipo password falhou para usuário "postgres"

A causa é muito simples: seu usuário postgres não tem senha. Basta criar uma senha para ele.

Como fazer isso?

Seu usuário precisa ter acesso de root, ou seja, ser administrador de sua máquina. Se isso for verdade, você pode dar o comando sudo su postgres e digitar a sua senha (a do seu usuário).

Em seguida, execute o comando psql. Ele abrirá o terminal de controle do PostgreSQL, que permite a você operar um SGBD. Nesse terminal, digite o seguinte comando:

alter role postgres encrypted password 'a senha que você quiser';

Pronto, agora você pode se conectar.