Programming in D – Solutions

assert and enforce

  1. You will notice that the program terminates normally when you enter 06:09 and 1: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 contains 09:06. This error will be caught by the help of an assert in the next problem.

  2. The assert failure after entering 06:09 and 15: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 invalid hour 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 duration 15: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.
    
  3. 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));
    }
    
  4. Good luck.