Python para Todos Explorando Dados Com Python 3 PTBR
Python para Todos Explorando Dados Com Python 3 PTBR
Python para Todos Explorando Dados Com Python 3 PTBR
Charles R Severance
Creative Commons Non-Commercial Share Alike 3.0
Por que você deveria aprender
a programar?
Escrever programas (ou programar) é uma atividade muito criativa e
gratificante. Você pode escrever programas por várias razões, seja
para ganhar a vida, para resolver um problema difícil de análises de
dados, ou apenas se divertir ajudando alguém a solucionar um
problema. Este livro assume que todos precisam saber como
programar, e, uma vez sabendo, você vai descobrir o que deseja
fazer com suas novas habilidades.
python words.py
Enter file:words.txt
de 8
What
Software Next?
Main Secondary
Memory Memory
Hardware Architecture
What
Software Next?
Main
Memory Secondary
Memory
Entendendo Programação
No resto do livro, nós tentaremos te transformar numa pessoa que
tem habilidade na arte de programar. No final, você será um
programador --- talvez não um profissional, mas ao menos você terá
a capacidade de olhar um problema relacionado a dados e/ou
informações e conseguirá desenvolver um programa que solucione
o problema.
Palavras e Frases
Ao contrário das línguas humanas, o vocabulário da Python é
realmente muito pequeno. Chamamos de "vocabulário" as palavras
"reservadas". Estas são palavras com um significado muito especial
para Python. Quando ela as vê em um programa, elas tem um e
apenas um significado para Python. Posteriormente, você escreverá
programas com suas palavras próprias que chamará de variáveis.
Você terá uma grande liberdade na escolha de nomes para as suas
variáveis, mas não será possível utilizar as palavras reservadas do
Python como um nome para uma variável.
print('Hello world!')
Vamos dizer, por exemplo, que você não conheça nem as mais
simples palavras ou sentenças da linguagem Python. Você pode
querer usar a frase padrão que os astronautas usam quando
aterrissam num planeta distante e tentam falar com os habitantes
locais::
Isso não está indo muito bem. A menos que você pense em algo
rápido, provavelmente os habitantes do planeta irão te apunhalar
com suas lanças, colocarão você num espeto, te assarão sobre o
fogo e comerão sua carne no jantar.
Felizmente, você levou uma cópia deste livro para sua viagem, abre
ele nesta exata página e tenta de novo:
>>> print (`Você deve ser o lendário Deus que vem do céu')
Você deve ser o lendário Deus que vem do céu
>>> print (`Nós estávamos te esperando há um longo tempo')
Nós estávamos te esperando há um longo tempo
>>> print (`Nossa lenda diz que você fica bastante saboroso com
Nossa lenda diz que você fica bastante saboroso com mostarda
>>> print `Nós teremos um banquete esta noite a menos que você d
File "<stdin>", line 1
print `Nós teremos um banquete esta noite a menos que você d
A conversa estava indo tão bem por um momento, até que você
cometeu o menor erro na linguagem Python e ele pegou as lanças
de volta.
>>> good-bye
(tchau)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'good' is not defined
>>> if you don't mind, I need to leave
(se você não se importa, eu preciso sair)
File "<stdin>", line 1
if you don't mind, I need to leave
^
SyntaxError: invalid syntax
>>> quit()
Você irá perceber que os erros são diferentes para cada uma das
duas falhas tentativas. O segundo erro é diferente porque if é uma
palavra reservada e o Python viu isso e pensou que estávamos
tentando dizer algo, mas teríamos errado na sintaxe da frase.
Algumas das linhas de Python falam para ele que você quer aquilo
para lembrar de algum valor para depois. Precisamos escolher um
nome para esse valor que será lembrado e podemos usar esse
nome simbólico para recuperar o valor depois. Usamos o termo
variável para nos referir a esses rótulos que se referem à
informação armazenada.
>>> x = 6
>>> print(x)
6
>>> y = x * 7
>>> print(y)
42
>>>
$ cat Alo.py
print(''Alô Mundo!')
$ python Alo.py
Alô Mundo!
O que é um programa?
A definição de um programa em seu básico é uma sequência de
instruções do Python que foram criadas para fazer algo. Até mesmo
nosso simples script Alo.py é um programa. Trata-se de um
programa de uma única linha e particularmente não é útil, mas na
definição mais estrita, é sim um programa em Python.
Imagine então que você está fazendo essa tarefa olhando para
milhões de linhas de texto. Francamente seria mais rápido para
você aprender Python e escrever um programa nesta linguagem
para fazer a contagem do que seria examinar manualmente as
palavras.
bigcount = None
bigword = None
for word, count in list(counts.items()):
if bigcount is None or count > bigcount:
bigword = word
bigcount = count
print(bigword, bigcount)
# Code: http://www.py4e.com/code3/words.py
Você nem mesmo precisa saber Python para usar este programa.
Você irá precisar passar do Capítulo 10 desse livro para entender
completamente as impressionantes técnicas de Python que nós
usamos para fazer esse programa. Você é o usuário final, você
simplesmente usa o programa e se maravilha com sua inteligência e
como isso poupou você de muito esforço manual. Você apenas
digita o código em um arquivo chamado words.py ou faz o download
do código-fonte de http://www.py4e.com/code3/, e o executa.
entrada (input)
Obter dados do "mundo externo". Isso pode ser ler dados de
um arquivo, ou até de algum tipo de sensor como um microfone
ou GPS. Nos nossos programas iniciais, nossa entrada virá do
usuário digitando dados em seu teclado.
saída (output)
Mostrar resultados de um programa numa tela, ou guardá-los
em um arquivo, ou talvez gravá-los em um dispositivo como um
alto falante, para que ele toque música ou fale algum texto.
execução sequencial
Realizar instruções uma após a outra na ordem na qual são
encontradas no script.
execução condicional
Checar certas condições para que uma certa sequência de
instruções seja executada ou ignorada. execução repetitiva:]
Realizar algum conjunto de instruções repetidamente,
geralmente com alguma variação.
reuso
Escrever um conjunto de instruções atribuindo um nome a ele
para que estas instruções sejam reutilizadas quando
necessárias durante o programa.
Parece quase simples demais para ser verdade, e é claro que nunca
é tão simples. É como dizer que andar é simplesmente "colocar um
pé na frente do outro". A "arte" de escrever um programa é compor
e tecer esses elementos básicos juntos muitas vezes para produzir
algo que é útil para seus usuários.
O programa de contagem de palavras acima usa diretamente todos
esses conceitos, exceto um.
Erros de Sintaxe
Estes são os primeiros erros que você vai cometer e os mais
fáceis para corrigir. Um erro de sintaxe significa que você violou
as regras da "gramática" do Python. Assim, ele faz o seu
melhor para apontar diretamente para a linha e caractere em
que ele percebeu estar confuso. A única complicação nos erros
de sintaxe é que às vezes o erro se encontra na verdade um
pouco antes de onde ele havia notado que estava confuso.
Assim, a linha e caractere que o Python indica pode ser apenas
o ponto de partida da sua investigação.
Erros de Lógica
Um erro lógico é quando o programa tem uma boa sintaxe, mas
há um erro na ordem das afirmações ou talvez um erro na
forma como as afirmações se relacionam entre si. UM bom
exemplo de um erro lógico pode ser, "abra sua garrafa e beba
um pouco d'água, coloque-a em sua mochila, caminhe até a
biblioteca e, somente em seguida, tampe a garrafa."
Erros de Semântica
Um erro semântico é quando a descrição dos passos a serem
tomados é sintaticamente perfeita e na ordem certa, mas há um
erro no programa. Ele está perfeito, mas não faz o que você
pretendia que fizesse. Um exemplo simples seria se você
estivesse dando a uma pessoa direções para um restaurante e
dissesse: "... quando você chegar no cruzamento com o posto
de gasolina, vire à esquerda e vá um kilômetro de distância e o
restaurante é um edifício vermelho à sua esquerda." Seu amigo
está muito atrasado e te liga para dizer que eles estão em uma
fazenda, andando por trás de um celeiro, sem sinal de um
restaurante.
Então você diz "você virou à esquerda ou direita no posto de
gasolina?" e Ele diz, "Eu segui suas direções perfeitamente, eu
as escrevi todas: diz para virar à esquerda e seguir um
kilômetro em direção ao posto de gasolina." Então você diz, "Eu
sinto muito, porque enquanto minhas instruções foram
sintaticamente corretas, elas infelizmente continham um erro
semântico pequeno, mas não detectado."
Debugging
Quando seu Python emite um erro ou até mesmo quando ele te dá
um resultado diferente do esperado, você inicia a "caça’’ em busca
da causa de tal problema. Debugging é o processo de encontrar
essa causa em seu código. Quando você está fazendo o Debugging
em seu programa, especialmente se for um erro difícil de encontrar,
existem quatro coisas a se tentar:
Ler
Leia seu código. Fale-o em voz alta para si próprio e verifique
se ele diz mesmo o que você quer que ele diga.
Testar
Experimente fazer mudanças e rodar diferentes versões do seu
programa. Geralmente, quando você coloca a coisa certa no
lugar certo, o problema se torna óbvio, porém, às vezes, você
precisará levar um tempo para encontrar o que deve ser
ajustado.
Refletir
Tire um tempo para pensar! Que tipo de erro está acontecendo:
sintaxe, semântica, em tempo de execução? Que informações
você pode extrair das mensagens de erro, ou da saída do
programa? Que tipo de erro poderia causar o problema que
você está vendo? Qual foi a última coisa que você alterou antes
do problema aparecer?
Retroceder
Em certo momento, o melhor a se fazer é voltar atrás. Desfazer
mudanças recentes, até retornar a um programa que funcione e
que você o entenda. Depois você pode começar a reconstruir o
código.
Por exemplo, ler seu código pode ajudar caso o problema seja um
erro tipográfico, mas não se ele for uma má compreensão
conceitual. Se você não entende o que o programa faz, você pode
lê-lo 100 vezes e nunca verá o erro, porque o erro está na sua
cabeça.
A jornada do aprendizado
Conforme for progredindo sobre os tópicos abordados no restante
do livro, não se deixe abalar se sentir que os conceitos não estão se
encaixando perfeitamente na primeira impressão. Quando você está
aprendendo a falar uma língua nova, não é um problema que os
seus primeiros anos de prática não passem além do que singelas
tentativas gorgolejantes. E está tudo em ordem se você leva um
semestre apenas para evoluir de um vocabulário simples para
pequenas sentenças, e se levar anos para transformar estas
sentenças em parágrafos, e alguns anos a mais para conseguir
escrever uma pequena fábula interessante com suas próprias
palavras.
Glossário
análise sintática
Processo de examinar um programa e analisar a estrutura
sintática.
bug
Um erro em um programa.
central processing unit
Unidade central de processamento, considerada o coração de
qualquer computador. É o que roda o software que escrevemos,
também chamado de "CPU” ou "processador”.
código de máquina
A linguagem de nível mais baixo para software, que é a
linguagem que é diretamente executada pela unidade central de
processamento (CPU).
código fonte
Um programa em uma linguagem de alto nível
compilar
Compilar. Ação de traduzir um programa escrito em uma
linguagem de alto nível em uma linguagem de baixo nível, tudo
em preparação, para a execução posterior.
erro de semântica
Um erro em um programa que faz com que, na execução, ele
faça algo diferente do que o programador intencionou.
função print
Instrução que faz com que o interpretador Python exiba um
valor na tela.
interpretar
Executar um programa em uma linguagem de alto nível,
traduzindo-o uma linha por vez.
linguagem de alto nível
Uma linguagem de programação como o Python, projetada para
ser fácil para os humanos lerem e escrever.
linguagem de baixo nível
Uma linguagem de programação projetada para ser fácil para
um computador executar; também chamado de "código de
máquina” ou "linguagem de montagem(assembly)”.
memória principal.
Armazena programas e dados. A memória principal perde sua
informação quando a energia é desligada.
memória secundária
Armazena programas e dados e retém suas informações
mesmo quando a fonte de alimentação está desligada.
Geralmente mais lento que a memória principal. Exemplos de
memória secundária incluem drives de disco e memória flash
em pendrives.
modo interativo
Uma maneira de usar o interpretador Python digitando
comandos e expressões no prompt.interpret: Para executar um
programa em uma linguagem de alto nível, traduzindo-o uma
linha por vez.
portabilidade
Uma propriedade de um programa que pode ser executado em
mais de um tipo de computador.
programa
Um conjunto de instruções que especifica a computação a ser
executada pela máquina.
prompt
Quando um programa exibe uma mensagem e pausa para o
usuário digitar alguma entrada para o programa.
resolução de problemas
O processo de formular um problema, encontrar uma solução e
expressar a resolução.
semântica
O significado de um programa.
Exercícios
Exercício 1: Qual é a função da memória secundária em um
computador?
a) O interpretador de Python
b) O teclado
c) Arquivo de origem do Python
d) Um documento de processamento de texto
x = 123
a) 43
b) 44
c) x + 1
d) Erro, porque x = x + 1 não é possível matematicamente
1. http://xkcd.com/231/↩
Variáveis, expressões e
declarações
Valores e tipos
Um valor é uma das coisas mais básicas trabalhadas por um
programa, como uma letra ou um número. Os valores que vimos até
aqui foram 1, 2, e "Alô, Mundo!"
python
>>> print(4)
4
Sem muita surpresa, strings são do tipo str e inteiros são do tipo
int. Um pouco menos óbvio, números com casas decimais são do
tipo float, porque esses números são representados em um
formato chamado ponto flutuante.
{class!float
>>> type(3.2)
<class 'float'>
Mas o que dizer sobre valores como "17" e "3.2"? Eles parecem
números, mas estão demarcados com aspas assim como as strings.
>>> type('17')
<class 'str'>
>>> type('3.2')
<class 'str'>
>>> print(1,000,000)
1 0 0
index{erro semântico}
Variáveis
Um dos recursos mais poderosos da linguagem de programação é a
capacidade de manipular variáveis. Uma variável é um nome que
faz referência a um valor.
>>> print(n)
17
>>> print(pi)
3.141592653589793
>>> type(message)
<class 'str'>
>>> type(n)
<class 'int'>
>>> type(pi)
<class 'float'>
Declarações
Uma declaração é uma parte do código que o Python interpreta e
pode executar. Nós temos visto dois tipos de declarações: print
como uma declaração ou uma atribuição.
print(1)
x = 2
print(x)
produz a saída
1
2
20+32
hora-1
hora*60+minuto
minuto/60
5**2
(5+9)*(15-7)
>>> minuto = 59
>>> minuto/60
0.9833333333333333
>>> minute = 59
>>> minute/60
0
Expressões
Uma expressão é uma combinação de valores, variáveis e
operadores. Um valor, por si só, é considerado uma expressão,
assim como uma variável. O que será apresentado a seguir são
expressões válidas (assumindo que tenha sido atribuído um valor à
variável x)
17
x
x + 17
>>> 1 + 1
2
Mas em um script, uma expressão, por si só, não faz nada! Isto
geralmente causa muita confusão com iniciantes.
5
x = 5
x + 1
Ordem das operações
Quando mais de um operador aparece em uma expressão, a ordem
de avaliação depende das regras de precedência. Para operadores
matemáticos, o Python segue a convenção matemática. A sigla
PEMDAS é uma maneira útil de lembrar as seguintes regras:
Operador de módulo
O operador de módulo funciona em inteiros e produz o restante
quando o primeiro operando é dividido pelo segundo. Em Python, o
operador módulos é um sinal de porcentagem %. a sintaxe é a
mesma que para outros operadores:
>>> quociente = 7 // 3
>>> print(quociente)
2
>>> resto = 7 % 3
>>> print(resto)
1
>>> primeira = 10
>>> segunda = 15
>>> print(primeira + segunda)
25
>>> primeira = '100'
>>> segunda = '150'
>>> print(primeira + segunda)
100150
O operador * também funciona strings multiplicando o conteúdo de
uma string por um inteiro. Por exemplo:
Antes de pedir algo para o usuário, é uma boa ideia mostrar uma
mensagem dizendo a ele o que digitar. Você pode passar uma string
dentro do input para ser mostrada em tela antes da pausa para a
entrada do dado: %não sei a melhor tradução para prompt
Comentários
A medida que os programas se tornam maiores e mais complicados,
eles ficam mais difíceis de ler. Linguagens formais são densas,
muitas vezes é difícil olhar para um pedaço de código e descobrir o
que está fazendo, ou porque.
Por esta razão, é uma boa ideia adicionar notas aos seus
programas para explicar em linguagem natural o que o programa
está fazendo. Essas notas são chamadas comentários, e no Python
eles começam com o simbolo #:
# calcule a porcentagem da hora que se passou
porcentagem = (minutos * 100) / 60
v = 5 # velocidade em metros/segundo.
a = 35.0
b = 12.50
c = a * b
print(c)
horas = 35.0
taxa = 12.50
pagamento = horas * taxa
print(pagamento)
x1q3z9ahd = 35.0
x1q3z9afd = 12.50
x1q3p9afd = x1q3z9ahd * x1q3z9afd
print(x1q3p9afd)
Enquanto tudo isso parece ótimo, e é uma otima ideia usar nomes
de variáveis mnemônicos, isso pode também atrapalhar a
capacidade de um programador iniciante de analisar e entender o
código. Isto acontece porque programadores iniciantes ainda não
memorizaram as palavras reservadas (existem apenas 33 delas) e
às vezes variáveis com nomes que são muito descritivos começam
a parecer parte da linguagem e não apenas boas escolhas de
nomes.
As partes do código que são definidas por Python (for, in, print, e
:) estão em negrito e as variáveis escolhidas pelo programados
(palavra e palavras) não estão .
Muitos editores de texto estão atentos à sintaxe de Python e irão
colorir as palavras reservadas diferentemente para lhe dar dicas
para mantê-las separadas de suas variáveis. Depois de um tempo
você começará a ler Python e rapidamente determinar o que é
variável e o que é palavra reservada
Debugging
Nesse ponto, o erro de sintaxe que você está mais habituado a
cometer é um nome inválido para variáveis, como class e yield, que
são palavras-chave, ou odd~job e US$, que contém caracteres
ilegais.
>>> mes = 09
File "<stdin>", line 1
mes = 09
^
SyntaxError: invalid token
Mas a divisão vem primeiro, e você terá π/2, que não é a mesma
coisa! Não tem nenhum jeito de Python saber o que você queria
escrever, então nesse caso não haverá nenhuma mensagem de
erro, você só vai ter a resposta errada.
Glossary
atribuição
Uma declaração que atribui um valor a uma variável.
concatenação
União de dois operandos de ponta a ponta.
comentário
Informações em um programa destinado a outros
programadores(ou qualquer pessoa que esteja lendo o código
fonte) e não tem efeito sobre a execução do programa.
avaliar
simplificar uma expressão executando as operações para gerar
um único valor.
expressão
uma combinação de variáveis, operadores e valores que
representa um único valor de resultado.
ponto-flutuante
Um tipo que representa a parte fracionária.
inteiro
Um tipo que representa números inteiros..
palavra chave
Uma palavra reservada que é usada pelo compilador para
analisar um programa; você não pode utilizar keywords como
if, def, e while para serem nomes de variáveis.
mnemônico
Um recurso auxiliar de memória. Muitas vezes damos nomes
variáveis de mnemônicos para nos ajudar a lembrar o que é
armazenado na variável.
modulus operator
Um operador, denotado com um sinal de porcentagem (%), que
trabalha com inteiros e produz o restante quando um número é
dividido por outro.
operando
Um dos valores nos quais um operador opera.
operador
Um símbolo especial que representa um cálculo simples como
adição, multiplicação ou concatenação de string.
declaração
Uma seção de código que representa um comando ou uma
ação. Até agora, as declarações que temos são atribuições e
declarações impressas.
string
Um tipo que representa sequencias de caracteres.
tipo
Uma categoria de valores. Os tipos que vimos até agora são
inteiros (tipo int), números com ponto flutuante (tipo float), e
strings (tipo str).
valor
Uma das unidades básicas de dados, como um número ou
string, que um programa manipula.
variável
m nome que se refere a um valor.
Exercícios
Exercício 2: Escreva um programa que use inputs para solicitar
ao usuário seu nome e, em seguida, faça um cumprimento.
Digite seu nome: Chuck
Olá Chuck
2. Largura/2.0
3. Altura/3
4. 1 + 2 * 5
>>> 5 == 5
True
>>> 5 == 6
False
{}
True e False são valores especiais que pertecem à classe bool; eles
não são strings:
>>> type(True)
<class 'bool'>
>>> type(False)
<class 'bool'>
x != y # x é diferente de y
x > y # x é maior do que y
x < y # x é menor do que y
x >= y # x é maior ou igual a y
x <= y # x é menor ou igual a y
x is y # x é o mesmo que y
x is not y # x não é o mesmo que y
Apesar dessas expressões provavelmente serem familiares para
você, os símbolos em Python são diferentes dos símbolos utilizados
na matemática para realizar as mesmas operações. Um erro comum
é usar apenas um sinal (=) ao invés de um sinal duplo (==) para
comparar uma igualdade. Lembre-se que = é um operador de
atribuição e == é um operador de comparação. Vale mencionar que
não há operadores =< e =>.
Operadores lógicos
Existem três operadores lógicos: and, or, e not. A semântica
(significado) desses operadores são similares ao seu significado em
Inglês. Por exemplo,
Essa flexibilidade pode ser útil, mas existem algumas sutilezas que
podem ser confusas. É bom evitá-los até você ter certeza de que
sabe o que está fazendo.
Execução condicional
A fim de escrever programas úteis, nós sempre necessitamos da
habilidade de checar condições e de mudar o comportamento do
programa de acordo com elas. Declarações Condicionais nos dão
essa habilidade. A forma mais simples é a declaração if:
if x > 0 :
print('x é positivo')
Ye s
x>0
print(‘x is postitive’)
If Logic
if x < 0 :
pass # necessitamos tratar os valores negativos!
>>> x = 3
>>> if x < 10:
... print('Pequeno')
...
Pequeno
>>>
>>> x = 3
>>> if x < 10:
... print('Pequeno')
... print('Feito')
File "<stdin>", line 3
print('Feito')
^
SyntaxError: invalid syntax
if x%2 == 0 :
print('x é par')
else :
print('x é ímpar')
No Ye s
x%2 == 0
If-Then-Else Logic
Condições encadeadas
As vezes há mais de duas possibilidades e precisamos de mais de
duas ramificações. Uma maneira de expressar uma lógica
computacional como essa é por meio de uma condição encadeada:
if x < y:
print('x é menor que y')
elif x > y:
print('x é maior que y')
else:
print('x e y são iguais')
Ye s
x<y print(‘less’)
Ye s
x>y print (‘greater’)
print(‘equal’)
If-Then-ElseIf Logic
if choice == 'a':
print('Mau Palpite')
elif choice == 'b':
print('Bom Palpite')
elif choice == 'c':
print('Perto, mas não está correto')
Cada condição é verificada em ordem. Se a primeira for falsa, a
próxima é verificada, e assim por diante. Se ao menos uma delas for
verdadeira, a ramificação correspondente será executada e o bloco
condicional terminará. Mesmo que mais de uma condição seja
verdadeira, somente a primeira ramificação verdadeira é executada.
Condições aninhadas
Uma condição pode também ser aninhada com outra. Nós
poderiamos ter escrito o exemplo com três ramos assim:
if x == y:
print('x e y são iguais')
else:
if x < y:
print('x é menor que y')
else:
print('x é maior que y')
Ye s No
x == y
Ye s No
x<y
print(‘equal’)
print(‘less’) print’‘greater’)
Sentenças de if aninhadas
if 0 < x:
if x < 10:
print('x é um número positivo de 1 dígito.')
# Code: http://www.py4e.com/code3/fahren.py
python fahren.py
Insira a temperatura em Fahrenheit:fred
Traceback (most recent call last):
File "fahren.py", line 2, in <module>
fahr = float(ent)
ValueError: could not convert string to float: 'fred'
(não foi possível converter string para float: 'fred')
# Code: http://www.py4e.com/code3/fahren2.py
python fahren2.py
Insira a temperatura em Fahrenheit:fred
Por favor, insira um número
>>> x = 6
>>> y = 2
>>> x >= 2 and (x/y) > 2
True
>>> x = 1
>>> y = 0
>>> x >= 2 and (x/y) > 2
False
>>> x = 6
>>> y = 0
>>> x >= 2 and (x/y) > 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
(divisão por zero)
>>>
>>> x = 1
>>> y = 0
>>> x >= 2 and y != 0 and (x/y) > 2
False
>>> x = 6
>>> y = 0
>>> x >= 2 and y != 0 and (x/y) > 2
False
>>> x >= 2 and (x/y) > 2 and y != 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
(divisão por zero)
>>>
Debugging
O "traceback" que o Python exibe quando um erro ocorre contém
bastante informação, mas isso pode ser um pouco sufocante. As
partes mais úteis são usualmente:
>>> x = 5
>>> y = 6
File "<stdin>", line 1
y = 6
^
IndentationError: unexpected indent
(indentação inprevista)
Glossário
Corpo
Sequência de instruções dentro de uma instrução composta.
Condicional aninhada
Uma condicional que aparece em um dos ramos de outra
sentença condicional.
Condicional encadeada
Uma condicional com uma série de ramos alternativos.
Condição
A expressão booleana em uma sentença condicional que
determina qual ramo será executado.
Curto-circuito
Quando Python está no meio da verificação de uma expressão
lógica e para a verificação porque sabe o resultado final da
expressão, sem a necessidade de verificar o restante desta.
Expressão booleana
Uma expressão cujo valor é True ou False.
Operador de comparação
Um operador que compara seus operandos: ==, !=, >, <, >=, e <=.
Operador lógico
Operadores que combinam expressões booleanas: and, or, e
not.
Padrão Guardião (guardian pattern)
Quando construímos uma expressão lógica com comparações
adicionais para ganhar vantagem com o comportamento de
short-circuit.
Ramo
Uma das alternativas de sequência de instruções dentro de uma
condicional.
Sentença composta
Uma sentença que consiste em um cabeçalho e um corpo. O
cabeçalho termina com dois pontos (:). O corpo é indentado
relativo ao cabeçalho.
Sentença condicional
Uma sentença que controla o fluxo de execução dependendo de
alguma condição.
Traceback
Uma lista das funções que estão sendo executadas, mostrada
quando uma exceção ocorre.
Exercícios
Exercício 1: Reescreva seu programa de pagamento, para pagar
ao funcionário 1.5 vezes o valor da taxa horária de pagamento
pelo tempo trabalhado acima de 40 horas
Digite as Horas: 45
Digite a taxa: 10
Pagamento: 475.0
Exercício 2: Reescreva seu programa de pagamento utilizando
try e except, de forma que o programa consiga lidar com
entradas não numéricas graciosamente, mostrando uma
mensagem e saindo do programa. A seguir é mostrado duas
execuções do programa
Digite as Horas: 20
Digite a taxa: nove
Erro, por favor utilize uma entrada numérica
>>> type(32)
<class 'int'>
Funções internas
O Python fornece várias funções internas importantes que nós
podemos usar sem precisar definí-las. Os criadores do Python
escreveram um conjunto de funções para solucionar problemas
comuns e incluíram elas na linguagem para nosso uso.
A funções max e min nos dão o maior e o menor valores de uma lista,
respectivamente:
>>> max('Alô mundo')
'ô'
>>> min('Alô mundo')
' '
>>>
A função max nos diz qual é o "maior caractere" da string (que acaba
sendo a letra "ô") e a função min nos mostra o menor caractere (que
acaba sendo o espaço).
Outra função interna muito comum é a len, que nos diz quantos
itens há em seu argumento. Caso este argumento seja uma string, a
função retorna o número de caracteres que a compõem.
>>> int('32')
32
>>> int('Olá')
ValueError: invalid literal for int() with base 10: 'Hello'
int pode converter valores em pontos-flutuante em inteiros, mas
não os arredonda; ela trunca a parte decimal:
>>> int(3.99999)
3
>>> int(-2.3)
-2
>>> float(32)
32.0
>>> float('3.14159')
3.14159
Funções matemáticas
Python tem um módulo math que possui a maioria das funções
matemáticas familiares. Antes que possamos utilizar o módulo, nós
temos que importá-lo:
>>> graus = 45
>>> radianos = graus / 360.0 * 2 * math.pi
>>> math.sin(radianoss)
0.7071067811865476
Números Aleatórios
Dadas as mesmas entradas, a maior parte dos programas geram
sempre as mesmas saídas, de forma que eles são ditos
determinísticos. Determinismo é geralmente uma boa coisa, já que
nós esperamos que o mesmo cálculo obtenha sempre o mesmo
resultado. Para algumas aplicações, porém, nós queremos que o
computador seja imprevisível. Jogos são um exemplo óbvio, mas
existem outros.
import random
for i in range(10):
x = random.random()
print(x)
Este programa produz a seguinte lista de 10 números aleatórios
entre 0.0 e até, mas não incluindo, 1.0.
0.11132867921152356
0.5950949227890241
0.04820265884996877
0.841003109276478
0.997914947094958
0.04842330803368111
0.7416295948208405
0.510535245390327
0.27447040171978143
0.028511805472785867
>>> t = [1, 2, 3]
>>> random.choice(t)
2
>>> random.choice(t)
3
def print_LetraDaMusica():
print("Eu sou um lenhador, e eu estou bem.")
print('Eu durmo a noite toda e trabalho o dia todo.')
>>> print(print_LetraDeMusica)
<function print_ LetraDeMusica at 0xb7e99e9c>
>>> print(type(print_ LetraDeMusica))
<class 'function'>
>>> print_LetraDeMusica()
Eu sou um lenhador, e eu estou bem.
Eu durmo a noite toda e trabalho o dia todo.
Uma vez que sua função está definida, você pode usá-la dentro de
outra função. Por exemplo, para repetir o refrão acima, nós
poderíamos escrever uma função chamada repetir_LetraDeMusica:
def repetir_LetraDeMusica():
print_ LetraDeMusica()
print_ LetraDeMusica()
Definições e usos
Colocando junto os fragmentos de código da seção anterior, o
programa inteiro fica assim:
def repetir_LetraDeMusica():
print_ LetraDeMusica()
print_ LetraDeMusica()
>>> repetir_LetraDeMusica()
def print_lyrics():
print("I'm a lumberjack, and I'm okay.")
print('I sleep all night and I work all day.')
def repeat_lyrics():
print_lyrics()
print_lyrics()
repeat_lyrics()
# Code: http://www.py4e.com/code3/lyrics.py
Fluxo de Execução
Para garantir que a função é definida antes de seu primeiro uso,
você precisa saber a ordem que cada declaração é executada, o
que é chamado de fluxo de execução.
Parâmetros e argumentos
Algumas das funções internas que vimos requerem argumentos. Por
exemplo, quando você chama math.sin você passa um número
como argumento. Algumas funções requerem mais de um
argumento: math.pow recebe dois, a base e o expoente.
def mostra_duas_vezes(bruce):
print(bruce)
print(bruce)
Essa função funciona com qualquer valor que possa ser mostrado.
>>> mostra_duas_vezes('Spam')
Spam
Spam
>>> mostra_duas_vezes(17)
17
17
>>> import math
>>> mostra_duas_vezes(math.pi)
3.141592653589793
3.141592653589793
Quando você chama uma função frutífera, você quase sempre quer
fazer alguma coisa com resultado; por exemplo, você pode atribuí-la
a uma variável ou usá-la como parte de uma expressão:
x = math.cos(radians)
golden = (math.sqrt(5) + 1) / 2
>>> math.sqrt(5)
2.23606797749979
math.sqrt(5)
Funções vazias podem exibir algo na tela ou ter algum outro efeito,
mas elas não têm um valor de retorno. Se você tentar atribuir o
resultado a uma variável, você obtém um valor especial chamado
None.
>>> resultado = mostra_duas_vezes('Bing')
Bing
Bing
>>> print(resultado)
None
O valor None não é o mesmo que uma string "None". Ele é um valor
especial que possui seu próprio tipo:
>>> print(type(None))
<class 'NoneType'>
>>> x = soma_dois(3, 5)
>>> print(x)
x = addtwo(3, 5)
print(x)
# Code: http://www.py4e.com/code3/addtwo.py
Depuração
Se você estiver usando um editor de texto para escrever seus
scripts, você pode encontrar problemas com espaços e tabulações
(tabs). A melhor maneira de evitar esses problemas é usar espaços
exclusivamente (sem tabs). A maioria dos editores de texto que
sabem sobre Python fazem isso por padrão, mas alguns não.
Glossário
algoritmo
Um processo geral para resolver uma categoria de problemas.
argumento
Um valor fornecido para uma função quando a função é
chamada. Esse valor é atribuído ao parâmetro correspondente
na função.
cabeçalho
A primeira linha de uma definição de função.
chamada de função
Uma declaração que executa uma função. Consiste na função
nome seguido por uma lista de argumentos.
composição
Utilizar uma expressão como parte de uma expressão maior ou
uma instrução como parte de uma declaração maior.
corpo
A sequência de instruções dentro de uma definição de função.
declaração de importação
Uma instrução que lê um arquivo do módulo e cria um objeto do
módulo.
definição de função
Uma declaração que cria uma nova função, especificando seu
nome, parâmetros e as instruções que executa.
determinista
Pertence a um programa que faz a mesma coisa toda vez que é
executado, dadas as mesmas entradas.
fluxo de execução
A ordem em que as instruções são executadas durante a
execução de um programa.
função
Uma sequência nomeada de instruções que realiza alguma
operação útil. As funções podem ou não aceitar argumentos
e podem ou não produzir um resultado.
função frutífera
Uma função que retorna um valor.
função vazia
Uma função que não retorna um valor.
notação de ponto
A sintaxe utilizada para chamar uma função em outro módulo
especificando o nome do módulo seguido por um ponto e o
nome da função.
objeto de função
Um valor criado por uma definição de uma função. O nome da
função é uma variável que se refere a um objeto de função.
objeto do módulo
Um valor criado por uma declaração import que fornece
acesso aos dados e código definidos em um módulo.
parâmetro
Um nome usado dentro de uma função para se referir ao valor
passado como argumento.
pseudoaleatório
Pertence a uma sequência de números que parecem ser
aleatórios, mas são gerados por um programa determinístico.
valor de retorno
O resultado de uma função. Se uma chamada de função for
usada como expressão, o valor de retorno é o valor da
expressão.
Exercícios
Exercício 4: Qual a finalidade da palavra-chave "def" em Python
def fred():
print("Zap")
def jane():
print("ABC")
jane()
fred()
jane()
x = x + 1
>>> x = x + 1
NameError: name 'x' is not defined
(nome ‘x’ não definido)
>>> x = 0
>>> x = x + 1
A declaração while
Frequentemente, computadores são utilizados para automatizar
tarefas repetitivas. Repetir tarefas, idênticas ou similares, sem
cometer erros, é algo que computadores fazem bem melhor que
pessoas. Devido à iteração ser tão comum, Python disponibiliza
diversos recursos para torná-la mais fácil.
n = 5
while n > 0:
print(n)
n = n - 1
print('Lançar!')
Laços infinitos
Uma fonte de diversão sem fim para programadores é observar que
as instruções no shampoo, “Ensaboe, enxague, repita”, são um laço
infinito pois não há variável de iteração lhe dizendo quantas vezes
executar essa sequência.
Às vezes você não sabe que é hora de terminar o laço até chegar
ao meio dele. Nesse caso você pode escrever um laço infinito de
propósito e então usar o comando break para interrompê-lo.
n = 10
while True:
print(n, end=' ')
n = n - 1
print('Pronto!')
Por exemplo, suponha que você queira entradas do usuário até que
ele digite pronto. Você pode escrever:
while True:
line = input('> ')
if line == 'done':
break
print(line)
print('Done!')
# Code: http://www.py4e.com/code3/copytildone1.py
while True:
line = input('> ')
if line[0] == '#':
continue
if line == 'done':
break
print(line)
print('Done!')
# Code: http://www.py4e.com/code3/copytildone2.py
> olá
olá
> # não exiba isso
> exiba isso!
exiba isso!
> pronto
Pronto!
Traduzir esse loop for para o português não é tão direto quanto o
while, mas se você pensar em amigos como um lista, ele interpreta
assim: "executar as instruções no corpo do for uma vez para cada
amigo in lista de amigos nomeados."
Padrões de laço
Muitas vezes usamos um laço for ou while para percorrer uma lista
de itens ou conteúdos de um arquivo, nesse caso nós estamos
procurando por algo como o maior ou menor valor dos dados que
nós percorremos.
contador = 0
for itervar in [3, 41, 12, 9, 74, 15]:
contador = contador + 1
print('Contagem: ', contador)
Nós ajustamos contador para zero antes do laço começar, então nós
escrevemos um laço for para percorrer a lista de números. Nossa
variável de iteração é chamada de itervar e enquanto nós não
usamos o itervar no laço, ele controla o laço e faz com que o corpo
desse laço seja executado uma vez para cada um dos valores na
lista.
total = 0
for itervar in [3, 41, 12, 9, 74, 15]:
total = total + itervar
print('Total: ', total)
Nesse loop, usamos a variável de iteração. Em vez de
simplesmente adicionar um a contagem, como na repetição anterior,
nós adicionamos o número real (3, 41, 12, etc.) ao total durante
cada iteração de repetição. Se você pensar na variável total, ela
contém o "total de valores percorridos até agora". Então, antes que
a repetição comece,total é zero porque ainda não vimos nenhum
valor. Durante todo o laço, total é o total atualizado e, ao final do
laço, total é o valor de todos os valores na lista.
máximo = None
print('Antes:', máximo)
for itervar in [3, 41, 12, 9, 74, 15]:
if máximo is None or itervar > máximo :
máximo = itervar
print('Laço:', itervar, máximo)
print('Máximo:', máximo)
Antes do início do laço, o maior valor que temos até agora é None, já
que nós ainda não percorremos nenhum valor. Enquanto o laço está
sendo executado, se o máximo for None, então nós pegamos o
primeiro valor que vemos como o maior até agora. Você pode ver na
primeira iteração quando o valor do itervar é 3, já que máximo é
None, nós imediatamente definimos máximo como sendo 3.
mínimo = None
print('Antes:', mínimo)
for itervar in [3, 41, 12, 9, 74, 15]:
if mínimo is None or itervar < mínimo:
mínimo = itervar
print('Laço:', itervar, mínimo)
print('Mínimo:', mínimo)
def min(valores):
mínimo = None
for valor in valores:
if mínimo is None or valor < mínimo:
mínimo = valor
return mínimo
Debugging
Ao começar a escrever programas maiores, você pode se encontrar
gastando mais tempo com debugging. Mais código significa mais
chances de cometer um erro e mais lugares para que erros se
escondam.
Glossário
Acumulador: Uma variável usada em um laço para adicionar ou
acumular um resultado. Contador: Uma variável usada em um laço
para contar o número de vezes que alguma coisa aconteceu. Nós
inicializamos um contador em zero e incrementamos o contador
cada vez que queremos "contar" alguma coisa. Decremento : Uma
atualização que diminuiu o valor de uma variável. Inicializar: Uma
atribuição que fornece um valor para uma variável que vai ser
atualizada. Incremento: Uma atualização que aumenta o valor de
uma variável (geralmente em um) . Laço infinito: Um laço cuja
condição de término nunca é satisfeita, ou para qual não existe
condição de término. Iteração: Execução repetida de um conjunto de
instruções usando uma função que chama a si mesma ou a um laço.
Exercícios
Exercício 1: Escreva um programa que lê repetitivamente
números até que o usuário digite "pronto". Quando "pronto" for
digitado, mostre a soma total, a quantidade e a média dos
números digitados. Se o usuário digitar qualquer coisa que não
seja um número, detecte o erro usando o trye o except e mostre
na tela uma mensagem de erro e pule para o próximo número.
Digite um número: 4
Digite um número: 5
Digite um número: dado errado
Entrada Inválida
Digite um número: 7
Digite um número: pronto
16 3 5.333333333333333
>>> print(letra)
a
String Indexes
Para obter a última letra de uma string, você pode ficar tentado a
fazer algo desta natureza:
indice = 0
while indice < len(fruta):
letra = fruta[indice]
print(letra)
indice = indice + 1
Segmentos de strings
Um segmento de uma string é chamado slice. A seleção de um slice
é similar a seleção de um caractere:
A razão para o erro é que strings são imutáveis, o que significa que
você não pode alterar uma string já existente. O melhor a se fazer é
criar uma nova string que é uma variação da original:
Laços e contagem
O programa a seguir conta o número de vezes que a letra "a"
aparece em uma string:
palavra = 'banana'
contagem = 0
for letra in palavra:
if letra == 'a':
contagem = contagem + 1
print(contagem)
O operador in
A palavra in é uma operador booleano que usa duas strings e
retorna True se a primeira aparecer como uma substring na
segunda:
Comparação de strings
Os operadores de comparação funcionam em strings. Para verificar
se duas delas são iguais:
if palavra == 'banana':
print('Certo, bananas.')
Métodos da String
Strings são exemplos de objetos no Python. Um objeto contém tanto
a informação (a própria string), como métodos, que são funções
eficientes construídas dentro do objeto e disponíveis em qualquer
instância do mesmo.
capitalize(...)
S.capitalize() -> str
Você pode usar o comando help para ter acesso a uma simples
documentação sobre o método. Uma melhor fonte de documentação
para os métodos da string pode ser encontrada em:
https://docs.python.org/library/stdtypes.html#string-methods.
Por exemplo, o método upper recebe uma string e retorna uma nova
com todas as letras em maiúsculo:
>>> palavra.find('na')
2
>>> palavra.find('na', 3)
4
Uma prática comum consiste em remover espaços em branco
(espaços, tabs ou quebra de linha) do começo e do final da string,
usando o método strip:
https://docs.python.org/library/stdtypes.html#string-methods
Particionando strings
Frequentemente, nós precisamos analisar o que há dentro de uma
string e encontrar uma substring. Por exemplo, se nos for
apresentada uma sequência de linhas formatadas da seguinte
forma:
https://docs.python.org/library/stdtypes.html#string-methods.
Operador de Formatação
O operador de formatação % nos permite construir strings,
substituindo partes destas strings pela informação contida em
variáveis. Quando aplicamos à inteiros, % é o operador de módulo.
Porém, quando o primeiro operando é uma string, % é o operador de
formatação.
>>> camelos = 42
>>> '%d' % camelos
'42'
>>> camelos = 42
>>> 'Eu vi %d camelos.' % camelos
'Eu vi 42 camelos.'
https://docs.python.org/library/stdtypes.html#printf-style-string-
formatting.
Debugging
Uma habilidade que você deveria desenvolver ao programar é a de
sempre se perguntar, "O que poderia dar errado aqui?" ou, de
maneira semelhante, "Qual loucura o usuário poderia fazer para
gerar um problema no nosso programa (aparentemente) perfeito?"
while True:
line = input('> ')
if line[0] == '#':
continue
if line == 'done':
break
print(line)
print('Done!')
# Code: http://www.py4e.com/code3/copytildone2.py
> Olá
Olá
> # não mostre isto
> Mostre isto!
Mostre isto!
>
Traceback (most recent call last):
File "copytildone.py", line 3, in <module>
if line[0] == '#':
IndexError: string index out of range
(índice fora dos limites da string)
if line.startswith('#'):
Glossário
contador
Uma variável que é utilizada para contar algo. Geralmente é
inicializada com zero e incrementada. fatia
Uma parte de uma string especificada por uma intervalo de
índices.
flag
Uma variável boleana utilizada para indicar quando uma
condição é verdadeira ou falsa.
imutável
A propriedade de uma sequência cujos os itens não podem ser
atribuídos ou alterados.
índice
Um valor inteiro utilizado para selecionar um item em uma
sequência, como um caractere em uma string.
invocação
Uma declaração que chama um método.
item
Um dos valores em uma sequência.
método
Uma função que é associada a um objeto e chamada utilizando
a notação com um ponto. objeto
Algo ao qual uma variável pode se referir. Por agora, você pode
utilizar "objeto" e "valor" indistintamente.
operador de formatação
Um operador,%, que recebe uma string de formatação e uma
tupla e gera uma string que inclui os elementos da tupla
formatados conforme especificado pela string.
pesquisa
Um padrão de travessia que para quando encontra o que
estava procurando.
sequência
Um conjunto ordenado; ou seja, um conjunto de valores em que
cada elemento é identificado por um índice.
sequência de formatação
Uma sequência de caracteres em uma string de formatação,
como %d, que especificam como um valor deve ser formatado
string de formatação
Uma string, utilizada com o operador de formatação, que
contém sequências de formatação.
string vazia
Uma string com nenhum caractere e de dimensão 0,
representada por duas aspas.
travessia
Iterar através dos elementos de uma sequência, realizando uma
operação similar em cada um deles.
Exercícios
Exercício 5: Utilize o seguinte código em Python que guarda
uma string:
What
Software Next?
Main Secondary
Memory Memory
Secondary Memory
Abrindo um arquivo
Quando queremos ler ou escrever um arquivo (digamos no seu disco rígido),
primeiro devemos abrir ele. Fazendo isso há uma comunicação com seu
sistema operacional, que sabe onde os dados para cada arquivo são
armazenados. Quando se abre um arquivo, você está pedindo para o sistema
operacional achá-lo por nome e ter certeza que ele existe. Nesse exemplo, nós
abrimos o arquivo mbox.txt, o qual deveria estar armazenado na mesma pasta
que você está quando inicia o Python. Você pode baixar este arquivo em
[www.py4e.com/code3/mbox.txt]
open H
A
close N
From stephen.m..
Return-Path: <p..
re a d D Date: Sat, 5 Jan ..
L To : s o u r c e @ c o l l . .
write E From: stephen...
Subject: [sakai]...
Details: http:/...
Your …
Program
A File Handle
Se o arquivo não existir, open falhará com um Traceback e você não receberá
um identificador para acessar o conteúdo dele:
Mais tarde, usaremos try e except para lidar mais graciosamente com a
situação em que tentamos abrir um arquivo que não existe.
www.py4e.com/code3/mbox.txt
www.py4e.com/code3/mbox-short.txt
Você também pode ver que o comprimento da string X\nY é * três * porque o
newline é um único caractere.
Lendo arquivos
Uma vez que o identificador de arquivo não contém os dados deste, é bem fácil
construir um laço for para ler e contar cada linha do arquivo:
fhand = open('mbox-short.txt')
count = 0
for line in fhand:
count = count + 1
print('Line Count:', count)
# Code: http://www.py4e.com/code3/open.py
A razão para a função open não ler todo o arquivo é que este pode ser bem
grande, com muitos gigabytes de dados. A sentença open toma a mesma
quantidade de tmepo independente do tamanho do arquivo. O loop na verdade
que faz os dados serem lidos.
Quando o arquivo é lido com o for dessa maneira, Python tem cuidado de
separar os dados em linhas diferente utilizando o newline. Ele lê cada linha até
o fim e inclui o newline quando alcança o último caractere na variável linha
para cada iteração do loop for.
Uma vez que o laço lê os dados uma linha por vez, ele pode eficientemente ler
e contar as linhas em arquivos muito grandes sem esgotar a memória principal
para armazenar os dados. O programa acima conta as linhas em um arquivo de
qualquer tamanho usando bem pouca memória já que cada linha é lida, contada
e descartada
Lembre que essa forma da função open deveria apenas ser usada se os dados
do arquivo confortavelmente cabem na sua memória principal do computador.
Se o arquivo é muito grande para a memória, você deveria escrever seu
programa para ler ele em pedaços usando um for ou um while.
Searching through a file
Quando você está procurando por dados em um arquivo, é um padrão muito
comum em percorrer um arquivo ignorando a maioria das linhas e apenas
processando as que vão de encontro com uma condição particular. Podemos
combinar o padrão de ler um arquivo com os métodos da sting para construir
um simples mecanismo de busca.
fhand = open('mbox-short.txt')
count = 0
for line in fhand:
if line.startswith('From:'):
print(line)
# Code: http://www.py4e.com/code3/search1.py
From: louis@media.berkeley.edu
From: zqian@umich.edu
From: rjlowe@iupui.edu
...
A saída parece ótima uma vez que as únicas linhas que estamos vendo são as
que começam com "From:", mas por que vemos também essas linhas em
branco extras? Isso é devido ao caractere newline invisível. Cada uma das
linhas termina com um, então a sentença print mostra a string na variável linha
que inclui um newline e então o print adiciona outro, resultando no efeito de
duplo espaçamento que observamos.
Nós podíamos usar o fatiamento das linhas para mostrar todos menos o último
caractere, mas uma abordagem mais simples é usar o método rstrip que
We could use line slicing to print all but the last character, but a simpler
approach is to use the rstrip method which tira os espaços em branco do lado
direito da stirng, como pode ser observado:
fhand = open('mbox-short.txt')
for line in fhand:
line = line.rstrip()
if line.startswith('From:'):
print(line)
# Code: http://www.py4e.com/code3/search2.py
fhand = open('mbox-short.txt')
for line in fhand:
line = line.rstrip()
# Skip 'uninteresting lines'
if not line.startswith('From:'):
continue
# Process our 'interesting' line
print(line)
# Code: http://www.py4e.com/code3/search3.py
Nós podemos usar o método find da string para simular um editor de texto que
encontra linhas onde a string procurada está em qualquer lugar da linha. Uma
vez que o find procura por uma ocorrência de uma string dentro de outra e ou
retorna a posição dela ou -1 se não for encontrada, podemos escrever o
seguinte laço para mostrar linhas que contém a string "@uct.ac.za" (isto é, elas
vêm da Universidade de Cape Town na África do Sul):
fhand = open('mbox-short.txt')
for line in fhand:
line = line.rstrip()
if line.find('@uct.ac.za') == -1: continue
print(line)
# Code: http://www.py4e.com/code3/search4.py
# Code: http://www.py4e.com/code3/search6.py
Nós lemos o nome do arquivo do usuário e o colocamos numa variável
nomeada fname, abrimos esse arquivo e então podemos executar o programa
repetidas vezes em arquivos diferentes.
python pesquisa6.py
Digite o nome do arquivo: mbox.txt
Havia 1797 linhas de conteúdo em mbox.txt
python pesquisa6.py
Digite o nome do arquivo: mbox-short.txt
Havia 27 linhas de conteúdo em mbox-short.txt
Antes de dar uma olhada na próxima seção, dê uma olhada no programa acima
e pergunte a si mesmo: "O que poderia dar errado aqui?" ou “O que nosso
amiguinho usuário poderia fazer que pararia desgraçadamente a execução do
nosso programinha com um erro de traceback e faria com que não
parecêssemos mais tão legais aos olhos do usuário?”
python pesquisa6.py
Digite o nome do arquivo: na na boo boo
Traceback (most recent call last):
File "pesquisa6.py", line 2, in <module>
fhand = open(fname)
FileNotFoundError: [Errno 2] No such file or directory: 'na na boo boo'
Não ria. Os usuários eventualmente farão todas as coisas possíveis que podem
fazer para quebrar seus programas, seja de propósito ou com intenção
maliciosa. De fato, uma parte importante de qualquer equipe de
desenvolvimento de software é uma pessoa ou grupo chamado Quality
Assurance (ou QA, abreviado) cujo trabalho é fazer as coisas mais loucas
possíveis na tentativa de quebrar o software que o programador criou.
# Code: http://www.py4e.com/code3/search7.py
A função exit termina o programa. É uma função sem retorno. Agora, quando
nosso usuário (ou equipe de QA) digitar bobagens ou nomes de arquivos que
não existem, nós os “pegamos” e recuperamos com elegância.
python pesquisa7.py
Digite o nome do arquivo: mbox.txt
Havia 1797 linhas de conteúdo em mbox.txt
python pesquisa7.py
Digite o nome do arquivo: na na boo boo
File cannot be opened: na na boo boo
Uma vez que você se torne mais habilidoso em Python, você pode interagir com
outros programadores para decidir qual das duas soluções equivalentes para
um problema é "mais Pythonico". O objetivo de ser "mais Pythonico" capta a
noção de que a programação é parte engenharia e parte arte. Nem sempre
estamos interessados em fazer algo funcionar, queremos também que a nossa
solução seja elegante e seja apreciada como elegante pelos nossos pares.
Escrevendo arquivos
Para escrever um arquivo você tem que abri-lo com o modo “w” como segundo
parâmetro:
>>> fout.close()
Poderíamos fechar os arquivos que abrimos para leitura também, mas podemos
ser um pouco desleixados se abrirmos apenas alguns arquivos, pois o Python
garante que todos os arquivos abertos sejam fechados quando o programa
terminar. Quando estamos escrevendo arquivos, queremos fechar
explicitamente os arquivos para não deixar nada ao acaso.
Debugging
Quando você está lendo ou escrevendo arquivos, pode ser que encontre
problemas com espaços em branco. Esses erros podem ser difíceis de tratar
porque espaços, tabulações e newlines são normalmente invisíveis:
A função interna repr pode ajudar. Ela pega qualquer parâmetro como
argumento e retorna uma representação em string desse objeto. Para strings,
caracteres de espaço em branco são representados como sequências de barra
invertida:
>>> print(repr(s))
'1 2\t 3\n 4'
Um outro problema que você deve encontrar é que diferentes sistemas usam
caracteres diferentes par indicar o fim de uma linha. Alguns usam o newline,
representado por \n. Outros usam o caractere de retorno, o \r. ALguns usam
ambos. Se você mover arquivos de um sistema para outro, essas
inconsistências podem causam problemas.
Glossário
arquivo de texto
Uma sequência de caracteres colocada em um armazenamento
permanente, como um disco rígido
capturar
Para prevenir que uma exceção encerre o programa. É usado com as
sentenças trye except
Controle de Qualidade
Uma pessoa ou time focado em assegurar a qualidade geral de um produto
de software. O CA é frequentemente envolvido em testes de um produto e
na identificação de problemas antes que o produto seja distribuído.
newline
Um caractere especial usado em arquivos e strings para indicar o fim de
uma linha.
Pythonico
Uma técnica que funciona de forma elegante em Python. "Usar try e except
é a forma Pythonica de contornar arquivos inexistentes"
Exercícios
Exercício 1: Escreva um programa que leia um arquivo e mostre o
conteúdo deste (linha por linha), completamente em caixa alta. A execução
do programa deverá ser a seguinte:
python shout.py
Digite o nome de um arquivo: mbox-short.txt
FROM STEPHEN.MARQUARD@UCT.AC.ZA SAT JAN 5 09:14:16 2008
RETURN-PATH: <POSTMASTER@COLLAB.SAKAIPROJECT.ORG>
RECEIVED: FROM MURDER (MAIL.UMICH.EDU [141.211.14.90])
BY FRANKENSTEIN.MAIL.UMICH.EDU (CYRUS V2.3.8) WITH LMTPA;
SAT, 05 JAN 2008 09:14:16 -0500
python egg.py
Digite o nome de um arquivo: missing.tyxt
Arquivo não pôde ser aberto: missing.tyxt
python egg.py
Digite o nome de um arquivo: na na boo boo
NA NA BOO BOO PRA VOCÊ TAMBÉM!
Nós não estamos encorajando você a pôr Easter Eggs nos seus
programas, isso é apenas um exercício.
Listas
Uma lista é uma sequência
Como uma string, uma lista é uma sequência de valores. Em uma string, os
valores são caracteres; em uma lista, eles podem ser de qualquer tipo. Os
valores em lista são chamados elementos ou às vezes itens.
Existem várias maneiras de criar uma nova lista; o mais simples é incluir os
elementos entre colchetes ("[" e "]"):
Uma lista que não contém elementos é chamada de lista vazia; você pode
criar uma com colchetes vazios, [].
Como você poderia esperar, você pode atribuir valores de lista a variáveis:
>>> print(queijos[0])
Cheddar
Ao contrário das strings, as listas são mutáveis porque você pode alterar a
ordem dos itens ou atribuir outro valor a um item. Quando o operador
colchete aparece no lado esquerdo de uma atribuição, ele identifica o
elemento da a lista que será modificado.
Você pode pensar em uma lista como uma relação entre índices e
elementos. Essa relação é chamada de mapeamento; cada index
"representa" um dos elementos.
Se você tentar ler ou escrever um elemento que não existe, você terá
um "IndexError".
Isso funciona bem se você precisar ler apenas os elementos da lista. Mas
se você quiser escrever ou atualizar os elementos, você precisa dos
índices. Uma maneira comum de fazer isso é combinar as funções range e
len:
for i in range(len(numeros)):
numeros[i] = numeros[i] * 2
Uma repetição for sobre uma lista vazia nunca executa o corpo:
for x in empty:
print('Isso nunca acontece.')
Embora uma lista possa conter outra lista, a lista encaixada ainda conta
como um único elemento. O comprimento dessa lista é quatro:
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> c = a + b
>>> print(c)
[1, 2, 3, 4, 5, 6]
>>> [0] * 4
[0, 0, 0, 0]
>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
Fatiamento de listas
O operador de fatiamento também funciona em listas:
>>> t[:]
['a', 'b', 'c', 'd', 'e', 'f']
Como as listas são mutáveis, geralmente é útil fazer uma cópia antes de
realizar operações que dobram, perfuram ou mutilam listas.
O operador de fatiamento no lado esquerdo de uma atribuição pode
atualizar múltiplos elementos:
extend leva uma lista como um argumento para o método append e adiciona
todos os elementos o final de uma lista:
A maioria dos métodos para lista é do tipo void; eles modificam a lista e
retornam None. Se você acidentalmente escrever t = t.sort(), você se
desapontará com o resultado.
Apagando elementos
Existem várias maneiras de excluir elementos de uma lista. Se você sabe o
índice do elemento que você quer eliminar, você pode usar pop:
pop modifica a lista e retorna o elemento que foi removido. Se você não
fornecer um índice, ele deleta e retorna o último elemento da lista.
Se você não precisar do valor removido, você pode usar o operador del:
Se você sabe o elemento que quer remover (mas não o índice), você pode
usar remove:
Para remover mais de um elemento, você pode usar del com um índice de
fatia:
Listas e funções
Há várias funções internas que podem ser usadas em listas que permitem
que você examine rapidamente uma lista sem escrever seus próprios laços:
total = 0
count = 0
while (True):
inp = input('Enter a number: ')
if inp == 'done': break
value = float(inp)
total = total + value
count = count + 1
# Code: http://www.py4e.com/code3/avenum.py
Nesse programa, nós temos as variáveis count e total para guardar o
número e a quantidade total dos números do usuário, conforme solicitamos
repetidamente ao usuário por um número.
numlist = list()
while (True):
inp = input('Enter a number: ')
if inp == 'done': break
value = float(inp)
numlist.append(value)
# Code: http://www.py4e.com/code3/avelist.py
Fazemos uma lista vazia antes do inicio do laço, e a cada vez que temos
um número, o acrescentamos na lista. No final do programa, nós
simplesmente calculamos a soma dos números na lista e os dividimos pela
contagem dos números na lista para chegar à média.
Listas e strings
Uma string é uma sequência de caracteres e uma lista é uma sequência de
valores, mas uma lista de caracteres não é o mesmo que uma string. Para
converter de uma string para uma lista de caracteres, você pode usar list:
>>> s = 'spam'
>>> t = list(s)
>>> print(t)
['s', 'p', 'a', 'm']
Como list é o nome de uma função interna, você deve evitar usá-la como
nome de uma variável. Eu além disso evito usar “I” porque parece muito
com o número “1”. Então é por isso que eu uso a letra "t".
Depois de você ter usado split para dividir a string em uma lista de
palavras, você pode usar o operador de índices (colchete) para ver uma
palavra particular da lista. Você pode chamar split com um argumento
opcional chamado um delimiter que especifica qual caractere usar como
limite de palavras.
>>> s = 'spam-spam-spam'
>>> delimiter = '-'
>>> s.split(delimiter)
['spam', 'spam', 'spam']
Linhas aliadas
Normalmente, quando estamos lendo um arquivo, queremos fazer algo com
as linhas, além de apenas imprimir a linha inteira. Muitas vezes queremos
encontrar as “linhas interessantes” e depois analisá-las para encontrar a
parte que seja interessante. E se quiséssemos imprimir o dia da semana a
partir das linhas que começam com "De"?
De stephen.marquard@uct.ac.za Sáb Jan 5 09:14:16 2008
O método split é muito eficaz quando confrontado com este tipo de
problema. Podemos escrever um pequeno programa que procura linhas
que começam com "De", divide essas linhas e depois imprime as três
primeiras letras:
fhand = open('mbox-short.txt')
for line in fhand:
line = line.rstrip()
if not line.startswith('From '): continue
words = line.split()
print(words[2])
# Code: http://www.py4e.com/code3/search5.py
Objetos e valores
Se nós executarmos estas atribuições:
a = 'banana'
b = 'banana'
a ‘banana’ a
‘banana’
b ‘banana’ b
>>> a = 'banana'
>>> b = 'banana'
>>> a is b
True
Neste exemplo, o Python criou apenas uma string objeto, e tanto a quanto b
se referem a ele.
Mas quando você cria duas listas, você obtém dois objetos:
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a is b
False
Nesse caso, diríamos que as duas listas são equivalentes, porque elas têm
os mesmos elementos, mas não são idênticas, porque não são o mesmo
objeto. Se dois objetos são idênticos, eles também são equivalentes, mas
se forem equivalentes, eles não são necessariamente idênticos.
Aliados
Se a refere-se a um objeto e você atribui b = a, então ambas as variáveis
referem-se ao mesmo objeto:
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
A associação de uma variável a um objeto é chamada de referência. Neste
exemplo, existem duas referências ao mesmo objeto.
>>> b[0] = 17
>>> print(a)
[17, 2, 3]
Para objetos imutáveis como strings, aliados não são um problema tão
grande. Neste exemplo:
a = 'banana'
b = 'banana'
def remove_primeiro_elemento(t)
del t[0]
>>> t1 = [1, 2]
>>> t2 = t1.append(3)
>>> print(t1)
[1, 2, 3]
>>> print(t2)
None
>>> t3 = t1 + [3]
>>> print(t3)
[1, 2, 3]
>>> t2 is t3
False
def errado_remove_primeiro_elemento(t)
t = t[1:] #ERRADO!
O operador 'slice' cria uma nova lista e a atribuição faz com que t se refira a
essa, mas nenhuma dessas atribuições tem qualquer efeito sobre a lista
passada como argumento.
Uma alternativa é escrever uma função que cria e retorna uma nova lista.
Por exemplo, calda retorna todos, menos o primeiro elemento da lista:
def calda(t):
return t[1:]
Exercício 1: Escreva uma função chamada corte que recebe uma lista
e a modifica, removendo o primeiro e o último elemento, e retorna
None. Depois escreva uma função chamada meio que recebe uma lista e
retorna uma nova lista que contém todos, menos o primeiro e o último
elemento.
Debugging
Descuido com o uso de listas (e outros objetos mutáveis) pode levar a
longa horas de debugging. Abaixo mostra algumas deslizes comuns e
formas de evitá-los:
\index{sort método}
\index{método!sort}
Como sort retorna None, a próxima operação que você executar com t
provavelmente irá falhar.
docs.python.org/library/stdtypes.html#mutable-sequence-types
t.append(x)
t = t + [x]
t.append([x]) # ERRADO!
t = t.append(x) # ERRADO!
t + [x] # ERRADO!
t = t + x # ERRADO!
orig = t[:]
t.sort()
Nesse exemplo, você também pode usar uma função existente
chamada sorted, que retorna uma nova lista organizada e também
mantém a original intacta. Porém, nesse caso, você deve evitar usar
sorted como um nome da variável!
Vamos revisitar nosso programa que procura pelo dia da semana nas
linhas do nosso arquivo:
De stephen.marquard@uct.ac.za Sáb Jan 5 09:14:16 2008
fhand = open('mbox-short.txt')
for linha in fhand:
palavras = line.split()
if palavras[0] != 'De' : continue
print(palavras[2])
Isso parece ser bem mais simples, além que não precisamos do
método rstrip para remover a quebra de linha no final do arquivo.
Porém, qual o melhor?
python search8.py
Sat
Traceback (most recent call last):
File "search8.py", line 5, in <module>
if palavras[0] != 'De' : continue
IndexError: list index out of range
Isso funciona e vemos o dia a partir da primeira linha (Sáb), mas o
programa falha com traceback error. Então, o que deu errado? Por
quê o nosso elegante, inteligente e "Pythonic" programa falhou?
Essa abordagem pode gerar várias linha na saída, pelo menos, você
terá, imediatamente, várias pistas sobre o problema em questão.
Então, adicionamos um print da variável letras logo depois da linha
cinco. Nós até adicionamos o prefixo "Debugging:" na linha, para
podermos manter nossa saída regular separadas de nossa saída de
debugging.
Details: http://source.sakaiproject.org/viewsvn/?view=rev&rev=39772
fhand = open('mbox-short.txt')
contador = 0
for linha in fhand:
palavras = line.split()
# print 'Debug:', palavras
if len(palavras) == 0 : continue
if palavras[0] != 'De' : continue
print(palavras[2])
Glossário
Aliados
Circunstância onde duas ou mais variáveis se referem ao mesmo
objeto.
delimitador
Caractere ou string usado para indicar onde a string deve ser dividida
elemento
Um dos valores em uma lista (ou outra sequência); também chamada
de itens.
equivalente
Ter o mesmo valor
índice
Um valor inteiro que indica um elemento da lista
idêntico
Ser o mesmo objeto (o que implica em equivalência)
lista
Uma sequência de valores
lista de passagem
O acesso sequencial sobre cada elemento da lista
lista aninhada
Uma lista que é um elemento de uma outra lista.
objeto
Algo que uma variável pode se referir. Um objeto tem um tipo e um
valor.
referência
Associação entre variável e seu valor
Exercícios
Exercicio 4: Baixe a copia do arquivo www.py4e.com/code3/romeo.txt.
Escreva um programa para abrir o arquivo chamado romeo.txt e leia-o linha
por linha. Para cada linha, separe-a em uma lista de palavras usando a
função split. Para cada palavra, cheque se esta palavra já existe na lista.
Caso não exista, adicione ela. Quando o programa terminar de verificar,
ordene e imprima estas palavras em ordem alfabética.**
Digite o nome do arquivo: romeo.txt
['Arise', 'But', 'It', 'Juliet', 'Who', 'already',
'and', 'breaks', 'east', 'envious', 'fair', 'grief',
'is', 'kill', 'light', 'moon', 'pale', 'sick', 'soft',
'sun', 'the', 'through', 'what', 'window',
'with', 'yonder']
Você vai analisar a linha que começa com From e irá pôr para imprimir
na tela a segunda palavra (para cada linha do tipo), depois o programa
também deverá contar o número de linhas que começam com "De" e
imprimir em tela o valor final desse contador. Esse é um bom exemplo
da saída com algumas linhas removidas:
python fromcount.py
Digite o nome do arquivo: mbox-short.txt
stephen.marquard@uct.ac.za
louis@media.berkeley.edu
zqian@umich.edu
ray@media.berkeley.edu
cwen@iupui.edu
cwen@iupui.edu
cwen@iupui.edu
There were 27 lines in the file with From as the first word
A função dict cria um novo dicionário com nenhum item. Como dict é
o nome de uma função interna da linguagem, deve-se evitar usá-lo
como nome de variável.
Esta linha cria um item que localiza, a partir da chave 'one', o valor
"um". Se pedirmos para o conteúdo do dicionário ser mostrado
novamente, veremos o par chave-valor separados por dois pontos:
>>> print(ing2port)
{'one': 'um'}
Este formato de saída também é um formato de entrada. Por exemplo,
um dicionário pode ser criado com três itens. Contudo, se ing2port for
mostrado, você pode se surpreender:
>>> print(ing2port['two'])
'dois'
>>> print(ing2port['four'])
KeyError: 'four'
>>> len(ing2port)
3
O operador in também funciona em dicionários; ele dirá se algo
aparece no dicionário como uma chave (os valores dos pares não são
considerados).
www.py4e.com/code3/words.txt
2. Você pode criar uma lista com 26 elementos. Então, você pode
converter cada caractere para um número (usando a função
embutida ord), usar o número como um índice na lista, e
incrementar o contador apropriado.
palavra = 'brontosaurus'
d = dict()
for c in palavra:
if c not in d:
d[c] = 1
else:
d[c] = d[c] + 1
print(d)
Estamos, efetivamente, computando um histograma, que é um termo
estatístico para um conjunto de contadores (ou frequências).
O histograma indica que as letras "a" e "b" aparecem uma vez; "o"
aparece duas vezes, e assim por diante.
word = 'brontosaurus'
d = dict()
for c in palavra:
d[c] = d.get(c,0) + 1
print(d)
Dicionários e Arquivos
Um dos usos mais comuns de um dicionário é a contagem da
ocorrência de palavras em um texto presente em algum arquivo.
Comecemos com um arquivo de palavras, muito simples, extraído do
texto de Romeu e Julieta.
Veremos que temos dois laços for. A repetição externa está lendo as
linhas do arquivo e a repetição interna está iterando entre cada palavra
naquela linha em particular. Esse é um exemplo de padrão chamado
laços aninhados, pois um laço está contido dentro de outro.
counts = dict()
for line in fhand:
words = line.split()
for word in words:
if word not in counts:
counts[word] = 1
else:
counts[word] += 1
print(counts)
# Code: http://www.py4e.com/code3/count1.py
Laços e Dicionários
Se usarmos um dicionário como a sequência em uma instrução for, ela
percorrerá as chaves do dicionário. Este laço mostra cada chave e seu
valor correspondente:
import string
counts = dict()
for line in fhand:
line = line.rstrip()
line = line.translate(line.maketrans('', '', string.punctuation
line = line.lower()
words = line.split()
for word in words:
if word not in counts:
counts[word] = 1
else:
counts[word] += 1
print(counts)
# Code: http://www.py4e.com/code3/count2.py
Debugging
Como você trabalhou com maiores conjuntos de dados, torna-se difícil
tratar erros mostrando tudo em tela e verificando manualmente. Aqui
estão algumas sugestões para o debugging de grandes conjuntos de
dados:
Escreva auto-verificadores
Glossario
chave
Um objeto que aparece num dicionário na primeira parte do par
chave-valor.
dicionário
Um conjunto de uma série de chaves e seus correspondentes
valores.
função hash
Uma função utilizada pela tabela de dispersão (hashtable) para
cacular a localização da chave.
histograma
Um conjunto de contadores.
implementação
A forma como o problema é resolvido (em forma de código, por
exemplo).
item
Outro nome para o par chave-valor.
key-value pair
The representation of the mapping from a key to a value.
laços aninhados
Quando há um ou mais laços de repetição "dentro" de outro laço.
O laço interno completa todas as iterações para cada iteração do
externo.
lookup
Uma operação do dicionário que toma um chave e encontra seu
valor correspondente.
tabela de Dispersão (hashtable)
O algorítmo utilizado para implementar os dicionários em Python.
valor
Um objeto que aparece num dicionário na segunda parte do par
chave-valor. Isso é mais específico do que nossos usos anteriores
da palavra "valor".
Exercícios
Exercício 2: Escreva um programa que categorize cada mensagem
de e-mail de acordo com o dia em que a mensagem foi enviada.
Para isso, procure por linhas que comecem com "From", depois
procure pela terceira palavra e mantenha uma contagem de
ocorrência para cada dia da semana. No final do programa, mostre
em tela o conteúdo do seu dicionário (a ordem não interessa).
linha exemplo:
From stephen.marquard@uct.ac.za Sat Jan 5 09:14:16 2008
Exemplo de código:
python dow.py
Enter a file name: mbox-short.txt
{'Sex': 20, 'Qui': 6, 'Sab': 1}
Para criar uma tupla com um único elemento, você precisa incluir a
vírgula final:
>>> t1 = ('a',)
>>> type(t1)
<type 'tuple'>
Sem a vírgula o Python trata '('a')' como uma expressão com uma
string entre parênteses que é avaliada como uma string:
>>> t2 = ('a')
>>> type(t2)
<type 'str'>
>>> t = tuple()
>>> print(t)
()
>>> t = tuple('lupins')
>>> print(t)
('l', 'u', 'p', 'i', 'n', 's')
>>> print(t[1:3])
('b', 'c')
Mas se você tentar modificar um dos elementos da tupla, você
receberá um erro:
Comparando tuplas
Os operadores de comparação trabalham com tuplas e outras
sequências. Python começa comparando o primeiro elemento de
cada sequência. Se eles forem iguais, ele passa para o próximo
elemento, e assim por diante, até encontrar elementos que diferem.
Elementos subsequentes não são considerados (mesmo se eles
sejam realmente grandes).
Por exemplo, suponha que você tem uma lista de palavras e você
deseja classificá-las do maior para o menor:
t.sort(reverse=True)
res = list()
for length, word in t:
res.append(word)
print(res)
# Code: http://www.py4e.com/code3/soft.py
O primeiro loop cria uma lista de tuplas, onde cada tupla é uma
palavra precedido pelo seu comprimento.
Atribuição de Tuplas
Um dos recursos sintáticos únicos da linguagem Python é a
capacidade de ter uma tupla no lado esquerdo de uma declaração
de atribuição. Isso permite atribuir mais de uma variável por vez
quando o lado esquerdo é uma sequência.
>>> a, b = b, a
>>> a, b = 1, 2, 3
ValueError: muitos valores para descompactar
>>> print(nomedeusuario)
florzinha
>>> print(dominiodoemail)
hotmail.com
Dicionários e tuplas
Os dicionários têm um método chamado items(atente-se à escrita
deste método) que retorna uma lista de tuplas, em que cada tupla é
um par de valores-chave:
Esse loop tem duas variáveis de iteração, isso porque items retorna
uma lista de tuplas e chave, valor é uma atribuição de tupla que
itera sucessivamente em cada um dos pares de valor/chave no
dicionário.
import string
fhand = open('romeo-full.txt')
counts = dict()
for line in fhand:
line = line.translate(str.maketrans('', '', string.punctuati
line = line.lower()
words = line.split()
for word in words:
if word not in counts:
counts[word] = 1
else:
counts[word] += 1
lst.sort(reverse=True)
# Code: http://www.py4e.com/code3/count3.py
Para começar com o óbvio, as strings são mais limitadas que outras
sequências, porque os elementos precisam ser caracteres. Eles
também são imutáveis. Se você precisar alterar os caracteres em
uma string (em vez de criar uma nova string), você deveria usar uma
lista de caracteres.
Debugging
Listas, dicionários e tuplas são conhecidos genericamente como
estrutura de dados; neste capítulo estamos começando a ver
estruturas compostas, como listas de tuplas, e dicionários que
contém tuplas como chaves e listas como valores. Tais estruturas
são úteis, mas elas são propensas ao que chamamos de erros de
forma; Isto é, erros causados quando a estrutura de dados tem o
tipo, tamanho ou composição errada, Ou talvez você escreva algum
código e esqueça da forma dos seus dados e introduza um erro. Por
exemplo, se você está esperando uma lista com um inteiro e eu te
dou um bom e velho inteiro (não em uma lista). Não funciona.
Glossário
atribuição por tuplas
Uma atribuição com uma sequência no lado direito e uma tupla
de variáveis do lado esquerdo. O lado direito é avaliado e então
seus elementos são atribuídos às variáveis do lado esquerdo.
comparável
Um tipo no qual um valor por ser verificado para ver se é maior,
menor, ou igual a outro valor desse mesmo tipo. Quando são
comparáveis, podem ser colocados em listas e também serem
ordenados.
DSU
Aberviação de "decorate-sort-undecorate" (decorar-ordenar-
esquecer), um padrão que envolve construir uma lista de tuplas,
ordenar e então etrair parte do resultado.
espalhar
A operação de tratar uma sequência como uma lista de
argumentos.
estrutura de dados
Uma coleção de valores relacionados, frequentemente
organizados em listas, dicionários, tuplas, etc.
forma (de uma estrutura de dados)
O conjunto de tipo, tamanho e composição de uma estrutura de
dados.
hashable
Um tipo que tem uma funçao hash. Tipos imutáveis como
inteiros, floats e strings são hashable, enquanto mutáveis como
listas e dicionários não são.
reunir
A operação de montar uma tupla de argumentos de tamanho
variável.
singleton
Uma lista (ou outr sequência) com um único elemento.
tupla
Uma sequência imutável de elementos.
Exercícios
Exercício 1: Revise um programa anterior como é pedido: Leia
e analise as linhas com "From" e retire os endereços dessas
linhas. Conte o número de mensagens de cada pessoa usando
um dicionário. Depois de todos os dados serem lidos, mostre a
pessoa com mais envios criando uma lista de tuplas
(contagem, email) do dicionário. Então, ordene a lista em ordem
reversa e mostre a pessoa na primeira posição.
Linha simples:
From stephen.marquard@uct.ac.za Sat Jan 5 09:14:16 2008
Digite o nome do arquivo: mbox-short.txt
cwen@iupui.edu 5
Essa tarefa de pesquisar e extrair é tão comum que o Python tem uma
biblioteca muito poderosa chamada expressões regulares (regular
expressions) que lida com muitas dessas tarefas com bastante elegância.
A razão pela qual não as introduzimos no início do livro é porque, embora
sejam muito poderosas, são um pouco complicadas, além de sua sintaxe
levar algum tempo para ser compreendida.
https://en.wikipedia.org/wiki/Regular_expression
https://docs.python.org/library/re.html
# Code: http://www.py4e.com/code3/re01.py
Abrimos o arquivo, percorremos cada linha e usamos a expressão
regular search () para imprimir apenas linhas que contenham a string
"From:". Este programa não usa o poder real das expressões regulares,
pois poderíamos ter usado com a mesma facilidade o line.find() para
obter o mesmo resultado.
# Code: http://www.py4e.com/code3/re02.py
# Code: http://www.py4e.com/code3/re03.py
# Search for lines that start with From and have an at sign
import re
hand = open('mbox-short.txt')
for line in hand:
line = line.rstrip()
if re.search('^From:.+@', line):
print(line)
# Code: http://www.py4e.com/code3/re04.py
Nós não queremos escrever código para cada um dos tipos de linha,
dividindo e fatiando de forma diferente cada linha. O seguinte programa
usa findall() para achar as linhas que contenham endereços de email e
extrair um ou mais endereços de cada uma dessas linhas.
import re
s = 'A message from csev@umich.edu to cwen@iupui.edu about meeting @2
lst = re.findall('\S+@\S+', s)
print(lst)
# Code: http://www.py4e.com/code3/re05.py
# Code: http://www.py4e.com/code3/re06.py
# Code: http://www.py4e.com/code3/re07.py
...
['wagnermr@iupui.edu']
['cwen@iupui.edu']
['postmaster@collab.sakaiproject.org']
['200801032122.m03LMFo4005148@nakamura.uits.iupui.edu']
['source@collab.sakaiproject.org']
['source@collab.sakaiproject.org']
['source@collab.sakaiproject.org']
['apache@localhost']
Veja também que a saída do programa é uma lista de Python que contém
uma string como unico elemento na lista.
# Search for lines that start with 'X' followed by any non
# whitespace characters and ':'
# followed by a space and any number.
# The number can include a decimal.
import re
hand = open('mbox-short.txt')
for line in hand:
line = line.rstrip()
if re.search('^X\S*: [0-9.]+', line):
print(line)
# Code: http://www.py4e.com/code3/re10.py
# Code: http://www.py4e.com/code3/re11.py
# Code: http://www.py4e.com/code3/re12.py
Nós podemos fazer isso de uma maneira muito mais simples com a
seguinte expressão regular:
^From .* [0-9][0-9]:
# Code: http://www.py4e.com/code3/re13.py
Caractere de Escape
Como usamos caracteres especiais em expressões regulares para
corresponder ao início ou ao final de uma linha ou para especificar
curingas, precisamos indicar como esses caracteres são "normais" e
queremos corresponder ao caractere atual, como um cifrão.
import re
x = 'Acabamos de receber R$ 10,00 por cookies.'
y = re.findall('\$[0-9.]+',x)
Sumário
Enquanto isso apenas arranhou a superfície das expressões regulares,
aprendemos um pouco sobre a linguagem das expressões regulares.
Eles são sequências de busca com caracteres especiais que comunicam
seus desejos ao sistema de expressões regulares quanto ao que define
“correspondência” e o que é extraído das sequências combinadas. Aqui
estão alguns desses caracteres especiais e sequências de caracteres:
Isso diz ao grep para mostrar as linhas que começam com a string
"From:" que estão no arquivo mbox-short.txt. Se você experimentar um
pouco o comando grep e ler a documentação do mesmo, você irá
encontrar algumas sutis diferenças entre o suporte a expressão regular
utilizada em Python e o suporte à expressão regular no grep. Por
exemplo, grep não suporta um caracter não vazio \S, então você irá
precisar utilizar uma maneira ligeiramente mais complexa para
representa-lo: [^ ], que indica um caracter que é qualquer coisa menos
um espaço em branco.
Depuração
Python tem algumas simples e rudimentares documentações embutidas
que podem ser bastante úteis se você precisar de uma rápida consulta
para refrescar sua memória sobre o nome exato de um método
específico. Essa documentação pode ser vista no interpretador do Python
no modo interativo.
>>> help()
help> modules
Se você sabe qual módulo você quer usar, você pode usar o comando
dir() para encontrar os métodos no módulo, como mostra a seguir:
>>> import re
>>> dir(re)
[.. 'compile', 'copy_reg', 'error', 'escape', 'findall',
'finditer', 'match', 'purge', 'search', 'split', 'sre_compile',
'sre_parse', 'sub', 'subn', 'sys', 'template']
Glossário
código frágil
Código executado quando os dados de entrada estão em um
formato particular, mas são propensos a quebra, caso ocorra algum
desvio em relação ao formato correto. Chamamos isto de “código
frágil” pois é facilmente quebrado.
correspondência gananciosa
Noção de que os caracteres + e * em uma expressão regular
expandem para o exterior, de forma a corresponder à maior string
possível.
curinga
Caractere especial que corresponde a qualquer tipo de caractere.
Em expressões regulares, o trunfo é o período.
expressão regular
A language for expressing more complex search strings. A regular
expression may contain special characters that indicate that a search
only matches at the beginning or end of a line or many other similar
capabilities.
grep
Comando disponível na maioria dos sistemas Unix que executa uma
busca entre arquivos de texto, procurando por linhas que
correspondem à expressão regular. O nome do comando é ligado à
expressão em inglês “Generalized Regular Expression Parser”, em
português: “Analisador Generalizado de Expressões Regulares”.
Exercícios
Exercício 1: Escreva um programa simples para simular a operação
do comando grep em Unix. Peça ao usuário para entrar com uma
expressão regular e conte o número de linhas que se igualam à
expressão digitada:
$ python grep.py
Digite uma expressão regular: ^Autor
mbox.txt teve 1798 linhas que se igualam a ^Autor
$ python grep.py
Digite uma expressão regular: ^X-
mbox.txt teve 14368 linhas que se igualam a ^X-
$ python grep.py
Digite uma expressão regular: java$
mbox.txt teve 4175 linhas que se igualam a java$
https://www.w3.org/Protocols/rfc2616/rfc2616.txt
import socket
mysock.close()
# Code: http://www.py4e.com/code3/socket1.py
Your
Program
www.py4e.com
socket S
O Web Pages
connect C Port 80 .
send K
.
E
recv T .
A Socket Connection
import socket
import time
HOST = 'data.pr4e.org'
PORT = 80
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect((HOST, PORT))
mysock.sendall(b'GET http://data.pr4e.org/cover3.jpg HTTP/1.0\r\
count = 0
picture = b""
while True:
data = mysock.recv(5120)
if len(data) < 1: break
#time.sleep(0.25)
count = count + len(data)
print(len(data), count)
picture = picture + data
mysock.close()
# Code: http://www.py4e.com/code3/urljpeg.py
import urllib.request
fhand = urllib.request.urlopen('http://data.pr4e.org/romeo.txt')
for line in fhand:
print(line.decode().strip())
# Code: http://www.py4e.com/code3/urllib1.py
fhand = urllib.request.urlopen('http://data.pr4e.org/romeo.txt')
counts = dict()
for line in fhand:
words = line.decode().split()
for word in words:
counts[word] = counts.get(word, 0) + 1
print(counts)
# Code: http://www.py4e.com/code3/urlwords.py
img = urllib.request.urlopen('http://data.pr4e.org/cover3.jpg').
fhand = open('cover3.jpg', 'wb')
fhand.write(img)
fhand.close()
# Code: http://www.py4e.com/code3/curl1.py
img = urllib.request.urlopen('http://data.pr4e.org/cover3.jpg')
fhand = open('cover3.jpg', 'wb')
size = 0
while True:
info = img.read(100000)
if len(info) < 1: break
size = size + len(info)
fhand.write(info)
# Code: http://www.py4e.com/code3/curl2.py
# Code: http://www.py4e.com/code3/urlregex.py
A biblioteca ssl permite que este programa acesse sites da web que
estritamente utilizam HTTPS. O método read retorna o código-fonte
HTML como um objeto de bytes em vez de retornar um objeto
HTTPResponse. O método de expressão regular findall nos
fornecerá uma lista de todas as strings que correspondem à nossa
expressão regular, retornando apenas o texto do link entre aspas
duplas.
https://pypi.python.org/pypi/beautifulsoup4
# Code: http://www.py4e.com/code3/urllinks.py
Essa lista é muito mais longa porque algumas tags âncora são
caminhos relativos (e.g., tutorial/index.html) ou referências in-page
(por exemplo, '#') que não incluem "http://" ou "https://", que era um
requisito em nossa expressão regular.
Você também pode usar o BeautifulSoup para extrair várias partes
de cada tag:
# Code: http://www.py4e.com/code3/urllink2.py
python urllink2.py
Enter - http://www.dr-chuck.com/page1.htm
TAG: <a href="http://www.dr-chuck.com/page2.htm">
Second Page</a>
URL: http://www.dr-chuck.com/page2.htm
Content: ['\nSecond Page']
Attrs: [('href', 'http://www.dr-chuck.com/page2.htm')]
http://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-
a-parser
$ curl -O http://www.py4e.com/cover.jpg
$ wget http://www.py4e.com/cover.jpg
Glossário
aranha
O ato de ferramentas de pesquisa na web recuperarem uma
página e então todas as outras relacionadas e assim
sucessivamente até terem quase todas as páginas na Internet
que são utilizadas para construir os seus índices de pesquisa.
BeautifulSoup
Uma biblioteca de Python usada analisar documentos HTML e
extrair dados destes que compensam a maioria das
imperfeições no HTML que o navegador geralmente ignora.
Você pode baixar o código do BeautifulSoup em
www.crummy.com.
porta
Um número que geralmente indica com qual aplicação você
está se comunicando quando faz uma conexão de soquete com
um servidor. Como no exemplo, o tráfego da web usualmente
utiliza a porta 80 enquanto o tráfego de email utiliza a porta 25.
Raspar
Quando um programa pretende ser um navegador da web e
recupera uma página e então olha para o conteúdo dela.
Frequentemente programas estão seguindo links em uma
página para achar a próxima e assim atravessar uma rede de
páginas ou uma rede social.
soquete
Uma rede de comunicações entre duas aplicações que podem
enviar e receber uma informação em qualquer direção.
Exercícios
Exercício 1: Altere o programa de soquete socket1.py pR pedir
ao usuário a URL para que então possa ler qualquer página da
web.Você pode usar split('/') para quebrar a URL em suas
componentes para que então possa extrair o nome do
hospedeiro para que o soquete connect chame. Adicione
tratamento de erro usando try e except para lidar com a
condição do usuário digitar uma URL formatada incorretamente
ou uma não existente
Exercício 2: Altere seu programa de soquete para que ele conte
o número de caracteres que recebeu e pare de mostrar
qualquer texto depois que mostrar 3000 caracteres. O programa
deve recuperar o documento inteiro e contar o número total de
caracteres e mostrar o resultado da contagem no final do
documento.
Existem dois formatos comuns que usamos ao trocar dados pela rede. A
Linguagem de Marcação Extensível (eXtensible Markup Language - XML) está
em uso há muito tempo e é mais adequada para a troca de dados no estilo de
documento. Entretanto, quando programas apenas desejam trocar dicionários,
listas ou outras informações entre si, eles usam a Notação de Objeto JavaScript
(JavaScript Object Notation - JSON) (consulte [www.json.org]
(http://www.json.org)). Vamos conhecer os dois formatos.
<person>
<name>Chuck</name>
<phone type="intl">
+1 734 303 4456
</phone>
<email hide="yes" />
</person>
Analisando XML
Aqui está um aplicativo simples que analisa um XML e extrai alguns elementos
de dados dele:
import xml.etree.ElementTree as ET
data = '''
<person>
<name>Chuck</name>
<phone type="intl">
+1 734 303 4456
</phone>
<email hide="yes" />
</person>'''
tree = ET.fromstring(data)
print('Name:', tree.find('name').text)
print('Attr:', tree.find('email').get('hide'))
# Code: http://www.py4e.com/code3/xml1.py
As aspas simples triplas ('''), bem como as aspas duplas triplas ("""), permitem
a criação de strings que abrangem várias linhas.
import xml.etree.ElementTree as ET
input = '''
<stuff>
<users>
<user x="2">
<id>001</id>
<name>Chuck</name>
</user>
<user x="7">
<id>009</id>
<name>Brent</name>
</user>
</users>
</stuff>'''
stuff = ET.fromstring(input)
lst = stuff.findall('users/user')
print('User count:', len(lst))
# Code: http://www.py4e.com/code3/xml2.py
input = '''
<stuff>
<users>
<user x="2">
<id>001</id>
<name>Chuck</name>
</user>
<user x="7">
<id>009</id>
<name>Brent</name>
</user>
</users>
</stuff>'''
stuff = ET.fromstring(input)
lst = stuff.findall('users/user')
print('User count:', len(lst))
lst2 = stuff.findall('user')
print('User count:', len(lst2))
lst armazena todos os elementos user que estão aninhados dentro de seu pai
users. lst2 procura por elementos user que não estão aninhados dentro do
elemento stuff de nível superior, onde não há nenhum.
User count: 2
User count: 0
{
"name" : "Chuck",
"phone" : {
"type" : "intl",
"number" : "+1 734 303 4456"
},
"email" : {
"hide" : "yes"
}
}
Em geral, estruturas JSON são mais simples que XML, muito devido ao fato de
JSON ter menos capacidades que XML. Mas JSON tem a vantagem de mapear
diretamente para alguma combinação de dicionários e listas. E como quase
todas as linguagens de programação têm algo equivalente aos dicionários e
listas do Python, o JSON é um formato muito natural para dois programas
cooperantes que trocam dados.
Analisando JSON
Construímos nosso JSON aninhando dicionários e listas, conforme necessário.
Neste exemplo, representamos uma lista de usuários, onde estes fazem parte de
um conjunto de pares chave-valor (ou seja, um dicionário). Assim, nós temos
uma lista de dicionários.
import json
data = '''
[
{ "id" : "001",
"x" : "2",
"name" : "Chuck"
} ,
{ "id" : "009",
"x" : "7",
"name" : "Brent"
}
]'''
info = json.loads(data)
print('User count:', len(info))
# Code: http://www.py4e.com/code3/json2.py
API
API API
Travel
Application
Arquitetura Orientada a Serviço
Algumas vezes, quando você consegue uma API Key, basta incluir essa chave
como uma parte dos dados POST, ou talvez como um parâmetro na URL em que
você está chamando a API.
Outras vezes, o fornecedor quer uma maior garantia sobre a origem das
requisições, então esperam que você envie, criptograficamente, mensagens
autenticadas usando chaves e segredos compartilhados. Uma tecnologia muito
comum usada para autenticar essas solicitações via internet é chamada OAuth.
Você pode ler mais sobre o protocolo OAuth em www.oauth.net.
Glossário
API
Application Program Interface (Interface de Programação de Aplicativos) -
Um contrato entre aplicativos que define padrões de interação entre dois
componentes de aplicativo.
ElementTree
Uma biblioteca interna do Python usada para analisar dados XML.
JSON
JavaScript Object Notation (Notação de Objeto JavaScript) - Um formato que
permite a marcação de dados estruturados baseado na sintaxe de objetos
JavaScript.
SOA
Service-Oriented Architecture (Arquitetura Orientada a Serviço) - Quando
uma aplicativo é feito de componentes conectados através de uma rede.
XML
eXtensible Markup Language (Linguagem de Marcação Extensível) - Um
formato que permite uma marcação de dados estruturados.
O serviço de geocódigo é de graça, porém tem taxa limitada, de forma que você
não poderá fazer uso ilimitado da API em uma aplicação comercial. Contudo, se
você tiver alguns dados de pesquisa, em que um usuário final inseriu uma
localização em uma caixa de entrada de formato livre, você pode utilizar essa
API para organizar seus dados.
Você pode ler a documentação online para esse serviço, porém é bem simples e
você pode até fazer um teste usando um navegador, basta digitar a URL a
seguir:
http://maps.googleapis.com/maps/api/geocode/json?
address=Ann+Arbor%2C+MI
Certifique-se copiar o URL retirando qualquer espaço que haja nele antes de
colá-lo em seu navegador.
A seguir temos uma simples aplicação que solicita ao usuário uma string de
busca, chama a API de geocódigo da Google e extrai as informações do JSON
retornado.
api_key = False
# If you have a Google Places API key, enter it here
# api_key = 'AIzaSy___IDByT70'
# https://developers.google.com/maps/documentation/geocoding/intro
if api_key is False:
api_key = 42
serviceurl = 'http://py4e-data.dr-chuck.net/json?'
else :
serviceurl = 'https://maps.googleapis.com/maps/api/geocode/json?'
while True:
address = input('Enter location: ')
if len(address) < 1: break
parms = dict()
parms['address'] = address
if api_key is not False: parms['key'] = api_key
url = serviceurl + urllib.parse.urlencode(parms)
print('Retrieving', url)
uh = urllib.request.urlopen(url, context=ctx)
data = uh.read().decode()
print('Retrieved', len(data), 'characters')
try:
js = json.loads(data)
except:
js = None
print(json.dumps(js, indent=4))
lat = js['results'][0]['geometry']['location']['lat']
lng = js['results'][0]['geometry']['location']['lng']
print('lat', lat, 'lng', lng)
location = js['results'][0]['formatted_address']
print(location)
print(location)
# Code: http://www.py4e.com/code3/geojson.py
O programa pega uma string de busca e constrói uma URL com essa string
como parâmetro corretamente codificado, e então usa a urllib para obter o texto
retornado pela API de geocódigo. Diferentemente de uma página web fixa, a
informação que recebemos depende dos parâmetros que enviamos e dos dados
geográficos armazenados nos servidores da Google.
Uma vez que tenhamos recebido os dados JSON, analisamos eles com a
biblioteca json e fazemos alguns teste para confirmar que recebemos bons
dados, e por fim extraímos as informações que procuramos.
{
"results": [
{
"address_components": [
{
"long_name": "Ann Arbor",
"short_name": "Ann Arbor",
"types": [
"locality",
"political"
]
},
{
"long_name": "Washtenaw County",
"short_name": "Washtenaw County",
"types": [
"administrative_area_level_2",
"political"
]
},
{
"long_name": "Michigan",
"short_name": "MI",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "United States",
"short_name": "US",
"types": [
"country",
"political"
]
}
],
"formatted_address": "Ann Arbor, MI, USA",
"geometry": {
"bounds": {
"northeast": {
"lat": 42.3239728,
"lng": -83.6758069
},
"southwest": {
"lat": 42.222668,
"lng": -83.799572
}
},
"location": {
"lat": 42.2808256,
"lng": -83.7430378
},
"location_type": "APPROXIMATE",
"viewport": {
"northeast": {
"lat": 42.3239728,
"lng": -83.6758069
},
"southwest": {
"lat": 42.222668,
"lng": -83.799572
}
}
},
"place_id": "ChIJMx9D1A2wPIgR4rXIhkb5Cds",
"types": [
"locality",
"political"
]
}
],
"status": "OK"
}
lat 42.2808256 lng -83.7430378
Ann Arbor, MI, USA
Enter location:
Aplicação 2: Twitter
À medida que a API Twitter se tornou cada vez mais valiosa, ela passou de uma
API aberta e pública para uma API que requer o uso de assinaturas OAuth em
cada requisição.
Para nosso próximo programa, faça o download dos arquivos twurl.py, hidden.py,
oauth.py, e twitter1.py, disponíveis em www.py4e.com/ code, e os coloque numa
mesma pasta em seu computador.
Para fazer uso desses programas, você precisará ter uma conta no Twitter e
autorizar seu código Python como uma aplicação, definir uma key, secret, token
e token secret. Você deve editar o arquivo hidden.py e inserir essas quatro
strings nas variáveis adequadas, dentro do arquivo:
# https://apps.twitter.com/
# Create new App and get the four strings
def oauth():
return {"consumer_key": "h7Lu...Ng",
"consumer_secret": "dNKenAC3New...mmn7Q",
"token_key": "10185562-eibxCp9n2...P4GEQQOSGI",
"token_secret": "H0ycCFemmC4wyf1...qoIpBo"}
# Code: http://www.py4e.com/code3/hidden.py
https://api.twitter.com/1.1/statuses/user_timeline.json
# https://apps.twitter.com/
# Create App and get the four strings, put them in hidden.py
TWITTER_URL = 'https://api.twitter.com/1.1/statuses/user_timeline.json'
while True:
print('')
acct = input('Enter Twitter Account:')
if (len(acct) < 1): break
url = twurl.augment(TWITTER_URL,
{'screen_name': acct, 'count': '2'})
print('Retrieving', url)
connection = urllib.request.urlopen(url, context=ctx)
data = connection.read().decode()
print(data[:250])
headers = dict(connection.getheaders())
# print headers
print('Remaining', headers['x-rate-limit-remaining'])
# Code: http://www.py4e.com/code3/twitter1.py
# https://apps.twitter.com/
# Create App and get the four strings, put them in hidden.py
TWITTER_URL = 'https://api.twitter.com/1.1/friends/list.json'
while True:
print('')
acct = input('Enter Twitter Account:')
if (len(acct) < 1): break
url = twurl.augment(TWITTER_URL,
{'screen_name': acct, 'count': '5'})
print('Retrieving', url)
connection = urllib.request.urlopen(url, context=ctx)
data = connection.read().decode()
js = json.loads(data)
print(json.dumps(js, indent=2))
headers = dict(connection.getheaders())
print('Remaining', headers['x-rate-limit-remaining'])
for u in js['users']:
print(u['screen_name'])
if 'status' not in u:
print(' * No status found')
continue
s = u['status']['text']
print(' ', s[:50])
# Code: http://www.py4e.com/code3/twitter2.py
{
"next_cursor": 1444171224491980205,
"users": [
{
"id": 662433,
"followers_count": 28725,
"status": {
"text": "@jazzychad I just bought one .__.",
"created_at": "Fri Sep 20 08:36:34 +0000 2013",
"retweeted": false,
},
"location": "San Francisco, California",
"screen_name": "leahculver",
"name": "Leah Culver",
},
{
"id": 40426722,
"followers_count": 2635,
"status": {
"text": "RT @WSJ: Big employers like Google ...",
"created_at": "Sat Sep 28 19:36:37 +0000 2013",
},
"location": "Victoria Canada",
"screen_name": "_valeriei",
"name": "Valerie Irvine",
}
],
"next_cursor_str": "1444171224491980205"
}
leahculver
@jazzychad I just bought one .__.
_valeriei
RT @WSJ: Big employers like Google, AT&T are h
ericbollens
RT @lukew: sneak peek: my LONG take on the good &a
halherzog
Learning Objects is 10. We had a cake with the LO,
scweeker
@DeviceLabDC love it! Now where so I get that "etc
A última parte da saída é onde vemos o laço for lendo os cinco “amigos” mais
recentes da conta @drchuck no Twitter e mostrando o status mais recente de
cada um desses amigos. Muito mais dados estão disponíveis no JSON obtido.
Se você olhar na saída do programa, também poderá ver que o “find the friends”
de uma conta em particular possui um limite de taxa diferente do número de
consultas à timeline que são permitidas a serem executadas por período de
tempo.
Essas keys de segurança da API permitem que o Twitter saiba com confiança
quem está usando seus dados e sua API, além da intensidade do uso. A tática
de limitação de taxa nos permite que obtenhamos dados simples e pessoais,
porém não permite que se desenvolva um produto que retire dados da API
milhões de vezes por dia.
Programação orientada a
objetos
Gerenciando programas maiores
No começo desse livro, vimos quatro tipos básicos de padrões de
programação que usamos para construir nossos programas:
Código sequencial
Código condicional (sentenças "if")
Códigos repetitivos (laços)
Armazenamento e reuso (funções)
Primeiros passos
Assim como vários aspectos de programação, é necessário aprender
os conceitos da programação orientada a objetos antes de usá-la
efetivamente. Você deveria tomar esse capítulo como um meio de
aprender alguns termos e conceitos, para então trabalhar em alguns
poucos exemplos estabelecendo uma fundação para um futuro
aprendizado.
Usando objetos
Como se pode ver, estávamos usando objetos durante todo esse
livro. Python nos fornece vários objetos built_in. Aqui está um código
simples onde as primeiras linhas deveriam parecer bem simples e
naturais para você.
stuff = list()
stuff.append('python')
stuff.append('chuck')
stuff.sort()
print (stuff[0])
print (stuff.__getitem__(0))
print (list.__getitem__(stuff,0))
# Code: http://www.py4e.com/code3/party1.py
Ao invés de focar no que essas linhas querem dizer, vamos olhar no
que está realmente acontecendo desse ponto de vista de
programação orientada a objetos. Não se preocupe se os próximos
parágrados não fizerem nenhum sentido na primeira vez que você lê-
los, uma vez que nós não definimos todos esses termos.
print (stuff.__getitem__(0))
print (list.__getitem__(stuff,0))
# Code: http://www.py4e.com/code3/elev.py
Program
Input Output
A Program
Uma forma de pensar acerca de programação orientada a objetos é
que ela separa o programa em multiplas "zonas". Cada zona contem
parte do código e dos dados (como um programa) e tem interações
bem definidas com o mundo real e com as outras partes do
programa.
# Code: http://www.py4e.com/code3/urllinks.py
Socket html.parser
Object Object
Subdividindo um problema
Umas das vantagens da programação orientada a objetos é que ela
consegue esconder a complexidade do código. Por exemplo,
enquanto precisamos saber como usar os códigos do urllib e
BeautifulSoup, nós não precisamos saber como essas bibliotecas
funcionam internamente. Isso nos permite focar na resolução do
problema e ignorar as outras partes do programa.
Socket html.parser
Object Object
Socket html.parser
Object Object
class PartyAnimal:
x = 0
def party(self) :
self.x = self.x + 1
print("So far",self.x)
an = PartyAnimal()
an.party()
an.party()
an.party()
PartyAnimal.party(an)
# Code: http://www.py4e.com/code3/party2.py
an = PartyAnimal()
counts = dict()
an.party()
self.x = self.x + 1
PartyAnimal.party(an)
Nessa variação, acessamos o código de dentro da classe e
explicitamente passar o ponteiro do objeto an como o primeiro
parâmetro(i.e., self dentro do método). Você pode pensar em
an.party() como abreviada para a linha acima.
class PartyAnimal:
x = 0
def party(self) :
self.x = self.x + 1
print("So far",self.x)
an = PartyAnimal()
print ("Type", type(an))
print ("Dir ", dir(an))
print ("Type", type(an.x))
print ("Type", type(an.party))
# Code: http://www.py4e.com/code3/party3.py
Você pode ver que usando a palavra classe , Criamos um novo tipo.
A partir da saídacdir, Você pode ver tanto ox atributo inteiro e o
método party estão disponíveis no objeto.
class PartyAnimal:
x = 0
def __init__(self):
print('I am constructed')
def party(self) :
self.x = self.x + 1
print('So far',self.x)
def __del__(self):
print('I am destructed', self.x)
an = PartyAnimal()
an.party()
an.party()
an = 42
print('an contains',an)
# Code: http://www.py4e.com/code3/party4.py
Instâncias múltiplas
Até então, nós definimos uma classe, construímos um único objeto,
usamos esse objeto e, então, descartamos esse objeto. Entretanto, o
verdadeiro poder da programação orientada a objeto é manifestado
quando construímos múltiplas instâncias de nossa classe.
class PartyAnimal:
x = 0
name = ''
def __init__(self, nam):
self.name = nam
print(self.name,'constructed')
def party(self) :
self.x = self.x + 1
print(self.name,'party count',self.x)
s = PartyAnimal('Sally')
j = PartyAnimal('Jim')
s.party()
j.party()
s.party()
# Code: http://www.py4e.com/code3/party5.py
class CricketFan(PartyAnimal):
points = 0
def six(self):
self.points = self.points + 6
self.party()
print(self.name,"points",self.points)
s = PartyAnimal("Sally")
s.party()
j = CricketFan("Jim")
j.party()
j.six()
print(dir(j))
# Code: http://www.py4e.com/code3/party6.py
Sumário
Esta é uma rápida introdução à programação orientada a objetos,
que foca principalmente na terminologia e na sintaxe da definição e
uso de objetos. Vamos rapidamente rever o código que nós vimos no
início do capítulo. Neste ponto você já deve entender completamente
o que está acontecendo.
stuff = list()
stuff.append('python')
stuff.append('chuck')
stuff.sort()
print (stuff[0])
print (stuff.__getitem__(0))
print (list.__getitem__(stuff,0))
# Code: http://www.py4e.com/code3/party1.py
Glossário
atributo
Uma variável que é parte de uma classe.
classe
Um modelo usado para a construção de um objeto. Define os
atributos e métodos que farão parte do objeto.
clase filha
Uma nova classe criada quando a classe pai é estendida. A
classe filha herda os atributos e métodos da classe pai.
construtor
Um método opcional especialmente nomeado (__init__) que é
chamado no momento em que uma classe está sendo usada
para construir um objeto. Normalmente é usado para definir os
valores iniciais do objeto.
destruidor
Um método opcional especialmente nomeado (__del__) que é
chamado no momento imediatamente anterior ao objeto ser
destruído. Destruidores são raramente usados.
herança
Quando nós criamos uma nova classe (filha) estendendo uma
classe existente (pai). A classe filha tem todos os atributos e
métodos da classe pai mais atributos e métodos adicionais
definidos por ela mesma.
método
Uma função contida numa classe e nos objetos construídos pela
classe. Alguns padrões orientados a objeto usam 'mensagem'
em vez de 'método' para descrever esse conceito.
objeto
Uma instância construída de uma classe. Um objeto contém
todos os atributos e métodos que foram definidos pela classe.
Algumas documentações orientadas a objeto usam o termo
'instância' e 'objeto' indistintamente.
classe pai
A classe que está sendo estendida para criar uma nova classe
filha. A classe pai contribui com todos os seus métodos e
atributos para a nova classe filha.
1. https://docs.python.org/3/library/html.parser.html↩
http://sqlite.org/
column attribute
Table Relation
Relational Databases
http://sqlitebrowser.org/
http://www.sqlite.org/datatypes.html
conn = sqlite3.connect('music.sqlite')
cur = conn.cursor()
conn.close()
# Code: http://www.py4e.com/code3/db1.py
execute C
U
fetchone R Users Courses
fetchall S
O Members
close R
Your
Program
A Database Cursor
Uma vez que temos o cursor, podemos começar a executar
comandos no conteúdo do banco de dados usando o método
execute().
http://en.wikipedia.org/wiki/SQL
import sqlite3
conn = sqlite3.connect('music.sqlite')
cur = conn.cursor()
print('Tracks:')
cur.execute('SELECT title, plays FROM Tracks')
for row in cur:
print(row)
cur.close()
# Code: http://www.py4e.com/code3/db2.py
Rows in a Table
Nosso loop for encontra duas linhas, e cada linha é uma tupla
Python com o primeiro valor como o title e o segundo valor como o
número de plays.
Nota: Você pode ver cadeias começando com u' em outros livros ou
na Internet. Essa foi uma indicação no Python 2 de que as strings
são strings Unicode capazes de armazenar conjuntos de caracteres
não latinos. No Python 3, todas as strings são unicode por padrão.
Usar * indica que você deseja que o banco de dados retorne todas
as colunas para cada linha que corresponda à cláusula WHERE.
TWITTER_URL = 'https://api.twitter.com/1.1/friends/list.json'
conn = sqlite3.connect('spider.sqlite')
cur = conn.cursor()
cur.execute('''
CREATE TABLE IF NOT EXISTS Twitter
(name TEXT, retrieved INTEGER, friends INTEGER)''')
while True:
acct = input('Enter a Twitter account, or quit: ')
if (acct == 'quit'): break
if (len(acct) < 1):
cur.execute('SELECT name FROM Twitter WHERE retrieved = 0
try:
acct = cur.fetchone()[0]
except:
print('No unretrieved Twitter accounts found')
continue
print('Remaining', headers['x-rate-limit-remaining'])
js = json.loads(data)
# Debugging
# print json.dumps(js, indent=4)
countnew = 0
countold = 0
for u in js['users']:
friend = u['screen_name']
print(friend)
cur.execute('SELECT friends FROM Twitter WHERE name = ? L
(friend, ))
try:
count = cur.fetchone()[0]
cur.execute('UPDATE Twitter SET friends = ? WHERE nam
(count+1, friend))
countold = countold + 1
except:
cur.execute('''INSERT INTO Twitter (name, retrieved,
VALUES (?, 0, 1)''', (friend, ))
countnew = countnew + 1
print('New accounts=', countnew, ' revisited=', countold)
conn.commit()
cur.close()
# Code: http://www.py4e.com/code3/twspider.py
contadornovo = 0
contadorantigo = 0
for u in js['users'] :
friend = u['screen_name']
print(amigo)
cur.execute('SELECT amigos FROM Twitter WHERE nome = ? LIMIT
(friend, ) )
try:
contador = cur.fetchone()[0]
cur.execute('UPDATE Twitter SET amigos = ? WHERE nome = ?
(contador+1, amigo) )
contadorantigo = contadorantigo + 1
except:
cur.execute('''INSERT INTO Twitter (nome, recuperada, ami
VALUES ( ?, 0, 1 )''', ( amigo, ) )
contadornovo = contadornovo + 1
print('Novas contas=',contadornovo,' revisitada=',contadorantigo)
conn.commit()
import sqlite3
conn = sqlite3.connect('spider.sqlite')
cur = conn.cursor()
cur.execute('SELECT * FROM Twitter')
count = 0
for row in cur:
print(row)
count = count + 1
print(count, 'rows.')
cur.close()
# Code: http://www.py4e.com/code3/twdump.py
Nós vemos que há uma linha para cada screen_name, que não foram
recuperados dados para esse screen_name e que cada um no banco
de dados tem um amigo.
Agora, nosso banco de dados nos mostra os amigos obtidos da
nossa primeira conta do Twitter (drchuck). Nós podemos executar o
programa novamente e solicitar que o mesmo obtenha os amigos da
proxima conta ainda "não verificada", simplesmente pressionando
"enter", como representado a seguir:
Entre com uma conta Twitter, ou digite sair:
Recuperando http://api.twitter.com/1.1/friends ...
Novas contas= 18 revisitada= 2
Entre com uma conta Twitter, ou digite sair:
Recuperando http://api.twitter.com/1.1/friends ...
Novas contas= 17 revisitada= 3
Entre com uma conta Twitter, ou digite sair: sair
if ( len(acct) < 1 ) :
cur.execute('SELECT name FROM Twitter WHERE recuperada= 0 LIM
try:
acct = cur.fetchone()[0]
except:
print('Nenhuma conta não visitada encontrada')
continue
http://en.wikipedia.org/wiki/Relational_model
Toda vez que nós encontrarmos uma nova pessoa que drchuck está
seguindo, iremos inserir uma linha da forma:
INSERT INTO Parceiros (from_friend,to_friend) VALUES ('drchuck',
TWITTER_URL = 'https://api.twitter.com/1.1/friends/list.json'
conn = sqlite3.connect('friends.sqlite')
cur = conn.cursor()
while True:
acct = input('Enter a Twitter account, or quit: ')
if (acct == 'quit'): break
if (len(acct) < 1):
cur.execute('''SELECT id, name FROM People
WHERE retrieved = 0 LIMIT 1''')
try:
(id, acct) = cur.fetchone()
except:
print('No unretrieved Twitter accounts found')
continue
else:
cur.execute('SELECT id FROM People WHERE name = ? LIMIT 1
(acct, ))
try:
id = cur.fetchone()[0]
except:
cur.execute('''INSERT OR IGNORE INTO People
(name, retrieved) VALUES (?, 0)''', (acct
conn.commit()
if cur.rowcount != 1:
print('Error inserting account:', acct)
continue
id = cur.lastrowid
data = connection.read().decode()
headers = dict(connection.getheaders())
print('Remaining', headers['x-rate-limit-remaining'])
try:
js = json.loads(data)
except:
print('Unable to parse json')
print(data)
break
# Debugging
# print(json.dumps(js, indent=4))
countnew = 0
countold = 0
for u in js['users']:
friend = u['screen_name']
print(friend)
cur.execute('SELECT id FROM People WHERE name = ? LIMIT 1
(friend, ))
try:
friend_id = cur.fetchone()[0]
countold = countold + 1
except:
cur.execute('''INSERT OR IGNORE INTO People (name, re
VALUES (?, 0)''', (friend, ))
conn.commit()
if cur.rowcount != 1:
print('Error inserting account:', friend)
continue
friend_id = cur.lastrowid
countnew = countnew + 1
cur.execute('''INSERT OR IGNORE INTO Follows (from_id, to
VALUES (?, ?)''', (id, friend_id))
print('New accounts=', countnew, ' revisited=', countold)
print('Remaining', headers['x-rate-limit-remaining'])
conn.commit()
cur.close()
# Code: http://www.py4e.com/code3/twfriends.py
2. Quando temos uma chave lógica para uma pessoa (i.e, nome da
conta) e precisamos do valor id dessa, dependendo se essa
pessoa já está ou não na tabela Pessoas, teremos que: (1)
Procurar essa pessoa na tabela Pessoas e recuperar o valor do
id daquela ou (2) adicionar essa pessoa na tabela Pessoas e
pegar o valor do id dessa nova linha adicionada.
amigo = u['screen_name']
cur.execute('SELECT id FROM Pessoas WHERE nome = ? LIMIT 1',
(amigo, ) )
try:
amigo_id = cur.fetchone()[0]
contadorantigo = contadorantigo + 1
except:
cur.execute('''INSERT OR IGNORE INTO Pessoas (nome, recup
VALUES ( ?, 0)''', ( amigo, ) )
conn.commit()
if cur.rowcount != 1 :
print('Error inserting account:', amigo)
continue
amigo_id = cur.lastrowid
contadornovo = contadornovo + 1
Uma vez que sabemos o valor chave para tanto o usuário do Twitter
quanto seu amigo, no JSON, basta inserirmos os dois números na
tabela Segue com o código abaixo:
Você pode ver os campos id, nome e visitado na tabela Pessoas, bem
como os números em ambas as pontas da relação na tabela Segue.
Na tabela Pessoas, vemos que as três primeiras pessoas foram
visitadas e suas informações foram obtidas. Os dados na tabela
Segue indicam que drchuck (usuário 1) é amigo de todas as pessoas
nas primeiras 5 linhas. Isso faz sentido já que o primeiro conjunto de
informações recuperado e armazenado foi referente aos amigos de
drchuck. Se desejasse imprimir mais linhas da tabela Segue, também
veria os amigos dos usuários 2 e 3.
Uma Chave lógica é uma chave que no "mundo real" pode ser
usado para procurar uma linha. No nosso exemplo de modelo de
dados, o campo nome é uma chave lógica. É o nome de tela para
o usuário e nós de fato procuramos linhas de um usuários várias
vezes no programa usando o campo nome. Você vai notar
frequentemente que isso faz sentido para adicionar uma
restrição UNIQUE para uma chave lógica. Como a chave lógica é
como procuramos uma linha do "mundo externo", faz pouco
sentido permitir várias linhas com o mesmo valor na tabela.
import sqlite3
conn = sqlite3.connect('friends.sqlite')
cur = conn.cursor()
cur.close()
# Code: http://www.py4e.com/code3/twjoin.py
Sumário
Esse capítulo englobou muito assunto para te dar uma visão geral do
básico sobre como usar base de dados em Python. É mais
complicado escrever o código para usar a base de dados para
guardar os dados que dicionários em Python ou arquivos simples,
então existe pouca razão para usar banco de dados a não ser que
sua aplicação realmente precise das capacidades de um banco de
dados. As situações que um banco de dados pode ser útil são: (1)
quando sua aplicação precisa fazer pequenas atualizações aleatórias
em um grande conjunto de dados, (2) quando seus dados são tão
grandes que não se encaixam num dicionário e você precisa analisar
as informações repetidamente, ou (3) quando você tem um processo
de longa duração que você é capaz de parar e reiniciar e manter as
informações de uma inicialização para a outra.
Você pode construir uma simples base de dados com uma única
tabela para satisfazer as necessidades da aplicação, mas várias
aplicações exigirão várias tabelas e conexões/relações entre linhas
em diferentes tabelas. Quando começar a fazer conexões entre
tabelas, é importante fazer um projeto mais pensado e seguir as
regras de normalização de base de dados para fazer melhor uso das
suas capacidades. Visto que a principal motivação para usar um
banco de dados é que há uma grande quantidade de dados para se
lidar, é importante categorizar seus dados de maneira eficiente para
que seu programa funcione o mais rápido possível.
Depurando
Um padrão comum quando você está desenvolvendo um programa
Python para conexão de uma base de dados SQLite será a de iniciar
o programa e conferir os resultados usando o navegador de banco
de dados pro SQLite. O navegador te permite verificar rapidamente
se o programa está funcionando corretamente.
Glossário
atributo
Um dos valores da tupla. Mais comumente chamado de "coluna"
ou "campo".
restrição
Quando chamamos o banco de dados para import uma regra
num campo ou numa linha numa tabela. Uma regra comum é
restringir que não possa haver valores duplicados num campo
em particular (i.e., todos os valores devem ser únicos).
cursor
O cursor te permite executar comandos SQL no banco de dados
e recuperar dados dele. O cursor é similar ao socket ou ao
identificaor de arquivo das conexões de internet e arquivos,
respectivamente.
navegador de banco de dados
Software que te permite se conectar diretamente com o banco
de dados para manipulá-lo diretamente sem escrever um
programa.
chave externa
Uma chave numérica que aponta para a primeira chave de uma
linha de outra tabela. Chaves externas estabelecem relações
entre linhas armazenadas em tabelas diferentes.
índice
Dado adicional que o software do banco de dados conserva
como linhas e adiciona na tabela pra facilitar acelerar a
visualização dos dados.
chave lógica
A chave que o "mundo externo" usa para visualizar uma linha
em particular. Por exemplo em uma tabela de contas de
usuários, o email de uma pessoa poderia ser um ótimo
candidato a ser uma chave lógica para os dados do usuário.
normalização
modelar os dados para que não haja réplicas. Guarda-se cada
item dos dados em um local no banco de dados e se faz
referência dele em outro lugar utilizando uma chave externa.
chave primária
Uma chave numérica atribuída a cada linha é utilizada para se
referenciar uma linha na tabela por meio de outra tabela.
Usualmente os bancos de dados são configurados para atribuir
automaticamente chaves primárias assim que linhas são
inseridas.
relação
Uma área no banco de dados que contém tuplas e atributos.
Mais comumente chamada como "tabela".
tupla
Uma entrada simples numa tabela do banco de dados que é um
conjunto de atributos. Mais comumente chamada como "linha".
Neste capítulo, nós analisaremos três aplicações que reúnem todas esses
conceitos para gerir e vizualizar dados. Você poderá usar essas aplicações
como um código base para te ajudar a começar a resolver um problema do
mundo real.
Todas essas aplicações estão num arquivo ZIP que você pode fazer o dowload
e extrair no seu computador.
www.py4e.com/code3/geodata.zip
Esta é uma variável em Javascript que contém uma lista de listas. A sintaxe
para uma lista constante nesta linguagem é muito semelhante à lista em
Python, logo esta sintaxe será familiar para você.
A Page Ranking
Você pode ter vários pontos de partida no mesmo banco de dados (dentro do
programa), eles são chamados de "webs" ("teias" em português). A "aranha"
escolhe aleatoriamente entre todos os links não visitados em todas as webs
como a próxima página para rastrear.
Isso mostra o número de links gravados, o antigo page rank, o novo page rank,
o id da página, e o url dela. O programa spdump.py apenas mostra páginas
que possuem, pelo menos, um link que aponta para elas.
Agora, com algumas páginas em seu banco de dados, você pode realizar a
classificação das páginas (page rank) usando o programa sprank.py. Você
simplesmente informa o número de iterações de page rank a serem
executadas.
How many iterations:2
1 0.546848992536
2 0.226714939664
[(1, 0.559), (2, 0.659), (3, 0.985), (4, 2.135), (5, 0.659)]
Você pode verificar o banco de dados de novo para confirmar que o page rank
foi atualizado.
(5, 1.0, 0.985, 3, 'http://www.dr-chuck.com/csev-blog')
(3, 1.0, 2.135, 4, 'http://www.dr-chuck.com/dr-chuck/resume/speaking.htm')
(1, 1.0, 0.659, 2, 'http://www.dr-chuck.com/csev-blog/')
(1, 1.0, 0.659, 5, 'http://www.dr-chuck.com/dr-chuck/resume/index.htm')
4 rows.
www.py4e.com/code3/gmane.zip
http://gmane.org/export.php
Quando os dados do email Sakai foram rastreados usando esse software, este
produziu quase um Gigabyte de dados e necessitou de várias execuções em
vários dias. O arquivo README.txt no ZIP acima pode ter instruções sobre
como você pode baixar uma cópia pré-rastreada do arquivo content.sqlite para
uma grande parte do corpo de e-mail Sakai, para que você não precise
rastrear por cinco dias apenas para executar os programas. Se você baixar o
conteúdo pré-rastreado, ainda deve executar o processo de rastreamento para
acompanhar as mensagens mais recentes.
Uma coisa boa é que, depois que você houver escaneado todas as suas
mensagens, contendo-as no arquivo content.sqlite, você poderá rodar o
programa gmane.py novamente para adquirir novas mensagens a medida que
elas são adicionadas à lista.
Os nomes de domínio .com, .org, .edu, and .net são truncados em dois níveis.
Outros nomes de domínio são truncados em três níveis. Logo, si.umich.edu se
torna umich.edu e caret.cam.ac.uk se torna cam.ac.uk. Endereços de e-mail
também são forçados a serem minúsculos, e alguns dos endereços do
@gmane.org descritos como o seguinte
arwhyte-63aXycvo3TyHXe+LvDLADg@public.gmane.org
são convertidos para o seu endereço real sempre que existir uma
correspondência em outra parte do corpo da mensagem.
Isso produz o arquivo gword.js, que pode ser visualizado usando o programa
gword.htm para produzir uma nuvem de palavras, semelhante àquela
produzida no início desta seção.
Uma segunda visualização é produzida pelo código em gline.py. Neste código
é calculado a participação de email pelas organizações ao longo do tempo.
Loaded messages= 51330 subjects= 25033 senders= 1584
Top 10 Oranizations
['gmail.com', 'umich.edu', 'uct.ac.za', 'indiana.edu',
'unicon.net', 'tfd.co.uk', 'berkeley.edu', 'longsight.com',
'stanford.edu', 'ox.ac.uk']
Output written to gline.js
Créditos
Suporte Editorial : Elliott Hauser, Sue Blumenberg
Cover Design: Toby Koening
Tradução para Português (PT-BR): Antonio Marcos, Alysson Hyago,
Andhré Carvalho, Arthur Carneiro, Caio Porto,
Debora Nunes, Gabriel Araújo Medeiros, Giovana
Oliveira, João Pedro Melquiades, Lara Sobral,
Maysa Freire, Natã Macedo, Pyettra Feitosa, Victor
Marinho, Vinicius França, Vinicius Formiga, Vitor
Araujo, Yuri Loia
Printing History
2020-Jan-08 Tradução completa para o português em Python 3.0
2016-Jul-05 Primeira Edição Completa em versão Python 3.0
2015-Dec-20 Conversão inicial para Python 3.0
http://creativecommons.org/licenses/by-nc-sa/3.0/
Você pode ver o que o autor considera como uso comercial e não comercial do
trabalho assim como as excessões da licensa utilizando o apêndice na seção
"Detalhes de Direitos Autorais".
Prefácio
Transformações em uma Jornada
A transformação do livro Python for Everybody em Python para
Todos é o resultado árduo de um projeto do capítulo sobre Robótica
e Automação do IEEE-UFCG (RAS IEEE - UFCG), localizado em
Campina Grande - Paraíba - Brasil.
Charles Severance
www.dr-chuck.com
Ann Arbor, MI, USA
9 de Setembro 2013
Charles Severance é um professor associado na University of
Michigan School of Information.
https://github.com/csev/py4e/graphs/contributors
(Allen B. Downey)
Espero que você goste de trabalhar com este livro e que o ajude a
aprender programa e pense, pelo menos um pouco, como um
cientista da computação.
(Allen B. Downey)
E agradeço à minha esposa, Lisa, por seu trabalho neste livro e pela
Green Tea Press e tudo mais.
Allen B. Downey
Needham MA
Allen Downey é um Professor Associado de Ciência de Computação
na Franklin W. Olin College of Engineering.
creativecommons.org/licenses/by-nc-sa/3.0/.
I would have preferred to license the book under the less restrictive
CC-BY-SA license. But unfortunately there are a few unscrupulous
organizations who search for and find freely licensed books, and
then publish and sell virtually unchanged copies of the books on a
print on demand service such as LuLu or CreateSpace.
CreateSpace has (thankfully) added a policy that gives the wishes of
the actual copyright holder preference over a non-copyright holder
attempting to publish a freely licensed work. Unfortunately there are
many print-on-demand services and very few have as well-
considered a policy as CreateSpace.
If you are intending to translate the book, you may want to contact
me so we can make sure that you have all of the related course
materials so you can translate them as well.
Charles Severance
www.dr-chuck.com
Ann Arbor, MI, USA
September 9, 2013