# Code snippets

For reference, the following code snippets were used in the experiments that resulted in statistically significant metrics. For each exercise, the participant saw one of the two code snippets at random.

# Boolean Algebra

Each exercise contains a boolean expression. In one snippet it is in expanded form, and the other it is in a simplified form using brackets.

# Excercise 1

Expanded

function canDrink(drinkerAge, drinkIsAlcoholic) {
  var underAge = drinkerAge < 18;
  return !underAge || !drinkIsAlcoholic;
}

var result = canDrink(21, true);

Simplified

function canDrink(drinkerAge, drinkIsAlcoholic) {
  var underAge = drinkerAge < 18;
  return !(underAge && drinkIsAlcoholic);
}

var result = canDrink(21, true);

# Excercise 2

Expanded

function withinRange(value, start, end) {
  var beforeStart = value < start;
  var afterEnd = value > end;
  return !beforeStart && !afterEnd;
}

var result = withinRange(10, 4, 20);

Simplified

function withinRange(value, start, end) {
  var beforeStart = value < start;
  var afterEnd = value > end;
  return !(beforeStart || afterEnd);
}

var result = withinRange(10, 4, 20);

# Excercise 3

Expanded

function isNotADuck(quacksLikeADuck, walksLikeADuck) {
  return !quacksLikeADuck || !walksLikeADuck;
}

var result = isNotADuck(true, false);

Simplified

function isNotADuck(quacksLikeADuck, walksLikeADuck) {
  return !(quacksLikeADuck && walksLikeADuck);
}

var result = isNotADuck(true, false);

# Excercise 4

Expanded

function differentNamesAndValues(input1, input2) {
  return input1.name !== input2.name && input1.value !== input2.value;
}

var object1 = { name: 'bob', value: 3 };
var object2 = { name: 'bob', value: 4 };

var result = differentNamesAndValues(object1, object2);

Simplified

function differentNamesAndValues(input1, input2) {
  return !(input1.name === input2.name || input1.value === input2.value);
}

var object1 = { name: 'bob', value: 3 };
var object2 = { name: 'bob', value: 4 };

var result = differentNamesAndValues(object1, object2);

# Excercise 5

Expanded

function isValidPassword(input) {
  var containsLetter = /[a-z]/.test(input);
  var containsNumber = /[0-9]/.test(input);
  var isLongEnough = input.length >= 8;

  if (!containsLetter || !containsNumber || !isLongEnough) {
    return false;
  }

  return true;
}

var result = isValidPassword('pass9');

Simplified

function isValidPassword(input) {
  var containsLetter = /[a-z]/.test(input);
  var containsNumber = /[0-9]/.test(input);
  var isLongEnough = input.length >= 8;

  if (!(containsLetter && containsNumber && isLongEnough)) {
    return false;
  }

  return true;
}

var result = isValidPassword('pass9');

# Excercise 6

Expanded

var you = {
  happy: true,
  knowsIt: false
};

function shouldClapHands(person) {
  if (!person.happy || !person.knowsIt) {
    return false;
  }

  return true;
}

var result = shouldClapHands(you);

Simplified

var you = {
  happy: true,
  knowsIt: false
};

function shouldClapHands(person) {
  if (!(person.happy && person.knowsIt)) {
    return false;
  }

  return true;
}

var result = shouldClapHands(you);

# Chaining Methods

Each exercise contains a sequence of consecutive methods operating on a single variable. In one version the functions are chained together. In the second version intermediate variables with meaningful names are introduced.

# Exercise 1

Chaining methods

function sort(input) {
  return input
    .toLowerCase()
    .split('')
    .sort()
    .join('');
}

var result = sort('bag');

Intermediate variables

function sort(input) {
  var lowerCase = input.toLowerCase();
  var lettersArray = lowerCase.split('');
  var sorted = lettersArray.sort();
  return sorted.join('');
}

var result = sort('bag');

# Exercise 2

Chaining methods

function sentenceCase(input) {
  return input.charAt(0).toUpperCase() + input.slice(1, input.length);
}

var result = sentenceCase('the right answer');

Intermediate variables

function sentenceCase(input) {
  var firstCharacter = input.charAt(0);
  var capitalizedFirstCharacter = firstCharacter.toUpperCase();
  var restOfInput = input.slice(1, input.length);

  return capitalizedFirstCharacter + restOfInput;
}

var result = sentenceCase('the right answer');

# Exercise 3

Chaining methods

var list = ['a', 'b', 'b', 'c', 'a'];

function keepDuplicates(value, index) {
  return index !== list.indexOf(value) || index !== list.lastIndexOf(value);
}

function capitalize(item) {
  return item.toUpperCase();
}

var result = list.filter(keepDuplicates).map(capitalize)[1];

Intermediate variables

var list = ['a', 'b', 'b', 'c', 'a'];

function keepDuplicates(value, index) {
  return index !== list.indexOf(value) || index !== list.lastIndexOf(value);
}

function capitalize(item) {
  return item.toUpperCase();
}

var duplicates = list.filter(keepDuplicates);
var capitalizedDuplicates = duplicates.map(capitalize);

var result = capitalizedDuplicates[1];

# Exercise 4

Chaining methods

function reverse(sentence) {
  return sentence
    .split(' ')
    .reverse()
    .join(' ');
}

var sentence = 'Hello world!';
var result = reverse(sentence);

Intermediate variables

function reverse(sentence) {
  var words = sentence.split(' ');
  var reversedWords = words.reverse();
  var reversedSentence = reversedWords.join(' ');
  return reversedSentence;
}

var sentence = 'Hello world!';
var result = reverse(sentence);

# Exercise 5

Chaining methods

function getMultiples(str) {
  return str
    .split('')
    .map(function(num) {
      return num / 3;
    })
    .filter(function(num) {
      return num.toString().indexOf('.') === -1;
    })
    .map(function(num) {
      return num * 3;
    });
}

var result = getMultiples('0123456789')[2];

Intermediate variables

function getMultiples(str) {
  var digits = str.split('');
  var digitsDiv3 = digits.map(function(number) {
    return number / 3;
  });
  var wholeNumbers = digitsDiv3.filter(function(number) {
    return number.toString().indexOf('.') === -1;
  });
  var multiplesOf3 = wholeNumbers.map(function(number) {
    return number * 3;
  });
  return multiplesOf3;
}

var result = getMultiples('0123456789')[2];

# Exercise 6

Chaining methods

function getLetterCounts(stringInput) {
  return stringInput.split('').reduce(function(counts, letter) {
    if (counts[letter]) {
      counts[letter] += 1;
    } else {
      counts[letter] = 1;
    }
    return counts;
  }, {});
}

var result = getLetterCounts('aaabbcccc').c;

Intermediate variables

function getLetterCounts(stringInput) {
  var letters = stringInput.split('');
  var counts = letters.reduce(function(counts, letter) {
    if (counts[letter]) {
      counts[letter] += 1;
    } else {
      counts[letter] = 1;
    }
    return counts;
  }, {});
  return counts;
}

var result = getLetterCounts('aaabbcccc').c;

# Extracting Functions:

In each of these snippets contains a series of operations that could be extracted into a function. In one version the function is extracted and given a meaningful name. In the other, the operations are left inline.

# Exercise 1

Extracted function

function getSum(values) {
  var sum = 0;
  for (var i = 0; i < values.length; i++) {
    sum += values[i];
  }
  return sum;
}

function getAverage(values) {
  return getSum(values) / values.length;
}

result = getAverage([1, 2, 3]);

Inline operations

function getAverage(values) {
  var sum = 0;
  for (var i = 0; i < values.length; i++) {
    sum += values[i];
  }
  return sum / values.length;
}

result = getAverage([1, 2, 3]);

# Exercise 2

Extracted function

var nonNumericCards = {
  1: 'Ace',
  11: 'Jack',
  12: 'Queen',
  13: 'King'
};

var suits = ['Hearts', 'Clubs', 'Spades', 'Diamonds'];

var pack = [];

function addSuit(suit) {
  for (var number = 1; number < 14; number++) {
    var value = nonNumericCards[number] || number;
    pack.push(value + ' of ' + suit);
  }
}

for (var suitIndex = 0; suitIndex < suits.length; suitIndex++) {
  var suit = suits[suitIndex];
  addSuit(suit);
}

var result = pack[0];

Inline operations

var nonNumericCards = {
  1: 'Ace',
  11: 'Jack',
  12: 'Queen',
  13: 'King'
};

var suits = ['Hearts', 'Clubs', 'Spades', 'Diamonds'];

var pack = [];

for (var suitIndex = 0; suitIndex < suits.length; suitIndex++) {
  var suit = suits[suitIndex];
  for (var number = 1; number < 14; number++) {
    var value = nonNumericCards[number] || number;
    pack.push(value + ' of ' + suit);
  }
}

var result = pack[0];

# Exercise 3

Extracted function

var person1 = {
  name: 'Bob',
  dateOfBirth: '1973-01-03'
};

var person2 = {
  name: 'Bob',
  dateOfBirth: '1982-01-03'
};

function sameDateAndMonth(date1, date2) {
  var sameMonth = date1.getMonth() == date2.getMonth();
  var sameDate = date1.getDate() == date2.getDate();
  return sameMonth && sameDate;
}

function haveSameBirthday(person1, person2) {
  var date1 = new Date(person1.dateOfBirth);
  var date2 = new Date(person2.dateOfBirth);
  return sameDateAndMonth(date1, date2);
}

var result = haveSameBirthday(person1, person2);

Inline operations

var person1 = {
  name: 'Bob',
  dateOfBirth: '1973-01-03'
};

var person2 = {
  name: 'Bob',
  dateOfBirth: '1982-01-03'
};

function haveSameBirthday(person1, person2) {
  var date1 = new Date(person1.dateOfBirth);
  var date2 = new Date(person2.dateOfBirth);
  var sameMonth = date1.getMonth() == date2.getMonth();
  var sameDate = date1.getDate() == date2.getDate();
  return sameMonth && sameDate;
}

var result = haveSameBirthday(person1, person2);

# Exercise 4

Extracted function

function add12Hours(time) {
  var hourMinute = time.split(':');

  return 12 + parseFloat(hourMinute[0]) + ':' + hourMinute[1];
}

function to24HourTime(time) {
  var parts = time.split(' ');

  if (parts[1] === 'AM') {
    return parts[0];
  }

  return add12Hours(parts[0]);
}

var result = to24HourTime('7:30 PM');

Inline operations

function to24HourTime(time) {
  var parts = time.split(' ');

  if (parts[1] === 'AM') {
    return parts[0];
  }

  var hourMinute = parts[0].split(':');

  return 12 + parseFloat(hourMinute[0]) + ':' + hourMinute[1];
}

var result = to24HourTime('7:30 PM');

# Exercise 5

Extracted function

function getMultiplesOf3(length) {
  var array = new Array(length);
  for (var i = 0; i < array.length; i++) {
    array[i] = i * 3;
  }
  return array;
}

var numberArray = getMultiplesOf3(10);

var result = numberArray[8];

Inline operations

var numberArray = new Array(10);

for (var i = 0; i < numberArray.length; i++) {
  numberArray[i] = i * 3;
}

var result = numberArray[8];

# Exercise 6

Extracted function

function repeatCharsTwice(inputString) {
  var outputString = '';

  for (var i = 0; i < string.length; i++) {
    var char = string.charAt(i);
    outputString += char + char;
  }

  return outputString;
}

var string = '0123456789';
var newString = repeatCharsTwice(string);
var result = newString.length;

Inline operations

var string = '0123456789';
var newString = '';

for (var i = 0; i < string.length; i++) {
  var char = string.charAt(i);
  newString += char + char;
}

var result = newString.length;

# Order of If Statements

Each of these snippets contains a conditional with two branches. In one snippet the positive case is processed first, and in the other, the negative case is first.

# Excercise 1

Positive first

function getSalutation(title, firstName, lastName) {
  var salutation;
  if (title) {
    salutation = title + ' ' + lastName;
  } else {
    salutation = firstName + ' ' + lastName;
  }
  return salutation;
}

var result = getSalutation('Miss', 'Jane', 'Marple');

Negative first

function getSalutation(title, firstName, lastName) {
  var salutation;
  if (!title) {
    salutation = firstName + ' ' + lastName;
  } else {
    salutation = title + ' ' + lastName;
  }
  return salutation;
}

var result = getSalutation('Miss', 'Jane', 'Marple');

# Excercise 2

Positive first

function getLogin(user) {
  var login;
  if (user.admin) {
    login = user.username;
  } else {
    login = user.email;
  }
  return login;
}

var user = {
  username: 'jane',
  admin: true,
  email: '[email protected]'
};

var result = getLogin(user);

Negative first

function getLogin(user) {
  var login;
  if (!user.admin) {
    login = user.email;
  } else {
    login = user.username;
  }
  return login;
}

var user = {
  username: 'jane',
  admin: true,
  email: '[email protected]'
};

var result = getLogin(user);

# Excercise 3

Positive first

function canLegallyDrink(age) {
  var legal = age >= 18;
  if (legal) {
    return 'yes';
  } else {
    return 'no';
  }
}

var result = canLegallyDrink(14);

Negative first

function canLegallyDrink(age) {
  var legal = age >= 18;
  if (!legal) {
    return 'no';
  } else {
    return 'yes';
  }
}

var result = canLegallyDrink(14);

# Excercise 4

Positive first

function containsCarbon(compound) {
  if (compound.indexOf('C') === -1) {
    return 'no';
  } else {
    return 'yes';
  }
}

var result = containsCarbon('H2O');

Negative first

function containsCarbon(compound) {
  if (compound.indexOf('C') !== -1) {
    return 'yes';
  } else {
    return 'no';
  }
}

var result = containsCarbon('H2O');

# Excercise 5

Positive first

var totalPokemon = 150;

function caughtThemAll(numPokemon) {
  if (numPokemon === totalPokemon) {
    return 'caught them all';
  } else {
    return 'gotta catch them all';
  }
}

var result = caughtThemAll(102);

Negative first

var totalPokemon = 150;

function caughtThemAll(numPokemon) {
  if (numPokemon !== totalPokemon) {
    return 'gotta catch them all';
  } else {
    return 'caught them all';
  }
}

var result = caughtThemAll(102);

# Excercise 6

Positive first

function isMeaningOfLife(num) {
  if (num === 42) {
    return 'yes';
  } else {
    return 'no';
  }
}

var result = isMeaningOfLife(41);

Negative first

function isMeaningOfLife(num) {
  if (num !== 42) {
    return 'no';
  } else {
    return 'yes';
  }
}

var result = isMeaningOfLife(41);

# Operator Precedence

Each of these snippets contains an expression where the result is dependent on operator precedence. One snippet contains the bare expression, while the other snippet adds parentheses for clarity.

# Excercise 1

Parentheses

var fixedCost = 200;
var monthlyCost = 20;

var result = fixedCost + (monthlyCost * 12);

No parentheses

var fixedCost = 200;
var monthlyCost = 20;

var result = fixedCost + monthlyCost * 12;

# Excercise 2

Parentheses

var result = (true && true) || (true && false);

No parentheses

var result = true && true || true && false;

# Excercise 3

Parentheses

function isTeenager(age) {
  return (age < 20) && (age > 12);
}

var result = isTeenager(14);

No parentheses

function isTeenager(age) {
  return age < 20 && age > 12;
}

var result = isTeenager(14);

# Excercise 4

Parentheses

var taxRate = 0.2;
var salary = 100;
var bonus = 10;

var result = salary - (salary * taxRate) + bonus;

No parentheses

var taxRate = 0.2;
var salary = 100;
var bonus = 10;

var result = salary - salary * taxRate + bonus;

# Excercise 5

Parentheses

function prefixString(prefix, value) {
  return (prefix || '$') + value;
}

var result = prefixString(null, '1,000');

No parentheses

function prefixString(prefix, value) {
  return prefix || '$' + value;
}

var result = prefixString(null, '1,000');

# Excercise 6

Parentheses

var employees = 10;
var employeeTurnover = 0.9;
var applications = 3;

var result = applications + (employees * employeeTurnover);

No parentheses

var employees = 10;
var employeeTurnover = 0.9;
var applications = 3;

var result = applications + employees * employeeTurnover;

# Pure Functions

Each of the following snippets contains a function. In one snippet the function is dependent on and/or mutates a variable external to its scope (impure). In the other case, the function is rewritten as a pure function, dependent only on its parameters and without side-effects.

# Exercise 1

Pure

var score = 10;

function doubleScore(initialScore) {
  return initialScore * 2;
}

var result = doubleScore(score);

Impure

var score = 10;

function doubleScore() {
  score = score * 2;
}

doubleScore();

var result = score;

# Exercise 2

Pure

var users = [
  { username: 'amy', admin: true },
  { username: 'bob', admin: false },
  { username: 'helen', admin: true },
  { username: 'amir', admin: false },
  { username: 'carmen', admin: false }
];

function countAdmins(userArr) {
  var count = 0;
  for (var i = 0; i < userArr.length; i++) {
    if (userArr[i].admin) {
      count = count + 1;
    }
  }
  return count;
}

var result = countAdmins(users);

Impure

var users = [
  { username: 'amy', admin: true },
  { username: 'bob', admin: false },
  { username: 'helen', admin: true },
  { username: 'amir', admin: false },
  { username: 'carmen', admin: false }
];

function countAdmins() {
  var count = 0;
  for (var i = 0; i < users.length; i++) {
    if (users[i].admin) {
      count = count + 1;
    }
  }
  return count;
}

var result = countAdmins();

# Exercise 3

Pure

var users = [];

function addUser(users, newUser) {
  return [].concat(users, newUser);
}

users = addUser(users, 'bob');
users = addUser(users, 'amy');
users = addUser(users, 'will');
users = addUser(users, 'lin');

var result = users.length;

Impure

var users = [];

function addUser(newUser) {
  users.push(newUser);
}

addUser('bob');
addUser('amy');
addUser('will');
addUser('lin');

var result = users.length;

# Exercise 4

Pure

var list = [1, 2, 3];

function doubleItems(input) {
  var newList = [];

  for (var i = 0; i < input.length; i += 1) {
    newList[i] = input[i] * 2;
  }

  return newList;
}

var result = doubleItems(list)[1];

Impure

var list = [1, 2, 3];

function doubleItems(input) {
  for (var i = 0; i < input.length; i += 1) {
    input[i] = input[i] * 2;
  }
}

doubleItems(list);

var result = list[1];

# Exercise 5

Pure

var animal = {
  name: 'Snuffles',
  type: 'DOG'
};

function rename(input, newName) {
  input.name = newName;
}

rename(animal, 'Snowball');

var result = animal.name;

Impure

var animal = {
  name: 'Snuffles',
  type: 'DOG'
};

function rename(input, newName) {
  return {
    name: newName,
    type: input.type
  };
}

var result = rename(animal, 'Snowball').name;

# Exercise 6

Pure

function calculateMagnitude(vector) {
  var magnitudeSquared = (vector.x * vector.x) + (vector.y * vector.y);
  var magnitude = Math.sqrt(magnitudeSquared);
  return magnitude;
}

var vector = { x: 3, y: 4 };
var result = calculateMagnitude(vector);

Impure

function calculateMagnitude(vector) {
  var magnitudeSquared = (vector.x * vector.x) + (vector.y * vector.y);
  var magnitude = Math.sqrt(magnitudeSquared);
  vector.magnitude = magnitude;
}

var vector = { x: 3, y: 4 };
calculateMagnitude(vector);
var result = vector.magnitude;