From 47d4ee7f00fc1c8eeade9e6e1f512000fc4de979 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Fri, 9 Dec 2022 00:37:29 -0500 Subject: [PATCH] Bring the code over. --- ex00-gearing-up/code.js | 1 + ex01-a-first-program/code.js | 6 ++ ex02-comments/code.js | 16 +++ ex03-simple-math-and-strings/code.js | 8 ++ ex04-variables/code.js | 19 ++++ ex05-constants/code.js | 13 +++ ex06-escape-sequences/code.js | 7 ++ ex07-prompting-input/code.js | 9 ++ ex08-command-line-arguments/code.js | 9 ++ ex09-files/code.js | 15 +++ ex09-files/test.txt | 4 + ex10-files-args-variables-oh-my/code.js | 10 ++ ex10-files-args-variables-oh-my/test.txt | 4 + ex11-functions/code.js | 38 +++++++ ex12-functions-files-variables/code.js | 23 +++++ ex12-functions-files-variables/poem.txt | 7 ++ ex13-modules/code.js | 7 ++ ex13-modules/geometry.js | 8 ++ ex15-if-and-else/code.js | 28 +++++ ex16-while-loops/code.js | 18 ++++ ex17-sequences-and-for-loops/all-loops.js | 25 +++++ ex17-sequences-and-for-loops/code.js | 19 ++++ ex18-more-arrays/code.js | 18 ++++ ex19-data-objects/code.js | 21 ++++ ex20-first-game/code.js | 64 ++++++++++++ ex21-simple-oop/alex.js | 4 + ex21-simple-oop/code.js | 52 ++++++++++ ex21-simple-oop/frank.js | 6 ++ ex21-simple-oop/franktalk.js | 5 + ex21-simple-oop/mary.js | 9 ++ ex21-simple-oop/marytalk.js | 4 + ex21-simple-oop/person.js | 18 ++++ ex22-more-complex-oop/code.js | 21 ++++ ex22-more-complex-oop/ex21.js | 23 +++++ ex23-inheritance/code.js | 61 +++++++++++ ex24-oop-game/code.js | 107 ++++++++++++++++++++ ex25-functions-and-recursion/code.js | 25 +++++ ex26-transforming-data/code.js | 32 ++++++ ex27-applying-functions/code.js | 31 ++++++ ex28-scope-and-closures/closure.js | 20 ++++ ex28-scope-and-closures/code.js | 16 +++ ex29-partial-application/code.js | 48 +++++++++ ex30-promises-async-await/async.js | 16 +++ ex30-promises-async-await/async.mjs | 17 ++++ ex30-promises-async-await/cbhell.js | 32 ++++++ ex30-promises-async-await/cbstart.js | 16 +++ ex30-promises-async-await/event.js | 35 +++++++ ex30-promises-async-await/eventhell.js | 50 +++++++++ ex30-promises-async-await/promise_clean.js | 50 +++++++++ ex30-promises-async-await/promises.js | 20 ++++ ex30-promises-async-await/promises_fixed.js | 12 +++ ex30-promises-async-await/test.txt | 1 + ex30-promises-async-await/topromise.js | 9 ++ ex31-modules-and-import/code.js | 6 ++ ex31-modules-and-import/code.mjs | 6 ++ ex31-modules-and-import/ex13_code.js | 7 ++ ex31-modules-and-import/ex13_geometry.js | 8 ++ ex31-modules-and-import/geometry.mjs | 7 ++ 58 files changed, 1171 insertions(+) create mode 100644 ex00-gearing-up/code.js create mode 100644 ex01-a-first-program/code.js create mode 100644 ex02-comments/code.js create mode 100644 ex03-simple-math-and-strings/code.js create mode 100644 ex04-variables/code.js create mode 100644 ex05-constants/code.js create mode 100644 ex06-escape-sequences/code.js create mode 100644 ex07-prompting-input/code.js create mode 100644 ex08-command-line-arguments/code.js create mode 100644 ex09-files/code.js create mode 100644 ex09-files/test.txt create mode 100644 ex10-files-args-variables-oh-my/code.js create mode 100644 ex10-files-args-variables-oh-my/test.txt create mode 100644 ex11-functions/code.js create mode 100644 ex12-functions-files-variables/code.js create mode 100644 ex12-functions-files-variables/poem.txt create mode 100644 ex13-modules/code.js create mode 100644 ex13-modules/geometry.js create mode 100644 ex15-if-and-else/code.js create mode 100644 ex16-while-loops/code.js create mode 100644 ex17-sequences-and-for-loops/all-loops.js create mode 100644 ex17-sequences-and-for-loops/code.js create mode 100644 ex18-more-arrays/code.js create mode 100644 ex19-data-objects/code.js create mode 100644 ex20-first-game/code.js create mode 100644 ex21-simple-oop/alex.js create mode 100644 ex21-simple-oop/code.js create mode 100644 ex21-simple-oop/frank.js create mode 100644 ex21-simple-oop/franktalk.js create mode 100644 ex21-simple-oop/mary.js create mode 100644 ex21-simple-oop/marytalk.js create mode 100644 ex21-simple-oop/person.js create mode 100644 ex22-more-complex-oop/code.js create mode 100644 ex22-more-complex-oop/ex21.js create mode 100644 ex23-inheritance/code.js create mode 100644 ex24-oop-game/code.js create mode 100644 ex25-functions-and-recursion/code.js create mode 100644 ex26-transforming-data/code.js create mode 100644 ex27-applying-functions/code.js create mode 100644 ex28-scope-and-closures/closure.js create mode 100644 ex28-scope-and-closures/code.js create mode 100644 ex29-partial-application/code.js create mode 100644 ex30-promises-async-await/async.js create mode 100644 ex30-promises-async-await/async.mjs create mode 100644 ex30-promises-async-await/cbhell.js create mode 100644 ex30-promises-async-await/cbstart.js create mode 100644 ex30-promises-async-await/event.js create mode 100644 ex30-promises-async-await/eventhell.js create mode 100644 ex30-promises-async-await/promise_clean.js create mode 100644 ex30-promises-async-await/promises.js create mode 100644 ex30-promises-async-await/promises_fixed.js create mode 100644 ex30-promises-async-await/test.txt create mode 100644 ex30-promises-async-await/topromise.js create mode 100644 ex31-modules-and-import/code.js create mode 100644 ex31-modules-and-import/code.mjs create mode 100644 ex31-modules-and-import/ex13_code.js create mode 100644 ex31-modules-and-import/ex13_geometry.js create mode 100644 ex31-modules-and-import/geometry.mjs diff --git a/ex00-gearing-up/code.js b/ex00-gearing-up/code.js new file mode 100644 index 0000000..812286e --- /dev/null +++ b/ex00-gearing-up/code.js @@ -0,0 +1 @@ +console.log("Hi!"); diff --git a/ex01-a-first-program/code.js b/ex01-a-first-program/code.js new file mode 100644 index 0000000..ddfd545 --- /dev/null +++ b/ex01-a-first-program/code.js @@ -0,0 +1,6 @@ +console.log("You are writing text to your screen.") +console.log("This is called 'standard output'.") +console.log("This stuff in the ( ) is a string.") +console.log("Start a string with a double-quote.") +console.log("Write what you want.") +console.log("Then end with a double-quote.") diff --git a/ex02-comments/code.js b/ex02-comments/code.js new file mode 100644 index 0000000..035a4aa --- /dev/null +++ b/ex02-comments/code.js @@ -0,0 +1,16 @@ +// This is a comment, everything after is ignored. + +console.log("I am Code"); + +/* This is also a comment. You use this for + * longer things that you want to say. + */ + +console.log("So am I"); + +// The code inside the next comment will not run: + +/* +console.log("I will not run."); +*/ + diff --git a/ex03-simple-math-and-strings/code.js b/ex03-simple-math-and-strings/code.js new file mode 100644 index 0000000..ef7fcf5 --- /dev/null +++ b/ex03-simple-math-and-strings/code.js @@ -0,0 +1,8 @@ +// You can give multiple things for console.log to print. +// Separate each thing with a comma. +console.log("Name:", 'Zed A. Shaw'); +console.log("Age:", 43); +console.log("Feet Tall:", Math.floor(74 / 12)); +console.log("And Inches:", 74 - (Math.floor(74 / 12) * 12)); +console.log("Age * Height:", 43 * 74); +console.log("Age * Feet:", 43 * Math.floor(74 / 12)); diff --git a/ex04-variables/code.js b/ex04-variables/code.js new file mode 100644 index 0000000..bc9bae7 --- /dev/null +++ b/ex04-variables/code.js @@ -0,0 +1,19 @@ +// let is the best way to make a variable +let name = 'Zed A. Shaw'; +let age = 43; +let height = 74; + +// PUZZLE: What happens if you use Math.round? +let feet = Math.floor(height / 12); +let inches = height - (feet * 12); + +// you can use a variable as a parameter +console.log("Name:", name); +console.log("Age:", age); + +// you can also embed variables in strings with `` +console.log(`Height ${feet} feet ${inches} inches.`); + +console.log("Age * Height:", age * height); +// you can also put math in the ${} boundaries +console.log(`Age * Feet: ${age * feet}`); diff --git a/ex05-constants/code.js b/ex05-constants/code.js new file mode 100644 index 0000000..ee21191 --- /dev/null +++ b/ex05-constants/code.js @@ -0,0 +1,13 @@ +const invincible = 94; +let changeme = 82; + +console.log(`invincible=${invincible} but changeme=${changeme}`); + +// this will work just fine +changeme = 100; + +// uncomment this to see how you can't do it +// invincible = 100000; + + +console.log(`After change: invicible=${invincible} but changeme=${changeme}`); diff --git a/ex06-escape-sequences/code.js b/ex06-escape-sequences/code.js new file mode 100644 index 0000000..71cef85 --- /dev/null +++ b/ex06-escape-sequences/code.js @@ -0,0 +1,7 @@ +let talking = "I'm not sure if she said, \"Hello\" or not."; +let walking = 'I\'ll need to go \'cause you don\'t know.'; + +// These strings are broken. Use escapes to fix them. +let height = "6'2""; +console.log('I'm not g'na see y'all for a while.'); + diff --git a/ex07-prompting-input/code.js b/ex07-prompting-input/code.js new file mode 100644 index 0000000..8feb258 --- /dev/null +++ b/ex07-prompting-input/code.js @@ -0,0 +1,9 @@ +const readline = require('readline-sync'); + +let name = readline.question("What's your name? "); +let age = readline.question("What's your age? "); +let eyes = readline.question("What's your eye color? "); + +console.log(`Your name is ${name}`); +console.log(`Your age is ${age}`); +console.log(`Your eyes are ${eyes}`); diff --git a/ex08-command-line-arguments/code.js b/ex08-command-line-arguments/code.js new file mode 100644 index 0000000..3b3298c --- /dev/null +++ b/ex08-command-line-arguments/code.js @@ -0,0 +1,9 @@ + +let name = process.argv[2]; +let age = process.argv[3]; +let eyes = process.argv[4]; + +console.log(`Your name is ${name}`); +console.log(`Your age is ${age}`); +console.log(`Your eyes are ${eyes}`); + diff --git a/ex09-files/code.js b/ex09-files/code.js new file mode 100644 index 0000000..823f94c --- /dev/null +++ b/ex09-files/code.js @@ -0,0 +1,15 @@ +// https://nodejs.org/api/fs.html +const fs = require("fs"); + +let contents = fs.readFileSync("test.txt"); + +console.log("Contents:"); +console.log(contents.toString()); + +// using a callback + +console.log("----------------------"); +fs.readFile("test.txt", (err, data) => { + console.log(data.toString()); +}); + diff --git a/ex09-files/test.txt b/ex09-files/test.txt new file mode 100644 index 0000000..8e2dd5b --- /dev/null +++ b/ex09-files/test.txt @@ -0,0 +1,4 @@ +I have a problem. +It's not a problem with you. +It's a problem with sleep. +And you have it too. diff --git a/ex10-files-args-variables-oh-my/code.js b/ex10-files-args-variables-oh-my/code.js new file mode 100644 index 0000000..8f5e9f9 --- /dev/null +++ b/ex10-files-args-variables-oh-my/code.js @@ -0,0 +1,10 @@ +// Exercise 10: Files, Args, Variables, Oh My + +const fs = require('fs'); + +let file_to_open = process.argv[2]; +let file_contents = fs.readFileSync(file_to_open); + +console.log(`The file named ${file_to_open} contains:`); +console.log(file_contents.toString()); + diff --git a/ex10-files-args-variables-oh-my/test.txt b/ex10-files-args-variables-oh-my/test.txt new file mode 100644 index 0000000..8e2dd5b --- /dev/null +++ b/ex10-files-args-variables-oh-my/test.txt @@ -0,0 +1,4 @@ +I have a problem. +It's not a problem with you. +It's a problem with sleep. +And you have it too. diff --git a/ex11-functions/code.js b/ex11-functions/code.js new file mode 100644 index 0000000..ff4ab1a --- /dev/null +++ b/ex11-functions/code.js @@ -0,0 +1,38 @@ +// Exercise 11: Functions + +const printPerson = (name, age) => { + console.log(`Hi ${name}, you are ${age} years old.`); +} + +printPerson('Zed', 44); +printPerson('Fran', 100); +printPerson('Alex', 30); +printPerson('Eve', 35); + +console.log('--------------- pets ----------------'); + +const printPet = (owner_name, owner_age, pet_name, pet_age) => { + printPerson(owner_name, owner_age); + console.log(`That person owns ${pet_name} who is ${pet_age} years old.`); +} + +printPet('Zed', 44, 'Mr. Scruffles', 10); +printPet('Fran', 100, 'Crazy', 2); +printPet('Alex', 30, 'Lizzy Lizard', 1); +printPet('Eve', 35, 'Kong The Donkey', 20); + + +// this part is tough! brain melting! give it a try +// +console.log('------------------ callback style ----------------'); + +const fancyPet = (owner_name, owner_age, pet_name, pet_age, cb) => { + cb(owner_name, owner_age); + console.log(`That person owns ${pet_name} who is ${pet_age} years old.`); +} + +// notice how I use a function here as the parameter cb? +fancyPet('Zed', 44, 'Mr. Scruffles', 10, (name, age) => { + console.log(`Ooooh fancy ${name} you are ${age} old.`); +}); + diff --git a/ex12-functions-files-variables/code.js b/ex12-functions-files-variables/code.js new file mode 100644 index 0000000..96ada40 --- /dev/null +++ b/ex12-functions-files-variables/code.js @@ -0,0 +1,23 @@ +// Exercise 12: Functions, Files, Variables + +const fs = require('fs'); + +const print_lines = (err, data) => { + console.log(data.toString()); +} + +const yell_at_me = (what) => { + return what.toUpperCase(); +} + +fs.readFile("poem.txt", print_lines); + +// let's do that again but with an anonymous function +// you've actually seen this before + +fs.readFile("poem.txt", (err, data) => { + let yelling = yell_at_me(data.toString()); + print_lines(err, yelling); +}); + + diff --git a/ex12-functions-files-variables/poem.txt b/ex12-functions-files-variables/poem.txt new file mode 100644 index 0000000..001f1cc --- /dev/null +++ b/ex12-functions-files-variables/poem.txt @@ -0,0 +1,7 @@ +The living light I once +could have progressed to vermilion +and concerned a compact miniscule +but no, that wasn't +it was this once in a million +terrible ways of broken chance + diff --git a/ex13-modules/code.js b/ex13-modules/code.js new file mode 100644 index 0000000..8fc0b5f --- /dev/null +++ b/ex13-modules/code.js @@ -0,0 +1,7 @@ +const geometry = require('./geometry'); + +let area51 = geometry.area(2.8); +let circ2 = geometry.circumference(6); + +console.log(`Area: ${area51}, Circumference: ${circ2}`); + diff --git a/ex13-modules/geometry.js b/ex13-modules/geometry.js new file mode 100644 index 0000000..31d88c4 --- /dev/null +++ b/ex13-modules/geometry.js @@ -0,0 +1,8 @@ +const area = (r) => Math.PI * r ** 2; +const circumference = (r) => 2 * Math.PI * r; + +module.exports = { + area: area, + circumference: circumference +} + diff --git a/ex15-if-and-else/code.js b/ex15-if-and-else/code.js new file mode 100644 index 0000000..7cda5c7 --- /dev/null +++ b/ex15-if-and-else/code.js @@ -0,0 +1,28 @@ +let x = 20; + +if (x === 10) { + console.log("x is equal to 10:", x); +} else if (x < 10) { + console.log("x is less than 10:", x); +} else { + console.log("x is greater than 10:", x); +} + +// consider this part a puzzle to solve +// what's the least number of times you have to change +// the code to make each console.log run? +let y = 100; + +if (y == 100) { + if(x < 10) { + console.log("log 1", x, y); + } else { + console.log("log 2", x, y); + } +} else { + if(x > 10) { + console.log("log 3", x, y); + } else { + console.log("log 4", x, y); + } +} diff --git a/ex16-while-loops/code.js b/ex16-while-loops/code.js new file mode 100644 index 0000000..00433e0 --- /dev/null +++ b/ex16-while-loops/code.js @@ -0,0 +1,18 @@ + +let count = 5; + +while(count > 0) { + console.log(`count down ${count}`); + count--; +} + +// what value is count right here? +while(count < 10) { + if(count % 2 == 0) { + console.log(count, "EVEN"); + } else { + console.log(count, "ODD"); + } + + count++; +} diff --git a/ex17-sequences-and-for-loops/all-loops.js b/ex17-sequences-and-for-loops/all-loops.js new file mode 100644 index 0000000..c6ba656 --- /dev/null +++ b/ex17-sequences-and-for-loops/all-loops.js @@ -0,0 +1,25 @@ + +let count = 5; +label1: +while(count > 0) { + console.log("in while", count); + if(count > 2) { + for(i = 0; i < 4; i++) { + console.log("in for", i); + if(i == 2) { + count--; + continue label1; + } + } + } else if(count == 2) { + count -= 2; + console.log("continue in while"); + continue label1; + } else { + break; + } + count--; +} + +label2: +console.log("Done."); diff --git a/ex17-sequences-and-for-loops/code.js b/ex17-sequences-and-for-loops/code.js new file mode 100644 index 0000000..d3ee436 --- /dev/null +++ b/ex17-sequences-and-for-loops/code.js @@ -0,0 +1,19 @@ +let pigments = ["perinone", "cadmium", + "titanium", "ultramarine", "napthol"]; + +let i = 0; +// you've seen this already +while(i < pigments.length) { + console.log(`while ${i}=${pigments[i]}`); + i++; +} + +// you can do the above in one move like this +for(let i = 0; i < pigments.length; i++) { + console.log(`for ${i}=${pigments[i]}`); +} + +// but this is the easiest of all +for(let paint of pigments) { + console.log(`for-of ${paint}`); +} diff --git a/ex18-more-arrays/code.js b/ex18-more-arrays/code.js new file mode 100644 index 0000000..1283456 --- /dev/null +++ b/ex18-more-arrays/code.js @@ -0,0 +1,18 @@ +exports.fruit = [ + ['Apples', 12, 'AAA'], ['Oranges', 1, 'B'], + ['Pears', 2, 'A'], ['Grapes', 14, 'UR']]; + +exports.cars = [ + ['Cadillac', ['Black', 'Big', 34500]], + ['Corvette', ['Red', 'Little', 1000000]], + ['Ford', ['Blue', 'Medium', 1234]], + ['BMW', ['White', 'Baby', 7890]] +]; + +exports.languages = [ + ['Python', ['Slow', ['Terrible', 'Mush']]], + ['JavaSCript', ['Moderate', ['Alright', 'Bizarre']]], + ['Perl6', ['Moderate', ['Fun', 'Weird']]], + ['C', ['Fast', ['Annoying', 'Dangerous']]], + ['Forth', ['Fast', ['Fun', 'Difficult']]], +]; diff --git a/ex19-data-objects/code.js b/ex19-data-objects/code.js new file mode 100644 index 0000000..f3fc6d7 --- /dev/null +++ b/ex19-data-objects/code.js @@ -0,0 +1,21 @@ +exports.fruit = [ + {kind: 'Apples', count: 12, rating: 'AAA'}, + {kind: 'Oranges', count: 1, rating: 'B'}, + {kind: 'Pears', count: 2, rating: 'A'}, + {kind: 'Grapes', count: 14, rating: 'UR'} +]; + +exports.cars = [ + {type: 'Cadillac', color: 'Black', size: 'Big', miles: 34500}, + {type: 'Corvette', color: 'Red', size: 'Little', miles: 1000000}, + {type: 'Ford', color: 'Blue', size: 'Medium', miles: 1234}, + {type: 'BMW', color: 'White', size: 'Baby', miles: 7890} +]; + +exports.languages = [ + {name: 'Python', speed: 'Slow', opinion: ['Terrible', 'Mush']}, + {name: 'JavaScript', speed: 'Moderate', opinion: ['Alright', 'Bizarre']}, + {name: 'Perl6', speed: 'Moderate', opinion: ['Fun', 'Weird']}, + {name: 'C', speed: 'Fast', opinion: ['Annoying', 'Dangerous']}, + {name: 'Forth', speed: 'Fast', opinion: ['Fun', 'Difficult']}, +]; diff --git a/ex20-first-game/code.js b/ex20-first-game/code.js new file mode 100644 index 0000000..48fab5d --- /dev/null +++ b/ex20-first-game/code.js @@ -0,0 +1,64 @@ +const readline = require('readline-sync'); + +const say = (prompt) => { + console.log(prompt); +} + +const die = (message) => { + say(message); + process.exit(1); +} + +const ask = (hp, prompt) => { + console.log(`[[You have ${hp} hit points.]]`); + if(hp <= 0) { + die("You died!"); + } else { + return readline.question(prompt + ' '); + } +} + +const door = (hp) => { + // they have to open the door to get the gold + // what kind of puzzle will they solve? +} + +const spider = (hp) => { + // they enter here, and the spider takes 10 hit points + // if they live then they can run away +} + +const gold = (hp) => { + // end of the game they win if they get the gold +} + +const rope = (hp) => { + // they are at the bottom of the well + // they can go through the door to the gold + // or go take a wrong turn to the spider +} + +const well = (hp) => { + say("You are walking through the woods and see a well."); + say("Walking up to it and looking down you see a shiny thing at the bottom."); + let next = ask(hp, "What do you do?"); + + if(next === "climb") { + say("You climb down the rope."); + rope(hp); + } else if(next === "jump") { + say("Yikes! Let's see if you survive!"); + hp = Math.floor(hp / 2); + rope(hp); + } else { + say("You can't do that here."); + well(hp); + } +} + +// setup hit points +let hp = Math.floor(Math.random() * 10) + 1; + +// this starts the game +well(hp) + diff --git a/ex21-simple-oop/alex.js b/ex21-simple-oop/alex.js new file mode 100644 index 0000000..badfa00 --- /dev/null +++ b/ex21-simple-oop/alex.js @@ -0,0 +1,4 @@ +// let's use that to make someone named alex +let alex = Person("Alex", 16, "green"); +// and see how they can talk without repetition? +alex.talk("Hi there!"); diff --git a/ex21-simple-oop/code.js b/ex21-simple-oop/code.js new file mode 100644 index 0000000..a5b5b44 --- /dev/null +++ b/ex21-simple-oop/code.js @@ -0,0 +1,52 @@ + +// data about a person named Frank +let frank = { + name: "Frank", + age: 34, + eyes: "blue" +} + +const frank_talk = (who, words) => { + console.log(`I am ${who.name} and ${words}.`); +} + +frank_talk(frank, "I am talking here!"); + +// working with that data by putting functions on it +let mary = { + name: "Mary", + age: 44, + eyes: "brown", + talk: (who, words) => { + console.log(`I am ${who.name} and ${words}.`); + } +} + +// this is kind of annoying though +mary.talk(mary, "these are some words"); +// and this works but that's weird +mary.talk(frank, "I am frank what?"); + +// we need a way to build these automatically +const Person = (name, age, eyes) => { + // this makes an obj for the data + let obj = { + name: name, + age: age, + eyes: eyes + } + + // then attach our function to it + obj.talk = (words) => { + // coolest part is obj here will keep a reference + console.log(`I am ${obj.name} and ${words}.`); + } + + // and return our new person + return obj; +} + +// let's use that to make someone named alex +let alex = Person("Alex", 16, "green"); +// and see how they can talk without repetition? +alex.talk("Hi there!"); diff --git a/ex21-simple-oop/frank.js b/ex21-simple-oop/frank.js new file mode 100644 index 0000000..b2742c8 --- /dev/null +++ b/ex21-simple-oop/frank.js @@ -0,0 +1,6 @@ +// data about a person named Frank +let frank = { + name: "Frank", + age: 34, + eyes: "blue" +} diff --git a/ex21-simple-oop/franktalk.js b/ex21-simple-oop/franktalk.js new file mode 100644 index 0000000..e390a9f --- /dev/null +++ b/ex21-simple-oop/franktalk.js @@ -0,0 +1,5 @@ +const frank_talk = (who, words) => { + console.log(`I am ${who.name} and ${words}.`); +} + +frank_talk(frank, "I am talking here!"); diff --git a/ex21-simple-oop/mary.js b/ex21-simple-oop/mary.js new file mode 100644 index 0000000..ea9a36d --- /dev/null +++ b/ex21-simple-oop/mary.js @@ -0,0 +1,9 @@ +// working with that data by putting functions on it +let mary = { + name: "Mary", + age: 44, + eyes: "brown", + talk: (who, words) => { + console.log(`I am ${who.name} and ${words}.`); + } +} diff --git a/ex21-simple-oop/marytalk.js b/ex21-simple-oop/marytalk.js new file mode 100644 index 0000000..9575ccc --- /dev/null +++ b/ex21-simple-oop/marytalk.js @@ -0,0 +1,4 @@ +// this is kind of annoying though +mary.talk(mary, "these are some words"); +// and this works but that's weird +mary.talk(frank, "I am frank what?"); diff --git a/ex21-simple-oop/person.js b/ex21-simple-oop/person.js new file mode 100644 index 0000000..9e0e998 --- /dev/null +++ b/ex21-simple-oop/person.js @@ -0,0 +1,18 @@ +// we need a way to build these automatically +const Person = (name, age, eyes) => { + // this makes an obj for the data + let obj = { + name: name, + age: age, + eyes: eyes + } + + // then attach our function to it + obj.talk = (words) => { + // coolest part is obj here will keep a reference + console.log(`I am ${obj.name} and ${words}.`); + } + + // and return our new person + return obj; +} diff --git a/ex22-more-complex-oop/code.js b/ex22-more-complex-oop/code.js new file mode 100644 index 0000000..e61949c --- /dev/null +++ b/ex22-more-complex-oop/code.js @@ -0,0 +1,21 @@ +class Person { + constructor (name, age, eyes) { + this.name = name; + this.age = age; + this.eyes = eyes; + } + + talk(words) { + console.log(`I am ${this.name} and ${words}.`); + } +} + +let alex = new Person("Alex", 16, "green"); +let mary = new Person("Mary", 44, "brown"); +let frank = new Person("Frank", 34, "blue"); + +frank.talk("I am talking here!"); +mary.talk("these are some words"); +alex.talk("Hi there!"); + +console.log(`Frank is ${frank.age}, Mary is ${mary.age}, Alex is ${alex.age}`); diff --git a/ex22-more-complex-oop/ex21.js b/ex22-more-complex-oop/ex21.js new file mode 100644 index 0000000..1a60943 --- /dev/null +++ b/ex22-more-complex-oop/ex21.js @@ -0,0 +1,23 @@ +const Person = (name, age, eyes) => { + let obj = { + name: name, + age: age, + eyes: eyes + } + + obj.talk = (words) => { + console.log(`I am ${obj.name} and ${words}.`); + } + + return obj; +} + +let alex = Person("Alex", 16, "green"); +let mary = Person("Mary", 44, "brown"); +let frank = Person("Frank", 34, "blue"); + +frank.talk("I am talking here!"); +mary.talk("these are some words"); +alex.talk("Hi there!"); + +console.log(`Frank is ${frank.age}, Mary is ${mary.age}, Alex is ${alex.age}`); diff --git a/ex23-inheritance/code.js b/ex23-inheritance/code.js new file mode 100644 index 0000000..1c649bd --- /dev/null +++ b/ex23-inheritance/code.js @@ -0,0 +1,61 @@ +class Guitar { + constructor (color, name, wood) { + this.color = color; + this.name = name; + this.wood = wood; + } + + play(note) { + console.log(`${this.name}:${this.color}:${this.wood} plays ${note}`); + } +} + +class Jazzmaster extends Guitar { + constructor (color, name, wood) { + super(color, name, wood); + this.volume = 0; + this.tone = 0; + } + + volume(level) { + this.volume = level; + } + + tone(level) { + this.tone = level; + } +} + +class BassVI extends Jazzmaster { + play(note) { + console.log(`${note}`); + } +} + +class Person { + constructor (name, age, eyes) { + this.name = name; + this.age = age; + } + + talk(words) { + console.log(`I am ${this.name} and ${words}.`); + } +} + +class Musician extends Person { + play(instrument, sheet_music) { + for(let note of sheet_music) { + instrument.play(note); + } + } +} + +let babbington = new Musician("Roy Babbington", 78); +let harris = new Musician("Jet Harris", 71); +let taliesin = new BassVI("red", "Taliesin"); +let golden = new BassVI("gold", "Golden Arm"); + +babbington.play(taliesin, ['a','b','c','d']); +harris.play(golden, ['a','b','c','d']); + diff --git a/ex24-oop-game/code.js b/ex24-oop-game/code.js new file mode 100644 index 0000000..bcd982d --- /dev/null +++ b/ex24-oop-game/code.js @@ -0,0 +1,107 @@ +const readline = require('readline-sync'); + +class Game { + constructor () { + this.hp = Math.floor(Math.random() * 10) + 1; + } + + say(prompt) { + console.log(prompt); + } + + die(message) { + this.say(message); + process.exit(1); + } + + ask(prompt) { + console.log(`[[You have ${this.hp} hit points.]]`); + if(this.hp <= 0) { + this.die("You died!"); + } else { + return readline.question(prompt + ' '); + } + } + + addRoom(room) { + this[room.name] = room; + room.game = this; + } + + play(name) { + this[name].enter(); + } + + hit(amount) { + this.hp -= amount; + } +} + +class Room { + constructor (name) { + this.name = name; + } + + enter() { + console.log("Implement me!"); + } +} + +class Door extends Room { + enter() { + // they have to open the door to get the gold + // what kind of puzzle will they solve? + } +} + +class Spider extends Room { + enter() { + // they enter here, and the spider takes 10 hit points + // if they live then they can run away + } +} + +class Gold extends Room { + enter() { + // end of the game they win if they get the gold + } +} + +class Rope extends Room { + enter() { + // they are at the bottom of the well + // they can go through the door to the gold + // or go take a wrong turn to the spider + } +} + +class Well extends Room { + + enter() { + this.game.say("You are walking through the woods and see a well."); + this.game.say("Walking up to it and looking down you see a shiny thing at the bottom."); + let next = this.game.ask("What do you do?"); + + if(next === "climb") { + this.game.say("You climb down the rope."); + this.game.rope.enter(); + } else if(next === "jump") { + this.game.say("Yikes! Let's see if you survive!"); + this.game.hit(5); + this.game.rope.enter(); + } else { + this.game.say("You can't do that here."); + this.game.well.enter(); + } + } +} + + +let game = new Game(); +game.addRoom(new Well("well")); +game.addRoom(new Rope("rope")); +game.addRoom(new Gold("gold")); +game.addRoom(new Spider("spider")); +game.addRoom(new Door("door")); +console.log(Object.entries(game)); +game.play("well"); diff --git a/ex25-functions-and-recursion/code.js b/ex25-functions-and-recursion/code.js new file mode 100644 index 0000000..1305c68 --- /dev/null +++ b/ex25-functions-and-recursion/code.js @@ -0,0 +1,25 @@ +// simple recursive counting function +const counter = (i, upto) => { + if(i < upto) { + console.log("counter", i, upto); + counter(i+1, upto); + } +} + +// use counter to just print out 1-5 +counter(1, 5); + +// a more complex counter that can call a callback +const cb_counter = (i, upto, cb) => { + if(i < upto) { + cb(i, upto); + cb_counter(i+1, upto, cb); + } +} + +// do the same thing but with a callback +cb_counter(1, 6, (i, j) => { + console.log(i, j) + }); + + diff --git a/ex26-transforming-data/code.js b/ex26-transforming-data/code.js new file mode 100644 index 0000000..88884e0 --- /dev/null +++ b/ex26-transforming-data/code.js @@ -0,0 +1,32 @@ +let pets = [ + {name: 'Yeller', type: 'Dog', age: 12}, + {name: 'Akumano', type: 'Japanese Bobtail Cat', age: 2}, + {name: 'Meaw Peesard', type: 'Siamese Cat', age: 100}, + {name: 'James', type: 'Gecko', age: 2}, +] + +let ages_only = pets.map(pet => pet.age); + +let total_age = ages_only.reduce((acc, age) => acc += age); + +let meaw = pets.find(pet => pet.name == 'Meaw Peesard'); + +let old_animals = pets.filter(pet => pet.age > 10); +let young_animals = pets.filter(pet => pet.age <= 10); + +console.log("Animal Ages:", ages_only); + +console.log("Total Age:", total_age); + +console.log("Meaw is:", meaw.age); + +console.log("\nOld Animals:"); +old_animals.forEach(pet => { + console.log(`\t${pet.name} is a ${pet.age} old ${pet.type}.`); +}); + +console.log("\nYoung Animals:"); +for(let pet of young_animals) { + console.log(`\t${pet.name} is a ${pet.age} old ${pet.type}.`); +} + diff --git a/ex27-applying-functions/code.js b/ex27-applying-functions/code.js new file mode 100644 index 0000000..25e2901 --- /dev/null +++ b/ex27-applying-functions/code.js @@ -0,0 +1,31 @@ +let pets = [ + {name: 'Yeller', type: 'Dog', age: 12}, + {name: 'Akumano', type: 'Japanese Bobtail Cat', age: 2}, + {name: 'Meaw Peesard', type: 'Siamese Cat', age: 100}, + {name: 'James', type: 'Gecko', age: 2}, +] + +const young_pets = (pet) => { + return pet.age <= 10; +} + +const age_pets = (pet) => { + return [pet.name, pet.age + 10]; +} + +const name_age = (pet) => { + return `${pet[0]} is ${pet[1]}`; +} + +const debug = (msg) => { + console.log(msg); + // why am I doing this here? + return msg; +} + +let age_young_animals = pets.filter(young_pets) + .map(age_pets) + .map(debug) // this is why + .map(name_age) + .forEach(debug); + diff --git a/ex28-scope-and-closures/closure.js b/ex28-scope-and-closures/closure.js new file mode 100644 index 0000000..2174d18 --- /dev/null +++ b/ex28-scope-and-closures/closure.js @@ -0,0 +1,20 @@ +// puzzle: how small can you make this? + +const build_adder = (left) => { + // do I really need this variable? + let left_hand = left; + return adder = (right) => { + // do I really need the return? + let result = left_hand + right; + return result; + } +} + +let add10 = build_adder(10); +let add20 = build_adder(20); + +console.log(`test builder 3 + 10 == ${add10(3)}`); +console.log(`test builder 3 + 20 == ${add20(3)}`); +console.log(`test builder 13 + 10 == ${add10(13)}`); +console.log(`test builder 3 + 10 + 20 == ${add10(add20(3))}`); + diff --git a/ex28-scope-and-closures/code.js b/ex28-scope-and-closures/code.js new file mode 100644 index 0000000..d45625c --- /dev/null +++ b/ex28-scope-and-closures/code.js @@ -0,0 +1,16 @@ +const var_sucks = () => { + var var_scope = 10; + let let_scope = 20; + + console.log(`>>> var_sucks before if: var=${var_scope}, let=${let_scope}`); + + if(true) { + var var_scope = 100; + let let_scope = 100; + console.log(`>>> var_sucks inside if: var=${var_scope}, let=${let_scope}`); + } + + console.log(`>>> var_sucks after if: var=${var_scope}, let=${let_scope}`); +} + +var_sucks(); diff --git a/ex29-partial-application/code.js b/ex29-partial-application/code.js new file mode 100644 index 0000000..8f8d3b9 --- /dev/null +++ b/ex29-partial-application/code.js @@ -0,0 +1,48 @@ +let pets = [ + {name: 'Yeller', type: 'Dog', age: 12}, + {name: 'Akumano', type: 'Japanese Bobtail Cat', age: 2}, + {name: 'Meaw Peesard', type: 'Siamese Cat', age: 100}, + {name: 'James', type: 'Gecko', age: 2}, +] + +const young_pets = (pet) => { + return pet.age <= 10; +} + +const age_pets = (pet) => { + return [pet.name, pet.age + 10]; +} + +const name_age = (pet) => { + return `${pet[0]} is ${pet[1]}`; +} + +const debug = (msg) => { + console.log(msg); + return msg; +} + +const tee = (result, data, cb) => { + const side = (input) => { + cb(input, result, data); + return input; + } + + return side; +} + +let owned_pets = []; +const add_owner_tee = tee(owned_pets, 'Zed', (i, r, d) => { + r.push({pet: i, owner: d}); +}); + +let age_young_animals = pets.filter(young_pets) + .map(add_owner_tee) + .map(age_pets) + .map(name_age); + +console.log("-- Pets with Owners:"); +owned_pets.forEach(debug); + +console.log("-- Young Animals:"); +age_young_animals.forEach(debug); diff --git a/ex30-promises-async-await/async.js b/ex30-promises-async-await/async.js new file mode 100644 index 0000000..765413a --- /dev/null +++ b/ex30-promises-async-await/async.js @@ -0,0 +1,16 @@ +let fs = require('fs').promises + +const read_file = async (fname) => { + try { + let file = await fs.open(fname, 'r'); + let stat = await file.stat(); + let buffer = Buffer.alloc(stat.size); + let result = await file.read(buffer, 0, stat.size, null); + console.log(`Read ${result.bytesRead} bytes: ${result.buffer.toString()}`); + } catch(err) { + console.log("ERROR", err); + } +} + +// see the async.mjs version +read_file('test.txt'); diff --git a/ex30-promises-async-await/async.mjs b/ex30-promises-async-await/async.mjs new file mode 100644 index 0000000..5aac7f2 --- /dev/null +++ b/ex30-promises-async-await/async.mjs @@ -0,0 +1,17 @@ +import { promises as fs } from "fs"; + +const read_file = async (fname) => { + try { + let file = await fs.open(fname, 'r'); + let stat = await file.stat(); + let buffer = Buffer.alloc(stat.size); + let result = await file.read(buffer, 0, stat.size, null); + console.log(`Read ${result.bytesRead} bytes: ${result.buffer.toString()}`); + } catch(err) { + console.log("ERROR", err); + } +} + +// This only works if your package.json has "type": "module", +// or if you name the file async.mjs. +await read_file('test.txt'); diff --git a/ex30-promises-async-await/cbhell.js b/ex30-promises-async-await/cbhell.js new file mode 100644 index 0000000..a31edd7 --- /dev/null +++ b/ex30-promises-async-await/cbhell.js @@ -0,0 +1,32 @@ +const fs = require('fs'); + +const read_file = (fname, cb) => { + fs.stat(fname, (err, stats) => { + if(err) { + cb(err, null); + } else { + fs.open(fname, 'r', (err, fd) => { + if(err) { + cb(err, null); + } else { + let inbuf = Buffer.alloc(stats.size); + fs.read(fd, inbuf, 0, stats.size, null, (err, bytesRead, buffer) => { + if(err) { + cb(err, null); + } else { + cb(err, buffer); + } + }); + } + }); + } + }); +} + +read_file('test.txt', (err, result) => { + if(err) { + console.log(err); + } else { + console.log(`Result is ${result.toString()}`); + } +}); diff --git a/ex30-promises-async-await/cbstart.js b/ex30-promises-async-await/cbstart.js new file mode 100644 index 0000000..89485bf --- /dev/null +++ b/ex30-promises-async-await/cbstart.js @@ -0,0 +1,16 @@ +const fs = require('fs'); + +const read_file = (fname, cb) => { + fs.stat(fname, (err, stats) => { + fs.open(fname, 'r', (err, fd) => { + let inbuf = Buffer.alloc(stats.size); + fs.read(fd, inbuf, 0, stats.size, null, (err, bytesRead, buffer) => { + cb(buffer); + }); + }); + }); +} + +read_file('test.txt', (result) => { + console.log(`Result is ${result.toString()}`); +}); diff --git a/ex30-promises-async-await/event.js b/ex30-promises-async-await/event.js new file mode 100644 index 0000000..390c2a4 --- /dev/null +++ b/ex30-promises-async-await/event.js @@ -0,0 +1,35 @@ +const fs = require('fs'); + +const read_file = (fname, events) => { + let noop = () => {}; + let onStat = events.onStat || noop; + let onOpen = events.onOpen || noop; + let onRead = events.onRead || noop; + + fs.stat(fname, (err, stats) => { + onStat(stats); + + fs.open(fname, 'r', (err, fd) => { + onOpen(fd); + let inbuf = Buffer.alloc(stats.size); + + fs.read(fd, inbuf, 0, stats.size, null, (err, bytesRead, buffer) => { + onRead(bytesRead, buffer); + }); + }); + }); +} + +read_file('test.txt', { + onRead: (bytesRead, buffer) => { + console.log(`Read ${bytesRead} bytes: ${buffer.toString()}`); + }, + onStat: (stat) => { + console.log(`Got stats, file is ${stat.size} size.`); + }, + onOpen: (fd) => { + console.log(`Open worked, fd is ${fd}`); + } +}); + + diff --git a/ex30-promises-async-await/eventhell.js b/ex30-promises-async-await/eventhell.js new file mode 100644 index 0000000..253f3b3 --- /dev/null +++ b/ex30-promises-async-await/eventhell.js @@ -0,0 +1,50 @@ +const fs = require('fs'); + +const read_file = (fname, events) => { + let noop = () => {}; + let onError = events.onError || noop; + let onStat = events.onStat || noop; + let onOpen = events.onOpen || noop; + let onRead = events.onRead || noop; + + fs.stat(fname, (err, stats) => { + + if(err) { + onError(err); + } else { + onStat(stats); + + fs.open(fname, 'r', (err, fd) => { + if(err) { + onError(err); + } else { + onOpen(fd); + let inbuf = Buffer.alloc(stats.size); + + fs.read(fd, inbuf, 0, stats.size, null, (err, bytesRead, buffer) => { + if(err) { + onError(err); + } else { + onRead(bytesRead, buffer); + } + }); + } + }); + } + }); +} + +read_file('test.txt', { + onRead: (bytesRead, buffer) => { + console.log(`Read ${bytesRead} bytes: ${buffer.toString()}`); + }, + onStat: (stat) => { + console.log(`Got stats, file is ${stat.size} size.`); + }, + onOpen: (fd) => { + console.log(`Open worked, fd is ${fd}`); + }, + onError: (err) => { + console.error(err); + } +}); diff --git a/ex30-promises-async-await/promise_clean.js b/ex30-promises-async-await/promise_clean.js new file mode 100644 index 0000000..d43849a --- /dev/null +++ b/ex30-promises-async-await/promise_clean.js @@ -0,0 +1,50 @@ +// all promise docs I could find fail to mention this feature +// they all say (correctly) that if you return a value from a .then it becomes the +// next .then callback parameter: + +let test2 = new Promise((res, rej) => { + res(3); +}).then(x => [x, x + 4]).then(x => [x, x[1] + 5]); + +let res2 = test2.then(x => console.log("Then after math", x)); + +// this produces: +// Then after math [ [ 3, 7 ], 12 ] + + +// Ok, but if your .then returns a promise, why does it become the next promise but +// not the next promise. Watch. +let outer_promise = new Promise((res, rej) => { + res(1); +}); + +// now I'm going to return this one in first_then +let inner_promise = new Promise((res, rej) => { + console.log("inner promise running"); + res("INNER_PROMISE"); +}); + +// log the parameter so you can see it's 1 +let first_then = outer_promise.then(x => { + console.log("first_then", x); + return inner_promise; // return the pomise here +}); + +// at this point you would expect x to == inner_promise, but instead it will equal "INNER PROMISE" +let last_then = first_then.then(x => { + // wtf? ok so then that means when I call first_then.then I should be working on inner_promise right? + console.log("first_then === outer_promise", first_then === outer_promise); + console.log("first_then === inner_promise", first_then === inner_promise); + console.log("first_then === last_then", first_then === last_then); + console.log("first_then === first_then", first_then === first_then); + + // no, not only is it using inner_promise as the next .then, it's wrapping inner_promise with a promise so + // that my call to .then is going through...two promises? Wtf? + // The expectation is that first_then === inner_promise since I returned that but instead it's a whole other 3rd + // promise adding a layer to the layer. + + // and here's the value "INNER_PROMISE", not a inner_promise like I returned. + console.log("Then after promise", x); +}); + + diff --git a/ex30-promises-async-await/promises.js b/ex30-promises-async-await/promises.js new file mode 100644 index 0000000..77d7679 --- /dev/null +++ b/ex30-promises-async-await/promises.js @@ -0,0 +1,20 @@ +const fs = require('fs').promises; + +// you have to do nested calls any time you need the result of the previous calculation + +const read_file = (fname) => { + fs.open(fname, 'r').then((fh) => { + fh.stat().then((stat) => { + let buf = Buffer.alloc(stat.size); + + fh.read(buf, 0, stat.size, null) + .then((result) => { + console.log(`Read ${result.bytesRead} bytes: ${result.buffer.toString()}`); + }).catch((err) => { + console.error(err); + }); + }).catch((err) => console.error(err)); + }).catch((err) => console.error(err)); +} + +read_file('test.txt'); diff --git a/ex30-promises-async-await/promises_fixed.js b/ex30-promises-async-await/promises_fixed.js new file mode 100644 index 0000000..7b538a5 --- /dev/null +++ b/ex30-promises-async-await/promises_fixed.js @@ -0,0 +1,12 @@ +const fs = require('fs').promises; + +const read_file = (fname) => + fs.open(fname, 'r') + .then(fh => fh.stat().then(stat => [fh, stat])) + .then(res => + res[0].read(Buffer.alloc(res[1].size), 0, res[1].size, null)) + .then(result => + console.log(`Read ${result.bytesRead} bytes: ${result.buffer.toString()}`)) + .catch(err => console.error(err)) + +read_file('test.txt'); diff --git a/ex30-promises-async-await/test.txt b/ex30-promises-async-await/test.txt new file mode 100644 index 0000000..9524014 --- /dev/null +++ b/ex30-promises-async-await/test.txt @@ -0,0 +1 @@ +I am a small file. diff --git a/ex30-promises-async-await/topromise.js b/ex30-promises-async-await/topromise.js new file mode 100644 index 0000000..9bcb1e7 --- /dev/null +++ b/ex30-promises-async-await/topromise.js @@ -0,0 +1,9 @@ +const sleeper = (timeout) => { + return new Promise((resolve, reject) => { + setTimeout(() => resolve('DONE'), timeout); + }); +} + +let wait1 = sleeper(100); +wait1.then(x => console.log("Done.", x)); + diff --git a/ex31-modules-and-import/code.js b/ex31-modules-and-import/code.js new file mode 100644 index 0000000..2020597 --- /dev/null +++ b/ex31-modules-and-import/code.js @@ -0,0 +1,6 @@ +import geometry from "./geometry.mjs"; + +let area51 = geometry.area(2.8); +let circ2 = geometry.circumference(6); + +console.log(`Area: ${area51}, Circumference: ${circ2}`); diff --git a/ex31-modules-and-import/code.mjs b/ex31-modules-and-import/code.mjs new file mode 100644 index 0000000..2020597 --- /dev/null +++ b/ex31-modules-and-import/code.mjs @@ -0,0 +1,6 @@ +import geometry from "./geometry.mjs"; + +let area51 = geometry.area(2.8); +let circ2 = geometry.circumference(6); + +console.log(`Area: ${area51}, Circumference: ${circ2}`); diff --git a/ex31-modules-and-import/ex13_code.js b/ex31-modules-and-import/ex13_code.js new file mode 100644 index 0000000..8fc0b5f --- /dev/null +++ b/ex31-modules-and-import/ex13_code.js @@ -0,0 +1,7 @@ +const geometry = require('./geometry'); + +let area51 = geometry.area(2.8); +let circ2 = geometry.circumference(6); + +console.log(`Area: ${area51}, Circumference: ${circ2}`); + diff --git a/ex31-modules-and-import/ex13_geometry.js b/ex31-modules-and-import/ex13_geometry.js new file mode 100644 index 0000000..31d88c4 --- /dev/null +++ b/ex31-modules-and-import/ex13_geometry.js @@ -0,0 +1,8 @@ +const area = (r) => Math.PI * r ** 2; +const circumference = (r) => 2 * Math.PI * r; + +module.exports = { + area: area, + circumference: circumference +} + diff --git a/ex31-modules-and-import/geometry.mjs b/ex31-modules-and-import/geometry.mjs new file mode 100644 index 0000000..7ad5bc3 --- /dev/null +++ b/ex31-modules-and-import/geometry.mjs @@ -0,0 +1,7 @@ +export const area = (r) => Math.PI * r ** 2; +export const circumference = (r) => 2 * Math.PI * r; + +export default { + area, + circumference +}