a review of a student’s code style from COMP1511
a reply-to-public; written 2017-08-25

I’ve spent a few minutes reading through this code – somewhat longer than an assessor would have to make a style judgement – and much longer writing this commentary. So, as you’ve probably guessed, I’ve got a few remarks on style; here’s a précis, in descending order of how severe a problem it is.

Let’s go through those.

And finally, some logic errors: you throw away, consistently, values moving up and down the call stack.

A function can be treated like a black box that, when given a set of values, produces a result. So, if I were to call getLocalTime, I’d have something that looks like

                                   ┌──────────────┐
(CITY_CHRISTCHURCH, 15, 5,  859) → │ getLocalTime │ → 2059
                                   └──────────────┘

That’s just a specific case, of course; in general, functions tend to look a bit more like this:

                       ┌──────────────┐
(int, int, int, int) → │ getLocalTime │ → int
                       └──────────────┘

When given four int-type values, this function produces an int type value. You don’t have to worry about how it happens, only that it does happen. This is part of what the prototype of a function does for us: it tells the compiler the shape of these values moving through the system.

For each level of abstraction you drill down, you should be able to treat the functions at the next level down as black boxes, too.

             ┌─────────┐
(int, int) → │ convert │ → int
             └─────────┘

Unfortunately, convert won’t behave like this: this function won’t return me a useful int-typed value, because, if I throw away the portions of the function that don’t directly produce me a value:

[   171]    int convert(int UTCtime,int Timezone)
[   172]    {
[   179]        return 0;
[   180]    }

This doesn’t seem like a particularly useful function. For all values I can put into it:

             ┌─────────┐
(int, int) → │ convert │ → 0
             └─────────┘

Worse, if I take away the portions of the getLocalTime function that don’t produce a useful value:

[   220]    int getLocalTime (int city, int day, int month, int timeUTC)
[   221]    {
[   267]    }

There’s nothing left!

Imagine you’re trying to do maths, but the numbers you’re working with, and the working space on which you can write, are balloons filled with helium. You can’t lose a string tying one of these balloons down, otherwise the numbers you’re working with just fly away!

A useful rule to follow: when you transform a value, whether it’s by applying the basic arithmetic operators, or by applying a function, you should always capture the result, or it flies away.

In this case, the return is undefined!

                       ┌──────────────┐
(int, int, int, int) → │ getLocalTime │ → ????
                       └──────────────┘

… so none of the asserts will ever pass, because there’s no value that comes back out of the function. If I just returned every convert:

                       ┌──────────────┐
(int, int, int, int) → │ getLocalTime │ → 0
                       └──────────────┘

If I made convert return the value of the add:

                       ┌──────────────┐
(int, int, int, int) → │ getLocalTime │ → int
                       └──────────────┘

And now your solution might work!