", {
+ 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
diff --git a/call_apply_bind_exercise/callApplyBind.js b/call_apply_bind_exercise/callApplyBind.js
index e69de29b..5481b1b3 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
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/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
diff --git a/intermediate_oop/.DS_Store b/intermediate_oop/.DS_Store
new file mode 100644
index 00000000..feb7a05a
Binary files /dev/null and b/intermediate_oop/.DS_Store differ
diff --git a/intermediate_oop/tic_tac_toe/.DS_Store b/intermediate_oop/tic_tac_toe/.DS_Store
new file mode 100644
index 00000000..335a2eeb
Binary files /dev/null and b/intermediate_oop/tic_tac_toe/.DS_Store differ
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 00000000..5008ddfc
Binary files /dev/null and b/intermediate_oop/tic_tac_toe/js/.DS_Store differ
diff --git a/intermediate_oop/tic_tac_toe/js/main.js b/intermediate_oop/tic_tac_toe/js/main.js
index 379d891d..8b221309 100644
--- a/intermediate_oop/tic_tac_toe/js/main.js
+++ b/intermediate_oop/tic_tac_toe/js/main.js
@@ -1,2 +1,111 @@
+function Board(){
+ //key is id of square; value is the text
+ this.squares = {}
+}
+
+Board.prototype.initSquares = function(){
+ var allSquares = document.querySelectorAll(".square");
+ for(var i = 0; i < allSquares.length; i++){
+ this.squares[allSquares[i].id] = "";
+ allSquares[i].innerText = "";
+ }
+}
+
+
+function Player(){
+ this.text = Math.random() < .5 ? "X" : "O";
+}
+
+
+function Game(){
+ this.turnCount = 0;
+ this.winner = false;
+ this.board = new Board();
+ this.player = new Player();
+}
+
+Game.prototype.initBoard = function(){
+ this.board.initSquares();
+}
+
+Game.prototype.reset = function(){
+ this.initBoard();
+ this.player.text = Math.random() < 0.5 ? "X" : "O";
+ this.turnCount = 0;
+ this.winner = false;
+ this.displayMessage(this.player.text + "'s turn");
+}
+
+
+Game.prototype.switchPlayers = function(id){
+ //if square is clicked, change the text of square to that player
+ this.board.squares[id] = this.player.text
+
+ this.turnCount++;
+ if(this.checkForWinner()){
+ this.displayMessage("Congratulations, " + this.player.text + " wins!");
+ } else if(this.turnCount === 9 && !this.winner){
+ this.displayMessage("Tie Game!");
+ } else if(this.player.text === "X"){
+ this.player.text = "O";
+ this.displayMessage(this.player.text + "'s turn");
+ } else {
+ this.player.text = "X";
+ this.displayMessage(this.player.text + "'s turn");
+ }
+}
+
+
+Game.prototype.checkForWinner = function(){
+ if(this.checkRow("1", "2", "3") ||
+ this.checkRow("4", "5", "6") ||
+ this.checkRow("7", "8", "9") ||
+ this.checkRow("1", "4", "7") ||
+ this.checkRow("2", "5", "8") ||
+ this.checkRow("3", "6", "9") ||
+ this.checkRow("1", "5", "9") ||
+ this.checkRow("3", "5", "7")){
+ this.winner = true;
+ }
+ return this.winner;
+
+}
+
+Game.prototype.checkRow = function(id1, id2, id3){
+ if(this.board.squares[id1] === this.player.text
+ && this.board.squares[id2] === this.player.text
+ && this.board.squares[id3] === this.player.text
+ ){
+ this.winner = true;
+ }
+ return this.winner;
+}
+
+Game.prototype.displayMessage = function(msg){
+ var message = document.querySelector("#message");
+ message.innerText = msg;
+}
+
+
document.addEventListener("DOMContentLoaded", function() {
+ const game = new Game();
+ game.initBoard();
+
+ const gameBoard = document.getElementById("board");
+ gameBoard.addEventListener("click", function(e){
+ if(e.target.innerText === "" && !game.winner){
+ e.target.innerText = game.player.text;
+ game.switchPlayers(e.target.id);
+ }
+ })
+
+ const resetButton = document.getElementById("new-game");
+ resetButton.addEventListener("click", function(e){
+ game.reset();
+ })
});
+
+
+
+
+
diff --git a/jquery_exercise/.DS_Store b/jquery_exercise/.DS_Store
new file mode 100644
index 00000000..5008ddfc
Binary files /dev/null and b/jquery_exercise/.DS_Store differ
diff --git a/jquery_exercise/index.html b/jquery_exercise/index.html
new file mode 100755
index 00000000..dbc01d66
--- /dev/null
+++ b/jquery_exercise/index.html
@@ -0,0 +1,58 @@
+
+
+
+
+ Hack or Snooze
+
+
+
+
+
+
+
+
+
+
\ 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
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;
}
+
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;
+}
diff --git a/recursion_exercise/recursion.js b/recursion_exercise/recursion.js
index e69de29b..2359a7f5 100644
--- a/recursion_exercise/recursion.js
+++ b/recursion_exercise/recursion.js
@@ -0,0 +1,107 @@
+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));
+}
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;
+}
+
+
+
+
+
+
+
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;
+ });
+ });
+})
+
+
+
+
+
+
+
+
+
+
+