Add initial code listings

This commit is contained in:
Michael Hartl
2022-01-12 14:58:42 -08:00
commit f2ddca9d3c
142 changed files with 1937 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Learn Enough JavaScript</title>
<meta charset="utf-8">
</head>
<body>
<h1>Hello, world!</h1>
<p>This page includes an alert written in JavaScript.</p>
</body>
</html>
+14
View File
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Learn Enough JavaScript</title>
<meta charset="utf-8">
<script>
alert("hello, world!");
</script>
</head>
<body>
<h1>Hello, world!</h1>
<p>This page includes an alert written in JavaScript.</p>
</body>
</html>
+1
View File
@@ -0,0 +1 @@
> console.log("hello, world!");
+2
View File
@@ -0,0 +1,2 @@
$ node
>
+1
View File
@@ -0,0 +1 @@
console.log("hello, world!");
+1
View File
@@ -0,0 +1 @@
console.log("hello, world!", "how's it going?");
+3
View File
@@ -0,0 +1,3 @@
#!/usr/local/bin/node
console.log("hello, world!");
+12
View File
@@ -0,0 +1,12 @@
#!/usr/local/bin/node
let fs = require("fs");
let Phrase = require("<username>-palindrome");
let text = fs.readFileSync("phrases.txt", "utf-8");
text.split("\n").forEach(function(line) {
let phrase = new Phrase(line);
if (phrase.palindrome()) {
console.log("palindrome detected:", line);
}
});
+11
View File
@@ -0,0 +1,11 @@
var urllib = require('urllib');
urllib.request('http://cnodejs.org/', function (err, data, res) {
if (err) {
throw err; // you need to handle error
}
console.log(res.statusCode);
console.log(res.headers);
// data is Buffer instance
console.log(data.toString());
});
+16
View File
@@ -0,0 +1,16 @@
#!/usr/local/bin/node
let urllib = require("urllib");
let Phrase = require("mhartl-palindrome");
let url = 'https://cdn.learnenough.com/phrases.txt'
urllib.request(url, { followRedirect: true }, function(error, data, response) {
let body = data.toString();
body.split("\n").forEach(function(line) {
let phrase = new Phrase(line);
if (phrase.palindrome()) {
console.log("palindrome detected:", line);
}
});
});
+15
View File
@@ -0,0 +1,15 @@
#!/usr/local/bin/node
let urllib = require("urllib");
let Phrase = require("<username>-palindrome");
let url = 'https://cdn.learnenough.com/phrases.txt'
urllib.request(url, { followRedirect: true }, function(error, data, response) {
let body = data.toString();
let lines = body.split("\n");
let palindromes = lines.filter(line => /* FILL IN */);
palindromes.forEach(function(palindrome) {
console.log("palindrome detected:", palindrome);
});
});
+8
View File
@@ -0,0 +1,8 @@
#!/usr/local/bin/node
// Returns the paragraphs from a Wikipedia link, stripped of reference numbers.
let urllib = require("urllib");
let url = process.argv[2];
console.log(url);
+9
View File
@@ -0,0 +1,9 @@
#!/usr/local/bin/node
// Returns the paragraphs from a Wikipedia link, stripped of reference numbers.
let urllib = require("urllib");
let url = process.argv[2];
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
+15
View File
@@ -0,0 +1,15 @@
#!/usr/local/bin/node
// Returns the paragraphs from a Wikipedia link, stripped of reference numbers.
let urllib = require("urllib");
let url = process.argv[2];
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
urllib.request(url, { followRedirect: true }, function(error, data, response) {
let body = data.toString();
// Simulate a Document Object Model.
let { document } = (new JSDOM(body)).window;
});
+19
View File
@@ -0,0 +1,19 @@
#!/usr/local/bin/node
// Returns the paragraphs from a Wikipedia link, stripped of reference numbers.
let urllib = require("urllib");
let url = process.argv[2];
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
urllib.request(url, { followRedirect: true }, function(error, data, response) {
let body = data.toString();
// Simulate a Document Object Model.
let { document } = (new JSDOM(body)).window;
// Grab all the paragraphs and references.
let paragraphs = document.querySelectorAll("p");
let references = document.querySelectorAll(".reference");
});
+29
View File
@@ -0,0 +1,29 @@
#!/usr/local/bin/node
// Returns the paragraphs from a Wikipedia link, stripped of reference numbers.
let urllib = require("urllib");
let url = process.argv[2];
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
urllib.request(url, { followRedirect: true }, function(error, data, response) {
let body = data.toString();
// Simulate a Document Object Model.
let { document } = (new JSDOM(body)).window;
// Grab all the paragraphs and references.
let paragraphs = document.querySelectorAll("p");
let references = document.querySelectorAll(".reference");
// Remove any references.
references.forEach(function(reference) {
reference.remove();
});
// Print out all of the paragraphs.
paragraphs.forEach(function(paragraph) {
console.log(paragraph.textContent);
});
});
+3
View File
@@ -0,0 +1,3 @@
function activateGallery() {
alert("Hello from the gallery file!");
}
+31
View File
@@ -0,0 +1,31 @@
// Activates the image gallery.
// The main task is to attach an event listener to each image in the gallery
// and respond appropriately on click.
function activateGallery() {
let thumbnails = document.querySelectorAll("#gallery-thumbs > div > img");
let mainImage = document.querySelector("#gallery-photo img");
thumbnails.forEach(function(thumbnail) {
// Preload large images.
let newImageSrc = thumbnail.dataset.largeVersion;
let largeVersion = new Image();
largeVersion.src = FILL_IN;
thumbnail.addEventListener("click", function() {
// Set clicked image as display image.
mainImage.setAttribute("src", newImageSrc);
// Change which image is current.
document.querySelector(".current").classList.remove("current");
thumbnail.parentNode.classList.add("current");
// Update image info.
let galleryInfo = document.querySelector("#gallery-info");
let title = galleryInfo.querySelector(".title");
let description = galleryInfo.querySelector(".description");
title.innerHTML = thumbnail.dataset.title;
description.innerHTML = thumbnail.dataset.description;
});
});
}
+13
View File
@@ -0,0 +1,13 @@
<head>
.
.
.
<link rel="stylesheet" href="/css/main.css">
<script src="/js/gallery.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
activateGallery();
});
</script>
</head>
+33
View File
@@ -0,0 +1,33 @@
---
layout: default
title: Gallery for Learn Enough JavaScript to Be Dangerous
---
<div class="gallery col-three">
<div class="col col-nav gallery-thumbs" id="gallery-thumbs">
<div class="current">
<img src="/images/small/beach.jpg" alt="Venice Beach"
data-large-version="/images/large/beach.jpg"
data-title="Venice Beach"
data-description="An overhead shot of Venice Beach, California.">
</div>
.
.
.
<div>
<img src="/images/small/turtle.jpg" alt="turtle"
data-large-version="/images/large/turtle.jpg"
data-title="Sea Turtle"
data-description="A friendly sea turtle.">
</div>
</div>
<div class="col col-content">
<div class="gallery-photo" id="gallery-photo">
<img src="/images/large/boat.jpg" alt="Catamaran">
</div>
</div>
<div class="col col-aside gallery-info" id="gallery-info">
<h3 class="title">Pacific Sunset</h3>
<p class="description">A sunset over the Pacific Ocean.</p>
</div>
</div>
+16
View File
@@ -0,0 +1,16 @@
// Activates the image gallery.
// The main task is to attach an event listener to each image in the gallery
// and respond appropriately on click.
function activateGallery() {
let thumbnails = document.querySelector("#gallery-thumbs").
querySelectorAll("img");
let mainImage = document.querySelector("#gallery-photo img");
thumbnails.forEach(function(thumbnail) {
thumbnail.addEventListener("click", function() {
// Set clicked image as main image.
let newImageSrc = thumbnail.dataset.largeVersion;
mainImage.setAttribute("src", newImageSrc);
});
});
}
+17
View File
@@ -0,0 +1,17 @@
// Activates the image gallery.
// The main task is to attach an event listener to each image in the gallery
// and respond appropriately on click.
function activateGallery() {
let thumbnails = document.querySelector("#gallery-thumbs").
querySelectorAll("img");
let mainImage = document.querySelector("#gallery-photo img");
thumbnails.forEach(function(thumbnail) {
thumbnail.addEventListener("click", function() {
// Set clicked image as main image.
let newImageSrc = thumbnail.dataset.largeVersion;
mainImage.setAttribute("src", newImageSrc);
mainImage.setAttribute("alt", FILL_IN);
});
});
}
+10
View File
@@ -0,0 +1,10 @@
// Activates the image gallery.
// The main task is to attach an event listener to each image in the gallery
// and respond appropriately on click.
function activateGallery() {
let thumbnails = document.querySelectorAll("#gallery-thumbs > ??? > ???");
let mainImage = document.querySelector("#gallery-photo img");
.
.
.
}
+19
View File
@@ -0,0 +1,19 @@
// Activates the image gallery.
// The main task is to attach an event listener to each image in the gallery
// and respond appropriately on click.
function activateGallery() {
let thumbnails = document.querySelectorAll("#gallery-thumbs > div > img");
let mainImage = document.querySelector("#gallery-photo img");
thumbnails.forEach(function(thumbnail) {
thumbnail.addEventListener("click", function() {
// Set clicked image as display image.
let newImageSrc = thumbnail.dataset.largeVersion;
mainImage.setAttribute("src", newImageSrc);
// Change which image is current.
document.querySelector(".current").classList.remove("current");
thumbnail.parentNode.classList.add("current");
});
});
}
+27
View File
@@ -0,0 +1,27 @@
// Activates the image gallery.
// The main task is to attach an event listener to each image in the gallery
// and respond appropriately on click.
function activateGallery() {
let thumbnails = document.querySelectorAll("#gallery-thumbs > div > img");
let mainImage = document.querySelector("#gallery-photo img");
// Image info to be updated
let galleryInfo = document.querySelector("#gallery-info");
let title = galleryInfo.querySelector(".title");
let description = galleryInfo.querySelector(".description");
thumbnails.forEach(function(thumbnail) {
thumbnail.addEventListener("click", function() {
// Set clicked image as display image.
let newImageSrc = thumbnail.dataset.largeVersion;
mainImage.setAttribute("src", newImageSrc);
// Change which image is current.
document.querySelector(".current").classList.remove("current");
thumbnail.parentNode.classList.add("current");
// Update image info.
title.innerHTML = thumbnail.dataset.title;
description.innerHTML = thumbnail.dataset.description;
});
});
}
+27
View File
@@ -0,0 +1,27 @@
---
layout: default
title: Gallery for Learn Enough JavaScript to Be Dangerous
---
<div class="gallery col-three">
<div class="col col-nav gallery-thumbs" id="gallery-thumbs">
<div class="current">
<img src="/images/small/beach.jpg" alt="Venice Beach"
data-large-version="/images/large/beach.jpg"
data-title="Venice Beach"
data-description="An overhead shot of Venice Beach, California.">
</div>
.
.
.
</div>
<div class="col col-content">
<div class="gallery-photo" id="gallery-photo">
<img src="/images/large/beach.jpg" alt="Venice Beach">
</div>
</div>
<div class="col col-aside gallery-info" id="gallery-info">
<h3 class="title">Venice Beach</h3>
<p class="description">An overhead shot of Venice Beach, California.</p>
</div>
</div>
+2
View File
@@ -0,0 +1,2 @@
> let firstName = "Michael";
> let lastName = "Hartl";
+8
View File
@@ -0,0 +1,8 @@
> true || true
true
> true || false
true
> false || true
true
> false || false
false
+6
View File
@@ -0,0 +1,6 @@
> if (x.length === 0 || y.length === 0) {
"At least one of the strings is empty!";
} else {
"Neither of the strings is empty.";
}
'At least one of the strings is empty!'
+4
View File
@@ -0,0 +1,4 @@
> !true
false
> !false
true
+6
View File
@@ -0,0 +1,6 @@
> if (!(x.length === 0)) {
"x is not empty.";
} else {
"x is empty.";
}
'x is not empty.'
+6
View File
@@ -0,0 +1,6 @@
> if (!x && !y) {
"Both strings are empty!";
} else {
"At least one of the strings is nonempty.";
}
'At least one of the strings is nonempty.'
+13
View File
@@ -0,0 +1,13 @@
> let soliloquy = "To be, or not to be, that is the question:";
> soliloquy.includes("To be"); // Does it include the substring "To be"?
true
> soliloquy.includes("question"); // What about "question"?
true
> soliloquy.includes("nonexistent"); // This string doesn't appear.
false
> soliloquy.includes("TO BE"); // String inclusion is case-sensitive.
false
> soliloquy.includes("To be", 1); // Can you guess what this one means?
false
> soliloquy.includes("o be,", 1); // A hint for the previous one
true
+8
View File
@@ -0,0 +1,8 @@
> console.log(soliloquy); // Just a reminder of what the string is
To be, or not to be, that is the question:
> soliloquy.charAt(0);
'T'
> soliloquy.charAt(1);
'o'
> soliloquy.charAt(2);
' '
+8
View File
@@ -0,0 +1,8 @@
> for (let i = 0; i < 5; i++) {
console.log(i);
}
0
1
2
3
4
+16
View File
@@ -0,0 +1,16 @@
> for (let i = 0; i < soliloquy.length; i++) {
console.log(soliloquy.charAt(i));
}
T
o
b
e
.
.
.
t
i
o
n
:
+2
View File
@@ -0,0 +1,2 @@
> firstName + " " + lastName;
'Michael Hartl'
+2
View File
@@ -0,0 +1,2 @@
var firstName = "Michael";
var lastName = "Hartl";
+4
View File
@@ -0,0 +1,4 @@
> firstName + " " + lastName; // Concatenation, with a space in between
'Michael Hartl'
> `${firstName} ${lastName}`; // The equivalent interpolation
'Michael Hartl'
+15
View File
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Learn Enough JavaScript</title>
<meta charset="utf-8">
<script>
alert("hello, world!");
console.log("This page contains a friendly greeting.");
</script>
</head>
<body>
<h1>Hello, world!</h1>
<p>This page includes an alert written in JavaScript.</p>
</body>
</html>
+5
View File
@@ -0,0 +1,5 @@
> let password = "foo";
> if (password.length < 6) {
"Password is too short.";
}
'Password is too short.'
+7
View File
@@ -0,0 +1,7 @@
> password = "foobar";
> if (password.length < 6) {
"Password is too short.";
} else {
"Password is long enough.";
}
'Password is long enough.'
+8
View File
@@ -0,0 +1,8 @@
> true && true
true
> false && true
false
> true && false
false
> false && false
false
+8
View File
@@ -0,0 +1,8 @@
> let x = "foo";
> let y = "";
> if (x.length === 0 && y.length === 0) {
"Both strings are empty!";
} else {
"At least one of the strings is nonempty.";
}
'At least one of the strings is nonempty.'
+6
View File
@@ -0,0 +1,6 @@
> a[0];
'b'
> a[1];
'a'
> a[2];
'd'
+10
View File
@@ -0,0 +1,10 @@
> a = ["ant", "bat", "cat", 42];
[ 'ant', 'bat', 'cat', 42 ]
> a.join(); // Join on default (comma).
'ant,bat,cat,42'
> a.join(", "); // Join on comma-space.
'ant, bat, cat, 42'
> a.join(" -- "); // Join on double dashes.
'ant -- bat -- cat -- 42'
> a.join(""); // Join on empty space.
'antbatcat42'
+16
View File
@@ -0,0 +1,16 @@
> for (let i = 0; i < soliloquy.length; i++) {
console.log(soliloquy[i]);
}
T
o
b
e
.
.
.
t
i
o
n
:
+7
View File
@@ -0,0 +1,7 @@
> for (let i = 0; i < a.length; i++) {
console.log(a[i]);
}
ant
bat
cat
42
+4
View File
@@ -0,0 +1,4 @@
> let total = "";
> for (let i = 0; i < a.length; i++) {
// set total equal to the running total plus the current element
}
+17
View File
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>Learn Enough JavaScript</title>
<meta charset="utf-8">
<script>
const daysOfTheWeek = ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"];
let now = new Date();
let dayName = daysOfTheWeek[now.getDay()];
alert(`Hello, world! Happy ${dayName}.`);
</script>
</head>
<body>
</body>
</html>
+14
View File
@@ -0,0 +1,14 @@
> const sonnet = `Let me not to the marriage of true minds
Admit impediments. Love is not love
Which alters when it alteration finds,
Or bends with the remover to remove.
O no, it is an ever-fixed mark
That looks on tempests and is never shaken;
It is the star to every wand'ring bark,
Whose worth's unknown, although his height be taken.
Love's not time's fool, though rosy lips and cheeks
Within his bending sickle's compass come:
Love alters not with his brief hours and weeks,
But bears it out even to the edge of doom.
If this be error and upon me proved,
I never writ, nor no man ever loved.`;
+7
View File
@@ -0,0 +1,7 @@
> user;
{ firstName: 'Michael', lastName: 'Hartl' }
> let otherUser = { firstName: 'Foo', lastName: 'Bar' };
> otherUser["firstName"];
'Foo'
> otherUser["lastName"];
'Bar'
+14
View File
@@ -0,0 +1,14 @@
const sonnet = `Let me not to the marriage of true minds
Admit impediments. Love is not love
Which alters when it alteration finds,
Or bends with the remover to remove.
O no, it is an ever-fixed mark
That looks on tempests and is never shaken;
It is the star to every wand'ring bark,
Whose worth's unknown, although his height be taken.
Love's not time's fool, though rosy lips and cheeks
Within his bending sickle's compass come:
Love alters not with his brief hours and weeks,
But bears it out even to the edge of doom.
If this be error and upon me proved,
I never writ, nor no man ever loved.`;
+17
View File
@@ -0,0 +1,17 @@
const sonnet = `Let me not to the marriage of true minds
Admit impediments. Love is not love
Which alters when it alteration finds,
Or bends with the remover to remove.
O no, it is an ever-fixed mark
That looks on tempests and is never shaken;
It is the star to every wand'ring bark,
Whose worth's unknown, although his height be taken.
Love's not time's fool, though rosy lips and cheeks
Within his bending sickle's compass come:
Love alters not with his brief hours and weeks,
But bears it out even to the edge of doom.
If this be error and upon me proved,
I never writ, nor no man ever loved.`;
let uniques = {};
let words = sonnet.match(/\w+/g);
+31
View File
@@ -0,0 +1,31 @@
const sonnet = `Let me not to the marriage of true minds
Admit impediments. Love is not love
Which alters when it alteration finds,
Or bends with the remover to remove.
O no, it is an ever-fixed mark
That looks on tempests and is never shaken;
It is the star to every wand'ring bark,
Whose worth's unknown, although his height be taken.
Love's not time's fool, though rosy lips and cheeks
Within his bending sickle's compass come:
Love alters not with his brief hours and weeks,
But bears it out even to the edge of doom.
If this be error and upon me proved,
I never writ, nor no man ever loved.`;
// Unique words
let uniques = {};
// All words in the text
let words = sonnet.match(/\w+/g);
// Iterate through `words` and build up an associative array of unique words.
for (let i = 0; i < words.length; i++) {
let word = words[i];
if (uniques[word]) {
uniques[word] += 1;
} else {
uniques[word] = 1;
}
}
console.log(uniques)
+9
View File
@@ -0,0 +1,9 @@
> function numberCompare(a, b) {
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
+10
View File
@@ -0,0 +1,10 @@
// Reverses a string.
function reverse(string) {
return string.split("").reverse().join("");
}
// Returns true for a palindrome, false otherwise.
function palindrome(string) {
let processedContent = string.toLowerCase();
return processedContent === reverse(processedContent);
}
+10
View File
@@ -0,0 +1,10 @@
// Reverses a string.
function reverse(string) {
return Array.from(string).reverse().join("")
}
// Returns true for a palindrome, false otherwise.
function palindrome(string) {
let processedContent = string.toLowerCase();
return processedContent === reverse(processedContent);
}
+3
View File
@@ -0,0 +1,3 @@
> function emailParts(email) {
// FILL IN
}
+4
View File
@@ -0,0 +1,4 @@
let a = ["ant", "bat", "cat", 42];
a.forEach(function(element) {
console.log(element);
});
+5
View File
@@ -0,0 +1,5 @@
$ node foreach.js
ant
cat
bat
42
+7
View File
@@ -0,0 +1,7 @@
.
.
.
let soliloquy = "To be, or not to be, that is the question:";
Array.from(soliloquy).forEach(function(character) {
console.log(character);
});
+18
View File
@@ -0,0 +1,18 @@
$ node foreach.js
ant
bat
cat
42
T
o
b
e
.
.
.
t
i
o
n
:
+3
View File
@@ -0,0 +1,3 @@
> let a = [8, 17, 42, 99];
> a.sort(function(a, b) { return a - b; });
[ 8, 17, 42, 99 ]
+23
View File
@@ -0,0 +1,23 @@
% const sonnet = `Let me not to the marriage of true minds
% .
% .
% .
% But bears it out even to the edge of doom.
% If this be error and upon me proved,
% I never writ, nor no man ever loved.`;
% // Unique words.
% let uniques = {};
% // All words in the text
% let words = sonnet.match(/[\w']+/g);
% // Iterate through `words` and build up a hash of unique words.
% words.forEach(function(word) {
% if (uniques[word]) {
% uniques[word] += 1;
% } else {
% uniques[word] = 1;
% }
% });
% console.log(uniques)
+6
View File
@@ -0,0 +1,6 @@
% .
% .
% .
% for (let word in uniques) {
% console.log(`"${word}" appears ${uniques[word]} time(s)`);
% }
+20
View File
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>Learn Enough JavaScript</title>
<meta charset="utf-8">
<script>
function dayName(date) {
const daysOfTheWeek = ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"];
return daysOfTheWeek[date.getDay()];
}
let now = new Date();
alert(`Hello, world! Happy ${dayName(now)}.`);
</script>
</head>
<body>
</body>
</html>
+6
View File
@@ -0,0 +1,6 @@
// Returns the day of the week for the given date.
function dayName(date) {
const daysOfTheWeek = ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"];
return daysOfTheWeek[date.getDay()];
}
+14
View File
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Learn Enough JavaScript</title>
<meta charset="utf-8">
<script>
let now = new Date();
alert(`Hello, world! Happy ${dayName(now)}!`);
</script>
</head>
<body>
</body>
</html>
+15
View File
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Learn Enough JavaScript</title>
<meta charset="utf-8">
<script src="day.js"></script>
<script>
let now = new Date();
alert(`Hello, world! Happy ${dayName(now)}!`);
</script>
</head>
<body>
</body>
</html>
+11
View File
@@ -0,0 +1,11 @@
// Returns the day of the week for the given date.
function dayName(date) {
const daysOfTheWeek = ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"];
return daysOfTheWeek[date.getDay()];
}
// Returns a greeting for the given date.
function greeting(date) {
// FILL IN
}
+15
View File
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Learn Enough JavaScript</title>
<meta charset="utf-8">
<script src="day.js"></script>
<script>
let now = new Date();
alert(greeting(now));
</script>
</head>
<body>
</body>
</html>
+4
View File
@@ -0,0 +1,4 @@
// Reverses a string.
function reverse(string) {
return string.split("").reverse().join("");
}
+9
View File
@@ -0,0 +1,9 @@
// Reverses a string.
function reverse(string) {
return string.split("").reverse().join("");
}
// Returns true for a palindrome, false otherwise.
function palindrome(string) {
return string === reverse(string);
}
+11
View File
@@ -0,0 +1,11 @@
let states = ["Kansas", "Nebraska", "North Dakota", "South Dakota"];
// urls: Imperative version
function imperativeUrls(elements) {
let urls = [];
elements.forEach(function(element) {
urls.push(element.toLowerCase().split(/\s+/).join("-"));
});
return urls;
}
console.log(imperativeUrls(states));
+17
View File
@@ -0,0 +1,17 @@
let states = ["Kansas", "Nebraska", "North Dakota", "South Dakota"];
// urls: Imperative version
function imperativeUrls(elements) {
let urls = [];
elements.forEach(function(element) {
urls.push(element.toLowerCase().split(/\s+/).join("-"));
});
return urls;
}
console.log(imperativeUrls(states));
// urls: Functional version
function functionalUrls(elements) {
return elements.map(element => element.toLowerCase().split(/\s+/).join('-'));
}
console.log(functionalUrls(states));
+23
View File
@@ -0,0 +1,23 @@
let states = ["Kansas", "Nebraska", "North Dakota", "South Dakota"];
// Returns a URL-friendly version of a string.
// Example: "North Dakota" -> "north-dakota"
function urlify(string) {
return string.toLowerCase().split(/\s+/).join("-");
}
// urls: Imperative version
function imperativeUrls(elements) {
let urls = [];
elements.forEach(function(element) {
urls.push(urlify(element));
});
return urls;
}
console.log(imperativeUrls(states));
// urls: Functional version
function functionalUrls(elements) {
return elements.map(element => urlify(element));
}
console.log(functionalUrls(states));
+15
View File
@@ -0,0 +1,15 @@
let states = ["Kansas", "Nebraska", "North Dakota", "South Dakota"];
.
.
.
// singles: Imperative version
function imperativeSingles(elements) {
let singles = [];
elements.forEach(function(element) {
if (element.split(/\s+/).length === 1) {
singles.push(element);
}
});
return singles;
}
console.log(imperativeSingles(states));
+21
View File
@@ -0,0 +1,21 @@
let states = ["Kansas", "Nebraska", "North Dakota", "South Dakota"];
.
.
.
// singles: Imperative version
function imperativeSingles(elements) {
let singles = [];
elements.forEach(function(element) {
if (element.split(/\s+/).length === 1) {
singles.push(element);
}
});
return singles;
}
console.log(imperativeSingles(states));
// singles: Functional version
function functionalSingles(elements) {
return elements.filter(element => element.split(/\s+/).length === 1);
}
console.log(functionalSingles(states));
+14
View File
@@ -0,0 +1,14 @@
.
.
.
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// sum: Imperative solution
function imperativeSum(elements) {
let total = 0;
elements.forEach(function(n) {
total += n;
});
return total;
}
console.log(imperativeSum(numbers));
+20
View File
@@ -0,0 +1,20 @@
.
.
.
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// sum: Imperative solution
function imperativeSum(elements) {
let total = 0;
elements.forEach(function(n) {
total += n;
});
return total;
}
console.log(imperativeSum(numbers));
// sum: Functional solution
function functionalSum(elements) {
return elements.reduce((total, n) => { return total += n; });
}
console.log(functionalSum(numbers));
+12
View File
@@ -0,0 +1,12 @@
.
.
.
// lengths: Imperative solution
function imperativeLengths(elements) {
let lengths = {};
elements.forEach(function(element) {
lengths[element] = element.length;
});
return lengths;
}
console.log(imperativeLengths(states));
+21
View File
@@ -0,0 +1,21 @@
.
.
.
// lengths: Imperative solution
function imperativeLengths(elements) {
let lengths = {};
elements.forEach(function(element) {
lengths[element] = element.length;
});
return lengths;
}
console.log(imperativeLengths(states));
// lengths: Functional solution
function functionalLengths(elements) {
return elements.reduce((lengths, element) => {
lengths[element] = element.length;
return lengths;
}, {});
}
console.log(functionalLengths(states));
+15
View File
@@ -0,0 +1,15 @@
// Reverses a string.
function reverse(string) {
return Array.from(string).reverse().join("");
}
// Returns true for a palindrome, false otherwise.
function palindrome(string) {
let processedContent = string.toLowerCase();
return processedContent === reverse(processedContent);
}
// Defines a Phrase object.
function Phrase(content) {
this.content = content;
}
+32
View File
@@ -0,0 +1,32 @@
// Reverses a string.
function reverse(string) {
return Array.from(string).reverse().join("");
}
// Defines a Phrase object.
function Phrase(content) {
this.content = content;
// Returns content processed for palindrome testing.
this.processedContent = function processedContent() {
return this.content.toLowerCase();
}
// Returns true if the phrase is a palindrome, false otherwise.
this.palindrome = function palindrome() {
return this.processedContent() === reverse(this.processedContent());
}
}
// Defines a TranslatedPhrase object.
function TranslatedPhrase(content, translation) {
this.content = content;
this.translation = translation;
// Returns translation processed for palindrome testing.
this.processedContent = function processedContent() {
return this.translation.toLowerCase();
}
}
TranslatedPhrase.prototype = new Phrase();
+4
View File
@@ -0,0 +1,4 @@
> .load palindrome.js
> frase = new TranslatedPhrase("recognize", "reconocer");
> frase.palindrome();
true
+31
View File
@@ -0,0 +1,31 @@
// Reverses a string.
function reverse(string) {
return Array.from(string).reverse().join("");
}
function Phrase(content) {
this.content = content;
this.processor = function(string) {
// FILL IN
}
this.processedContent = function processedContent() {
return this.processor(this.content);
}
// Returns true if the phrase is a palindrome, false otherwise.
this.palindrome = function palindrome() {
return this.processedContent() === reverse(this.processedContent());
}
}
function TranslatedPhrase(content, translation) {
this.content = content;
this.translation = translation;
// Returns translation processed for palindrome testing.
this.processedContent = function processedContent() {
return this.processor(this.translation);
}
}
+19
View File
@@ -0,0 +1,19 @@
// Adds `reverse` to all strings.
String.prototype.reverse = function() {
return Array.from(this).reverse().join("");
}
// Defines a Phrase object.
function Phrase(content) {
this.content = content;
// Returns content processed for palindrome testing.
this.processedContent = function processedContent() {
return this.content.toLowerCase();
}
// Returns true if the phrase is a palindrome, false otherwise.
this.palindrome = function palindrome() {
return this.processedContent() === this.processedContent().reverse();
}
}
+15
View File
@@ -0,0 +1,15 @@
// Reverses a string.
function reverse(string) {
return Array.from(string).reverse().join("");
}
// Defines a Phrase object.
function Phrase(content) {
this.content = content;
// Returns true if the phrase is a palindrome, false otherwise.
this.palindrome = function palindrome() {
let processedContent = this.content.toLowerCase();
return processedContent === reverse(processedContent);
}
}
+9
View File
@@ -0,0 +1,9 @@
// Defines a Phrase object.
function Phrase(content) {
this.content = content;
// Makes the phrase LOUDER.
this.louder = function() {
// FILL IN
};
}
+4
View File
@@ -0,0 +1,4 @@
> .load palindrome.js
> let p = new Phrase("yo adrian!");
> p.louder();
'YO ADRIAN!'
+14
View File
@@ -0,0 +1,14 @@
// Reverses a string.
function reverse(string) {
return Array.from(string).reverse().join("");
}
// Defines a Phrase object.
function Phrase(content) {
this.content = content;
this.palindrome = function palindrome() {
let processedContent = this.content.toLowerCase();
return processedContent === reverse(processedContent);
}
}
+19
View File
@@ -0,0 +1,19 @@
// Reverses a string.
function reverse(string) {
return Array.from(string).reverse().join("");
}
// Defines a Phrase object.
function Phrase(content) {
this.content = content;
// Returns content processed for palindrome testing.
this.processedContent = function processedContent() {
return this.content.toLowerCase();
}
// Returns true if the phrase is a palindrome, false otherwise.
this.palindrome = function palindrome() {
return this.processedContent() === reverse(this.processedContent());
}
}
+8
View File
@@ -0,0 +1,8 @@
.
.
.
// Defines a TranslatedPhrase object.
function TranslatedPhrase(content, translation) {
this.content = content;
this.translation = translation;
}
+10
View File
@@ -0,0 +1,10 @@
.
.
.
// Defines a TranslatedPhrase object.
function TranslatedPhrase(content, translation) {
this.content = content;
this.translation = translation;
}
TranslatedPhrase.prototype = new Phrase();
+4
View File
@@ -0,0 +1,4 @@
> .load palindrome.js
> let frase = new TranslatedPhrase("recognize", "reconocer");
> frase.palindrome();
false
+27
View File
@@ -0,0 +1,27 @@
$ npm init
package name: (mhartl-palindrome)
version: (0.1.0)
description: Palindrome detector
entry point: (index.js)
test command: mocha
git repository: https://github.com/mhartl/mhartl-palindrome
keywords: palindrome learn-enough javascript
author: Michael Hartl
license: (ISC)
About to write to /Users/mhartl/repos/palindrome/package.json:
{
"name": "mhartl-palindrome",
"version": "0.1.0",
"description": "Palindrome detector",
"main": "index.js",
"scripts": {
"test": "mocha"
},
"repository": {
"type": "git",
"url": "https://github.com/mhartl/mhartl-palindrome"
},
"author": "Michael Hartl",
"license": "ISC"
}
+22
View File
@@ -0,0 +1,22 @@
$ npm test
Phrase
#palindrome
✓ should return false for a non-palindrome
✓ should return true for a plain palindrome
✓ should return true for a mixed-case palindrome
1) should return true for a palindrome with punctuation
3 passing (8ms)
1 failing
1) Phrase
#palindrome
should return true for a palindrome with punctuation:
AssertionError [ERR_ASSERTION]: false == true
+ expected - actual
-false
+true
+2
View File
@@ -0,0 +1,2 @@
let punctuatedPalindrome = new Phrase("Madam, I'm Adam.");
assert(punctuatedPalindrome.letters() === "MadamImAdam");
+1
View File
@@ -0,0 +1 @@
assert.strictEqual(<actual>, <expected>);

Some files were not shown because too many files have changed in this diff Show More