I have a year or so of experience in developing in Java. I submitted the solution for this task, but never got the feedback that was promised. Since I still would like to get a feedback on my solution, I figured that here I will find skilled developers who wish to help me and others who may have similar questions.
Compute electricity day- and night- consumption of a client. Given client's per-hour electricity consumption for some month. Goal is to compute total day- and night- consumption. Hours are enumerated from 1 starting from beginning of month. Day hours are 7-23 at working days (8-24 at daylight saving time or summer). All other hours are night hours. Example for January 2012:
1 - 2kW (hour #1 is January 1, Sunday, 00:00 - 01:00 - NIGHT) 2 - 3kW (hour #2 is January 1, Sunday, 01:00 - 02:00 - NIGHT) 26 - 3kW (hour #26 is January 2, Monday, 01:00 - 02:00 - NIGHT) 32 - 6kW (hour #32 is January 2, Monday, 07:00 - 08:00 - DAY) ... 744 - 0kW (hour #744 is January 31, 23:00 - 24:00)
In this case, night consumption is 8 = 2+3+3 and day consumption is 6.
/**
* Used for calculating day and night tariff energy consumption for one month. Takes into account the start and end time changes of
* the day and night tariff because of the day light saving time period.
* This constructor uses Estonian time zone and 7-23 as day hours and 8-24 as day hours at daylight saving time.
*
* @param consumptionData One month's consumption data for each hour. Each hour - consumption pair has to be on a separate line.
* Syntax: First the hour value, second, the separator: ' - ' and then the amount.
* Hours have to be integers, and start from 1. Lines with non-integer hour values are disregarded.
* Amount has to be a number value. Non-numbers are considered as zero value.
* For example, if one line of data is '1 - 2.5kW', then the hour #1 is first day of a month at 00:00 - 01:00.
* @param month Month (1-12) for which the data belongs to.
* @param year Year for which the data belongs to.
*/
public MonthConsumption(final BufferedReader consumptionData, final int month, final int year)
/**
* Used for calculating day and night tariff energy consumption for one month. Takes into account the start and end time changes of
* the day and night tariff because of the day light saving time period.
*
* @param consumptionData One month's consumption data for each hour. Each hour has to be on a separate line.
* First the hour value, then the separator ' - ' and then the amount.
* Hours have to be integers, and start from 1. Lines with non-integer hour values are disregarded.
* Amount can be double or integer value.
* For example, if one line of data is '1 - 2kW', then the hour #1 is first day of a month at 00:00 - 01:00.
* @param month Month (1-12) for which the data belongs to.
* @param year Year for which the data belongs to.
* @param timezone Timezone where the data was measured. Values for the timezones can be acquired
* <a href="http://joda-time.sourceforge.net/timezones.html">here</a>
* from the 'Canonical ID' column. This is needed to consider the daylight saving time changes.
* @param dayTariffStartHour The hour of the day from which the day tariff is being measured during the standard, non-daylight saving time period.
* @param dayTariffEndHour The hour of the day which is the last hour of day tariff during the standard, non-daylight saving time period.
* @param dstDayTariffStartHour The hour of the day from which the day tariff is being measured during the daylight saving time period.
* @param dstDayTariffEndHour The hour of the day which is the last hour of day tariff during the daylight saving time period.
*/
public MonthConsumption(final BufferedReader consumptionData, final int month, final int year, final String timezone,
final int dayTariffStartHour, final int dayTariffEndHour, final int dstDayTariffStartHour, final int dstDayTariffEndHour)
/**
*
* @return Consumption amount that the day tariff applies to.
*/
public Double duringDayTariff()
/**
*
* @return Consumption amount that the night tariff applies to.
*/
public Double duringNightTariff()
@Test
public void nightConsumptionIsFromFirstHourToEighthHourWhenDST() throws Exception {
BufferedReader reader = new BufferedReader(new StringReader("1 - 1" + "\n" + "8 - 1" + "\n" + "24 - 10" + "\n" + "9 - 10"));
MonthConsumption monthConsumption = new MonthConsumption(reader, 4, 2013);
assertEquals(2, monthConsumption.duringNightTariff(), 0);
}
@Test
public void testIncludedWithTheTask() throws Exception {
BufferedReader reader = new BufferedReader(new StringReader("1 - 2" + "\n" + "2 - 3" + "\n" + "26 - 3" + "\n" + "32 - 6" + "\n" + "744 - 0"));
MonthConsumption monthConsumption = new MonthConsumption(reader, 1, 2013);
assertEquals(8, monthConsumption.duringNightTariff(), 0);
assertEquals(6, monthConsumption.duringDayTariff(), 0);
}
@Test
public void daylightSavingStartsOnLastSundayOfMarchInEstoniaAt01UTC_March2013() throws FileNotFoundException {
String fileName = "endOfMarch2013.csv";
String fileSeparator = System.getProperty("file.separator");
final String filePath = "src" +
fileSeparator + "test" + fileSeparator + "resources" + fileSeparator + fileName;
BufferedReader reader = new BufferedReader(new FileReader(filePath));
MonthConsumption monthConsumption = new MonthConsumption(reader, 3, 2013);
/* The "endOfMarch2013.csv" file has 50 hours, each with consumed value of 1.
The 723th hour is 2013 31th March 02:00-02:59. DST starts at 03:00 (UTC 01:00).
This means that the time from 3:00-3:59 is skipped.
724th hour is 2013 31th March 04:00-05:59
Therefore, 744th hour is the beginning of the next month, which will not be
added.*/
assertEquals(48, monthConsumption.duringNightTariff(), 0);
assertEquals(1, monthConsumption.duringDayTariff(), 0);
}
Questions:
- Is the public interface easy to use? Is there a better way instead of
BufferedReader
to pass data toMonthConsumption
? Do the public methods ofMonthConsumption
have understandable documentation? - Which tests are missing? Should I create tests for private methods as well? Have you come up with a test that would give some unwanted response?
- Is the design of unit tests using best practices? Do the unit tests serve as an explanation of what the program does? If no, then what should I change?
- Are there enough/not too many comments? Are there some private methods that need comments?
- Do the method and variable names help in understanding and reading the code?