defmodule TaxCalculator do def calculate_tax_from_file(order_filename) do calculate_tax_from_file(order_filename, [ NC: 0.075, TX: 0.08 ]) end def calculate_tax_from_file(order_filename, tax_rates) do read(order_filename) |> Stream.map(&TaxCalculator.parse/1) |> calculate_tax(tax_rates) |> Enum.to_list end def read(filename) do {:ok, file} = File.open(filename) data = IO.read(file, :line) IO.stream(file, :line) end def parse(line) do regex = ~r/(?\d*?),:(?\w{2}),(?.*?)$/ named_captures = Regex.named_captures(regex, line) [ id: String.to_integer(named_captures["id"]), ship_to: String.to_atom(named_captures["ship_to"]), net_amount: String.to_float(named_captures["net_amount"]) ] end def calculate_tax(orders, tax_rates) do for order <- orders, do: Keyword.merge( order, TaxCalculator.calculate_total_amount(tax_rates[order[:ship_to]], order[:net_amount]) ) end def calculate_total_amount(nil, net_amount), do: [total_amount: Float.round(net_amount, 2)] def calculate_total_amount(tax_rate, net_amount) do total_amount = (1 + tax_rate) * net_amount [total_amount: Float.round(total_amount, 2)] end end