<commit_before>const fs = require('fs');

const babel = require('babel-core');
import babelGenerator from 'babel-generator';

import parsing from './parsing';

const options = {
    functionMarker: 'i18n',
    elementMarker: 'I18N',
    whitelistedAttributes: {
        a:   ['href'],
        img: ['alt'],
        '*': ['title', 'placeholder', 'alt', 'summary'],
        'Pluralize': ['on'],
        'Match': ['when'],
    },
};

const whitelist = (function(wl) {
    const shared = wl['*'];
    return Object.entries(wl).reduce((whitelist, [name, attrs]) => {
        if (name !== '*') {
            wl[name] = attrs.concat(shared);
        }
        return wl;
    }, {'*': shared});
})(options.whitelistedAttributes);

// Error types

function InputError(description) {
    return {
        description,
        inputError: true
    };
}

function assertInput(condition, description) {
    if (!condition) {
        throw InputError(description);
    }
}

// Code generation

function generate(ast) {
    return babelGenerator(ast, {comments: false}).code;
}

// Function messages: i18n("Foo all the bars.")

function isFunctionMarker(callExpression) {
    return callExpression.callee.name === options.functionMarker;
}

function validateFunctionMessage(callExpression) {
    assertInput(
        callExpression.arguments.length === 1,
        `Expected exactly 1 argument to ${options.functionMarker}(), but got ${callExpression.arguments.length}`
    );

    assertInput(
        callExpression.arguments[0].type === 'StringLiteral',
        `Expected a StringLiteral argument to ${options.functionMarker}(), but got ${callExpression.arguments[0].type}`
    );
}

function extractFunctionMessage(callExpression) {
    return callExpression.arguments[0].value;
}

// Element messages: <I18N>Foo all the bars.</I18N>

function nodeName(node) {
    return generate(node.name);
}

function elementName(jsxElement) {
    return nodeName(jsxElement.openingElement);
}

function isElementMarker(jsxElement) {
    return elementName(jsxElement) === 'I18N';
}

const JSXElementValidationVisitor = {
    JSXElement(path)  {

    },

    JSXAttribute(path) {

    },

    JSXExpressionContainer(path) {

    },
};

function attributeName(jsxAttribute) {
    return nodeName(jsxAttribute);
}

function attributeIsSanitized(elementName, attributeName) {
    const whitelistedAttributes = whitelist[elementName] || whitelist['*'];
    return !whitelistedAttributes.includes(attributeName);
}

const JSXElementSanitizationVisitor = {
    JSXAttribute(path) {
        if (attributeIsSanitized(elementName(path.parentPath.parent), attributeName(path.node))) {
            path.remove();
        }
    },
};

function extractElementMessage(jsxElement) {
    const messageWithContainer = generate(jsxElement);
    return /<I18N>([\s\S]+?)<\/I18N>/.exec(messageWithContainer)[1].trim();
}

export function extractFromSource(src) {
    const messages = [];

    const plugin = function({types: t}, {opts} = {opts: {}}) {
        Object.assign(options, opts)
        return {
            visitor: {
                CallExpression({node: callExpression}) {
                    if (isFunctionMarker(callExpression)) {
                        validateFunctionMessage(callExpression);
                        messages.push(extractFunctionMessage(callExpression));
                    }
                },

                JSXElement(path) {
                    if (isElementMarker(path.node)) {
                        const validationContext = {};
                        path.traverse(JSXElementSanitizationVisitor);
                        messages.push(extractElementMessage(path.node));
                    }
                },
            }
        }
    }

    parsing.transform(src, plugin);
    return messages;
}

export default function extractFromPaths(paths) {
    let messages = {};
    const ffmp = require('../bin/filesFromMixedPaths');

    ffmp(paths).forEach(path => {
        const src = fs.readFileSync(path, "utf-8");
        try {
            extractFromSource(src).forEach(msg => messages[msg] = msg);
        } catch(e) {
            console.error(path, e);
            if (e.stack) {
                console.error(e.stack);
            }
        }
    });

    return messages;
}
<commit_msg>Work toward validation; extracting messages w/ namespaced names<commit_after>const fs = require('fs');

const babel = require('babel-core');

import babelGenerator from 'babel-generator';
import * as types from 'babel-types';

import parsing from './parsing';

const options = {
    functionMarker: 'i18n',
    elementMarker: 'I18N',
    whitelistedAttributes: {
        a:   ['href'],
        img: ['alt'],
        '*': ['title', 'placeholder', 'alt', 'summary'],
        'Pluralize': ['on'],
        'Match': ['when'],
    },
};

const whitelist = (function(wl) {
    const shared = wl['*'];
    return Object.entries(wl).reduce((whitelist, [name, attrs]) => {
        if (name !== '*') {
            wl[name] = attrs.concat(shared);
        }
        return wl;
    }, {'*': shared});
})(options.whitelistedAttributes);

// Error types

function InputError(description, node) {
    return {
        description,
        node,
        inputError: true
    };
}

function assertInput(condition, description, node) {
    if (!condition) {
        throw InputError(description, node);
    }
}

// Code generation

function generate(ast) {
    return babelGenerator(ast, {comments: false}).code;
}

// Function messages: i18n("Foo all the bars.")

function isFunctionMarker(callExpression) {
    return callExpression.callee.name === options.functionMarker;
}

function validateFunctionMessage(callExpression) {
    assertInput(
        callExpression.arguments.length === 1,
        `Expected exactly 1 argument to ${options.functionMarker}(), but got ${callExpression.arguments.length}`,
        callExpression
    );

    assertInput(
        callExpression.arguments[0].type === 'StringLiteral',
        `Expected a StringLiteral argument to ${options.functionMarker}(), but got ${callExpression.arguments[0].type}`,
        callExpression
    );
}

function extractFunctionMessage(callExpression) {
    return callExpression.arguments[0].value;
}

// Element messages: <I18N>Foo all the bars.</I18N>

function nodeName(node) {
    return generate(node.name);
}

function elementName(jsxElement) {
    return nodeName(jsxElement.openingElement);
}

function elementAttributes(jsxElement) {
    return jsxElement.openingElement.attributes;
}

function isElementMarker(jsxElement) {
    return elementName(jsxElement) === 'I18N';
}

function isSimpleExpression(expression) {
    if (expression.type === 'Identifier') {
        return true;
    } else if (expression.type === 'ThisExpression') {
        return true;
    } else if (expression.type === 'MemberExpression') {
        return !expression.computed && isSimpleExpression(expression.object);
    } else {
        return false;
    }
}

function hasNamespacedName(jsxElement) {
    return jsxElement.openingElement.name.type === 'JSXNamespacedName';
}

function hasI18nId(jsxElement) {
    return (
        hasNamespacedName(jsxElement) ||
        hasI18nIdAttribute(jsxElement)
    );
}

function hasI18nIdAttribute(jsxElement) {
    return elementAttributes(jsxElement).map(attributeName).includes('i18n-id');
}

function i18nId(jsxElement) {
    if (hasNamespacedName(jsxElement)) {
        // It's names all the way down
        return jsxElement.openingElement.name.name.name;
    } else {
        const attr = elementAttributes(jsxElement)
            .find(a => attributeName(a) === 'i18n-id');
        if (attr) {
            assertInput(attr.value.type === 'StringLiteral',
                "i18n-id attribute found with non-StringLiteral value",
                jsxElement
            );
            return attr.value.value;
        }
    }
}

function convertToNamespacedName(jsxElement) {
    if (!hasNamespacedName(jsxElement)) {
        const name = elementName(jsxElement);
        const id = i18nId(jsxElement);
        if (id) {
            const nameAst = types.JSXNamespacedName(
                types.JSXIdentifier(name),
                types.JSXIdentifier(id)
            );
            jsxElement.openingElement.name = nameAst;
            if (jsxElement.closingElement) {
                jsxElement.closingElement.name = nameAst;
            }
        }
    }

    return elementName(jsxElement);
}

const JSXElementValidationVisitor = {
    JSXElement(path) {
        // prevent nested markers
        assertInput(!isElementMarker(path.node),
            "Found a nested message marker",
            path.node
        );

        // // ensure i18n-id is present if there are sanitized attributes
        // if (path.node.openingElement.attributes.some(
        //     a => attributeIsSanitized(path.node, a))
        // ) {
        //     assertInput(hasI18nId(path.node),
        //         "Element with sanitized attributes was missing an i18n-id",
        //         path.node
        //     );
        // }

        // keep count of name/id for duplicate checking
        const elementName = convertToNamespacedName(path.node);
        const count = this.validationContext.componentNamesAndIds[elementName] || 0;
        this.validationContext.componentNamesAndIds[elementName] = count + 1;
    },

    JSXAttribute(path) {
        // technically part of sanitization, but visitors are merged
        // for performance
        if (attributeIsSanitized(path.parentPath.parent, path.node)) {
            path.remove();
        }
    },

    JSXExpressionContainer(path) {
        assertInput(isSimpleExpression(path.node),
            "Only identifiers and simple member expressions (this.that.thud) are allowed in " +
            "<I18N> tags.",
            path.node
        );
    },
};

function attributeName(jsxAttribute) {
    return nodeName(jsxAttribute);
}

function attributeIsSanitized(element, attribute) {
    const whitelistedAttributes = whitelist[elementName(element)] || whitelist['*'];
    return !whitelistedAttributes.includes(attributeName(attribute));
}

function extractElementMessage(jsxElement) {
    const messageWithContainer = generate(jsxElement);
    // HACK.
    return /<I18N>([\s\S]+?)<\/I18N>/.exec(messageWithContainer)[1].trim();
}

export function extractFromSource(src) {
    const messages = [];

    const plugin = function({types: t}, {opts} = {opts: {}}) {
        Object.assign(options, opts)
        return {
            visitor: {
                CallExpression({node: callExpression}) {
                    if (isFunctionMarker(callExpression)) {
                        validateFunctionMessage(callExpression);
                        messages.push(extractFunctionMessage(callExpression));
                    }
                },

                JSXElement(path) {
                    if (isElementMarker(path.node)) {
                        // Traverse with state of validationContext
                        const validationContext = {
                            root: path,
                            componentNamesAndIds: {},
                        };
                        path.traverse(JSXElementValidationVisitor, {validationContext});
                        messages.push(extractElementMessage(path.node));
                    }
                },
            }
        }
    }

    parsing.transform(src, plugin);
    return messages;
}

export default function extractFromPaths(paths) {
    let messages = {};
    const ffmp = require('../bin/filesFromMixedPaths');

    ffmp(paths).forEach(path => {
        const src = fs.readFileSync(path, "utf-8");
        try {
            extractFromSource(src).forEach(msg => messages[msg] = msg);
        } catch(e) {
            console.error(path, e);
            if (e.stack) {
                console.error(e.stack);
            }
            if (e.node) {
                console.error("Error at ", generate(e.node));
            }
        }
    });

    return messages;
}
<|endoftext|>


<commit_before>(function($){

	/* ---------------------------- *\
				Fall Style
	\* ---------------------------- */

	var settings;

	$.fn.fallwall_init = function( template, dataArray, options, callback_func ) {

		// Required parameters
		if( template == null || dataArray == null ) {
			throw new Error('You missed some parameters while initializing')
		}

		// Store data from user
		settings = $.extend({
			gridNumber: 20,
			columnNumber: 1,
			defaultClass: '',
			html_template: `<div class='fw_grid'>${template}</div>`,
			dataArray: dataArray,
			currentGrid: 0
		}, options);

		// Add columns
		var colElements = '';
		for( var i = 0; i < settings.columnNumber; i++ ) {
			colElements += '

';
		}
		this.append( colElements );

		// Prepare CSS
		this.find('.fw_column').css({
			'display': 'inline-block',
			'vertical-align': 'top',
			'width': this.width()%settings.columnNumber == 0 ? this.width()/settings.columnNumber-1 : Math.floor(this.width()/settings.columnNumber)
		});

		// Add grids at first
		_setContentAtFirst( dataArray, callback_func );

	};

	$.fn.loadMoreFw = function( callback_func ) {

		if( settings.currentGrid +1 < settings.dataArray.length ) {

			settings.currentGrid++;
			const limitNum = settings.currentGrid + settings.gridNumber;
			for( var i = settings.currentGrid; i < limitNum; i++ ) {

				if( typeof settings.dataArray[i] != "undefined" ) {

					_createGrid( settings.dataArray[i], 'down' );
					settings.currentGrid = i;

				}
				else {
					// Data is exhausted before last run in loop
					if( callback_func ) {
						if( typeof callback_func == 'function' )
							callback_func();
						else
							console.error(`${callback_func} is not a function`);
					}
					return "NO_MORE_DATA";
				}

				// Last run in loop
				if( i == limitNum-1 ) {
					if( callback_func ) {
						if( typeof callback_func == 'function' )
							callback_func();
						else
							console.error(`${callback_func} is not a function`);
					}
					return "FINISHED";
				}

			}

		}

		/***
		 * There is no more data.
		 * All is displayed.
		***/
		return "NO_MORE_DATA";

	};

	// Directly add a new grid at the top of any column
	$.fn.addFwGrid = function( data, callback_func ) {

		if( typeof data == 'object' ) {
			// Add a new grid
			_createGrid( data, 'up' );

			if( callback_func ) {
				if( typeof callback_func == 'function' )
					callback_func();
				else
					console.error(`${callback_func} is not a function`);
			}
		}
		else {
			throw new Error(`First parameter of addFwGrid(): ${data} must be Object`);
		}

	};

	function _setContentAtFirst( dataArray, callback_func ) {

		for( var i = 0; i < settings.gridNumber; i++ ) {
			if( typeof dataArray[i] != "undefined" ) {
				_createGrid( dataArray[i], 'down' );
				settings.currentGrid = i;
			}
			else {
				break;
			}
		}

		if( callback_func ) {
			if( typeof callback_func == 'function' )
				callback_func();
			else
				console.error(`${callback_func} is not a function`);
		}

	}

	/***
	 *
	 * Add new grid
	 * direction: up/down => grid is added at the top/bottom
	 * But keep second parameter - data because of 'addFwGrid()'
	 *
	***/
	function _createGrid( obj, direction ) {

		var thisCode = settings.html_template;

		for( var j = 0; j < Object.keys(obj).length; j++ ) {
			thisCode = thisCode.replace( `fallwall_#${j+1}`, obj[j] );
		}

		const targetColumn = $('.fw_column').eq( _getShortestCol() );
		var creatingElement;
		if( direction == 'up' ) {
			targetColumn.prepend( thisCode );
			creatingElement = targetColumn.find('.fw_grid').first();
		}
		else {
			targetColumn.append( thisCode );
			creatingElement = targetColumn.find('.fw_grid').last();
		}

		// Add animation class
		if( settings.defaultClass != '' ) {
			creatingElement.addClass( settings.defaultClass );
		}

	}

	// Return the shortest '.fw_column' to append a new grid
	function _getShortestCol() {

		var heightArray = [];

		$.each( $('.fw_column'), function(index, element) {
			heightArray.push( element.offsetHeight );
		});

		const minColumn = Math.min.apply( null, heightArray );
		return $.inArray( minColumn, heightArray );

	}

}(jQuery));
<commit_msg>Why didn't I use percent-wdith<commit_after>(function($){

	/* ---------------------------- *\
				Fall Style
	\* ---------------------------- */

	var settings;

	$.fn.fallwall_init = function( template, dataArray, options, callback_func ) {

		// Required parameters
		if( template == null || dataArray == null ) {
			throw new Error('You missed some parameters while initializing')
		}

		// Store data from user
		settings = $.extend({
			gridNumber: 20,
			columnNumber: 1,
			defaultClass: '',
			html_template: `<div class='fw_grid'>${template}</div>`,
			dataArray: dataArray,
			currentGrid: 0
		}, options);

		// Add columns
		var colElements = '';
		for( var i = 0; i < settings.columnNumber; i++ ) {
			colElements += '

';
		}
		this.append( colElements );

		// Prepare CSS
		this.find('.fw_column').css({
			'display': 'inline-block',
			'vertical-align': 'top',
			'width': `${100/settings.columnNumber}%`
		});

		// Add grids at first
		_setContentAtFirst( dataArray, callback_func );

	};

	$.fn.loadMoreFw = function( callback_func ) {

		if( settings.currentGrid +1 < settings.dataArray.length ) {

			settings.currentGrid++;
			const limitNum = settings.currentGrid + settings.gridNumber;
			for( var i = settings.currentGrid; i < limitNum; i++ ) {

				if( typeof settings.dataArray[i] != "undefined" ) {

					_createGrid( settings.dataArray[i], 'down' );
					settings.currentGrid = i;

				}
				else {
					// Data is exhausted before last run in loop
					if( callback_func ) {
						if( typeof callback_func == 'function' )
							callback_func();
						else
							console.error(`${callback_func} is not a function`);
					}
					return "NO_MORE_DATA";
				}

				// Last run in loop
				if( i == limitNum-1 ) {
					if( callback_func ) {
						if( typeof callback_func == 'function' )
							callback_func();
						else
							console.error(`${callback_func} is not a function`);
					}
					return "FINISHED";
				}

			}

		}

		/***
		 * There is no more data.
		 * All is displayed.
		***/
		return "NO_MORE_DATA";

	};

	// Directly add a new grid at the top of any column
	$.fn.addFwGrid = function( data, callback_func ) {

		if( typeof data == 'object' ) {
			// Add a new grid
			_createGrid( data, 'up' );

			if( callback_func ) {
				if( typeof callback_func == 'function' )
					callback_func();
				else
					console.error(`${callback_func} is not a function`);
			}
		}
		else {
			throw new Error(`First parameter of addFwGrid(): ${data} must be Object`);
		}

	};

	function _setContentAtFirst( dataArray, callback_func ) {

		for( var i = 0; i < settings.gridNumber; i++ ) {
			if( typeof dataArray[i] != "undefined" ) {
				_createGrid( dataArray[i], 'down' );
				settings.currentGrid = i;
			}
			else {
				break;
			}
		}

		if( callback_func ) {
			if( typeof callback_func == 'function' )
				callback_func();
			else
				console.error(`${callback_func} is not a function`);
		}

	}

	/***
	 *
	 * Add new grid
	 * direction: up/down => grid is added at the top/bottom
	 * But keep second parameter - data because of 'addFwGrid()'
	 *
	***/
	function _createGrid( obj, direction ) {

		var thisCode = settings.html_template;

		for( var j = 0; j < Object.keys(obj).length; j++ ) {
			thisCode = thisCode.replace( `fallwall_#${j+1}`, obj[j] );
		}

		const targetColumn = $('.fw_column').eq( _getShortestCol() );
		var creatingElement;
		if( direction == 'up' ) {
			targetColumn.prepend( thisCode );
			creatingElement = targetColumn.find('.fw_grid').first();
		}
		else {
			targetColumn.append( thisCode );
			creatingElement = targetColumn.find('.fw_grid').last();
		}

		// Add animation class
		if( settings.defaultClass != '' ) {
			creatingElement.addClass( settings.defaultClass );
		}

	}

	// Return the shortest '.fw_column' to append a new grid
	function _getShortestCol() {

		var heightArray = [];

		$.each( $('.fw_column'), function(index, element) {
			heightArray.push( element.offsetHeight );
		});

		const minColumn = Math.min.apply( null, heightArray );
		return $.inArray( minColumn, heightArray );

	}

}(jQuery));
<|endoftext|>


<commit_before>$(function(){
  $('#canvas')[0].ondragover = function() { return false; };
  $('#canvas')[0].ondrop = function(e){
    uploadImage( e.dataTransfer.files[0] );
    return false;
  };
  $("#find_file").on('click', function() {
    $("#image-to-upload").trigger('click');
  });
  $("#image-to-upload").on('change', function() {
    uploadImage( document.getElementById("image-to-upload").files[0] );
  });
  $('#download_image').on('click', function(){
    var canvas = document.getElementById('canvas');
    this.href = canvas.toDataURL().replace("image/png", "image/octet-stream");
    this.download = "image.png";
  });
  function uploadImage(file){
    if(typeof file != "undefined"){
      var ctx = document.getElementById('canvas').getContext('2d');
      var img = new Image();
      if( file.substring(0, 4) == "http" ){
        img.src = file;
      }
      else{
        var url = window.URL || window.webkitURL;
        var src = url.createObjectURL(file);
        img.src = src;
      }
      img.onload = function(){
        dimension = resizeImage(img);
        $('#canvas').attr({width: dimension.width, height: dimension.height});
        ctx.drawImage(img,0,0, dimension.width, dimension.height);
        url.revokeObjectURL(src);
      };
    }
  }

  function resizeImage(img){
    var MAX_WIDTH = 640;
    var MAX_HEIGHT = 480;
    var width = img.width;
    var height = img.height;

    if (width > height) {
      if (width > MAX_WIDTH) {
          height *= MAX_WIDTH / width;
          width = MAX_WIDTH;
        }
    } else {
      if (height > MAX_HEIGHT) {
          width *= MAX_HEIGHT / height;
          height = MAX_HEIGHT;
        }
    }
    return {width: width, height: height};
  }

  function loadInitialImage(){
    uploadImage( document.URL+'/img/image.png' );
  }
  loadInitialImage();
});
<commit_msg>Design layout and UI<commit_after>$(function(){
  $('#canvas')[0].ondragover = function() { return false; };
  $('#canvas')[0].ondrop = function(e){
    uploadImage( e.dataTransfer.files[0] );
    return false;
  };
  $("#find_file").on('click', function() {
    $("#image-to-upload").trigger('click');
  });
  $("#image-to-upload").on('change', function() {
    uploadImage( document.getElementById("image-to-upload").files[0] );
  });
  $('#download_image').on('click', function(){
    var canvas = document.getElementById('canvas');
    this.href = canvas.toDataURL().replace("image/png", "image/octet-stream");
    this.download = "image.png";
  });
  function uploadImage(file){
    if(typeof file != "undefined"){
      var ctx = document.getElementById('canvas').getContext('2d');
      var img = new Image();
      if( typeof file == "string" ){
        img.src = file;
      }
      else{
        var url = window.URL || window.webkitURL;
        var src = url.createObjectURL(file);
        img.src = src;
        url.revokeObjectURL(src);
      }
      img.onload = function(){
        dimension = resizeImage(img);
        $('#canvas').attr({width: dimension.width, height: dimension.height});
        ctx.drawImage(img,0,0, dimension.width, dimension.height);
      };
    }
  }

  function resizeImage(img){
    var MAX_WIDTH = 640;
    var MAX_HEIGHT = 480;
    var width = img.width;
    var height = img.height;

    if (width > height) {
      if (width > MAX_WIDTH) {
          height *= MAX_WIDTH / width;
          width = MAX_WIDTH;
        }
    } else {
      if (height > MAX_HEIGHT) {
          width *= MAX_HEIGHT / height;
          height = MAX_HEIGHT;
        }
    }
    return {width: width, height: height};
  }

  function loadInitialImage(){
    uploadImage( document.URL+'/img/image.png' );
  }
  loadInitialImage();
});
<|endoftext|>


<commit_before>var text = []; //"content of text here";
var delay = 50;
var currentWord = 0;
var currentChar = 1;
var destination = "[set in call to type]";
var dest = null;

console.log("testing - 8");

function type() {
    if (document.getElementById) {
        dest = document.getElementById(destination);
        if (dest) {
            dest.innerHTML = text[currentWord].substr(0, currentChar);
            ++currentChar;
            if (currentChar > text[currentWord].length) {

                unType();

            }
            else
                setTimeout("type()", delay);
        }
    }
}

function unType() {
    console.log("unType()");

    /*if (currentChar === 1) {
        type();//setTimeout("type()", 2500);
        return;
    }*/

    setTimeout(
        function () {
            console.log("lambda");
            dest.innerHTML = text[currentWord].substr(0, currentChar - 3);

            unType();

            /* currentChar = 1;
            if (++currentWord === text.length) {
                currentWord = 0;
            }*/

        },
        1000);
}

function startTyping(textParam, delayParam, destinationParam) {
    text = textParam;
    delay = delayParam;
    currentChar = 1;
    destination = destinationParam;
    type();
}

startTyping(["Software Developer", "University of Texas Student", "Entrepreneur"], 50, "messages");<commit_msg>added dec<commit_after>var text = []; //"content of text here";
var delay = 50;
var currentWord = 0;
var currentChar = 1;
var destination = "[set in call to type]";
var dest = null;

console.log("testing - 8");

function type() {
    if (document.getElementById) {
        dest = document.getElementById(destination);
        if (dest) {
            dest.innerHTML = text[currentWord].substr(0, currentChar);
            ++currentChar;
            if (currentChar > text[currentWord].length) {

                unType();

            }
            else
                setTimeout("type()", delay);
        }
    }
}

function unType() {
    console.log("unType()");

    /*if (currentChar === 1) {
        type();//setTimeout("type()", 2500);
        return;
    }*/

    setTimeout(
        function () {
            console.log("lambda");
            dest.innerHTML = text[currentWord].substr(0, --currentChar);

            unType();

            /* currentChar = 1;
            if (++currentWord === text.length) {
                currentWord = 0;
            }*/

        },
        1000);
}

function startTyping(textParam, delayParam, destinationParam) {
    text = textParam;
    delay = delayParam;
    currentChar = 1;
    destination = destinationParam;
    type();
}

startTyping(["Software Developer", "University of Texas Student", "Entrepreneur"], 50, "messages");<|endoftext|>


<commit_before>/************************************************
 * #### jQuery bcralnit.js v0.0.1 ####
 * Coded by Ican Bachors 2017.
 * https://github.com/bachors/bcralnit.js
 * Updates will be posted to this site.
 ***********************************************/

$.fn.bcralnit = function(e) {
    var f = {
        width: '60px',
        background: '#ddd',
        color: '#333'
    };
    if (typeof e === 'object') {
        e.width = (e.width == undefined ? f.width : e.width);
        e.background = (e.background == undefined ? f.background : e.background);
        e.color = (e.color == undefined ? f.color : e.color);
    } else {
        e = f
    }
    $(this).each(function(i, a) {
        var w = $(this).css('width'),
            h = $(this).css('height'),
            d = ($(this).css('display') == 'inline' ? 'inline-block' : $(this).css('display')),
            ff = $(this).css('font-family'),
            fs = $(this).css('font-size'),
            lh = $(this).css('line-height'),
            bt = $(this).css('border-top-width'),
            bb = $(this).css('border-bottom-width'),
            br = $(this).css('border-right-width'),
            bl = $(this).css('border-left-width'),
            m = $(this).css('margin'),
            pt = $(this).css('padding-top'),
            pb = $(this).css('padding-bottom'),
            pl = $(this).css('padding-left'),
            pr = $(this).css('padding-right'),
            nw = (parseInt(w) - parseInt(e.width)) + 'px',
            c = ($(this).attr('id') != null && $(this).attr('id') != undefined ? 'bcralnit_' + $(this).attr('id') + i : 'bcralnit_' + $(this).attr('class') + i),
            b = '<div style="position:absolute;box-sizing:border-box;border:none;margin:0px;overflow:hidden;white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;padding:' + (parseInt(pt) + parseInt(bt)) + 'px ' + pr + ' ' + pb + ' ' + pl + ';font-family:' + ff + ';font-size:' + fs + ';line-height:' + lh + ';right:' + e.width + ';width:' + (parseInt(nw) - parseInt(br) - parseInt(bl)) + 'px;height:calc(100% - ' + bb + ');background:' + e.background + ';color:' + e.color + '">
';
        $(this).css('width', nw);
        $(this).css('height', '100%');
        $(this).css('position', 'absolute');
        $(this).css('overflow', 'auto');
        $(this).css('resize', 'none');
        $(this).css('top', '0px');
        $(this).css('margin', '0px');
        $(this).css('box-shadow', 'none');
        $(this).css('left', e.width);
        $(this).css('box-sizing', 'border-box');
        $(this).wrap('

');
        $(this).before(b);
        var b = $(this).val().split('\n').length;
        addln(b, c);
        $(this).on('blur focus change keyup keydown', function() {
            var a = $(this).val().split('\n').length;
            addln(a, c)
        });
        $(this).scroll(function() {
            $('#' + c + ' div').scrollTop($(this).scrollTop())
        });
        $('#' + c + ' div').scroll(function() {
            $(this).scrollTop($('#' + c + ' div').scrollTop())
        })
    });

    function addln(a, b) {
        var c = '';
        for (i = 0; i < a; i++) {
            var j = $('#' + b + ' textarea').val().split('\n')[i].substr(i.toString().length).length;
            var s = '';
            for (x = 0; x < j; x++) {
                s += ' '
            }
            c += (i + 1) + s + '
'
        };
        $('#' + b + ' div').html(c);
        $('#' + b + ' div').scrollTop($('#' + b + ' textarea').scrollTop())
    }
}
<commit_msg>textarea, pre, div etc<commit_after>/************************************************
 * #### jQuery bcralnit.js v0.0.1 ####
 * add line number in textarea, pre, div etc.
 * Coded by Ican Bachors 2017.
 * https://github.com/bachors/bcralnit.js
 * Updates will be posted to this site.
 ***********************************************/

$.fn.bcralnit = function(e) {
    var f = {
        width: '60px',
        background: '#ddd',
        color: '#333'
    };
    if (typeof e === 'object') {
        e.width = (e.width == undefined ? f.width : e.width);
        e.background = (e.background == undefined ? f.background : e.background);
        e.color = (e.color == undefined ? f.color : e.color)
    } else {
        e = f
    }
    $(this).each(function(i, a) {
        var f = $(this)[0].tagName,
            w = $(this).css('width'),
            h = $(this).css('height'),
            d = ($(this).css('display') == 'inline' ? 'inline-block' : $(this).css('display')),
            ff = $(this).css('font-family'),
            fs = $(this).css('font-size'),
            fw = $(this).css('font-weight'),
            lh = $(this).css('line-height'),
            bt = $(this).css('border-top-width'),
            bb = $(this).css('border-bottom-width'),
            br = $(this).css('border-right-width'),
            bl = $(this).css('border-left-width'),
            m = $(this).css('margin'),
            pt = $(this).css('padding-top'),
            pb = $(this).css('padding-bottom'),
            pl = $(this).css('padding-left'),
            pr = $(this).css('padding-right'),
            nw = (parseInt(w) - parseInt(e.width)) + 'px',
            c = ($(this).attr('id') != null && $(this).attr('id') != undefined ? 'bcralnit_' + $(this).attr('id') + i : 'bcralnit_' + $(this).attr('class') + i),
            b = '<div class="bcr_number" style="text-shadow:none;position:absolute;box-sizing:border-box;border:none;margin:0px;overflow-x:hidden;overflow-y:auto;white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;padding:' + (parseInt(pt) + parseInt(bt)) + 'px ' + pr + ' ' + pb + ' ' + pl + ';font-family:' + ff + ';font-size:' + fs + ';font-weight:' + fw + ';line-height:' + lh + ';right:' + e.width + ';width:' + (parseInt(nw) - parseInt(br) - parseInt(bl)) + 'px;height:calc(100% - ' + bb + ');background:' + e.background + ';color:' + e.background + '">
';
        $(this).css('width', nw);
        $(this).css('height', '100%');
        $(this).css('position', 'absolute');
        $(this).css('overflow-x', 'hidden');
        $(this).css('overflow-y', 'auto');
        $(this).css('resize', 'none');
        $(this).css('top', '0px');
        $(this).css('margin', '0px');
        $(this).css('box-shadow', 'none');
        $(this).css('left', e.width);
        $(this).css('box-sizing', 'border-box');
        $(this).css('white-space', 'pre-wrap');
        $(this).css('white-space', 'moz-pre-wrap');
        $(this).css('white-space', '-pre-wrap');
        $(this).css('white-space', '-o-pre-wrap');
        $(this).css('word-wrap', 'break-word');
        $(this).addClass("bcr_line");
        $(this).wrap('

');
        $(this).before(b);
        var b = (f == 'TEXTAREA' ? $(this).val().split('\n').length : $(this).html().split('\n').length);
        addln(f, b, c);
        $(this).on('blur focus change keyup keydown', function() {
            var a = (f == 'TEXTAREA' ? $(this).val().split('\n').length : $(this).html().split('\n').length);
            addln(f, a, c)
        });
        $(this).scroll(function() {
            $('#' + c + ' .bcr_number').scrollTop($(this).scrollTop())
        })
    });

    function addln(d, a, b) {
        var c = '';
        for (i = 0; i < a; i++) {
            var n = (i + 1);
            var f = (d == 'TEXTAREA' ? $('#' + b + ' .bcr_line').val().split('\n')[i] : $('#' + b + ' .bcr_line').html().split('\n')[i]);
            var g = f.substring(n.toString().length, f.length);
            c += '' + n + '' + g.replace(/\</ig, '~').replace(/\>/ig, '~') + '
'
        };
        $('#' + b + ' .bcr_number').html(c);
        $('#' + b + ' .bcr_number').scrollTop($('#' + b + ' .bcr_line').scrollTop())
    }
}
<|endoftext|>


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

// I worked on this challenge with: Aaron Ophfal
// This challenge took me 3 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 data structure that links the name of a person to their voter ballot. Each ballot is a data structure in itself, linking an office to the name of the candidates the voter is voting for

// Loop through each voter name on the inputted structure
//   loop through each individual voter's vote (for each position) on the ballot
//      identify the office/position in that particular vote, and the candidate
//      assign that vote to another data structure that stores the names, vote counts, and office
//     IF the candidate's name is not in the structure for that position
//         add the name as a new item, and insert 1 as the count
//    ELSE IF the candidate's name is already in the structure
//          add one to the count of votes the candidate received for that office
// return a data structure that is a list of offices, and each office points to a list of candidate names and the number of votes each candidate received
// Take that data structure and loop through each S.G. office at a time
//    FOR each S.G. office, find the name of the candidate that is linked to the largest number of votes
//    Write that candidate's name to another data structure that stores the winners of the office
// return data structure of winners as the output

// output - A data structure that links an office in Student Government to the name of the person who received the most votes for that office

// __________________________________________
// Initial Solution

// //EXTRACT NAME
// //Loops through each item in votes to search for voter
// for (var voter in votes) {
//   // Tests if statement is true. Returns boolean.
//   // statement is whether the votes object has a property called voter
//    if (votes.hasOwnProperty(voter)) {
//     // sets variable called ballot that is the "value" to the key that is the
//       var ballot = votes[voter];
//       console.log(ballot + "Is the ballot")
//       console.log(voter+ "Is the voter")
//       for (var office in ballot) {
//         console.log(office + "is the office")
//          if (ballot.hasOwnProperty(office)) {
//             //console.log("It has the property")
//             var name = ballot[office];
//             console.log(name + "Is the name")
//             //voteCount.office] = name; //left off here
//          }
//       }
//    }
// };

// for (var voter in votes) {
//    if (votes.hasOwnProperty(voter)) {
//       var ballot = votes[voter];
//       console.log(ballot + "Is the ballot");
//       console.log(voter+ "Is the voter");
//       for (var office in ballot) {
//         console.log(office + "is the office");
//          if (ballot.hasOwnProperty(office)) {
//             var name = ballot[office];
//             console.log(name + "Is the name");
//             break;

//          }
//       }
//    }
// };

// __________________________________________
// Initial Solution

// voteCount.tallyVotes = function(votes) {
//   for (var voter in votes) {
//     if (votes.hasOwnProperty(voter)) {
//       var ballot = votes[voter];
//         for (var vote in ballot) {
//           if (ballot.hasOwnProperty(vote)) {
//             var candidate = ballot[vote];
//             var numberOfVotes = [];
//             if (voteCount[vote][candidate]) {
//               voteCount[vote][candidate] += 1;
//             } else {
//               voteCount[vote][candidate] = 1;
//             }
//             // numberOfVotes.push(voteCount[vote][candidate]);;
//           }
//         }
//      }
//   }
// }

// voteCount.tallyVotes = function(votes) {
  for (var voter in votes) {
    if (votes.hasOwnProperty(voter)) {
      var ballot = votes[voter];
        for (var vote in ballot) {
          if (ballot.hasOwnProperty(vote)) {
            var candidate = ballot[vote];
            var numberOfVotes = [];
            if (voteCount[vote][candidate]) {
              voteCount[vote][candidate] += 1;
            } else {
              voteCount[vote][candidate] = 1;
            }
            // numberOfVotes.push(voteCount[vote][candidate]);;
          }
        }
     }
}

console.log(voteCount);

for (var offices in voteCount) {
if (voteCount.hasOwnProperty(offices)) {
  // console.log(offices + "Is the office");
  var numberOfVotes = 0;
  var candidate = voteCount[offices];
    for (var name in candidate) {
      if (candidate.hasOwnProperty(name)) {
        // console.log(name + "is the name")
        var votes = candidate[name];
        // console.log(votes + "is the number of votes");
        if (numberOfVotes < votes) {
          numberOfVotes = votes;
          officers[offices] = name;
        }
      }
    }
        // numberOfVotes.push(voteCount[vote][candidate]);;
  }
}

console.log(officers)

// __________________________________________
// Refactored Solution

voteCount.tallyVotes = function(office) {
}

for (var voter in votes) {
  var ballot = votes[voter];
  for (var vote in ballot) {
    var candidate = ballot[vote];
    if (voteCount[vote][candidate]) {
      voteCount[vote][candidate] += 1;
    } else {
      voteCount[vote][candidate] = 1;
    }
  }
}

for (var offices in voteCount) {
  var numberOfVotes = 0;
  var candidate = voteCount[offices];
    for (var name in candidate) {
      var votes = candidate[name];
      if (numberOfVotes < votes) {
          numberOfVotes = votes;
          officers[offices] = name;
      }
    }
  }
}

// __________________________________________
// Reflection

// My partner and I really struggled with this challenge and I think it shows. I am very sure that we could have used object methods stored in properties for one or either object. But I wasn't sure how to do it, and I was too late to talk to the guides. Although it also wasn't covered well this week, so perhaps I'm thinking too far ahead.
// I learned that if there is a difference between diving into the function with for loops or alternating with an if loop of hasOwnProperty, it is a way that doesn't affect functionality in the limited way we interacted with our functions. hasOwnProperty is the best method I've learned this challenge. My loose understanding is that using that method will be a poor move if the code is kept for a long time and maintained and built upon. Because JavaScript has prototypical inheritance, a child object could inherit that functionality when it's function is different from the one that it's parent object had. I will try to use it going forward.
// The concept of debugging through printing variables as they traveled through the functions. That saved us more time than anything, because it proved that the loop was moving, where it was breaking, and which variables were which. I got my partner on board at the end.
//

// __________________________________________
// 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>Making hard code into functions<commit_after>// Tally Votes in JavaScript Pairing Challenge.

// I worked on this challenge with: Aaron Ophfal
// This challenge took me 3 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 data structure that links the name of a person to their voter ballot. Each ballot is a data structure in itself, linking an office to the name of the candidates the voter is voting for

// Loop through each voter name on the inputted structure
//   loop through each individual voter's vote (for each position) on the ballot
//      identify the office/position in that particular vote, and the candidate
//      assign that vote to another data structure that stores the names, vote counts, and office
//     IF the candidate's name is not in the structure for that position
//         add the name as a new item, and insert 1 as the count
//    ELSE IF the candidate's name is already in the structure
//          add one to the count of votes the candidate received for that office
// return a data structure that is a list of offices, and each office points to a list of candidate names and the number of votes each candidate received
// Take that data structure and loop through each S.G. office at a time
//    FOR each S.G. office, find the name of the candidate that is linked to the largest number of votes
//    Write that candidate's name to another data structure that stores the winners of the office
// return data structure of winners as the output

// output - A data structure that links an office in Student Government to the name of the person who received the most votes for that office

// __________________________________________
// Initial Solution

// //EXTRACT NAME
// //Loops through each item in votes to search for voter
// for (var voter in votes) {
//   // Tests if statement is true. Returns boolean.
//   // statement is whether the votes object has a property called voter
//    if (votes.hasOwnProperty(voter)) {
//     // sets variable called ballot that is the "value" to the key that is the
//       var ballot = votes[voter];
//       console.log(ballot + "Is the ballot")
//       console.log(voter+ "Is the voter")
//       for (var office in ballot) {
//         console.log(office + "is the office")
//          if (ballot.hasOwnProperty(office)) {
//             //console.log("It has the property")
//             var name = ballot[office];
//             console.log(name + "Is the name")
//             //voteCount.office] = name; //left off here
//          }
//       }
//    }
// };

// for (var voter in votes) {
//    if (votes.hasOwnProperty(voter)) {
//       var ballot = votes[voter];
//       console.log(ballot + "Is the ballot");
//       console.log(voter+ "Is the voter");
//       for (var office in ballot) {
//         console.log(office + "is the office");
//          if (ballot.hasOwnProperty(office)) {
//             var name = ballot[office];
//             console.log(name + "Is the name");
//             break;

//          }
//       }
//    }
// };

// __________________________________________
// Initial Solution

// voteCount.tallyVotes = function(votes) {
//   for (var voter in votes) {
//     if (votes.hasOwnProperty(voter)) {
//       var ballot = votes[voter];
//         for (var vote in ballot) {
//           if (ballot.hasOwnProperty(vote)) {
//             var candidate = ballot[vote];
//             var numberOfVotes = [];
//             if (voteCount[vote][candidate]) {
//               voteCount[vote][candidate] += 1;
//             } else {
//               voteCount[vote][candidate] = 1;
//             }
//             // numberOfVotes.push(voteCount[vote][candidate]);;
//           }
//         }
//      }
//   }
// }

// voteCount.tallyVotes = function(votes) {
//   for (var voter in votes) {
//     if (votes.hasOwnProperty(voter)) {
//       var ballot = votes[voter];
//         for (var vote in ballot) {
//           if (ballot.hasOwnProperty(vote)) {
//             var candidate = ballot[vote];
//             var numberOfVotes = [];
//             if (voteCount[vote][candidate]) {
//               voteCount[vote][candidate] += 1;
//             } else {
//               voteCount[vote][candidate] = 1;
//             }
//             // numberOfVotes.push(voteCount[vote][candidate]);;
//           }
//         }
//      }
// }

// console.log(voteCount);

// for (var offices in voteCount) {
// if (voteCount.hasOwnProperty(offices)) {
//   // console.log(offices + "Is the office");
//   var numberOfVotes = 0;
//   var candidate = voteCount[offices];
//     for (var name in candidate) {
//       if (candidate.hasOwnProperty(name)) {
//         // console.log(name + "is the name")
//         var votes = candidate[name];
//         // console.log(votes + "is the number of votes");
//         if (numberOfVotes < votes) {
//           numberOfVotes = votes;
//           officers[offices] = name;
//         }
//       }
//     }
//         // numberOfVotes.push(voteCount[vote][candidate]);;
//   }
// }

// console.log(officers)

// __________________________________________
// Refactored Solution

 function tallyVotes(votes, voteCount) {
  for (var voter in votes) {
    var ballot = votes[voter];
    for (var vote in ballot) {
      var candidate = ballot[vote];
      if (voteCount[vote][candidate]) {
        voteCount[vote][candidate] += 1;
      } else {
        voteCount[vote][candidate] = 1;
      }
    }
  }
}

// for (var voter in votes) {
//   var ballot = votes[voter];
//   for (var vote in ballot) {
//     var candidate = ballot[vote];
//     if (voteCount[vote][candidate]) {
//       voteCount[vote][candidate] += 1;
//     } else {
//       voteCount[vote][candidate] = 1;
//     }
//   }
// }

// for (var offices in voteCount) {
//   var numberOfVotes = 0;
//   var candidate = voteCount[offices];
//     for (var name in candidate) {
//       var votes = candidate[name];
//       if (numberOfVotes < votes) {
//           numberOfVotes = votes;
//           officers[offices] = name;
//       }
//     }
//   }
// }

// __________________________________________
// Reflection

// My partner and I really struggled with this challenge and I think it shows. I am very sure that we could have used object methods stored in properties for one or either object. But I wasn't sure how to do it, and I was too late to talk to the guides. Although it also wasn't covered well this week, so perhaps I'm thinking too far ahead.
// I learned that if there is a difference between diving into the function with for loops or alternating with an if loop of hasOwnProperty, it is a way that doesn't affect functionality in the limited way we interacted with our functions. hasOwnProperty is the best method I've learned this challenge. My loose understanding is that using that method will be a poor move if the code is kept for a long time and maintained and built upon. Because JavaScript has prototypical inheritance, a child object could inherit that functionality when it's function is different from the one that it's parent object had. I will try to use it going forward.
// The concept of debugging through printing variables as they traveled through the functions. That saved us more time than anything, because it proved that the loop was moving, where it was breaking, and which variables were which. I got my partner on board at the end.
//

// __________________________________________
// 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>"use strict";function isValidDottedPath(e){return e!=null&&e!==""&&e!=="hasOwnProperty"&&MEMBER_NAME_REGEX.test("."+e)}function lookupDottedPath(e,t){if(!isValidDottedPath(t))throw $resourceMinErr("badmember",'Dotted member path "@{0}" is invalid.',t);var n=t.split(".");for(var r=0,i=n.length;r<i&&e!==undefined;r++){var s=n[r];e=e!==null?e[s]:undefined}return e}function shallowClearAndCopy(e,t){t=t||{},angular.forEach(t,function(e,n){delete t[n]});for(var n in e)e.hasOwnProperty(n)&&(n.charAt(0)!=="$"||n.charAt(1)!=="$")&&(t[n]=e[n]);return t}var $resourceMinErr=angular.$$minErr("$resource"),MEMBER_NAME_REGEX=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;angular.module("ngResource",["ng"]).provider("$resource",function(){var e=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}},this.$get=["$http","$q",function(t,n){function a(e){return f(e,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function f(e,t){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,t?"%20":"+")}function l(t,n){this.template=t,this.defaults=s({},e.defaults,n),this.urlParams={}}function c(a,f,h,p){function v(e,t){var n={};return t=s({},f,t),i(t,function(t,r){u(t)&&(t=t()),n[r]=t&&t.charAt&&t.charAt(0)=="@"?lookupDottedPath(e,t.substr(1)):t}),n}function m(e){return e.resource}function g(e){shallowClearAndCopy(e||{},this)}var d=new l(a,p);return h=s({},e.defaults.actions,h),g.prototype.toJSON=function(){var e=s({},this);return delete e.$promise,delete e.$resolved,e},i(h,function(e,a){var f=/^(POST|PUT|PATCH)$/i.test(e.method);g[a]=function(l,c,h,p){var y={},b,w,E;switch(arguments.length){case 4:E=p,w=h;case 3:case 2:if(!u(c)){y=l,b=c,w=h;break}if(u(l)){w=l,E=c;break}w=c,E=h;case 1:u(l)?w=l:f?b=l:y=l;break;case 0:break;default:throw $resourceMinErr("badargs","Expected up to 4 arguments [params, data, success, error], got {0} arguments",arguments.length)}var S=this instanceof g,x=S?b:e.isArray?[]:new g(b),T={},N=e.interceptor&&e.interceptor.response||m,C=e.interceptor&&e.interceptor.responseError||undefined;i(e,function(e,t){["params","isArray","interceptor","ifMatch"].indexOf(t)==-1&&(T[t]=o(e))}),e.ifMatch&&(T.headers||(T.headers={}),T.headers["If-Match"]=b[e.ifMatch]),f&&(T.data=b),d.setUrlParams(T,s({},v(b,e.params||{}),y),e.url);var k=t(T).then(function(t){var n=t.data,r=x.$promise;if(n){if(angular.isArray(n)!==!!e.isArray)throw $resourceMinErr("badcfg","Error in resource configuration for action `{0}`. Expected response to contain an {1} but got an {2} (Request: {3} {4})",a,e.isArray?"array":"object",angular.isArray(n)?"array":"object",T.method,T.url);e.isArray?(x.length=0,i(n,function(e){typeof e=="object"?x.push(new g(e)):x.push(e)})):(shallowClearAndCopy(n,x),x.$promise=r)}return x.$resolved=!0,t.resource=x,t},function(e){return x.$resolved=!0,(E||r)(e),n.reject(e)});return k=k.then(function(e){var t=N(e);return(w||r)(t,e.headers),t},C),S?k:(x.$promise=k,x.$resolved=!1,x)},g.prototype["$"+a]=function(e,t,n){u(e)&&(n=t,t=e,e={});var r=g[a].call(this,e,this,t,n);return r.$promise||r}}),g.bind=function(e){return c(a,s({},f,e),h)},g}var r=angular.noop,i=angular.forEach,s=angular.extend,o=angular.copy,u=angular.isFunction;return l.prototype={setUrlParams:function(e,t,n){var r=this,s=n||r.template,o,u,f=r.urlParams={};i(s.split(/\W/),function(e){if(e==="hasOwnProperty")throw $resourceMinErr("badname","hasOwnProperty is not a valid parameter name.");!(new RegExp("^\\d+$")).test(e)&&e&&(new RegExp("(^|[^\\\\]):"+e+"(\\W|$)")).test(s)&&(f[e]=!0)}),s=s.replace(/\\:/g,":"),t=t||{},i(r.urlParams,function(e,n){o=t.hasOwnProperty(n)?t[n]:r.defaults[n],angular.isDefined(o)&&o!==null?(u=a(o),s=s.replace(new RegExp(":"+n+"(\\W|$)","g"),function(e,t){return u+t})):s=s.replace(new RegExp("(/?):"+n+"(\\W|$)","g"),function(e,t,n){return n.charAt(0)=="/"?n:t+n})}),r.defaults.stripTrailingSlashes&&(s=s.replace(/\/+$/,"")||"/"),s=s.replace(/\/\.(?=\w+($|\?))/,"."),e.url=s.replace(/\/\\\./,"/."),i(t,function(t,n){r.urlParams[n]||(e.params=e.params||{},e.params[n]=t)})}},c}]});
<commit_msg>Minify JS<commit_after>"use strict";function isValidDottedPath(e){return e!=null&&e!==""&&e!=="hasOwnProperty"&&MEMBER_NAME_REGEX.test("."+e)}function lookupDottedPath(e,t){if(!isValidDottedPath(t))throw $resourceMinErr("badmember",'Dotted member path "@{0}" is invalid.',t);var n=t.split(".");for(var r=0,i=n.length;r<i&&e!==undefined;r++){var s=n[r];e=e!==null?e[s]:undefined}return e}function shallowClearAndCopy(e,t){t=t||{},angular.forEach(t,function(e,n){delete t[n]});for(var n in e)e.hasOwnProperty(n)&&(n.charAt(0)!=="$"||n.charAt(1)!=="$")&&(t[n]=e[n]);return t}var $resourceMinErr=angular.$$minErr("$resource"),MEMBER_NAME_REGEX=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;angular.module("ngResource",["ng"]).provider("$resource",function(){var e=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}},this.$get=["$http","$q",function(t,n){function a(e){return f(e,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function f(e,t){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,t?"%20":"+")}function l(t,n){this.template=t,this.defaults=s({},e.defaults,n),this.urlParams={}}function c(a,f,h,p){function v(e,t){var n={};return t=s({},f,t),i(t,function(t,r){u(t)&&(t=t()),n[r]=t&&t.charAt&&t.charAt(0)=="@"?lookupDottedPath(e,t.substr(1)):t}),n}function m(e){return e.resource}function g(e){shallowClearAndCopy(e||{},this)}var d=new l(a,p);return h=s({},e.defaults.actions,h),g.prototype.toJSON=function(){var e=s({},this);return delete e.$promise,delete e.$resolved,e},i(h,function(e,a){var f=/^(POST|PUT|PATCH)$/i.test(e.method);g[a]=function(l,c,h,p){var y={},b,w,E;switch(arguments.length){case 4:E=p,w=h;case 3:case 2:if(!u(c)){y=l,b=c,w=h;break}if(u(l)){w=l,E=c;break}w=c,E=h;case 1:u(l)?w=l:f?b=l:y=l;break;case 0:break;default:throw $resourceMinErr("badargs","Expected up to 4 arguments [params, data, success, error], got {0} arguments",arguments.length)}var S=this instanceof g,x=S?b:e.isArray?[]:new g(b),T={},N=e.interceptor&&e.interceptor.response||m,C=e.interceptor&&e.interceptor.responseError||undefined;i(e,function(e,t){["params","isArray","interceptor","ifMatch"].indexOf(t)==-1&&(T[t]=o(e))}),e.ifMatch&&(T.headers||(T.headers={}),b&&(T.headers["If-Match"]=b[e.ifMatch])),f&&(T.data=b),d.setUrlParams(T,s({},v(b,e.params||{}),y),e.url);var k=t(T).then(function(t){var n=t.data,r=x.$promise;if(n){if(angular.isArray(n)!==!!e.isArray)throw $resourceMinErr("badcfg","Error in resource configuration for action `{0}`. Expected response to contain an {1} but got an {2} (Request: {3} {4})",a,e.isArray?"array":"object",angular.isArray(n)?"array":"object",T.method,T.url);e.isArray?(x.length=0,i(n,function(e){typeof e=="object"?x.push(new g(e)):x.push(e)})):(shallowClearAndCopy(n,x),x.$promise=r)}return x.$resolved=!0,t.resource=x,t},function(e){return x.$resolved=!0,(E||r)(e),n.reject(e)});return k=k.then(function(e){var t=N(e);return(w||r)(t,e.headers),t},C),S?k:(x.$promise=k,x.$resolved=!1,x)},g.prototype["$"+a]=function(e,t,n){u(e)&&(n=t,t=e,e={});var r=g[a].call(this,e,this,t,n);return r.$promise||r}}),g.bind=function(e){return c(a,s({},f,e),h)},g}var r=angular.noop,i=angular.forEach,s=angular.extend,o=angular.copy,u=angular.isFunction;return l.prototype={setUrlParams:function(e,t,n){var r=this,s=n||r.template,o,u,f=r.urlParams={};i(s.split(/\W/),function(e){if(e==="hasOwnProperty")throw $resourceMinErr("badname","hasOwnProperty is not a valid parameter name.");!(new RegExp("^\\d+$")).test(e)&&e&&(new RegExp("(^|[^\\\\]):"+e+"(\\W|$)")).test(s)&&(f[e]=!0)}),s=s.replace(/\\:/g,":"),t=t||{},i(r.urlParams,function(e,n){o=t.hasOwnProperty(n)?t[n]:r.defaults[n],angular.isDefined(o)&&o!==null?(u=a(o),s=s.replace(new RegExp(":"+n+"(\\W|$)","g"),function(e,t){return u+t})):s=s.replace(new RegExp("(/?):"+n+"(\\W|$)","g"),function(e,t,n){return n.charAt(0)=="/"?n:t+n})}),r.defaults.stripTrailingSlashes&&(s=s.replace(/\/+$/,"")||"/"),s=s.replace(/\/\.(?=\w+($|\?))/,"."),e.url=s.replace(/\/\\\./,"/."),i(t,function(t,n){r.urlParams[n]||(e.params=e.params||{},e.params[n]=t)})}},c}]});
<|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
}

// Pseudocode

// __________________________________________
// Initial Solution

// __________________________________________
// 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>Add tally votes file<commit_after>// Tally Votes in JavaScript Pairing Challenge.

// I worked on this challenge with: Mark Janzer
// This challenge took me [1] 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
//
// Block to input votes
// Input: no arguments taken, needs votes object
// Output: VoteCount with each officer number of votes correlated to them in the correct office.

// Create a for loop to iterate through votes object
//   Create a for loop to iterate through the individual vote.
//     IF voteCount[current office][current candidate] exists
//       then voteCount[current office][current candidate] += 1
//     ELSE
//       voteCount[current office][current candidate] = 1
//     END
//   END
// END

// Block to count votes for each office and return the max (aka the winner);
// Input: needs voteCount
// Output: Winner

// Create a for loop to iterate through voteCount object
//   Create a for loop to iterate through each office object
//     Find max for voteCount[office][candidate], set candidate as property to officers[office]
//   END
// END

// __________________________________________
// Initial Solution

// for (var voter in votes) {
//   for (var office in votes[voter]) {
//     if (votes[voter][office] in voteCount[office]) {
//       voteCount[office][votes[voter][office]] += 1;
//     } else {
//       voteCount[office][votes[voter][office]] = 1;
//     }
//   }
// }

