# Lógica de programação
## com `Python`
----
### criado por Bossa
----
# Aula 02
## Caminhando
---
# Listas
Listas são vetores de dados, criados entre colchetes. Podem conter _qualquer_ tipo de dados em seu interior.
----
## Criando listas
Podemos criar listas diretamente
```python
lista = ["a", "bc", "d", 1, 2.0, 3, True ]
```
Ou criar através de outros objetos
```python
texto = "Um texto qualquer"
texto_convertido = list(texto)
# Cada letra vira um item da lista
texto_separado = texto.split(" ") # O método .split(x)
# quebra o texto dado em todas as ocorrências de x
```
----
## _Ranges_
São "listas" de números que geramos usando o comando `range`. Podemos usar de três maneiras:
```python
# range(n) gera uma lista de 0 até n-1
zero_a_nove = list(range(10))
# range(a,b) gera uma lista de a até b-1
dez_a_dezenove = list(range(10,20))
# range(a,b,k) gera uma lista de a até b-1 pulando de k em k
pares_10_20 = list(range(10,20,2))
```
----
## Acessando listas
A notação com colchetes usada em texto pode ser usada também em listas
```python
lista = list("abcdefgh")
print(lista[0]) # retorna só um elemento
print(lista[0:1]) # retorna uma sublista
print(lista[2:5])
print(lista[:3])
print(lista[4:])
print(lista[-1])
```
----
## Informações da lista
```python
lista = list("aaabbcdefghi")
# retorna o número de elementos da lista
a = len(lista)
# .count(x) conta o número de ocorrências de x na lista
b = lista.count("a")
# .index(x) retorna o primeiro índice em que o valor x ocorrre
c = lista.index("d")
d = 1 in lista # verificar se um valor está na lista
e = "g" in lista
print(a,b,c,d,e)
```
----
## Modificando listas
```python
lista = list(range(10))
# alterar somente um elemento da lista
lista[0] = "a"
# alterar um trecho da lista
lista[8:10] = [-1, -2]
print(lista)
```
----
## Apagando listas
```python
lista = list("abcdefghi")
# apagando o primeiro elemento
del lista[0]
# .pop(n) remove o elemento na posição n
# e retorna seu valor
q = lista.pop(4)
# .remove(x) remove a primeira ocorrẽncia do valor x
lista.remove("f")
print(lista)
```
----
## Aumentando listas
```python
lista1 = list("abcde")
lista2 = list(range(5))
# operador + concatena listas
lista = lista1 + lista2
# .append(valor) adiciona o valor ao final da lista
lista1.append("F")
# .extend(lista) extende a lista original concatenando
# a lista dada como argumento
lista2.extend([-1,-2,-3])
print(lista, lista1, lista2, sep="\n")
```
----
## Reorganizando listas
```python
lista = ["a", "c", "z", "x", "b"]
# .reverse() inverte a ordem da lista
lista.reverse() # CUIDADO: o método altera o objeto
print(lista)
# .sort() ordena a lista em ordem crescente
lista.sort() # CUIDADO: o método altera o objeto
print(lista)
```
---
# `for`
ou sobre como percorrer listas
----
## Percorrendo iteráveis
Objetos como listas, ranges e textos são iteráveis: podemos percorrer seus elementos usando o comando `for`
```python
for elemento in iterável:
# executar algumas coisas
```
----
## Usando o `for`
```python
lista = ["a", "B", "c", "deF"]
intervalo = range(10)
texto = "Luiz"
for x in lista: # vamos percorrer cada elemento da lista
print(x.swapcase()) # e imprimi-los modificados
for n in intervalo: # percorrer cada n em 0, 1, ..., 9
print(x**2) # e imprimir n²
for letra in texto: # aqui percorremos cada letra
print(letra, end="\t")
```
----
## Parando o `for`
Usamos a cláusula `break` sempre que quisermos parar a execução do `for`
```python
# No loop abaixo, vamos parar quando encontrarmos um texto
lista = [2, 3 , 4, -5, "a", -6, 7]
for x in lista:
if type(x)==str: # se o tipo de x for texto
break # paramos o loop
else:
print(x**2) # se não imprimimos x²
```
----
## Continuando o `for`
Usamos a cláusula `continue` sempre que quisermos passar para o próximo elemento sem executar os comandos do laço
```python
# No loop abaixo, vamos pular quando encontrarmos um texto
lista = [2, 3 , 4, -5, "a", -6, 7]
for x in lista:
if type(x)==str: # se o tipo de x for texto
continue # passamos pro próximo elemento
else:
print(x**2) # se não imprimimos x²
```
---
# Exercícios
----
## Exercício 01 - Soma
- Vamos criar um algoritmo que soma todas as entradas numéricas de uma lista, ignorando os demais tipos
```python
lista = [1, 2.0, 3, "a", "b", -3, -2.0, "c"]
soma = 0
for n in lista:
if type(n) in [int, float]:
soma += n
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Exercício 02 - Divisores
- Vamos criar um algoritmo que pede como entrada um número inteiro e tem como saída uma lista com seus divisores
```python
n = int(input("Digite um inteiro:"))
divisores = [] # começamos com uma lista vazia
for d in range(1, n//2 + 1): # o maior divisor possível
# de n é n/2
if n % d == 0: # se o resto da divisão de n por d for 0
divisores.append(d) # é pq d é divisor de n
print(divisores)
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Exercício 03 - Médias
- Vamos criar um programa que computa a média de $n$ notas. O usuário deve informar o número de notas, as notas e o programa deve retornar a média delas.
```python
n = int(input("Quantas notas serão? "))
lista_notas = [] # começamos com a lista vazia
for i in range(n): # fazemos um loop sobre o n
# vamos criar uma mensagem personalizada
msg = "Digite a " + str(i+1) + "a nota:"
nota = float(input(msg))
lista_notas.append(nota)
media = sum(lista_notas)/n
print("Sua média foi:", media)
```
<!-- .element: class="fragment" data-fragment-index="1" -->
---
# `while`
faz o _loop_
----
## `while`
Executa um loop enquanto uma condição for verdadeira
```python
while condicao:
# faz algumas coisas
# e ao final do loop
# verifica a condicao novamente
```
----
## Usando `while`
Podemos usar o while para gerar uma sequência
```python
a = 0
while a < 10: # enquanto a for menor que 10
print(a) # imprime a
a += 1 # adiciona 1 ao a
```
----
### Operadores de atribuição
Muitas vezes precisamos atualizar (aumentar, diminuir) o valor de uma variável. Para isso podemos usar os operadores de atribuição
```python
# a seguinte expressão
a += b
# é equivalente a
a = a + b
# e funciona sempre que os objetos a e b
# puderem ser somados
# de modo geral, se @ é um operador qualquer
# "a @= b" significa "a = a @ b"
```
----
### Exemplos de atribuição
```python
a = 10
a /= 2 # isso equivale a dividir a por 2
b = "Texto"
b *= 3 # isso multiplica o texto por 3
c = ["a", "b", "c"]
c += [1, 2, 3] # isso contatena as listas
print(a,b,c, sep="\n")
```
---
# Funções
----
## Funções
Comandos como `print`, `sum` e `input` são funções: eles recebem algum argumento e devolvem (ou não) algum valor.
----
## Sintaxe
```python
def nome_da_funcao(argumentos):
# aqui voce faz alguma coisa com os
# argumentos, e se quiser, pode
# retornar algum valor usando
return algum_valor
```
----
## Exemplo - Média
A função abaixo retorna a média de uma lista de números
```python
def media(lista):
med = sum(lista)/len(lista)
return med
lista = [1, 3, 4, 7, 8]
print( media(lista) )
```
----
## Exemplo - Extraindo texto
```python
def extrair(texto, palavra_inicial, palavra_final):
# Essa função extrai o texto entre palavra inicial e palavra final
pos_i = texto.find(palavra_inicial)
tam = len(palavra_inicial)
pos_f = texto.find(palavra_final)
extraido = texto[pos_i+tam:pos_f]
return extraido
frase = "Olá, faça a transferência para a conta corrente 12129-4 agência 1282-5 banco Lehmann Brothers."
conta = extrair(frase, "corrente", "agência")
agencia = extrair(frase, "agência", "banco")
banco = extrair(frase, "banco", ".")
print(banco, agencia, conta, sep="\n")
```
----
## Exemplo - Recorrência
Lembramos que o fatorial de um número natural $n$ é $$n! = n(n-1)(n-2)\cdots 1$$
```python
def fatorial(n):
if n==0:
return 1 # pois 0! = 1 por definição
else:
return n*fatorial(n-1)
# pois vale a igualdade n! = n*(n-1)!
```
----
## Argumentos padrão
Algumas funções podem ter argumentos com valores padrão
```python
def saudacao(nome, sobrenome = "da Silva"):
print("Bom dia", nome, sobrenome)
saudacao("Fulano") # sobrenome assume o valor padrao
saudacao("Ciclano", "de Souza") # sobrenome assume o valor dado
saudacao() # vai dar erro
```
----
## Argumentos sequenciais
Quer uma função que trabalhe com uma lista de argumentos, igual `print`?
```python
def funcao(*argumentos):
for x in argumentos:
print(x, end=", ")
funcao(1,2,4)
funcao("a", "b", "c", "d", "e")
```
----
## Exercício 04 - Criando uma lista
- Vamos criar um algoritmo que mostra um prompt e, enquanto a entrada do usuário não for vazia, pede uma nova entrada e adiciona essa entrada a uma lista. Ao final, exibe a lista.
```python
entrada = "@"
lista = []
n=1
while entrada != "":
entrada = input("Digite o " + str(n) + "o item: ")
lista.append(entrada)
n += 1
print(lista)
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Exercício 05 - Separando coisas
- Vamos criar uma que recebe dois argumentos: uma lista e um tipo de objeto. Essa função vai retornar uma lista que contenha elementos da lista original que sejam do tipo especificado. O tipo padrão vai ser `str`
```python
def extrair(lista, tipo = str):
saida = []
for x in lista:
if type(x)==tipo:
saida.append(x)
return saida
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Salvado e importando
- Se salvarmos a nossa função `fatorial` no arquivo `modulo.py` podemos usa-lo no arquivo `main.py`
```python
import modulo
# importamos o arquivo modulo.py
# e podemos usar a função fatorial assim
a = modulo.fatorial(6)
# ou podemos importar diretamente a função
from modulo import fatorial
b = fatorial(10)
```
---
# A Biblioteca Padrão do Python
----
O `python` vem com vários módulos instalados por padrão, que formam a biblioteca padrão.
> [docs.python.org](https://docs.python.org/pt-br/3/library/)
----
## Exemplos de usos dos módulos padrão
----
### Datas
```python
from datetime import date, timedelta
# do módulo datetime vamos importar date
# para lidar com datas e timedelta para
# calcular diferenças entre datas
hoje = date.today() # pegamos a data de hoje
aniversário = date(1994, 5, 26) # os argumentos são
# ano, mes, dia
diferença = hoje - aniversário
# o resultado é um objeto timedelta
print(diferença.days, "dias")
idade = diferença.days//365.25
# divisão inteira considerando anos bissextos
print(idade, "anos")
```
----
### Funções matemáticas
```python
import math
a = math.sin(0) # seno
b = math.cos(0) # cosseno
c = math.pi # pi
d = math.log2(10) # log base 2
e = math.exp(1) # exponencial
f = math.sqrt(2) # raiz quadrada
print(a,b,c,d,e,f, sep=",")
```
----
### Download de arquivo
```python
# Vamos baixar um arquivo com dados
from urllib.request import urlretrieve
url = "https://sistemas.furg.br/sistemas/dados_abertos/arquivos/sae-r-u.csv"
# link encontrado na pagina do dados.gov.br
arquivo = "./refeicoes-furg.csv"
# vamos salvar na pasta local com o nome
# refeicoes-furg.csv
urlretrieve(url, arquivo)
```
----
### Enviando um email
```python
import smtplib
from email.mime.text import MIMEText
# conexão com os servidores da UFSC
smtp_ssl_host = 'smtp.ufsc.br'
smtp_ssl_port = 465
# username ou email para logar no servidor
username = 'l.f.bossa@ufsc.br'
password = '<aqui vai a sua senha>'
# de qual endereço vou enviar
from_addr = "Bossa <%s>" % username
# lista de endereços para os quais
# vou enviar
to_addrs = ['LABMAC <labmac.bnu@contato.ufsc.br>']
# a biblioteca email possuí vários templates
# para diferentes formatos de mensagem
# neste caso usaremos MIMEText para enviar
# somente texto
message = MIMEText('Aqui vai o corpo do e-mail')
message['subject'] = 'Aqui vai o assunto'
message['from'] = from_addr
message['to'] = ', '.join(to_addrs)
# conectaremos de forma segura usando SSL
server = smtplib.SMTP_SSL(smtp_ssl_host, smtp_ssl_port)
# para interagir com um servidor externo precisaremos
# fazer login nele
server.login(username, password)
# enviamos o email
server.sendmail(from_addr, to_addrs, message.as_string())
# e fechamos a conexão
server.quit()
```
----
### Organizando uma pasta
```python=
import glob
import os
CAMINHO = "/home/bossa/Downloads"
# mudando para a pasta que queremos limpar
os.chdir(CAMINHO)
# listando todos os arquivos
arquivos = glob.glob("*.*")
# vamos pegar todas as extensões
extensoes = set([ fl.split(".")[-1] # separa o . e pega o ultimo termo
for fl in arquivos ])
# vamos criar as pastas com as extensões
for ext in extensoes:
os.makedirs("./%s" % ext, exist_ok=True)
# se a pasta já existe, a opção exist_ok=True evita erros
# agora vamos mover os arquivos
for arq in arquivos:
ext = arq.split(".")[-1]
os.rename(arq, "./%s/%s" % (ext, arq))
```
---
# Fim Aula 02
{"title":"Lógica de programação 2 - v2","tags":"minicurso, programação","description":"Minicurso de lógica de programação.","slideOptions":{"theme":"blood","transition":"none"}}