Code & Coffee 5/20/2022

The goal is to drive out good test naming in a group setting using "isLeapYear" as a sample problem.

- Work as a group to derive

Topic: Having fun with isLeapYear

- Had a bit of fun with the exercise
- Noticed that people liked to try to optimize it
- Was mentioned that isLeapYear looks a lot like FizzBuzz
- replit is not as good as real vim.

- Talked a bunch about logging and interpolation penalties for unlogged messages (not logged because of logging level)
- Talked about interesting stuff in the hiring space.
- Talked about COBOL for a little bit.
- What is a Senior Developer?
- Capable of mentoring more than putting out code
- Interviewing skills

- Flex box
- And overflow interact in an interesting way
- overflow hidden and visible are part of the weird interaction.

- REPL driven development
- Sooo good

The code we came up with:

/*

Every year that is exactly divisible by four is a leap year,

except for years that are exactly divisible by 100,

but these centurial years are leap years if they are exactly divisible by 400.

For example,

the years 1700, 1800, and 1900 are not leap years,

but the years 1600 and 2000 are.[14]

*/

//logger.warn("Something {}").mdc("one", () -> "two").log();

function isLeapYear(year) {

return (year & 3) == 0 && (

(year % 25) != 0 || (year & 15) == 0

);

}

function isLeapYearDate(year) {

return new Date(year, 1, 29).getDate() === 29;

}

function isLeapYearBad(year) {

const modYear = year % 400;

if(year === 0) return true;

if(year % 100 === 0) return false;

return false;

}

function isLeapYear3(year) {

if (year % 4 == 0) {

if (year % 100 == 0) {

if (year % 400 == 0) {

return true

}

return false;

}

return true;

}

return false;

}

function oldIsLeapYear(year) {

if (year % 400 == 0) {

return true;

} else if (year % 100 == 0) {

return false;

} else if (year % 4 == 0) {

return true;

}

return false;

}

group('leap year tests', () => {

ok('0 is not a leap year', !isLeapYear(0));

ok('negative numbers dont blow up', !isLeapYear(-1));

group('Year not divisible by 4', () => {

ok('1601 is not a leap year', !isLeapYear(1601));

});

group('Years divisible by 400', () => {

ok('1600 is a leap year', isLeapYear(1600));

ok('2000 is a leap year', isLeapYear(2000));

});

group('Years divisible by 100', () => {

ok('1700 is not a leap year', !isLeapYear(1700));

ok('1800 is not a leap year', !isLeapYear(1800));

ok('1900 is not a leap year', !isLeapYear(1800));

});

});

// This is another potential style:

group('A year is a leap year', () => {

ok('if it is divisible by 4 but not 100 (2020)', isLeapYear(2020));

ok('if it is divisible by 4 but not 100 (1984)', isLeapYear(1984));

ok('if it is divisible by 4 but not 100 (4)', isLeapYear(4));

ok('if it is divisible by 400 (400)', isLeapYear(400));

ok('if it is divisible by 400 (2400)', isLeapYear(2400));

});

group('A year is not a leap year', () => {

ok('if it is not divisible by 4 (2018)', !isLeapYear(2018));

ok('if it is not divisible by 4 (2017)', !isLeapYear(2017));

ok('if it is not divisible by 100 but not by 400 (2100)', !isLeapYear(2100));

});

// test "framework", just enough of one to play with anyway.

function ok(message, result) {

const GREEN = 32;

const RED = 31;

if (result) {

log(`OK - ${message}`, GREEN);

return;

}

log(`FAIL - ${message}`, RED);

}

function group(description, fn) {

log(description);

indentMore();

fn();

indentLess();

}

function indenter() {

if (typeof indenter.indent !== 'undefined' && Number.isInteger(indenter.indent))

return ' '.repeat(indenter.indent);

return '';

}

function indentMore() {

if (typeof indenter.indent === 'undefined' || !Number.isInteger(indenter.indent))

indenter.indent = 0;

indenter.indent += 2;

}

function indentLess() {

if (typeof indenter.indent === 'undefined' || !Number.isInteger(indenter.indent))

indenter.indent = 0;

indenter.indent -= 2;

indenter.indent = Math.max(0, indenter.indent);

}

function log(message, color) {

const prefix = indenter() + (color ? `\x1b[${color}m` : '');

const suffix = color ? '\033[0m' : '';

console.log(prefix + message + suffix);

}

Resources:

- Hoare Triple
- Preconditions and postconditions defining a program.
- https://wiki.c2.com/?HoareTriple
- https://softwarefoundations.cis.upenn.edu/plf-current/Hoare.html
- Tony himself expounding upon it:
- https://www.youtube.com/watch?v=czzp8gMESSY

- Hoar's paper:
- https://dl.acm.org/doi/pdf/10.1145/363235.363259
- the less exciting page pointing to it: https://dl.acm.org/doi/10.1145/363235.363259

- Kevlin Henney presenting on GUTs
- https://www.youtube.com/watch?v=tWn8RA_DEic
- https://www.youtube.com/watch?v=azoucC_fwzw
- https://www.theregister.com/2007/07/28/what_are_your_units/