Skip to content

Instantly share code, notes, and snippets.

@wsmoak
Last active February 14, 2016 13:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wsmoak/22e8243fd6f6f1f7e48e to your computer and use it in GitHub Desktop.
Save wsmoak/22e8243fd6f6f1f7e48e to your computer and use it in GitHub Desktop.
Minty - parse and summarize transactions.csv from Mint
# Read the transactions.csv file from Mint and summarize it
defmodule Minty do
@amt 3
@drcr 4
@category 5
def read_it do
File.stream!("/Users/wsmoak/Downloads/transactions.csv")
|> CSV.decode
|> Enum.reduce( %{}, &count_it/2 )
|> print_it
end
# Match on the first row of the CSV which contains titles and discard it
def count_it(["Date"|_], accum) do
accum
end
def count_it(row, accum) do
Map.update(accum, Enum.at(row,@category), get_value(row), fn curr_val -> curr_val + get_value(row) end)
end
def get_value(row) do
get_value( Enum.at(row,@amt), Enum.at(row,@drcr) )
end
def get_value( amt, "debit") do
String.to_float(amt) * -1
end
def get_value( amt, "credit") do
String.to_float(amt)
end
def print_it(accum) do
Enum.sort(accum, &compare_it/2)
|> Enum.each( fn x -> IO.puts("#{elem(x,0)} #{Float.to_string(elem(x,1),[decimals: 2])}") end)
end
def compare_it( item1, item2) do
elem(item1,1) > elem(item2,1)
end
end
defmodule Minty.Mixfile do
use Mix.Project
def project do
[app: :minty,
version: "0.0.1",
elixir: "~> 1.3-dev",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps]
end
# Configuration for the OTP application
#
# Type "mix help compile.app" for more information
def application do
[applications: [:logger]]
end
# Dependencies can be Hex packages:
#
# {:mydep, "~> 0.3.0"}
#
# Or git/path repositories:
#
# {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
#
# Type "mix help deps" for more examples and options
defp deps do
[
{:csv, "~> 1.2.3"},
]
end
end
# In a Phoenix project, priv/repo/seeds.exs
# Seed the Transactions table with all strings like this:
# TODO: use a proper Date field, store amounts as positive/negative numbers
# Script for populating the database. You can run it as:
#
# mix run priv/repo/seeds.exs
#
# Inside the script, you can read and write to any of your
# repositories directly:
#
# Minty.Repo.insert!(%Minty.SomeModel{})
#
# We recommend using the bang functions (`insert!`, `update!`
# and so on) as they will fail if something goes wrong.
alias Minty.Transaction
alias Minty.Repo
defmodule Minty.Seeds do
def store_it(row) do
IO.inspect row
changeset = Transaction.changeset(%Transaction{}, row)
Repo.insert!(changeset)
end
end
File.stream!("/Users/wsmoak/Downloads/transactions.csv")
|> Stream.drop(1)
|> CSV.decode(headers: [:date, :description, :original_description, :amount, :transaction_type, :category, :account_name, :labels, :notes])
|> Enum.each(&Minty.Seeds.store_it/1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment