0% acharam este documento útil (0 voto)
7 visualizações40 páginas

Curso Completo de Python: Fundamentos e Estruturas

O curso de Python abrange desde os fundamentos básicos, como variáveis, tipos de dados e operadores, até conceitos intermediários, incluindo estruturas de controle de fluxo e funções. Os módulos e estruturas de dados, como listas, tuplas, dicionários e conjuntos, são explorados para organizar e manipular dados de forma eficiente. Exercícios práticos são fornecidos para reforçar o aprendizado e a aplicação dos conceitos apresentados.

Enviado por

drsavageband
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
7 visualizações40 páginas

Curso Completo de Python: Fundamentos e Estruturas

O curso de Python abrange desde os fundamentos básicos, como variáveis, tipos de dados e operadores, até conceitos intermediários, incluindo estruturas de controle de fluxo e funções. Os módulos e estruturas de dados, como listas, tuplas, dicionários e conjuntos, são explorados para organizar e manipular dados de forma eficiente. Exercícios práticos são fornecidos para reforçar o aprendizado e a aplicação dos conceitos apresentados.

Enviado por

drsavageband
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

Curso de Python: Básico ao Avançado

Módulo 1: Fundamentos do Python (Básico)

1.1 Variáveis, Tipos de Dados e Operadores

Python é uma linguagem de programação de alto nível, interpretada, orientada a


objetos e com tipagem dinâmica. Isso significa que você não precisa declarar o tipo de
uma variável antes de usá-la.

Variáveis

Variáveis são usadas para armazenar informações que podem ser referenciadas e
manipuladas em um programa. Em Python, você atribui um valor a uma variável
usando o operador de atribuição ( = ).

nome = "Alice"
idade = 30
preco = 25.50
is_ativo = True

print(nome) # Saída: Alice


print(idade) # Saída: 30
print(preco) # Saída: 25.5
print(is_ativo) # Saída: True

Tipos de Dados

Python possui vários tipos de dados embutidos:

Números:

int (inteiros): 10 , -5 , 0

float (ponto flutuante): 3.14 , -0.5 , 2.0

complex (números complexos): 1 + 2j

Sequências:
str (strings): "Olá, Mundo!" , 'Python'

list (listas): [1, 2, 3] , ['a', 'b', 'c']

tuple (tuplas): (1, 2, 3) , ('x', 'y')

Mapeamento:

dict (dicionários): {'chave': 'valor', 'nome': 'João'}

Conjuntos:

set (conjuntos): {1, 2, 3} , {'maçã', 'banana'}

Booleanos:

bool (booleanos): True , False

Você pode verificar o tipo de uma variável usando a função type() :

x = 10
y = 3.14
z = "Olá"

print(type(x)) # Saída: <class 'int'>


print(type(y)) # Saída: <class 'float'>
print(type(z)) # Saída: <class 'str'>

Operadores

Operadores são símbolos que realizam operações em valores e variáveis.

Operadores Aritméticos:

+ (Adição): 5 + 3 = 8

- (Subtração): 5 - 3 = 2

* (Multiplicação): 5 * 3 = 15

/ (Divisão): 5 / 3 = 1.666... (sempre retorna float)

// (Divisão inteira): 5 // 3 = 1

% (Módulo - resto da divisão): 5 % 3 = 2

** (Exponenciação): 5 ** 3 = 125
Operadores de Comparação:

== (Igual a): 5 == 3 = False

!= (Diferente de): 5 != 3 = True

> (Maior que): 5 > 3 = True

< (Menor que): 5 < 3 = False

>= (Maior ou igual a): 5 >= 3 = True

<= (Menor ou igual a): 5 <= 3 = False

Operadores Lógicos:

and (E lógico): True and False = False

or (Ou lógico): True or False = True

not (Negação lógica): not True = False

Operadores de Atribuição:

= (Atribuição simples): x = 10

+= (Adição e atribuição): x += 5 (equivalente a x = x + 5 )

-= (Subtração e atribuição): x -= 5

*= (Multiplicação e atribuição): x *= 5

/= (Divisão e atribuição): x /= 5

e assim por diante para outros operadores aritméticos.


a = 10
b = 3

print(f"Adição: {a + b}")
print(f"Subtração: {a - b}")
print(f"Multiplicação: {a * b}")
print(f"Divisão: {a / b}")
print(f"Divisão Inteira: {a // b}")
print(f"Módulo: {a % b}")
print(f"Exponenciação: {a ** b}")

print(f"Igual a: {a == b}")
print(f"Diferente de: {a != b}")

print(f"And lógico: {True and False}")


print(f"Or lógico: {True or False}")
print(f"Not lógico: {not True}")

c = 10
c += 5
print(f"Atribuição com adição: {c}") # Saída: 15

Exercícios

1. Crie duas variáveis, num1 e num2 , com valores inteiros. Realize e imprima o
resultado de todas as operações aritméticas básicas entre elas.

2. Crie uma variável frase com uma string. Verifique o tipo da variável e imprima-
o.

3. Crie duas variáveis booleanas, condicao1 e condicao2 . Use operadores lógicos


para imprimir o resultado de condicao1 and condicao2 , condicao1 or
condicao2 e not condicao1 .

1.2 Estruturas de Controle de Fluxo

As estruturas de controle de fluxo permitem que você controle a ordem em que as


instruções são executadas em um programa.

Condicionais ( if , elif , else )

Usadas para executar blocos de código diferentes com base em certas condições.
idade = 18

if idade >= 18:


print("Você é maior de idade.")
else:
print("Você é menor de idade.")

nota = 75

if nota >= 90:


print("Conceito A")
elif nota >= 70:
print("Conceito B")
elif nota >= 50:
print("Conceito C")
else:
print("Conceito D")

Laços de Repetição ( for , while )

Usados para executar um bloco de código repetidamente.

for loop

Itera sobre uma sequência (como uma lista, tupla, string ou range).

# Iterando sobre uma lista


frutas = ["maçã", "banana", "cereja"]
for fruta in frutas:
print(fruta)

# Iterando sobre uma string


for letra in "Python":
print(letra)

# Usando range()
for i in range(5): # Gera números de 0 a 4
print(i)

for i in range(2, 8): # Gera números de 2 a 7


print(i)

for i in range(1, 10, 2): # Gera números de 1 a 9, pulando de 2 em 2


print(i)

while loop

Executa um bloco de código enquanto uma condição for verdadeira.


contador = 0
while contador < 5:
print(contador)
contador += 1

# break e continue
for i in range(10):
if i == 3:
continue # Pula para a próxima iteração
if i == 7:
break # Sai do loop
print(i)

