From 923a9d19088287501cd9f2768c7ba4a5923b0c98 Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Mon, 31 Jul 2017 21:54:01 -0700 Subject: [PATCH 01/15] updated testing.js and testingSpec.js with solutions --- testing_exercise/testing.js | 45 +++++++++++++ testing_exercise/testingSpec.js | 115 +++++++++++++++++++++++++++++++- 2 files changed, 159 insertions(+), 1 deletion(-) diff --git a/testing_exercise/testing.js b/testing_exercise/testing.js index e69de29b..871df400 100644 --- a/testing_exercise/testing.js +++ b/testing_exercise/testing.js @@ -0,0 +1,45 @@ +function replaceWith(str,charOut,charIn){ + return str.split("").map(function(val){ + if(val === charOut){ + return charIn; + } + return val; + }).join(""); +} + +function expand(arr,num){ + var newArr = []; + for(var i = 0; i < Math.floor(num); i++){ + newArr = newArr.concat(arr); + } + return newArr; +} + +function acceptNumbersOnly(){ + if(arguments.length === 0){ + return false; + } + for(var i = 0; i < arguments.length; i++){ + if(typeof arguments[i] !== "number" || isNaN(arguments[i])){ + return false; + } + } + return true; +} + +function mergeArrays(arr1,arr2){ + return arr1.concat(arr2).sort(function(a,b){ + return a - b; + }); +} + +function mergeObjects(obj1, obj2) { + var newObj = {}; + for(var key in obj1){ + newObj[key] = obj1[key]; + } + for(var key in obj2){ + newObj[key] = obj2[key]; + } + return newObj; +} \ No newline at end of file diff --git a/testing_exercise/testingSpec.js b/testing_exercise/testingSpec.js index aef56b1d..1fceec45 100644 --- a/testing_exercise/testingSpec.js +++ b/testing_exercise/testingSpec.js @@ -1,3 +1,116 @@ var expect = chai.expect; -// WRITE YOUR TESTS HERE! \ No newline at end of file +describe("testing exercise", function(){ + describe("replaceWith", function(){ + it("should return a string", function(){ + expect(replaceWith("awesome", "e", "z")).to.be.a("string"); + }); + it("should return a string of equal length", function(){ + expect(replaceWith("awesome", "e", "z").length).to.equal("awesome".length) + }); + it("should respect case of lowercase letter being replaced", function(){ + expect(replaceWith("awesomE", "e", "z")).to.equal("awzsomE"); + expect(replaceWith("awesomE", "e", "Z")).to.equal("awZsomE"); + }); + it("should respect case of uppercase letter being replaced", function(){ + expect(replaceWith("Foof", "F", "b")).to.equal("boof"); + expect(replaceWith("Foof", "F", "B")).to.equal("Boof"); + }); + it("should accept an empty string as an argument", function(){ + expect(replaceWith("", "F", "b")).to.be.a("string").that.is.empty; + expect(replaceWith("awesome", "", "z")).to.equal("awesome"); + expect(replaceWith("Foo", "F", "")).to.equal("oo"); + }); + }); + describe("expand", function(){ + it("should return an array", function(){ + expect(expand([1,2,3],3)).to.be.an("array"); + }); + it("should return a copy of the array with as many numbers as specified", function(){ + expect(expand([1,2,3],3)).to.deep.equal([1,2,3,1,2,3,1,2,3]); + expect(expand(["foo", "test"],1)).to.deep.equal(["foo", "test"]); + expect(expand([1,"foo",2,"test",3],2)).to.deep.equal([1, "foo", 2, "test", 3, 1, "foo", 2, "test", 3]); + }); + it("rounds second argument down to nearest whole number", function(){ + expect(expand([1,2,3],2.7)).to.deep.equal([1,2,3,1,2,3]); + }); + it("returns an empty array if second argument is less than or equal to 0", function(){ + expect(expand([1,2,3], 0)).to.be.an("array").that.is.empty; + expect(expand(["foo", "test"], -2)).to.be.an('array').that.is.empty; + }); + it("should return an empty array if an empty array is passed as argument", function(){ + expect(expand([],2)).to.be.an("array").that.is.empty; + }); + }); + describe("acceptNumbersOnly", function(){ + it("should return a boolean", function(){ + expect(acceptNumbersOnly(1,"foo")).to.be.a("boolean"); + expect(acceptNumbersOnly(0,1,2,3,4.2)).to.be.a("boolean") + }); + it("should return false for any non-number argument", function(){ + expect(acceptNumbersOnly(1,"foo")).to.equal(false); + expect(acceptNumbersOnly(1,[],{})).to.equal(false); + expect(acceptNumbersOnly(1,null)).to.equal(false); + expect(acceptNumbersOnly(1,undefined)).to.equal(false); + expect(acceptNumbersOnly(1,NaN)).to.equal(false); + }); + it("should return false if there are no arguments", function(){ + expect(acceptNumbersOnly()).to.be.equal(false); + }); + it("should return true if arguments are all numbers", function(){ + expect(acceptNumbersOnly(0,1,2,3,4.2)).to.equal(true); + expect(acceptNumbersOnly(-1,-2,-3.4)).to.equal(true); + }); + }); + describe("mergeArrays", function(){ + it("should return an array", function(){ + expect(mergeArrays([2,1],[3,4])).to.be.an("array"); + }); + it("should return an array with length equal to sum of argument arrays", function(){ + expect(mergeArrays([2,1],[3,4]).length).to.equal([1,2,3,4].length); + }); + it("should concat argument arrays and sort resulting array", function(){ + expect(mergeArrays([2,1],[3,4])).to.deep.equal([1,2,3,4]); + expect(mergeArrays([-2,10,27],[3,-4,0])).to.deep.equal([-4,-2,0,3,10,27]); + expect(mergeArrays([4,1,8],[])).to.deep.equal([1,4,8]); + }); + it("returns an empty array if both arrays passed in are empty", function(){ + expect(mergeArrays([],[])).to.be.an("array").that.is.empty; + }); + }); + describe("mergeObjects", function(){ + var obj1 = { + name: "Foo", + num: 33 + } + var obj2 = { + test: "thing", + num: 55 + } + it("should return an object", function(){ + expect(mergeObjects(obj1,obj2)).to.be.an("object"); + }) + it("should return an object that combines keys and values of both objects with value of overlapping keys equal to that of second parameter", function(){ + expect(mergeObjects(obj1,obj2)).to.have.all.keys("name", "num", "test"); + expect(mergeObjects(obj1,obj2)).to.have.property("num", 55); + }); + it("should return an object with only keys of the passed in object if the other argument is an empty object", function(){ + expect(mergeObjects(obj1,{})).to.to.have.all.keys("name", "num"); + expect(mergeObjects({},obj2)).to.to.have.all.keys("num", "test"); + }); + it("should return an empty object if both objects passed in are empty", function(){ + expect(mergeObjects({},{})).to.be.an("object").that.is.empty; + }); + }); +}) + + + + + + + + + + + From 843a52fbc9340956660f3b530e9b73dfcbfc5dc1 Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Wed, 2 Aug 2017 01:18:49 -0700 Subject: [PATCH 02/15] finished recursion exercises --- recursion_exercise/recursion.js | 108 ++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/recursion_exercise/recursion.js b/recursion_exercise/recursion.js index e69de29b..07066fe5 100644 --- a/recursion_exercise/recursion.js +++ b/recursion_exercise/recursion.js @@ -0,0 +1,108 @@ +function productOfArray(arr){ + if(arr.length === 0) return 1; + return arr[0] * productOfArray(arr.slice(1)) +} + +function collectStrings(obj){ + var newArr = []; + function helper(newObj){ + for(var key in newObj){ + if(typeof newObj[key] === "object") helper(newObj[key]); + if(typeof newObj[key] === "string") newArr.push(newObj[key]); + } + } + helper(obj); + return newArr; +} + +function contains(obj, val){ + var result = false; + function helper(helperObj){ + for(var key in helperObj){ + if(helperObj[key] === val) result = true; + else if(typeof helperObj[key] === "object") helper(helperObj[key]); + } + } + helper(obj); + return result; +} + + +function realSize(arrays) { + var count = 0; + function helper(arr){ + for(var i = 0; i < arr.length; i++){ + if(typeof arr[i] === "number") count++; + else if(Array.isArray(arr[i])) helper(arr[i]); + } + } + helper(arrays); + return count; +} + + +function SumSquares(l){ + var total = 0; + function helper(a){ + for(var i = 0; i < a.length; i++){ + if(typeof a[i] === "number") total += Math.pow(a[i], 2); + else if(Array.isArray(a[i])) helper(a[i]); + } + } + helper(l); + return total; +} + +function replicate(times, number) { + var newArr = []; + if(times <= 0) return newArr; + else return newArr.concat(number,replicate(times-1, number)); +} + + +function search(arr, val){ + var index = 0; + function helper(newArr){ + if(newArr.length === 0) index = -1; + if(newArr[0] !== val){ + index++; + helper(newArr.slice(1)); + } + } + helper(arr); + return index; +} + +function binarySearch(arr, val, start, end){ + var start = start || 0; + var end = end || arr.length-1; + var middle = Math.floor((start+end)/2); + if(end < start || val < arr[start] || val > arr[end]) return -1; + if(val === arr[middle]) return middle; + if(val < arr[middle]) return binarySearch(arr, val, start, middle-1); + else return binarySearch(arr, val, middle+1, end); +} + +function stringifyNumbers(obj) { + var newObj = {}; + for(var key in obj) { + if(typeof obj[key] === "object" && !Array.isArray(obj[key])){ + newObj[key] = stringifyNumbers(obj[key]); + } else if(typeof obj[key] === "number"){ + newObj[key] = (obj[key]).toString(); + } else{ + newObj[key] = obj[key]; + } + } + return newObj; +} + +function F(n) { + if (n === 0) return 1; + return n - M(F(n - 1)); +} + +function M(n) { + if (n === 0) return 0; + return n - F(M(n - 1)); +} From 739b83c6bd0112c0bcaa47488b4573c4eddc603e Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Wed, 2 Aug 2017 13:59:08 -0700 Subject: [PATCH 03/15] added recursion dom exercises --- recursion_exercise/recursion_dom_exercises.js | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 recursion_exercise/recursion_dom_exercises.js diff --git a/recursion_exercise/recursion_dom_exercises.js b/recursion_exercise/recursion_dom_exercises.js new file mode 100644 index 00000000..f017236f --- /dev/null +++ b/recursion_exercise/recursion_dom_exercises.js @@ -0,0 +1,49 @@ +function getElementById(id){ + var element = null; + function helper(e){ + for(var i = 0; i < e.length; i++){ + if(e[i].id === id){ + element = e[i]; + } + helper(e[i].children); + } + } + helper(document.body.children); + return element; +} + + +function getElementsByTagName(tag){ + var newArr = []; + function helper(e){ + for(var i = 0; i < e.length; i++){ + if(e[i].tagName === tag.toUpperCase()){ + newArr.push(e[i]); + } + helper(e[i].children); + } + } + helper(document.body.children); + return newArr; +} + +function getElementsByClassName(className){ + var newArr = []; + function helper(e){ + for(var i = 0; i < e.length; i++){ + if(e[i].className.split(" ").includes(className)){ + newArr.push(e[i]); + } + helper(e[i].children); + } + } + helper(document.body.children); + return newArr; +} + + + + + + + From 0ae4f4bacf367bced690f094b1d74a755ce5a65c Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Thu, 3 Aug 2017 12:01:15 -0700 Subject: [PATCH 04/15] updated indentation --- recursion_exercise/recursion.js | 43 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/recursion_exercise/recursion.js b/recursion_exercise/recursion.js index 07066fe5..ca0530a7 100644 --- a/recursion_exercise/recursion.js +++ b/recursion_exercise/recursion.js @@ -34,19 +34,18 @@ function realSize(arrays) { for(var i = 0; i < arr.length; i++){ if(typeof arr[i] === "number") count++; else if(Array.isArray(arr[i])) helper(arr[i]); - } } - helper(arrays); - return count; + } + helper(arrays); + return count; } - function SumSquares(l){ var total = 0; - function helper(a){ + function helper(a){ for(var i = 0; i < a.length; i++){ if(typeof a[i] === "number") total += Math.pow(a[i], 2); - else if(Array.isArray(a[i])) helper(a[i]); + else if(Array.isArray(a[i])) helper(a[i]); } } helper(l); @@ -56,7 +55,7 @@ function SumSquares(l){ function replicate(times, number) { var newArr = []; if(times <= 0) return newArr; - else return newArr.concat(number,replicate(times-1, number)); + else return newArr.concat(number,replicate(times-1, number)); } @@ -80,29 +79,29 @@ function binarySearch(arr, val, start, end){ if(end < start || val < arr[start] || val > arr[end]) return -1; if(val === arr[middle]) return middle; if(val < arr[middle]) return binarySearch(arr, val, start, middle-1); - else return binarySearch(arr, val, middle+1, end); + else return binarySearch(arr, val, middle+1, end); } function stringifyNumbers(obj) { - var newObj = {}; - for(var key in obj) { - if(typeof obj[key] === "object" && !Array.isArray(obj[key])){ - newObj[key] = stringifyNumbers(obj[key]); - } else if(typeof obj[key] === "number"){ - newObj[key] = (obj[key]).toString(); - } else{ - newObj[key] = obj[key]; - } + var newObj = {}; + for(var key in obj) { + if(typeof obj[key] === "object" && !Array.isArray(obj[key])){ + newObj[key] = stringifyNumbers(obj[key]); + } else if(typeof obj[key] === "number"){ + newObj[key] = (obj[key]).toString(); + } else{ + newObj[key] = obj[key]; } - return newObj; + } + return newObj; } function F(n) { - if (n === 0) return 1; - return n - M(F(n - 1)); + if (n === 0) return 1; + return n - M(F(n - 1)); } function M(n) { - if (n === 0) return 0; - return n - F(M(n - 1)); + if (n === 0) return 0; + return n - F(M(n - 1)); } From 8e1cb7948661ba3af5ae06fc452fb17cfdf1ac2f Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Thu, 3 Aug 2017 12:07:58 -0700 Subject: [PATCH 05/15] edited indentation of recursion exercises --- recursion_exercise/recursion.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/recursion_exercise/recursion.js b/recursion_exercise/recursion.js index ca0530a7..3ff346d4 100644 --- a/recursion_exercise/recursion.js +++ b/recursion_exercise/recursion.js @@ -33,9 +33,9 @@ function realSize(arrays) { function helper(arr){ for(var i = 0; i < arr.length; i++){ if(typeof arr[i] === "number") count++; - else if(Array.isArray(arr[i])) helper(arr[i]); - } - } + else if(Array.isArray(arr[i])) helper(arr[i]); + } + } helper(arrays); return count; } @@ -43,18 +43,18 @@ function realSize(arrays) { function SumSquares(l){ var total = 0; function helper(a){ - for(var i = 0; i < a.length; i++){ - if(typeof a[i] === "number") total += Math.pow(a[i], 2); - else if(Array.isArray(a[i])) helper(a[i]); - } - } - helper(l); - return total; + for(var i = 0; i < a.length; i++){ + if(typeof a[i] === "number") total += Math.pow(a[i], 2); + else if(Array.isArray(a[i])) helper(a[i]); + } + } + helper(l); + return total; } function replicate(times, number) { var newArr = []; - if(times <= 0) return newArr; + if(times <= 0) return newArr; else return newArr.concat(number,replicate(times-1, number)); } @@ -86,11 +86,11 @@ function stringifyNumbers(obj) { var newObj = {}; for(var key in obj) { if(typeof obj[key] === "object" && !Array.isArray(obj[key])){ - newObj[key] = stringifyNumbers(obj[key]); + newObj[key] = stringifyNumbers(obj[key]); } else if(typeof obj[key] === "number"){ newObj[key] = (obj[key]).toString(); } else{ - newObj[key] = obj[key]; + newObj[key] = obj[key]; } } return newObj; From ef4d6ae78665c8c1014a9802775d44aee37107f3 Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Thu, 3 Aug 2017 12:16:52 -0700 Subject: [PATCH 06/15] reedited indentation of recursion exercises --- recursion_exercise/recursion.js | 108 ++++++++++++++++---------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/recursion_exercise/recursion.js b/recursion_exercise/recursion.js index 3ff346d4..2359a7f5 100644 --- a/recursion_exercise/recursion.js +++ b/recursion_exercise/recursion.js @@ -1,84 +1,84 @@ function productOfArray(arr){ - if(arr.length === 0) return 1; - return arr[0] * productOfArray(arr.slice(1)) + if(arr.length === 0) return 1; + return arr[0] * productOfArray(arr.slice(1)) } function collectStrings(obj){ - var newArr = []; - function helper(newObj){ - for(var key in newObj){ - if(typeof newObj[key] === "object") helper(newObj[key]); - if(typeof newObj[key] === "string") newArr.push(newObj[key]); - } - } - helper(obj); - return newArr; + var newArr = []; + function helper(newObj){ + for(var key in newObj){ + if(typeof newObj[key] === "object") helper(newObj[key]); + if(typeof newObj[key] === "string") newArr.push(newObj[key]); + } + } + helper(obj); + return newArr; } function contains(obj, val){ - var result = false; - function helper(helperObj){ - for(var key in helperObj){ - if(helperObj[key] === val) result = true; - else if(typeof helperObj[key] === "object") helper(helperObj[key]); - } - } - helper(obj); - return result; -} + var result = false; + function helper(helperObj){ + for(var key in helperObj){ + if(helperObj[key] === val) result = true; + else if(typeof helperObj[key] === "object") helper(helperObj[key]); + } + } + helper(obj); + return result; +} function realSize(arrays) { - var count = 0; - function helper(arr){ - for(var i = 0; i < arr.length; i++){ - if(typeof arr[i] === "number") count++; - else if(Array.isArray(arr[i])) helper(arr[i]); - } - } + var count = 0; + function helper(arr){ + for(var i = 0; i < arr.length; i++){ + if(typeof arr[i] === "number") count++; + else if(Array.isArray(arr[i])) helper(arr[i]); + } + } helper(arrays); return count; } function SumSquares(l){ - var total = 0; + var total = 0; function helper(a){ - for(var i = 0; i < a.length; i++){ - if(typeof a[i] === "number") total += Math.pow(a[i], 2); - else if(Array.isArray(a[i])) helper(a[i]); - } - } - helper(l); - return total; + for(var i = 0; i < a.length; i++){ + if(typeof a[i] === "number") total += Math.pow(a[i], 2); + else if(Array.isArray(a[i])) helper(a[i]); + } + } + helper(l); + return total; } function replicate(times, number) { - var newArr = []; + var newArr = []; if(times <= 0) return newArr; else return newArr.concat(number,replicate(times-1, number)); } function search(arr, val){ - var index = 0; - function helper(newArr){ - if(newArr.length === 0) index = -1; - if(newArr[0] !== val){ - index++; - helper(newArr.slice(1)); - } - } - helper(arr); - return index; + var index = 0; + function helper(newArr){ + if(newArr.length === 0) index = -1; + if(newArr[0] !== val){ + index++; + helper(newArr.slice(1)); + } + } + helper(arr); + return index; } function binarySearch(arr, val, start, end){ - var start = start || 0; - var end = end || arr.length-1; - var middle = Math.floor((start+end)/2); - if(end < start || val < arr[start] || val > arr[end]) return -1; - if(val === arr[middle]) return middle; - if(val < arr[middle]) return binarySearch(arr, val, start, middle-1); + var start = start || 0; + var end = end || arr.length-1; + var middle = Math.floor((start+end)/2); + if(end < start || val < arr[start] || val > arr[end]) return -1; + if(val === arr[middle]) return middle; + if(val < arr[middle]) return binarySearch(arr, val, start, middle-1); else return binarySearch(arr, val, middle+1, end); } @@ -88,7 +88,7 @@ function stringifyNumbers(obj) { if(typeof obj[key] === "object" && !Array.isArray(obj[key])){ newObj[key] = stringifyNumbers(obj[key]); } else if(typeof obj[key] === "number"){ - newObj[key] = (obj[key]).toString(); + newObj[key] = (obj[key]).toString(); } else{ newObj[key] = obj[key]; } From fb02ddd8ec5beafd79cd8b61fd1730271f112685 Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Fri, 4 Aug 2017 01:27:52 -0700 Subject: [PATCH 07/15] added lodash and canvas exercises --- canvas_exercise/shapes_game/index.js | 81 ++++++- lodash_exercise/lodash.js | 315 ++++++++++++++++++++------- 2 files changed, 308 insertions(+), 88 deletions(-) diff --git a/canvas_exercise/shapes_game/index.js b/canvas_exercise/shapes_game/index.js index 0de5f18a..136c6ba7 100644 --- a/canvas_exercise/shapes_game/index.js +++ b/canvas_exercise/shapes_game/index.js @@ -1,15 +1,56 @@ window.addEventListener("load", function() { - function clear(ctx, width, heigt) { + function clear(ctx, width, height) { + ctx.clearRect(0, 0, width, height); } function drawRandomShape(ctx, width, height) { + clear(ctx, canvas.width, canvas.height); + var shapes = ["wTri", "wSq", "rTri", "rSq"]; + var randomShape = shapes[Math.floor(Math.random()*shapes.length)]; + + var randomX = Math.floor(Math.random()*(canvas.width - 2*width) + width); + var randomY = Math.floor(Math.random()*(canvas.height - 2*height) + height); + + + if(randomShape === "wSq" || randomShape === "wTri") { + ctx.fillStyle = "white"; + } else { + ctx.fillStyle = "red"; + } + + if(randomShape === "wSq" || randomShape === "rSq") { + ctx.fillRect(randomX, randomY, width, height); + } else { + ctx.beginPath(); + ctx.moveTo(randomX, randomY); + ctx.lineTo(randomX + width, randomY + height); + ctx.lineTo(randomX, randomY + height); + ctx.fill(); + ctx.closePath(); + } + + return randomShape; } function drawGameStartText(ctx, width, height, score) { + ctx.fillStyle = "white"; + ctx.font = '30px arial'; + ctx.textAlign = "center"; + ctx.fillText('Press the space bar to start a new game', width/2, height/2); } + function restartGame(ctx, width, height) { + clear(ctx, canvas.width, canvas.height); + ctx.fillStyle = "white"; + ctx.font = '30px arial'; + ctx.textAlign = "center"; + ctx.fillText('Press the space bar to play again', width/2, height/2); + ctx.fillText("You scored " + score + " points", width/2, height/2 + 50); + gameOn = false; + score = 0; + seconds = 30; } var canvas = document.getElementById("shapes-game"), @@ -20,17 +61,47 @@ window.addEventListener("load", function() { 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}, + expectedKeysMap = {wTri: 38, rSq: 40, rTri: 37, wSq: 39}, timerSpan = document.getElementById("time-remaining"), scoreSpan = document.getElementById("score-val"), - seconds = 3, + seconds = 30, + score = 0, intervalId; canvas.width = width; canvas.height = height; - document.addEventListener("keyup", function() { - + document.addEventListener("keyup", function(e) { + e.preventDefault(); //doesn't work + if(e.keyCode === 32 && !gameOn){ + gameOn = true; + scoreSpan.innerText = score; + timerSpan.innerText = seconds; + intervalId = setInterval(function(){ + seconds--; + timerSpan.innerText = seconds; + },1000) + + setTimeout(function(){ + clearInterval(intervalId); + clear(ctx, canvas.width, canvas.height); + restartGame(ctx, canvas.width, canvas.height); + },seconds * 1000); + + expectedKey = drawRandomShape(ctx, 50, 50) + } else if(e.keyCode === expectedKeysMap[expectedKey] && gameOn){ + score++; + scoreSpan.innerText = score; + expectedKey = drawRandomShape(ctx, 50, 50); + } else if(gameOn){ + score--; + scoreSpan.innerText = score; + expectedKey = drawRandomShape(ctx, 50, 50); + } }); + + drawGameStartText(ctx, canvas.width, canvas.height) + }); + diff --git a/lodash_exercise/lodash.js b/lodash_exercise/lodash.js index 483d734a..1be09080 100644 --- a/lodash_exercise/lodash.js +++ b/lodash_exercise/lodash.js @@ -1,99 +1,248 @@ -function drop(){ - -} - -function fromPairs(){ - -} - -function head(){ - -} - -function take(){ - -} - -function takeRight(){ - -} - -function union(){ - -} - -function zipObject(){ - -} - -function includes(){ - -} - -function sample(){ - -} - -function cloneDeep(){ - -} - -function sumBy(){ - -} - -function inRange(){ - -} - -function has(){ - -} - -function omit(){ - -} - -function pick(){ - -} - -function pickBy(){ - -} - -function omitBy(){ - -} - -function padEnd(){ - -} - -function repeat(){ - +function drop(arr, n=1){ + return arr.slice(n) +} + +function fromPairs(arr){ + var obj = {} + arr.forEach(function(val){ + obj[val[0]] = val[1] + }) + return obj; +} + +function head(arr){ + return arr[0]; +} + +function take(arr, n=1){ + return arr.slice(0,n); +} + +function takeRight(arr, n=1){ + if(n >= arr.length) n = arr.length; + return arr.slice(arr.length-n) +} + +function union(...arrays){ + var newArr = []; + arrays.forEach(function(val){ + val.forEach(function(e){ + if(newArr.indexOf(e) === -1){ + newArr.push(e); + } + }) + }) + return newArr; +} + +function zipObject(arr1,arr2){ + return arr1.reduce(function(acc,next,idx){ + acc[next] = arr2[idx]; + return acc; + },{}) +} + +function includes(col, val, idx=0){ + if(typeof col === "object" && !Array.isArray(col)){ + for(var key in col){ + if(col[key] === val){ + return true; + } + } + return false; + } + if(Array.isArray(col)){ + if(idx>0){ + col = col.slice(idx) + } + return col.indexOf(val) >=0; + } + if(typeof col === "string"){ + return col.indexOf(val) >=0; + } +} + +function sample(col){ + var objArr = []; + if(typeof col === "object" && !Array.isArray(col)){ + for(var key in col){ + objArr.push(col[key]); + } + return objArr[Math.floor(Math.random()*objArr.length)]; + } + if(Array.isArray(col)){ + return col[Math.floor(Math.random()*col.length)]; + } +} + +function cloneDeep(val){ + var obj = {}; + var arr = []; + if(typeof val === "object"){ + for(var i = 0; i < val.length; i++){ + for(var key in val[i]){ + if(typeof val === "object"){ + obj[key] = cloneDeep(val[i][key]) + } else{ + obj[key] = val[i][key]; + } + } + arr.push(obj) + } + return arr; + } +} + +function sumBy(arr,itr){ + if(typeof itr === "function"){ + return arr.reduce(function(acc,next){ + acc += itr(next); + return acc; + },0); + } else if(typeof itr === "string"){ + return arr.reduce(function(acc,next){ + return acc + next[itr]; + },0); + } +} + + +function inRange(num, start=0, end){ + if(arguments.length === 2){ + end = start; + start = 0; + } + return num>=Math.min(start,end) && num= 0){ + newObj[key] = obj[key] + } + } + return newObj; +} + +function pickBy(obj, fn){ + var newObj = {}; + for(var key in obj){ + if(fn(obj[key])){ + newObj[key] = obj[key]; + } + } + return newObj; +} + +function omitBy(obj, fn){ + var newObj = {}; + for(var key in obj){ + if(!fn(obj[key])){ + newObj[key] = obj[key]; + } + } + return newObj; +} + +function padEnd(str,num,padding){ + if(arguments.length === 2) padding = " "; + if(str.length + padding.length === num){ + return str.concat(padding); + } + if(str.length + padding.length < num){ + str = str.concat(padding); + return padEnd(str,num,padding); + } + else if(str.length + padding.length > num){ + return str.concat(padding).slice(0,num); + } +} + + +function repeat(str,num){ + var newStr = ""; + for(var i = 0; i < num; i++){ + newStr = newStr.concat(str); + } + return newStr; } function upperFirst(str){ - + return str[0].toUpperCase().concat(str.slice(1)); } -function flatten(){ - +function flatten(arr){ + return arr.reduce(function(acc,next){ + return acc.concat(next); + },[]); } -function zip(){ +function zip(...arr){ + var resultArr = []; + arr[0].forEach(function(val,idx){ + var holderArr = []; + arr.forEach(function(v,i){ + holderArr.push(arr[i][idx]); + }) + resultArr.push(holderArr); + }) + return resultArr; } -function unzip(){ - +function unzip(...arr){ + var resultArr = []; + arr[0][0].forEach(function(val,idx){ + var holderArr = []; + arr[0].forEach(function(v,i){ + holderArr.push(arr[0][i][idx]); + }) + resultArr.push(holderArr); + }) + return resultArr; } -function flip(){ +function flip(fn){ + return function(...args){ + return fn(...args.reverse()); + } } -function flattenDeep(){ - +function flattenDeep(arr){ + var newArr = []; + function helper(a){ + for(var i = 0; i < a.length; i++){ + if(Array.isArray(a[i])) helper(a[i]); + else newArr.push(a[i]); + } + } + helper(arr); + return newArr; } + From e140957e070da4823c5f3ae78d7a8a8f24d0074b Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Sun, 6 Aug 2017 02:48:46 -0700 Subject: [PATCH 08/15] finished es2015 exercise --- es2015_exercise/readme.md | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/es2015_exercise/readme.md b/es2015_exercise/readme.md index 9e482efa..c57d49ed 100644 --- a/es2015_exercise/readme.md +++ b/es2015_exercise/readme.md @@ -11,16 +11,31 @@ var person = { }.bind(this),1000) } } + +var person = { + fullName: "Harry Potter", + sayHi(){ + setTimeout(() => + console.log(`Your name is ${this.fullName}`) + ,1000) + } +} ``` ```javascript var name = "Josie" console.log("When " + name + " comes home, so good") + +var name = "Josie" +console.log(`When ${name} comes home, so good`) ``` ```javascript var DO_NOT_CHANGE = 42; DO_NOT_CHANGE = 50; // stop me from doing this! + +const DO_NOT_CHANGE = 42; +DO_NOT_CHANGE = 50; // Uncaught TypeError: Assignment to constant variable. ``` ```javascript @@ -28,6 +43,10 @@ var arr = [1,2] var temp = arr[0] arr[0] = arr[1] arr[1] = temp + +var arr = [1,2] +var [temp,temp2] = arr +[temp,temp2] = [temp2,temp] ``` ```javascript @@ -36,6 +55,8 @@ function double(arr){ return val*2 }); } + +let double = arr => arr.map(val => val*2) ``` ```javascript @@ -48,6 +69,9 @@ var obj = { var a = obj.numbers.a; var b = obj.numbers.b; + + +var {a,b} = obj.numbers; ``` ```javascript @@ -62,14 +86,16 @@ function add(a,b){ } return a+b } + +let add = (a=10, b=10) => a+b; ``` Research the following functions - what do they do? -`Array.from` - +`Array.from` - creates a new Array instance from an array-like or iterable objects, such as arguments -`Object.assign` - +`Object.assign` - creates a shallow copy of an object by copying the vaules of all enumerable and own properties from one or more source objects to a target object and returning the target object -`Array.includes` - +`Array.includes` - determines whether an array includes a certain element, returning true if found and false if not found; if we need the index of the element, need to use indexOf -`String.startsWith` - +`String.startsWith` - determines whether a string begins with the characters of a specified string, returning true if the characters are found and false if not found From 6736fb78890c5d0947197d041a3c3a1732c66a22 Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Tue, 8 Aug 2017 09:28:50 -0700 Subject: [PATCH 09/15] added hack or snooze exercise --- jquery_exercise/.DS_Store | Bin 0 -> 6148 bytes jquery_exercise/index.html | 58 +++++++++++++++++++++++++++ jquery_exercise/script.js | 80 +++++++++++++++++++++++++++++++++++++ jquery_exercise/styles.css | 61 ++++++++++++++++++++++++++++ 4 files changed, 199 insertions(+) create mode 100644 jquery_exercise/.DS_Store create mode 100755 jquery_exercise/index.html create mode 100755 jquery_exercise/script.js create mode 100755 jquery_exercise/styles.css diff --git a/jquery_exercise/.DS_Store b/jquery_exercise/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 + + + + Hack or Snooze + + + + +
+
+
+
+ Hack or Snooze + + submit | favorites + +
+
+
+
+
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+
+
    +
  1. Visualizing Algorithms + (visualgo.net) +
  2. +
  3. Problem Solving with Rithm + (rithmschool.com) +
  4. +
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/jquery_exercise/script.js b/jquery_exercise/script.js new file mode 100755 index 00000000..e7c2aa0f --- /dev/null +++ b/jquery_exercise/script.js @@ -0,0 +1,80 @@ +$(function(){ + + let $submit = $("#submit"); + let $favorites = $("#favorites"); + let $addStory = $("#add-story"); + let $storyList = $("#story-list") + let $form = $("form"); + let $title = $("#title"); + let $url = $("#url"); + let $ol = $("ol"); + + + $submit.on("click", function(e){ + $addStory.toggleClass("hide"); + }) + + + $form.on("submit", function(e){ + e.preventDefault(); + + let $starSpan = $("", { + addClass: "glyphicon glyphicon-star-empty" + }) + + let $hostName = $url.val().split("://")[1] + if($url.val().split(".").length > 2){ + $hostName = $url.val().split(".").slice(-2).join("."); + } + + let $urlSpan = $("", { + class: "small", + text: `(${$hostName})` + }) + + let $newA = $("", { + attr: { + href: $url.val() + }, + target: "_blank", + text: `${$title.val()} ` + }) + + let $newStory = $("
  • ").append($starSpan).append($newA).append($urlSpan); + + $ol.append($newStory); + + $form.trigger("reset"); + $addStory.toggleClass("hide"); + }) + + $ol.on("click", "span.glyphicon", function(e){ + $(e.target).toggleClass("glyphicon-star-empty glyphicon-star"); + }) + + $ol.on("click", "span.small", function(e){ + let $clickedUrlText = $(e.target).text(); + let $allLis = $("li"); + $allLis.each(function(i,el){ + console.log($(el).children().eq(2).text()) + if($(el).children().eq(2).text() !== $clickedUrlText){ + $(el).toggleClass("hide"); + } + }) + }) + + $favorites.on("click", function(e){ + let $allLis = $("li"); + if($(e.target).text() === "favorites"){ + $(e.target).text("all"); + } else { + $(e.target).text("favorites"); + } + + $allLis.each(function(i,el){ + if($(el).children().eq(0).hasClass("glyphicon-star-empty")){ + $(el).toggleClass("hide"); + } + }) + }) +}) \ No newline at end of file diff --git a/jquery_exercise/styles.css b/jquery_exercise/styles.css new file mode 100755 index 00000000..f651ff8d --- /dev/null +++ b/jquery_exercise/styles.css @@ -0,0 +1,61 @@ + +header { + background-color: #FF6600; + height: 50px; + font-size: 20px; + padding: 1rem; + margin-top: 10px; + border-radius: 2px; +} + +section { + background-color: #F5F5EE; + border-radius: 2px; +} + +.links { + font-size: 15px; + margin-left: 10px; + cursor: pointer; +} + +#submit:hover { + text-decoration: underline; +} + +#favorites:hover { + text-decoration: underline; +} + +.small{ + color: gray; + cursor: pointer; +} + +.small:hover { + text-decoration: underline; +} + +.hide { + display: none; +} + +a { + color: black; + text-decoration: none; + margin-left: 5px; +} + +a, a:hover, a:focus { + text-decoration: none; + color: black; +} + +li { + padding: 5px; +} + +form{ + margin-top: 10px; + margin-left: 30px; +} \ No newline at end of file From e9b6eaf9d451f0f36f63951030c786ec0e374970 Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Wed, 9 Aug 2017 17:03:40 -0700 Subject: [PATCH 10/15] finished call apply bind exercises --- call_apply_bind_exercise/callApplyBind.js | 117 ++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/call_apply_bind_exercise/callApplyBind.js b/call_apply_bind_exercise/callApplyBind.js index e69de29b..a7255026 100644 --- a/call_apply_bind_exercise/callApplyBind.js +++ b/call_apply_bind_exercise/callApplyBind.js @@ -0,0 +1,117 @@ +//1. Fix the following code: + +var obj = { + fullName: "Harry Potter", + person: { + sayHi: function(){ + return "This person's name is " + this.fullName + } + } +} + +//Fix + +var obj = { + fullName: "Harry Potter", + sayHi: function(){ + return "This person's name is " + this.fullName + } +} + +obj.sayHi(); + +//2. Two examples of array-like-objects are arguments and document.querySelectorAll() + + + +//3. Write a function called sumEvenArguments which takes all of the arguments passed to a function and returns the sum of the even ones. + +function sumEvenArguments(){ + return [].slice.call(arguments).reduce(function(acc,next){ + if(next % 2 === 0){ + acc += next; + } + return acc; + },0) +} + +/*sumEvenArguments(1,2,3,4) // 6 +sumEvenArguments(1,2,6) // 8 +sumEvenArguments(1,2) // 2*/ + + +//4. Write a function called arrayFrom which converts an array-like-object into an array. + +// function sample(){ +// var arr = arrayFrom(arguments) +// if(!arr.reduce) throw "This is not an array!" +// return arr.reduce(function(acc,next){ +// return acc+next; +// },0) +// } + +function arrayFrom(){ + return [].slice.call(arguments); +} + +//5. Write a function called invokeMax which accepts a function and a maximum amount. invokeMax should return a function that when called increments a counter. If the counter is greater than the maximum amount, the inner function should return "Maxed Out" + +/*function add(a,b){ + return a+b +} + +var addOnlyThreeTimes = invokeMax(add,3); +addOnlyThreeTimes(1,2) // 3 +addOnlyThreeTimes(2,2) // 4 +addOnlyThreeTimes(1,2) // 3 +addOnlyThreeTimes(1,2) // "Maxed Out!"*/ + +function invokeMax(fn,max){ + var counter = 0; + return function(){ + counter++; + if(counter > max){ + return "Maxed Out!"; + } + return fn.apply(this,arguments); + } +} + +//6. Write a function called guessingGame which takes in one parameter amount. The function should return another function that takes in a parameter called guess. In the outer function, you should create a variable called answer which is the result of a random number between 0 and 10 as well as a variable called guesses which should be set to 0. + +/*In the inner function, if the guess passed in is the same as the random number (defined in the outer function) - you should return the string "You got it!". If the guess is too high return "You're too high!" and if it is too low, return "You're too low!". You should stop the user from guessing if the amount of guesses they have made is greater than the initial amount passed to the outer function. + +You will have to make use of closure to solve this problem.*/ + +/*var game = guessingGame(5) +game(1) // "You're too low!" +game(8) // "You're too high!" +game(5) // "You're too low!" +game(7) // "You got it!" +game(1) // "You are all done playing!" + +var game2 = guessingGame(3) +game2(5) // "You're too low!" +game2(3) // "You're too low!" +game2(1) // "No more guesses the answer was 0" +game2(1) // "You are all done playing!*/ + + +function guessingGame(amount){ + var answer = Math.floor(Math.random()*11); + var guesses = 0; + return function(guess){ + guesses++; + if(guesses > amount){ + return "You are all done playing!"; + } else{ + if(guess === answer){ + return "You got it!"; + } else if(guess > answer){ + return "You're too high!"; + } else{ + return "You're too low!"; + } + } + } +} \ No newline at end of file From a904de51acf877e5f381dda7d6bb64840df3531d Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Wed, 9 Aug 2017 17:08:21 -0700 Subject: [PATCH 11/15] updated call apply bind exercises --- call_apply_bind_exercise/callApplyBind.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/call_apply_bind_exercise/callApplyBind.js b/call_apply_bind_exercise/callApplyBind.js index a7255026..445bd16f 100644 --- a/call_apply_bind_exercise/callApplyBind.js +++ b/call_apply_bind_exercise/callApplyBind.js @@ -3,19 +3,19 @@ var obj = { fullName: "Harry Potter", person: { - sayHi: function(){ - return "This person's name is " + this.fullName - } - } + sayHi: function(){ + return "This person's name is " + this.fullName + } + } } //Fix var obj = { - fullName: "Harry Potter", - sayHi: function(){ - return "This person's name is " + this.fullName - } + fullName: "Harry Potter", + sayHi: function(){ + return "This person's name is " + this.fullName + } } obj.sayHi(); @@ -54,7 +54,7 @@ function arrayFrom(){ return [].slice.call(arguments); } -//5. Write a function called invokeMax which accepts a function and a maximum amount. invokeMax should return a function that when called increments a counter. If the counter is greater than the maximum amount, the inner function should return "Maxed Out" +//5. Write a function called invokeMax which accepts a function and a maximum amount. invokeMax should return a function that when called increments a counter. If the counter is greater than the maximum amount, the inner function should return "Maxed Out!" /*function add(a,b){ return a+b From 2a5ed0ec5d2ad9259d2e8b9b73ccc3c9fb1b18ce Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Wed, 9 Aug 2017 17:10:56 -0700 Subject: [PATCH 12/15] updated call apply bind exercises --- call_apply_bind_exercise/callApplyBind.js | 78 +++++++++++------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/call_apply_bind_exercise/callApplyBind.js b/call_apply_bind_exercise/callApplyBind.js index 445bd16f..5481b1b3 100644 --- a/call_apply_bind_exercise/callApplyBind.js +++ b/call_apply_bind_exercise/callApplyBind.js @@ -3,19 +3,19 @@ var obj = { fullName: "Harry Potter", person: { - sayHi: function(){ - return "This person's name is " + this.fullName - } - } + sayHi: function(){ + return "This person's name is " + this.fullName + } + } } //Fix var obj = { - fullName: "Harry Potter", - sayHi: function(){ + fullName: "Harry Potter", + sayHi: function(){ return "This person's name is " + this.fullName - } + } } obj.sayHi(); @@ -27,12 +27,12 @@ obj.sayHi(); //3. Write a function called sumEvenArguments which takes all of the arguments passed to a function and returns the sum of the even ones. function sumEvenArguments(){ - return [].slice.call(arguments).reduce(function(acc,next){ - if(next % 2 === 0){ - acc += next; - } - return acc; - },0) + return [].slice.call(arguments).reduce(function(acc,next){ + if(next % 2 === 0){ + acc += next; + } + return acc; + },0) } /*sumEvenArguments(1,2,3,4) // 6 @@ -51,10 +51,10 @@ sumEvenArguments(1,2) // 2*/ // } function arrayFrom(){ - return [].slice.call(arguments); + return [].slice.call(arguments); } -//5. Write a function called invokeMax which accepts a function and a maximum amount. invokeMax should return a function that when called increments a counter. If the counter is greater than the maximum amount, the inner function should return "Maxed Out!" +//5. Write a function called invokeMax which accepts a function and a maximum amount. invokeMax should return a function that when called increments a counter. If the counter is greater than the maximum amount, the inner function should return "Maxed Out" /*function add(a,b){ return a+b @@ -67,14 +67,14 @@ addOnlyThreeTimes(1,2) // 3 addOnlyThreeTimes(1,2) // "Maxed Out!"*/ function invokeMax(fn,max){ - var counter = 0; - return function(){ - counter++; - if(counter > max){ - return "Maxed Out!"; - } - return fn.apply(this,arguments); - } + var counter = 0; + return function(){ + counter++; + if(counter > max){ + return "Maxed Out!"; + } + return fn.apply(this,arguments); + } } //6. Write a function called guessingGame which takes in one parameter amount. The function should return another function that takes in a parameter called guess. In the outer function, you should create a variable called answer which is the result of a random number between 0 and 10 as well as a variable called guesses which should be set to 0. @@ -98,20 +98,20 @@ game2(1) // "You are all done playing!*/ function guessingGame(amount){ - var answer = Math.floor(Math.random()*11); - var guesses = 0; - return function(guess){ - guesses++; - if(guesses > amount){ - return "You are all done playing!"; - } else{ - if(guess === answer){ - return "You got it!"; - } else if(guess > answer){ - return "You're too high!"; - } else{ - return "You're too low!"; - } - } - } + var answer = Math.floor(Math.random()*11); + var guesses = 0; + return function(guess){ + guesses++; + if(guesses > amount){ + return "You are all done playing!"; + } else{ + if(guess === answer){ + return "You got it!"; + } else if(guess > answer){ + return "You're too high!"; + } else{ + return "You're too low!"; + } + } + } } \ No newline at end of file From 43b5d50da11364b0b50ef3485612082277b11a98 Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Fri, 11 Aug 2017 00:57:46 -0700 Subject: [PATCH 13/15] finished prototye exercises --- prototypes_exercise/prototypes.js | 64 +++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/prototypes_exercise/prototypes.js b/prototypes_exercise/prototypes.js index e69de29b..6dab99b8 100644 --- a/prototypes_exercise/prototypes.js +++ b/prototypes_exercise/prototypes.js @@ -0,0 +1,64 @@ +//Part I + +function Person(firstName, lastName, favoriteColor, favoriteNumber, favoriteFoods){ + this.firstName = firstName; + this.lastName = lastName; + this.favoriteColor = favoriteColor; + this.favoriteNumber = favoriteNumber; + this.favoriteFoods = []; + this.family = []; +} + +Person.prototype.fullName = function(){ + return `${this.firstName} ${this.lastName}`; +} + +Person.prototype.toString = function(){ + return `${this.firstName} ${this.lastName}, Favorite Color: ${this.favoriteColor}, Favorite Number: ${this.favoriteNumber}`; +} + +Person.prototype.addToFamily = function(person){ + if(person instanceof Person && !this.family.includes(person)){ + return this.family.push(person); + } +} + +//Part II + +Array.prototype.map = function(fn){ + let newArr = []; + for(let i = 0; i < this.length; i++){ + newArr.push(fn(this[i], [i], this)) + } + return newArr; +} + + +String.prototype.reverse = function(){ + let reverseStr = ""; + for(let i = this.length-1; i >=0; i--){ + reverseStr = reverseStr.concat(this[i]); + } + return reverseStr; +} + + +Function.prototype.bind = function(thisArg){ + let _this = this; + let outerArgs = [].slice.call(arguments, 1) + return function() { + let innerArgs = [].slice.call(arguments); + return _this.apply(thisArg, outerArgs.concat(innerArgs)); + } +} + +Array.prototype.reduce = function(fn, startVal) { + let acc = startVal ? startVal : this[0]; + let idx = startVal ? 0 : 1; + + while(idx < this.length){ + acc = fn(acc, this[idx], idx, this); + idx++; + } + return acc; +} From 5121ed4441b6542aa453c0dab66edbc6a916ecb0 Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Wed, 16 Aug 2017 00:17:54 -0700 Subject: [PATCH 14/15] finished hack or snooze --- ajax_with_jquery_exercise/index.html | 81 +++++++ ajax_with_jquery_exercise/script.js | 347 +++++++++++++++++++++++++++ ajax_with_jquery_exercise/styles.css | 77 ++++++ 3 files changed, 505 insertions(+) create mode 100755 ajax_with_jquery_exercise/index.html create mode 100755 ajax_with_jquery_exercise/script.js create mode 100755 ajax_with_jquery_exercise/styles.css diff --git a/ajax_with_jquery_exercise/index.html b/ajax_with_jquery_exercise/index.html new file mode 100755 index 00000000..9bafed4c --- /dev/null +++ b/ajax_with_jquery_exercise/index.html @@ -0,0 +1,81 @@ + + + + + Hack or Snooze + + + + +
    +
    +
    +
    + Hack or Snooze + + favorites + + + + +
    +
    +
    +
    +
    +

    login

    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    sign up

    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
      + +
    +
      + +
    +
    + + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/ajax_with_jquery_exercise/script.js b/ajax_with_jquery_exercise/script.js new file mode 100755 index 00000000..5e649da3 --- /dev/null +++ b/ajax_with_jquery_exercise/script.js @@ -0,0 +1,347 @@ +$(function(){ + let authToken = localStorage.getItem("token") || null; + let storedFavs = JSON.parse(localStorage.getItem("storedFavs")) || {}; + let $login = $("#login"); + let $loginForm = $("#login-form"); + let $signUp = $("#sign-up"); + let $signUpForm = $("#sign-up-form"); + let $logout = $("#logout"); + let $favorites = $("#favorites"); + let $storyList = $("#story-list"); + let $favoritesList = $("#favorites-list"); + let $bothLists = $("#both-lists") + let $errorMsg = $("#error-msg"); + + function buttonToggle(){ + $login.toggleClass("hide"); + $signUp.toggleClass("hide"); + $logout.toggleClass("hide"); + } + + if(authToken){ + buttonToggle() + $.ajax({ + method: "GET", + url: "https://hn-favorites.herokuapp.com/stories.json", + dataType: "json", + contentType: "application/json", + headers: { + Authorization: authToken + } + }).then(function(res){ + $favoritesList.empty() + res.forEach(function(val){ + storedFavs[val.story_id] = { + id: val.id, + title: val.title, + by: val.by, + url: val.url + } + }) + localStorage.setItem("storedFavs", JSON.stringify(storedFavs)); + for(var key in storedFavs){ + addStories(key, storedFavs[key].title, storedFavs[key].by, storedFavs[key].url, $favoritesList); + } + }) + } + + $login.on("click", function(e){ + $loginForm.toggleClass("hide"); + if(!$signUpForm.hasClass("hide")){ + $signUpForm.toggleClass("hide"); + } + if(!$errorMsg.text() === ""){ + $errorMsg.toggleClass("hide"); + } + }) + + $signUp.on("click", function(e){ + $signUpForm.toggleClass("hide"); + if(!$loginForm.hasClass("hide")){ + $loginForm.toggleClass("hide"); + } + if(!$errorMsg.text() === ""){ + $errorMsg.toggleClass("hide"); + } + }) + + $loginForm.on("submit", function(e){ + e.preventDefault(); + authenticate("login", $("#login-email").val(), $("#login-password").val()); + $loginForm.trigger("reset"); + }) + + $signUpForm.on("submit", function(e){ + e.preventDefault(); + authenticate("signup", $("#sign-up-email").val(), $("#sign-up-password").val()); + $signUpForm.trigger("reset"); + }) + + $logout.on("click", function(){ + localStorage.removeItem("token"); + localStorage.removeItem("storedFavs"); + authToken = null; + storedFavs = {}; + buttonToggle() + if($storyList.hasClass("hide")){ + $storyList.toggleClass("hide") + $favoritesList.toggleClass("hide") + } + $(".glyphicon").toggleClass("hide"); + }) + + $storyList.on("click", "span.glyphicon", function(e){ + var $by = $(e.target).siblings().eq(2).text().slice(3); + var $story_id = $(e.target).siblings().eq(3).text(); + var $title = $(e.target).siblings().eq(0).text(); + var $url = $(e.target).siblings().eq(0).attr("href") + $(e.target).toggleClass("glyphicon-star-empty glyphicon-star"); + if($(e.target).hasClass("glyphicon-star") && authToken){ + $.ajax({ + method: "POST", + url: "https://hn-favorites.herokuapp.com/stories.json", + data: JSON.stringify({ + hacker_news_story: { + by: $by, + story_id: $story_id, + title: $title, + url: $url + } + }), + dataType: "json", + contentType: "application/json", + headers: { + Authorization: authToken + } + }) + .then(function(res){ + storedFavs[res.story_id] = { + id: res.id, + title: res.title, + by: res.by, + url: res.url + } + localStorage.setItem("storedFavs", JSON.stringify(storedFavs)); + }) + .fail(function(err){ + console.log(err); + }) + } else if($(e.target).hasClass("glyphicon-star-empty") && authToken){ + $.ajax({ + method: "DELETE", + url: `https://hn-favorites.herokuapp.com/stories/${storedFavs[$story_id].id}.json`, + headers: { + Authorization: authToken + } + }) + .then(function(res){ + if(storedFavs[$story_id]) { + delete storedFavs[$story_id]; + } + localStorage.storedFavs = JSON.stringify(storedFavs); + }) + .fail(function(err){ + console.log(err); + }) + } + }) + + + $favoritesList.on("click", "span.glyphicon", function(e){ + var $story_id = $(e.target).siblings().eq(3).text(); + $(e.target).toggleClass("glyphicon-star-empty glyphicon-star"); + if($(e.target).hasClass("glyphicon-star-empty") && authToken){ + $.ajax({ + method: "DELETE", + url: `https://hn-favorites.herokuapp.com/stories/${storedFavs[$story_id].id}.json`, + headers: { + Authorization: authToken + } + }) + .then(function(res){ + $(e.target).parent().remove(); + $storyList.children().each(function(i,el){ + for(var key in storedFavs){ + if(key === $(el).children().eq(4).text()){ + $(el).children().eq(0).toggleClass("glyphicon-star-empty glyphicon-star"); + } + } + }) + if(storedFavs[$story_id]) { + delete storedFavs[$story_id]; + } + localStorage.storedFavs = JSON.stringify(storedFavs); + }) + .fail(function(err){ + console.log(err); + }) + } + }) + + $favorites.on("click", function(e){ + + if($(e.target).text() === "favorites"){ + $(e.target).text("top stories"); + $storyList.toggleClass("hide"); + $favoritesList.toggleClass("hide"); + for(var key in storedFavs){ + addStories(key, storedFavs[key].title, storedFavs[key].by, storedFavs[key].url, $favoritesList); + } + } else { + $(e.target).text("favorites"); + $storyList.toggleClass("hide"); + $favoritesList.toggleClass("hide"); + $favoritesList.empty() + } + }) + + + function authenticate(action, email, password){ + $.ajax({ + method: "POST", + url: `https://hn-favorites.herokuapp.com/${action}`, + data: JSON.stringify({ + email: email, + password: password + }), + dataType: "json", + contentType: "application/json" + }).then(function(res){ + localStorage.setItem("token", res.auth_token); + authToken = res.auth_token; + if(authToken){ + $(".glyphicon").toggleClass("hide"); + } + buttonToggle(); + if(action === "login"){ + $loginForm.toggleClass("hide"); + $.ajax({ + method: "GET", + url: "https://hn-favorites.herokuapp.com/stories.json", + dataType: "json", + contentType: "application/json", + headers: { + Authorization: authToken + } + }).then(function(res){ + res.forEach(function(val){ + storedFavs[val.story_id] = { + id: val.id, + title: val.title, + by: val.by, + url: val.url + } + }) + localStorage.setItem("storedFavs", JSON.stringify(storedFavs)); + let $allLis = $("li"); + $allLis.each(function(i,el){ + for(var key in storedFavs){ + if(key === $(el).children().eq(4).text()){ + $(el).children().eq(0).toggleClass("glyphicon-star-empty glyphicon-star"); + } + } + }) + }) + + } else { + storedFavs = {}; + $signUpForm.toggleClass("hide"); + } + }) + .catch(function(err){ + if(action === "login") { + $errorMsg.toggleClass("hide"); + $errorMsg.text("There was an error logging you in, please try again later."); + } else { + $errorMsg.toggleClass("hide"); + $errorMsg.text("There was an error signing you up, please try again later."); + } + }); + } + + + function getTopStories(){ + let stories = []; + + $.get("https://hacker-news.firebaseio.com/v0/topstories.json") + .then(function(res){ + stories = stories.concat(res.slice(0,20)); + return stories; + }) + .then(function(res){ + //get details for each story + let storyDetails = res.map(function(val){ + return $.get(`https://hacker-news.firebaseio.com/v0/item/${val}.json`); + }) + return Promise.all(storyDetails); + }) + .then(function(res){ + res.forEach(function(val){ + addStories(val.id, val.title, val.by, val.url, $storyList); + }) + if(authToken){ + $(".glyphicon").toggleClass("hide"); + } + }) + .fail(function(err){ + console.log(`There was an error, ${err}`); + }) + } + + getTopStories(); + + + function addStories(id, title, author, url, list){ + + let $newLi = $("
  • ") + if(list === $storyList){ + var $starSpan = $("", { + addClass: "glyphicon glyphicon-star-empty hide" + }) + } else { + $starSpan = $("", { + addClass: "glyphicon glyphicon-star" + }) + } + + + if(url){ + var hostName = url.split("://")[1].split("/")[0]; + var n = hostName.split(".").length + if(n <= 2){ + hostName = hostName.split(".").slice(-(n)).join("."); + } + else if(n > n-1){ + hostName = hostName.split(".").slice(-(n-1)).join("."); + } + } else hostName = "n/a"; + + + let $urlSpan = $("", { + class: "small", + text: `(${hostName})` + }) + + let $newA = $("", { + attr: { + href: url + }, + target: "_blank", + text: `${title}` + }) + + let $authorDiv = $("
    ", { + class: "small", + text: `by ${author}` + }) + + let $storyIdSpan = $("", { + class: "small hide", + text: id + }) + + let $newStory = $("
  • ").append($starSpan).append($newA).append($urlSpan).append($authorDiv).append($storyIdSpan); + + list.append($newStory); + } +}) \ No newline at end of file diff --git a/ajax_with_jquery_exercise/styles.css b/ajax_with_jquery_exercise/styles.css new file mode 100755 index 00000000..62cfe0e7 --- /dev/null +++ b/ajax_with_jquery_exercise/styles.css @@ -0,0 +1,77 @@ + +header { + background-color: #FF6600; + height: 50px; + font-size: 20px; + padding: 1rem; + margin-top: 10px; + border-radius: 2px; +} + +section { + background-color: #F5F5EE; + border-radius: 2px; +} + +.links { + font-size: 15px; + margin-left: 10px; + cursor: pointer; +} + +#submit:hover { + text-decoration: underline; +} + +#favorites:hover { + text-decoration: underline; +} + +.small{ + color: gray; + cursor: pointer; + margin-left: 5px; +} + +.small:hover { + text-decoration: underline; +} + +.hide { + display: none; +} + +.orange { + background-color: #FF6600; +} + +.auth { + color: #FF6600; + font-weight: bold; + font-size: 18px; +} + +#error-msg { + color: red; + text-align: center; +} + +a { + color: black; + text-decoration: none; + margin-left: 5px; +} + +a, a:hover, a:focus { + text-decoration: none; + color: black; +} + +li { + padding: 5px; +} + +form{ + margin-top: 10px; + margin-left: 30px; +} \ No newline at end of file From 44653fe984df38db71578b9cf29200a8864be647 Mon Sep 17 00:00:00 2001 From: Jonathan Yuen Date: Wed, 16 Aug 2017 00:18:21 -0700 Subject: [PATCH 15/15] finished tic tac toe oop --- intermediate_oop/.DS_Store | Bin 0 -> 8196 bytes intermediate_oop/tic_tac_toe/.DS_Store | Bin 0 -> 8196 bytes intermediate_oop/tic_tac_toe/index.html | 24 ++--- intermediate_oop/tic_tac_toe/js/.DS_Store | Bin 0 -> 6148 bytes intermediate_oop/tic_tac_toe/js/main.js | 109 ++++++++++++++++++++++ 5 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 intermediate_oop/.DS_Store create mode 100644 intermediate_oop/tic_tac_toe/.DS_Store create mode 100644 intermediate_oop/tic_tac_toe/js/.DS_Store diff --git a/intermediate_oop/.DS_Store b/intermediate_oop/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..feb7a05a95a67b45efbdc5b0829bdac4aa98eb4e GIT binary patch literal 8196 zcmeI1PfQ$D9LImZg|_qfV;>aCc9FU%A{7^1h%G^zx(i!uLz|)tEKqcv-I>C~VP>;4 zyP$-KMx!=r)ab#3Ce}aIUi9KcFUDBopMwW`fauAaClmG1qrW$AmbSniyr@m*ZRY*n zyx;FP^Y%NRnc=qp01lP3K7cR)D6|R7>#5tO3BTC3w2(hjOBN{~zy%fZkR@wxi4GB4+_vbTQsH0dtZ8kK2RV~;HFeSJRhR837hcksCq1+#8QY55-qv z(dEAWfx%dGpnqUxg}<#R?ROqZo|-PKoIC&C`yYIG;iIp0orlPyETS=wOr$@p%+Vht_+QR!7 z|4fSpFQ-{Fe1LIP8Fy%D@(^9Dn{kJYKTa1@ruMLy z!ZkKwsyW@1Q}?hwg^#jKS*~AB-pdXvO&DWSd3#}jR_Ms-!SMYG|5kZaocpBexTg!c zb#+w_D9W_(BsERfl+MIKc{Mu|aXH}PC9@A=a1=&hhJd$V5nh6q;T3ob&cj9c6h4Pb z@C|$i-@}iv2J7%M`~tthAMhvqg@6p}umKyf8Qbwz+>f{6?bwTVV;uW%027$RVNBsk zoWMz(#u?0`i3@0B0iVJb@I^d_Z{VBw4qlM!301I5$^A-?AJeGHO-b1KH)SZZ9d?nC z#s^dX33lrZ0=A~+JuR(1eaVfh=V5g%F&-q60*{W$)!%ewuZM3hAsK0B9o1l-Ak6e7 zj~l-0vWR9;cEIDBgSQ{)igYUkH4jO5Pb4Og-a$t2jWWJd z?jDUK1dCje!CjFQQ#fveT~+AbCFDMVFW^f;?g#h@eudxR3SqVrIqtszKXBm z>k_|B@ExyUC#?r(75K{OqGj6F97R^py*@eEyO9*Ak&6wB`u|w<-~VrZbJ2?zy;zp9{5g0q2Pi#x^JJBJ$kEr+v&ipNtzvqs`@McY zGu>Z*GffWwfP+P?2Otap3RNL_9W~n&;TLsF3Hg?4l1TZGHSH|vH?w)u*b*HW0t5mC z0t5mC0t5mC{tpPyo-K;9!@e)QK^q_tAh0VD5buX5RUs3;T$a*%bx`9S0Z57?fLBQ8 zLLnLTWx|)sQj&)X%2bjv75yUy%5<_v{kViLm!*{Hfd1hF{X3(7LP78Dbp5Co4w#TK zXafWS1hyg|9-k0A4o+7ScJ6F-iY};JZ)$D|!movP1$hKV7u=K*Z)S0wlX?A(gE?Sy1lakj<8=5

    Fw)}Mf-aDmX`S2iqdxH zv4L|_`K3!&-h2Op53hdo)z@|0X!DSFkXh(x}8D^pN{@+G?* zwd+X4rNYGqau8y05{6+Ka$rFjF2l?43cLkZ;2L}ipTl+d2EK#u;YV13Rrncxf#2W{ z_!Is@K!&wgj}6#_ZFnml!rSn6?8dt>jy>3i2^_#7OyXG_#|fOmY0ROC^JrrppT-yQ zCA@@h;G6gkUX|ksRY;bU{Yr};ljc2eL^A(@3#GRsS!B53!Q_8JvekM)t;VMP%`HCH z2G-WfBhh+(c$AQ9?s1{A)|=LGBh?NN0V8d!eJARU6RGqCk0pHX4H3F%^Sh_iN- z>SI(z5pl~>dMVUw_z*z-wSO3r9;Hx`lknxTlw_guuYU-jzdVBd--AAAb}<5f19Qf} Ay#N3J literal 0 HcmV?d00001 diff --git a/intermediate_oop/tic_tac_toe/index.html b/intermediate_oop/tic_tac_toe/index.html index 00c74eb9..90eac45d 100644 --- a/intermediate_oop/tic_tac_toe/index.html +++ b/intermediate_oop/tic_tac_toe/index.html @@ -11,27 +11,27 @@ - - - + + +

    Tic Tac Toe

    -
    -
    -
    +
    +
    +
    -
    -
    -
    +
    +
    +
    -
    -
    -
    +
    +
    +
    diff --git a/intermediate_oop/tic_tac_toe/js/.DS_Store b/intermediate_oop/tic_tac_toe/js/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0