15 de junho de 2009

O input do python 3

No Python 2.x nós temos 2 modos de entrada de dados o input() e raw_input()
Primeiro vamos entender como cada um funciona pra depois sabermos como ficou agora e porque a mudança no Python 3

raw_input()
o raw_input() captura pela entrada padrão (sys.stdin.readline) tudo o que você digita (até apertar "enter") e lhe retorna como uma string, mais simples que isso impossivel, opcionalmente você pode também colocar uma mensagem quando chama o raw_input()
ex:
>>> raw_input()
1, 2, 3 # <-- usuario digita
'1, 2, 3'
raw_input retornou a string "1, 2, 3"
Se quisermos avisar o que tipo de dado estamos esperando podemos fazer:
>>> raw_input("Digite seu nome: ")
Digite seu nome: Larry # <-- usuario digita
'Larry'
Simples sem misterios.

input()
o input por outro lado é muito mais "esperto", tão esperto que a maioria embora acha que saiba, na verdade não tem noção de como ele funciona (eu já estive nesta lista)
muitos o input() é muito parecido com o raw_input() com a diferenca dele "avaliar" os tipo de dados e retornar os tipo "certo"
ex:
>>> x = input()
1
>>> type(x)
#input avalia a entrada como um inteiro
>>> input()
1, 2, 3
(1, 2, 3) # input retornava uma tupla de 3 inteiros

>>> input()
1, haha, 4.8
(1, 'haha', 4.8) #input retornava uma tupla com um inteiro uma string e um float
Então você pensa: "esse é o kra que eu vou usar sempre"
Mas o buraco é mais embaixo do que você pensa
ex:
>>> input("usuario digita: ")
usuario digita: if x
Traceback (most recent call last):
File "", line 1, in ;
File "", line 1
if x
^
SyntaxError: invalid syntax
WTF???
Sim amigo ele faz mais do que você pensa.
O "esperado" seria uma string "if x"
Na verdade o input() pega o que você digita, roda e da um retorno como uma expressão python, na verdade você disponibiliza um "terminal" python e pega o retorno
ex:
>>> x = 2
>>> input("usuario digita: ")
usuario digita: x + 3
5 #retorno de input() sera o valor da variavel x mais o int 3

>>> input("usuario digita: ")
usuario digita: x == 4 and "ola" or "NAUM e PAH"
"NAUM e PAH"
Se não for bem tratado isso pode ser MUITO perigoso.

Enquanto isso no Python 3...

No python 3.0 isso foi mudado, o raw_input() foi renomeado para input() se tornando o input padrão
- E o input() antigo?
Foi sumariamente REMOVIDO, exterminado, jogaram ele no marmore do inferno
Mas nem tudo está perdido, se você prestou atenção deve ter percebido que existe alguém que praticamente a mesma coisa que o antigo input com um pequena diferença. Eu estou falando do eval():
O eval() recebe um string faz e o mesmo que o antigo input() (na verdade seria o contrario, o input() faz o mesmo que o eval()), ele
avalia a string no interpretador python e retorna o resultado da expressão, da mesma forma que o console python faz.
Entao para se ter o mesmo efeito do antigo input basta chamar a funcao eval() pro retorno de input
>>> input()
1, 2, 3 # <-- usario digita
'1, 2, 3" # <-- string

>>> eval('1, 2, 3")
(1, 2, 3)

#portanto
>>> eval(input())
1, 2, 3 # <-- usario digita
(1, 2, 3) # <-- tupla
Quando você for converter seus programas python 2.x para 3 bastar usar eval(input()) e você terá o mesmo efeito (mas agora você sabe o motivo ;-) )

mais posts sobre Python:
1 - Vantagens do novo print do Python 3
2 - Diferencas entre o Python 3 vs Python 2.x
3 - Edje / QEdje (usando Python)4 - Receitas com Python
5 - Mini Curso PyGame - JED 2008

14 de junho de 2009

Vantagens do novo print do Python 3

A primeira diferença que se nota quando se muda para o python 3 e a mudança do print, que virou uma função e agora tem que ter os parênteses para funcionar
Antes o famoso "hello Word" era assim:
>>> print 'ola mundo'
agora fica assim:
>>> print ('ola mundo')
A principal vantagem está na padronização da função e na possibilidade de testar o print() com funções como o dir() e help(),
Antes:
>>> dir(print)
File "<stdin>", line 1
dir(print)
^
SyntaxError: invalid syntax
Agora:
>>> dir(print)
['__call__', '__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
O mesmo acontecia com o help(), por falar nele fica mais fácil para os iniciantes saberem como fazer para, por exemplo, enviar a saída do print para um arquivo, e usar o print como um log, (ou mudar a saída padrão)
Antes:
>>> arquivoLog = open("log.txt", "a")
>>> print>>arquivoLog, "imprimindo no arquivo de log"

>>> print>>sys.stderr, "imprimindo na saida padrao"
Agora:
>>> arquivoLog = open("log.txt", "a")
>>> print("imprimindo no arquivo de log", file=arquivoLog

>>> print("imprimindo no saida padrao", file=sys.stderr)
Agora é possivel usar separadores quando temos varios objetos para imprimir:
>>>print(1, 2, 3, sep=" - ")
1 - 2 - 3
E definir o caractere de fim de linha (o padrão é o '\n'):
>>>print("mensagem", end=" - log\n")
mensagem - log/n
A sintax da função print() ficou assim:
>>>print([objeto, ...][, sep='separador'][, end='caractere final de linha'][, file=arquivoDirecionado])

Pra mim o antigo print ja vai tarde ;)

mais posts sobre Python:
1- Diferencas entre o Python 3 vs Python 2.x
2 - Edje / QEdje (usando Python)3 - Receitas com Python
4 - Mini Curso PyGame - JED 2008

Diferencas entre o Python 3 vs Python 2.x

Na universidade que eu faço, a UFRPE, nós temos a tradição de usar o python como linguagem "oficial". Portanto eu tenho usado Python a pelo menos 3 anos e a 2 profissionalmente, a algum tempo (+- 6 meses atrás) saiu uma nova versão do Python a 3 ou 3000 ou 3k (escolha o nome que achar melhor), e as opiniões são as mais variadas possíveis, algumas mudanças a tempos era discutida e os caminhos que a linguagem seguia pedia algumas dessas mudanças, e o "Ditador Benevolente do Python" vulgo Guido van Rossum juntamente com os hacker do python após grande discussões chegaram a várias mudanças, algumas, mesmo na versão 3.0, ainda não estão totalmente implementadas e alguns problemas de desempenho ainda existem.
Entre as mudanças mais pedidas e que não foram colocadas no python 3 é o polémico self obrigatório em todos os métodos de uma classe, (assunto de post futuro).
O grande problema para a maioria está na não compatibilidade entre as versões, programas pequenos podem ser facilmente alterados, basicamente substituindo print por print() e input() por eval(input()), mas grandes aplicativos, principalmente os que fazem uso de módulos externos, terão grande trabalho para portar seus aplicativos. Agora é principalmente o momento de portar módulos, vai demorar um tempo até termos tomos os módulos devidamente portados, por esses e outros motivos a comunidade vai continuar por aproximadamente 3 anos mantendo e desenvolvendo em paralelo a versão 2.x, agora na versão 2.6 e que tem certo a saída de uma versão 2.7 (talvez até uma 2.8), com o objetivo de "suavizar" a transição do python 2.x pro 3.

Não era minha intenção falar sobre isso, mas devido as duvidas (minhas e de outros), resolvi dar uma estudada sobre o assunto e vou colocar por aqui as minhas impressões sempre que possível.

Ficarei atualizando este post com os novas postagens ficando um índice para os posts sobre esse assunto:
  1. Vantagens do print no Python 3
  2. O input do python 3
mais posts sobre Python:
- Edje / QEdje (usando Python)- Receitas com Python
- Mini Curso PyGame - JED 2008

Mais informações sobre as "novidades" do python 3 no site oficial