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.

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.50

O 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.csv

Ordena 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.50

O 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.