Módulo 8 - Arquivos CSV e pathlib
Prática: relatório de vendas em CSV
12 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026
O que você vai aprender
- Ler um CSV de vendas com DictReader e converter os valores.
- Somar o total por categoria usando um dicionário como acumulador.
- Gravar um resumo.csv com DictWriter, writeheader e writerows.
- Montar os caminhos de entrada e saída com pathlib.
Ouvir o resumo desta aula
Um recap de cerca de 2 minutos na voz do Valim, para ouvir no trânsito ou na academia.
Ler a transcrição do resumo
Resumo da aula: Prática: relatório de vendas em CSV.
Os objetivos desta aula. Ler um CSV de vendas com DictReader e converter os valores. Somar o total por categoria usando um dicionário como acumulador. Gravar um resumo.csv com DictWriter, writeheader e writerows. Montar os caminhos de entrada e saída com pathlib.
Veja o essencial, parte por parte.
O plano do relatório. Ler vendas.csv com DictReader, convertendo o valor de cada linha para número.
Ler e somar por categoria. Sem get, você escreveria um if para ver se a categoria já existe: mais linhas.
Gravar o resumo em CSV. A segunda metade grava o resultado.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
O plano do relatório
Vamos montar um relatório de verdade, do tipo que se usa em qualquer trabalho com dados. Partimos de um arquivo vendas.csv com três colunas: produto, categoria e valor. O objetivo é descobrir quanto foi vendido em cada categoria e gravar esse resumo em um novo arquivo, resumo.csv. O programa segue o padrão de três etapas que aparece o tempo todo: ler a entrada, processar os números na memória e gravar o resultado. Cada etapa usa uma peça que você aprendeu neste módulo.
produto,categoria,valor
Caderno,Papelaria,15.00
Caneta,Papelaria,4.50
Mouse,Informatica,80.00
Teclado,Informatica,120.00
Cafe,Alimentos,22.00
Biscoito,Alimentos,8.50O arquivo de entrada vendas.csv: produto, categoria e valor.
Antes de escrever qualquer código, vale visualizar o resultado esperado. Somando por categoria, Papelaria dá 19,50 (15,00 mais 4,50), Informática dá 200,00 (80,00 mais 120,00) e Alimentos dá 30,50 (22,00 mais 8,50). O programa precisa chegar a esses três totais e gravá-los. Ter o resultado na cabeça antes ajuda a conferir se o código está certo. Agora, ao trabalho.
Ler e somar por categoria
A primeira metade lê o arquivo e acumula os totais. Usamos pathlib para montar o caminho, DictReader para ler por nome de coluna e um dicionário como acumulador. O truque do acumulador é este: para cada linha, pegamos a categoria e o valor; se a categoria ainda não está no dicionário, começamos do zero; depois somamos o valor ao total daquela categoria. O método get do dicionário, com um segundo argumento, resolve o caso da categoria nova de forma elegante, devolvendo zero quando a chave ainda não existe.
import csv
from pathlib import Path
entrada = Path("dados") / "vendas.csv"
totais = {}
with open(entrada, newline="", encoding="utf-8") as arquivo:
leitor = csv.DictReader(arquivo)
for linha in leitor:
categoria = linha["categoria"]
valor = float(linha["valor"])
totais[categoria] = totais.get(categoria, 0.0) + valor
print(totais)
# {'Papelaria': 19.5, 'Informatica': 200.0, 'Alimentos': 30.5}DictReader lê linha a linha; totais.get(categoria, 0.0) soma no acumulador sem quebrar na categoria nova.
Analise a linha central: totais[categoria] = totais.get(categoria, 0.0) + valor. O totais.get(categoria, 0.0) devolve o total já acumulado da categoria, ou 0.0 se ela aparece pela primeira vez. Somamos o valor da linha atual e guardamos de volta na chave. Ao fim do laço, o dicionário tem uma entrada por categoria com a soma completa. Note também o float(linha['valor']): sem essa conversão, o Python tentaria somar textos e daria erro ou juntaria strings. É o cuidado que você viu na aula de leitura.
Gravar o resumo em CSV
A segunda metade grava o resultado. Vamos ordenar as categorias do maior total para o menor, só para o relatório ficar agradável de ler, e depois gravar com DictWriter. Montamos uma lista de dicionários, cada um com categoria e total, chamamos writeheader para escrever o cabeçalho e writerows para despejar todas as linhas. Usamos encoding utf-8-sig, porque um resumo de vendas provavelmente será aberto por uma pessoa no Excel, e queremos os acentos certos, mesmo que aqui as categorias não tenham acento.
import csv
from pathlib import Path
# totais veio da etapa anterior:
totais = {"Papelaria": 19.5, "Informatica": 200.0, "Alimentos": 30.5}
saida = Path("dados") / "resumo.csv"
# ordena do maior total para o menor
ordenado = sorted(totais.items(), key=lambda par: par[1], reverse=True)
linhas = [{"categoria": cat, "total": f"{tot:.2f}"} for cat, tot in ordenado]
with open(saida, "w", newline="", encoding="utf-8-sig") as arquivo:
escritor = csv.DictWriter(arquivo, fieldnames=["categoria", "total"])
escritor.writeheader()
escritor.writerows(linhas)
print(f"Resumo gravado em {saida.name}")
# Resumo gravado em resumo.csvOrdena por total, monta os dicionários com o valor formatado e grava com writeheader e writerows.
categoria,total
Informatica,200.00
Alimentos,30.50
Papelaria,19.50O arquivo resumo.csv gerado: uma linha por categoria, da maior para a menor.
Repare em três decisões. O sorted com key=lambda par: par[1] ordena os pares categoria e total pelo total, e reverse=True coloca do maior para o menor. A compreensão de lista monta os dicionários já com o total formatado em duas casas, f'{tot:.2f}', para o CSV sair com 200.00 em vez de 200.0. E o pathlib deu os dois caminhos, entrada e saída, na mesma pasta, com o operador barra. Juntando as duas metades, você tem um programa completo que lê dados reais, resume e grava, o padrão que se repete em incontáveis tarefas de trabalho.
Teste rápido
No relatório, para que serve totais.get(categoria, 0.0) ao somar por categoria?
Perguntas frequentes
- Por que converter o valor com float ao ler o CSV?
- Porque o módulo csv lê tudo como texto: o valor 15.00 chega como a string '15.00'. Somar textos não faz a conta certa, junta os caracteres ou dá erro. O float('15.00') transforma em número 15.0, que pode ser somado ao acumulador da categoria.
- O que acontece se uma categoria aparecer só uma vez?
- Funciona igual. Na primeira aparição, totais.get(categoria, 0.0) devolve 0.0, e o programa soma o valor daquela linha, criando a entrada com o total certo. Se a categoria não voltar a aparecer, esse total é o final dela. O acumulador trata categorias únicas e repetidas do mesmo jeito.
- Preciso ordenar o resumo do maior para o menor?
- Não é obrigatório para o cálculo, só melhora a leitura. O sorted com reverse=True coloca as categorias que mais venderam no topo. Se você não ordenar, o resumo sai na ordem em que as categorias apareceram no arquivo, o que também é válido.
- Por que gravar o resumo com utf-8-sig?
- Porque um resumo de vendas costuma ser aberto por uma pessoa no Excel em português, e o utf-8-sig garante que eventuais acentos, como em Informática, apareçam corretos. Se o arquivo fosse consumido só por outro programa, o utf-8 comum bastaria.
- Dá para ler de um CSV e gravar em outro no mesmo programa?
- Sim, e é exatamente o que este relatório faz. Você lê vendas.csv em um with, processa na memória com o dicionário acumulador e grava resumo.csv em outro with. Também é possível abrir os dois no mesmo with, separados por vírgula, quando a lógica permite processar linha a linha direto.
- E se o arquivo de vendas tiver milhares de linhas?
- O programa continua funcionando bem. O DictReader lê linha a linha, sem carregar o arquivo inteiro de uma vez, e o dicionário acumulador guarda só uma entrada por categoria, não por linha. Por isso o padrão ler, processar e gravar aguenta arquivos grandes com pouco uso de memória.
Fontes
Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.