1.3 Funções e Módulos Básicos

Funções

Funções são blocos de código reutilizáveis que realizam uma tarefa específica. Elas
ajudam a organizar o código e torná-lo mais legível e modular.

def saudar(nome):
"""Esta função saúda a pessoa com o nome passado como argumento."""
print(f"Olá, {nome}!")

saudar("Maria")
saudar("Pedro")

def somar(a, b):


"""Esta função retorna a soma de dois números."""
return a + b

resultado = somar(10, 5)
print(f"A soma é: {resultado}")

# Argumentos padrão
def potencia(base, expoente=2):
return base ** expoente

print(potencia(3)) # Saída: 9 (3^2)


print(potencia(3, 3)) # Saída: 27 (3^3)

Módulos

Um módulo é um arquivo Python ( .py ) que contém definições e declarações Python.


Módulos permitem organizar o código em arquivos separados, tornando-o mais
gerenciável e reutilizável.
# Exemplo de uso do módulo math
import math

print([Link](25)) # Saída: 5.0


print([Link]) # Saída: 3.141592653589793

# Importando funções específicas de um módulo


from math import sqrt, pi

print(sqrt(16)) # Saída: 4.0


print(pi) # Saída: 3.141592653589793

# Renomeando um módulo ou função importada


import math as matematica
print([Link](5)) # Saída: 120

from math import sqrt as raiz_quadrada


print(raiz_quadrada(49)) # Saída: 7.0

Exercícios

1. Escreva um programa que peça ao usuário para digitar um número e determine


se ele é par ou ímpar.

2. Crie um loop for que imprima os números de 1 a 10. Em seguida, crie um loop
while que faça o mesmo.

3. Crie uma função chamada calcular_media que receba três notas como
argumentos e retorne a média. Teste a função com diferentes valores.

4. Importe o módulo random e use a função [Link]() para gerar um


número inteiro aleatório entre 1 e 100. Imprima o número gerado.

Módulo 2: Python Intermediário

2.1 Estruturas de Dados

Python oferece várias estruturas de dados embutidas que são muito eficientes e
flexíveis para organizar e armazenar dados.

Listas ( list )

Listas são coleções ordenadas e mutáveis de itens. Podem conter itens de diferentes
tipos de dados.
# Criando uma lista
minha_lista = [1, 2, 3, "quatro", 5.0]
print(minha_lista) # Saída: [1, 2, 3, 'quatro', 5.0]

# Acessando elementos (indexação)


print(minha_lista[0]) # Saída: 1
print(minha_lista[-1]) # Saída: 5.0 (último elemento)

# Fatiamento (slicing)
print(minha_lista[1:4]) # Saída: [2, 3, 'quatro']

# Modificando elementos
minha_lista[0] = 10
print(minha_lista) # Saída: [10, 2, 3, 'quatro', 5.0]

# Adicionando elementos
minha_lista.append("novo") # Adiciona ao final
print(minha_lista) # Saída: [10, 2, 3, 'quatro', 5.0, 'novo']
minha_lista.insert(1, "inserido") # Adiciona em uma posição específica
print(minha_lista) # Saída: [10, 'inserido', 2, 3, 'quatro', 5.0, 'novo']

# Removendo elementos
minha_lista.remove("quatro") # Remove o primeiro item com o valor especificado
print(minha_lista) # Saída: [10, 'inserido', 2, 3, 5.0, 'novo']
minha_lista.pop() # Remove e retorna o último elemento
print(minha_lista) # Saída: [10, 'inserido', 2, 3, 5.0]
minha_lista.pop(0) # Remove e retorna o elemento no índice especificado
print(minha_lista) # Saída: ['inserido', 2, 3, 5.0]

# Outros métodos úteis


lista_numeros = [1, 5, 2, 8, 3]
lista_numeros.sort() # Ordena a lista
print(lista_numeros) # Saída: [1, 2, 3, 5, 8]
lista_numeros.reverse() # Inverte a ordem da lista
print(lista_numeros) # Saída: [8, 5, 3, 2, 1]
print(len(lista_numeros)) # Saída: 5 (tamanho da lista)

Tuplas ( tuple )

Tuplas são coleções ordenadas e imutáveis de itens. Uma vez criadas, seus elementos
não podem ser alterados.

# Criando uma tupla


minha_tupla = (1, 2, "três", 4.0)
print(minha_tupla) # Saída: (1, 2, 'três', 4.0)

# Acessando elementos (indexação e fatiamento funcionam como em listas)


print(minha_tupla[0]) # Saída: 1
print(minha_tupla[1:3]) # Saída: (2, 'três')

# Tuplas são imutáveis (a linha abaixo geraria um erro)


# minha_tupla[0] = 10

# Desempacotamento de tuplas
a, b, c = (1, 2, 3)
print(a, b, c) # Saída: 1 2 3
Dicionários ( dict )

Dicionários são coleções não ordenadas de pares chave-valor. As chaves devem ser
únicas e imutáveis (strings, números, tuplas).

# Criando um dicionário
meu_dicionario = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
print(meu_dicionario) # Saída: {'nome': 'João', 'idade': 30, 'cidade': 'São
Paulo'}

# Acessando valores
print(meu_dicionario["nome"]) # Saída: João

# Adicionando/Modificando pares chave-valor


meu_dicionario["profissao"] = "Engenheiro"
print(meu_dicionario) # Saída: {'nome': 'João', 'idade': 30, 'cidade': 'São
Paulo', 'profissao': 'Engenheiro'}
meu_dicionario["idade"] = 31
print(meu_dicionario) # Saída: {'nome': 'João', 'idade': 31, 'cidade': 'São
Paulo', 'profissao': 'Engenheiro'}

# Removendo pares chave-valor


meu_dicionario.pop("cidade")
print(meu_dicionario) # Saída: {'nome': 'João', 'idade': 31, 'profissao':
'Engenheiro'}

# Métodos úteis
print(meu_dicionario.keys()) # Saída: dict_keys(['nome', 'idade', 'profissao'])
print(meu_dicionario.values()) # Saída: dict_values(['João', 31, 'Engenheiro'])
print(meu_dicionario.items()) # Saída: dict_items([('nome', 'João'), ('idade',
31), ('profissao', 'Engenheiro')])

# Iterando sobre dicionários


for chave, valor in meu_dicionario.items():
print(f"{chave}: {valor}")

Conjuntos ( set )

Conjuntos são coleções não ordenadas de itens únicos. São úteis para remover
duplicatas e realizar operações de conjunto (união, interseção, diferença).
# Criando um conjunto
meu_conjunto = {1, 2, 3, 2, 1}
print(meu_conjunto) # Saída: {1, 2, 3} (duplicatas são removidas
automaticamente)

# Adicionando elementos
meu_conjunto.add(4)
print(meu_conjunto) # Saída: {1, 2, 3, 4}

# Removendo elementos
meu_conjunto.remove(2)
print(meu_conjunto) # Saída: {1, 3, 4}

# Operações de conjunto
conjunto_a = {1, 2, 3, 4}
conjunto_b = {3, 4, 5, 6}

print(conjunto_a.union(conjunto_b)) # União: {1, 2, 3, 4, 5, 6}


print(conjunto_a.intersection(conjunto_b)) # Interseção: {3, 4}
print(conjunto_a.difference(conjunto_b)) # Diferença: {1, 2}

Exercícios

1. Crie uma lista de 5 nomes de frutas. Adicione uma nova fruta, remova uma
existente e imprima a lista final.

2. Crie uma tupla com as coordenadas (latitude, longitude) de um local. Tente


modificar um dos valores e observe o erro.

3. Crie um dicionário para representar um livro, com chaves como "titulo", "autor" e
"ano". Adicione uma nova chave "genero" e imprima o dicionário completo.

4. Crie dois conjuntos de números. Encontre a união, interseção e diferença entre


eles e imprima os resultados.

2.2 Programação Orientada a Objetos (POO)

POO é um paradigma de programação que organiza o design do software em torno de


objetos, em vez de funções e lógica. Um objeto pode ser definido como uma instância
de uma classe.

Classes e Objetos

Classe: Um blueprint ou modelo para criar objetos. Define um conjunto de


atributos (variáveis) e métodos (funções) que os objetos criados a partir dela
terão.
Objeto: Uma instância de uma classe. É uma entidade real baseada no modelo
da classe.

class Carro:
# Atributo de classe (compartilhado por todas as instâncias)
rodas = 4

def __init__(self, marca, modelo, ano):


# Atributos de instância
[Link] = marca
[Link] = modelo
[Link] = ano
[Link] = 0

def acelerar(self, incremento):


[Link] += incremento
print(f"O {[Link]} está a {[Link]} km/h.")

def frear(self, decremento):


[Link] -= decremento
if [Link] < 0:
[Link] = 0
print(f"O {[Link]} está a {[Link]} km/h.")

# Criando objetos (instâncias da classe Carro)


carro1 = Carro("Toyota", "Corolla", 2020)
carro2 = Carro("Honda", "Civic", 2022)

print(f"Carro 1: {[Link]} {[Link]} ({[Link]})")


print(f"Carro 2: {[Link]} {[Link]} ({[Link]})")

[Link](50)
[Link](70)
[Link](20)

print(f"Rodas do carro1: {[Link]}")


print(f"Rodas do carro2: {[Link]}")

Herança

Herança permite que uma classe (subclasse/classe filha) herde atributos e métodos de
outra classe (superclasse/classe pai). Isso promove a reutilização de código.
class Veiculo:
def __init__(self, marca, modelo):
[Link] = marca
[Link] = modelo

def exibir_info(self):
print(f"Marca: {[Link]}, Modelo: {[Link]}")

class Carro(Veiculo):
def __init__(self, marca, modelo, portas):
super().__init__(marca, modelo) # Chama o construtor da classe pai
[Link] = portas

def exibir_info(self):
super().exibir_info()
print(f"Portas: {[Link]}")

class Moto(Veiculo):
def __init__(self, marca, modelo, cilindradas):
super().__init__(marca, modelo)
[Link] = cilindradas

def exibir_info(self):
super().exibir_info()
print(f"Cilindradas: {[Link]}")

carro = Carro("Ford", "Focus", 4)


moto = Moto("Yamaha", "Fazer", 250)

carro.exibir_info()
moto.exibir_info()

Polimorfismo

Polimorfismo significa "muitas formas". Em POO, refere-se à capacidade de objetos de


diferentes classes responderem ao mesmo método de maneiras diferentes.
class Cachorro:
def fazer_som(self):
print("Au Au")

class Gato:
def fazer_som(self):
print("Miau")

class Pato:
def fazer_som(self):
print("Quack")

def emitir_som(animal):
animal.fazer_som()

cachorro = Cachorro()
gato = Gato()
pato = Pato()

emitir_som(cachorro)
emitir_som(gato)
emitir_som(pato)

Encapsulamento

Encapsulamento é o agrupamento de dados (atributos) e métodos que operam sobre


esses dados em uma única unidade (classe), e a restrição do acesso direto a alguns
dos componentes do objeto. Em Python, usa-se convenções de nomenclatura para
indicar se um atributo ou método é privado (prefixo _ ou __ ).
class ContaBancaria:
def __init__(self, saldo_inicial):
self.__saldo = saldo_inicial # Atributo privado (convenção)

def depositar(self, valor):


if valor > 0:
self.__saldo += valor
print(f"Depósito de {valor} realizado. Novo saldo: {self.__saldo}")
else:
print("Valor de depósito inválido.")

def sacar(self, valor):


if valor > 0 and valor <= self.__saldo:
self.__saldo -= valor
print(f"Saque de {valor} realizado. Novo saldo: {self.__saldo}")
else:
print("Saldo insuficiente ou valor de saque inválido.")

def get_saldo(self):
return self.__saldo

conta = ContaBancaria(1000)
[Link](500)
[Link](200)
print(f"Saldo atual: {conta.get_saldo()}")
# print(conta.__saldo) # Isso geraria um AttributeError, pois __saldo é
'privado'

Exercícios

1. Crie uma classe Pessoa com atributos nome e idade e um método apresentar
que imprima uma mensagem de apresentação.

2. Crie uma classe Estudante que herde de Pessoa e adicione um atributo curso
e um método estudar .

3. Demonstre polimorfismo criando diferentes classes de formas geométricas (e.g.,


Circulo , Retangulo ) com um método calcular_area e chame esse método
para instâncias de cada classe em uma função genérica.

4. Modifique a classe ContaBancaria para incluir um atributo __numero_conta e


um método get_numero_conta .

2.3 Manipulação de Arquivos e Exceções

Manipulação de Arquivos

Python facilita a leitura e escrita de arquivos. O processo geralmente envolve abrir o


arquivo, realizar operações e fechar o arquivo.
# Escrevendo em um arquivo (modo 'w' - write, sobrescreve se existir)
with open("meu_arquivo.txt", "w") as arquivo:
[Link]("Olá, mundo!\n")
[Link]("Este é um exemplo de escrita em arquivo.\n")

# Lendo de um arquivo (modo 'r' - read)


with open("meu_arquivo.txt", "r") as arquivo:
conteudo = [Link]()
print("Conteúdo do arquivo:\n", conteudo)

# Lendo linha por linha


with open("meu_arquivo.txt", "r") as arquivo:
print("Lendo linha por linha:")
for linha in arquivo:
print([Link]()) # .strip() remove quebras de linha extras

# Adicionando conteúdo a um arquivo (modo 'a' - append)


with open("meu_arquivo.txt", "a") as arquivo:
[Link]("Adicionando uma nova linha.\n")

with open("meu_arquivo.txt", "r") as arquivo:


conteudo_atualizado = [Link]()
print("\nConteúdo atualizado:\n", conteudo_atualizado)

# Lidando com arquivos que não existem


try:
with open("arquivo_inexistente.txt", "r") as arquivo:
print([Link]())
except FileNotFoundError:
print("Erro: O arquivo não foi encontrado.")

Tratamento de Exceções ( try , except , finally )

Exceções são erros que ocorrem durante a execução de um programa. O tratamento


de exceções permite que você lide com esses erros de forma elegante, evitando que o
programa trave.
# Exemplo básico de try-except
try:
resultado = 10 / 0
print(resultado)
except ZeroDivisionError:
print("Erro: Divisão por zero não é permitida.")

# Tratando múltiplas exceções


try:
numero = int(input("Digite um número: "))
resultado = 10 / numero
print(f"O resultado é: {resultado}")
except ValueError:
print("Erro: Entrada inválida. Por favor, digite um número inteiro.")
except ZeroDivisionError:
print("Erro: Não é possível dividir por zero.")
except Exception as e: # Captura qualquer outra exceção
print(f"Ocorreu um erro inesperado: {e}")
finally:
print("Esta parte sempre será executada, independentemente de erro.")

# Usando else com try-except (executa se não houver exceção)


try:
num1 = int(input("Digite o primeiro número: "))
num2 = int(input("Digite o segundo número: "))
divisao = num1 / num2
except ValueError:
print("Erro: Certifique-se de digitar números válidos.")
except ZeroDivisionError:
print("Erro: Divisão por zero.")
else:
print(f"A divisão é: {divisao}")
finally:
print("Fim da operação.")

Exercícios

1. Crie um programa que escreva seu nome e sua idade em um arquivo chamado
dados_pessoais.txt . Em seguida, leia o conteúdo desse arquivo e imprima-o.

2. Escreva um programa que tente abrir um arquivo chamado lista_compras.txt


para leitura. Se o arquivo não existir, ele deve criar o arquivo e escrever alguns
itens de compra nele. Se existir, deve ler e imprimir o conteúdo.

3. Crie uma função que receba dois números e realize a divisão. Use tratamento de
exceções para lidar com ValueError (se a entrada não for um número) e
ZeroDivisionError (se o segundo número for zero).
2.4 Módulos e Pacotes Avançados

Módulos

Como vimos, módulos são arquivos .py que contêm código Python. Eles permitem
organizar o código em unidades lógicas e reutilizáveis. Além dos módulos embutidos,
você pode criar seus próprios módulos.

Criando e Usando um Módulo Personalizado:

Vamos criar um arquivo minhas_funcoes.py :

# minhas_funcoes.py
def saudacao(nome):
return f"Olá, {nome}! Bem-vindo(a) ao meu módulo."

def dobrar(numero):
return numero * 2

PI = 3.14159

Agora, você pode usar este módulo em outro arquivo Python (no mesmo diretório ou
em um diretório que esteja no PYTHONPATH ):

# meu_programa.py
import minhas_funcoes

print(minhas_funcoes.saudacao("Ana"))
print(minhas_funcoes.dobrar(10))
print(minhas_funcoes.PI)

from minhas_funcoes import saudacao, PI


print(saudacao("Bruno"))
print(PI)

Pacotes

Pacotes são uma forma de organizar módulos relacionados em um diretório


hierárquico. Um pacote é simplesmente um diretório que contém um arquivo especial
chamado __init__.py (que pode estar vazio).

Estrutura de um Pacote:
meu_projeto/
├── [Link]
└── meu_pacote/
├── __init__.py
├── [Link]
└── sub_pacote/
├── __init__.py
└── [Link]

Exemplo de Conteúdo:

meu_pacote/[Link] :

# meu_pacote/[Link]
def funcao_modulo1():
return "Função do Módulo 1"

meu_pacote/sub_pacote/[Link] :

# meu_pacote/sub_pacote/[Link]
def funcao_modulo2():
return "Função do Módulo 2 no Sub-pacote"

Usando o Pacote em [Link] :

# [Link]
from meu_pacote import modulo1
from meu_pacote.sub_pacote import modulo2

print(modulo1.funcao_modulo1())
print(modulo2.funcao_modulo2())

# Você também pode importar diretamente as funções


from meu_pacote.modulo1 import funcao_modulo1
print(funcao_modulo1())

__init__.py

O arquivo __init__.py é o que faz com que o Python trate os diretórios como
pacotes. Ele pode estar vazio, mas também pode ser usado para:

Inicialização do Pacote: Executar código de inicialização quando o pacote é


importado.

Definir __all__ : Controlar o que é importado quando from pacote import *


é usado.
Importações Simplificadas: Fazer importações de sub-módulos para o nível
superior do pacote.

Exemplo de meu_pacote/__init__.py para importações simplificadas:

# meu_pacote/__init__.py
from . import modulo1
from .sub_pacote import modulo2

# Opcional: definir o que é importado com 'from meu_pacote import *'


__all__ = ["modulo1", "modulo2"]

Com isso, em [Link] você poderia fazer:

# [Link]
import meu_pacote

print(meu_pacote.modulo1.funcao_modulo1())
print(meu_pacote.modulo2.funcao_modulo2())

Boas Práticas

Organização: Mantenha seus módulos e pacotes bem organizados e com nomes


descritivos.

Reutilização: Crie módulos para funcionalidades que você planeja reutilizar em


diferentes partes do seu projeto ou em outros projetos.

Evite from ... import * : Embora conveniente, from ... import * pode
poluir o namespace e dificultar a identificação da origem das funções e variáveis.
Prefira importações explícitas ( import modulo ou from modulo import
funcao ).

Exercícios

1. Crie um pacote chamado calculadora com dois módulos: [Link] (com uma
função somar ) e [Link] (com uma função subtrair ). Crie um arquivo
[Link] fora do pacote e importe e use as funções de soma e subtracao .

