Skip to content

Instantly share code, notes, and snippets.

@jalehman
Created October 15, 2015 03:39
Show Gist options
  • Save jalehman/314d6ca940bd8c3a2c66 to your computer and use it in GitHub Desktop.
Save jalehman/314d6ca940bd8c3a2c66 to your computer and use it in GitHub Desktop.
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<title>Telegraph Prep Week 2</title>
<meta name="description" content="JavaScript Fundamentals: Objects, Arrays and Functions">
</head>
<body>
<div>
<h2> This Page is intentionally left blank. Please open the javascript console in your developer tools</p>
</div>
</body>
<script type="text/javascript" src="bookstore_data.js"></script>
<script type="text/javascript" src="helpers.js"></script>
<script type="text/javascript" src="bookstore.js"></script>
</html>
// The default approach to this problem has been to define a global bookstore
// like so:
var globalBookStore = __createBookStore();
// And to have all of our code operate on this global bookstore. There are some
// problems with this approach.
// Imagine that our deletion operation looks like this:
function statefulDeleteBook(book) {
// ...delete book from globalBookStore...
return book;
}
// What happens when I do this?
var book = {title: "Test"};
statefulDeleteBook(book);
statefulDeleteBook(book);
// The first time the book should be returned, and the second time I should get
// undefined. This is what's callend an *impure* function, or a function with
// *side-effects* -- even though the function is called with the same input, it
// returns *different* outputs each time. These kinds of functions are harder to
// debug, because it isn't apparent what the output will be when you call the
// function.
// Why does it matter?
// Imagine that I also have a function to check the store for a book, defined
// something like this:
function statefulCheckStore(query) {
// Searches the `globalBookStore` for books matching `query`, and returns the
// matching book if found; otherwise `undefined`.
}
// If I'm testing code that does a combination of `statefulCheckStore`ing and
// `statefulDeleteBook`ing, the order in which I call those functions will matter:
var book2 = {title: "Test"};
statefulCheckStore("Test");
statefulDeleteBook(book);
statefulCheckStore("Test");
// There's a cleaner way that we can define these operations in such a way that
// they do not depend on a piece of global state, and that's by parameterizing
// the `bookStore` itself. Here's an alternate implementation:
// Deletes a book from the input book store, and returns the deleted book if
// found; otherwise `undefined`.
function __deleteBook(bookStore, book) {
return book;
}
// Searches the input bookStore for books matching `query`, and returns the
// matching book if found; otherwise `undefined`.
function __checkStore(bookStore, query) {
// ...
}
// Structuring the code in this fashion means that we can test the actual
// functionality of the application with *mocked* state (the bookStore) -- this
// means that we can model our logic as *pure* functions. This means that given
// the same inputs, our functions always return the same output.
// Now, we can get the same behavior as before:
var store = __createBookStore();
var book3 = {title: "Test"};
__deleteBook(store, book);
__deleteBook(store, book);
// Or we do more interesting things
//var store2 = __createBookStore();
__deleteBook(__createBookStore(), book3); // should return the book
__deleteBook(__createBookStore(), book3); // exact same result as above
__deleteBook([], book3); // should return undefined, as there are no books in this store!
__deleteBook(moesBookStore, book3); // delete book from Moe's book store
var App = function() {
var store = __createBookStore();
return {
deleteBook: function(book) {
return __deleteBook(store, book);
},
checkStore: function(query) {
return __checkStore(store, query);
}
};
};
var __data = {
books:"Lucky Jim by Kingsley Amis, Money by Martin Amis, The Information by Martin Amis, The Bottle Factory Outing by Beryl Bainbridge, According to Queeney by Beryl Bainbridge, Flaubert's Parrot by Julian Barnes, A History of the World in 10 1/2 Chapters by Julian Barnes, Augustus Carp Esq. by Himself: Being the Autobiography of a Really Good Man by Henry Howarth Bashford, Molloy by Samuel Beckett, Zuleika Dobson by Max Beerbohm, The Adventures of Augie March by Saul Bellow, The Uncommon Reader by Alan Bennett, Queen Lucia by EF Benson, The Ascent of Rum Doodle by WE Bowman, A Good Man in Africa by William Boyd, The History Man by Malcolm Bradbury, No Bed for Bacon by Caryl Brahms and SJ Simon, Illywhacker by Peter Carey, A Season in Sinji by JL Carr, The Harpole Report by JL Carr, The Hearing Trumpet by Leonora Carrington, Mister Johnson by Joyce Cary, The Horse's Mouth by Joyce Cary, Don Quixote by Miguel de Cervantes, The Case of the Gilded Fly by Edmund Crispin, Just William by Richmal Crompton, The Provincial Lady by EM Delafield, Slouching Towards Kalamazoo by Peter De Vries, The Pickwick Papers by Charles Dickens, Martin Chuzzlewit by Charles Dickens, Jacques the Fatalist and his Master by Denis Diderot, A Fairy Tale of New York by JP Donleavy, The Commitments by Roddy Doyle, Ennui by Maria Edgeworth, Cheese by Willem Elsschot, Bridget Jones's Diary by Helen Fielding, Joseph Andrews by Henry Fielding, Tom Jones by Henry Fielding, Caprice by Ronald Firbank, Bouvard et Pécuchet by Gustave Flaubert, Towards the End of the Morning by Michael Frayn, The Polygots by William Gerhardie, Cold Comfort Farm by Stella Gibbons, Dead Souls by Nikolai Gogol, Oblomov by Ivan Goncharov, The Wind in the Willows by Kenneth Grahame, Brewster's Millions by Richard Greaves (George Barr McCutcheon), Squire Haggard's Journal by Michael Green, Our Man in Havana by Graham Greene, Travels with My Aunt by Graham Greene, Diary of a Nobody by George Grossmith, The Little World of Don Camillo by Giovanni Guareschi, The Curious Incident of the Dog in the Night-time by Mark Haddon, Catch-22 by Joseph Heller, Mr Blandings Builds His Dream House by Eric Hodgkins, High Fidelity by Nick Hornby, I Served the King of England by Bohumil Hrabal, The Lecturer's Tale by James Hynes, Mr Norris Changes Trains by Christopher Isherwood, The Mighty Walzer Howard by Jacobson, Pictures from an Institution by Randall Jarrell, Three Men in a Boat by Jerome K Jerome, Finnegans Wake by James Joyce, The Castle by Franz Kafka, Lake Wobegon Days by Garrison Keillor, Death and the Penguin by Andrey Kurkov, The Debt to Pleasure by John Lanchester, L'Histoire de Gil Blas de Santillane (Gil Blas) by Alain-René Lesage, Changing Places by David Lodge, Nice Work by David Lodge, The Towers of Trebizond by Rose Macaulay, England Their England by AG Macdonell, Whisky Galore by Compton Mackenzie, Memoirs of a Gnostic Dwarf by David Madsen, Cakes and Ale - Or the Skeleton in the Cupboard by W Somerset Maugham, Tales of the City by Armistead Maupin, Bright Lights Big City by Jay McInerney, Puckoon by Spike Milligan, The Restraint of Beasts by Magnus Mills, Charade by John Mortimer, Titmuss Regained by John Mortimer, Under the Net by Iris Murdoch, Pnin by Vladimir Nabokov, Pale Fire by Vladimir Nabokov, Fireflies by Shiva Naipaul, The Sacred Book of the Werewolf by Victor Pelevin, La Disparition by Georges Perec, Les Revenentes by Georges Perec, La Vie Mode d'Emploi by Georges Perec, My Search for Warren Harding by Robert Plunkett, A Dance to the Music of Time by Anthony Powell, A Time to be Born by Dawn Powell, Excellent Women by Barbara Pym, Less Than Angels by Barbara Pym, Zazie in the Metro by Raymond Queneau, Solomon Gursky Was Here by Mordecai Richler, Alms for Oblivion by Simon Raven, Portnoy's Complaint by Philip Roth, The Westminster Alice by Saki, The Unbearable Bassington by Saki , Hurrah for St Trinian's by Ronald Searle, Great Apes by Will Self, Porterhouse Blue by Tom Sharpe, Blott on the Landscape by Tom Sharpe, Office Politics by Wilfrid Sheed, Belles Lettres Papers: A Novel by Charles Simmons, Moo by Jane Smiley, Topper Takes a Trip by Thorne Smith, The Adventures of Ferdinand Count Fathom by Tobias Smollett, The Adventures of Roderick Random by Tobias Smollett, The Adventures of Peregrine Pickle by Tobias Smollett, The Expedition of Humphry Clinker by Tobias Smollett, The Prime of Miss Jean Brodie by Muriel Spark, The Girls of Slender Means by Muriel Spark, The Driver's Seat by Muriel Spark, Loitering with Intent by Muriel Spark, A Far Cry from Kensington by Muriel Spark, The Life and Opinions by Tristram Shandy, Gentleman by Laurence Sterne, White Man Falling by Mike Stocks, Handley Cross by RS Surtees, A Tale of a Tub by Jonathan Swift, Penrod by Booth Tarkington, The Luck of Barry Lyndon by William Makepeace Thackeray, Before Lunch by Angela Thirkell, Tropic of Ruislip by Leslie Thomas, A Confederacy of Dunces by John Kennedy Toole, Barchester Towers by Anthony Trollope, Venus on the Half-Shell by Kilgore Trout, The Mysterious Stranger by Mark Twain, The Witches of Eastwick by John Updike, Breakfast of Champions by Kurt Vonnegut, Infinite Jest by David Foster Wallace, Decline and Fall by Evelyn Waugh, Vile Bodies by Evelyn Waugh, Black Mischief by Evelyn Waugh, Scoop by Evelyn Waugh, The Loved One by Evelyn Waugh, A Handful of Dust by Evelyn Waugh , The Life and Loves of a She-Devil by Fay Weldon, Tono Bungay by HG Wells, Molesworth by Geoffrey Willans and Ronald Searle, The Wimbledon Poisoner by Nigel Williams, Anglo-Saxon Attitudes by Angus Wilson, Something Fresh by PG Wodehouse, Piccadilly Jim by PG Wodehouse, Thank You Jeeves by PG Wodehouse, Heavy Weather by PG Wodehouse, The Code of the Woosters by PG Wodehouse, Joy in the Morning by PG Wodehouse",
categories: ['classic', 'horror', 'romantic comedy', 'self help', 'historical']
};
// Returns an array of "book" objects, each of which have title, author, price
// and category keys.
function __createBookStore() {
var __books = __data.books;
var __bookStore = [];
var __booksArray = __books.split(',');
var __categories = __data.categories;
function __createBook(bookName){
var price = Math.random() * 20;
price = parseFloat(price.toString().slice(0, 4), 10);
var category = (__categories[Math.floor(Math.random() * 5)]);
return {
title: bookName.split('by')[0].trim(),
author: bookName.split('by')[1].trim(),
price: price,
category: category
};
}
function __createBookStore(arr) {
for (var i = 0; i < arr.length; i++) {
__bookStore.push(__createBook(arr[i]));
}
return __bookStore;
}
return __createBookStore(__booksArray);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment