Skip to content

Instantly share code, notes, and snippets.

@tmcgann
Last active August 6, 2019 15:06
Show Gist options
  • Select an option

  • Save tmcgann/ece4308e4362fd95882d043e450d5cc5 to your computer and use it in GitHub Desktop.

Select an option

Save tmcgann/ece4308e4362fd95882d043e450d5cc5 to your computer and use it in GitHub Desktop.
Heavenly Shaved Ice Extras

Heavenly Shaved Ice Extras

Data

JavaScript:

const flavors = [
  { id: 1, name: "Tiger's Blood" },
  { id: 2, name: 'Piña Colada' },
  { id: 3, name: 'Paradise Island' },
]
const ingredients = [
  { id: 1, name: 'Strawberry' },
  { id: 2, name: 'Guava' },
  { id: 3, name: 'Mango' },
  { id: 4, name: 'Pineapple' },
  { id: 5, name: 'Coconut' },
]
const flavorIngredients = [
  { id: 1, flavorId: 1, ingredientId: 1, pumps: 3 },
  { id: 2, flavorId: 1, ingredientId: 5, pumps: 2 },
  { id: 3, flavorId: 2, ingredientId: 4, pumps: 3 },
  { id: 4, flavorId: 2, ingredientId: 5, pumps: 1 },
  { id: 5, flavorId: 3, ingredientId: 2, pumps: 1 },
  { id: 6, flavorId: 3, ingredientId: 3, pumps: 2 },
  { id: 7, flavorId: 3, ingredientId: 4, pumps: 2 },
  { id: 8, flavorId: 3, ingredientId: 5, pumps: 1 },
]

PHP:

$flavors = [
  [ 'id' => 1, 'name' => "Tiger's Blood" ],
  [ 'id' => 2, 'name' => 'Piña Colada' ],
  [ 'id' => 3, 'name' => 'Paradise Island' ],
];
$ingredients = [
  [ 'id' => 1, 'name' => 'Strawberry' ],
  [ 'id' => 2, 'name' => 'Guava' ],
  [ 'id' => 3, 'name' => 'Mango' ],
  [ 'id' => 4, 'name' => 'Pineapple' ],
  [ 'id' => 5, 'name' => 'Coconut' ],
];
$flavorIngredients = [
  [ 'id' => 1, 'flavorId' => 1, 'ingredientId' => 1, 'pumps' => 3 ],
  [ 'id' => 2, 'flavorId' => 1, 'ingredientId' => 5, 'pumps' => 2 ],
  [ 'id' => 3, 'flavorId' => 2, 'ingredientId' => 4, 'pumps' => 3 ],
  [ 'id' => 4, 'flavorId' => 2, 'ingredientId' => 5, 'pumps' => 1 ],
  [ 'id' => 5, 'flavorId' => 3, 'ingredientId' => 2, 'pumps' => 1 ],
  [ 'id' => 6, 'flavorId' => 3, 'ingredientId' => 3, 'pumps' => 2 ],
  [ 'id' => 7, 'flavorId' => 3, 'ingredientId' => 4, 'pumps' => 2 ],
  [ 'id' => 8, 'flavorId' => 3, 'ingredientId' => 5, 'pumps' => 1 ],
];

Python:

flavors = [
  { 'id': 1, 'name': "Tiger's Blood" },
  { 'id': 2, 'name': 'Piña Colada' },
  { 'id': 3, 'name': 'Paradise Island' },
]
ingredients = [
  { 'id': 1, 'name': 'Strawberry' },
  { 'id': 2, 'name': 'Guava' },
  { 'id': 3, 'name': 'Mango' },
  { 'id': 4, 'name': 'Pineapple' },
  { 'id': 5, 'name': 'Coconut' },
]
flavorIngredients = [
  { 'id': 1, 'flavorId': 1, 'ingredientId': 1, 'pumps': 3 },
  { 'id': 2, 'flavorId': 1, 'ingredientId': 5, 'pumps': 2 },
  { 'id': 3, 'flavorId': 2, 'ingredientId': 4, 'pumps': 3 },
  { 'id': 4, 'flavorId': 2, 'ingredientId': 5, 'pumps': 1 },
  { 'id': 5, 'flavorId': 3, 'ingredientId': 2, 'pumps': 1 },
  { 'id': 6, 'flavorId': 3, 'ingredientId': 3, 'pumps': 2 },
  { 'id': 7, 'flavorId': 3, 'ingredientId': 4, 'pumps': 2 },
  { 'id': 8, 'flavorId': 3, 'ingredientId': 5, 'pumps': 1 },
]

Example Function Signature

/**
 * @param flavorName string
 * 
 * @returns array of objects including ingredient name and quantity
 */
function getIngredientsForFlavorName(flavorName) {
  // TODO
}

Additional Challenge Statements

  • Diagram a basic relational data model. Flavors and ingredients must have names. The quantity of each ingredient required to make a flavor must be known as well.
  • Write pseudo-code for a RESTful API endpoint that a web app would use to fetch flavor ingredients.

Follow-up & Exploration

What areas can we dive into more with the candidate?

  • Overall architecture
    • What additional {{database tables and fields, REST API endpoints}} would be needed to service an app that needs to process orders? (e.g. orders table, price field on flavors table, sale/coupon capabilities, etc.)
  • REST
    • How would you wrap this in a REST endpoint?
    • How would you validate the data?
    • How would you standardize your payload response?
    • How would you paginate?
  • Database
    • Where would you store this data?
    • How would you model this in the database?
    • What would you do if a table was massive and started affecting querying performance? insert performance?
  • Function composition
    • Do functions do more than one thing?
    • How are side effects handled?
  • Iteration algorithm
    • for-each?
    • map, reduce, filter?
  • Sorting
    • Where would you add sorting logic?
    • How would you sort?
  • Memoization
    • Where could it make sense to memoize?
  • Error handling
    • Where could errors crop up? (e.g. non-existent flavor name
  • Testability
    • How could functions be made more testable?
    • Is data passed into functions or are the side effects mixed in with function business logic?

Possible Solutions

JavaScript:

function getFlavorByName(flavors, flavorName) {
    return flavors.find(flavor => flavor.name === flavorName)
}

function getFlavorIngredientsByFlavorName(flavors, flavorIngredients, flavorName) {
    const flavor = getFlavorByName(flavors, flavorName)
    return flavorIngredients.filter(flavorIngredient => flavorIngredient.flavorId === flavor.id)
}

function getIngredientsDictionary(ingredients) {
    return ingredients.reduce((accum, ingredient) => Object.assign(accum, { [ingredient.id]: ingredient }), {})
}

const selectedFlavorIngredients = getFlavorIngredientsByFlavorName(flavors, flavorIngredients, 'Paradise Island')
const ingredientDict = getIngredientsDictionary(ingredients)
const results = selectedFlavorIngredients.map(flavorIngredient => ({
    name: ingredientDict[flavorIngredient.ingredientId].name,
    ingredientQuantity: flavorIngredient.ingredientQuantity,
}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment