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]:

Introdução à Programação em Python

Dicionários

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)


[['Joao', '3333-2332']]
[['Joao', '3333-2332'], ['Maria', '444-2332']]
[['Joao', '3333-2332'], ['Maria', '444-2332'], ['Jose', '2233-2332']]
[['Joao', '3333-2332'], ['Maria', '444-2332'], ['Jose', '2233-2332']]

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)


{'Joao': '3333-2332'}
{'Joao': '3333-2332', 'Maria': '444-2332'}
{'Joao': '3333-2332', 'Maria': '444-2332', 'Jose': '2233-2332'}
{'Joao': '3333-2332', 'Maria': '444-2332', 'Jose': '2233-2332'}

In [3]:
agenda = {'Jose': '2233-2332', 'Joao': '3333-2332', 'Maria': '444-2332'}
print (agenda)


{'Joao': '3333-2332', 'Maria': '444-2332', 'Jose': '2233-2332'}

Essa estrutura permite adicionar telefones indexados pelo nome!

Dessa forma podemos acessar um telefone da seguinte forma:


In [4]:
print (agenda['Joao'])


3333-2332

Também podemos verificar se um elemento existe nessa agenda:


In [6]:
print ("Joao" in agenda, "Mario" in agenda)


True False

Também é possível obter a lista de nomes e de telefones:


In [5]:
print (agenda.keys())
print (agenda.values())


dict_keys(['Joao', 'Maria', 'Jose'])
dict_values(['3333-2332', '444-2332', '2233-2332'])

E percorrer todos os nomes e valores ao mesmo tempo:


In [8]:
for nome, telefone in agenda.items():
    print ("O telefone de", nome, "é", telefone)


O telefone de Joao é 3333-2332
O telefone de Maria é 444-2332
O telefone de Jose é 2233-2332

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.:

  • amor, roma
  • pedro, poder
  • rato, rota
  • assim, missa

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"))


True
False

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'])


0
10

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'])


0
0
10

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"))


True
False

Dicionários como Mapa de Substituição

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 cada letra da palavra:
    • Se a letra existir no Mapa, adiciona a letra convertida na nova palavra
    • Senão, adiciona a própria letra

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))


460r4 $0m0$ #4(k3r$

Para evitar a condicional para verificar se a letra existe no Mapa, podemos usar o comando .get(chave, padrao) que recebe dois parâmetros:

  • a chave que queremos recuperar do dicionário
  • valor padrão caso a chave não seja encontrada

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))


4
B
460r4 $0m0$ m4!$ #4(k3r$

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))


460r4 $0m0$ mu!70 #4(k3r$

Leitura de Arquivos

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()


Esse exemplo será usado para aprender o mínimo sobre leituras de arquivos textos

e como o texto pode ser usado em uma estrutura de dicionário

Se o resultado for correto teremos a ocorrência da palavra o em quatro vezes

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:

  • 'r': ler o arquivo
  • 'w': escrever no arquivo (apagando todo seu conteúdo)
  • 'a': escrever a partir do final do arquivo (sem apagar o conteúdo anterior)

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()


Linha de Exemplo


In [ ]: