# Lógica de programação com `Python`
----
# Aula 03
## Correndo
---
# Mais dados
---
<style>
code.error {
color: red !important;
}
</style>
# Tuplas
----
## Tuplas 1
- São parecidas com listas, porém são imutáveis
```python
❯❯❯ tupla = ('a', 'b', 'c')
❯❯❯ tupla[0]
'a'
❯❯❯ tupla[0:2]
('a','b')
❯❯❯ del tupla[2]
```
----
<!-- .slide: data-transition="zoom" -->
<code class="error">Traceback (most recent call last): </code>
<code class="error"> File "<stdin>", line 1, in </code>
<code class="error">TypeError: 'tuple' object doesn't support item deletion </code>
----
## Tuplas 2
```python
❯❯❯ tupla = -1, 2 # podemos criar sem usar parenteses
❯❯❯ print(tupla)
(-1,2)
❯❯❯ x, y = tupla # podemos transferir o valor para
# outras variáveis
❯❯❯ print(x,y)
-1 2
❯❯❯ x, y = y, x + y # atribuição mútipla (aula 2)
❯❯❯ print(x,y) # nada mais é que atribuição em tuplas
2 1
```
---
# Dicionários
----
## Dicionários
- Em listas e tuplas, acessamos os valores usando índices numéricos
- Nos *dicionários*, nomeamos os índices (também chamados _chaves_) como quisermos
- Sintaxe: `dicionario = {chave: valor}`
----
### Dicionários 1
```python
❯❯❯ dicionário = {"nome": "Bossa", "idade": 25, 8: ('x', 'y')}
❯❯❯ dicionário['nome'] # pegando o valor
'Bossa'
❯❯❯ dicionário[8]
('x', 'y')
❯❯❯ dicionário['idade']
25
❯❯❯ list(dicionário) # listando os indices
['nome', 'idade', 8]
❯❯❯ list(dicionário.values()) # listando os valores
['Bossa', 25, ('x', 'y')]
```
----
### Dicionários 2
```python
❯❯❯ dicionário[8] = 'z' # alterando um valor
❯❯❯ dicionário
{'nome': 'Bossa', 'idade': 25, 8: 'z'}
❯❯❯ dicionário['chave' ] = [1,2,3] # inserindo um valor
❯❯❯ dicionário
{'nome': 'Bossa', 'idade': 25, 8: 'z', 'chave': [1, 2, 3]}
❯❯❯ del dicionário[8] # apagando um valor
❯❯❯ dicionário
{'nome': 'Bossa', 'idade': 25, 'chave': [1, 2, 3]}
❯❯❯ 'nome' in dicionário # verifica se existe a chave
True
❯❯❯ 'Bossa' in dicionário # não verifica por valor
False
```
----
### Dicionários 3
```python
❯❯❯ for chave, valor in dicionário.items():
... print("A chave {} tem valor {}.".format(chave, valor))
...
A chave nome tem valor Bossa.
A chave idade tem valor 25.
A chave 8 tem valor z.
A chave chave tem valor [1, 2, 3].
```
----
### Guardando dados
```python=
# esse dicionário vai conter logins como chaves
# e os valores dessas chaves são outros
# dicionários com informações como nome e senha
bancodedados = {
"bossa": {'nome': "Luiz Fernando", "senha": "12345"},
"fulano": {'nome': "Fulano da Silva", "senha": "abcde"},
"admin": {'nome': "Administrador", "senha": "admin"},
"user": {'nome': "Usuário", "senha": "passwd"}
}
```
----
### Usando dados
```python=+
# vamos criar um prompt de login
login = input("Digite seu login: ")
senha = input("Digite sua senha: ")
if login in bancodedados:
# login ok, vamos ver a senha
if bancodedados[login]["senha"] == senha:
# login bem sucedido
msg = "Bem-vindo {}"
print(msg.format(bancodedados[login]["nome"]))
else:
print("Senha incorreta.")
else:
print("Login não encontrado.")
```
---
# + entradas e + saídas
----
## Lendo e escrevendo em arquivos
- Podemos usar o comando `open` para abrir um arquivo
- Uma vez aberto, podemos ler/escrever no arquivo
----
### Lendo um arquivo
- Crie um arquivo chamado `texto.txt` e escreva qualquer coisa nele
```python=
arquivo = open("texto.txt", "r")
# abrimos o arquivo em modo leitura
conteudo = arquivo.read() # lemos o arquivo inteiro
print(conteudo) # mostramos o conteúdo
arquivo.close() # fechamos o arquivo
```
----
### Lendo linhas de um arquivo
```python=
arquivo = open("texto.txt", "r")
# abrimos o arquivo em modo leitura
i = 1
for linha in arquivo: # podemos iterar pelas linhas
print("linha {}:".format(i),linha, end="")
i += 1
arquivo.close()
# fechamos o arquivo
```
----
### Gerenciador de contexto
- Para evitar o erro de esquecer de fechar o arquivo, usamos a cláusula `with`
```python=
i = 1
with open("texto.txt", "r") as arquivo:
# dizemos que arquivo vai ser igual a open([...])
for linha in arquivo: # podemos iterar pelas linhas
print("linha {}:".format(i),linha, end="")
i += 1
# quando o python sai do bloco with, fecha automaticamente
```
----
### Escrevendo no arquivo
```python=
with open("resultado.txt", "w") as arquivo:
arquivo.write("Primeira frase")
arquivo.write("Segunda frase\n")
# precisamos escrever a quebra de linha
arquivo.writelines(["A", "B", "C"])
```
----
:::danger
Abrir o arquivo com a opção `'w'` apaga o conteúdo existente no arquivo. Se não quiser apagar, use a opção `'a'` para acrescentar conteúdo.
:::
---
# Exercícios arquivos
----
## Instruções 1
- Vamos salvar nosso `bancodedados` em um arquivo que terá o nome `bancodedados.csv`
- A primeira linha do arquivo será `login,nome,hash`
- Para cada chave do dicionário `bancodedados` será escrita uma linha do arquivo
----
## Instruções 2
- Não iremos salvar as senhas no arquivo, iremos criar _hashs_ das senhas, usando a função `crypt` do módulo `crypt`
- Cada linha do arquivo deve ser composta do login, seguido do nome e do hash da senha, todos esses valores separados por vírgula e terminado numa quebra de linha
----
### Solução
```python=
from crypt import crypt # importando a função citada
prelinha = "{},{},{}\n"
# esse vai ser o formato da nossa linha
with open("bancodedados.csv", "w") as arquivo:
# abrindo o arquivo com o gerenciador de contexto
cabecalho = prelinha.format("login", "nome", "hash")
arquivo.write(cabecalho)
# escrevemos a primeira linha
for x in bancodedados: # x é o login
dados = bancodedados[x]
hash = crypt(dados["senha"]) # senha criptografada
linha = prelinha.format(x,dados["nome"],hash)
arquivo.write(linha) # escreve a linha
```
<!-- .element: class="fragment" data-fragment-index="1" -->
---
# Compressão de listas
----
Assim como em matemática temos descrições de conjuntos como $$\{x^2+1\, | \, x\in \mathbb{N} \text{ e $x$ é par } \},$$
podemos fazer o mesmo com listas em `python`
----
## Compressão de listas
```python=!
❯❯❯ universo = range(10) # definindo uma lista
❯❯❯ [x**2 for x in universo ]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
❯❯❯ pares = [ n for n in universo if n % 2 == 0 ]
# pegando só os elementos que satisfazem a condição do if
❯❯❯ pares
[0, 2, 4, 6, 8]
# construindo uma lista com if e else
❯❯❯ [n if n % 2 == 0 else "impar" for n in universo]
[0, 'impar', 2, 'impar', 4, 'impar', 6, 'impar', 8, 'impar']
# construindo um conjunto de pares ordenados
❯❯❯ [(i//2,j) for i in pares for j in pares]
[(0, 0), (0, 2), (0, 4), (0, 6), (0, 8), (1, 0), (1, 2), (1, 4), (1, 6), (1, 8), (2, 0), (2, 2), (2, 4), (2, 6), (2, 8), (3, 0), (3, 2), (3, 4), (3, 6), (3, 8), (4, 0), (4, 2), (4, 4), (4, 6), (4, 8)]
```
----
### Compressão de listas: matrizes
- Uma matriz pode ser representada como uma lista de listas
- Compressão de listas torna mais fácil criar listas
- Vamos usar a seguinte função para mostrar matrizes
```python=
def mshow(A):
"""Função que mostra uma matriz
"""
for linha in A: # percorre as linhas de A
print(*linha, sep="\t") # abre a linha e coloca
# <tab> como separador
```
----
### Matrizes 1
```python=!
❯❯❯ linhas = range(6)
❯❯❯ colunas = range(5)
❯❯❯ A = [[2**i*3**j for j in colunas] for i in linhas]
❯❯❯ mshow(A)
1 3 9 27 81
2 6 18 54 162
4 12 36 108 324
8 24 72 216 648
16 48 144 432 1296
32 96 288 864 2592
```
----
### Matrizes 2
```python=!
❯❯❯ I = [[ 1 if i==j else 0 for j in linhas ] for i in linhas ]
❯❯❯ mshow(I)
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1
```
----
### Matrizes 3
```python
❯❯❯ zeros = [[0]*5]*6
❯❯❯ mshow(zeros) # Matriz 5x6 cheias de zero
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
```
---
# Mais coisas legais
---
## NumPy
- Biblioteca para computação científica
- Vários algoritmos já prontos
- Substituto ao MATLAB
----
### NumPy
```python
❯❯❯ import numpy as np
❯❯❯ x = np.array([1, 0, 3, 4]) # vetor
❯❯❯ A = np.array([[1,0,0,0], # matriz
... [0,2,0,0],
... [0,0,3,0],
... [0,0,0,4] ])
❯❯❯ A[0,3] = -1 # mudando um valor
❯❯❯ A
array([[ 1, 0, 0, -1],
[ 0, 2, 0, 0],
[ 0, 0, 3, 0],
[ 0, 0, 0, 4]])
```
----
### NumPy
```python
❯❯❯ A.T # transposta
array([[ 1, 0, 0, 0],
[ 0, 2, 0, 0],
[ 0, 0, 3, 0],
[-1, 0, 0, 4]])
❯❯❯ A**2
array([[ 1, 0, 0, 1],
[ 0, 4, 0, 0],
[ 0, 0, 9, 0],
[ 0, 0, 0, 16]])
```
----
### NumPy
```python!
❯❯❯ A*x # A*x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "[...]/numpy/matrixlib/defmatrix.py", line 220, in __mul__
return N.dot(self, asmatrix(other))
File "<__array_function__ internals>", line 6, in dot
ValueError: shapes (4,4) and (1,4) not aligned: 4 (dim 1) != 1 (dim 0)
❯❯❯ A.shape
(4,4)
❯❯❯ x.shape
(4,)
```
----
### NumPy
```python
❯❯❯ x.reshape(4,1)
array([[1],
[0],
[3],
[4]])
❯❯❯ A*x # agora a multiplicação funciona
matrix([[-3],
[ 0],
[ 9],
[16]])
❯❯❯ b = np.array([[4,0,0,4]]).T # isso gera um vetor `de pé`
```
----
### NumPy
```python
❯❯❯ np.linalg.solve(A,b) # Resolve o sistema A*x = b
array([[5.],
[0.],
[0.],
[1.]])
❯❯❯ np.linalg.det(A)
23.999999999999993
❯❯❯ autovalores, autovetores = np.linalg.eig(A)
❯❯❯ autovalores
array([1., 2., 3., 4.])
```
----
### NumPy
```python
❯❯❯ autovetores # colunas são autovetores normalizados
matrix([[ 1. , 0. , 0. , -0.31622777],
[ 0. , 1. , 0. , 0. ],
[ 0. , 0. , 1. , 0. ],
[ 0. , 0. , 0. , 0.9486833 ]])
```
----
:::info
Mais infos em
- [NumPy for Matlab users](https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html)
- [numpy.org](https://numpy.org/)
:::
---
## SymPy
Biblioteca para computação simbólica
```python
❯❯❯ from sympy import symbols, expand, factor, diff, integrate
❯❯❯ x = symbols("x")
❯❯❯ diff(x**3 + 2*x + 1)
3*x**2 + 2
❯❯❯ expand((x+1)*(x+3))
x**2 + 4*x + 3
❯❯❯ factor(x**2 + 4*x + 4)
(x + 2)**2
❯❯❯ from sympy import sin
❯❯❯ integrate(x*sin(x))
-x*cos(x) + sin(x)
```
----
### Sympy
Podemos trabalhar com álgebra pura
```python!
❯❯❯ from sympy.combinatorics.free_groups import free_group
❯❯❯ from sympy.combinatorics.fp_groups import FpGroup
❯❯❯ F, a, b = free_group("a, b")
❯❯❯ G = FpGroup(F, [a**2, b**3, (a*b)**4]) # G = <a,b | a², b³, (ab)⁴>
❯❯❯ G.order()
24
❯❯❯ G.is_abelian
False
❯❯❯ G.center()
[<identity>]
❯❯❯ G.elements
[<identity>, a, b, b**-1, a*b, a*b**2, b*a, b**2*a, a*b*a, a*b**2*a, b*a*b, b*a*b**2, b**2*a*b, b**2*a*b**2, a*b*a*b, a*b*a*b**2, a*b**2*a*b, b*a*b*a, b*a*b**2*a, b**2*a*b*a, a*b*a*b**2*a, a*b**2*a*b*a, b*a*b**2*a*b, b*a*b**2*a*b*a]
```
---
## pandas
Biblioteca para trabalhar com dados.
```python
❯❯❯ dados = [["Nome", "Curso", "P1", "P2", "P3"],
... ["Alice", "Matemática", 4.5, 6.0, 8.0],
... ["Bob", "Química", 6.0, 5.0, 8.0],
... ["Charlie", "Matemática", 8.0, 9.0, 10.0],
... ["David", "Matemática", 3.0, None, 5.0],
... ["Eva", "Química", 6.0, 7.0, None]]
❯❯❯ import numpy as np
❯❯❯ import pandas as pd
❯❯❯ df = pd.DataFrame(dados[1:], columns=dados[0])
# primeira linha como colunas, o resto como dados
```
----
### pandas
```python
❯❯❯ df
Nome Curso P1 P2 P3
0 Alice Matemática 4.5 3.0 8.0
1 Bob Química 6.0 2.0 7.0
2 Charlie Matemática 8.0 9.0 10.0
3 David Matemática 3.0 NaN 5.0
4 Eva Química 6.0 7.0 NaN
❯❯❯ df["Media"] = (df["P1"] + df["P2"] + df["P3"])/3
# calcula uma nova coluna usando valores das outras
❯❯❯ df
Nome Curso P1 P2 P3 Media
0 Alice Matemática 4.5 6.0 8.0 6.166667
1 Bob Química 6.0 2.0 7.0 5.000000
2 Charlie Matemática 8.0 9.0 10.0 9.000000
3 David Matemática 3.0 NaN 5.0 NaN
4 Eva Química 6.0 7.0 NaN NaN
```
----
### pandas
```python
❯❯❯ def resultado(x): # funcao que vamos aplicar
... if x >= 6:
... return "Aprov"
... elif 3 <= x < 6:
... return "Rec"
... elif x < 3:
... return "Repr"
... else:
... return "2a Cham"
...
❯❯❯ df["Resultado"] = df["Media"].apply(resultado)
# aplica a função resultado em cada linha de "Media"
```
----
### pandas
```python
❯❯❯ df
Nome Curso P1 P2 P3 Media Resultado
0 Alice Matemática 4.5 6.0 8.0 6.166667 Aprov
1 Bob Química 6.0 2.0 7.0 5.000000 Rec
2 Charlie Matemática 8.0 9.0 10.0 9.000000 Aprov
3 David Matemática 3.0 NaN 5.0 NaN 2a Cham
4 Eva Química 6.0 7.0 NaN NaN 2a Cham
```
---
## matplotlib
- Pacote para criar gráficos fantásticos
- Não pode ser usado no terminal
> Alguns exemplos do site [matplolib.org](https://matplotlib.org/)
----
### matplotlib

----
### matplotlib

----
### matplotlib

---
# Instalação
----
## Instalação
- Nas distribuições linux, o python já vem instalado por padrão.
- No windows você baixar os arquivos autoinstaláveis em [python.org](https://www.python.org/)
----
## Ubuntu
Para instalar um pacote completo com as bibliotecas científicas, basta executar
```bash!
sudo apt install python3-venv python3-pip
pip3 install numpy scipy matplotlib ipython jupyter jupyterlab pandas sympy nose spyder
```
----
## Windows
Instale o _Anaconda_, um gerenciador de pacotes que já inclui tudo o que precisamos.
Acesse [anaconda.com](https://www.anaconda.com/).
----

---
# Onde codificar
----
## Terminal
- No Ubuntu basta digitar `python3` na linha de comando
- No Windows, após instalar o Anaconda, basta abrir o _Anaconda Prompt_ e digitar `python`
----
## `Ipython`
- No Ubuntu basta digitar `ipython` na linha de comando
- No Windows, após instalar o Anaconda, basta abrir o _Anaconda Prompt_ e digitar `ipython`
- É um `Python` interativo melhorado, com completamento usando `<TAB>`, ajuda com `?`, exibição de gráficos e mais
----

----
## IDE
- O _Spyder_ é um *ambiente de desenvolvimento integrado* multiplataforma que se assemelha muito ao MATLAB.
----

----
## Notebooks
- O `Jupyter` é um projeto que permite usar _notebooks_, que são documentos que misturam conteúdo, código, resultado de código, visualização (programação literal). Ele é manipulado no seu próprio navegador.
----

----
### Notebooks online
- https://colab.research.google.com
---
# Projeto
----
### Trabalhando com tudo
- Entre na [sala de aula](https://repl.it/community/classrooms/150657) no repl.it
- Tem um projeto ali, com nome `LendoArquivos`
- O arquivo `LEIAME.md` contém as instruções
---
# Coisas que não vimos
----
- Cláusulas `try` .. `except`, `raise`
- Classes
- Operador `lambda`, função `eval()`
- Diferença entre variável local e global
- Doc strings
- Dados do tipo _conjunto_
---
# Por que `Python` é :top:
---
{%youtube Og847HVwRSI %}
---
## Comunidade
* [Python Brasil](https://python.org.br/)
* [Comunidades Locais](https://python.org.br/comunidades-locais/)
* GrouPy Blumenau
* [Pyladies](https://python.org.br/pyladies/)
---
## Referências
- [python.org](https://python.org)
- [repl.it](https://repl.it/languages/python3)
- [Lógica de Programação](http://ftp.unicamp.br/pub/apoio/treinamentos/logica/logica.pdf)
- [snakify.org](https://snakify.org/en/)
- [pythontutor.com](http://www.pythontutor.com/visualize.html )
- [learn python in 20 minutes](https://pt.slideshare.net/SidharthNadhan/learn-python-in-20-minutes)
- [python 101](http://www.davekuhlman.org/python_101.html)
- [automate the boring stuff](https://automatetheboringstuff.com/)
---
# Fim Aula 03
{"metaMigratedAt":"2023-06-14T23:52:56.031Z","metaMigratedFrom":"YAML","title":"Lógica de programação 3","breaks":"true","description":"Minicurso de lógica de programação.","slideOptions":"{\"theme\":\"blood\",\"transition\":\"none\"}","contributors":"[{\"id\":\"97cff931-683e-4939-8bd1-380f6caced12\",\"add\":20876,\"del\":4163}]"}