assert
and enforce
- You will notice that the program terminates normally when you enter
06:09
and1:2
. However, you may notice that the start time is not what has been entered by the user:1 hours and 2 minutes after 09:06 is 10:08.
As you can see, although the time that has been entered as
06:09
, the output contains09:06
. This error will be caught by the help of anassert
in the next problem. - The
assert
failure after entering06:09
and15:2
takes us to the following line:string timeToString(int hour, int minute) { assert((hour >= 0) && (hour <= 23)); // ... }
For this
assert
check to fail, this function must have been called with invalidhour
value.The only two calls to
timeToString()
in the program do not appear to have any problems:writefln("%s hours and %s minutes after %s is %s.", durationHour, durationMinute, timeToString(startHour, startMinute), timeToString(endHour, endMinute));
A little more investigation should reveal the actual cause of the bug: The hour and minute variables are swapped when reading the start time:
readTime("Start time", startMinute, startHour);
That programming error causes the time to be interpreted as
09:06
and incrementing it by duration15:2
causes an invalid hour value.An obvious correction is to pass the hour and minute variables in the right order:
readTime("Start time", startHour, startMinute);
The output:
Start time? (HH:MM) 06:09 Duration? (HH:MM) 15:2 15 hours and 2 minutes after 06:09 is 21:11.
- It is again the same
assert
check:assert((hour >= 0) && (hour <= 23));
The reason is that
addDuration()
can produce hour values that are greater than 23. Adding a remainder operation at the end would ensure one of the output guarantees of the function:void addDuration(int startHour, int startMinute, int durationHour, int durationMinute, out int resultHour, out int resultMinute) { resultHour = startHour + durationHour; resultMinute = startMinute + durationMinute; if (resultMinute > 59) { ++resultHour; } resultHour %= 24; }
Observe that the function has other problems. For example,
resultMinute
may end up being greater than 59. The following function calculates the minute value correctly and makes sure that the function's output guarantees are enforced:void addDuration(int startHour, int startMinute, int durationHour, int durationMinute, out int resultHour, out int resultMinute) { resultHour = startHour + durationHour; resultMinute = startMinute + durationMinute; resultHour += resultMinute / 60; resultHour %= 24; resultMinute %= 60; assert((resultHour >= 0) && (resultHour <= 23)); assert((resultMinute >= 0) && (resultMinute <= 59)); }
- Good luck.