-
-
Save 6ewis/c4c3dfb54ed165338d64 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'csv' | |
require 'active_support/inflector' | |
Customer = Struct.new(:cust_id, | |
:elect_or_gas, | |
:disconnect_doc, | |
:move_in_date, | |
:move_out_date, | |
:bill_year, | |
:bill_month, | |
:span_days, | |
:meter_read_date, | |
:meter_read_type, | |
:consumption, | |
:exception_code, | |
:data | |
) | |
class Parser | |
attr_accessor :customers | |
def initialize filename | |
self.customers = [] | |
deserialize_users filename | |
serialize_users | |
end | |
def deserialize_users filename | |
CSV.foreach(filename, col_sep: "|") do |row| | |
next if row.join == /^[:space:]/ # make sure that all cases are taken care of e,g ["","",""," "] | |
sanitize_values(row) | |
customers << Customer.new(*row, row) | |
end | |
customers | |
end | |
def serialize_users | |
CSV.open("./serialized_users.csv", "w+") do |csv| | |
customers.each do |c| | |
csv << c.data | |
end | |
end | |
end | |
def sanitize_values(row) | |
row.map!(&:to_s) | |
end | |
end | |
module Statistics | |
attr_accessor :parser, :output_size | |
def initialize data , output_size | |
self.parser = Parser.new data | |
self.output_size = output_size | |
end | |
def customers | |
parser.customers | |
end | |
def unique_customers | |
customers.uniq(&:cust_id ) | |
end | |
def customers_with_electricity#_ONLY | |
customer = customers.select { |customer| customer.elect_or_gas == "1" || customer.elect_or_gas == "ElecOrGas" } | |
end | |
def customers_with_gas#_ONLY | |
customers.select { |customer| customer.elect_or_gas == "2" || customer.elect_or_gas == "ElecOrGas"} | |
end | |
def customers_bill_month month , resource = nil | |
[:customers_with_electricity, :customers_with_gas, :customers].each do |receiver| | |
break send(receiver).select {|customer| customer.bill_month == "#{month}"} if receiver.to_s.end_with?(resource.to_s) | |
end | |
end | |
def list_of_nbr_of_meter_readings_and_customer_ID resource = nil | |
customers_id = | |
[:customers_with_electricity, :customers_with_gas, :customers].each do |receiver| | |
break send(receiver).collect { |customer| next if customer.cust_id == "CustID"; customer.cust_id}.compact if receiver.to_s.end_with?(resource.to_s) | |
end | |
customers_id.map do |customer_id| | |
[customers_id.count(customer_id), customer_id] | |
end.uniq | |
end | |
def list_nbr_of_meters_readings resource = nil | |
list_of_nbr_of_meter_readings_and_customer_ID(resource).map { |a,_| a } | |
end | |
def nbr_of_customers_with_that_many_readings arg, resource = nil | |
list_nbr_of_meters_readings(resource).count(arg) | |
end | |
def list_of_unique_nbr_of_meter_readings_and_number_of_customers_with_that_many_readings resource = nil | |
list_of_nbr_of_meter_readings_and_customer_ID(resource).map { |a,_| [a, nbr_of_customers_with_that_many_readings(a,resource) ]}.uniq.sort | |
end | |
def avg_consumption_month month , resource = nil | |
!customers_bill_month(month, resource).empty? ? ( (customers_bill_month(month, resource).inject(0) { |sum, n| sum + n.consumption.to_i } ) / customers_bill_month(month, resource).length ) : 0 | |
end | |
end | |
class Reporting | |
include Statistics | |
def show_all_data | |
print "\n\nALL CUSTOMERS AND DATA\n\n" | |
format_show customers | |
puts "\nNumber of customers: #{customers.count - 1}" | |
end | |
[:unique_customers, :customers_with_electricity, :customers_with_gas].each do |meth| | |
define_method "show_#{meth}" do | |
print "\n\n#{meth.to_s.humanize.upcase}\n\n" | |
format_show send(meth) | |
puts "\nNumber of unique customers: #{send(meth).count - 1}" | |
end | |
end | |
def show_avg_consumption_per_bill_month resource = nil | |
print "\n\nAVERAGE CONSUMPTION PER BILL MONTH #{'PER ' + resource.to_s.upcase if resource} ACROSS ALL CUSTOMERS\n\n" | |
print "MONTHS".center(output_size*2) + "|" + "AVERAGE CONSUMPTION(S)".center(output_size*2) + "\n\n" | |
total_avg_consumption = [] | |
(1..12).each do |i| | |
puts "\n\n" + "#{ Date::MONTHNAMES[i]}".center(output_size*2) + "|" + "#{avg_consumption_month i, resource}".center(output_size*2) | |
total_avg_consumption << avg_consumption_month(i, resource) | |
end | |
puts "\n\n" + "TOTAL AVERAGE CONSUMPTION".center(output_size*2) + "|" + "#{total_avg_consumption.inject(:+) / total_avg_consumption.length}".center(output_size*2) | |
end | |
def show_nbr_of_meters_readings_per_number_of_customers_with_that_many_readings resource = nil | |
print "\n\nNUMBER OF METERS READINGS PER NUMBER OF CUSTOMERS WITH THAT MANY READINGS #{'(' + resource.to_s.upcase + ' ONLY)' if resource}\n\n" | |
print "#{'Number of meter readings'}".center(output_size*2) + "|" + "#{'Number of customers'}".center(output_size*2) + "\n\n" | |
list_of_unique_nbr_of_meter_readings_and_number_of_customers_with_that_many_readings(resource).each \ | |
{ |a,b| puts "#{a}".center(output_size*2) + "|" + "#{b}".center(output_size*2)} | |
end | |
private | |
def format_show customers | |
customers.map do |customer| | |
puts customer.data.map { |item| item.center output_size}.join'|' | |
end | |
end | |
end | |
r = Reporting.new "./pulse_data.txt", 15 | |
r.show_all_data | |
r.show_unique_customers | |
r.show_customers_with_gas | |
r.show_customers_with_electricity | |
r.show_avg_consumption_per_bill_month | |
r.show_avg_consumption_per_bill_month :electricity | |
r.show_avg_consumption_per_bill_month :gas | |
r.show_nbr_of_meters_readings_per_number_of_customers_with_that_many_readings | |
r.show_nbr_of_meters_readings_per_number_of_customers_with_that_many_readings :electricity | |
r.show_nbr_of_meters_readings_per_number_of_customers_with_that_many_readings :gas | |
puts "\nMethods available: #{Reporting.instance_methods(false)}" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment