Pular para o conteúdo

Planilhas

Do banco à planilha, passando pela análise.

Este é o caminho completo de um trabalho de dados: os dados moram no banco, a análise responde à pergunta, e a planilha é o que se manda para quem decide. As três peças conversam.

As quatro peças#

MóduloPara
`Arcane.Database`SQLite: consultas, migrações, transações, modelos
`Arcane.Analytics`média, desvio, correlação, regressão, describe
`Arcane.Excel`ler e gravar .xlsx
`Arcane.IO`arquivos, CSV, JSON

Do banco à planilha#

dataforge
adopt Arcane.Database as DB
adopt Arcane.Analytics as An
adopt Arcane.Excel as Xls

// 1. os dados
banco := DB.connect("vendas.db")
registros := DB.query(banco, "SELECT * FROM vendas ORDER BY qtd DESC")

// 2. a pergunta
tabela := An.from_records(registros)
descricao := An.describe(tabela)
correlacao := An.correlation(
    [r["qtd"] cycle r in registros],
    [r["preco"] cycle r in registros])

// 3. o entregável
livro := Xls.new()
aba := Xls.sheet(livro, "Vendas", registros)
Xls.set(aba, "E1", "receita")
cycle i from 2 to len(registros) + 1:
    Xls.formula(aba, $"E{i}", $"C{i}*D{i}")

Xls.sheet(livro, "Estatísticas", [
    ["métrica", "valor"],
    ["vendas", len(registros)],
    ["correlação", round(correlacao, 3)]
])
Xls.save(livro, "relatorio.xlsx")

`describe` sobre um frame#

Sobre uma lista, descreve a lista. Sobre um frame, descreve cada coluna:

dataforge
An.describe(tabela)
// {
//   "qtd":     {count: 5, mean: 13.0, std: 9.6, min: 3, max: 27, …},
//   "produto": {count: 0, type: "non-numeric"}
// }

Colunas de texto aparecem marcadas em vez de zerarem o resultado inteiro. Booleanos são ignorados: em Python yes vale 1, e numa coluna de dados isso é ruído.

Escrever arquivos#

QuerUse
texto, JSON, CSVIO.write_file, IO.write_json, IO.write_csv
planilhaXls.save, Xls.quick
bancoDB.execute — e DB.close quando terminar
um caminho ao lado do programaOS.beside("dados", "x.json")

OS.beside resolve a partir do arquivo .df em execução, não de onde o usuário chamou o programa. Sem isso, rodar de duas pastas diferentes lê — ou não lê — arquivos diferentes.

Servir a planilha por HTTP#

dataforge
route GET "/relatorio.xlsx":
    livro := montar(consultar_agora())
    Xls.save(livro, "/tmp/r.xlsx")
    respond file "/tmp/r.xlsx"

O arquivo não precisa existir antes do pedido. O projeto loja-web faz exatamente isso, com fórmulas que o Excel resolve ao abrir.

Uma armadilha de precedência#

dataforge
// errado: divide o ZERO, não a soma
media := precos >> distill a, v: a + v 0 / len(precos)

// certo
soma := precos >> distill a, v: a + v 0
media := soma / len(precos)

O valor inicial do distill vem depois do corpo. O relatório mostra a soma no lugar da média, e nada na tela denuncia — o número simplesmente está errado.