<commit_before>// Tally Votes in JavaScript Pairing Challenge.

// I worked on this challenge with: Michael Jasinski
// This challenge took me [8] hours.

These are the votes cast by each student. Do not alter these objects here.
var votes = {
  "Alex": { president: "Bob", vicePresident: "Devin", secretary: "Gail", treasurer: "Kerry" },
  "Bob": { president: "Mary", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Cindy": { president: "Cindy", vicePresident: "Hermann", secretary: "Bob", treasurer: "Bob" },
  "Devin": { president: "Louise", vicePresident: "John", secretary: "Bob", treasurer: "Fred" },
  "Ernest": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Fred": { president: "Louise", vicePresident: "Alex", secretary: "Ivy", treasurer: "Ivy" },
  "Gail": { president: "Fred", vicePresident: "Alex", secretary: "Ivy", treasurer: "Bob" },
  "Hermann": { president: "Ivy", vicePresident: "Kerry", secretary: "Fred", treasurer: "Ivy" },
  "Ivy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Gail" },
  "John": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Kerry" },
  "Kerry": { president: "Fred", vicePresident: "Mary", secretary: "Fred", treasurer: "Ivy" },
  "Louise": { president: "Nate", vicePresident: "Alex", secretary: "Mary", treasurer: "Ivy" },
  "Mary": { president: "Louise", vicePresident: "Oscar", secretary: "Nate", treasurer: "Ivy" },
  "Nate": { president: "Oscar", vicePresident: "Hermann", secretary: "Fred", treasurer: "Tracy" },
  "Oscar": { president: "Paulina", vicePresident: "Nate", secretary: "Fred", treasurer: "Ivy" },
  "Paulina": { president: "Louise", vicePresident: "Bob", secretary: "Devin", treasurer: "Ivy" },
  "Quintin": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Bob" },
  "Romanda": { president: "Louise", vicePresident: "Steve", secretary: "Fred", treasurer: "Ivy" },
  "Steve": { president: "Tracy", vicePresident: "Kerry", secretary: "Oscar", treasurer: "Xavier" },
  "Tracy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Ullyses": { president: "Louise", vicePresident: "Hermann", secretary: "Ivy", treasurer: "Bob" },
  "Valorie": { president: "Wesley", vicePresident: "Bob", secretary: "Alex", treasurer: "Ivy" },
  "Wesley": { president: "Bob", vicePresident: "Yvonne", secretary: "Valorie", treasurer: "Ivy" },
  "Xavier": { president: "Steve", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Yvonne": { president: "Bob", vicePresident: "Zane", secretary: "Fred", treasurer: "Hermann" },
  "Zane": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Mary" }
}

// Tally the votes in voteCount.
var voteCount = {
  president: { Bob: 3, Cindy: x },
  vicePresident: {},
  secretary: {},
  treasurer: {}
}

/* The name of each student receiving a vote for an office should become a property
of the respective office in voteCount.  After Alex's votes have been tallied,
voteCount would be ...
  var voteCount = {
    president: { Bob: 1 },
    vicePresident: { Devin: 1 },
    secretary: { Gail: 1 },
    treasurer: { Kerry: 1 }
  }
*/

/* Once the votes have been tallied, assign each officer position the name of the
student who received the most votes. */
var officers = {
  president: undefined,
  vicePresident: undefined,
  secretary: undefined,
  treasurer: undefined
}

// Pseudocode
/*
Input: A list of voters and their votes
Output: A list of tallied votes, and a winner for each office

Steps:

Loop through the voters to get their choices
  Loop through each office to get the voter's vote
    IF a candidate received a vote for a particular office, put that name in the appropriate office
  IF a candidate received a vote, tick up the value associated with the candidate in voteCount

Loop through candidates in voteCount
  Initialize the first candidate in officers
  IF the first candidate received fewer votes than the next, change the first to the next

// __________________________________________
// Initial Solution

/*
for (var voter in votes) {
    var choices = votes[voter];
    for(var office in choices) {
      var person = choices[office]
        if(voteCount[office][person] === undefined) {
          voteCount[office][person] = 0;
        }
    voteCount[office][person]++;
    }
}
for (var office in voteCount) {
  for (var candidate in voteCount[office]) {
    var official = officers[office]
    if (official === undefined) {
      officers[office] = candidate;
    }
    if (voteCount[office][officers[office]] < voteCount[office][candidate]) {
      officers[office] = candidate;
    }
  }
}
*/

// __________________________________________
// Refactored Solution

for (var voter in votes) {
    for(var office in votes[voter]) {
      var person = votes[voter][office]
        if(voteCount[office][person] === undefined) {
          voteCount[office][person] = 0;
        }
    voteCount[office][person]++;
    }
}
for (var office in voteCount) {
  for (var candidate in voteCount[office]) {
    var official = officers[office]
    if (official === undefined) {
      officers[office] = candidate;
    }
    if (voteCount[office][officers[office]] < voteCount[office][candidate]) {
      officers[office] = candidate;
    }
  }
}

// __________________________________________
// Reflection
/*
***What did you learn about iterating over nested objects in JavaScript?

I learned how to use the for..in loop effectively to dive through multiple layers of nested data.
This process can become quickly overwhelming however, depending on the complexity of the data structures
you're iterating over. The for..in loop is very powerful though, and is necessary in order to pull
information from objects without resorting to lengthy hardcoding.

***Were you able to find useful methods to help you with this?

I wasn't able to find any built-in methods for objects in JS to help with this, but I found that
variable names were incredibly important in this challenge, because without clearly named variables
it's extremely easy to lose track of what you're doing

***What concepts were solidified in the process of working through this challenge?

Basic JS syntax was solidified for me personally. In this challenge, missing a semi-colon or putting a
curly brace in the wrong place can be the difference between success and broken code. The concepts of
property value pairs and the notation used to access them were also solidified.

*/
// __________________________________________
// Test Code:  Do not alter code below this line.

function assert(test, message, test_number) {
  if (!test) {
    console.log(test_number + "false");
    throw "ERROR: " + message;
  }
  console.log(test_number + "true");
  return true;
}

assert(
  (voteCount.president["Bob"] === 3),
  "Bob should receive three votes for President.",
  "1. "
)

assert(
  (voteCount.vicePresident["Bob"] === 2),
  "Bob should receive two votes for Vice President.",
  "2. "
)

assert(
  (voteCount.secretary["Bob"] === 2),
  "Bob should receive two votes for Secretary.",
  "3. "
)

assert(
  (voteCount.treasurer["Bob"] === 4),
  "Bob should receive four votes for Treasurer.",
  "4. "
)

assert(
  (officers.president === "Louise"),
  "Louise should be elected President.",
  "5. "
)

assert(
  (officers.vicePresident === "Hermann"),
  "Hermann should be elected Vice President.",
  "6. "
)

assert(
  (officers.secretary === "Fred"),
  "Fred should be elected Secretary.",
  "7. "
)

assert(
  (officers.treasurer === "Ivy"),
  "Ivy should be elected Treasurer.",
  "8. "<commit_msg>Fix error<commit_after>// Tally Votes in JavaScript Pairing Challenge.

// I worked on this challenge with: Michael Jasinski
// This challenge took me [8] hours.

These are the votes cast by each student. Do not alter these objects here.
var votes = {
  "Alex": { president: "Bob", vicePresident: "Devin", secretary: "Gail", treasurer: "Kerry" },
  "Bob": { president: "Mary", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Cindy": { president: "Cindy", vicePresident: "Hermann", secretary: "Bob", treasurer: "Bob" },
  "Devin": { president: "Louise", vicePresident: "John", secretary: "Bob", treasurer: "Fred" },
  "Ernest": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Fred": { president: "Louise", vicePresident: "Alex", secretary: "Ivy", treasurer: "Ivy" },
  "Gail": { president: "Fred", vicePresident: "Alex", secretary: "Ivy", treasurer: "Bob" },
  "Hermann": { president: "Ivy", vicePresident: "Kerry", secretary: "Fred", treasurer: "Ivy" },
  "Ivy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Gail" },
  "John": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Kerry" },
  "Kerry": { president: "Fred", vicePresident: "Mary", secretary: "Fred", treasurer: "Ivy" },
  "Louise": { president: "Nate", vicePresident: "Alex", secretary: "Mary", treasurer: "Ivy" },
  "Mary": { president: "Louise", vicePresident: "Oscar", secretary: "Nate", treasurer: "Ivy" },
  "Nate": { president: "Oscar", vicePresident: "Hermann", secretary: "Fred", treasurer: "Tracy" },
  "Oscar": { president: "Paulina", vicePresident: "Nate", secretary: "Fred", treasurer: "Ivy" },
  "Paulina": { president: "Louise", vicePresident: "Bob", secretary: "Devin", treasurer: "Ivy" },
  "Quintin": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Bob" },
  "Romanda": { president: "Louise", vicePresident: "Steve", secretary: "Fred", treasurer: "Ivy" },
  "Steve": { president: "Tracy", vicePresident: "Kerry", secretary: "Oscar", treasurer: "Xavier" },
  "Tracy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Ullyses": { president: "Louise", vicePresident: "Hermann", secretary: "Ivy", treasurer: "Bob" },
  "Valorie": { president: "Wesley", vicePresident: "Bob", secretary: "Alex", treasurer: "Ivy" },
  "Wesley": { president: "Bob", vicePresident: "Yvonne", secretary: "Valorie", treasurer: "Ivy" },
  "Xavier": { president: "Steve", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Yvonne": { president: "Bob", vicePresident: "Zane", secretary: "Fred", treasurer: "Hermann" },
  "Zane": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Mary" }
}

// Tally the votes in voteCount.
var voteCount = {
  president: {},
  vicePresident: {},
  secretary: {},
  treasurer: {}
}

/* The name of each student receiving a vote for an office should become a property
of the respective office in voteCount.  After Alex's votes have been tallied,
voteCount would be ...
  var voteCount = {
    president: { Bob: 1 },
    vicePresident: { Devin: 1 },
    secretary: { Gail: 1 },
    treasurer: { Kerry: 1 }
  }
*/

/* Once the votes have been tallied, assign each officer position the name of the
student who received the most votes. */
var officers = {
  president: undefined,
  vicePresident: undefined,
  secretary: undefined,
  treasurer: undefined
}

// Pseudocode
/*
Input: A list of voters and their votes
Output: A list of tallied votes, and a winner for each office

Steps:

Loop through the voters to get their choices
  Loop through each office to get the voter's vote
    IF a candidate received a vote for a particular office, put that name in the appropriate office
  IF a candidate received a vote, tick up the value associated with the candidate in voteCount

Loop through candidates in voteCount
  Initialize the first candidate in officers
  IF the first candidate received fewer votes than the next, change the first to the next

// __________________________________________
// Initial Solution

/*
for (var voter in votes) {
    var choices = votes[voter];
    for(var office in choices) {
      var person = choices[office]
        if(voteCount[office][person] === undefined) {
          voteCount[office][person] = 0;
        }
    voteCount[office][person]++;
    }
}
for (var office in voteCount) {
  for (var candidate in voteCount[office]) {
    var official = officers[office]
    if (official === undefined) {
      officers[office] = candidate;
    }
    if (voteCount[office][officers[office]] < voteCount[office][candidate]) {
      officers[office] = candidate;
    }
  }
}
*/

// __________________________________________
// Refactored Solution

for (var voter in votes) {
    for(var office in votes[voter]) {
      var person = votes[voter][office]
        if(voteCount[office][person] === undefined) {
          voteCount[office][person] = 0;
        }
    voteCount[office][person]++;
    }
}
for (var office in voteCount) {
  for (var candidate in voteCount[office]) {
    var official = officers[office]
    if (official === undefined) {
      officers[office] = candidate;
    }
    if (voteCount[office][officers[office]] < voteCount[office][candidate]) {
      officers[office] = candidate;
    }
  }
}

// __________________________________________
// Reflection
/*
***What did you learn about iterating over nested objects in JavaScript?

I learned how to use the for..in loop effectively to dive through multiple layers of nested data.
This process can become quickly overwhelming however, depending on the complexity of the data structures
you're iterating over. The for..in loop is very powerful though, and is necessary in order to pull
information from objects without resorting to lengthy hardcoding.

***Were you able to find useful methods to help you with this?

I wasn't able to find any built-in methods for objects in JS to help with this, but I found that
variable names were incredibly important in this challenge, because without clearly named variables
it's extremely easy to lose track of what you're doing

***What concepts were solidified in the process of working through this challenge?

Basic JS syntax was solidified for me personally. In this challenge, missing a semi-colon or putting a
curly brace in the wrong place can be the difference between success and broken code. The concepts of
property value pairs and the notation used to access them were also solidified.

*/
// __________________________________________
// Test Code:  Do not alter code below this line.

function assert(test, message, test_number) {
  if (!test) {
    console.log(test_number + "false");
    throw "ERROR: " + message;
  }
  console.log(test_number + "true");
  return true;
}

assert(
  (voteCount.president["Bob"] === 3),
  "Bob should receive three votes for President.",
  "1. "
)

assert(
  (voteCount.vicePresident["Bob"] === 2),
  "Bob should receive two votes for Vice President.",
  "2. "
)

assert(
  (voteCount.secretary["Bob"] === 2),
  "Bob should receive two votes for Secretary.",
  "3. "
)

assert(
  (voteCount.treasurer["Bob"] === 4),
  "Bob should receive four votes for Treasurer.",
  "4. "
)

assert(
  (officers.president === "Louise"),
  "Louise should be elected President.",
  "5. "
)

assert(
  (officers.vicePresident === "Hermann"),
  "Hermann should be elected Vice President.",
  "6. "
)

assert(
  (officers.secretary === "Fred"),
  "Fred should be elected Secretary.",
  "7. "
)

assert(
  (officers.treasurer === "Ivy"),
  "Ivy should be elected Treasurer.",
  "8. "<|endoftext|>


<commit_before>// Tally Votes in JavaScript Pairing Challenge.

// I worked on this challenge with:
// This challenge took me [#] hours.

// These are the votes cast by each student. Do not alter these objects here.
var votes = {
  "Alex": { president: "Bob", vicePresident: "Devin", secretary: "Gail", treasurer: "Kerry" },
  "Bob": { president: "Mary", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Cindy": { president: "Cindy", vicePresident: "Hermann", secretary: "Bob", treasurer: "Bob" },
  "Devin": { president: "Louise", vicePresident: "John", secretary: "Bob", treasurer: "Fred" },
  "Ernest": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Fred": { president: "Louise", vicePresident: "Alex", secretary: "Ivy", treasurer: "Ivy" },
  "Gail": { president: "Fred", vicePresident: "Alex", secretary: "Ivy", treasurer: "Bob" },
  "Hermann": { president: "Ivy", vicePresident: "Kerry", secretary: "Fred", treasurer: "Ivy" },
  "Ivy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Gail" },
  "John": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Kerry" },
  "Kerry": { president: "Fred", vicePresident: "Mary", secretary: "Fred", treasurer: "Ivy" },
  "Louise": { president: "Nate", vicePresident: "Alex", secretary: "Mary", treasurer: "Ivy" },
  "Mary": { president: "Louise", vicePresident: "Oscar", secretary: "Nate", treasurer: "Ivy" },
  "Nate": { president: "Oscar", vicePresident: "Hermann", secretary: "Fred", treasurer: "Tracy" },
  "Oscar": { president: "Paulina", vicePresident: "Nate", secretary: "Fred", treasurer: "Ivy" },
  "Paulina": { president: "Louise", vicePresident: "Bob", secretary: "Devin", treasurer: "Ivy" },
  "Quintin": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Bob" },
  "Romanda": { president: "Louise", vicePresident: "Steve", secretary: "Fred", treasurer: "Ivy" },
  "Steve": { president: "Tracy", vicePresident: "Kerry", secretary: "Oscar", treasurer: "Xavier" },
  "Tracy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Ullyses": { president: "Louise", vicePresident: "Hermann", secretary: "Ivy", treasurer: "Bob" },
  "Valorie": { president: "Wesley", vicePresident: "Bob", secretary: "Alex", treasurer: "Ivy" },
  "Wesley": { president: "Bob", vicePresident: "Yvonne", secretary: "Valorie", treasurer: "Ivy" },
  "Xavier": { president: "Steve", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Yvonne": { president: "Bob", vicePresident: "Zane", secretary: "Fred", treasurer: "Hermann" },
  "Zane": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Mary" }
}

// Tally the votes in voteCount.
var voteCount = {
  president: {},
  vicePresident: {},
  secretary: {},
  treasurer: {}
}

/* The name of each student receiving a vote for an office should become a property
of the respective office in voteCount.  After Alex's votes have been tallied,
voteCount would be ...
  var voteCount = {
    president: { Bob: 1 },
    vicePresident: { Devin: 1 },
    secretary: { Gail: 1 },
    treasurer: { Kerry: 1 }
  }
*/

/* Once the votes have been tallied, assign each officer position the name of the
student who received the most votes. */
var officers = {
  president: undefined,
  vicePresident: undefined,
  secretary: undefined,
  treasurer: undefined
}

// __________________________________________
// Refactored Solution
for (var voter in votes){
  for (var officer in votes[voter]){
    var candidate = voteCount[officer][votes[voter][officer]];
    if ( candidate == undefined){
      voteCount[officer][votes[voter][officer]] = 1
    } else {
      voteCount[officer][votes[voter][officer]]++
    }
  }
}

console.log(voteCount);

for (var officer in voteCount){
  var tally = 0;
  for (var person in voteCount[officer]){
    if ((voteCount[officer][person]) > tally) {
      tally = voteCount[officer][person];
      officers[officer] = person;
    }
  }
}
console.log(officers);

// __________________________________________
// Reflection
// What did you learn about iterating over nested objects in JavaScript?
  // It can get really confusing when
// Were you able to find useful methods to help you with this?
// What concepts were solidified in the process of working through this challenge?

// __________________________________________
// Test Code:  Do not alter code below this line.

function assert(test, message, test_number) {
  if (!test) {
    console.log(test_number + "false");
    throw "ERROR: " + message;
  }
  console.log(test_number + "true");
  return true;
}

assert(
  (voteCount.president["Bob"] === 3),
  "Bob should receive three votes for President.",
  "1. "
)

assert(
  (voteCount.vicePresident["Bob"] === 2),
  "Bob should receive two votes for Vice President.",
  "2. "
)

assert(
  (voteCount.secretary["Bob"] === 2),
  "Bob should receive two votes for Secretary.",
  "3. "
)

assert(
  (voteCount.treasurer["Bob"] === 4),
  "Bob should receive four votes for Treasurer.",
  "4. "
)

assert(
  (officers.president === "Louise"),
  "Louise should be elected President.",
  "5. "
)

assert(
  (officers.vicePresident === "Hermann"),
  "Hermann should be elected Vice President.",
  "6. "
)

assert(
  (officers.secretary === "Fred"),
  "Fred should be elected Secretary.",
  "7. "
)

assert(
  (officers.treasurer === "Ivy"),
  "Ivy should be elected Treasurer.",
  "8. "
)<commit_msg>Add reflection to tally vote<commit_after>// Tally Votes in JavaScript Pairing Challenge.

// I worked on this challenge with:
// This challenge took me [#] hours.

// These are the votes cast by each student. Do not alter these objects here.
var votes = {
  "Alex": { president: "Bob", vicePresident: "Devin", secretary: "Gail", treasurer: "Kerry" },
  "Bob": { president: "Mary", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Cindy": { president: "Cindy", vicePresident: "Hermann", secretary: "Bob", treasurer: "Bob" },
  "Devin": { president: "Louise", vicePresident: "John", secretary: "Bob", treasurer: "Fred" },
  "Ernest": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Fred": { president: "Louise", vicePresident: "Alex", secretary: "Ivy", treasurer: "Ivy" },
  "Gail": { president: "Fred", vicePresident: "Alex", secretary: "Ivy", treasurer: "Bob" },
  "Hermann": { president: "Ivy", vicePresident: "Kerry", secretary: "Fred", treasurer: "Ivy" },
  "Ivy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Gail" },
  "John": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Kerry" },
  "Kerry": { president: "Fred", vicePresident: "Mary", secretary: "Fred", treasurer: "Ivy" },
  "Louise": { president: "Nate", vicePresident: "Alex", secretary: "Mary", treasurer: "Ivy" },
  "Mary": { president: "Louise", vicePresident: "Oscar", secretary: "Nate", treasurer: "Ivy" },
  "Nate": { president: "Oscar", vicePresident: "Hermann", secretary: "Fred", treasurer: "Tracy" },
  "Oscar": { president: "Paulina", vicePresident: "Nate", secretary: "Fred", treasurer: "Ivy" },
  "Paulina": { president: "Louise", vicePresident: "Bob", secretary: "Devin", treasurer: "Ivy" },
  "Quintin": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Bob" },
  "Romanda": { president: "Louise", vicePresident: "Steve", secretary: "Fred", treasurer: "Ivy" },
  "Steve": { president: "Tracy", vicePresident: "Kerry", secretary: "Oscar", treasurer: "Xavier" },
  "Tracy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Ullyses": { president: "Louise", vicePresident: "Hermann", secretary: "Ivy", treasurer: "Bob" },
  "Valorie": { president: "Wesley", vicePresident: "Bob", secretary: "Alex", treasurer: "Ivy" },
  "Wesley": { president: "Bob", vicePresident: "Yvonne", secretary: "Valorie", treasurer: "Ivy" },
  "Xavier": { president: "Steve", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Yvonne": { president: "Bob", vicePresident: "Zane", secretary: "Fred", treasurer: "Hermann" },
  "Zane": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Mary" }
}

// Tally the votes in voteCount.
var voteCount = {
  president: {},
  vicePresident: {},
  secretary: {},
  treasurer: {}
}

/* The name of each student receiving a vote for an office should become a property
of the respective office in voteCount.  After Alex's votes have been tallied,
voteCount would be ...
  var voteCount = {
    president: { Bob: 1 },
    vicePresident: { Devin: 1 },
    secretary: { Gail: 1 },
    treasurer: { Kerry: 1 }
  }
*/

/* Once the votes have been tallied, assign each officer position the name of the
student who received the most votes. */
var officers = {
  president: undefined,
  vicePresident: undefined,
  secretary: undefined,
  treasurer: undefined
}

// __________________________________________
// Refactored Solution
for (var voter in votes){
  for (var officer in votes[voter]){
    var candidate = voteCount[officer][votes[voter][officer]];
    if ( candidate == undefined){
      voteCount[officer][votes[voter][officer]] = 1
    } else {
      voteCount[officer][votes[voter][officer]]++
    }
  }
}

console.log(voteCount);

for (var officer in voteCount){
  var tally = 0;
  for (var person in voteCount[officer]){
    if ((voteCount[officer][person]) > tally) {
      tally = voteCount[officer][person];
      officers[officer] = person;
    }
  }
}
console.log(officers);

// __________________________________________
// Reflection
// What did you learn about iterating over nested objects in JavaScript?
  // It can get really confusing when you are working with deeply nested objects
  // Special focus should be given to naming variables appropriately and descriptively
  // when looping through data.
// Were you able to find useful methods to help you with this?
  // We did not use anything too fancy with this just mostly for loops.
// What concepts were solidified in the process of working through this challenge?
  // How to access elements and how to use a counter in a really useful practical way.

// __________________________________________
// Test Code:  Do not alter code below this line.

function assert(test, message, test_number) {
  if (!test) {
    console.log(test_number + "false");
    throw "ERROR: " + message;
  }
  console.log(test_number + "true");
  return true;
}

assert(
  (voteCount.president["Bob"] === 3),
  "Bob should receive three votes for President.",
  "1. "
)

assert(
  (voteCount.vicePresident["Bob"] === 2),
  "Bob should receive two votes for Vice President.",
  "2. "
)

assert(
  (voteCount.secretary["Bob"] === 2),
  "Bob should receive two votes for Secretary.",
  "3. "
)

assert(
  (voteCount.treasurer["Bob"] === 4),
  "Bob should receive four votes for Treasurer.",
  "4. "
)

assert(
  (officers.president === "Louise"),
  "Louise should be elected President.",
  "5. "
)

assert(
  (officers.vicePresident === "Hermann"),
  "Hermann should be elected Vice President.",
  "6. "
)

assert(
  (officers.secretary === "Fred"),
  "Fred should be elected Secretary.",
  "7. "
)

assert(
  (officers.treasurer === "Ivy"),
  "Ivy should be elected Treasurer.",
  "8. "
)<|endoftext|>


<commit_before>// Tally Votes in JavaScript Pairing Challenge.

// I worked on this challenge with: Colin Razevich
// This challenge took me [#] hours.

// These are the votes cast by each student. Do not alter these objects here.
var votes = {
  "Alex": { president: "Bob", vicePresident: "Devin", secretary: "Gail", treasurer: "Kerry" },
  "Bob": { president: "Mary", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Cindy": { president: "Cindy", vicePresident: "Hermann", secretary: "Bob", treasurer: "Bob" },
  "Devin": { president: "Louise", vicePresident: "John", secretary: "Bob", treasurer: "Fred" },
  "Ernest": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Fred": { president: "Louise", vicePresident: "Alex", secretary: "Ivy", treasurer: "Ivy" },
  "Gail": { president: "Fred", vicePresident: "Alex", secretary: "Ivy", treasurer: "Bob" },
  "Hermann": { president: "Ivy", vicePresident: "Kerry", secretary: "Fred", treasurer: "Ivy" },
  "Ivy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Gail" },
  "John": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Kerry" },
  "Kerry": { president: "Fred", vicePresident: "Mary", secretary: "Fred", treasurer: "Ivy" },
  "Louise": { president: "Nate", vicePresident: "Alex", secretary: "Mary", treasurer: "Ivy" },
  "Mary": { president: "Louise", vicePresident: "Oscar", secretary: "Nate", treasurer: "Ivy" },
  "Nate": { president: "Oscar", vicePresident: "Hermann", secretary: "Fred", treasurer: "Tracy" },
  "Oscar": { president: "Paulina", vicePresident: "Nate", secretary: "Fred", treasurer: "Ivy" },
  "Paulina": { president: "Louise", vicePresident: "Bob", secretary: "Devin", treasurer: "Ivy" },
  "Quintin": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Bob" },
  "Romanda": { president: "Louise", vicePresident: "Steve", secretary: "Fred", treasurer: "Ivy" },
  "Steve": { president: "Tracy", vicePresident: "Kerry", secretary: "Oscar", treasurer: "Xavier" },
  "Tracy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Ullyses": { president: "Louise", vicePresident: "Hermann", secretary: "Ivy", treasurer: "Bob" },
  "Valorie": { president: "Wesley", vicePresident: "Bob", secretary: "Alex", treasurer: "Ivy" },
  "Wesley": { president: "Bob", vicePresident: "Yvonne", secretary: "Valorie", treasurer: "Ivy" },
  "Xavier": { president: "Steve", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Yvonne": { president: "Bob", vicePresident: "Zane", secretary: "Fred", treasurer: "Hermann" },
  "Zane": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Mary" },
}

// Tally the votes in voteCount.
var voteCount = {
  president: {},
  vicePresident: {},
  secretary: {},
  treasurer: {}
}

/* The name of each student receiving a vote for an office should become a property
of the respective office in voteCount.  After Alex's votes have been tallied,
voteCount would be ...
  var voteCount = {
    president: { Bob: 1 },
    vicePresident: { Devin: 1 },
    secretary: { Gail: 1 },
    treasurer: { Kerry: 1 }
  }
*/

/* Once the votes have been tallied, assign each officer position the name of the
student who received the most votes. */
var officers = {
  president: undefined,
  vicePresident: undefined,
  secretary: undefined,
  treasurer: undefined
}

// Pseudocode
// Iterate through votes
// Select the votes
// Add those votes to candidate properties
//   IF candidate has no votes
//     create new property
//   ELSE add to existing property
// Find candidate with max votes
// Set officer property to winning candidate

// __________________________________________
// Initial Solution

// for(var voter in votes){
//   if (votes.hasOwnProperty(voter)){
//     var count = votes[voter];
//       for(var cand in count){
//         if(count.hasOwnProperty(cand)){
// //           console.log(cand + " = " + count[cand]);

//           var check = count[cand];
//           console.log(check);
//         }
//       }
//   }
// }

for (var voter in votes){
  if (!voteCount.president[votes[voter].president]){
    voteCount.president[votes[voter].president] = 1;
  }else{ voteCount.president[votes[voter].president] +=1;
  }
  if (!voteCount.vicePresident[votes[voter].vicePresident]){
    voteCount.vicePresident[votes[voter].vicePresident] = 1;
  }else{ voteCount.vicePresident[votes[voter].vicePresident] +=1;
  }
    if (!voteCount.secretary[votes[voter].secretary]){
    voteCount.secretary[votes[voter].secretary] = 1;
  }else{ voteCount.secretary[votes[voter].secretary] +=1;
  }
    if (!voteCount.treasurer[votes[voter].treasurer]){
    voteCount.treasurer[votes[voter].treasurer] = 1;
  }else{ voteCount.treasurer[votes[voter].treasurer] +=1;
  }
}

var prez = "Bob";
for (var candidate in voteCount.president){
  if (voteCount.president[candidate]>voteCount.president[prez]) {
    prez = candidate;
  };
};
officers.president = prez;

var vp = "Bob";
for (var candidate in voteCount.vicePresident){
  if (voteCount.vicePresident[candidate]>voteCount.vicePresident[vp]) {
    vp = candidate;
  };
};
officers.vicePresident = vp;

var sec = "Bob";
for (var candidate in voteCount.secretary){
  if (voteCount.secretary[candidate]>voteCount.secretary[sec]) {
    sec = candidate;
  };
};
officers.secretary = sec;

var treasure = "Bob";
for (var candidate in voteCount.treasurer){
  if (voteCount.treasurer[candidate]>voteCount.treasurer[treasure]) {
    treasure = candidate;
  };
};
officers.treasurer = treasure;

// __________________________________________
// Refactored Solution

// __________________________________________
// Reflection

// __________________________________________
// Test Code:  Do not alter code below this line.

function assert(test, message, test_number) {
  if (!test) {
    console.log(test_number + "false");
    throw "ERROR: " + message;
  }
  console.log(test_number + "true");
  return true;
}

assert(
  (voteCount.president["Bob"] === 3),
  "Bob should receive three votes for President.",
  "1. "
)

assert(
  (voteCount.vicePresident["Bob"] === 2),
  "Bob should receive two votes for Vice President.",
  "2. "
)

assert(
  (voteCount.secretary["Bob"] === 2),
  "Bob should receive two votes for Secretary.",
  "3. "
)

assert(
  (voteCount.treasurer["Bob"] === 4),
  "Bob should receive four votes for Treasurer.",
  "4. "
)

assert(
  (officers.president === "Louise"),
  "Louise should be elected President.",
  "5. "
)

assert(
  (officers.vicePresident === "Hermann"),
  "Hermann should be elected Vice President.",
  "6. "
)

assert(
  (officers.secretary === "Fred"),
  "Fred should be elected Secretary.",
  "7. "
)

assert(
  (officers.treasurer === "Ivy"),
  "Ivy should be elected Treasurer.",
  "8. "
)<commit_msg>tally_votes<commit_after>// Tally Votes in JavaScript Pairing Challenge.

// I worked on this challenge with: Colin Razevich
// This challenge took me [4] hours.

// These are the votes cast by each student. Do not alter these objects here.
var votes = {
  "Alex": { president: "Bob", vicePresident: "Devin", secretary: "Gail", treasurer: "Kerry" },
  "Bob": { president: "Mary", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Cindy": { president: "Cindy", vicePresident: "Hermann", secretary: "Bob", treasurer: "Bob" },
  "Devin": { president: "Louise", vicePresident: "John", secretary: "Bob", treasurer: "Fred" },
  "Ernest": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Fred": { president: "Louise", vicePresident: "Alex", secretary: "Ivy", treasurer: "Ivy" },
  "Gail": { president: "Fred", vicePresident: "Alex", secretary: "Ivy", treasurer: "Bob" },
  "Hermann": { president: "Ivy", vicePresident: "Kerry", secretary: "Fred", treasurer: "Ivy" },
  "Ivy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Gail" },
  "John": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Kerry" },
  "Kerry": { president: "Fred", vicePresident: "Mary", secretary: "Fred", treasurer: "Ivy" },
  "Louise": { president: "Nate", vicePresident: "Alex", secretary: "Mary", treasurer: "Ivy" },
  "Mary": { president: "Louise", vicePresident: "Oscar", secretary: "Nate", treasurer: "Ivy" },
  "Nate": { president: "Oscar", vicePresident: "Hermann", secretary: "Fred", treasurer: "Tracy" },
  "Oscar": { president: "Paulina", vicePresident: "Nate", secretary: "Fred", treasurer: "Ivy" },
  "Paulina": { president: "Louise", vicePresident: "Bob", secretary: "Devin", treasurer: "Ivy" },
  "Quintin": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Bob" },
  "Romanda": { president: "Louise", vicePresident: "Steve", secretary: "Fred", treasurer: "Ivy" },
  "Steve": { president: "Tracy", vicePresident: "Kerry", secretary: "Oscar", treasurer: "Xavier" },
  "Tracy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Ullyses": { president: "Louise", vicePresident: "Hermann", secretary: "Ivy", treasurer: "Bob" },
  "Valorie": { president: "Wesley", vicePresident: "Bob", secretary: "Alex", treasurer: "Ivy" },
  "Wesley": { president: "Bob", vicePresident: "Yvonne", secretary: "Valorie", treasurer: "Ivy" },
  "Xavier": { president: "Steve", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Yvonne": { president: "Bob", vicePresident: "Zane", secretary: "Fred", treasurer: "Hermann" },
  "Zane": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Mary" },
}

// Tally the votes in voteCount.
var voteCount = {
  president: {},
  vicePresident: {},
  secretary: {},
  treasurer: {}
}

/* The name of each student receiving a vote for an office should become a property
of the respective office in voteCount.  After Alex's votes have been tallied,
voteCount would be ...
  var voteCount = {
    president: { Bob: 1 },
    vicePresident: { Devin: 1 },
    secretary: { Gail: 1 },
    treasurer: { Kerry: 1 }
  }
*/

/* Once the votes have been tallied, assign each officer position the name of the
student who received the most votes. */
var officers = {
  president: undefined,
  vicePresident: undefined,
  secretary: undefined,
  treasurer: undefined
}

// Pseudocode
// Iterate through votes
// Select the votes
// Add those votes to candidate properties
//   IF candidate has no votes
//     create new property
//   ELSE add to existing property
// Find candidate with max votes
// Set officer property to winning candidate

// __________________________________________
// Initial Solution

// for (var voter in votes){
//   if (!voteCount.president[votes[voter].president]){
//     voteCount.president[votes[voter].president] = 1;
//   }else{ voteCount.president[votes[voter].president] +=1;
//   }
//   if (!voteCount.vicePresident[votes[voter].vicePresident]){
//     voteCount.vicePresident[votes[voter].vicePresident] = 1;
//   }else{ voteCount.vicePresident[votes[voter].vicePresident] +=1;
//   }
//     if (!voteCount.secretary[votes[voter].secretary]){
//     voteCount.secretary[votes[voter].secretary] = 1;
//   }else{ voteCount.secretary[votes[voter].secretary] +=1;
//   }
//     if (!voteCount.treasurer[votes[voter].treasurer]){
//     voteCount.treasurer[votes[voter].treasurer] = 1;
//   }else{ voteCount.treasurer[votes[voter].treasurer] +=1;
//   }
// }

// var prez = "Bob";
// for (var candidate in voteCount.president){
//   if (voteCount.president[candidate]>voteCount.president[prez]) {
//     prez = candidate;
//   };
// };
// officers.president = prez;

// var vp = "Bob";
// for (var candidate in voteCount.vicePresident){
//   if (voteCount.vicePresident[candidate]>voteCount.vicePresident[vp]) {
//     vp = candidate;
//   };
// };
// officers.vicePresident = vp;

// var sec = "Bob";
// for (var candidate in voteCount.secretary){
//   if (voteCount.secretary[candidate]>voteCount.secretary[sec]) {
//     sec = candidate;
//   };
// };
// officers.secretary = sec;

// var treasure = "Bob";
// for (var candidate in voteCount.treasurer){
//   if (voteCount.treasurer[candidate]>voteCount.treasurer[treasure]) {
//     treasure = candidate;
//   };
// };
// officers.treasurer = treasure;

// __________________________________________
// Refactored Solution

for (var voter in votes) {
  for (var position in voteCount){
    var name = votes[voter][position];
    if (voteCount[position][name] == undefined){
      voteCount[position][name] = 1;
    }
    else {
      voteCount[position][name] += 1;
    }
  }
}

for (var position in voteCount) {
  var highestCount = 0;
  for (var candidate in voteCount[position]){
    if (voteCount[position][candidate] > highestCount){
      officers[position] = candidate;
      highestCount = voteCount[position][candidate];
    }
  }
}

// __________________________________________
// Reflection

// What did you learn about iterating over nested objects in JavaScript?
// It can be difficult to keep track of the values you are iterating over, so it's really super important to choose the most descriptive variable names possible to avoid getting lost when you're trying to read through it. It's also really helpful to console.log everything so you know exactly where you are and what you're dealing with.

// Were you able to find useful methods to help you with this?
// for...in loops were the real star of the show here. hasOwnKey was an absolute waste of space. Still have no idea what it does (besides confuse the hell out of me), but am positive that it did nothing useful for us. Things were much better once we cut that shit out.

// What concepts were solidified in the process of working through this challenge?
// Iterating through nested objects. I used to get lost 1+ deep, and now I can usually make it through 2+! The descriptive variable names really help with that, and also just getting used to the idea of having things inside of other things inside of other things.

// __________________________________________
// Test Code:  Do not alter code below this line.

function assert(test, message, test_number) {
  if (!test) {
    console.log(test_number + "false");
    throw "ERROR: " + message;
  }
  console.log(test_number + "true");
  return true;
}

assert(
  (voteCount.president["Bob"] === 3),
  "Bob should receive three votes for President.",
  "1. "
)

assert(
  (voteCount.vicePresident["Bob"] === 2),
  "Bob should receive two votes for Vice President.",
  "2. "
)

assert(
  (voteCount.secretary["Bob"] === 2),
  "Bob should receive two votes for Secretary.",
  "3. "
)

assert(
  (voteCount.treasurer["Bob"] === 4),
  "Bob should receive four votes for Treasurer.",
  "4. "
)

assert(
  (officers.president === "Louise"),
  "Louise should be elected President.",
  "5. "
)

assert(
  (officers.vicePresident === "Hermann"),
  "Hermann should be elected Vice President.",
  "6. "
)

assert(
  (officers.secretary === "Fred"),
  "Fred should be elected Secretary.",
  "7. "
)

assert(
  (officers.treasurer === "Ivy"),
  "Ivy should be elected Treasurer.",
  "8. "
)<|endoftext|>


<commit_before>var itemsPerPage = 2; // set the number of items you want per page

var store = Ext.create('Ext.data.Store', {
    id: 'simpsonsStore',
    autoLoad: false,
    fields: ['name', 'email', 'phone'],
    pageSize: itemsPerPage, // items per page
    proxy: {
        type: 'ajax',
        url: 'pagingstore.js', // url that will load data with respect to start and limit params
        reader: {
            type: 'json',
            root: 'items',
            totalProperty: 'total'
        }
    }
});

// specify segment of data you want to load using params
store.load({
    params: {
        start: 0,
        limit: itemsPerPage
    }
});

Ext.create('Ext.grid.Panel', {
    title: 'Simpsons',
    store: store,
    columns: [{
        header: 'Name',
        dataIndex: 'name'
    }, {
        header: 'Email',
        dataIndex: 'email',
        flex: 1
    }, {
        header: 'Phone',
        dataIndex: 'phone'
    }],
    width: 400,
    height: 125,
    dockedItems: [{
        xtype: 'pagingtoolbar',
        store: store, // same store GridPanel is using
        dock: 'bottom',
        displayInfo: true
    }],
    renderTo: Ext.getBody()
});
<commit_msg>extjs pager<commit_after>var itemsPerPage = 2; // set the number of items you want per page

var store = Ext.create('Ext.data.Store', {
    id: 'simpsonsStore',
    autoLoad: false,
    fields: ['name', 'email', 'phone'],
    pageSize: itemsPerPage, // items per page
    proxy: {
        type: 'ajax',
        url: 'pagingstore.js', // url that will load data with respect to start and limit params
        reader: {
            type: 'json',
            root: 'items',
            totalProperty: 'total'
        }
    }
});

// specify segment of data you want to load using params
store.load({
    params: {
        start: 0,
        limit: itemsPerPage
    }
});

Ext.create('Ext.grid.Panel', {
    title: 'Simpsons',
    store: store,
    columns: [{
        header: 'Name',
        dataIndex: 'name'
    }, {
        header: 'Email',
        dataIndex: 'email',
        flex: 1
    }, {
        header: 'Phone',
        dataIndex: 'phone'
    }],
    width: 400,
    height: 125,
    dockedItems: [{
        xtype: 'pagingtoolbar',
        store: store, // same store GridPanel is using
        dock: 'bottom',
        displayInfo: true
    }],
    renderTo: Ext.getBody()
});
store.load({
    params: {
        // specify params for the first page load if using paging
        start: 0,
        limit: myPageSize,
        // other params
        foo: 'bar'
    }
});
<|endoftext|>


<commit_before>// Tally Votes in JavaScript Pairing Challenge.

// I worked on this challenge with: Hanah Yender/KB DiAngelo
// This challenge took me [#] hours.

// These are the votes cast by each student. Do not alter these objects here.
var votes = {
  "Alex": { president: "Bob", vicePresident: "Devin", secretary: "Gail", treasurer: "Kerry" },
  "Bob": { president: "Mary", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Cindy": { president: "Cindy", vicePresident: "Hermann", secretary: "Bob", treasurer: "Bob" },
  "Devin": { president: "Louise", vicePresident: "John", secretary: "Bob", treasurer: "Fred" },
  "Ernest": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Fred": { president: "Louise", vicePresident: "Alex", secretary: "Ivy", treasurer: "Ivy" },
  "Gail": { president: "Fred", vicePresident: "Alex", secretary: "Ivy", treasurer: "Bob" },
  "Hermann": { president: "Ivy", vicePresident: "Kerry", secretary: "Fred", treasurer: "Ivy" },
  "Ivy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Gail" },
  "John": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Kerry" },
  "Kerry": { president: "Fred", vicePresident: "Mary", secretary: "Fred", treasurer: "Ivy" },
  "Louise": { president: "Nate", vicePresident: "Alex", secretary: "Mary", treasurer: "Ivy" },
  "Mary": { president: "Louise", vicePresident: "Oscar", secretary: "Nate", treasurer: "Ivy" },
  "Nate": { president: "Oscar", vicePresident: "Hermann", secretary: "Fred", treasurer: "Tracy" },
  "Oscar": { president: "Paulina", vicePresident: "Nate", secretary: "Fred", treasurer: "Ivy" },
  "Paulina": { president: "Louise", vicePresident: "Bob", secretary: "Devin", treasurer: "Ivy" },
  "Quintin": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Bob" },
  "Romanda": { president: "Louise", vicePresident: "Steve", secretary: "Fred", treasurer: "Ivy" },
  "Steve": { president: "Tracy", vicePresident: "Kerry", secretary: "Oscar", treasurer: "Xavier" },
  "Tracy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Ullyses": { president: "Louise", vicePresident: "Hermann", secretary: "Ivy", treasurer: "Bob" },
  "Valorie": { president: "Wesley", vicePresident: "Bob", secretary: "Alex", treasurer: "Ivy" },
  "Wesley": { president: "Bob", vicePresident: "Yvonne", secretary: "Valorie", treasurer: "Ivy" },
  "Xavier": { president: "Steve", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Yvonne": { president: "Bob", vicePresident: "Zane", secretary: "Fred", treasurer: "Hermann" },
  "Zane": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Mary" }
}

/* The name of each student receiving a vote for an office should become a property
of the respective office in voteCount.  After Alex's votes have been tallied,
voteCount would be ...
  var voteCount = {
    president: { Bob: 1 },
    vicePresident: { Devin: 1 },
    secretary: { Gail: 1 },
    treasurer: { Kerry: 1 }
  }
*/

// Pseudocode
// For Assert 1 - 4, access the object voteCount and then access the property of that object, and then insert an object inside that includes the property Bob with the value 3.
// For Asserts 5-8, create a function that "elects" students based on the number of votes recieved. Access the voteCount's particular student government position property, and return the student name with the highest number.
// In order to tally up the votes iterate over votes.  Access each property inside of votes, and if the property inside of that matches with the property inside of votecount (so president and president), if the person didn't exist yet inside, add the person and 1 vote.  The second case is that the person already exists, in which case ++ their vote count.

// __________________________________________
// Initial Solution

// Tally the votes in voteCount.

/* Once the votes have been tallied, assign each officer position the name of the
student who received the most votes. */
var voteCount = {
  president: {},
  vicePresident: {},
  secretary: {},
  treasurer: {}
}

var officers = {
  president: undefined,
  vicePresident: undefined,
  secretary: undefined,
  treasurer: undefined
}

//Pseudocode

var tallyVotes = function(votes, voteCount){
  for (position in voteCount) { //position is president: {}
    var positionVoteNames = voteCount[position]; // positionVoteNames is {}
    for (student in votes) { //student is "Alex": { president: "Bob", ... }
      var studentsVote = votes[student]; //studentsVote is { president: "Bob", ... }
      var name = studentsVote[position];

      for ( officer in studentsVote) { // officer is president, vicepresident, etc
        if (positionVoteNames.hasOwnProperty(name))
      }

      studentsVote[position]
    }
  }

  for (var student in votes) { //Alex
    var studentsVote = votes[student]; //studentsVote is the object following Alex, containing {president:Bob, vicePresident: Devin, etc;}
    for (var officer in studentsVote) { //officer is president, vicepresident, etc
      var name = studentsVote[officer]; //name is the value of the officer key, so aka Bob, Devin, etc
      for (position in voteCount) {
        var positionVoteNames = voteCount[position];
        if (positionVoteNames.hasOwnProperty(name)){
          positionVoteNames[name] += 1 ;
        } else {
          positionVoteNames[name] = 1;
        }
      }
    }
  }
return voteCount;
}

var talliedVotes = tallyVotes(votes, voteCount);
//console.log(talliedVotes);
// var determineWinner = function(officers, talliedVotes) {
//   var frontrunner = "";
//   var maxVotes = 0;
//   for (position in talliedVotes) {
//     var  positionVoteNames = talliedVotes[position];
//     for (name in positionVoteNames) {
//       if (positionVoteNames[name] > maxVotes) {
//         maxVotes = positionVoteNames[name];
//         frontrunner = name;
//       }
//     }
//     officers[position] = frontrunner;
//   }
//   return officers;
// }

// console.log(determineWinner(officers, talliedVotes));

// __________________________________________
// Refactored Solution

// __________________________________________
// Reflection

// __________________________________________
// Test Code:  Do not alter code below this line.

/*

function assert(test, message, test_number) {
  if (!test) {
    console.log(test_number + "false");
    throw "ERROR: " + message;
  }
  console.log(test_number + "true");
  return true;
}

assert(
  (voteCount.president["Bob"] === 3),
  "Bob should receive three votes for President.",
  "1. "
)

assert(
  (voteCount.vicePresident["Bob"] === 2),
  "Bob should receive two votes for Vice President.",
  "2. "
)

assert(
  (voteCount.secretary["Bob"] === 2),
  "Bob should receive two votes for Secretary.",
  "3. "
)

assert(
  (voteCount.treasurer["Bob"] === 4),
  "Bob should receive four votes for Treasurer.",
  "4. "
)

assert(
  (officers.president === "Louise"),
  "Louise should be elected President.",
  "5. "
)

assert(
  (officers.vicePresident === "Hermann"),
  "Hermann should be elected Vice President.",
  "6. "
)

assert(
  (officers.secretary === "Fred"),
  "Fred should be elected Secretary.",
  "7. "
)

assert(
  (officers.treasurer === "Ivy"),
  "Ivy should be elected Treasurer.",
  "8. "
)

*/<commit_msg>Finish exercises<commit_after>// Tally Votes in JavaScript Pairing Challenge.

// I worked on this challenge with: Hanah Yender/KB DiAngelo
// This challenge took me [#] hours.

// These are the votes cast by each student. Do not alter these objects here.
var votes = {
  "Alex": { president: "Bob", vicePresident: "Devin", secretary: "Gail", treasurer: "Kerry" },
  "Bob": { president: "Mary", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Cindy": { president: "Cindy", vicePresident: "Hermann", secretary: "Bob", treasurer: "Bob" },
  "Devin": { president: "Louise", vicePresident: "John", secretary: "Bob", treasurer: "Fred" },
  "Ernest": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Fred": { president: "Louise", vicePresident: "Alex", secretary: "Ivy", treasurer: "Ivy" },
  "Gail": { president: "Fred", vicePresident: "Alex", secretary: "Ivy", treasurer: "Bob" },
  "Hermann": { president: "Ivy", vicePresident: "Kerry", secretary: "Fred", treasurer: "Ivy" },
  "Ivy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Gail" },
  "John": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Kerry" },
  "Kerry": { president: "Fred", vicePresident: "Mary", secretary: "Fred", treasurer: "Ivy" },
  "Louise": { president: "Nate", vicePresident: "Alex", secretary: "Mary", treasurer: "Ivy" },
  "Mary": { president: "Louise", vicePresident: "Oscar", secretary: "Nate", treasurer: "Ivy" },
  "Nate": { president: "Oscar", vicePresident: "Hermann", secretary: "Fred", treasurer: "Tracy" },
  "Oscar": { president: "Paulina", vicePresident: "Nate", secretary: "Fred", treasurer: "Ivy" },
  "Paulina": { president: "Louise", vicePresident: "Bob", secretary: "Devin", treasurer: "Ivy" },
  "Quintin": { president: "Fred", vicePresident: "Hermann", secretary: "Fred", treasurer: "Bob" },
  "Romanda": { president: "Louise", vicePresident: "Steve", secretary: "Fred", treasurer: "Ivy" },
  "Steve": { president: "Tracy", vicePresident: "Kerry", secretary: "Oscar", treasurer: "Xavier" },
  "Tracy": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Ullyses": { president: "Louise", vicePresident: "Hermann", secretary: "Ivy", treasurer: "Bob" },
  "Valorie": { president: "Wesley", vicePresident: "Bob", secretary: "Alex", treasurer: "Ivy" },
  "Wesley": { president: "Bob", vicePresident: "Yvonne", secretary: "Valorie", treasurer: "Ivy" },
  "Xavier": { president: "Steve", vicePresident: "Hermann", secretary: "Fred", treasurer: "Ivy" },
  "Yvonne": { president: "Bob", vicePresident: "Zane", secretary: "Fred", treasurer: "Hermann" },
  "Zane": { president: "Louise", vicePresident: "Hermann", secretary: "Fred", treasurer: "Mary" }
}

/* The name of each student receiving a vote for an office should become a property
of the respective office in voteCount.  After Alex's votes have been tallied,
voteCount would be ...
  var voteCount = {
    president: { Bob: 1 },
    vicePresident: { Devin: 1 },
    secretary: { Gail: 1 },
    treasurer: { Kerry: 1 }
  }
*/

// Pseudocode
// For Assert 1 - 4, access the object voteCount and then access the property of that object, and then insert an object inside that includes the property Bob with the value 3.
// For Asserts 5-8, create a function that "elects" students based on the number of votes recieved. Access the voteCount's particular student government position property, and return the student name with the highest number.
// In order to tally up the votes iterate over votes.  Access each property inside of votes, and if the property inside of that matches with the property inside of votecount (so president and president), if the person didn't exist yet inside, add the person and 1 vote.  The second case is that the person already exists, in which case ++ their vote count.

// __________________________________________
// Initial Solution

// Tally the votes in voteCount.

/* Once the votes have been tallied, assign each officer position the name of the
student who received the most votes. */
var voteCount = {
  president: {},
  vicePresident: {},
  secretary: {},
  treasurer: {}
}

var officers = {
  president: undefined,
  vicePresident: undefined,
  secretary: undefined,
  treasurer: undefined
}

//   for (var student in votes) { //Alex
//     var studentsVote = votes[student]; //studentsVote is the object following Alex, containing {president:Bob, vicePresident: Devin, etc;}
//     for (var officer in studentsVote) { //officer is president, vicepresident, etc
//       var name = studentsVote[officer]; //name is the value of the officer key, so aka Bob, Devin, etc
//       for (position in voteCount) {
//         var positionVoteNames = voteCount[position];
//         if (positionVoteNames.hasOwnProperty(name)){
//           positionVoteNames[name] += 1 ;
//         } else {
//           positionVoteNames[name] = 1;
//         }
//       }
//     }
//   }
// return voteCount;
// }

var tallyVotes = function(votes, voteCount){
  for (var position in voteCount) { //position is president: {}
    var positionVoteNames = voteCount[position]; // positionVoteNames is {}
    for (var student in votes) { //student is "Alex": { president: "Bob", ... }
      var studentsVote = votes[student]; //studentsVote is { president: "Bob", ... }
        var name = studentsVote[position]; //name is Bob, etc
        if (positionVoteNames.hasOwnProperty(name)) {
          positionVoteNames[name] += 1;
        } else {
          positionVoteNames[name] = 1;
        }
    }
  }
  return voteCount;
}

var talliedVotes = tallyVotes(votes, voteCount);

var determineWinner = function(officers, talliedVotes) {
  var frontrunner = "";
  for (position in talliedVotes) {
     var maxVotes = 0;
    var  positionVoteNames = talliedVotes[position];
    for (name in positionVoteNames) {
      if (positionVoteNames[name] > maxVotes) {
        maxVotes = positionVoteNames[name];
        frontrunner = name;
      }
       // console.log(maxVotes + " " + name)
    }
    officers[position] = frontrunner;
  }
  return officers;
}

console.log(determineWinner(officers, talliedVotes));

// __________________________________________
// Refactored Solution

// __________________________________________
// Reflection
// Took me a long time to solve, due to the looping within looping concept, and making sure everything was working the way it should be.

// __________________________________________
// Test Code:  Do not alter code below this line.

/*

function assert(test, message, test_number) {
  if (!test) {
    console.log(test_number + "false");
    throw "ERROR: " + message;
  }
  console.log(test_number + "true");
  return true;
}

assert(
  (voteCount.president["Bob"] === 3),
  "Bob should receive three votes for President.",
  "1. "
)

assert(
  (voteCount.vicePresident["Bob"] === 2),
  "Bob should receive two votes for Vice President.",
  "2. "
)

assert(
  (voteCount.secretary["Bob"] === 2),
  "Bob should receive two votes for Secretary.",
  "3. "
)

assert(
  (voteCount.treasurer["Bob"] === 4),
  "Bob should receive four votes for Treasurer.",
  "4. "
)

assert(
  (officers.president === "Louise"),
  "Louise should be elected President.",
  "5. "
)

assert(
  (officers.vicePresident === "Hermann"),
  "Hermann should be elected Vice President.",
  "6. "
)

assert(
  (officers.secretary === "Fred"),
  "Fred should be elected Secretary.",
  "7. "
)

assert(
  (officers.treasurer === "Ivy"),
  "Ivy should be elected Treasurer.",
  "8. "
)

*/<|endoftext|>


<commit_before>import mongoose from 'mongoose'
import Node from '../model/node'
import rank from './rank'

import {
  HTTP_OK,
  HTTP_CREATED,
  HTTP_NOT_FOUND,
  HTTP_BAD_REQUEST,
  HTTP_INTERNAL_SERVER_ERROR,
} from '../../../shared/config'

/* eslint no-underscore-dangle: ["error", { "allow": ["_id"] }] */

mongoose.set('debug', true)

exports.findAll = (req, res/* , next*/) => {
  Node.find({}, (err, nodes) => {
    if (err) {
      return res.status(HTTP_NOT_FOUND).send(err)
    }
    req.nodes = nodes
    return res.status(HTTP_OK).json(nodes)
    // next()
  })
}

exports.findById = (req, res, next) => {
  if (req.params.id) {
    Node.findOne({ _id: req.params.id }, (err, node) => {
      if (err) {
        return res.status(HTTP_NOT_FOUND).send(err)
      }
      req.node = node
      // res.status(HTTP_OK).json(node)
      return next()
    })
  } else {
    res.status(HTTP_BAD_REQUEST).send('No node id')
  }
}

exports.add = (req, res) => {
  if (req.body.node.mId !== ('' || null)) {
    req.body.node._id = req.body.node.mId
  }
  const newNode = new Node(req.body.node)
  newNode.mRank = rank.calcRank(newNode.mId)
  newNode.mTimeStampRankFromServer = new Date()
  try {
    newNode.save((err) => {
      if (err) {
        return res.send(err)
      }
      return res.status(HTTP_CREATED).json({ message: 'Node added!' })
    })
  } catch (ex) {
    res.status(HTTP_INTERNAL_SERVER_ERROR).send(ex)
  }
}

exports.update = (req, res, next) => {
  if (req.params.id) {
    if (req.body.node.mId !== ('' || null)) {
      req.body.node._id = req.body.node.mId
    }
    const newNode = new Node(req.body.node)
    newNode.mRank = rank.calcRank(newNode._id)
    newNode.mTimeStampRankFromServer = new Date()
    Node.findByIdAndUpdate(req.params.id, req.body.node, { new: true, upsert: true },
    (err, node) => {
      if (err) {
        return res.status(HTTP_NOT_FOUND).send(err)
      }
      req.node = node
      // res.status(HTTP_OK).json(node)
      return next()
    })
  } else {
    res.status(HTTP_BAD_REQUEST).send('No node id')
  }
}

exports.delete = (req, res) => {
  if (req.params.id) {
    Node.remove({
      _id: req.params.id,
    }, (err) => {
      if (err) {
        return res.send(err)
      }
      return res.status(HTTP_OK).json({ message: `Node ${req.params.id} successfully deleted` })
    })
  } else {
    res.status(HTTP_BAD_REQUEST).send('No node id')
  }
}
<commit_msg>Sync Node<commit_after>import mongoose from 'mongoose'
import Node from '../model/node'
import rank from './rank'

import {
  HTTP_OK,
  HTTP_CREATED,
  HTTP_NOT_FOUND,
  HTTP_BAD_REQUEST,
  HTTP_INTERNAL_SERVER_ERROR,
} from '../../../shared/config'

/* eslint no-underscore-dangle: ["error", { "allow": ["_id"] }] */

mongoose.set('debug', true)

exports.findAll = (req, res/* , next*/) => {
  Node.find({}, (err, nodes) => {
    if (err) {
      return res.status(HTTP_NOT_FOUND).send(err)
    }
    req.nodes = nodes
    return res.status(HTTP_OK).json(nodes)
    // next()
  })
}

exports.findById = (req, res, next) => {
  if (req.params.id) {
    Node.findOne({ _id: req.params.id }, (err, node) => {
      if (err) {
        return res.status(HTTP_NOT_FOUND).send(err)
      }
      req.node = node
      // res.status(HTTP_OK).json(node)
      return next()
    })
  } else {
    res.status(HTTP_BAD_REQUEST).send('No node id')
  }
}

exports.add = (req, res) => {
  if (req.body.node.mId !== ('' || null)) {
    req.body.node._id = req.body.node.mId
  }
  const newNode = new Node(req.body.node)
  newNode.mRank = rank.calcRank(newNode.mId)
  newNode.mTimeStampRankFromServer = new Date()
  try {
    newNode.save((err) => {
      if (err) {
        return res.send(err)
      }
      return res.status(HTTP_CREATED).json({ message: 'Node added!' })
    })
  } catch (ex) {
    res.status(HTTP_INTERNAL_SERVER_ERROR).send(ex)
  }
}

exports.update = (req, res, next) => {
  if (req.params.id) {
    // if (req.body.node.mId !== ('' || null)) {
    //   req.body.node._id = req.body.node.mId
    // }
    const newNode = new Node(req.body.node)
    newNode.mRank = rank.calcRank(newNode._id)
    newNode.mTimeStampRankFromServer = new Date()
    Node.findOneAndUpdate(req.params.id, req.body.node, { new: true, upsert: true },
    (err, node) => {
      if (err) {
        return res.status(HTTP_NOT_FOUND).send(err)
      }
      req.node = node
      // res.status(HTTP_OK).json(node)
      return next()
    })
  } else {
    res.status(HTTP_BAD_REQUEST).send('No node id')
  }
}

exports.delete = (req, res) => {
  if (req.params.id) {
    Node.remove({
      _id: req.params.id,
    }, (err) => {
      if (err) {
        return res.send(err)
      }
      return res.status(HTTP_OK).json({ message: `Node ${req.params.id} successfully deleted` })
    })
  } else {
    res.status(HTTP_BAD_REQUEST).send('No node id')
  }
}
<|endoftext|>


<commit_before>'use strict';

var passport = require('passport');
var q = require('q');
var _ = require('underscore');

var FacebookStrategy = require('passport-facebook').Strategy;
var LocalStrategy = require('passport-local').Strategy;

var pr = require('app/util/pr');
var user_config = require('app/config/user');
var logger_module = require('app/util/logger');
var logger = logger_module.get('app/util/auth/index');

/**
 * Serialise user id only to session
 */
passport.serializeUser(function(user, done) {
  done(null, user.id);
});

/**
 * Read all user information from the main database to populate the session info
 */
passport.deserializeUser(function(id, done) {
  q(pr.pr.auth.user.find(id))
  .then(function(user) {
    done(undefined, user);
  })
  .fail(function(error) {
    logger.error('pr.pr.auth.user.find(' + id + ') failed with error: ' + error);
    done(error , undefined);
  });
});

/**
 * passport.js local-signup strategy
 */
passport.use('local-signup', new LocalStrategy({
  usernameField: user_config.local_auth.username_field,
  passwordField: user_config.local_auth.password_field,
  passReqToCallback: true
}, function(req, email, password, done) {
  // Why process.nextTick nec? (copied from https://scotch.io/tutorials/easy-node-authentication-setup-and-local)
  // Prob: "Quora: What does process.nextTick(callback) actually do in Node.js?" - answer by Aran Mulholland, bullet 3
  process.nextTick(function() {
    var where_object = {};
    where_object[user_config.local_auth.username_field] = email;
    q(pr.pr.auth.user.find({ where: where_object }))
    .then(function(user) {
      if(user === null) { // email not found, create the user
        var user_attrs = {};
        user_attrs[user_config.local_auth.username_field] = email;
        user_attrs[user_config.local_auth.password_field] = pr.pr.auth.user.hash_password(password);
        q(pr.pr.auth.user.create(user_attrs))
        .then(function(user) {
          logger.info('local-signup user created: ' + email);
          return done(null, user);
        })
        .fail(function(error) {
          // DB or validation error - do not distinguish validation or set flash because that is also done client side
          logger.warn('local-signup callback for ' + email + ' failed user creation, error: ' + error);
          return done(error, undefined, req.flash('message', 'Account creation failed'));
        });
      }
      else {
        logger.warn('local-signup account creation requested for existing account: ' + email);
        return done(null, false, req.flash('message', 'An account with that email address already exists'));
      }
    })
    .fail(function(error) {
      logger.error('local-signup callback for ' + email + ' failed while checking if email already used: ' + error);
      return done(error, undefined, req.flash('message', 'System error'));
    });
  });
}));

/**
 * passport.js local-login strategy
 */
passport.use('local-login', new LocalStrategy({
  usernameField: user_config.local_auth.username_field,
  passwordField: user_config.local_auth.password_field,
  passReqToCallback: true
}, function(req, email, password, done) {
  var where_object = {};
  where_object[user_config.local_auth.username_field] = email;
  q(pr.pr.auth.user.find({ where: where_object }))
  .then(function(user) {
    if(user !== null) {
      if(user.check_password(password)) {
        logger.debug('local-signup logged in: ' + email);
        return done(null, user);
      }
      else {
        logger.debug('local-signup incorrect password: ' + email);
        return done(null, false, req.flash('message', 'Incorrect password'));
      }
    }
    else {
      logger.debug('local-signup unknown email: ' + email);
      return done(null, false, req.flash('message', 'No user with that email address found'));
    }
  })
  .fail(function(error) {
    logger.error('local-login callback for ' + email + ' failed while loading user: ' + error);
    return done(error, undefined, req.flash('message', 'System error'));
  });
}));

passport.use('facebook-auth', new FacebookStrategy({
  clientID: user_config.facebook_auth.client_id,
  clientSecret: user_config.facebook_auth.client_secret,
  callbackURL: user_config.facebook_auth.callback_url,
  passReqToCallback: true
}, function(req, token, refresh_token, profile, done) {
  var where_object = { facebook_id: profile.id };
  q(pr.pr.auth.user.find({ where: where_object }))
  .then(function(user) {
    if(user !== null) { // user found - log in
      logger.debug('facebook-auth callback -- Found existing user, logging in: ' + JSON.stringify(user));
      return done(null, user);
    }
    else { // user not found - create account
      var user_attrs = {
        facebook_id: profile.id,
        facebook_token: token,
        facebook_name: profile.name.givenName + ' ' + profile.name.familyName,
        facebook_email: profile.emails ? profile.emails[0].value : undefined
      };
      logger.debug('facebook-auth callback -- user not found, creating: ' + JSON.stringify(user_attrs));
      q(pr.pr.auth.user.create(user_attrs))
      .then(function(user) {
        logger.info('facebook-auth user created: ' + user_attrs.facebook_id + ' / ' + user_attrs.facebook_name);
        return done(null, user);
      })
      .fail(function(error) {
        // DB or validation error - do not distinguish validation or set flash because that is also done client side
        logger.warn('facebook-auth callback for ' + user_attrs.facebook_id + ' / ' + user_attrs.facebook_name +
          ' failed user creation, error: ' + error);
        return done(error, undefined, req.flash('message', 'Account creation failed'));
      });
    }
  })
  .fail(function(error) {
    logger.error('facebook-auth callback for token ' + token + ' failed while loading user, error: ' + error);
    return done(error, undefined, req.flash('message', 'System error'));
  });
}));

module.exports = {
  passport: passport,

  /**
   * Middleware generator functions relating to authentication
   */
  mw_gen: {
    /**
     * Generates a middleware function that checks req.body has keys for all strings in required_fields, an array
     * TODO: Is this middleware general? Should it be moved into some sort of general middleware library?
     * @param  {Array} required_fields An array of strings
     * @return {Function}              A middleware function that can be passed to an Express router
     */
    check_post_has_req_fields: function check_post_has_req_fields(required_fields) {
      return function(req, res, next) {
        _.each(required_fields, function(req_field) {
          if(req.body[req_field] === undefined) {
            logger.warn('exports.mw_gen.check_post_has_req_fields -- Required post variable undefined: ' + req_field);
          }
        });
        next();
      };
    }
  },

  /**
   * Middleware relating to authentication
   */
  mw: {
    /**
     * Call next if the requester is authenticated otherwise send 403
     */
    ensure_auth: function ensure_auth(req, res, next) {
      logger.debug('exports.mw.ensure_auth - isAuthenticated: ' + req.isAuthenticated());
      if (req.isAuthenticated()) {
        return next();
      }
      else {
        // Don't redirect - this is just an API call so redirects if unauthenticated should be checked/happen client side
        res.status(403).end(); // slightly weird use of 403 but sending something back makes debugging easier
      }
    },

    /**
     * Call next if the requester is unauthenticated otherwise send 403
     */
    ensure_unauth: function ensure_unauth(req, res, next) {
      logger.debug('exports.mw.ensure_unauth - isUnauthenticated: ' + req.isUnauthenticated());
      if (req.isUnauthenticated()) {
        return next();
      }
      else {
        // Don't redirect - this is just an API call so redirects if authenticated should be checked/happen client side
        res.status(403).end();
      }
    },

    /**
     * Middleware that sets a client-visible cookie if a user is logged in, this allows the client-side app to respond
      * intelligently to requests for views that require the user to be logged in (or not).
    */
    set_client_auth_status_cookie: function set_logged_in_cookie_if_authenticated(req, res, next) {
      if(req.isAuthenticated()) {
        res.cookie(user_config.logged_in_cookie_name, 'true', { maxAge: user_config.session.cookie.maxAge });
      }
      next();
    },

    /**
     * Initialise session with start date
     * TODO This is not required - just used in session api example/fiddle
     */
    set_session_start_date: function set_session_start_date(req, res, next) {
      if(!req.session.start) {
        req.session.start = new Date();
      }
      next();
    }
  }
};
<commit_msg>server - set logged-in cookie to false if not logged in<commit_after>'use strict';

var passport = require('passport');
var q = require('q');
var _ = require('underscore');

var FacebookStrategy = require('passport-facebook').Strategy;
var LocalStrategy = require('passport-local').Strategy;

var pr = require('app/util/pr');
var user_config = require('app/config/user');
var logger_module = require('app/util/logger');
var logger = logger_module.get('app/util/auth/index');

/**
 * Serialise user id only to session
 */
passport.serializeUser(function(user, done) {
  done(null, user.id);
});

/**
 * Read all user information from the main database to populate the session info
 */
passport.deserializeUser(function(id, done) {
  q(pr.pr.auth.user.find(id))
  .then(function(user) {
    done(undefined, user);
  })
  .fail(function(error) {
    logger.error('pr.pr.auth.user.find(' + id + ') failed with error: ' + error);
    done(error , undefined);
  });
});

/**
 * passport.js local-signup strategy
 */
passport.use('local-signup', new LocalStrategy({
  usernameField: user_config.local_auth.username_field,
  passwordField: user_config.local_auth.password_field,
  passReqToCallback: true
}, function(req, email, password, done) {
  // Why process.nextTick nec? (copied from https://scotch.io/tutorials/easy-node-authentication-setup-and-local)
  // Prob: "Quora: What does process.nextTick(callback) actually do in Node.js?" - answer by Aran Mulholland, bullet 3
  process.nextTick(function() {
    var where_object = {};
    where_object[user_config.local_auth.username_field] = email;
    q(pr.pr.auth.user.find({ where: where_object }))
    .then(function(user) {
      if(user === null) { // email not found, create the user
        var user_attrs = {};
        user_attrs[user_config.local_auth.username_field] = email;
        user_attrs[user_config.local_auth.password_field] = pr.pr.auth.user.hash_password(password);
        q(pr.pr.auth.user.create(user_attrs))
        .then(function(user) {
          logger.info('local-signup user created: ' + email);
          return done(null, user);
        })
        .fail(function(error) {
          // DB or validation error - do not distinguish validation or set flash because that is also done client side
          logger.warn('local-signup callback for ' + email + ' failed user creation, error: ' + error);
          return done(error, undefined, req.flash('message', 'Account creation failed'));
        });
      }
      else {
        logger.warn('local-signup account creation requested for existing account: ' + email);
        return done(null, false, req.flash('message', 'An account with that email address already exists'));
      }
    })
    .fail(function(error) {
      logger.error('local-signup callback for ' + email + ' failed while checking if email already used: ' + error);
      return done(error, undefined, req.flash('message', 'System error'));
    });
  });
}));

/**
 * passport.js local-login strategy
 */
passport.use('local-login', new LocalStrategy({
  usernameField: user_config.local_auth.username_field,
  passwordField: user_config.local_auth.password_field,
  passReqToCallback: true
}, function(req, email, password, done) {
  var where_object = {};
  where_object[user_config.local_auth.username_field] = email;
  q(pr.pr.auth.user.find({ where: where_object }))
  .then(function(user) {
    if(user !== null) {
      if(user.check_password(password)) {
        logger.debug('local-signup logged in: ' + email);
        return done(null, user);
      }
      else {
        logger.debug('local-signup incorrect password: ' + email);
        return done(null, false, req.flash('message', 'Incorrect password'));
      }
    }
    else {
      logger.debug('local-signup unknown email: ' + email);
      return done(null, false, req.flash('message', 'No user with that email address found'));
    }
  })
  .fail(function(error) {
    logger.error('local-login callback for ' + email + ' failed while loading user: ' + error);
    return done(error, undefined, req.flash('message', 'System error'));
  });
}));

passport.use('facebook-auth', new FacebookStrategy({
  clientID: user_config.facebook_auth.client_id,
  clientSecret: user_config.facebook_auth.client_secret,
  callbackURL: user_config.facebook_auth.callback_url,
  passReqToCallback: true
}, function(req, token, refresh_token, profile, done) {
  var where_object = { facebook_id: profile.id };
  q(pr.pr.auth.user.find({ where: where_object }))
  .then(function(user) {
    if(user !== null) { // user found - log in
      logger.debug('facebook-auth callback -- Found existing user, logging in: ' + JSON.stringify(user));
      return done(null, user);
    }
    else { // user not found - create account
      var user_attrs = {
        facebook_id: profile.id,
        facebook_token: token,
        facebook_name: profile.name.givenName + ' ' + profile.name.familyName,
        facebook_email: profile.emails ? profile.emails[0].value : undefined
      };
      logger.debug('facebook-auth callback -- user not found, creating: ' + JSON.stringify(user_attrs));
      q(pr.pr.auth.user.create(user_attrs))
      .then(function(user) {
        logger.info('facebook-auth user created: ' + user_attrs.facebook_id + ' / ' + user_attrs.facebook_name);
        return done(null, user);
      })
      .fail(function(error) {
        // DB or validation error - do not distinguish validation or set flash because that is also done client side
        logger.warn('facebook-auth callback for ' + user_attrs.facebook_id + ' / ' + user_attrs.facebook_name +
          ' failed user creation, error: ' + error);
        return done(error, undefined, req.flash('message', 'Account creation failed'));
      });
    }
  })
  .fail(function(error) {
    logger.error('facebook-auth callback for token ' + token + ' failed while loading user, error: ' + error);
    return done(error, undefined, req.flash('message', 'System error'));
  });
}));

module.exports = {
  passport: passport,

  /**
   * Middleware generator functions relating to authentication
   */
  mw_gen: {
    /**
     * Generates a middleware function that checks req.body has keys for all strings in required_fields, an array
     * TODO: Is this middleware general? Should it be moved into some sort of general middleware library?
     * @param  {Array} required_fields An array of strings
     * @return {Function}              A middleware function that can be passed to an Express router
     */
    check_post_has_req_fields: function check_post_has_req_fields(required_fields) {
      return function(req, res, next) {
        _.each(required_fields, function(req_field) {
          if(req.body[req_field] === undefined) {
            logger.warn('exports.mw_gen.check_post_has_req_fields -- Required post variable undefined: ' + req_field);
          }
        });
        next();
      };
    }
  },

  /**
   * Middleware relating to authentication
   */
  mw: {
    /**
     * Call next if the requester is authenticated otherwise send 403
     */
    ensure_auth: function ensure_auth(req, res, next) {
      logger.debug('exports.mw.ensure_auth - isAuthenticated: ' + req.isAuthenticated());
      if (req.isAuthenticated()) {
        return next();
      }
      else {
        // Don't redirect - this is just an API call so redirects if unauthenticated should be checked/happen client side
        res.status(403).end(); // slightly weird use of 403 but sending something back makes debugging easier
      }
    },

    /**
     * Call next if the requester is unauthenticated otherwise send 403
     */
    ensure_unauth: function ensure_unauth(req, res, next) {
      logger.debug('exports.mw.ensure_unauth - isUnauthenticated: ' + req.isUnauthenticated());
      if (req.isUnauthenticated()) {
        return next();
      }
      else {
        // Don't redirect - this is just an API call so redirects if authenticated should be checked/happen client side
        res.status(403).end();
      }
    },

    /**
     * Middleware that sets a client-visible cookie if a user is logged in, this allows the client-side app to respond
      * intelligently to requests for views that require the user to be logged in (or not).
    */
    set_client_auth_status_cookie: function set_logged_in_cookie_if_authenticated(req, res, next) {
      if(req.isAuthenticated()) {
        res.cookie(user_config.logged_in_cookie_name, 'true', { maxAge: user_config.session.cookie.maxAge });
      }
      else {
        res.cookie(user_config.logged_in_cookie_name, 'false', { maxAge: user_config.session.cookie.maxAge });
      }
      next();
    },

    /**
     * Initialise session with start date
     * TODO This is not required - just used in session api example/fiddle
     */
    set_session_start_date: function set_session_start_date(req, res, next) {
      if(!req.session.start) {
        req.session.start = new Date();
      }
      next();
    }
  }
};
<|endoftext|>


<commit_before>/* eslint no-console:0 */
import * as tap from 'tap'
import { typeov } from '..'
const test = tap.test
test('float', t => {
  t.equal(typeov(Math.PI), 'float', '=== Math.PI/3.14')
  t.end()
})
test('number', t => {
  t.equal(typeov(666), 'number', '=== 666')
  t.equal(typeov(+0), 'number', '=== +0')
  t.equal(typeov(-0), 'number', '=== -0')
  t.end()
})
test('string', t => {
  t.equal(typeov('hello world'), 'string', '=== hello world')
  t.end()
})
test('boolean', t => {
  t.equal(typeov(true), 'boolean', '=== true')
  t.equal(typeov(false), 'boolean', '=== false')
  t.end()
})
test('symbol', t => {
  t.equal(typeov(Symbol()), 'symbol', '=== Symbol()')
  t.end()
})
test('null', t => {
  t.equal(typeov(null), 'null', null, '=== null')
  t.end()
})
test('infinity', t => {
  t.equal(typeov(Infinity), 'infinity', '=== Infinity')
  t.equal(typeov(-Infinity), 'infinity', '=== -Infinity')
  t.equal(typeov(+Infinity), 'infinity', '=== +Infinity')
  t.end()
})
test('undefined', t => {
  t.equal(typeov(undefined), 'undefined', '=== undefined')
  t.end()
})
test('function', t => {
  t.equal(typeov(function(){}), 'function', '=== function(){}')
  t.end()
})
test('object', t => {
  t.equal(typeov({}), 'object', '=== {}')
  t.equal(typeov(Object.create(null)), 'object', '=== Object.create(null)')
  t.end()
})
test('array', t => {
  t.equal(typeov([]), 'array', '=== []')
  t.equal(typeov(Array()), 'array', '=== Array()')
  t.end()
})
test('date', t => {
  t.equal(typeov(new Date), 'date', '=== new Date')
  t.end()
})
test('json', t => {
  t.equal(typeov('[{"A": "B"}]'), 'json', '!== [{"A": "B"}]')
  t.notEqual(typeov('[{a: "B"}]'), 'json', '!== [{a: "B"}]')
  t.equal(typeov('{"A":"B"}'), 'json', '=== {"A":"B"}')
  t.notEqual(typeov('{a:"B"}'), 'json', '!== {a:"B"}')
  t.end()
})
test('promise', t => {
  t.equal(typeov(Promise.resolve(true)), 'promise', '=== Promise.resolve(true)')
  t.end()
})
test('set', t => {
  t.equal(typeov(new Set), 'set', '=== new Set')
  t.end()
})
test('weakset', t => {
  t.equal(typeov(new WeakSet), 'weakset', '=== new WeakSet')
  t.end()
})
test('map', t => {
  t.equal(typeov(new Map), 'map', '=== new Map')
  t.end()
})
test('weakmap', t => {
  t.equal(typeov(new WeakMap), 'weakmap', '=== new WeakMap')
  t.end()
})
test('regexp', t => {
  t.equal(typeov(/regex/), 'regexp', '=== /regex/')
  t.equal(typeov(new RegExp), 'regexp', '=== new RegExp')
  t.equal(typeov(RegExp()), 'regexp', '=== RegExp()')
  t.end()
})
test('buffer', t => {
  t.equal(typeov(new Buffer(0)), 'buffer', '=== new Buffer')
  t.end()
})
<commit_msg>add more tests<commit_after>/* eslint no-console:0 */
import * as tap from 'tap'
import { typeov } from '..'
const test = tap.test
test('float', t => {
  t.equal(typeov(Math.PI), 'float', '=== Math.PI/3.14')
  t.equal(typeov(6.666666666), 'float', '=== 6.666666666')
  t.equal(typeov(6.6), 'float', '=== 6.6')
  t.equal(typeov(.6), 'float', '=== .6')
  t.equal(typeov(0.6), 'float', '=== 0.6')
  t.equal(typeov(1e99), 'float', '=== 1e99')
  t.end()
})
test('number', t => {
  t.equal(typeov(666), 'number', '=== 666')
  t.equal(typeov(+0), 'number', '=== +0')
  t.equal(typeov(-0), 'number', '=== -0')
  t.equal(typeov(0), 'number', '=== 0')
  t.equal(typeov(1e6), 'number', '=== 1e6')
  t.end()
})
test('string', t => {
  t.equal(typeov('hello world'), 'string', '=== hello world')
  t.end()
})
test('boolean', t => {
  t.equal(typeov(true), 'boolean', '=== true')
  t.equal(typeov(false), 'boolean', '=== false')
  t.equal(typeov(Boolean()), 'boolean', '=== Boolean()')
  t.end()
})
test('symbol', t => {
  t.equal(typeov(Symbol()), 'symbol', '=== Symbol()')
  t.end()
})
test('null', t => {
  t.equal(typeov(null), 'null', null, '=== null')
  t.end()
})
test('infinity', t => {
  t.equal(typeov(Infinity), 'infinity', '=== Infinity')
  t.equal(typeov(-Infinity), 'infinity', '=== -Infinity')
  t.equal(typeov(+Infinity), 'infinity', '=== +Infinity')
  t.end()
})
test('undefined', t => {
  t.equal(typeov(undefined), 'undefined', '=== undefined')
  t.end()
})
test('function', t => {
  t.equal(typeov(function(){}), 'function', '=== function(){}')
  t.end()
})
test('object', t => {
  t.equal(typeov({}), 'object', '=== {}')
  t.equal(typeov(Object.create(null)), 'object', '=== Object.create(null)')
  t.equal(typeov(new function(){}), 'object', '=== new function(){}')
  t.end()
})
test('array', t => {
  t.equal(typeov([]), 'array', '=== []')
  t.equal(typeov(Array()), 'array', '=== Array()')
  t.end()
})
test('date', t => {
  t.equal(typeov(new Date), 'date', '=== new Date')
  t.end()
})
test('json', t => {
  t.equal(typeov('[{"A": "B"}]'), 'json', '!== [{"A": "B"}]')
  t.notEqual(typeov('[{a: "B"}]'), 'json', '!== [{a: "B"}]')
  t.equal(typeov('{"A":"B"}'), 'json', '=== {"A":"B"}')
  t.notEqual(typeov('{a:"B"}'), 'json', '!== {a:"B"}')
  t.end()
})
test('promise', t => {
  t.equal(typeov(Promise.resolve(true)), 'promise', '=== Promise.resolve(true)')
  t.end()
})
test('set', t => {
  t.equal(typeov(new Set), 'set', '=== new Set')
  t.end()
})
test('weakset', t => {
  t.equal(typeov(new WeakSet), 'weakset', '=== new WeakSet')
  t.end()
})
test('map', t => {
  t.equal(typeov(new Map), 'map', '=== new Map')
  t.end()
})
test('weakmap', t => {
  t.equal(typeov(new WeakMap), 'weakmap', '=== new WeakMap')
  t.end()
})
test('regexp', t => {
  t.equal(typeov(/regex/), 'regexp', '=== /regex/')
  t.equal(typeov(new RegExp), 'regexp', '=== new RegExp')
  t.equal(typeov(RegExp()), 'regexp', '=== RegExp()')
  t.end()
})
test('buffer', t => {
  t.equal(typeov(new Buffer(0)), 'buffer', '=== new Buffer')
  t.end()
})
<|endoftext|>


<commit_before>export const TOGGLE_PLAY = 'TOGGLE_PLAY';
export const CHANGE_CURRENT_SECONDS = 'CHANGE_CURRENT_SECONDS';
export const SEEK = 'SEEK';
export const SET_CURRENT_SONG = 'SET_CURRENT_SONG';
export const SET_DURATION = 'SET_DURATION';

export const togglePlay = {
  type: TOGGLE_PLAY
};

export const changeCurrentSeconds = (seconds) => ({
  type: CHANGE_CURRENT_SECONDS,
  currentSeconds: seconds
});

export const seekToSeconds = (seconds) => ({
  type: SEEK,
  playFromSeconds: seconds
});

export const setCurrentSong = (song) => ({
  type: SET_CURRENT_SONG,
  currentSong: {
    title: song.title,
    artist: song.artist,
    album: song.album,
    albumArt: song.albumArt,
    src: song.src
  }
});

export const setDuration = (duration) => ({
  type: SET_DURATION,
  totalSeconds: duration
});
<commit_msg>Add missing action<commit_after>export const TOGGLE_PLAY = 'TOGGLE_PLAY';
export const CHANGE_CURRENT_SECONDS = 'CHANGE_CURRENT_SECONDS';
export const SEEK = 'SEEK';
export const SET_CURRENT_SONG = 'SET_CURRENT_SONG';
export const SET_DURATION = 'SET_DURATION';
export const CHANGE_VOLUME = 'CHANGE_VOLUME';

export const togglePlay = {
  type: TOGGLE_PLAY
};

export const changeCurrentSeconds = (seconds) => ({
  type: CHANGE_CURRENT_SECONDS,
  currentSeconds: seconds
});

export const seekToSeconds = (seconds) => ({
  type: SEEK,
  playFromSeconds: seconds
});

export const setCurrentSong = (song) => ({
  type: SET_CURRENT_SONG,
  currentSong: {
    title: song.title,
    artist: song.artist,
    album: song.album,
    albumArt: song.albumArt,
    src: song.src
  }
});

export const setDuration = (duration) => ({
  type: SET_DURATION,
  totalSeconds: duration
});
<|endoftext|>