In [1]:
# ignore esse código inicial, é apenas para preparar a página
from IPython.display import YouTubeVideo, HTML, Image, display
css_file = './modelo.css'
HTML(open(css_file, "r").read())
Out[1]:
Vamos criar um programa que gerencia uma agenda telefônica.
Para esse fim, armazenaremos nossos contatos em uma lista.
Teremos que criar uma função para adicionar um contato e outra para procurar pelo contato (vamos supor que nunca apagaremos um contato da lista).
In [2]:
"""
A lista de contatos terá o formato:
[ ["nome", "telefone"] ]
"""
def Procura(nome, agenda):
for contato in agenda:
if contato[0] == nome:
return contato[1]
return None
def Adiciona(nome, telefone, agenda):
if Procura(nome, agenda) == None:
agenda.append([nome,telefone])
In [3]:
agenda = []
Adiciona("Joao","3333-2332", agenda)
print (agenda)
Adiciona("Maria","444-2332", agenda)
print (agenda)
Adiciona("Jose","2233-2332", agenda)
print (agenda)
Adiciona("Joao","3333-2332", agenda)
print (agenda)
A palavra-chave None
significa que você não quer retornar nada!
Cuidado: Note que não é necessário retornar a lista na função Adiciona()
. As listas passadas como parâmetros de uma função são alteradas diretamente!
O Python possui um tipo de variável que facilita o uso de estruturas desse tipo, conhecida como dicionários.
In [2]:
agenda = {}
agenda['Joao'] = "3333-2332"
print (agenda)
agenda["Maria"] = "444-2332"
print (agenda)
agenda["Jose"] = "2233-2332"
print (agenda)
agenda['Joao'] = "3333-2332"
print (agenda)
In [3]:
agenda = {'Jose': '2233-2332', 'Joao': '3333-2332', 'Maria': '444-2332'}
print (agenda)
Essa estrutura permite adicionar telefones indexados pelo nome!
Dessa forma podemos acessar um telefone da seguinte forma:
In [4]:
print (agenda['Joao'])
Também podemos verificar se um elemento existe nessa agenda:
In [6]:
print ("Joao" in agenda, "Mario" in agenda)
Também é possível obter a lista de nomes e de telefones:
In [5]:
print (agenda.keys())
print (agenda.values())
E percorrer todos os nomes e valores ao mesmo tempo:
In [8]:
for nome, telefone in agenda.items():
print ("O telefone de", nome, "é", telefone)
Anagrama: determine se uma palavra $p1$ é anagrama da palavra $p2$.
$p1$ e $p2$ são anagramas se for possível escrever $p1$ utilizando as letras de $p2$. Ex.:
Para resolver esse problema basta verificar se a lista de frequências das letras de $p1$ é igual a de $p2$:
In [9]:
def Anagrama(p1,p2):
return FreqLetras(p1) == FreqLetras(p2)
Uma lista de frequências de letras pode ser feita na forma (ex.: amar):
Freq['a'] = 2
Freq['b'] = 0
...
Freq['m'] = 1
...
Freq['r'] = 1
...
Freq['z'] = 0
Ou ignorando as letras com frequência igual a $0$:
Freq = { 'a':2, 'm':1, 'r':1' }
In [48]:
def FreqLetras(palavra):
print (Anagrama("amor", "roma"))
print (Anagrama("amor", "terror"))
Para facilitar podemos utilizar a função defaultdict
da biblioteca collections
que permite criar um dicionário em que toda chave inexistente contém um valor padrão:
In [10]:
from collections import defaultdict
def Padrao():
return 0
Freq = defaultdict( Padrao )
print (Freq['a'])
Freq['a'] += 10
print (Freq['a'])
De forma conveniente, a função int()
, usada para converter um valor para inteiro, retorna 0
caso nenhum parâmetro seja passado para ela.
Nota: da mesma forma, float()
retorna 0.0
e str()
retorna ''
.
In [11]:
from collections import defaultdict
print (int())
Freq = defaultdict( int )
print (Freq['a'])
Freq['a'] += 10
print (Freq['a'])
In [12]:
def FreqLetras(palavra):
Freq = defaultdict( int )
for letra in palavra:
Freq[letra] += 1
return Freq
print (Anagrama("amor", "roma"))
print (Anagrama("amor", "terror"))
Escrita L337: no submundo hacker é comum escrever as palavras com a substituição de algumas letras por números ou símbolos como exemplificado abaixo:
Letra | L337 |
---|---|
A | 4 |
C | ( |
E | 3 |
G | 6 |
H | # |
I | ! |
O | 0 |
S | $ |
T | 7 |
X | % |
Podemos criar um dicionário que mapeia cada letra do alfabeto para seu correspondente L337, se houver, ou a própria letra caso contrário.
Temos que tomar o cuidado de fazer o mapa para maiúsculas ou mínusculas.
Vamos primeiro criar uma lista de tuplas contendo as letras que queremos mapear.
tuplas são listas que não podem ser alteradas, elas são definidas por parênteses ao invés de colchetes.
In [13]:
trocas = [ ('A', '4'), ('C', '('), ('E', '3'), ('G','6'),
('H','#'), ('I','!'), ('O','0'), ('S','$'),
('T','7'), ('X','%') ]
Em seguida percorremos essa lista de trocas para gerar nosso dicionário Mapa
.
Sabendo que todas as tuplas tem apenas dois elementos podemos percorrer essa lista de uma forma conveniente:
In [14]:
Mapa = {}
for letra, l337 in trocas:
Mapa[letra.lower()] = l337 # converte a letra para minúscula
Mapa[letra.upper()] = l337 # converte a letra para maiúscula
Agora basta que a nossa função faça o seguinte, dado um mapa de trocas e uma frase, construir uma string da seguinte maneira:
Para facilitar a construção da string, vamos adicionar cada letra da nova palavra em uma lista.
Em seguida podemos usar o seguinte comando para construir uma string a partir de uma lista de letras:
palavra = ''.join(listaLetras)
In [58]:
def converte(palavra, Mapa):
print (converte('Agora somos hackers', Mapa))
Para evitar a condicional para verificar se a letra existe no Mapa, podemos usar o comando .get(chave, padrao)
que recebe dois parâmetros:
In [15]:
def converte(palavra, Mapa):
listaLetras = []
for letra in palavra:
listaLetras.append( Mapa.get(letra, letra) ) # se não encontrar a letra, queremos que retorne a mesma letra
return ''.join(listaLetras)
print (Mapa.get('A', 'A'))
print (Mapa.get('B', 'B'))
print (converte('Agora somos mais hackers', Mapa))
Podemos reduzir ainda mais essa função usando list comprehension:
In [16]:
def converte(palavra, Mapa):
return ''.join( [ Mapa.get(letra, letra) for letra in palavra ] )
print (converte('Agora somos muito hackers', Mapa))
Nos próximos exercícios utilizaremos textos lidos diretamente de um arquivo externo.
O Python conta com diversas opções de leitura de arquivos, vamos aprender a usar uma delas para arquivos com textos acentuados.
In [18]:
import codecs
f = codecs.open('exemplo.txt', 'r', 'utf-8')
for linha in f:
print (linha)
f.close()
A função open()
da biblioteca codec recebe três parâmetros.
O primeiro é o nome do arquivo a ser aberto.
O segundo é uma letra que representa o que eu quero fazer com o arquivo:
Ao abrir o arquivo, posso usar a variável associada a ele (f, no exemplo) para realizar as operações de leitura e escrita.
Para guardar todas as linhas em uma lista, temos o comando:
listaLinhas = f.readlines()
Ou podemos percorrer as linhas utilizando o for, como no exemplo.
Para escrever um conteúdo em um arquivo utilizamos o comando print
conforme o seguinte exemplo:
In [22]:
import codecs
f = codecs.open('exemploEscrita.txt', 'w', 'utf-8')
print("Linha de Exemplo", file=f)
f.close()
In [23]:
import codecs
f = codecs.open('exemploEscrita.txt', 'r', 'utf-8')
for linha in f:
print(linha)
f.close()
In [ ]: