Skip to content

zolvaczi/billing-code-challenge

Repository files navigation

Billing Coding Challenge 2020-09-19

Overview

In this challenge, we’d like you to write a small program which, given a set of meter readings, computes a member’s monthly energy bill. To do this, we have stubbed out the following files for you:

  • bill_member.py, which contains functions to compute the customer bill and print it to screen.
    • You should implement calculate_bill. This is the entry point to your solution.
    • calculate_bill is currently hardcoded to give the correct answer for August 2017.
    • There’s no need to change calculate_and_print_bill.
  • test_bill_member.py, a test module for bill_member.
  • main.py, the entry point for the program, there’s no need to make changes to this module.
  • tariff.py, prices by kWh for all energy
  • load_readings.py, provides a function for loading the readings from the given json.
  • readings.json, contains a set of monthly meter readings for a given year, member and fuel

We’d like you to:

  • Implement the calculate_bill function, so that given a member_id, optional account argument and billing date, we can compute the bill for the customer.

We do not want you to spend time on:

  • Making this backwards compatible with python <= 3.

You can assume:

  • All times are UTC.
  • We’re only dealing with £ denominated billing.
  • You only need to handle electricity and gas billing.
  • Energy is consumed linearly.
  • The billing date is the last day of the month.
  • Readings are always taken at midnight.
  • There is only one meter reading per billing period.
  • The JSON file structure will remain the same in any follow on exercise.

Analysis

###Problem breakdown:

  1. Low-level: calculate consumption and charges from a single series of meter readings (calculate_meter_bill function)
  2. Higher-level: apply the above to each meter and each account of the member (calculate_bill function)

Further Assumptions and Known Limitations

  1. Due to the lack of JSON schema and the minimal JSON sample, the generic JSON schema was guessed.
  2. It is assumed that the datasource is static during the runtime of this application, and therefore it is only read once.
  3. only one reading (starting reading) is assumed to be an invalid use-case for billing
  4. VAT is not considered by this function, it could be applied to the total bill by a higher-level module/function (where the total can be adjusted by discounts, for instance)
  5. scaling was not considered at this level of implementation, scalability could be solved at a higher level of the architecture, e.g. by decomposing requests to process individual members or smaller batches of members in parallel, with data partitioning...
  6. Leaving customers need a final bill, in which case billing date may fall to other than the last day of the month
  7. abstraction: normally, I would implement some sort of interface class to access the data, to decouple the business logic from the underlying data structure + datasource implementation (see assumption "The JSON file structure will remain the same")
  8. no conversion from gas cubic meters to kWh has been implemented, as the formula was not specified
  9. a limitation of the solution is that the monthly bills will not always exactly add up to a yearly total consumption if some of the readings are not provided on the billing dates (but mid month, for instance). The solution to this limitation would be to also record the estimated readings on the billing date, and use those to calculate the new consumption for the next billing period. Rounding errors can also accumulate over a year due to the 2-decimals precision (pence) used.

###Edge cases considered

  1. data points
    1. bill date is an exact date match with a reading date
    2. extrapolation from last two readings
    3. only one reading is available (assumption: this is an error*)
    4. no data points at all (assumption: this is an error*)
  2. bill dates
    1. end of month
    2. not the last day of a month
    3. no date specified (assumption: this is an error*)
    4. test for leap years
  3. yearly total charges == sum of monthly bills (roughly: max rounding error: 12 * 0.5= 6 kWh, and 12 * £0.005 * 2= £0.12)
  4. meters: member has
    1. gas meter
    2. electricity meter
    3. dual fuel
    4. none (assumption: this is an error*)
  5. accounts
    1. member has one account
    2. member has more accounts
    3. member has no account (assumption: this is an error*)
  6. units
    1. electricity/gas consumption specified in kWh
    2. gas consumption specified in cubic meters (conversion formula to be provided*)

*normally, edge cases should be verified with the product manager before implementation

About

Energy bill practice exercise

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages