Willian Fernandes

Desenvolvimento Web com Python, SQLObject e PSE – Parte 3

Comente »

Continuando com a série sobre desenvolvimento web[bb] com Python[bb], vou mostrar agora como deixar as coisa mais interessante com includes e formulários.

Includes

É muito comum utilizar arquivos separados que estarão em várias partes da aplicação. Por exemplo, podemos ter um arquivo para o cabeçalho HTML[bb], um outro para o menu e um terceiro para o rodapé do HTML[bb].

Mas antes de criarmos nossos arquivos de include, teremos que configurar o PSE para apontar para nosso diretório de includes. Para isso abra o arquivo pse.conf (no Linux este arquivo fica em /etc/pse/pse.conf). Procure pela linha

;IncludePath = /app/servlet/path,/other/servlet/path

E troque por:

IncludePath = /var/www/includes,.

Caso você não esteja usando Linux[bb] (eu uso o Ubuntu[bb]) configure para o diretório que o Apache aponta. Isso muda de sistema para sistema.
Dentro deste diretório crie um sub-diretório chamado includes e dentro deste sub-diretório vamos colocar os arquivos abaixo:

cabecalho.pt

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="pt-BR">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Biblioteca ABC</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="language" content="pt-br" />
</head>
<body>
    <div id="geral">
        <div id="topo">
            <h1>Biblioteca ABC</h1>
        </div>
        <div id="menu">
            <ul>
                <li class="primeiro"><a href="home.pt">Home</a></li>
                <li><a href="categorias_list.pt">Categorias</a></li>
                <li><a href="livros_list.pt">Livros</a></li>
                <li><a href="clientes_list.pt">Clientes</a></li>
                <li class="ultimo"><a href="sair.pt">Sair</a></li>
            </ul>
        </div>

rodape.pt

        <address class="rodape">
            &copy; Biblioteca ABC
        </address>
    </div>
</body>
</html>

Ok, os arquivos estão criados!
Agora vamos criar o arquivo principal do nosso sistema. Este arquivo terá um formulário de login, porém ele fará include do cabeçalho e do rodapé.
Salve o arquivo abaixo na raiz de onde ficará a sua aplicação, ou seja, em um diretório acima do sub-diretório includes.

index.pt

<?= pse.include("cabecalho.pt") ?>
<form id="frm-login" method="post" action="">
    <fieldset>
        <legend>Logar no Sistema</legend>
        <label>E-mail: <input type="text" id="email" name="email" /></label>
        <label>Senha: <input type="password" id="senha" name="senha" /></label>
        <input type="submit" id="entrar" name="entrar" value="Entrar" class="botao" />
    </fieldset>
</form>
<?= pse.include("rodape.pt") ?>
 

Perceberam o quanto é simples?
Toda página PSE possui um objeto chamado pse que contém vários métodos e objetos e no exemplo acima utilizamos o método include. Mais para frente mostrarei outras funcionalidades do objeto pse.

O método include recebe como parâmetro o nome do arquivo que iremos incluir. O PSE procura este arquivo nos diretórios que configuramos no arquivo pse.conf.

Para não prolongar muito, explicarei como trabalhar com formulários utilizando PSE no próximo post.

Prometo não demorar muito para postar o próximo post da série e aproveito para pedir o feedback de vocês em relação à esta série.

Usando Ruby para trabalhar com datas

Comente »

Foi publicado como “Converter formato de data do MySQL para o formato BR, em uma linha de código só” usando PHP[bb], o DGMike mostrou como ficaria sua versão em Python[bb], eu até fiz minha contribuição lá mostrando como eu faria em Python usando um objeto datetime e agora resolvi fazer o mesmo em Ruby[bb], já que estou estudando essa linguagem:

data = '2008-08-12'
td = []
data.split('-').each{ |d| td << d.to_i}
d = DateTime.new(td[0], td[1], td[2])
ndata = d.strftime('%d/%m/%Y')

[ATUALIZADO]
Respondendo a pergunta do d3rf e aproveitando a dica do Caio Moritz:

'2008-08-12'.split('-').reverse.join('/')

Aguarde, em breve voltarei com o desenvolvimento em Python com PSE e SQLObject!!!

Desenvolvimento Web com Python, SQLObject e PSE – Parte 2

Comente »

Continuando o post anterior, vamos agora instalar e configurar nosso ambiente para começar o desenvolvimento com Python, SQLObject e PSE.

Vou assumir que você utiliza Ubuntu, ou qualquer outra distribuição Linux baseada no Debian. Caso você utilize outro Sistema Operacional, verifique na página oficial dos programas (veja no post anterior) como instalar cada um deles.

O Elcio publicou um post explicando, detalhadamente, como instalar o apache2, o mod_python e o PSE na versão 7.10 do Ubuntu, incluindo uma correção necessária para essa versão do Ubuntu.

Após executar os passos descritos pelo Elcio, falta apenas instalar o SQLObject:

sudo apt-get install python-sqlobject
[ATUALIZADO] Seguindo a dica do Elcio:
sudo apt-get install python-mysqldb python-setuptools
sudo easy_install sqlobject

Tudo instalado e configurado? Ok, agora vamos entender um pouco o funcionamento do PSE para depois desenvolvermos algo funcional.

O PSE trabalha com arquivos na extensão .pt, então vamos fazer um teste criando um arquivo chamado hello_world.pt no diretório do apache (no Ubuntu esse diretório fica em /var/www):

<?="Hello World"?>

As tags <? e ?> indicam a abertura e o fechamento de código Python e tags especiais do PSE, que veremos mais adiante.

Execute no navegador: http://localhost/hello_world.pt.

Vamos alterar agora nosso arquivo para integrar código Python com o PSE gerado:

hello_world.pt

<?= msg ?>

hello_world.py

import datetime
msg = "Hello Word<br>Hoje é %s" % datetime.date.today().strftime("%d/%m/%Y")

Execute novamente no navegador: http://localhost/hello_world.pt.

Perceba que escrevemos código Python normalmente e que o arquivo hello_world.pt identificou a variável msg e escreveu seu conteúdo na tela. Isso acontece porque o PSE integra automaticamente arquivos que tenham o mesmo nome, ou seja, ele sempre executara hello_world.py junto com hello_world.pt.

No próximo post mostrarei como trabalhar com includes no PSE e formulários. Prometo que os próximos posts não demorarão tanto quanto este. ;)

Retornando o último número (script JavaScript)

Comente »

O DGmike publicou o post Retornando o último número (script PHP), o Elcio mostrou a visão dele em Retornando o último número (script Python) e resolvi fazer o mesmo em JavaScript[bb]:

function ultimoNumero(str) {
    return str.match(/\d+/g).pop();
}

[UPDATE]

Uma simples correção para quando não for passado uma string e para quando a string for vazio ou não tiver números:

function ultimoNumero(str) {
    try {
        return str.match(/\d+/g).pop();
    } catch(e) {
        return '';
    }
}

Muito simples, não?

Desenvolvimento Web com Python, SQLObject e PSE – Parte 1

Comente »

Já faz um tempo que estou ensaiando para escrever sobre como desenvolvemos aplicações web[bb] lá na Visie. Nós utilizamos Python porque amamos essa linguagem e achamos uma dupla excelente para auxiliar no desenvolvimento Web. Estou falando do PSE e do SQLObject.

Existem muitas alternativas que permitem a criação de aplicações web com Python, mas a que irei apresentar nessa série de artigos é a que prefiro.

Primeiro explicarei do que se trata cada ingrediente que utilizaremos e depois como instalá-los, configurá-los e como utilizá-los.

Python
Uma linguagem dinâmica, interativa e orientada a objetos. Diferente de linguagens como o PHP[bb], Python possui tipagem forte, mas não necessita de declarações de variáveis. É uma linguagem interpretada e não compilada, como JAVA[bb] e DotNet[bb].

falei sobre Python anteriormente, citando exemplos comparativos com PHP. Mas se você ainda não conhece a linguagem e quiser aprender sobre ela, segue abaixo uma lista de sites que recomendo:

SQLObject
Trata-se de uma biblioteca de mapeamento objeto-relacional[bb] escrita em Python.
O objetivo do SQLObject é o mesmo do Hibernate[bb] para JAVA e do nHibernate para DotNet: permitir que as tabelas de um banco de dados sejam mapeadas e utilizadas como objetos dentro do programa.

Felizmente, o SQLObject possui uma documentação completa disponibilizada online.

PSE
É um framework escrito em Python que permite a publicação de páginas na web. Necessita do Apache e do mod_python instalados e configurados para funcionar.
Seu funcionamento é parecido com o Framework SmartyTemplate, feito para PHP. Mas ele vai muito além, pois nos permite: efetuar requisições de dados enviados por formulários (POST) e de QueryStrings (GET), a criação de Sessões e Cookies, a criação de tags customizadas (Custom Tags), a recuperação do IP do usuário, etc.

Maiores informações podem ser encontradas no site oficial e no manual.

 

Após apresentar os ingredientes necessários para a utilização do Python no desenvolvimento web, mostrarei como instalar e configurar todos os ingredientes para podermos colocar a mão na massa.
Para este post não ficar muito extenso, publicarei a instalação e a configuração em um próximo post.

Palestras

Comente »

Na semana que vem, do dia 09/11 até o dia 11/11, acontecerá a 5ª edição do CONISLI (Congresso Nacional de Software Livre).

O evento visa promover o Software Livre através de palestras, mini-cursos e tutoriais apresentados por profissionais que utilizam Software Livre no seu dia-a-dia.

Eu acompanho o CONISLI desde 2004, e na edição desse ano fui convidado como palestrante do evento. Confesso que fiquei muito contente com o convite, mas não foi nada fácil pensar em um tema para apresentar em um evento tão grande e que conta com muitas pessoas que poderiam estar lá, no meu lugar, apresentando a palestra.

Depois de longo tempo pensando e conversando com algumas pessoas resolvi falar sobre “Desenvolvimento Web com Python, SQLObject e PSE”.

Agora que a palestra está confirmada, as datas marcadas, o conteúdo da palestra quase pronto, voltarei a publicar novos posts aqui no blog. Muitos deles sobre o tema da palestra.

Inscrições e Grade de Horários:

Também fui convidado como palestrante do PHPConference Brasil 2007. Assim que liberarem eu postarei as informações sobre esse evento.

E os Padrões Web?

Comente »

Atualmente estou alocado em um cliente, desenvolvendo um projeto de grande porte. Esse cliente reformulou todo o seu site e estão tendo alguns problemas com as mudanças.

Ontem ouvi uma conversa vindo de uma mesa próxima a minha. Aquela conversa me deixou indignado a ponto de colocar o fone de ouvido, procurar algumas músicas do System of a Down e aumentar o volume do som. Veja um trecho da conversa:

Fulano 1: Cara, você conhece o navegador Safari?
Fulano 2: Sim, é um navegador da Apple.
Fulano 1: Você tem ele instalado aí?
Fulano 2: Aqui não, tenho somente em casa. Por quê?
Fulano 1: Você já acessou o novo site da Nossa Empresa no Safari? Tem alguns clientes ligando aqui dizendo que o site fica todo desformatado no Safari.
Fulano 2: Não, ainda não abri. Mas abri no no Firefox e vi que nele também fica desformatado. O menu vai parar no canto da tela…
Fulano 1: Assim não dá! Não posso fazer uma programação diferente para cada tipo de navegador! O usuário que se vire para acessar o site. Ele que utilize o Internet Explorer para navegar em nosso site. No IE funciona perfeitamente.
Fulano 2: Acho que você terá que fazer um “scriptizinho” para identificar o navegador do usuário e utilizar um JavaScript para cada navegador.

E depois disso a conversa foi piorando cada vez mais… Fazia tempo que eu não ouvia alguém falando um absurdo desses e achava que não ouviria mais.

Para que servem os Padrões Web? E a programação de JavaScript Cross-browser?

Muitas pessoas, assim como eu, ouviram esse diálogo e, na hora do almoço, foi o comentário da mesa…rs Daí comecei a chegar em uma conclusão:
A maioria das pessoas que estavam na mesa tinham aproximadamente 25 anos de idade. Os dois aí da conversa devem ter ultrapassado os 30. Será que isso é problema de pessoa mais velha?
Será que só porque a pessoa é mais velha ela tem o direito de não acompanhar a evolução da Web?

Não é possível. Conheço pessoas com mais de 30 anos que sabem, e sabem muito, os Padrões Web, JavaScript Cross-browser, Acessibilidade, e o quanto é importante tudo isso.

Não sei no que deu o final da história. O fone de ouvido e as pesadas músicas do System of a Down me salvaram de ouvir o resto. Mas acredito que gambiarras virão para que o site funcione pelo menos no Firefox.

Eu não tenho medo de JavaScript

Comente »

Muitos desenvolvedores possuem medo (ou será preconceito?) quando alguém lhe diz que precisarão desenvolver algo em Client-Side.

Recentemente, o Elcio e eu participamos de um projeto que não tinha nenhuma linha de código Server-Side (PHP, Python, Ruby, etc), era puro JavaScript.

Sim, sabemos que não podemos prender o usuário ao JavaScript. Sabemos que devemos permitir que o usuário navegue pelo site mesmo se ele não estiver com o JavaScript habilitado no navegador dele. Mas não podemos ser radicais. Existem alguns casos que permitem o desenvolvedor não se preocupar com questões de Acessibilidade e JavaScript Não-Obstrutivo, esse era o nosso caso.

Com a combinação de AJAX, DOM e JSON podemos fazer coisas incríveis sem precisar, na maioria das vezes, de uma linguagem Server-Side. Veja como exemplo o Wallpapr, uma aplicação desenvolvida pelo Marco Gomes utilizando o framework jQuery e sem nenhuma linguagem Server-Side.

Assim que comecei a ouvir falar do framework jQuery comecei a estudá-lo e estou ficando cada vez mais curioso em aprendê-lo, mas até agora não consegui fazer testes reais. Por isso irei escrever uma série de posts falando sobre a utilização do jQuery, desenvolvimento de JavaScript Orientado à Objetos e JSON, muito JSON.

Até o próximo post!

Que tal medir a velocidade do seu site?

Comente »

WebWait é um serviço interessante que acabei de conhecer.

O serviço é bem simples, você coloca uma URL e ele mede o tempo em segundos que o site demorou para carregar por completo.

Veja alguns resultados:

O Fantástico Mundo do Python – Parte 1

Comente »

Gosto muito de programar, principalmente para Web. Sempre gostei muito de PHP e outras linguagens/tecnlogias do mundo Open Source, apesar de também ter trabalhado bastante com ASP/ASP.NET (C#) meu principal foco foi o mundo Open Source.

Há um pouco menos de um ano comecei a estudar Python e cada dia que passa meu interesse por essa linguagem aumenta mais e mais.

Assim que lancei o blog recebi alguns comentários e e-mails de pessoas pedindo conteúdo de Python, pois sempre ouvem falar desta linguagem e gostariam de saber como ela é. Por isso resolvi listar algumas diferenças entre Python e PHP (umas das linguagens mais usadas no Brasil).

Abaixo segue uma lista com algumas diferenças entre a sintaxe e a estrutura de dados do PHP e do Python:

1. Criando listas (arrays)

PHP

$numeros = array(1,2,3,4,5);
echo "O número " . $numeros[1] . " é segundo número da lista";

Python

numeros = [1,2,3,4,5]
print "O número %i é segundo número da lista" % numeros[1]

2. Criando dicionários (arrays associativos)

PHP

$numeros = array(
    "um" => 1,
    "dois" => 2,
    "tres" => 3,
    "quatro" => 4,
    "cinco" => 5
);
echo "O número " . $numeros["dois"] . " é segundo número da lista";

Python

numeros = {
    "um":1,
    "dois":2,
    "tres":3,
    "quatro":4,
    "cinco":5
}
print "O número %i é segundo número da lista" % numeros["dois"]

3. Percorrendo a lista (array)

PHP

$numeros = array(1,2,3,4,5);
for ($i = 0; $i &lt; count($numeros); $i++) {
    echo $numeros[$i];
}

Python

numeros = [1,2,3,4,5]
for i in numeros:
    print i

4. Verificando se uma chave existe em um dicionário (array associativo)

PHP

$numeros = array(
    "um" => 1,
    "dois" => 2,
    "tres" => 3,
    "quatro" => 4,
    "cinco" => 5
);
if (array_key_exists("um", $numeros)) {
    echo "A chave existe";
}

Python

numeros = {
    "um":1,
    "dois":2,
    "tres":3,
    "quatro":4,
    "cinco":5
}
if numeros.has_key("um"):
    print "A chave existe"

5. Replaces em String

PHP

$titulo = "{NOME} e o Pé de Feijão";
$titulo = str_replace("{NOME}", "João", $titulo);
//Ou, para simplicar em uma única linha
$titulo = str_replace("{NOME}", "João", "{NOME} e o Pé de Feijão");

Python

titulo = "{NOME} e o Pé de Feijão"
titulo = titulo.replace("{NOME}", "João")
#Ou, para simplicar em uma única linha
titulo = "{NOME} e o Pé de Feijão".replace("{NOME}", "João")

6. Escrevendo uma parte da String

PHP

$titulo = "João e o Pé de Feijão";
echo substr($titulo, 9, 2);

Python

titulo = "João e o Pé de Feijão"
print titulo[9:11]

7. Verificando tipo da variável

PHP

$var = "Teste";
if (is_array($var)) {
    echo "É array";
}
elseif (is_string($var)) {
    echo "É string";
}
elseif (is_integer($var)) {
    echo "É inteiro";
}

Python

var = "Teste"
if type(var) == list:
    print "É array"
elif type(var) == str:
    print "É string"
elif type(var) == int:
    print "É inteiro"

8. Estrutura de controle

PHP

$n = 4;
if ($n == 1) {
    echo "Um";
}
elseif ($n == 2) {
    echo "Dois";
}
else {
    echo "Maior que dois";
}

Python

n = 4
if n == 1:
    print "Um"
elif n == 2:
    print "Dois"
else:
    print "Maior que dois"

9. Definindo funções

PHP

function Teste() {
    echo "teste";
}
Teste();

Python

def Teste():
    print "teste"
Teste()

10. Definindo classes

PHP

class TestePai {
}
class Teste extends TestePai {
    public function __construct() {
        echo "Esta é a classe Teste que faz herança da classe TestePai.";
    }
}
$t = new Teste();

Python

class TestePai:
    pass
class Teste(TestePai):
    def __init__(self):
        print "Esta é a classe Teste que faz herança da classe TestePai.";
t = Teste()

Perceba que, em todos os casos, acabamos escrevendo menos código em Python do que em PHP. Isso por que em Python temos uma estrutura de dados mais simples e sua forma de trabalhar sempre com objetos facilita muito a vida do programador. Ao invés de ficarmos decorando milhares de funções em PHP, decoramos somente alguns métodos em Python.

Particularmente, acho mais fácil decorar métodos do que funções, isso porque os métodos se diferenciam entre os tipos de objetos disponíveis na linguagem. Além disso, se eu estiver com dúvida se algum método existe ou não em determinado objeto, basta utilizar a função dir:

>>> minha_lista = [1,2,3,4]
>>> dir(minha_lista)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__',
'__eq__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__',
'__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__',
'__setattr__', '__setitem__', '__setslice__', '__str__', 'append', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']
>>> lista.sort()

Ao digitar a função dir() passando como parâmetro o objeto minha_lista, podemos ver todos os método que um objeto do tipo list possui.

Em posts futuros colocarei exemplos mais complexos, e quem sabe envolvendo outras linguagens também…

Você pode sugerir um exemplo, basta escrever nos comentários…