Escolar Documentos
Profissional Documentos
Cultura Documentos
1. O básico
Para começar, pense em Python como sendo pseudo-código. Isto é quase uma
verdade. Variáveis não têm tipos, assim você não precisa declará-las. Elas são
criadas quando você lhes atribui um valor, e são destruídas quando não forem
mais usadas. A atribuição é feita pelo operador =. A igualdade é testada com o
operador ==. Você pode atribuir mais de uma variável ao mesmo tempo:
x,y,z = 1,2,3
primeiro, segundo = segundo, primeiro
a = b = 123
for i in [1,2,3,4,5]:
print("Esta é a iteração número", i)
x = 10
while x >= 0:
print("x ainda não é negativo.")
x = x-1
A variável de índice no laço for varia de acordo com os elementos de uma lista
(escrita como no exemplo). Para fazer um laço for comum (isto é, um laço de
contagem), use a função embutida range().
# Mostra os valores de 0 a 99 inclusive.
for valor in range(100):
print(valor)
Vejamos: agora você já sabe o suficiente (em teoria) para implementar qualquer
algoritmo em Python. Vamos incluir alguma interação básica com o usuário.
Para obter dados do usuário (a partir de um prompt texto), use a função
embutida input.
A função input mostra o texto dado (o qual pode ser vazio) e deixa o usuário
entrar qualquer valor válido em Python. Neste caso nós estamos esperando um
número - se alguma outra coisa (como uma string) for fornecida, o programa
poderá falhar. Para evitar isto nós devemos implementar alguma checagem de
erro.
Eu não vou entrar em detalhes aqui; é suficiente dizer que se você deseja
receber o dado do usuário, literalmente como uma string (assim qualquer coisa
pode ser fornecida), use a função raw_input. Se você deseja converter uma
string s para um inteiro, você poderia usar int(s).
Nota: Se o usuário deseja fornecer uma string com input, ele deverá escrever as
aspas explicitamente. Em python, as strings podem ser delimitadas com aspas
simples ou duplas.
x = [[1,2,3],[y,z],[[[]]]]
Uma das coisas mais interessantes sobre as listas é que os seus elementos
podem ser acessados separadamente ou em grupos, através de indexação e
corte em fatias. A indexação é feita (como em muitas outras linguagens) pela
colocação do índice entre os colchetes (Note que o primeiro elemento tem
índice 0).
nome[0] = "Smith"
O corte em fatias é parecido com a indexação, indicando-se os índices inicial e
final separados por dois pontos (":")
x = ["spam","spam","spam","spam","spam","eggs","and","spam"]
E agora, o que há sobre os dicionários? Para ser breve, eles são como listas, mas
o seu conteúdo não está ordenado. Como você os indexa então? Bem, cada
elemento tem uma chave, ou um "nome" que é usado para buscar o elemento
tal qual um dicionário de verdade. Eis dois dicionários como exemplo:
2. Funções
Próximo passo: Abstração. Queremos dar um nome a um pedaço de código, e
chamá-lo com um parâmetro. Em outras palavras - nós queremos definir uma
função (ou "procedimento"). Isto é fácil. Use a palavra-chave def assim:
def quadrado(x):
return x*x
print(quadrado(2)) # Mostra 4
Para quem pode entender: todos os parâmetros em Python são passados por
referência (como, por exemplo, em Java). Para quem não entende: Não se
preocupe com isto :)
Python tem muitas coisas "legais" como argumentos com nome e argumentos
com valor padrão, podendo manipular um número variável de argumentos para
uma função. Para mais informações sobre isto, veja a seção 4.7 do tutorial de
Python.
Se você sabe como usar funções em geral, isto é basicamente o que você
precisa saber sobre elas em Python. (Ah, sim... A palavra-chave return termina a
execução da função e retorna o valor dado.)
Uma coisa que é útil saber, entretanto, é que as função são valores em python.
Assim se você tem uma função como quadrado, você pode fazer alguma coisa
assim:
figura = quadrado
figura(2) # Mostra 4
Para chamar uma função sem argumentos você deve lembrar de escrever func()
e não func. A segunda forma, como mostrado, somente retorna a própria
função, como um valor. (Isto ocorre com os métodos dos objetos também...
Veja abaixo.)
3. Objetos e coisas...
Eu suponho que você saiba como funciona a programação orientada a objetos.
(De outra forma, esta seção não faria muito sentido. Sem problemas... Comece a
brincar sem os objetos :).) Em Python você define classes com a palavra-chave
(surpresa!) class, assim:
class Cesta:
def adicione(self,elemento):
self.conteudo.append(elemento)
def mostre_me(self):
result = ""
for elemento in self.conteudo:
resultado = resultado + " " + "elemento"
print("Contém:" + resultado)
Aqui, spam pode ser chamado com um ou zero parâmetros. Se nenhum for
usado, então o parâmetro idade terá o valor 32. "Lógica de curto-circuito." Este
é um ponto... Veja abaixo.
Todos os valores em Python podem ser usados como valores lógicos. Alguns
dos mais "vazios", tais como [], 0, "" e None representam o valor lógico "falso",
enquanto o resto dos valores (como [0], 1 ou "Olá Mundo" representam o valor
lógico "verdadeiro".
Assim, expressões lógicas como a and b são avaliadas deste modo: Primeiro,
verifique se a é verdadeiro. Se não, então simplesmente retorne-o. Se sim, então
simplesmente retorne b (o que irá representar o valor lógico da expressão.). A
lógica correspondente para a or b é: se a é verdadeiro, então retorne-o, Se não
é, então retorne b.
if a:
print(a)
else:
print(b)
print(a or b)
if conteudo:
self.conteudo = conteudo
else:
self.conteudo = []
É claro, agora você sabe como fazer de uma forma melhor. E por que nós não
demos o valor padrão [] no começo? Porque da maneira como o Python
funciona, isto daria a todas as Cestas a mesma lista vazia como valor padrão.
Tão logo uma das listas começasse a ser preenchida, todas as outras teriam os
mesmo elementos, e o padrão não seria mais vazio... Para aprender mais sobre
isto você deveria ler a documentação e procurar a diferença entre identidade e
igualdade.
Você pode adivinhar como isto funciona? Ao invés de usar a mesma lista vazia
para todos, nós usamos a expressão conteudo[:] para fazer uma cópia (Usamos
uma fatia que contém a lista toda.)
Assim, para fazer uma Cesta e usá-la (isto é. para chamar alguns dos seus
métodos) nós devemos fazer algo assim:
b = Cesta(['maçã','laranja'])
b.adicione("limão")
b.mostre_me()
Há outros métodos mágicos além do init. Um desses métodos é str que define
como o objeto será conhecido quando for tratado como uma string. Nós
poderíamos usar este método ao invés de mostre_me:
def __str__(self):
result = ""
for elemento in self.conteudo:
resultado = resultado + " " + "elemento"
return "Contém:" + resultado
print(b)
class CestaSpam(Cesta):
# ...
Python permite herança múltipla, assim você pode ter várias superclasses entre
parênteses, separadas por vírgulas. Classes são instanciadas assim: x = Cesta().
Construtores são implementados, como disse, com a definição de uma função
membro especial init. Digamos que CestaSpam tem um
construtor init(self,tipo). Então você poderia fazer uma cesta spam assim: y =
CestaSpam("maças").
Python usa espaços de nomes dinâmicos (não léxicos). Isto quer dizer que se há
uma função como esta:
def suco_laranja():
return x*2
... onde uma variável (neste caso x) não está ligada a um argumento e não é
dado um valor dentro da função, Python usará o valor que ela tiver onde e
quando a função for chamada. Neste caso:
x = 3
y = suco_laranja() # y agora é 6
x = 1
y = suco_laranja() # y agora é 2
x = 4
def suco_maça(x=x):
return x*2
x = 3
y = suco_maça():
# y agora é 8
x = 1
y = suco_maça():
# y agora é 8
Assim - o valor de x não é alterado. Se isto era tudo que nós queríamos,
poderíamos simplesmente ter escrito
def suco_tomate():
x = 4
return x*2
ou mesmo
def suco_cenoura():
return 8
sincos = componha(sin,cos)
x = sincos(3)
Onde componha é a função que queremos fazer, e x tem o valor -
0.836021861538, que é o mesmo que sin(cos(3)). Agora, como faremos isto?
(Note que nós estamos usando funções como argumentos... Este é o próprio
truque.)
def fun1(x):
return x + " mundo!"
def fun2(x):
return "Olá,"
x = sincos(3)
Agora, qual valor x terá? Resposta: "Olá, mundo!". Por que isto? Porque quando
é chamada, ela toma o valor de fun1 e fun2 do ambiente, não aqueles de
quando foi criada. Para conseguir a solução correta, tudo que teremos que fazer
é usar a técnica descrita anteriormente:
Agora nós só temos que esperar que ninguém forneça mais de um argumento à
função resultante, pois isto quebraria os esquemas :). E, a propósito, já que nós
não precisamos do nome interior, e esta função contém somente uma
expressão, nós podemos usar uma função anônima, usando a palavra-chave
lambda:
5. E agora...
Só umas coisinhas para terminar. A maioria das funções e classes mais úteis são
colocadas em módulos, os quais são na verdade arquivos-texto contendo
código Python. Você pode importá-los e usá-los em seus programas. Por
exemplo, para usar o método split do módulo padrão string, você pode ter
estas duas formas:
import string
x = string.split(y)
Ou...
x = split(y)
if __name__ == "__main__":
run()
Esta é uma forma mágica de dizer que se este módulo esta sendo executado
como um script executável (isto é, que não está sendo importado por outro
script), então a função executar deve ser chamada. E é claro, você poderia fazer
qualquer coisa após os dois pontos... :)
E para aqueles que desejam fazer um script UN*X executável, escreva isto como
primeira linha do arquivo:
#!/usr/bin/env python
def divisao_segura(a,b):
try:
return a/b
except ZeroDivisionError:
return None
ZeroDivisionError é uma exceção padrão. Neste caso, você poderia ter verificado
se b era zero, mas em muitos casos, esta estratégia não é viável. Além disso, se
não tivermos a cláusula try em divisao_segura, e dessa forma tornando arriscada
a sua chamada, nós poderíamos ainda fazer alguma coisa assim:
try:
divisao_insegura(a,b)
except ZeroDivisionError:
print("Foi tentada uma divisão por zero em divisao_insegura")
Nos casos onde normalmente não haveriam problemas específicos, mas eles
poderiam ocorrer, o uso de exceções evita tediosos testes, etc.
Bem - era isto. Espero que você tenha aprendido alguma coisa. Agora pode ir
brincar. E lembre-se do lema do aprendizado em Python: "Use os fontes, Lucas."
(Tradução: leia todo código fonte a que você tiver acesso :)) Para começar, aqui
está um exemplo. É o conhecido algoritmo QuickSort, de Hoare. Uma versão
com a sintaxe destacada em cores está aqui.
Vale a pena mencionar uma coisa sobre este exemplo. A variável done controla
se partition foi finalizada, ou não, na busca entre os elementos. Assim quando
um dos dois laços internos querem terminar a sequência de trocas, eles
atribuem 1 à variável done e interrompem-se a si próprios com break. Por que
os laços internos usam done? Porque, quando o primeiro laço interno finaliza
com um break, o laço seguinte só será executado se done não estiver com o
valor 1:
if not done:
while 1:
# Só executado se o primeiro não atribuir 1 para "done"
A única razão para eu usar a variável done no primeiro laço foi porque eu
preferi manter a simetria entre os dois laços. Desta forma poderia ser invertida a
ordem e mesmo assim o algoritmo funcionaria.
Mais alguns exemplos podem ser encontrados na página tidbit de Joe Strout.