8  Manipulação de Arquivos em Python

Saindo da telinha sem cor do terminal: trabalhando com arquivos

8.1 O que você saberá se ler todo este capítulo?

Prepare-se para sair da “telinha sem cor” do terminal e entrar no mundo real da programação!

8.1.1 Você vai aprender:

  1. Por que trabalhar com arquivos - Quando o terminal não é suficiente
  2. Abrir e fechar arquivos - Os comandos open() e close(), e o poderoso with
  3. Modos de arquivo - Leitura (r), escrita (w), anexar (a) e binário (b)
  4. Arquivos de texto - Como salvar e ler textos simples
  5. Arquivos JSON - O formato mais popular para troca de dados
  6. Arquivos Pickle - Como salvar objetos Python diretamente
  7. Módulos Python - Como usar import para acessar funcionalidades extras
  8. Boas práticas - Como trabalhar com arquivos de forma segura

8.1.2 Conceitos que você vai dominar:

  • Persistência de dados - Como salvar informações permanentemente
  • Formatos de arquivo - Texto, JSON, Pickle e quando usar cada um
  • Gerenciamento de recursos - Como usar with para evitar problemas
  • Módulos - Como expandir as funcionalidades do Python
  • Serialização - Como converter dados para diferentes formatos

💡 Dica importante: Este capítulo é essencial! Trabalhar com arquivos é fundamental para qualquer aplicação real. Domine isso e você estará pronto para criar programas que realmente fazem algo útil!

8.2 Livro de Receitas

Achou que eu esqueci da receita de bolo? Claro que não! Jamais esqueceria de um bolo. Com um café então, nem se fala!

Bom, vamos imaginar que você tem uma receita de bolo e quer dar o seu toque pessoal. Transformar aquela receita da internet em uma receita de família, sabe?

Quem sabe você se animou bastante e agora quer fazer o seu próprio caderno de receitas usando como base algumas receitas comuns que já viu por aí. Como você faria isso?

8.2.1 O Processo:

  1. Abrir o caderno - Pegar seu caderno de receitas
  2. Procurar uma folha em branco - Encontrar espaço para nova receita
  3. Escrever a receita - Colocar tudo do seu jeito
  4. Modificar se necessário - Voltar e ajustar ingredientes ou instruções
  5. Compartilhar - Mostrar para família e amigos

8.2.2 A Vantagem dos Arquivos:

Ah, e sabe qual é a vantagem disso? Você pode compartilhar com todo mundo! As pessoas podem tirar fotos ou cópias do seu caderno e, com isso, algum dia você poderá ser reconhecido como o maior boleiro (é esse o nome?) do mundo!

Quem diria, né? Por causa desse livro aqui você se tornou o maior mestre dos bolos do mundo e até conseguiu comprar um iate! 🛥️

Um iate navegando no mar

O que isso tem a ver com programação? Em Python, os arquivos funcionam exatamente como esse caderno de receitas!

8.2.3 O Problema do Terminal

Se você quiser continuar estudando desenvolvimento de software, a explicação acima ainda se aplica!

Você pode ter percebido que as variáveis que trabalhamos até o momento nunca eram salvas no seu computador, não é?

O que acontece:

  1. Você clica em Run
  2. O código aparece no terminal
  3. Você interage com ele
  4. E acabou!

Tirou o computador da tomada? Acabou a bateria do notebook? Todas as variáveis foram apagadas!

8.2.4 A Solução: Arquivos!

Por outro lado, os arquivos existem para ajudar a salvar e transmitir esta informação para outros lugares.

E se nós quiséssemos usar Python para:

  • ✅ Adicionar informações a um arquivo
  • ✅ Modificar informações existentes
  • ✅ Excluir informações desnecessárias
  • ✅ Compartilhar dados entre programas

É possível? Claro que é!

É exatamente isso que veremos a partir de agora. Vamos lá?

8.3 Abrindo e Fechando Arquivos

Lembra que no pseudocódigo tínhamos o leia e escreva, né? E que, em Python, eles eram traduzidos como input() e print().

Então, será que o Python teria algo para abrir e fechar arquivos?

Mas é claro! E, como você deve adivinhar, os nomes das funções para isso são:

  • open() - Para abrir arquivos
  • close() - Para fechar arquivos

8.3.1 O Processo Básico:

  1. Abrir o arquivo (open())
  2. Trabalhar com o arquivo (ler/escrever)
  3. Fechar o arquivo (close())

Vamos começar com um trabalho simples: vamos escrever uma receita de bolo dentro de um arquivo em Python! 🍰

8.3.2 Criando Arquivos (Escrevendo)

Rode o código abaixo em um arquivo .py, tal qual você vem fazendo até o momento no PyCharm:

with open("receita.txt", "w") as f:
    f.write("Bolo de chocolate\n")
    f.write("Ingredientes:\n")
    f.write("- 2 xícaras de açúcar\n")
    f.write("- 1 e 3/4 xícaras de farinha de trigo\n")
    f.write("- 3/4 xícara de cacau em pó\n")
    
print("Finalizou!")

Muita coisa nova, né? Agora tem with, tem open, tem aquele "w" também. O que quer dizer tudo isso?

Calma! É mais simples do que parece! 😊

8.3.2.1 Analisando o Código:

Linha 1: with open("receita.txt", "w") as f:

  • open() - Abre um arquivo
  • "receita.txt" - Nome do arquivo que será criado
  • "w" - Modo de escrita (write)
  • as f - Chama o arquivo de f (como uma variável)
  • with - Garante que o arquivo seja fechado automaticamente

Em bom português: “Abra um arquivo chamado ‘receita.txt’ para a gente escrever coisas dentro dele”

Linhas 2-6: f.write("texto\n")

  • write() - Escreve texto no arquivo
  • \n - Quebra de linha (igual ao Enter)

Como funciona:

  1. Abre o arquivo para escrita
  2. Escreve cada linha da receita
  3. Fecha automaticamente o arquivo
  4. Salva todas as alterações

💡 Dica: O write() é bem parecido com o print(), mas em vez de mostrar na tela, ele escreve no arquivo!

Teste: Depois de rodar este código, experimente abrir o arquivo receita.txt que foi criado na mesma pasta do seu arquivo .py. Percebe que contém exatamente as 5 linhas da receita?

8.3.3 Lendo Arquivos

Bom, e para lermos o arquivo? Teste o seguinte código:

with open("receita.txt", "r") as f:
    conteudo = f.read()
    print(conteudo)

8.3.3.1 Analisando o Código:

Linha 1: with open("receita.txt", "r") as f:

  • "r" - Modo de leitura (read) - ao invés de escrever, queremos ler!

Linha 2: conteudo = f.read()

  • .read() - Lê todo o conteúdo do arquivo
  • conteudo - Variável que armazena o texto lido

Linha 3: print(conteudo)

  • print() - Mostra o conteúdo na tela

8.3.3.2 Alternativa sem with:

f = open("receita.txt", "r")
conteudo = f.read()
print(conteudo)
f.close()

Diferenças:

  1. Sem with - Não há indentação
  2. Sem fechamento automático - Precisamos fechar manualmente
  3. f.close() - Fecha o arquivo explicitamente

⚠️ Importante: Sempre use with para evitar esquecer de fechar o arquivo!

8.3.4 Adicionando ao Arquivo (Append)

Finalmente, e se quiséssemos adicionar mais alguma coisinha no arquivo sem apagar o que já temos? Também tem como!

Veja só:

with open("receita.txt", "a") as f:
    f.write("- 1 colher de sopa de fermento em pó\n")
    f.write("- Granulado a gosto\n")

8.3.4.1 Analisando o Código:

Linha 1: with open("receita.txt", "a") as f:

  • "a" - Modo append (adicionar) - adiciona no final sem apagar nada!

Linhas 2-3: f.write("texto\n")

  • write() - Adiciona texto no final do arquivo

💡 Dica: O modo "a" é perfeito para adicionar informações sem perder o que já existe!

8.3.5 Resumo dos Modos de Arquivo

Modo Nome Função Quando usar
"r" Read Lê o arquivo Quando você quer ler
"w" Write Escreve (apaga tudo) Quando você quer criar/substituir
"a" Append Adiciona no final Quando você quer adicionar
"x" Exclusive Cria novo arquivo Quando você quer garantir que é novo
"b" Binary Dados binários Para imagens, vídeos, etc.

8.3.6 Funções Principais:

  • open() - Abre um arquivo
  • close() - Fecha um arquivo (não precisa com with)
  • write() - Escreve texto no arquivo
  • read() - Lê todo o conteúdo do arquivo
  • with - Garante que o arquivo seja fechado automaticamente

⚠️ Lembre-se: Sempre use with para evitar esquecer de fechar arquivos!

8.4 Escrevendo diferentes tipos de arquivo

Até agora, trabalhamos apenas com arquivos de texto simples (como o receita.txt que você criou). Esses arquivos .txt contêm apenas texto puro - sem formatação, cores ou estilos especiais. São ótimos para receitas, anotações e textos simples.

Mas e se você quiser salvar dados mais estruturados? Como listas, dicionários ou números? É aí que entram outros formatos! Vamos ver alguns exemplos:

valor_pi = 3.14159
lista_frutas = ["maçã", "banana", "laranja", "manga"]
dicionario_pessoas = {"João": 25, "Maria": 30, "Pedro": 20, "Marcos": 15}

São três variáveis, e cada um possui um tipo diferente, certo? Uma delas é uma variável do tipo float, outra é uma lista e, a outra, um dicionário. Agora, como guardaríamos estas informações em arquivos? Vamos testar de quatro jeitos diferentes: com arquivos de texto (que acabei de explicar o que são), CSVs, JSON e, finalmente, Pickle. Também vamos falar para que servem cada um desses tipos, beleza? Ah, para cada um desses jeitos, salvaremos essas três variáveis em arquivos separados e, depois, abriremos elas para ver como ficaram.

8.4.1 Salvando em texto

Vamos começar escrevendo aquela variável valor_pi em um arquivo de texto, o que acha? Usando as mesmas funções que vimos até agora, teríamos:

# salvar valor_pi em um arquivo txt
with open("valor_pi.txt", "w") as f:
    f.write(str(valor_pi))

# ler valor_pi de um arquivo txt
with open("valor_pi.txt", "r") as f:
    valor_pi_lido = f.read()
    print(f'{valor_pi_lido}, tipo {type(valor_pi_lido)}')

Percebe a linha f.write(str(valor_pi))? Para salvarmos texto precisaremos, obrigatoriamente, converter as variáveis para texto. É por isso que o valor da variável é convertido em uma string usando a função str() antes de o gravarmos no arquivo.

Quanto à leitura, veja que na penúltima linha estamos lendo o conteúdo do arquivo valor_pi.txt usando o modo de leitura "r" do método open(). O conteúdo do arquivo é armazenado na variável valor_pi_lido como uma string. Para comprovar isso, veja que na última linha eu mostro na tela o valor de valor_pi_lido e o tipo de dado da variável usando a função print(). No caso, aquele type(valor_pi_lido) mostra na tela o tipo daquela variável que, no caso, é uma string.

O resultado, portanto, seria:

3.14159, tipo <class 'str'>

Quer converter aquele valor lido do arquivo de volta para um número? Então você precisaria fazer um float(valor_pi_lido) para isso. Agora, e se quiséssemos salvar a lista em arquivo? Veja só (e teste, se possível):

# salvar lista_frutas em um arquivo txt
with open("lista_frutas.txt", "w") as f:
    f.write(str(lista_frutas))

# ler lista_frutas de um arquivo txt
with open("lista_frutas.txt", "r") as f:
    lista_frutas_lida = f.read()
    print(f'{lista_frutas_lida}, tipo {type(lista_frutas_lida)}')

A mesma coisa: convertemos primeiro a lista para string para poder salvar (por isso o str() em f.write(str(lista_frutas))). E, para ler, também teremos o resultado em string, igualzinho como no exemplo anterior. Aqui, a saída será:

['maçã', 'banana', 'laranja', 'manga'], tipo <class 'str'>

Também existe outra forma de salvar os dados dessa lista em arquivo. Poderíamos, por exemplo, salvar cada fruta em uma linha separada. Assim, teríamos o seguinte:

# salvar lista_frutas em um arquivo txt
with open("lista_frutas_split.txt", "w") as f:
    for fruta in lista_frutas:
        f.write(fruta + "\n")

# ler lista_frutas de um arquivo txt
with open("lista_frutas_split.txt", "r") as f:
    lista_frutas_lida = f.readlines()
    print(f'{lista_frutas_lida}, tipo {type(lista_frutas_lida)}')

O primeiro for irá percorrer cada elemento da lista_frutas e escreverá cada elemento em uma linha separada no arquivo de texto. Já a linha f.write(fruta + "\n") adiciona uma quebra de linha depois de cada fruta, para que cada uma fique em uma linha separada no arquivo.

Outra mudança: viu a função readlines()? Ela lerá o arquivo linha por linha e retornará uma lista contendo cada linha como um elemento separado. Interessante, não é? Agora, e para salvarmos o dicionário? Poderíamos fazer o seguinte:

# salvar dicionario_pessoas em um arquivo txt
with open("dicionario_pessoas.txt", "w") as f:
    f.write(str(dicionario_pessoas))

# ler dicionario_pessoas de um arquivo txt
with open("dicionario_pessoas.txt", "r") as f:
    dicionario_pessoas_lido = f.read()
    print(f'{dicionario_pessoas_lido}, tipo {type(dicionario_pessoas_lido)}')

Aqui, a mesma coisa dos outros exemplos anteriores também acontece: convertemos o dicionário para texto, e lemos de volta um texto. É por isso que para guardarmos estruturas de dados um pouco mais complexas como um dicionário ou uma lista não seria muito interessante trabalhar com esse read() ou readlines() do jeito que são. Afinal, teríamos uma certa dor de cabeça para convertermos o resultado do arquivo lido (que é sempre em string) de volta para uma lista, um dicionário ou qualquer outra estrutura.

8.4.2 Salvando em JSON

O JSON é outra maneira bem comum para salvarmos arquivos. Ele é usado para transmitir informações entre diferentes aplicações, permitindo que dados sejam facilmente compartilhados e manipulados. Geralmente sites, aplicativos e outros serviços que se comunicam com um usuário também trocam informações com servidores e bancos de dados usando JSON.

Um arquivo JSON é composto por pares chave-valor, onde a chave é uma string que identifica o valor correspondente, que pode ser um número, string, objeto ou lista. Os objetos e listas podem ser aninhados, o que permite a criação de estruturas complexas de dados. Aqui, uma analogia para entender um arquivo JSON seria pensar em um mapa de cidade. Cada chave seria como uma rua, e seu valor correspondente seria como as casas ou prédios nessa rua. Assim como um mapa, um arquivo JSON fornece um meio organizado de acessar informações e entender a estrutura de um conjunto de dados.

Sabe o dicionário em Python que você está acostumado (eu espero) a trabalhar? Então, está praticamente (senão totalmente) em formato JSON, já. Bom, vamos para os exemplos? Experimente rodar o código abaixo em Python:

import json

# INÍCIO DO BLOCO 1
# salvar valor_pi em um arquivo json
with open("valor_pi.json", "w") as f:
    json.dump(valor_pi, f)

# ler valor_pi de um arquivo json
with open("valor_pi.json", "r") as f:
    valor_pi_lido = json.load(f)
    print(f'{valor_pi_lido}, tipo {type(valor_pi_lido)}')
# FIM DO BLOCO 1

# INÍCIO DO BLOCO 2
# salvar lista_frutas em um arquivo json
with open("lista_frutas.json", "w") as f:
    json.dump(lista_frutas, f)

# ler lista_frutas de um arquivo json
with open("lista_frutas.json", "r") as f:
    lista_frutas_lido = json.load(f)
    print(f'{lista_frutas_lido}, tipo {type(lista_frutas_lido)}')
# FIM DO BLOCO 2

# INÍCIO DO BLOCO 3
# salvar dicionario_pessoas em um arquivo json
with open("dicionario_pessoas.json", "w") as f:
    json.dump(dicionario_pessoas, f)

# ler dicionario_pessoas de um arquivo json
with open("dicionario_pessoas.json", "r") as f:
    dicionario_pessoas_lido = json.load(f)
    print(f'{dicionario_pessoas_lido}, tipo {type(dicionario_pessoas_lido)}')
    for nome, idade in dicionario_pessoas_lido.items():
        print(nome, idade)
# FIM DO BLOCO 3

Muito código? Calma, vou explicar. Tá vendo aquele import json na primeira linha? Este código é uma importação do módulo json em Python. O módulo json é utilizado para codificar e decodificar dados em formato JSON. Imagine estes módulos como se fossem itens adicionais de uma comida de um fast-food ou os itens opcionais de um carro: eles não vem “de fábrica”, e você precisa “pedir” por este item. Existem vários módulos já integrados ao Python que fornecem funções úteis para lidar com tarefas comuns, como manipulação de arquivos, processamento de dados, matemática, networking, entre outras. Como nem sempre precisamos desses módulos em todo código, só os importamos quando realmente é necessário. Como somente agora estamos precisando trabalhar com o JSON, nós chamamos agora por esta importação.

Percebe que temos ao longo do código o json.dump() e json.load() no lugar do f.write() e f.read()? Então: estas funções são específicas para salvarmos os dados em formato JSON e lermos de volta os dados que estão em JSON, respectivamente. A função json.dump() sempre recebe dois parâmetros: primeiro, o objeto a ser salvo. Depois, o arquivo onde ele deve ser salvo.

Em seguida, o código lê cada um dos arquivos utilizando a função json.load(), que recebe como parâmetro o arquivo de onde os dados devem ser lidos. O bloco 1 salva e lê o valor da variável valor_pi em um arquivo JSON (experimente abrir o arquivo valor_pi.json no bloco de notas depois de rodar este código). O bloco 2 salva e lê a lista de frutas lista_frutas. Por fim, o bloco 3 salva e lê o dicionário dicionario_pessoas, que é impresso na tela utilizando um for.

O resultado desse código será isto:

3.14159, tipo <class 'float'>
['maçã', 'banana', 'laranja', 'manga'], tipo <class 'list'>
{'João': 25, 'Maria': 30, 'Pedro': 20, 'Marcos': 15}, tipo <class 'dict'>
João 25
Maria 30
Pedro 20
Marcos 15

Percebeu que os tipos estão corretos? Temos float, list e dict. Legal, né? Isto acontece porque a função json.load() já converte automaticamente os dados lidos para o formato Python correspondente.

8.4.3 Salvando em Pickle

Mas e se você quiser salvar suas variáveis Python exatamente como elas estão? Sem precisar converter em texto? É aí que entram os arquivos Pickle! 🥒

Imagine o Pickle como um pote de vidro na geladeira: você coloca a comida lá e ela fica preservada exatamente como você guardou. Quando você abre o pote depois, a comida está igualzinha!

O Pickle funciona assim: você “enfrasca” seus dados Python e depois pode “desenfrascar” eles quando precisar. É como ter uma geladeira mágica para suas variáveis!

Em termos técnicos: o Pickle converte seus objetos Python em bytes (código binário) que podem ser salvos em arquivo. Depois, você pode recuperar os objetos exatamente como eram antes!

Quer ver na prática? Vamos testar!

import pickle

# INÍCIO DO BLOCO 1
# salvar valor_pi em um arquivo pickle
with open("valor_pi.pickle", "wb") as f:
    pickle.dump(valor_pi, f)

# ler valor_pi de um arquivo pickle
with open("valor_pi.pickle", "rb") as f:
    valor_pi_lido = pickle.load(f)
    print(f'{valor_pi_lido}, tipo {type(valor_pi_lido)}')
# FIM DO BLOCO 1

# INÍCIO DO BLOCO 2
# salvar lista_frutas em um arquivo pickle
with open("lista_frutas.pickle", "wb") as f:
    pickle.dump(lista_frutas, f)

# ler lista_frutas de um arquivo pickle
with open("lista_frutas.pickle", "rb") as f:
    lista_frutas_lida = pickle.load(f)
    print(f'{lista_frutas_lida}, tipo {type(lista_frutas_lida)}')
# FIM DO BLOCO 2

# INÍCIO DO BLOCO 3
# salvar dicionario_pessoas em um arquivo pickle
with open("dicionario_pessoas.pickle", "wb") as f:
    pickle.dump(dicionario_pessoas, f)

# ler dicionario_pessoas de um arquivo pickle
with open("dicionario_pessoas.pickle", "rb") as f:
    dicionario_pessoas_lido = pickle.load(f)
    print(f'{dicionario_pessoas_lido}, tipo {type(dicionario_pessoas_lido)}')
    for nome, idade in dicionario_pessoas_lido.items():
        print(nome, idade)
# FIM DO BLOCO 3

Percebeu as diferenças? Vamos destacar o que mudou:

8.4.4 Principais Diferenças:

  • Modos de arquivo: Agora usamos "wb" (write binary) e "rb" (read binary) em vez de "w" e "r"
  • Funções: pickle.dump() para salvar e pickle.load() para carregar
  • Formato: Arquivos binários (se você abrir no Bloco de Notas, verá caracteres estranhos!)

8.4.5 JSON vs Pickle: Qual Escolher?

Situação Use Por quê?
Trocar dados entre programas JSON Todo mundo entende
Ler no Bloco de Notas JSON Texto legível
Salvar para uso só em Python Pickle Mais rápido e preserva tipos
Dados de fontes desconhecidas JSON Mais seguro

⚠️ Cuidado: Nunca abra arquivos Pickle de fontes desconhecidas! Eles podem conter código malicioso!

8.5 Exercícios Práticos (respostas no final da página)

Hora de praticar! Aqui estão 25 exercícios organizados por dificuldade. Cada exercício tem solução completa com explicação linha por linha!

8.5.1 MUITO FÁCIL (Nível 1)

1. Criar Arquivo de Texto Crie um arquivo de texto com seu nome e idade.

  • Exemplo: Input → "João Silva", "25 anos" | Output → Arquivo criado com sucesso!

2. Ler Arquivo de Texto Leia o arquivo criado no exercício 1 e mostre o conteúdo na tela.

  • Exemplo: Input → meus_dados.txt | Output → Nome: João Silva, Idade: 25 anos

3. Adicionar ao Arquivo Adicione sua cidade ao arquivo do exercício 1.

  • Exemplo: Input → "Cidade: São Paulo" | Output → Informação adicionada!

4. Salvar Lista em Texto Crie uma lista com 3 frutas e salve cada uma em uma linha do arquivo.

  • Exemplo: Input → ["maçã", "banana", "laranja"] | Output → Lista de frutas salva!

5. Ler e Mostrar Lista Leia o arquivo de frutas e mostre cada fruta em uma linha separada.

  • Exemplo: Input → frutas.txt | Output → - maçã, - banana, - laranja

8.5.2 FÁCIL (Nível 2)

6. Salvar Dicionário em JSON Crie um dicionário com nome e idade de uma pessoa e salve em JSON.

  • Exemplo: Input → {"nome": "Maria", "idade": 30} | Output → Dados salvos em JSON!

7. Ler Dicionário do JSON Leia o arquivo JSON do exercício 6 e mostre os dados.

  • Exemplo: Input → pessoa.json | Output → Nome: Maria, Idade: 30

8. Salvar Lista em Pickle Crie uma lista com números de 1 a 5 e salve em arquivo pickle.

  • Exemplo: Input → [1, 2, 3, 4, 5] | Output → Lista salva em pickle!

9. Ler Lista do Pickle Leia o arquivo pickle do exercício 8 e mostre a lista.

  • Exemplo: Input → numeros.pickle | Output → Lista carregada: [1, 2, 3, 4, 5], Tipo: <class 'list'>

10. Criar Arquivo com Input Peça para o usuário digitar uma frase e salve em arquivo.

  • Exemplo: Input → "Python é incrível!" | Output → Frase salva com sucesso!

8.5.3 MÉDIO (Nível 3)

11. Sistema de Cadastro em Arquivo Crie um sistema que cadastra pessoas em um arquivo de texto.

  • Exemplo: Input → 2 pessoas com nome e idade | Output → Pessoa cadastrada com sucesso!, Pessoa cadastrada com sucesso!

12. Ler e Processar Dados Leia o arquivo de pessoas e mostre os dados formatados.

  • Exemplo: Input → pessoas.txt | Output → LISTA DE PESSOAS: Nome: Ana, Idade: 25 anos, Nome: João, Idade: 30 anos

13. Salvar Múltiplas Listas em JSON Salve uma lista de nomes e uma lista de idades em um arquivo JSON.

  • Exemplo: Input → nomes: ["Ana", "João", "Maria"], idades: [25, 30, 28] | Output → Dados salvos em JSON!

14. Ler e Combinar Dados do JSON Leia o arquivo JSON do exercício 13 e combine nomes com idades.

  • Exemplo: Input → dados_pessoas.json | Output → PESSOAS CADASTRADAS: Ana tem 25 anos, João tem 30 anos, Maria tem 28 anos

15. Sistema de Backup Crie um backup de um arquivo copiando seu conteúdo para outro arquivo.

  • Exemplo: Input → pessoas.txt → pessoas_backup.txt | Output → Backup criado: pessoas_backup.txt

8.5.4 DIFÍCIL (Nível 4)

16. Sistema de Estoque com Arquivos Crie um sistema de estoque que salva produtos em JSON.

  • Exemplo: Input → produto: "Notebook", preço: 2500.00, quantidade: 5 | Output → Produto adicionado!, ESTOQUE: Notebook: R$ 2500.00 - 5 unidades

17. Sistema de Login com Arquivos Crie um sistema simples de login que salva usuários em arquivo.

  • Exemplo: Input → cadastrar: "admin", "123", login: "admin", "123" | Output → Usuário cadastrado!, Login realizado com sucesso!

18. Sistema de Notas Escolares Crie um sistema que gerencia notas de alunos em arquivo.

  • Exemplo: Input → aluno: "João", matéria: "Matemática", nota: 8.5 | Output → Nota adicionada!, Média de João: 8.50

19. Sistema de Agenda Telefônica Crie uma agenda telefônica que salva contatos em arquivo.

  • Exemplo: Input → nome: "Ana", telefone: "11999999999", email: "ana@email.com" | Output → Contato adicionado!, Nome: Ana, Telefone: 11999999999, Email: ana@email.com

20. Sistema de Vendas Crie um sistema de vendas que salva transações em arquivo.

  • Exemplo: Input → produto: "Mouse", quantidade: 2, preço: 50.00 | Output → Venda registrada! Total: R$ 100.00, RELATÓRIO DE VENDAS: Mouse: 2x R$ 50.00 = R$ 100.00

8.5.5 MUITO DIFÍCIL (Nível 5)

21. Sistema Completo de Biblioteca Crie um sistema completo de biblioteca com livros e empréstimos.

  • Exemplo: Input → adicionar livro, emprestar livro | Output → Livro adicionado!, Livro emprestado para João. Devolução: 15/01/2024, EMPRÉSTIMOS ATIVOS: Usuário: João, ISBN: 123, Devolução: 15/01/2024

22. Sistema de Backup Automático Crie um sistema que faz backup automático de múltiplos arquivos.

  • Exemplo: Input → configurar arquivos, fazer backup | Output → Configuração salva!, Backup concluído! 3 arquivos salvos em backups/backup_20240101_120000

23. Sistema de Log de Atividades Crie um sistema que registra todas as atividades em arquivo de log.

  • Exemplo: Input → registrar: "Usuário fez login", "João" | Output → Atividade registrada: Usuário fez login, LOG DE ATIVIDADES: [01/01/2024 12:00:00] João: Usuário fez login

24. Sistema de Configurações Crie um sistema que gerencia configurações de aplicação em arquivo.

  • Exemplo: Input → alterar tema para "escuro", tamanho_fonte para 14 | Output → Configuração 'tema' alterada para 'escuro', Configuração 'tamanho_fonte' alterada para '14'

25. Sistema de Criptografia de Arquivos Crie um sistema que criptografa e descriptografa arquivos de texto.

  • Exemplo: Input → criptografar teste.txt, descriptografar teste_criptografado.txt | Output → Arquivo criptografado: teste_criptografado.txt, Arquivo descriptografado: teste_descriptografado.txt

8.6 Respostas e Explicações

8.6.1 MUITO FÁCIL (Nível 1)

1. Criar Arquivo de Texto

with open("meus_dados.txt", "w") as arquivo:
    arquivo.write("Nome: João Silva\n")
    arquivo.write("Idade: 25 anos\n")

print("Arquivo criado com sucesso!")

Explicação linha por linha:

  • Linha 1: with open("meus_dados.txt", "w") as arquivo: - Abre arquivo para escrita usando with para fechamento automático
  • Linha 2: arquivo.write("Nome: João Silva\n") - Escreve nome com quebra de linha ()
  • Linha 3: arquivo.write("Idade: 25 anos\n") - Escreve idade com quebra de linha
  • Linha 5: print("Arquivo criado com sucesso!") - Confirma criação do arquivo

2. Ler Arquivo de Texto

with open("meus_dados.txt", "r") as arquivo:
    conteudo = arquivo.read()
    print(conteudo)

Explicação linha por linha:

  • Linha 1: with open("meus_dados.txt", "r") as arquivo: - Abre arquivo para leitura usando with
  • Linha 2: conteudo = arquivo.read() - Lê todo o conteúdo do arquivo e armazena na variável
  • Linha 3: print(conteudo) - Mostra o conteúdo lido na tela

3. Adicionar ao Arquivo

with open("meus_dados.txt", "a") as arquivo:
    arquivo.write("Cidade: São Paulo\n")

print("Informação adicionada!")

Explicação linha por linha:

  • Linha 1: with open("meus_dados.txt", "a") as arquivo: - Abre arquivo em modo append (adicionar) sem apagar conteúdo existente
  • Linha 2: arquivo.write("Cidade: São Paulo\n") - Adiciona cidade no final do arquivo
  • Linha 4: print("Informação adicionada!") - Confirma que a informação foi adicionada

4. Salvar Lista em Texto

frutas = ["maçã", "banana", "laranja"]

with open("frutas.txt", "w") as arquivo:
    for fruta in frutas:
        arquivo.write(fruta + "\n")

print("Lista de frutas salva!")

Explicação linha por linha:

  • Linha 1: frutas = ["maçã", "banana", "laranja"] - Cria lista com 3 frutas
  • Linha 3: with open("frutas.txt", "w") as arquivo: - Abre arquivo para escrita
  • Linha 4: for fruta in frutas: - Percorre cada fruta da lista
  • Linha 5: arquivo.write(fruta + "\n") - Escreve cada fruta em uma linha separada
  • Linha 7: print("Lista de frutas salva!") - Confirma que a lista foi salva

5. Ler e Mostrar Lista

with open("frutas.txt", "r") as arquivo:
    linhas = arquivo.readlines()
    
for linha in linhas:
    print(f"- {linha.strip()}")

Explicação linha por linha:

  • Linha 1: with open("frutas.txt", "r") as arquivo: - Abre arquivo para leitura
  • Linha 2: linhas = arquivo.readlines() - Lê todas as linhas do arquivo em uma lista
  • Linha 4: for linha in linhas: - Percorre cada linha lida
  • Linha 5: print(f"- {linha.strip()}") - Remove espaços em branco e mostra fruta formatada

8.6.2 FÁCIL (Nível 2)

6. Salvar Dicionário em JSON

import json

pessoa = {
    "nome": "Maria",
    "idade": 30
}

with open("pessoa.json", "w") as arquivo:
    json.dump(pessoa, arquivo)

print("Dados salvos em JSON!")

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linhas 3-6: Cria dicionário com dados da pessoa (nome e idade)
  • Linha 8: with open("pessoa.json", "w") as arquivo: - Abre arquivo para escrita
  • Linha 9: json.dump(pessoa, arquivo) - Salva dicionário em formato JSON usando função dump()
  • Linha 11: print("Dados salvos em JSON!") - Confirma que os dados foram salvos

7. Ler Dicionário do JSON

import json

with open("pessoa.json", "r") as arquivo:
    dados = json.load(arquivo)

print(f"Nome: {dados['nome']}")
print(f"Idade: {dados['idade']}")

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 3: with open("pessoa.json", "r") as arquivo: - Abre arquivo JSON para leitura
  • Linha 4: dados = json.load(arquivo) - Carrega dados do arquivo JSON usando função load()
  • Linha 6: print(f"Nome: {dados['nome']}") - Mostra nome acessando chave do dicionário
  • Linha 7: print(f"Idade: {dados['idade']}") - Mostra idade acessando chave do dicionário

8. Salvar Lista em Pickle

import pickle

numeros = [1, 2, 3, 4, 5]

with open("numeros.pickle", "wb") as arquivo:
    pickle.dump(numeros, arquivo)

print("Lista salva em pickle!")

Explicação linha por linha:

  • Linha 1: import pickle - Importa módulo pickle para trabalhar com arquivos binários
  • Linha 3: numeros = [1, 2, 3, 4, 5] - Cria lista com números de 1 a 5
  • Linha 5: with open("numeros.pickle", "wb") as arquivo: - Abre arquivo binário para escrita (wb = write binary)
  • Linha 6: pickle.dump(numeros, arquivo) - Salva lista em formato pickle usando função dump()
  • Linha 8: print("Lista salva em pickle!") - Confirma que a lista foi salva

9. Ler Lista do Pickle

import pickle

with open("numeros.pickle", "rb") as arquivo:
    numeros = pickle.load(arquivo)

print(f"Lista carregada: {numeros}")
print(f"Tipo: {type(numeros)}")

Explicação linha por linha:

  • Linha 1: import pickle - Importa módulo pickle para trabalhar com arquivos binários
  • Linha 3: with open("numeros.pickle", "rb") as arquivo: - Abre arquivo binário para leitura (rb = read binary)
  • Linha 4: numeros = pickle.load(arquivo) - Carrega lista do arquivo pickle usando função load()
  • Linha 6: print(f"Lista carregada: {numeros}") - Mostra lista carregada
  • Linha 7: print(f"Tipo: {type(numeros)}") - Mostra tipo da variável (deve ser <class ‘list’>)

10. Criar Arquivo com Input

frase = input("Digite uma frase: ")

with open("frase_usuario.txt", "w") as arquivo:
    arquivo.write(frase)

print("Frase salva com sucesso!")

Explicação linha por linha:

  • Linha 1: frase = input("Digite uma frase: ") - Solicita frase ao usuário usando função input()
  • Linha 3: with open("frase_usuario.txt", "w") as arquivo: - Abre arquivo para escrita
  • Linha 4: arquivo.write(frase) - Escreve a frase digitada pelo usuário no arquivo
  • Linha 6: print("Frase salva com sucesso!") - Confirma que a frase foi salva com sucesso

8.6.3 MÉDIO (Nível 3)

11. Sistema de Cadastro em Arquivo

def cadastrar_pessoa():
    nome = input("Digite o nome: ")
    idade = input("Digite a idade: ")
    
    with open("pessoas.txt", "a") as arquivo:
        arquivo.write(f"{nome},{idade}\n")
    
    print("Pessoa cadastrada com sucesso!")

# Exemplo de uso
cadastrar_pessoa()
cadastrar_pessoa()

Explicação linha por linha:

  • Linha 1: def cadastrar_pessoa(): - Define função para cadastrar pessoa
  • Linha 2: nome = input("Digite o nome: ") - Solicita nome ao usuário
  • Linha 3: idade = input("Digite a idade: ") - Solicita idade ao usuário
  • Linha 5: with open("pessoas.txt", "a") as arquivo: - Abre arquivo em modo append para adicionar dados
  • Linha 6: arquivo.write(f"{nome},{idade}\n") - Escreve dados separados por vírgula com quebra de linha
  • Linha 8: print("Pessoa cadastrada com sucesso!") - Confirma que pessoa foi cadastrada

12. Ler e Processar Dados

with open("pessoas.txt", "r") as arquivo:
    linhas = arquivo.readlines()

print("=== LISTA DE PESSOAS ===")
for linha in linhas:
    dados = linha.strip().split(",")
    nome = dados[0]
    idade = dados[1]
    print(f"Nome: {nome}, Idade: {idade} anos")

Explicação linha por linha:

  • Linha 1: with open("pessoas.txt", "r") as arquivo: - Abre arquivo para leitura
  • Linha 2: linhas = arquivo.readlines() - Lê todas as linhas do arquivo em uma lista
  • Linha 4: print("=== LISTA DE PESSOAS ===") - Imprime cabeçalho formatado
  • Linha 5: for linha in linhas: - Percorre cada linha do arquivo
  • Linha 6: dados = linha.strip().split(",") - Remove espaços em branco e separa dados por vírgula
  • Linha 7: nome = dados[0] - Extrai nome (primeiro elemento da lista)
  • Linha 8: idade = dados[1] - Extrai idade (segundo elemento da lista)
  • Linha 9: print(f"Nome: {nome}, Idade: {idade} anos") - Mostra dados formatados

13. Salvar Múltiplas Listas em JSON

import json

nomes = ["Ana", "João", "Maria"]
idades = [25, 30, 28]

dados = {
    "nomes": nomes,
    "idades": idades
}

with open("dados_pessoas.json", "w") as arquivo:
    json.dump(dados, arquivo)

print("Dados salvos em JSON!")

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 3: nomes = ["Ana", "João", "Maria"] - Cria lista com nomes de pessoas
  • Linha 4: idades = [25, 30, 28] - Cria lista com idades correspondentes
  • Linhas 6-9: Cria dicionário organizando as duas listas com chaves descritivas
  • Linha 11: with open("dados_pessoas.json", "w") as arquivo: - Abre arquivo para escrita
  • Linha 12: json.dump(dados, arquivo) - Salva dicionário em formato JSON usando função dump()
  • Linha 14: print("Dados salvos em JSON!") - Confirma que os dados foram salvos

14. Ler e Combinar Dados do JSON

import json

with open("dados_pessoas.json", "r") as arquivo:
    dados = json.load(arquivo)

nomes = dados["nomes"]
idades = dados["idades"]

print("=== PESSOAS CADASTRADAS ===")
for i in range(len(nomes)):
    print(f"{nomes[i]} tem {idades[i]} anos")

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 3: with open("dados_pessoas.json", "r") as arquivo: - Abre arquivo JSON para leitura
  • Linha 4: dados = json.load(arquivo) - Carrega dados do arquivo JSON usando função load()
  • Linha 6: nomes = dados["nomes"] - Extrai lista de nomes do dicionário carregado
  • Linha 7: idades = dados["idades"] - Extrai lista de idades do dicionário carregado
  • Linha 9: print("=== PESSOAS CADASTRADAS ===") - Imprime cabeçalho formatado
  • Linha 10: for i in range(len(nomes)): - Percorre índices das listas usando range()
  • Linha 11: print(f"{nomes[i]} tem {idades[i]} anos") - Combina nome e idade usando índice

15. Sistema de Backup

def fazer_backup(arquivo_original, arquivo_backup):
    with open(arquivo_original, "r") as original:
        conteudo = original.read()
    
    with open(arquivo_backup, "w") as backup:
        backup.write(conteudo)
    
    print(f"Backup criado: {arquivo_backup}")

# Exemplo de uso
fazer_backup("pessoas.txt", "pessoas_backup.txt")

Explicação linha por linha:

  • Linha 1: def fazer_backup(arquivo_original, arquivo_backup): - Define função para criar backup de arquivo
  • Linha 2: with open(arquivo_original, "r") as original: - Abre arquivo original para leitura
  • Linha 3: conteudo = original.read() - Lê todo o conteúdo do arquivo original
  • Linha 5: with open(arquivo_backup, "w") as backup: - Abre arquivo backup para escrita
  • Linha 6: backup.write(conteudo) - Escreve conteúdo lido no arquivo backup
  • Linha 8: print(f"Backup criado: {arquivo_backup}") - Confirma que backup foi criado com nome do arquivo

8.6.4 DIFÍCIL (Nível 4)

16. Sistema de Estoque com Arquivos

import json

def adicionar_produto():
    nome = input("Nome do produto: ")
    preco = float(input("Preço: "))
    quantidade = int(input("Quantidade: "))
    
    produto = {
        "nome": nome,
        "preco": preco,
        "quantidade": quantidade
    }
    
    try:
        with open("estoque.json", "r") as arquivo:
            estoque = json.load(arquivo)
    except FileNotFoundError:
        estoque = []
    
    estoque.append(produto)
    
    with open("estoque.json", "w") as arquivo:
        json.dump(estoque, arquivo)
    
    print("Produto adicionado!")

def listar_estoque():
    try:
        with open("estoque.json", "r") as arquivo:
            estoque = json.load(arquivo)
        
        print("=== ESTOQUE ===")
        for produto in estoque:
            print(f"{produto['nome']}: R$ {produto['preco']:.2f} - {produto['quantidade']} unidades")
    except FileNotFoundError:
        print("Estoque vazio!")

# Exemplo de uso
adicionar_produto()
listar_estoque()

Explicação linha NOTA: Este exercício é muito longo, vou continuar com as respostas dos exercícios 17-25 na próxima célula para manter o tamanho adequado.

17. Sistema de Login com Arquivos

import json

def cadastrar_usuario():
    usuario = input("Nome de usuário: ")
    senha = input("Senha: ")
    
    try:
        with open("usuarios.json", "r") as arquivo:
            usuarios = json.load(arquivo)
    except FileNotFoundError:
        usuarios = {}
    
    usuarios[usuario] = senha
    
    with open("usuarios.json", "w") as arquivo:
        json.dump(usuarios, arquivo)
    
    print("Usuário cadastrado!")

def fazer_login():
    usuario = input("Usuário: ")
    senha = input("Senha: ")
    
    try:
        with open("usuarios.json", "r") as arquivo:
            usuarios = json.load(arquivo)
        
        if usuario in usuarios and usuarios[usuario] == senha:
            print("Login realizado com sucesso!")
        else:
            print("Usuário ou senha incorretos!")
    except FileNotFoundError:
        print("Nenhum usuário cadastrado!")

# Exemplo de uso
cadastrar_usuario()
fazer_login()

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 3: def cadastrar_usuario(): - Define função para cadastrar novo usuário
  • Linhas 4-5: Solicita nome de usuário e senha ao usuário
  • Linhas 7-10: Tenta carregar usuários existentes ou cria dicionário vazio se arquivo não existir
  • Linha 12: usuarios[usuario] = senha - Adiciona usuário e senha ao dicionário
  • Linhas 14-15: Salva dicionário de usuários em arquivo JSON
  • Linha 17: print("Usuário cadastrado!") - Confirma que usuário foi cadastrado

18. Sistema de Notas Escolares

import json

def adicionar_nota():
    aluno = input("Nome do aluno: ")
    materia = input("Matéria: ")
    nota = float(input("Nota: "))
    
    try:
        with open("notas.json", "r") as arquivo:
            notas = json.load(arquivo)
    except FileNotFoundError:
        notas = {}
    
    if aluno not in notas:
        notas[aluno] = {}
    
    notas[aluno][materia] = nota
    
    with open("notas.json", "w") as arquivo:
        json.dump(notas, arquivo)
    
    print("Nota adicionada!")

def calcular_media(aluno):
    try:
        with open("notas.json", "r") as arquivo:
            notas = json.load(arquivo)
        
        if aluno in notas:
            notas_aluno = notas[aluno]
            media = sum(notas_aluno.values()) / len(notas_aluno)
            print(f"Média de {aluno}: {media:.2f}")
        else:
            print("Aluno não encontrado!")
    except FileNotFoundError:
        print("Nenhuma nota cadastrada!")

# Exemplo de uso
adicionar_nota()
calcular_media("João")

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 3: def adicionar_nota(): - Define função para adicionar nota de aluno
  • Linhas 4-6: Solicita dados da nota (aluno, matéria, nota)
  • Linhas 8-11: Carrega notas existentes ou cria dicionário vazio se arquivo não existir
  • Linhas 13-14: Cria estrutura para aluno se não existir no dicionário
  • Linha 16: notas[aluno][materia] = nota - Adiciona nota para aluno e matéria específicos
  • Linhas 18-19: Salva notas atualizadas em arquivo JSON

19. Sistema de Agenda Telefônica

import json

def adicionar_contato():
    nome = input("Nome: ")
    telefone = input("Telefone: ")
    email = input("Email: ")
    
    contato = {
        "telefone": telefone,
        "email": email
    }
    
    try:
        with open("agenda.json", "r") as arquivo:
            agenda = json.load(arquivo)
    except FileNotFoundError:
        agenda = {}
    
    agenda[nome] = contato
    
    with open("agenda.json", "w") as arquivo:
        json.dump(agenda, arquivo)
    
    print("Contato adicionado!")

def buscar_contato():
    nome = input("Nome para buscar: ")
    
    try:
        with open("agenda.json", "r") as arquivo:
            agenda = json.load(arquivo)
        
        if nome in agenda:
            contato = agenda[nome]
            print(f"Nome: {nome}")
            print(f"Telefone: {contato['telefone']}")
            print(f"Email: {contato['email']}")
        else:
            print("Contato não encontrado!")
    except FileNotFoundError:
        print("Agenda vazia!")

# Exemplo de uso
adicionar_contato()
buscar_contato()

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 3: def adicionar_contato(): - Define função para adicionar contato à agenda
  • Linhas 4-6: Solicita dados do contato (nome, telefone, email)
  • Linhas 8-11: Cria dicionário com informações do contato
  • Linhas 13-16: Carrega agenda existente ou cria dicionário vazio se arquivo não existir
  • Linha 18: agenda[nome] = contato - Adiciona contato à agenda usando nome como chave
  • Linhas 20-21: Salva agenda atualizada em arquivo JSON

20. Sistema de Vendas

import json
from datetime import datetime

def registrar_venda():
    produto = input("Produto vendido: ")
    quantidade = int(input("Quantidade: "))
    preco_unitario = float(input("Preço unitário: "))
    
    venda = {
        "produto": produto,
        "quantidade": quantidade,
        "preco_unitario": preco_unitario,
        "total": quantidade * preco_unitario,
        "data": datetime.now().strftime("%d/%m/%Y %H:%M")
    }
    
    try:
        with open("vendas.json", "r") as arquivo:
            vendas = json.load(arquivo)
    except FileNotFoundError:
        vendas = []
    
    vendas.append(venda)
    
    with open("vendas.json", "w") as arquivo:
        json.dump(vendas, arquivo)
    
    print(f"Venda registrada! Total: R$ {venda['total']:.2f}")

def relatorio_vendas():
    try:
        with open("vendas.json", "r") as arquivo:
            vendas = json.load(arquivo)
        
        print("=== RELATÓRIO DE VENDAS ===")
        total_geral = 0
        
        for venda in vendas:
            print(f"{venda['data']} - {venda['produto']}: {venda['quantidade']}x R$ {venda['preco_unitario']:.2f} = R$ {venda['total']:.2f}")
            total_geral += venda['total']
        
        print(f"\nTotal Geral: R$ {total_geral:.2f}")
    except FileNotFoundError:
        print("Nenhuma venda registrada!")

# Exemplo de uso
registrar_venda()
relatorio_vendas()

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 2: from datetime import datetime - Importa função datetime para registrar data/hora
  • Linha 4: def registrar_venda(): - Define função para registrar nova venda
  • Linhas 5-7: Solicita dados da venda (produto, quantidade, preço)
  • Linhas 9-15: Cria dicionário com dados da venda incluindo total calculado e data atual
  • Linhas 17-20: Carrega vendas existentes ou cria lista vazia se arquivo não existir
  • Linha 22: vendas.append(venda) - Adiciona nova venda à lista de vendas
  • Linhas 24-25: Salva lista de vendas atualizada em arquivo JSON

8.6.5 MUITO DIFÍCIL (Nível 5)

21. Sistema Completo de Biblioteca

import json
from datetime import datetime, timedelta

class Biblioteca:
    def __init__(self):
        self.arquivo_livros = "livros.json"
        self.arquivo_emprestimos = "emprestimos.json"
    
    def adicionar_livro(self):
        titulo = input("Título do livro: ")
        autor = input("Autor: ")
        isbn = input("ISBN: ")
        
        livro = {
            "titulo": titulo,
            "autor": autor,
            "isbn": isbn,
            "disponivel": True
        }
        
        try:
            with open(self.arquivo_livros, "r") as arquivo:
                livros = json.load(arquivo)
        except FileNotFoundError:
            livros = []
        
        livros.append(livro)
        
        with open(self.arquivo_livros, "w") as arquivo:
            json.dump(livros, arquivo)
        
        print("Livro adicionado!")
    
    def emprestar_livro(self):
        isbn = input("ISBN do livro: ")
        usuario = input("Nome do usuário: ")
        
        try:
            with open(self.arquivo_livros, "r") as arquivo:
                livros = json.load(arquivo)
            
            livro_encontrado = None
            for livro in livros:
                if livro["isbn"] == isbn and livro["disponivel"]:
                    livro_encontrado = livro
                    break
            
            if livro_encontrado:
                livro_encontrado["disponivel"] = False
                
                emprestimo = {
                    "isbn": isbn,
                    "usuario": usuario,
                    "data_emprestimo": datetime.now().strftime("%d/%m/%Y"),
                    "data_devolucao": (datetime.now() + timedelta(days=7)).strftime("%d/%m/%Y")
                }
                
                try:
                    with open(self.arquivo_emprestimos, "r") as arquivo:
                        emprestimos = json.load(arquivo)
                except FileNotFoundError:
                    emprestimos = []
                
                emprestimos.append(emprestimo)
                
                with open(self.arquivo_livros, "w") as arquivo:
                    json.dump(livros, arquivo)
                
                with open(self.arquivo_emprestimos, "w") as arquivo:
                    json.dump(emprestimos, arquivo)
                
                print(f"Livro emprestado para {usuario}. Devolução: {emprestimo['data_devolucao']}")
            else:
                print("Livro não disponível!")
        except FileNotFoundError:
            print("Nenhum livro cadastrado!")
    
    def listar_emprestimos(self):
        try:
            with open(self.arquivo_emprestimos, "r") as arquivo:
                emprestimos = json.load(arquivo)
            
            print("=== EMPRÉSTIMOS ATIVOS ===")
            for emprestimo in emprestimos:
                print(f"Usuário: {emprestimo['usuario']}, ISBN: {emprestimo['isbn']}, Devolução: {emprestimo['data_devolucao']}")
        except FileNotFoundError:
            print("Nenhum empréstimo ativo!")

# Exemplo de uso
biblioteca = Biblioteca()
biblioteca.adicionar_livro()
biblioteca.emprestar_livro()
biblioteca.listar_emprestimos()

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 2: from datetime import datetime, timedelta - Importa funções de data e tempo para calcular datas
  • Linha 4: class Biblioteca: - Define classe para gerenciar sistema de biblioteca
  • Linhas 5-7: Define nomes dos arquivos para livros e empréstimos
  • Linha 9: def adicionar_livro(self): - Método para adicionar novo livro ao acervo
  • Linhas 10-12: Solicita dados do livro (título, autor, ISBN)
  • Linhas 14-18: Cria dicionário com dados do livro incluindo status de disponibilidade
  • Linhas 20-23: Carrega livros existentes ou cria lista vazia se arquivo não existir
  • Linha 25: livros.append(livro) - Adiciona novo livro à lista de livros
  • Linhas 27-28: Salva lista atualizada de livros em arquivo JSON

22. Sistema de Backup Automático

import json
import shutil
from datetime import datetime
import os

class SistemaBackup:
    def __init__(self):
        self.arquivos_config = "config_backup.json"
        self.pasta_backup = "backups"
        
        if not os.path.exists(self.pasta_backup):
            os.makedirs(self.pasta_backup)
    
    def configurar_backup(self):
        arquivos = []
        
        while True:
            arquivo = input("Arquivo para backup (ou 'fim' para terminar): ")
            if arquivo.lower() == 'fim':
                break
            if os.path.exists(arquivo):
                arquivos.append(arquivo)
            else:
                print(f"Arquivo {arquivo} não encontrado!")
        
        config = {
            "arquivos": arquivos,
            "ultimo_backup": None
        }
        
        with open(self.arquivos_config, "w") as arquivo:
            json.dump(config, arquivo)
        
        print("Configuração salva!")
    
    def fazer_backup(self):
        try:
            with open(self.arquivos_config, "r") as arquivo:
                config = json.load(arquivo)
        except FileNotFoundError:
            print("Configure primeiro os arquivos para backup!")
            return
        
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        pasta_backup_atual = os.path.join(self.pasta_backup, f"backup_{timestamp}")
        
        if not os.path.exists(pasta_backup_atual):
            os.makedirs(pasta_backup_atual)
        
        arquivos_backup = 0
        for arquivo in config["arquivos"]:
            try:
                nome_arquivo = os.path.basename(arquivo)
                destino = os.path.join(pasta_backup_atual, nome_arquivo)
                shutil.copy2(arquivo, destino)
                arquivos_backup += 1
                print(f"Backup: {arquivo} -> {destino}")
            except Exception as e:
                print(f"Erro ao fazer backup de {arquivo}: {e}")
        
        config["ultimo_backup"] = timestamp
        with open(self.arquivos_config, "w") as arquivo:
            json.dump(config, arquivo)
        
        print(f"Backup concluído! {arquivos_backup} arquivos salvos em {pasta_backup_atual}")

# Exemplo de uso
backup_system = SistemaBackup()
backup_system.configurar_backup()
backup_system.fazer_backup()

Explicação linha por linha:

  • Linhas 1-4: Importa módulos necessários (json, shutil, datetime, os)
  • Linha 6: class SistemaBackup: - Define classe para sistema de backup automático
  • Linhas 7-12: Define arquivos de configuração e pasta de backup, criando pasta se não existir
  • Linha 14: def configurar_backup(self): - Método para configurar arquivos que serão incluídos no backup
  • Linhas 15-24: Loop para solicitar arquivos e validar sua existência
  • Linhas 26-32: Salva configuração em arquivo JSON
  • Linha 34: def fazer_backup(self): - Método para executar backup dos arquivos configurados

23. Sistema de Log de Atividades

import json
from datetime import datetime

class SistemaLog:
    def __init__(self):
        self.arquivo_log = "atividades.log"
    
    def registrar_atividade(self, atividade, usuario="Sistema"):
        timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
        
        log_entry = {
            "timestamp": timestamp,
            "usuario": usuario,
            "atividade": atividade
        }
        
        with open(self.arquivo_log, "a") as arquivo:
            arquivo.write(f"[{timestamp}] {usuario}: {atividade}\n")
        
        print(f"Atividade registrada: {atividade}")
    
    def consultar_log(self, usuario=None):
        try:
            with open(self.arquivo_log, "r") as arquivo:
                linhas = arquivo.readlines()
            
            print("=== LOG DE ATIVIDADES ===")
            for linha in linhas:
                if usuario is None or usuario in linha:
                    print(linha.strip())
        except FileNotFoundError:
            print("Nenhuma atividade registrada!")
    
    def estatisticas(self):
        try:
            with open(self.arquivo_log, "r") as arquivo:
                linhas = arquivo.readlines()
            
            usuarios = {}
            atividades_hoje = 0
            hoje = datetime.now().strftime("%d/%m/%Y")
            
            for linha in linhas:
                if hoje in linha:
                    atividades_hoje += 1
                
                for usuario in usuarios:
                    if usuario in linha:
                        usuarios[usuario] += 1
            
            print("=== ESTATÍSTICAS ===")
            print(f"Atividades hoje: {atividades_hoje}")
            print(f"Total de atividades: {len(linhas)}")
            
        except FileNotFoundError:
            print("Nenhuma atividade registrada!")

# Exemplo de uso
log_system = SistemaLog()
log_system.registrar_atividade("Usuário fez login", "João")
log_system.registrar_atividade("Arquivo criado", "Maria")
log_system.consultar_log()
log_system.estatisticas()

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 2: from datetime import datetime - Importa função datetime para registrar timestamps
  • Linha 4: class SistemaLog: - Define classe para sistema de log de atividades
  • Linhas 5-6: Define arquivo de log onde as atividades serão registradas
  • Linha 8: def registrar_atividade(self, atividade, usuario="Sistema"): - Método para registrar nova atividade
  • Linha 9: timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S") - Gera timestamp atual formatado
  • Linhas 11-15: Cria dicionário com dados da atividade (timestamp, usuário, atividade)
  • Linhas 17-18: Escreve atividade no arquivo de log em formato texto legível
  • Linha 20: print(f"Atividade registrada: {atividade}") - Confirma que atividade foi registrada

24. Sistema de Configurações

import json
import os

class GerenciadorConfig:
    def __init__(self):
        self.arquivo_config = "config.json"
        self.config_padrao = {
            "tema": "claro",
            "idioma": "pt-BR",
            "tamanho_fonte": 12,
            "salvar_automatico": True,
            "backup_automatico": False,
            "ultima_atualizacao": None
        }
    
    def carregar_config(self):
        try:
            with open(self.arquivo_config, "r") as arquivo:
                config = json.load(arquivo)
            
            # Mescla com configurações padrão
            for chave, valor in self.config_padrao.items():
                if chave not in config:
                    config[chave] = valor
            
            return config
        except FileNotFoundError:
            return self.config_padrao.copy()
    
    def salvar_config(self, config):
        config["ultima_atualizacao"] = "2024-01-01"  # Simula data atual
        
        with open(self.arquivo_config, "w") as arquivo:
            json.dump(config, arquivo, indent=2)
        
        print("Configurações salvas!")
    
    def alterar_config(self, chave, valor):
        config = self.carregar_config()
        
        if chave in config:
            config[chave] = valor
            self.salvar_config(config)
            print(f"Configuração '{chave}' alterada para '{valor}'")
        else:
            print(f"Configuração '{chave}' não encontrada!")
    
    def mostrar_config(self):
        config = self.carregar_config()
        
        print("=== CONFIGURAÇÕES ATUAIS ===")
        for chave, valor in config.items():
            print(f"{chave}: {valor}")
    
    def resetar_config(self):
        config = self.config_padrao.copy()
        self.salvar_config(config)
        print("Configurações resetadas para padrão!")

# Exemplo de uso
config_manager = GerenciadorConfig()
config_manager.mostrar_config()
config_manager.alterar_config("tema", "escuro")
config_manager.alterar_config("tamanho_fonte", 14)
config_manager.mostrar_config()

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 2: import os - Importa módulo os para operações do sistema operacional
  • Linha 4: class GerenciadorConfig: - Define classe para gerenciar configurações de aplicação
  • Linhas 5-14: Define arquivo de configuração e configurações padrão da aplicação
  • Linha 16: def carregar_config(self): - Método para carregar configurações do arquivo
  • Linhas 17-22: Tenta carregar configurações existentes do arquivo JSON
  • Linhas 24-26: Mescla configurações carregadas com padrões para garantir completude
  • Linha 28: return self.config_padrao.copy() - Retorna configurações padrão se arquivo não existir

25. Sistema de Criptografia de Arquivos

import json
import base64

class CriptografadorArquivos:
    def __init__(self):
        self.arquivo_chaves = "chaves.json"
        self.chaves = self.carregar_chaves()
    
    def carregar_chaves(self):
        try:
            with open(self.arquivo_chaves, "r") as arquivo:
                return json.load(arquivo)
        except FileNotFoundError:
            return {}
    
    def salvar_chaves(self):
        with open(self.arquivo_chaves, "w") as arquivo:
            json.dump(self.chaves, arquivo)
    
    def gerar_chave(self, nome_arquivo):
        import random
        import string
        
        chave = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
        self.chaves[nome_arquivo] = chave
        self.salvar_chaves()
        return chave
    
    def criptografar_arquivo(self, arquivo_original, arquivo_criptografado):
        if arquivo_original not in self.chaves:
            chave = self.gerar_chave(arquivo_original)
        else:
            chave = self.chaves[arquivo_original]
        
        try:
            with open(arquivo_original, "r") as arquivo:
                conteudo = arquivo.read()
            
            # Criptografia simples (XOR com chave)
            conteudo_bytes = conteudo.encode('utf-8')
            chave_bytes = chave.encode('utf-8')
            
            criptografado = bytearray()
            for i, byte in enumerate(conteudo_bytes):
                criptografado.append(byte ^ chave_bytes[i % len(chave_bytes)])
            
            conteudo_criptografado = base64.b64encode(criptografado).decode('utf-8')
            
            with open(arquivo_criptografado, "w") as arquivo:
                arquivo.write(conteudo_criptografado)
            
            print(f"Arquivo criptografado: {arquivo_criptografado}")
        except FileNotFoundError:
            print(f"Arquivo {arquivo_original} não encontrado!")
    
    def descriptografar_arquivo(self, arquivo_criptografado, arquivo_descriptografado):
        nome_original = arquivo_criptografado.replace("_criptografado", "")
        
        if nome_original not in self.chaves:
            print("Chave não encontrada para descriptografar!")
            return
        
        chave = self.chaves[nome_original]
        
        try:
            with open(arquivo_criptografado, "r") as arquivo:
                conteudo_criptografado = arquivo.read()
            
            # Descriptografia
            criptografado_bytes = base64.b64decode(conteudo_criptografado.encode('utf-8'))
            chave_bytes = chave.encode('utf-8')
            
            descriptografado = bytearray()
            for i, byte in enumerate(criptografado_bytes):
                descriptografado.append(byte ^ chave_bytes[i % len(chave_bytes)])
            
            conteudo_descriptografado = descriptografado.decode('utf-8')
            
            with open(arquivo_descriptografado, "w") as arquivo:
                arquivo.write(conteudo_descriptografado)
            
            print(f"Arquivo descriptografado: {arquivo_descriptografado}")
        except FileNotFoundError:
            print(f"Arquivo {arquivo_criptografado} não encontrado!")
        except Exception as e:
            print(f"Erro ao descriptografar: {e}")

# Exemplo de uso
criptografador = CriptografadorArquivos()

# Criar arquivo de teste
with open("teste.txt", "w") as arquivo:
    arquivo.write("Este é um arquivo de teste para criptografia!")

# Criptografar
criptografador.criptografar_arquivo("teste.txt", "teste_criptografado.txt")

# Descriptografar
criptografador.descriptografar_arquivo("teste_criptografado.txt", "teste_descriptografado.txt")

Explicação linha por linha:

  • Linha 1: import json - Importa módulo json para trabalhar com arquivos JSON
  • Linha 2: import base64 - Importa módulo base64 para codificação de dados binários
  • Linha 4: class CriptografadorArquivos: - Define classe para sistema de criptografia de arquivos
  • Linhas 5-7: Define arquivo para armazenar chaves de criptografia e carrega chaves existentes
  • Linha 9: def carregar_chaves(self): - Método para carregar chaves de criptografia do arquivo
  • Linha 16: def gerar_chave(self, nome_arquivo): - Método para gerar chave aleatória de criptografia
  • Linhas 17-18: Importa módulos random e string para gerar chave aleatória
  • Linha 20: chave = ''.join(random.choices(string.ascii_letters + string.digits, k=16)) - Gera chave de 16 caracteres alfanuméricos
  • Linha 24: def criptografar_arquivo(self, arquivo_original, arquivo_criptografado): - Método para criptografar arquivo

🎯 Parabéns! Você completou todos os exercícios de manipulação de arquivos! Agora você domina como trabalhar com arquivos em Python, incluindo texto, JSON e Pickle. Continue praticando e explore mais possibilidades!

8.6.6 Respostas

1. Crie um dicionário com o nome e a profissão de duas pessoas e adicione uma terceira pessoa com nome e profissão. Salve o resultado em um arquivo JSON.

Você deve ter percebido que é praticamente o mesmo exercício do capítulo anterior, mas com um passo final para salvar o resultado em JSON, não é? Veja só como ficaria um exemplo de resposta:

import json

pessoas = {}

# adiciona as duas primeiras pessoas
for i in range(2):
    nome = input("Digite o nome da pessoa: ")
    profissao = input("Digite a profissão da pessoa: ")
    pessoas[nome] = profissao

# adiciona a terceira pessoa
nome = input("Digite o nome da terceira pessoa: ")
profissao = input("Digite a profissão da terceira pessoa: ")
pessoas[nome] = profissao

# salva o resultado em um arquivo JSON
with open("pessoas.json", "w") as arquivo:
    json.dump(pessoas, arquivo)

O que temos de diferente neste código? Veja que, primeiramente, importamos a biblioteca json na primeira linha do Python para salvar o dicionário pessoas em um arquivo JSON. A função json.dump() é usada para escrever o dicionário no arquivo JSON. E, ainda, a opção "w" é passada para o open() para indicar que queremos escrever no arquivo.

Experimente testar o código e abrir o arquivo pessoas.json logo em seguida para ver o que houve. No meu caso, o meu arquivo ficou assim:

{"João": "Engenheiro", "Maria": "Advogada", "Pedro": "Médico"}

8.6.7 Encoding e Caracteres Especiais

Antes de trabalharmos com diferentes formatos de arquivo, é importante entender o conceito de encoding (codificação de caracteres). O encoding define como os caracteres são representados como bytes no arquivo.

8.6.7.1 O que é Encoding?

Encoding é como o computador converte caracteres (letras, números, símbolos) em bytes que podem ser armazenados em arquivo. O encoding mais comum é o UTF-8, que consegue representar praticamente todos os caracteres de todas as línguas do mundo.

8.6.7.2 Problemas com Encoding

Quando você tem problemas com caracteres especiais (acentos, ç, ñ, etc.), geralmente é por causa de encoding:

# Exemplo de problema de encoding
texto = "Olá, mundo! Café, açúcar, coração"

# Salvando com encoding UTF-8 (recomendado)
with open("texto_utf8.txt", "w", encoding="utf-8") as arquivo:
    arquivo.write(texto)

# Salvando com encoding ASCII (pode dar erro com acentos)
try:
    with open("texto_ascii.txt", "w", encoding="ascii") as arquivo:
        arquivo.write(texto)
except UnicodeEncodeError:
    print("Erro: ASCII não suporta acentos!")

8.6.7.3 ensure_ascii no JSON

No JSON, o parâmetro ensure_ascii controla como caracteres especiais são tratados:

import json

dados = {
    "nome": "José da Silva",
    "cidade": "São Paulo",
    "emoji": "😊"
}

# ensure_ascii=True (padrão) - converte caracteres especiais para escape
with open("dados_ascii.json", "w", encoding="utf-8") as arquivo:
    json.dump(dados, arquivo, ensure_ascii=True, indent=2)

# ensure_ascii=False - mantém caracteres especiais
with open("dados_utf8.json", "w", encoding="utf-8") as arquivo:
    json.dump(dados, arquivo, ensure_ascii=False, indent=2)

Diferença nos arquivos gerados:

  • dados_ascii.json: {"nome": "Jos\\u00e9 da Silva", "cidade": "S\\u00e3o Paulo"}
  • dados_utf8.json: {"nome": "José da Silva", "cidade": "São Paulo"}

8.6.7.4 Boas Práticas de Encoding

  1. Sempre especifique encoding: encoding="utf-8"
  2. Use UTF-8: Suporta todos os caracteres
  3. Para JSON: Use ensure_ascii=False para manter acentos legíveis
  4. Para compatibilidade: Use ensure_ascii=True se precisar de compatibilidade com sistemas antigos

2. Crie um código que peça para o usuário digitar uma frase. Salve o resultado em uma arquivo de texto. Depois, abra este arquivo de texto que salvou e mostre o resultado na tela.

# pede para o usuário digitar uma frase
frase = input("Digite uma frase: ")

# salva a frase em um arquivo de texto
with open("frase.txt", "w") as arquivo:
    arquivo.write(frase)

# abre o arquivo de texto e exibe o conteúdo na tela
with open("frase.txt", "r") as arquivo:
    conteudo = arquivo.read()
    print("Conteúdo do arquivo:")
    print(conteudo)

Veja que a função input() para solicitar que o usuário digite uma frase. Em seguida, a salvamos em um arquivo de texto chamado frase.txt usando a abertura do arquivo em modo de escrita ("w") e a função write().

Depois, abrimos o arquivo em modo de leitura ("r") e o conteúdo é lido usando o método read() e salvo na variável conteudo, que é mostrada na tela com o print(conteudo).

3. A partir do exercício 2 e após mostrar o resultado na tela, peça novamente para que o usuário digite uma nova frase. Adicione esta nova frase no mesmo arquivo de texto sem apagar o conteúdo que já estava lá, e mostre o resultado na tela.

# pede para o usuário digitar uma frase
frase = input("Digite uma frase: ")

# salva a frase em um arquivo de texto
with open("frase.txt", "w") as arquivo:
    arquivo.write(frase)

# abre o arquivo de texto e exibe o conteúdo na tela
with open("frase.txt", "r") as arquivo:
    conteudo = arquivo.read()
    print("Conteúdo do arquivo:")
    print(conteudo)

# Pede ao usuário para digitar uma outra frase
frase = input("Digite uma frase: ")

# Abre o arquivo em modo "a" para adicionar a nova frase
with open("frases.txt", "a") as arquivo:
# Adiciona a nova frase ao arquivo
    arquivo.write(frase + "\n")

# Abre o arquivo novamente em modo "r" (leitura)
with open("frases.txt", "r") as arquivo:
# Lê o conteúdo do arquivo e mostra na tela
    conteudo = arquivo.read()
    print(conteudo)

Perceba principalmente o que vem depois do comentário “Pede ao usuário para digitar uma outra frase”. Para adicionar a nova frase ao arquivo de texto sem apagar o conteúdo já existente, usamos o modo "a" (append) na abertura do arquivo. Se usássemos o "w" de volta iríamos sobrescrever o que já havia sido salvo anteriormente.

4. Crie uma lista com números de 1 a 10 e, em seguida, crie uma segunda lista contendo somente os números pares. Salve somente a lista dos números pares em um arquivo pickle. Depois, abra novamente o arquivo pickle que salvou e mostre na tela o seu conteúdo.

import pickle

# cria a lista de números de 1 a 10
numeros = list(range(1, 11))

# filtra os números pares
numeros_pares = []
for num in numeros:
    if num % 2 == 0:
        numeros_pares.append(num)

# salva a lista de números pares em um arquivo pickle
with open("numeros_pares.pickle", "wb") as f:
    pickle.dump(numeros_pares, f)

# abre o arquivo pickle e mostra o conteúdo na tela
with open("numeros_pares.pickle", "rb") as f:
    numeros_pares_lidos = pickle.load(f)
    print(numeros_pares_lidos)

Veja que salvamos a lista numeros_pares em um arquivo pickle chamado numeros_pares.pickle. Como é um arquivo binário (isto é: não é legível por humanos ao abrir no bloco de notas), salvamos este arquivo usando "wb" e lemos usando "rb" (perceba a letra b presente em ambos os casos). Por fim, o código abre novamente o arquivo pickle com o uso do pickle.load() e mostra o conteúdo na tela. O resultado esperado é a exibição na tela da lista [2, 4, 6, 8, 10].

5. Modifique o código do exercício 4 para que salve, dentro de um único arquivo, as duas listas. Depois, abra novamente o arquivo pickle que salvou e mostre na tela o seu conteúdo.

import pickle

# cria a lista de números de 1 a 10
numeros = list(range(1, 11))

# filtra os números pares
numeros_pares = []
for num in numeros:
    if num % 2 == 0:
        numeros_pares.append(num)

# salva a lista de números pares em um arquivo pickle
with open("numeros_pares.pickle", "wb") as f:
    pickle.dump([numeros, numeros_pares], f)

# abre o arquivo pickle e mostra o conteúdo na tela
with open("numeros_pares.pickle", "rb") as f:
    numeros_lidos, numeros_pares_lidos = pickle.load(f)
    print(numeros_lidos)
    print(numeros_pares_lidos)

É muito provável que você tenha dificuldades para fazer este aqui. Afinal, em nenhum momento lhe disse como salvaríamos mais de uma variável em um arquivo pickle. Sem problemas - a ideia aqui é a de demonstrar, mesmo. Perceba duas grandes modificações em relação ao código anterior:

  • O pickle.dump([numeros, numeros_pares], f): veja o [numeros, numeros_pares]. Para salvar mais de uma variável em um mesmo arquivo pickle basta informar todas as variáveis em uma lista.
  • Para ler estas variáveis, basta informar a mesma quantidade na hora de chamar o pickle.load(). Como salvamos duas variáveis, teremos que armazenar o resultado do pickle.load() em duas variáveisl. É por isso que temos o numeros_lidos, numeros_pares_lidos na antepenúltima linha.

8.6.8 Comparação de Formatos: CSV vs JSON vs TXT

Agora que você conhece os principais formatos de arquivo, é importante entender quando usar cada um no mercado de trabalho:

8.6.8.1 Arquivo TXT (Texto Simples)

Características: - Formato mais simples - Apenas texto puro - Sem estrutura específica - Leve e rápido

Quando usar: - Logs de sistema - Documentação simples - Dados não estruturados - Arquivos de configuração básicos

Exemplo de uso profissional:

# Log de sistema
with open("sistema.log", "a", encoding="utf-8") as log:
    log.write(f"[{datetime.now()}] Usuário fez login\n")

8.6.8.2 Arquivo CSV (Comma-Separated Values)

Características: - Estrutura tabular (linhas e colunas) - Separado por vírgulas (ou outros delimitadores) - Excelente para dados numéricos - Amplamente suportado

Quando usar: - Planilhas e dados tabulares - Relatórios financeiros - Dados de sensores - Exportação de bancos de dados - Análise de dados com pandas

Exemplo de uso profissional:

# Relatório de vendas
import csv
vendas = [
    ["Produto", "Quantidade", "Valor"],
    ["Notebook", "5", "25000.00"],
    ["Mouse", "20", "500.00"]
]

with open("vendas.csv", "w", newline="", encoding="utf-8") as arquivo:
    writer = csv.writer(arquivo)
    writer.writerows(vendas)

8.6.8.3 Arquivo JSON (JavaScript Object Notation)

Características: - Estrutura hierárquica (chave-valor) - Suporta tipos de dados complexos - Fácil de ler e escrever - Padrão da web

Quando usar: - APIs web (REST, GraphQL) - Configurações de aplicação - Dados de frontend/backend - Bancos de dados NoSQL - Microserviços

Exemplo de uso profissional:

# API de e-commerce
import json

produto = {
    "id": 123,
    "nome": "Smartphone XYZ",
    "preco": 1299.99,
    "categoria": "Eletrônicos",
    "especificacoes": {
        "tela": "6.1 polegadas",
        "memoria": "128GB",
        "cor": ["Preto", "Branco", "Azul"]
    },
    "disponivel": True
}

with open("produto.json", "w", encoding="utf-8") as arquivo:
    json.dump(produto, arquivo, ensure_ascii=False, indent=2)

8.6.8.4 Comparação Prática

Aspecto TXT CSV JSON
Estrutura Não estruturado Tabular Hierárquica
Tamanho Menor Médio Maior
Legibilidade Simples Boa Excelente
Processamento Manual Fácil Muito fácil
APIs Web Não Raramente Sim
Excel Não Sim Não nativo
Bancos de Dados Não Sim Sim

8.6.8.5 Cenários Reais no Mercado

1. E-commerce: - CSV: Relatórios de vendas, estoque - JSON: APIs, configurações de produtos - TXT: Logs de sistema

2. Análise de Dados: - CSV: Dados para pandas, Excel - JSON: Dados de APIs, configurações - TXT: Dados brutos de sensores

3. Desenvolvimento Web: - JSON: Comunicação frontend/backend - CSV: Exportação de relatórios - TXT: Logs de aplicação

4. Machine Learning: - CSV: Datasets tabulares - JSON: Configurações de modelo - TXT: Dados de texto para NLP

8.6.8.6 Dicas para Escolher o Formato

  1. Use TXT quando:
    • Dados são simples e não estruturados
    • Precisa de máximo desempenho
    • Arquivo é temporário
  2. Use CSV quando:
    • Dados são tabulares
    • Precisa compatibilidade com Excel
    • Trabalha com análise de dados
  3. Use JSON quando:
    • Dados têm estrutura complexa
    • Trabalha com APIs
    • Precisa de flexibilidade

💡 Dica Profissional: No mercado de trabalho, JSON é o formato mais usado para comunicação entre sistemas, CSV para análise de dados, e TXT para logs e configurações simples.

8.7 Referências bibliográficas

  • PYTHON. CSV File Reading and Writing. Disponível em: https://docs.python.org/3/library/csv.html. Acesso em: 14 mar. 2023.
  • PYTHON. JSON - JavaScript Object Notation. Disponível em: https://docs.python.org/3/library/json.html. Acesso em: 14 mar. 2023.
  • PYTHON. pickle — Python object serialization. Disponível em: https://docs.python.org/3/library/pickle.html. Acesso em: 14 mar. 2023.
  • PYTHON. Tutorial de Python 3.9.6rc1. Disponível em: https://docs.python.org/pt-br/3/tutorial/index.html. Acesso em: 14 mar. 2023.
  • GEEKSFORGEEKS. JSON with Python. Disponível em: https://www.geeksforgeeks.org/json-with-python/. Acesso em: 14 mar. 2023.
  • GEEKSFORGEEKS. Reading CSV files in Python. Disponível em: https://www.geeksforgeeks.org/reading-csv-files-in-python/. Acesso em: 14 mar. 2023.
  • JSON.org. Introducing JSON. Disponível em: https://www.json.org/json-en.html. Acesso em: 14 mar. 2023.
  • W3SCHOOLS. Python File Handling. Disponível em: https://www.w3schools.com/python/python_file_handling.asp. Acesso em: 14 mar. 2023.