2. Adicione um arquivo __init__.py ao pacote calculadora para que você possa


importar as funções somar e subtrair diretamente do pacote (ex: from
calculadora import somar ).
3. Crie um módulo [Link] com algumas constantes (e.g., GRAVIDADE ,
VELOCIDADE_LUZ ). Importe e use essas constantes em outro script.

Módulo 3: Python Avançado

3.1 Decoradores, Geradores e Iteradores

Decoradores

Decoradores são funções que modificam o comportamento de outras funções ou


métodos. Eles permitem adicionar funcionalidades a uma função existente sem
modificar sua estrutura.

def meu_decorador(funcao):
def wrapper():
print("Antes da função ser chamada.")
funcao()
print("Depois da função ser chamada.")
return wrapper

@meu_decorador
def minha_funcao():
print("Minha função foi chamada.")

minha_funcao()

# Exemplo de decorador com argumentos


def log_execucao(funcao):
def wrapper(*args, **kwargs):
print(f"Executando a função {funcao.__name__} com argumentos: {args},
{kwargs}")
resultado = funcao(*args, **kwargs)
print(f"Função {funcao.__name__} finalizada. Resultado: {resultado}")
return resultado
return wrapper

@log_execucao
def somar(a, b):
return a + b

@log_execucao
def multiplicar(a, b):
return a * b

somar(10, 5)
multiplicar(4, 6)
Geradores

Geradores são funções que retornam um iterador. Eles geram valores "on the fly" (sob
demanda) usando a palavra-chave yield , o que os torna muito eficientes em termos
de memória, especialmente para sequências grandes.

def gerador_numeros(n):
i = 0
while i < n:
yield i
i += 1

# Usando o gerador
for numero in gerador_numeros(5):
print(numero)

# Geradores são iteradores, então podem ser convertidos em listas (mas perdem a
eficiência de memória)
lista_gerada = list(gerador_numeros(3))
print(lista_gerada)

# Exemplo: Gerador de Fibonacci


def fibonacci_generator(limite):
a, b = 0, 1
while a < limite:
yield a
a, b = b, a + b

for num in fibonacci_generator(10):


print(num)

Iteradores

Um iterador é um objeto que implementa o protocolo iterador, que consiste nos


métodos __iter__() e __next__() . O método __iter__() retorna o próprio objeto
iterador, e __next__() retorna o próximo item da sequência. Se não houver mais
itens, ele levanta a exceção StopIteration .
# Exemplo de iterador personalizado
class Contador:
def __init__(self, maximo):
[Link] = maximo
[Link] = 0

def __iter__(self):
return self

def __next__(self):
if [Link] < [Link]:
[Link] += 1
return [Link] - 1
else:
raise StopIteration

# Usando o iterador
meu_contador = Contador(3)
for num in meu_contador:
print(num)

# Ou manualmente
it = iter(Contador(2))
print(next(it))
print(next(it))
try:
print(next(it))
except StopIteration:
print("Fim da iteração.")

Exercícios

1. Crie um decorador que meça o tempo de execução de uma função.

2. Crie um gerador que produza números pares até um determinado limite.

3. Implemente um iterador para uma sequência de números de 1 a N, onde N é


definido na inicialização da classe.

3.2 Programação Assíncrona (Async/Await)

Programação assíncrona permite que um programa execute tarefas sem bloquear a


execução de outras tarefas, melhorando a responsividade e a eficiência,
especialmente em operações de I/O (entrada/saída) como requisições de rede ou
acesso a banco de dados.

Conceitos Chave

Corrotinas: Funções especiais definidas com async def . Elas podem ser
pausadas e retomadas.
await : Usado dentro de corrotinas para pausar a execução da corrotina atual
até que uma operação assíncrona seja concluída.

asyncio : Módulo da biblioteca padrão do Python para escrever código


concorrente usando a sintaxe async/await .

Loop de Eventos: O coração do asyncio , responsável por gerenciar e executar


as corrotinas.

import asyncio
import time

async def tarefa_assincrona(nome, tempo):


print(f"Iniciando {nome}...")
await [Link](tempo) # Simula uma operação de I/O demorada
print(f"{nome} concluída após {tempo} segundos.")
return f"Resultado de {nome}"

async def main():


print("Iniciando o programa principal...")

# Executando tarefas em paralelo


tarefa1 = asyncio.create_task(tarefa_assincrona("Tarefa 1", 3))
tarefa2 = asyncio.create_task(tarefa_assincrona("Tarefa 2", 2))

# Aguardando a conclusão das tarefas


resultado1 = await tarefa1
resultado2 = await tarefa2

print(f"Resultados: {resultado1}, {resultado2}")


print("Programa principal concluído.")

# Para executar o loop de eventos


if __name__ == "__main__":
start_time = [Link]()
[Link](main())
end_time = [Link]()
print(f"Tempo total de execução: {end_time - start_time:.2f} segundos")

No exemplo acima, tarefa_assincrona simula uma operação que leva tempo. Ao


usar await [Link](tempo) , a execução da tarefa_assincrona é pausada,
mas o loop de eventos pode alternar para outras corrotinas (como tarefa2 ) em vez
de ficar ocioso. Isso permite que as tarefas sejam executadas de forma concorrente,
reduzindo o tempo total de execução.

Requisições HTTP Assíncronas (com aiohttp )

Para operações de rede, bibliotecas como requests são síncronas. Para requisições
assíncronas, você pode usar aiohttp (precisa ser instalado: pip install aiohttp ).
import asyncio
import aiohttp

async def fetch_url(session, url):


async with [Link](url) as response:
return await [Link]()

async def main_http():


urls = [
"[Link]
"[Link]
"[Link]
]

async with [Link]() as session:


tasks = []
for url in urls:
[Link](fetch_url(session, url))

# Executa todas as tarefas de forma concorrente


htmls = await [Link](*tasks)

for i, html in enumerate(htmls):


print(f"Conteúdo da URL {urls[i]} (primeiros 100
caracteres):\n{html[:100]}\n...")

if __name__ == "__main__":
print("\n--- Exemplo de Requisições HTTP Assíncronas ---")
[Link](main_http())

Exercícios

1. Crie três corrotinas que simulem o download de arquivos de tamanhos


diferentes (usando [Link] com tempos variados). Execute-as
concorrentemente e imprima a ordem em que elas terminam.

2. Pesquise sobre [Link] e [Link] e explique a diferença entre


eles em um pequeno texto.

3. (Opcional, requer aiohttp ) Modifique o exemplo de main_http para buscar


dados de uma API pública (ex: JSONPlaceholder) e imprima o JSON retornado.

3.3 Frameworks Web (Flask/Django) e Manipulação de APIs

Python é amplamente utilizado no desenvolvimento web, graças a frameworks


poderosos como Flask e Django.
Flask (Microframework)

Flask é um microframework web leve e flexível. É ideal para projetos menores, APIs
RESTful e para quem prefere ter mais controle sobre os componentes.

Exemplo Básico de Flask:

Para rodar este exemplo, você precisará instalar Flask: pip install Flask

# [Link]
from flask import Flask, jsonify, request

app = Flask(__name__)

# Rota Home
@[Link]('/')
def home():
return "Olá, mundo! Bem-vindo à minha API Flask!"

# Rota com parâmetro


@[Link]('/saudar/<nome>')
def saudar(nome):
return f"Olá, {nome}!"

# Rota para API RESTful (GET)


@[Link]('/api/dados', methods=['GET'])
def get_dados():
dados = {
"id": 1,
"nome": "Exemplo",
"valor": 123.45
}
return jsonify(dados)

# Rota para API RESTful (POST)


@[Link]('/api/adicionar', methods=['POST'])
def adicionar_dados():
novo_dado = [Link] # Espera um JSON no corpo da requisição
print(f"Dado recebido: {novo_dado}")
# Aqui você normalmente salvaria o dado em um banco de dados
return jsonify({"mensagem": "Dado adicionado com sucesso!", "dado":
novo_dado}), 201 # 201 Created

if __name__ == '__main__':
[Link](debug=True) # debug=True para desenvolvimento (recarrega
automaticamente)

Para executar, salve como [Link] e rode python [Link] . Acesse


[Link] no seu navegador. Para testar a rota POST, você pode usar
ferramentas como Postman, Insomnia ou curl :

curl -X POST -H "Content-Type: application/json" -d '{"item": "caneta",


"quantidade": 10}' [Link]
Django (Full-stack Framework)

Django é um framework web de alto nível que incentiva o desenvolvimento rápido e


design limpo e pragmático. Ele vem com muitas funcionalidades "baterias incluídas",
como ORM (Object-Relational Mapper), sistema de administração, autenticação, etc. É
ideal para aplicações complexas e escaláveis.

Conceitos Chave do Django: * MTV (Model-Template-View): Similar ao MVC. Model


(dados), Template (interface), View (lógica de negócio). * ORM: Mapeia objetos Python
para tabelas de banco de dados, eliminando a necessidade de escrever SQL
diretamente. * Admin Site: Um painel de administração gerado automaticamente
para gerenciar dados do modelo.

Exemplo Básico de Django (Estrutura):

Para iniciar um projeto Django:

pip install Django


django-admin startproject meuprojeto
cd meuprojeto
python [Link] startapp minhaapp

meuprojeto/meuprojeto/[Link] : Adicione 'minhaapp' em INSTALLED_APPS .

meuprojeto/minhaapp/[Link] :

from [Link] import models

class Livro([Link]):
titulo = [Link](max_length=200)
autor = [Link](max_length=100)
ano_publicacao = [Link]()

def __str__(self):
return [Link]

Após definir o modelo, execute as migrações:

python [Link] makemigrations


python [Link] migrate

meuprojeto/minhaapp/[Link] :
from [Link] import render
from [Link] import HttpResponse
from .models import Livro

def lista_livros(request):
livros = [Link]()
return render(request, 'minhaapp/lista_livros.html', {'livros': livros})

def saudacao_django(request):
return HttpResponse("Olá do Django!")

meuprojeto/minhaapp/[Link] (crie este arquivo):

from [Link] import path


from . import views

urlpatterns = [
path('livros/', views.lista_livros, name='lista_livros'),
path('saudacao/', views.saudacao_django, name='saudacao_django'),
]

meuprojeto/meuprojeto/[Link] : Inclua as URLs da sua app.

from [Link] import admin


from [Link] import path, include

urlpatterns = [
path('admin/', [Link]),
path('minhaapp/', include('[Link]')), # Inclui as URLs da sua app
]

Crie o diretório meuprojeto/minhaapp/templates/minhaapp/ e o arquivo


lista_livros.html :

<!-- meuprojeto/minhaapp/templates/minhaapp/lista_livros.html -->


<!DOCTYPE html>
<html>
<head>
<title>Lista de Livros</title>
</head>
<body>
<h1>Livros Disponíveis</h1>
<ul>
{% for livro in livros %}
<li>{{ [Link] }} - {{ [Link] }} ({{ livro.ano_publicacao
}})</li>
{% endfor %}
</ul>
</body>
</html>
Para rodar o servidor de desenvolvimento:

python [Link] runserver

Acesse [Link] ou
[Link] .

Manipulação de APIs (Consumindo APIs)

Além de criar APIs, Python é excelente para consumir APIs existentes. A biblioteca
requests é a mais popular para isso.

Para instalar: pip install requests


import requests

def buscar_posts_jsonplaceholder():
url = "[Link]
try:
response = [Link](url)
response.raise_for_status() # Levanta um erro para códigos de status
HTTP ruins (4xx ou 5xx)
posts = [Link]() # Converte a resposta JSON em um objeto Python
for post in posts[:5]: # Imprime os primeiros 5 posts
print(f"ID: {post['id']}\nTítulo: {post['title']}\nCorpo:
{post['body'][:50]}...\n---\n")
except [Link] as errh:
print(f"Erro HTTP: {errh}")
except [Link] as errc:
print(f"Erro de Conexão: {errc}")
except [Link] as errt:
print(f"Timeout: {errt}")
except [Link] as err:
print(f"Ocorreu um erro: {err}")

def criar_novo_post():
url = "[Link]
novo_post = {
"title": "Meu Novo Post",
"body": "Este é o corpo do meu post de teste.",
"userId": 1
}
headers = {'Content-type': 'application/json; charset=UTF-8'}

try:
response = [Link](url, json=novo_post, headers=headers)
response.raise_for_status()
print("\nNovo post criado com sucesso:")
print([Link]())
except [Link] as err:
print(f"Erro ao criar post: {err}")

if __name__ == "__main__":
print("Buscando posts de exemplo...")
buscar_posts_jsonplaceholder()

print("\nCriando um novo post de exemplo...")


criar_novo_post()

Exercícios

1. (Flask) Modifique o aplicativo Flask para ter uma rota


/calculadora/<operacao>/<num1>/<num2> que realize operações básicas
(soma, subtracao, multiplicacao, divisao) e retorne o resultado em JSON.

2. (Django) Crie um novo modelo Django chamado Produto com campos nome ,
preco e estoque . Configure o admin para gerenciar Produto e crie algumas
instâncias via painel de administração.
3. (APIs) Use a biblioteca requests para consumir uma API pública diferente (ex:
Star Wars API - SWAPI, OpenWeatherMap API - requer chave, ou outra de sua
escolha) e imprima alguns dados relevantes.

3.4 Testes Unitários e Boas Práticas de Código

Testes Unitários com unittest

Testes unitários são uma parte crucial do desenvolvimento de software moderno. Eles
garantem que pequenas unidades de código (funções, métodos) funcionem como
esperado, facilitando a detecção de bugs e a manutenção do código.

Python possui um módulo embutido para testes unitários chamado unittest .

# [Link] (o código que vamos testar)


def somar(a, b):
return a + b

def subtrair(a, b):


return a - b

def multiplicar(a, b):


return a * b

def dividir(a, b):


if b == 0:
raise ValueError("Não é possível dividir por zero!")
return a / b
# test_calculadora.py (o arquivo de testes)
import unittest
from calculadora import somar, subtrair, multiplicar, dividir

class TestCalculadora([Link]):

def test_somar(self):
[Link](somar(2, 3), 5)
[Link](somar(-1, 1), 0)
[Link](somar(-1, -1), -2)

def test_subtrair(self):
[Link](subtrair(5, 2), 3)
[Link](subtrair(2, 5), -3)
[Link](subtrair(10, 0), 10)

def test_multiplicar(self):
[Link](multiplicar(2, 3), 6)
[Link](multiplicar(-1, 5), -5)
[Link](multiplicar(0, 10), 0)

def test_dividir(self):
[Link](dividir(10, 2), 5)
[Link](dividir(10, 3), 3.33333, places=5)
with [Link](ValueError):
dividir(10, 0)

if __name__ == '__main__':
[Link]()

Para executar os testes, salve os dois arquivos no mesmo diretório e execute python
test_calculadora.py no terminal.

Boas Práticas de Código Python (PEP 8)

Seguir boas práticas de codificação torna seu código mais legível, mantenível e
colaborativo. A PEP 8 é o guia de estilo oficial do Python.

Principais Pontos da PEP 8:

Nomenclatura:

Variáveis e funções: snake_case (ex: minha_variavel , calcular_total ).

Classes: CamelCase (ex: MinhaClasse , ContaBancaria ).

Constantes: ALL_CAPS (ex: MAX_SIZE , PI ).

Módulos: lowercase_with_underscores .

Espaçamento:
Indentação: 4 espaços (NUNCA tabs).

Linhas em branco: Duas linhas em branco entre funções e classes de nível


superior; uma linha em branco entre métodos dentro de uma classe.

Espaços em branco: Evite espaços em branco desnecessários (ex: x = 1 e


não x = 1 ).

Comprimento da Linha: Limite as linhas a 79 caracteres (ou 99 para comentários


e docstrings). Use parênteses para quebrar linhas longas.

```python

Ruim
resultado_muito_longo = funcao_com_muitos_parametros(parametro1,
parametro2, parametro3, parametro4, parametro5, parametro6)

Bom
resultado_muito_longo = funcao_com_muitos_parametros( parametro1,
parametro2, parametro3, parametro4, parametro5, parametro6 ) ```

Comentários e Docstrings:

Comentários ( # ): Use para explicar o "porquê" do código, não o "o quê".

Docstrings ( """Docstring""" ): Use para documentar módulos, classes e


funções. Explique o propósito, argumentos, o que retorna e possíveis
exceções.

Importações:

Importe módulos no início do arquivo.

Organize as importações em grupos: biblioteca padrão, bibliotecas de


terceiros, módulos locais. Separe os grupos com uma linha em branco.

Importe um módulo por linha.


```python import os import sys

import requests from flask import Flask

from meu_modulo import minha_funcao ```

Tratamento de Exceções: Seja específico ao capturar exceções. Evite except


Exception as e: genéricos, a menos que você realmente precise capturar tudo
e saiba como lidar com isso.

List Comprehensions: Use para criar listas de forma concisa e legível.

```python

Ruim
quadrados = [] for i in range(10): [Link](i**2)

Bom
quadrados = [i**2 for i in range(10)] ```

Uso de if __name__ == "__main__": : Garante que o código dentro deste bloco


só seja executado quando o script é rodado diretamente, e não quando é
importado como um módulo.

Ferramentas como flake8 , black e isort podem ajudar a automatizar a verificação


e formatação do código de acordo com a PEP 8.

Exercícios

1. Crie um arquivo minha_string_utils.py com uma função


inverter_string(texto) e outra contar_vogais(texto) . Escreva um arquivo
de teste test_string_utils.py usando unittest para testar essas funções.

2. Pegue um dos seus códigos anteriores e refatore-o para seguir as boas práticas
da PEP 8, prestando atenção à nomenclatura, espaçamento e comprimento das
linhas.

3. Pesquise sobre a ferramenta Black (formatador de código Python) e explique


em um parágrafo como ela pode ajudar a manter a conformidade com a PEP 8.

Módulo 4: Projetos Práticos

Para solidificar o conhecimento adquirido, é fundamental aplicar os conceitos em


projetos práticos. Abaixo, sugerimos alguns projetos, divididos por nível de
dificuldade, que você pode desenvolver.

4.1 Projetos Nível Básico

Estes projetos são ideais para praticar os fundamentos de variáveis, estruturas de


controle, funções e manipulação básica de strings e listas.

Projeto 1: Jogo de Adivinhação de Números

Descrição: O computador escolhe um número aleatório entre 1 e 100, e o jogador


tenta adivinhar. O programa deve dar dicas se o palpite é muito alto ou muito baixo, e
contar quantas tentativas o jogador levou.

Conceitos a praticar: * Geração de números aleatórios ( [Link] ). * Laços de


repetição ( while ). * Condicionais ( if / elif / else ). * Entrada e saída de dados
( input() , print() ). * Conversão de tipos ( int() ).

Exemplo de Estrutura:
import random

def jogar_adivinhacao():
numero_secreto = [Link](1, 100)
tentativas = 0
print("Bem-vindo ao Jogo de Adivinhação!")
print("Estou pensando em um número entre 1 e 100.")

while True:
try:
palpite = int(input("Qual é o seu palpite? "))
tentativas += 1

if palpite < numero_secreto:


print("Muito baixo! Tente novamente.")
elif palpite > numero_secreto:
print("Muito alto! Tente novamente.")
else:
print(f"Parabéns! Você adivinhou o número em {tentativas}
tentativas!")
break
except ValueError:
print("Entrada inválida. Por favor, digite um número inteiro.")

if __name__ == "__main__":
jogar_adivinhacao()

Projeto 2: Calculadora Simples

Descrição: Crie uma calculadora que realize as quatro operações básicas (adição,
subtração, multiplicação, divisão) com dois números fornecidos pelo usuário.

Conceitos a praticar: * Funções. * Condicionais. * Entrada de dados. * Tratamento de


exceções ( try / except para divisão por zero e entrada inválida).

4.2 Projetos Nível Intermediário

Estes projetos envolvem estruturas de dados mais complexas, POO, manipulação de


arquivos e módulos/pacotes.

Projeto 1: Sistema de Gerenciamento de Tarefas (To-Do List)

Descrição: Desenvolva um programa que permita ao usuário adicionar, remover,


marcar como concluída e listar tarefas. As tarefas devem ser persistidas em um
arquivo (e.g., CSV ou JSON).

Conceitos a praticar: * Listas e Dicionários. * Programação Orientada a Objetos


(classe Tarefa ). * Manipulação de arquivos (leitura/escrita). * Funções para cada
operação (adicionar, remover, etc.). * Uso de módulos como json ou csv .

Exemplo de Estrutura:
import json

class Tarefa:
def __init__(self, descricao, concluida=False):
[Link] = descricao
[Link] = concluida

def __str__(self):
status = "[X]" if [Link] else "[ ]"
return f"{status} {[Link]}"

def to_dict(self):
return {"descricao": [Link], "concluida": [Link]}

class GerenciadorTarefas:
def __init__(self, arquivo_dados="[Link]"):
self.arquivo_dados = arquivo_dados
[Link] = self._carregar_tarefas()

def _carregar_tarefas(self):
try:
with open(self.arquivo_dados, "r") as f:
dados = [Link](f)
return [Tarefa(t["descricao"], t["concluida"]) for t in dados]
except FileNotFoundError:
return []

def _salvar_tarefas(self):
with open(self.arquivo_dados, "w") as f:
[Link]([t.to_dict() for t in [Link]], f, indent=4)

def adicionar_tarefa(self, descricao):


[Link](Tarefa(descricao))
self._salvar_tarefas()
print(f"Tarefa \"{descricao}\" adicionada.")

def listar_tarefas(self):
if not [Link]:
print("Nenhuma tarefa na lista.")
return
print("\n--- Suas Tarefas ---")
for i, tarefa in enumerate([Link]):
print(f"{i + 1}. {tarefa}")
print("-------------------")

def marcar_concluida(self, indice):


if 0 <= indice < len([Link]):
[Link][indice].concluida = True
self._salvar_tarefas()
print(f"Tarefa \"{[Link][indice].descricao}\" marcada como
concluída.")
else:
print("Índice de tarefa inválido.")

def remover_tarefa(self, indice):


if 0 <= indice < len([Link]):
removida = [Link](indice)
self._salvar_tarefas()
print(f"Tarefa \"{[Link]}\" removida.")
else:
print("Índice de tarefa inválido.")
def menu():
gerenciador = GerenciadorTarefas()
while True:
print("\nMenu:")
print("1. Adicionar tarefa")
print("2. Listar tarefas")
print("3. Marcar tarefa como concluída")
print("4. Remover tarefa")
print("5. Sair")

escolha = input("Escolha uma opção: ")

if escolha == "1":
desc = input("Descrição da tarefa: ")
gerenciador.adicionar_tarefa(desc)
elif escolha == "2":
gerenciador.listar_tarefas()
elif escolha == "3":
gerenciador.listar_tarefas()
try:
idx = int(input("Número da tarefa para marcar como concluída:
")) - 1
gerenciador.marcar_concluida(idx)
except ValueError:
print("Entrada inválida. Digite um número.")
elif escolha == "4":
gerenciador.listar_tarefas()
try:
idx = int(input("Número da tarefa para remover: ")) - 1
gerenciador.remover_tarefa(idx)
except ValueError:
print("Entrada inválida. Digite um número.")
elif escolha == "5":
print("Saindo do programa.")
break
else:
print("Opção inválida. Tente novamente.")

if __name__ == "__main__":
menu()

Projeto 2: Consumidor de API de Clima

Descrição: Crie um programa que use uma API de clima (ex: OpenWeatherMap,
[Link]) para obter e exibir informações sobre o clima de uma cidade
fornecida pelo usuário.

Conceitos a praticar: * Requisições HTTP ( requests ). * Manipulação de JSON. *


Tratamento de erros de rede e API. * Uso de chaves de API.
4.3 Projetos Nível Avançado

Estes projetos exploram tópicos como programação assíncrona, frameworks web e


testes mais complexos.

Projeto 1: Aplicação Web Simples com Flask/Django

Descrição: Desenvolva uma pequena aplicação web (e.g., um blog simples, um


encurtador de URL, um gerenciador de contatos) usando Flask ou Django. A aplicação
deve ter pelo menos duas rotas e interagir com um banco de dados (pode ser SQLite
para simplicidade).

Conceitos a praticar: * Frameworks web (Flask ou Django). * Rotas e views. *


Templates (Jinja2 para Flask, Django Templates). * Interação com banco de dados
(ORM). * Formulários (WTForms para Flask, Django Forms).

Projeto 2: Raspador de Dados Assíncrono (Web Scraper)

Descrição: Crie um programa que raspe dados de um site (e.g., títulos de notícias,
preços de produtos) de forma assíncrona para melhorar a performance. Salve os
dados em um arquivo ou banco de dados.

Conceitos a praticar: * Programação assíncrona ( asyncio , aiohttp ). * Parsing de


HTML ( BeautifulSoup4 ). * Tratamento de exceções. * Manipulação de arquivos/banco
de dados.

Dicas para os Projetos:

Comece Pequeno: Não tente construir tudo de uma vez. Divida o projeto em
pequenas funcionalidades e implemente uma por uma.

Pesquise: Use a documentação oficial, Stack Overflow e outros recursos online


quando tiver dúvidas.

Teste: Escreva testes para suas funções e classes para garantir que tudo funcione
como esperado.

Controle de Versão: Use Git e GitHub para gerenciar seu código. Isso é uma
prática essencial no desenvolvimento de software.

Refatore: À medida que você aprende mais, revise seu código antigo e veja como
pode melhorá-lo (torná-lo mais limpo, eficiente, legível).
Divirta-se! A melhor forma de aprender é fazendo e se divertindo com o
processo.

Você também pode gostar