// for (var position in voteCount) {
//   var max = 0;
//   var topRunner = "";
//   for (var candidate in voteCount[position]) {
//     if (voteCount[position][candidate] > max) {
//       max = voteCount[position][candidate];
//       topRunner = candidate;
//     }
//   }
//   officers[position] = topRunner;
// }

// __________________________________________
// Refactored Solution

for (var voter in votes) {
  for (var office in votes[voter]) {
    var candidateChoice = votes[voter][office];
    if (candidateChoice in voteCount[office]) {
      voteCount[office][candidateChoice] += 1;
    } else {
      voteCount[office][candidateChoice] = 1;
    }
  }
}

for (var position in voteCount) {
  var max = 0;
  var topRunner = "";
  for (var candidate in voteCount[position]) {
    var numberOfVotes = voteCount[position][candidate];
    if (numberOfVotes > max) {
      max = numberOfVotes;
      topRunner = candidate;
    }
  }
  officers[position] = topRunner;
}

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

  We learned that you have to use a for..in loop to iterate over an object.
  Regular for loops won't work since the object doesn't have a numbered
  index. You also have to nest one inside the other.

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

  We didn't really find much this time. Well, we did use the if..in
  statement which checks if A exists in B for `if (A in B)`. This is
  a bit like the includes? method in Ruby. It helped us check whether
  we needed to add a person's name to an office or just incredment
  the value of their name.

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

  This helped me understand nested objects a lot better. It was a
  challenging problem, and we really had to be specific with our variable
  names so we didn't get confused about what was what.

// __________________________________________
// 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|>