diff --git a/ajax_with_jquery_exercise/app.css b/ajax_with_jquery_exercise/app.css
new file mode 100644
index 00000000..e476c43a
--- /dev/null
+++ b/ajax_with_jquery_exercise/app.css
@@ -0,0 +1,92 @@
+.row {
+ background-color: #f6f6ef;
+ }
+
+ .borderless td, .borderless th {
+ border: none;
+ }
+ .navbar {
+ background-color: #ff6600;
+ margin-bottom: 0;
+ }
+ .navbar-text p {
+ display: inline;
+ }
+
+ /*#loggedUser {
+ display:inline-block; !important
+ vertical-align: middle; !important
+ }*/
+
+ #loggedUser span {
+ display: block;
+ }
+
+
+.formdeco {
+ background-color: #f6f6ef;
+ padding-top: 10px;
+}
+.noShow {
+ /*padding-bottom: 0px;*/
+ display: none;
+ }
+
+ .loginOnly {
+ display: none;
+ }
+
+ li {
+ padding: 5px;
+ }
+ ol {
+ padding-top: 0px;
+ background-color: #f6f6ef;
+ /*text-decoration: none !important;
+ color: black !important;*/
+
+ }
+ section + ol {
+ margin-top: -20px;
+}
+ol {
+ padding-top: 20px;
+}
+
+.navbar-text span:hover {
+ cursor: pointer;
+ text-decoration: underline;
+}
+
+.navbar-right li {
+ padding-left: 0px;
+ /*margin-right: 10px;*/
+}
+
+.navbar ul {
+ margin-right: 0px;
+}
+
+ol a:link {
+ text-decoration: none !important;
+ /*color: inherit;*/
+}
+
+ol a {
+ color: black !important;
+}
+
+span.cuthead {
+ font: 8pt Verdana, Geneva, sans-serif !important;
+ /*font: italic small-caps normal 13px/150% Arial, Helvetica, sans-serif;
+ font-size: 8pt !important;
+ font-family: Verdana, Geneva, sans-serif !important;*/
+ /*color: #828282;*/
+
+}
+
+span.cuthead:hover {
+ cursor: pointer;
+ display: inline-block;
+ text-decoration: underline;
+}
\ No newline at end of file
diff --git a/ajax_with_jquery_exercise/app.js b/ajax_with_jquery_exercise/app.js
new file mode 100644
index 00000000..12cd92d7
--- /dev/null
+++ b/ajax_with_jquery_exercise/app.js
@@ -0,0 +1,168 @@
+$(document).ready(function() {
+
+ // do this
+ fetchTopTwentyStories();
+
+ var signUp;
+
+
+$('#login').on('click', function(event) {
+ if ($( this ).text() === "logout") {
+ var email = $( ".navbar-right li" ).eq(1).text();
+ // remove text on right
+ $( ".navbar-right li" ).each(function() {
+ $( this ).remove();
+ });
+
+ // toggle favorite
+ $('.navbar-text text').eq(1).toggleClass('loginOnly');
+ $('#fav').toggleClass('loginOnly');
+ //$('.loginOnly').toggleClass('loginOnly');
+
+ // remove auth token from local storage
+ localStorage.removeItem(email);
+
+ // change text back to login
+ $( this ).text("login").wrapInner("");
+
+ // empty stories list display
+ $("ol").empty();
+ }
+ else {
+ $('section').toggleClass('noShow');
+ signUp = false;
+ }
+});
+
+$('#signup').on('click', function(event) {
+ $('section').toggleClass('noShow');
+ signUp = true;
+});
+
+$('.form-horizontal').on('submit', function(event) {
+ if(signUp) {
+ loginOrSignUp("signup");
+ }
+ else {
+ loginOrSignUp("login");
+ }
+
+ $('section').toggleClass('noShow');
+ event.preventDefault();
+});
+
+$('#fav').on("click", function(e) {
+ if ($( this ).text() === "all") {
+ $( "li span" ).each(function( index ) {
+ if($( this ).hasClass('glyphicon-star-empty') ) {
+ $( this ).parent().show();
+ }
+ });
+ $( this ).text("favorites").wrapInner("");
+ }
+ else if ( $( this ).text() === "favorites" ) {
+ $( "li span" ).each(function( index ) {
+ if($( this ).hasClass('glyphicon-star-empty') ) {
+ $( this ).parent().hide();
+ }
+ });
+ $( this ).text("all").wrapInner("");
+
+ }
+
+ });
+
+ $("ol").on("click", ".glyphicon", function(e) {
+ if( $(e.target).hasClass('glyphicon-star-empty') ) {
+
+ $(e.target).toggleClass('glyphicon-star-empty glyphicon-star');
+ }
+ else {
+ $(e.target).toggleClass('glyphicon-star glyphicon-star-empty');
+ }
+ });
+});
+
+function fetchTopTwentyStories() {
+ $.get("https://hacker-news.firebaseio.com/v0/topstories.json")
+ .then(function(stories) {
+ return stories.slice(0, 20);
+ })
+ .then(function(tStories) {
+ tStories.forEach(function(element) {
+ $.get('https://hacker-news.firebaseio.com/v0/item/' + element + '.json')
+ .then(function(storyDetail) {
+ if ('url' in storyDetail) {
+ var cutUrl = "";
+ var iUrl = storyDetail.url;
+ if (iUrl.includes("www.")) {
+ cutUrl = iUrl.split('www.')[1].split('/')[0].split('.').slice(-2).join('.');
+ }
+ else {
+ cutUrl = storyDetail.url.split('//')[1].split('/')[0];
+ if (cutUrl.match(/(.*\.)+(.*\.)+.*/g)) {
+ cutUrl = cutUrl.split('.').slice(-2).join('.');
+ }
+ }
+ var element = '
' + storyDetail.title + ' (' +
+ '' + cutUrl +
+ ')';
+ $('ol').append(element);
+ }
+ })
+ .fail(function(error) {
+ console.warn("Isuue encountered in item fetch api");
+ });
+ });
+ })
+ .fail(function(error) {
+ console.warn("Isuue encountered in top stories fetch api");
+ });
+}
+
+function loginOrSignUp(str) {
+ var email = $('#email').val();
+ var password = $('#password').val();
+ $.ajax({
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json"
+ },
+
+ url: 'https://hn-favorites.herokuapp.com/' + str + '',
+ data: JSON.stringify({
+ email: email,
+ password: password
+ })
+ })
+ .then(function(data) {
+ if ( data.auth_token.length > 0 && data.auth_token.includes('.') ) {
+ alert(str + " successful.");
+ // save the auth token in local storage
+ localStorage.setItem(email, data.auth_token);
+ $('.form-horizontal').each(function() {
+ this.reset();
+ });
+
+ // toggle login to logout and add text logged in as on right nav
+ // and show the favorites tab/icon
+ if(str === "login") {
+ $('.navbar-text text').eq(1).toggleClass('loginOnly');
+ $('#fav').toggleClass('loginOnly');
+ //$('.loginOnly').toggleClass('loginOnly');
+ var element = 'Logged in as:' +
+ '' + email + '';
+ $('.navbar-right').append(element);
+ $('#login').text("logout").wrapInner("");
+ }
+ }
+ })
+ .fail(function(err) {
+ if( 'status' in err && 'statusText' in err )
+ // if( err.status !== undefined && err.statusText !== undefined )
+ alert(str + " not successful. " + err.status + ": " + err.statusText);
+ else
+ alert(str + " not successful.");
+ });
+}
\ No newline at end of file
diff --git a/call_apply_bind_exercise/callApplyBind.js b/call_apply_bind_exercise/callApplyBind.js
index e69de29b..669461db 100644
--- a/call_apply_bind_exercise/callApplyBind.js
+++ b/call_apply_bind_exercise/callApplyBind.js
@@ -0,0 +1,68 @@
+var obj = {
+ fullName: "Harry Potter",
+ person: {
+ sayHi: function(){
+ return "This person's name is " + this.fullName
+ }.bind(obj)
+ }
+}
+
+
+function sumEvenArguments() {
+ var args = [].slice.call(arguments);
+
+ return args.reduce(function(acc, nextValue) {
+ if( nextValue % 2 === 0 ) acc += nextValue;
+ return acc;
+ }, 0);
+
+ // return args.filter(function(a) { return (a % 2) === 0; }).reduce(function(acc, nextValue) {
+ // return acc + nextValue
+ // }, 0);
+}
+
+function arrayFrom() {
+ return [].slice.call(arguments);
+}
+
+function invokeMax(fn, num) {
+ var count = num;
+ return function innerFunction(){
+ if (count <= 0) {
+ return "Maxed Out!";
+ }
+ else {
+ count--;
+ return fn.apply(this, arguments);
+
+ }
+ }
+}
+
+function guessingGame(amount) {
+ var answer = Math.floor(Math.random() * 11);
+ var guesses = 0;
+ return function innerFunction(guess) {
+ if(guesses <= amount) {
+ if(guesses === amount && guess !== answer) {
+ guesses++;
+ return "No more guesses the answer was " + answer;
+ }
+ if(guess === answer) {
+ guesses = amount + 1;
+ return "You got it!";
+ }
+ if (guess < answer) {
+ guesses++;
+ return "You're too low!";
+ }
+ if (guess > answer) {
+ guesses++;
+ return "You're too high!";
+ }
+ }
+ else {
+ return "You are all done playing!";
+ }
+ }
+}
\ No newline at end of file
diff --git a/canvas_exercise/shapes_game/index.js b/canvas_exercise/shapes_game/index.js
index 0de5f18a..cbb71b0a 100644
--- a/canvas_exercise/shapes_game/index.js
+++ b/canvas_exercise/shapes_game/index.js
@@ -1,36 +1,135 @@
window.addEventListener("load", function() {
function clear(ctx, width, heigt) {
+ ctx.clearRect(0, 0, width, height);
}
- function drawRandomShape(ctx, width, height) {
+ function drawTraingle(ctx, width, height, color) {
+ ctx.fillStyle = color;
+ ctx.beginPath();
+ ctx.moveTo(width,height);
+ ctx.lineTo(width+100, height+100);
+ ctx.lineTo(width, height+100);
+ ctx.fill();
+ ctx.closePath();
}
- function drawGameStartText(ctx, width, height, score) {
+ function drawRandomShape(shapes) {
+ var shape = shapes[Math.floor(Math.random()*shapes.length)];
+ var randWidth = Math.floor(Math.random() * (700 - 100)) + 100;
+ var randHeight = Math.floor(Math.random() * (650 - 100)) + 100;
+ var eKey;
+ switch(shape) {
+ case "redT":
+ clear(ctx, (canvas.width), (canvas.height));
+ drawTraingle(ctx, randWidth, randHeight, "red");
+ eKey = "redT";
+ break;
+ case "redS":
+ clear(ctx, (canvas.width), (canvas.height));
+ drawSquare(ctx, randWidth, randHeight, 100, 100, "red");
+ eKey = "redS";
+ break;
+ case "whiteT":
+ clear(ctx, (canvas.width), (canvas.height));
+ drawTraingle(ctx, randWidth, randHeight, "white");
+ eKey = "whiteT";
+ break;
+ case "whiteS":
+ clear(ctx, (canvas.width), (canvas.height));
+ drawSquare(ctx, randWidth, randHeight, 100, 100, "white");
+ eKey = "whiteS";
+ break;
+ default:
+ clear(ctx, (canvas.width), (canvas.height));
+ drawTraingle(ctx, randWidth, randHeight, "red");
+ eKey = "redT";
+ }
+ return eKey;
}
- function restartGame(ctx, width, height) {
+ function drawSquare(ctx, startx, starty, width, height, color) {
+ var square = {
+ corner: [startx,starty],
+ width: width,
+ height: height,
+ color: color,
+ draw: function() {
+ ctx.fillStyle = this.color;
+ ctx.fillRect(this.corner[0], this.corner[1], this.width, this.height);
+ }
+ }
+ square.draw();
+ }
+
+ function drawGameStartText(ctx, width, height, score) {
+ ctx.fillStyle = "#FFFFFF";
+ ctx.font = '30px san-serif';
+ ctx.textBaseline = 'middle';
+ ctx.textAlign = 'center';
+ ctx.fillText('Press the space bar to start a new game.' , width, height);
+ ctx.fillText("Score: " + score, width, height + 30);
}
- var canvas = document.getElementById("shapes-game"),
- height = canvas.scrollHeight,
- width = canvas.scrollWidth,
- gameOn = false,
- expectedKey = undefined,
- ctx = canvas.getContext('2d'),
- // white triangle = up, red square = down,
- // red triangle = left, white square = right
- expectedKeysMap = {white0: 38, red1: 40, red0: 37, white1: 39},
- timerSpan = document.getElementById("time-remaining"),
- scoreSpan = document.getElementById("score-val"),
- seconds = 3,
- intervalId;
+ //. ########################## //
+ // Loading prep work
+ //. ########################## //
+ var canvas = document.getElementById("shapes-game"),
+ height = canvas.scrollHeight,
+ width = canvas.scrollWidth,
+ gameOn = false,
+ expectedKey = undefined,
+ shapes = ["whiteS", "whiteT", "redS", "redT"],
+ ctx = canvas.getContext('2d'),
+ // white triangle = up, red square = down,
+ // red triangle = left, white square = right
+ expectedKeysMap = {whiteT: 38, redS: 40, redT: 37, whiteS: 39},
+ timerSpan = document.getElementById("time-remaining"),
+ scoreSpan = document.getElementById("score-val"),
+ seconds = 3,
+ cScore = 0,
+ intervalId;
canvas.width = width;
canvas.height = height;
+ drawGameStartText(ctx, (canvas.width/2), (canvas.height/2), 0);
- document.addEventListener("keyup", function() {
-
- });
-});
+ //. ########################## //
+ // Key up activities
+ //. ########################## //
+ document.addEventListener("keyup", function(e) {
+ if (e.keyCode === 32) {
+ gameOn = true;
+ expectedKey = drawRandomShape(shapes);
+ // start timer
+ var time = parseInt(timerSpan.innerText);
+ intervalId = setInterval(function() {
+ timerSpan.innerText = --time;
+ if (time === 0) {
+ clearInterval(intervalId);
+ // reset gameOn, score and time to default values
+ gameOn = false;
+ scoreSpan.innerText = "0";
+ timerSpan.innerText = "30";
+ // display text
+ clear(ctx, (canvas.width), (canvas.height));
+ drawGameStartText(ctx, (canvas.width/2), (canvas.height/2), cScore);
+ }
+ }, 1000);
+ }
+ else { // score computations
+ if(gameOn) {
+ cScore = parseInt(scoreSpan.innerText);
+ if (e.keyCode === expectedKeysMap[expectedKey])
+ scoreSpan.innerText = ++cScore;
+ else {
+ if(cScore > 0)
+ scoreSpan.innerText = --cScore;
+ }
+
+ expectedKey = drawRandomShape(shapes);
+ }
+ }
+ });
+});
\ No newline at end of file
diff --git a/lodash_exercise/lodash.js b/lodash_exercise/lodash.js
index 483d734a..53850775 100644
--- a/lodash_exercise/lodash.js
+++ b/lodash_exercise/lodash.js
@@ -1,77 +1,288 @@
-function drop(){
+function drop(arr, n=1){
+ var nArr = [];
+ for(var i=n; i arr.length) {
+ num--;
+ }
+
+ nArr = arr.slice(arr.length - num);
+ return nArr;
}
-function zipObject(){
+function union(...arrays){
+ var rSet = new Set();
+ var nArr = [];
-}
+ for(var i=0; i values.length -1)
+ nObj[props[i]] = undefined;
+ nObj[props[i]] = values[i];
+ }
+ return nObj;
}
-function cloneDeep(){
-
+function includes(a, val, idx=0){
+ if (typeof a === 'string') {
+ if(a.indexOf(val) !== -1)
+ return true;
+ }
+ else if (Array.isArray(a)) {
+ if (idx > 0) {
+ var nArr = a.slice(idx);
+ if(nArr.indexOf(val) > -1)
+ return true;
+ }
+ else {
+ if(a.indexOf(val) > -1)
+ return true;
+ }
+ }
+ else if (typeof a === 'object') {
+ if (Object.values(a).indexOf(val) > -1)
+ return true;
+ }
+ else if (Array.isArray(a)) {
+ if (idx > 0) {
+ var nArr = a.slice(idx);
+ if(nArr.indexOf(val) > -1)
+ return true;
+ }
+ else
+ if(a.indexOf(val) > -1)
+ return true;
+ }
+
+ return false;
}
-function sumBy(){
+function sample(arr){
+ var num = Math.floor(Math.random() * arr.length);
+ return arr[num];
+}
+function cloneDeep(a){
+ if (Array.isArray(a)) {
+ var nArr = [];
+ for (var i=0; i < a.length; i++) {
+ if (Array.isArray(a[i]) || typeof a[i] === 'object')
+ nArr.push(cloneDeep(a[i]));
+ else
+ nArr.push(a[i]);
+ }
+
+ return nArr;
+ }
+ else if (typeof a === 'object') {
+ var nObj = {};
+ for (key in a) {
+ if ( Array.isArray(a[key]) || typeof a[key] === 'object')
+ nObj[key] = cloneDeep(a[key]);
+ }
+ return nObj;
+ }
}
-function inRange(){
+function sumBy(arr, second){
+ var sum = 0;
+ if(typeof second === 'function') {
+ for(var i=0; i end && num < start;
+ else
+ return num < end && num > start;
}
-function has(){
+function has(obj, gKeys){
+ if(typeof gKeys === 'string')
+ gKeys = gKeys.split('.');
-}
+ var presentKeys = [];
+ function helper(a) {
+ for (key in a) {
+ presentKeys.push(key);
-function omit(){
+ if(typeof a[key] === 'object')
+ helper(a[key]);
+ }
+ }
+ helper(obj);
+ for(var i=0; i= len)
+ return str;
-}
+ if(chars === undefined) {
+ chars = "";
+ for (var i=0; i num) {
+ maxIndex = mid - 1;
+ helper(a);
+ }
+ else if (a[mid] < num) {
+ minIndex = mid + 1;
+ helper(a);
+ }
+ else {
+ return mid;
+ }
+ }
+ idx = helper(arr);
+ return idx;
+}
+
+// simple recursion
+function stringifyNumbers(obj) {
+ var nObj = {};
+ var kArr = Object.keys(obj);
+
+ if (kArr.length === 0)
+ return obj;
+
+ for (var i=0; i