new class js -advanced
This commit is contained in:
13
01_grundlagen/faq/xyz-example.js
Normal file
13
01_grundlagen/faq/xyz-example.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
let x = () => {
|
||||
a = 3;
|
||||
};
|
||||
let y = () => (a = 5);
|
||||
let z = () => {
|
||||
console.log(a);
|
||||
};
|
||||
|
||||
x();
|
||||
y();
|
||||
z();
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
@@ -40,6 +40,24 @@
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
const outputEl = document.querySelector('.output');
|
||||
|
||||
const isPalindrom = (toCheckString) => {
|
||||
const reverseString = toCheckString
|
||||
.replace(/[$%!.,]/g, '')
|
||||
.split('')
|
||||
.reverse()
|
||||
.join('');
|
||||
return toCheckString.trim().toLowerCase() === reverseString.trim().toLowerCase() ? true : false;
|
||||
};
|
||||
|
||||
const toTest = ` Lagerregal`;
|
||||
|
||||
const result = isPalindrom(toTest);
|
||||
|
||||
console.log(toTest, result);
|
||||
outputEl.textContent = `${toTest} ist ${result ? 'ein' : 'KEIN'} Palindrom`;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Übung 46: Richtige Gewinner</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container py-5">
|
||||
<div class="alert alert-primary">
|
||||
<h1>Übung 46: Richtige Gewinner</h1>
|
||||
<p>
|
||||
Die Ausgabe der Gewinner aus dem letzten Beispiel (Codebeispiel 324) ist immer noch nicht ideal. Am Besten
|
||||
wäre das folgende Ergebnis-Array:
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
[
|
||||
'1st place: Heribert',
|
||||
'2nd place: Friedlinde',
|
||||
'3rd place: Tusnelda',
|
||||
'Oswine',
|
||||
'Ladislaus',
|
||||
]
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="output alert alert-secondary"></div>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
const outputEl = document.querySelector('.output');
|
||||
|
||||
const winners = ['Heribert', 'Friedlinde', 'Tusnelda', 'Oswine', 'Ladislaus'];
|
||||
|
||||
// Beispiel
|
||||
const getWinners = (winners) => {};
|
||||
|
||||
console.log(getWinners(winners));
|
||||
outputEl.innerHTML = `<ul><li>${getWinners(winners).join('</li><li>')}</li></ul>`;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,79 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Übung 47: Lückentext zu Higher-Order-Funktionen</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container py-5">
|
||||
<h1>Übung 47: Lückentext zu Higher-Order-Funktionen</h1>
|
||||
<p>
|
||||
Das ist garantiert der letzte Lückentext für diese Lektion. Ersetzen Sie wieder die Kommentare
|
||||
<strong>/* ??? */</strong> durch den richtigen Code, um das angegebene Ergebnis zu erzielen.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
let result;
|
||||
let results;
|
||||
let inputs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
let text = 'Hi this is a short text';
|
||||
let names = ['Heribert', 'Friedlinde', 'Tusnelda', 'Oswine', 'Ladislaus'];
|
||||
|
||||
//odd numbers
|
||||
//results = inputs
|
||||
console.log(results); // => [ 1, 3, 5, 7, 9 ]
|
||||
|
||||
//sum
|
||||
//result = inputs
|
||||
console.log(result); // => 55
|
||||
|
||||
//product
|
||||
//result = inputs
|
||||
console.log(result); // => 3628800
|
||||
|
||||
//longest word length
|
||||
result = text.split(' '); //=> ['Hi', 'this', 'is', 'a', 'short', 'text'];
|
||||
//
|
||||
|
||||
console.log(result); // => 5
|
||||
|
||||
//longest word
|
||||
result = text.split(' '); //=> ['Hi', 'this', 'is', 'a', 'short', 'text'];
|
||||
//
|
||||
|
||||
console.log(result); // =>'short'
|
||||
|
||||
//avg word length =========================
|
||||
|
||||
// result =
|
||||
console.log(result); // => 3
|
||||
|
||||
//sort by 3rd letter
|
||||
// ['Heribert', 'Friedlinde', 'Tusnelda', 'Oswine', 'Ladislaus'];
|
||||
|
||||
const names2 = [...names];
|
||||
// results =
|
||||
console.log(results); // => [ 'Ladislaus', 'Friedlinde', 'Heribert', 'Tusnelda', 'Oswine' ]
|
||||
|
||||
// Are there names with more than 8 letters?
|
||||
// ['Heribert', 'Friedlinde', 'Tusnelda', 'Oswine', 'Ladislaus'];
|
||||
|
||||
// result = names
|
||||
|
||||
// Has every name at least 8 letters?
|
||||
// result = names
|
||||
console.log(result); // false
|
||||
|
||||
// What is the lowest value from the inputs?
|
||||
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
// result = inputs
|
||||
console.log(result);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
100
01_grundlagen/uebungen/u46_richtige-gewinner.html
Normal file
100
01_grundlagen/uebungen/u46_richtige-gewinner.html
Normal file
@@ -0,0 +1,100 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Übung 46: Richtige Gewinner</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container py-5">
|
||||
<div class="alert alert-primary">
|
||||
<h1>Übung 46: Richtige Gewinner</h1>
|
||||
<p>
|
||||
Die Ausgabe der Gewinner aus dem letzten Beispiel (Codebeispiel 324) ist immer noch nicht ideal. Am Besten
|
||||
wäre das folgende Ergebnis-Array:
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
[
|
||||
'1st place: Heribert',
|
||||
'2nd place: Friedlinde',
|
||||
'3rd place: Tusnelda',
|
||||
'Oswine',
|
||||
'Ladislaus',
|
||||
]
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="output alert alert-secondary"></div>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
const outputEl = document.querySelector('.output');
|
||||
|
||||
const winners = ['Heribert', 'Friedlinde', 'Tusnelda', 'Oswine', 'Ladislaus'];
|
||||
|
||||
// const PlaceWinner = () => {
|
||||
// console.log(winners());
|
||||
// };
|
||||
|
||||
// Beispiel
|
||||
const getWinners = (winners) => {
|
||||
const results = [];
|
||||
const restAr = [];
|
||||
for (let i = 0; i < winners.length; i++) {
|
||||
if (i === 0) {
|
||||
results.push(`1st Place: ${winners[i]}`);
|
||||
} else if (i === 1) {
|
||||
results.push(`2nd Place: ${winners[i]}`);
|
||||
} else if (i === 2) {
|
||||
results.push(`3rd Place: ${winners[i]}`);
|
||||
} else {
|
||||
restAr.push(winners[i]);
|
||||
}
|
||||
}
|
||||
//return [results, restAr];
|
||||
return results.concat(rest);
|
||||
};
|
||||
|
||||
// Beispiel
|
||||
const getWinners2 = (names = []) => {
|
||||
const results = names.map((name, idx) => {
|
||||
if (idx === 0) {
|
||||
return `1st place: ${name}`;
|
||||
}
|
||||
if (idx === 1) {
|
||||
return `2nd place: ${name}`;
|
||||
}
|
||||
if (idx === 2) {
|
||||
return `3rd place: ${name}`;
|
||||
}
|
||||
return name;
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
const labels = ['1st', '2nd', '3rd'];
|
||||
|
||||
// Beispiel
|
||||
const getWinners3 = (names = []) => {
|
||||
const results = names.map((name, idx) => {
|
||||
// if (idx < 3) {
|
||||
// return `${labels[idx]} place: ${name}`;
|
||||
// } else {
|
||||
// return name;
|
||||
// }
|
||||
|
||||
return idx < labels.length ? `${labels[idx]} place: ${name}` : name;
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
console.log(getWinners3(winners));
|
||||
outputEl.innerHTML = `<ul><li>${getWinners3(winners).join('</li><li>')}</li></ul>`;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
173
01_grundlagen/uebungen/u47_higher-order-fn-lueckentext.html
Normal file
173
01_grundlagen/uebungen/u47_higher-order-fn-lueckentext.html
Normal file
@@ -0,0 +1,173 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Übung 47: Lückentext zu Higher-Order-Funktionen</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container py-5">
|
||||
<h1>Übung 47: Lückentext zu Higher-Order-Funktionen</h1>
|
||||
<p>
|
||||
Das ist garantiert der letzte Lückentext für diese Lektion. Ersetzen Sie wieder die Kommentare
|
||||
<strong>/* ??? */</strong> durch den richtigen Code, um das angegebene Ergebnis zu erzielen.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
let result;
|
||||
let results;
|
||||
let inputs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
let text = 'Hi this is a short text';
|
||||
let names = ['Heribert', 'Friedlinde', 'Tusnelda', 'Oswine', 'Ladislaus'];
|
||||
|
||||
//odd numbers
|
||||
//results = inputs
|
||||
//let inputs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
|
||||
results = inputs.filter((n) => n % 2 !== 0);
|
||||
|
||||
const ungeradeZahlen = [];
|
||||
for (let i = 0; i < inputs.length; i++) {
|
||||
if (inputs[i] % 2 !== 0) {
|
||||
ungeradeZahlen.push(inputs[i]);
|
||||
}
|
||||
}
|
||||
console.log(ungeradeZahlen); // => [ 1, 3, 5, 7, 9 ]
|
||||
console.log(results); // => [ 1, 3, 5, 7, 9 ]
|
||||
// ==================================================================
|
||||
|
||||
// sum
|
||||
inputs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
// a und b wrd addiert (1+2 = 3) speichert in a und ( a + b ( 3 +3 = 6))
|
||||
const sum = inputs.reduce((a, b) => a + b, 0);
|
||||
console.log('sum: ', sum); // => 55
|
||||
|
||||
// ======================================================================
|
||||
//product
|
||||
//result = inputs
|
||||
const gesamtsumme = inputs.reduce((a, b) => a * b, 1);
|
||||
|
||||
console.log(gesamtsumme); // => 3628800
|
||||
// ========================================================================
|
||||
//longest word length
|
||||
// let text = 'Hi this is a short text';
|
||||
const longestWordLength = text.split(' ').reduce((a, b) => {
|
||||
if (a.length > b.length) {
|
||||
return a;
|
||||
} else {
|
||||
return b;
|
||||
}
|
||||
}).length;
|
||||
|
||||
console.log(longestWordLength); //=> 5
|
||||
|
||||
// longest word length
|
||||
results = text.split(' '); //=> ['Hi', 'this', 'is', 'a', 'short', 'text'];
|
||||
|
||||
const getWordLength = (word) => {
|
||||
return word.length;
|
||||
};
|
||||
|
||||
const wordLength = results.map(getWordLength); // => [2,4,2,1,5,4]
|
||||
|
||||
result = wordLength.sort((n1, n2) => {
|
||||
return n2 - n1;
|
||||
});
|
||||
|
||||
result = result[0];
|
||||
|
||||
console.log(result); // => 5
|
||||
|
||||
result = text
|
||||
.split(' ') //=> ['Hi', 'this', 'is', 'a', 'short', 'text'];
|
||||
.map((a) => a.length) // => [2,4,2,1,5,4]
|
||||
.reduce((a, b) => Math.max(a, b)); // => 5
|
||||
// .reduce((a, b) => (a < b ? b : a)); // => 5
|
||||
|
||||
console.log('Max word length: ', result);
|
||||
|
||||
//longest word length
|
||||
result = text.split(' ').sort((a, b) => b.length - a.length)[0].length;
|
||||
//=> ['Hi', 'this', 'is', 'a', 'short', 'text'];
|
||||
console.log(`Länge des längsten Wortes: ${result}`); // => 5
|
||||
|
||||
// ======================================================
|
||||
//longest word
|
||||
//result = text.split(' '); //=> ['Hi', 'this', 'is', 'a', 'short', 'text'];
|
||||
const longestword = text.split(' ').reduce((a, b) => {
|
||||
if (a.length > b.length) return a;
|
||||
else return b;
|
||||
});
|
||||
|
||||
result = text.split(' ').sort((a, b) => b.length - a.length)[0];
|
||||
|
||||
console.log('longestword: ', result); // =>'short'
|
||||
console.log(longestword); // =>'short'
|
||||
// =========================================================
|
||||
//avg word length =========================// => 3
|
||||
|
||||
const avgword = text.split(' ');
|
||||
const AnzahlSum = avgword.length; // 6
|
||||
const AvgSum = AnzahlSum / 2;
|
||||
console.log(AvgSum); // 3
|
||||
|
||||
result =
|
||||
text
|
||||
.split(' ') //=> ['Hi', 'this', 'is', 'a', 'short', 'text'];
|
||||
.map((a) => a.length) // => [2,4,2,1,5,4]
|
||||
.reduce((a, b) => a + b, 0) / text.split(' ').length;
|
||||
|
||||
console.log(`Avg word length: ${result}`); // => 3
|
||||
|
||||
result =
|
||||
text
|
||||
.split(' ')
|
||||
.map((text) => text.length)
|
||||
.reduce((n1, n2) => n1 + n2, 0) / text.split(' ').length;
|
||||
console.log(`Durchschnittliche Wortlänge: ${result}`); // => 3
|
||||
|
||||
result = text.replaceAll(' ', '').length / text.split(' ').length;
|
||||
console.log(`Durchschnittliche Wortlänge: ${result}`); // => 3
|
||||
|
||||
// ============================================================
|
||||
|
||||
//sort by 3rd letter
|
||||
// ['Heribert', 'Friedlinde', 'Tusnelda', 'Oswine', 'Ladislaus'];
|
||||
|
||||
const names2 = [...names];
|
||||
const sortedByThirdLetterAr = names2.sort((a, b) => a.charAt(2).localeCompare(b.charAt(2)));
|
||||
|
||||
results = [...names].sort((a, b) => (a.charAt(2) < b.charAt(2) ? -1 : 1));
|
||||
console.log(`sort by 3rd letter: ${results}`); // => [ 'Ladislaus', 'Friedlinde', 'Heribert', 'Tusnelda', 'Oswine' ]
|
||||
|
||||
console.log(sortedByThirdLetterAr); // => [ 'Ladislaus', 'Friedlinde', 'Heribert', 'Tusnelda', 'Oswine' ]
|
||||
// ========================================================================
|
||||
// Are there names with more than 8 letters?
|
||||
// ['Heribert', 'Friedlinde', 'Tusnelda', 'Oswine', 'Ladislaus'];
|
||||
const names3 = [...names];
|
||||
const moreThenEightLetters = names3.filter((name) => name.length > 8);
|
||||
|
||||
result = names.some((name) => name.length > 8);
|
||||
console.log(moreThenEightLetters.length > 0); // => true
|
||||
console.log(result); // => true
|
||||
//===================================================================
|
||||
// Has every name at least 8 letters?
|
||||
result = [...names].every((name) => name.length <= 8);
|
||||
|
||||
console.log('Has every name at least 8 letters?: ', result);
|
||||
//====================================================
|
||||
|
||||
// What is the lowest value from the inputs?
|
||||
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
// result = inputs
|
||||
result = Math.min(...inputs);
|
||||
|
||||
console.log(result);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
@@ -28,7 +28,13 @@
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
const honoluluFlip = ['Maracuja Juice', 'Pineapple Juice', 'Lemon Juice', 'Grapefruit Juice', 'Crushed Ice'];
|
||||
const honoluluFlip = [
|
||||
'Maracuja Juice', //
|
||||
'Pineapple Juice',
|
||||
'Lemon Juice',
|
||||
'Grapefruit Juice',
|
||||
'Crushed Ice',
|
||||
];
|
||||
|
||||
const ingredientsFromMyBar = [
|
||||
'Pineapple',
|
||||
@@ -49,14 +55,16 @@
|
||||
|
||||
// 1. Schreibe eine Funktion, `hasIngredient`, die `true` zurückgibt, wenn eine angegebene Zutat in einer Rezeptliste vorhanden ist. Rufe deine Funktion mit Maracujsasaft und Honolulu Flip auf.
|
||||
|
||||
const hasIngredient = (listOfIngredients, searchedIngredient) => {
|
||||
/* ??? */
|
||||
const hasIngredient = (cocktailAr = [], searchStr) => {
|
||||
return cocktailAr.includes(searchStr);
|
||||
};
|
||||
|
||||
//alert(hasIngredient(honoluluFlip, 'Maracuja Juice'));
|
||||
|
||||
// 2. So richtig sinnvoll ist unsere Funktion noch nicht. Viel hilfreicher wäre es, wenn wir eine Funktion hätten, die anhand unserer vorhandenen Zutaten herausfindet, ob wir den Cocktail auch tatsächlich machen können. Dafür benötigst du die komplette Liste aller bei dir vorhandenen Zutaten (ingredientsFromMyBar). Du möchtest wissen, ob du alle Zutaten vorrätig hast, die du zum Mixen des Cocktails benötigst.
|
||||
|
||||
const isMixableWith = (cocktailRecipe, availableIngredients) => {
|
||||
/* ??? */
|
||||
const isMixableWith = (cocktailAr, allAr = []) => {
|
||||
return cocktailAr.every((str) => hasIngredient(allAr, str));
|
||||
};
|
||||
|
||||
//honoluluFlip isMixableWith ingredientsFromMyBar?
|
||||
@@ -19,6 +19,10 @@
|
||||
const transform = (fullName) => {
|
||||
const nameParts = fullName.split(' '); // => ['Ladislaus', 'Coolio', 'Barry', 'Crazy', 'Jones'];
|
||||
const lastName = nameParts.slice(nameParts.length - 1); // => 'Jones'
|
||||
|
||||
// nameParts = nameParts.slice(0, nameParts.length - 1); // => ['Ladislaus', 'Coolio', 'Barry', 'Crazy']
|
||||
// Wenn Variable mit "let" deklarariert wäre, könnten wir die Variable neu befüllen. Bezeichner wäre aber dann nicht mehr sinnvoll.
|
||||
|
||||
const firstNames = nameParts.slice(0, nameParts.length - 1); // => ['Ladislaus', 'Coolio', 'Barry', 'Crazy']
|
||||
|
||||
return firstNames.map((firstName) => firstName.charAt(0) + '.').join(' ') + ' ' + lastName;
|
||||
|
||||
15
02_advanced/.vscode/extensions.json
vendored
Normal file
15
02_advanced/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"kamikillerto.vscode-colorize",
|
||||
"sleistner.vscode-fileutils",
|
||||
"bierner.github-markdown-preview",
|
||||
"bradgashler.htmltagwrap",
|
||||
"zhuangtongfa.material-theme",
|
||||
"techer.open-in-browser",
|
||||
"esbenp.prettier-vscode",
|
||||
"pdconsec.vscode-print",
|
||||
"vscode-icons-team.vscode-icons",
|
||||
"formulahendry.auto-rename-tag",
|
||||
"tomoki1207.pdf"
|
||||
]
|
||||
}
|
||||
332
02_advanced/.vscode/marp-theme.css
vendored
Normal file
332
02_advanced/.vscode/marp-theme.css
vendored
Normal file
@@ -0,0 +1,332 @@
|
||||
/* @theme marp-theme */
|
||||
|
||||
@charset "UTF-8";
|
||||
/*!
|
||||
* Marp Dracula theme.
|
||||
* @theme marp-theme
|
||||
* @author Daniel Nicolas Gisolfi & modified by Philippe Botzek
|
||||
*
|
||||
* @auto-scaling true
|
||||
* @size 4:3 960px 720px
|
||||
* @size 16:9 1280px 720px
|
||||
*/
|
||||
|
||||
@import url('https://fonts.googleapis.com/css?family=Lato:400,900|IBM+Plex+Sans:400,700');
|
||||
|
||||
:root {
|
||||
--dracula-background: #282a36;
|
||||
--dracula-current-line: #44475a;
|
||||
--dracula-foreground: #f8f8f2;
|
||||
--dracula-comment: #6272a4;
|
||||
--dracula-cyan: #8be9fd;
|
||||
--dracula-green: #50fa7b;
|
||||
--dracula-orange: #ffb86c;
|
||||
--dracula-pink: #ff79c6;
|
||||
--dracula-purple: #bd93f9;
|
||||
--dracula-red: #ff5555;
|
||||
--dracula-yellow: #f1fa8c;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: var(--dracula-background);
|
||||
}
|
||||
|
||||
/* Dracula Foreground */
|
||||
.hljs,
|
||||
.hljs-subst,
|
||||
.hljs-typing,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: var(--dracula-foreground);
|
||||
}
|
||||
|
||||
/* Dracula Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-deletion {
|
||||
color: var(--dracula-comment);
|
||||
}
|
||||
|
||||
/* Dracula Cyan */
|
||||
.hljs-meta .hljs-doctag,
|
||||
.hljs-built_in,
|
||||
.hljs-selector-tag,
|
||||
.hljs-section,
|
||||
.hljs-link,
|
||||
.hljs-class {
|
||||
color: var(--dracula-cyan);
|
||||
}
|
||||
|
||||
/* Dracula Green */
|
||||
.hljs-title {
|
||||
color: var(--dracula-green);
|
||||
}
|
||||
|
||||
/* Dracula Orange */
|
||||
.hljs-params {
|
||||
color: var(--dracula-orange);
|
||||
}
|
||||
|
||||
/* Dracula Pink */
|
||||
.hljs-keyword {
|
||||
color: var(--dracula-pink);
|
||||
}
|
||||
|
||||
/* Dracula Purple */
|
||||
.hljs-literal,
|
||||
.hljs-number {
|
||||
color: var(--dracula-purple);
|
||||
}
|
||||
|
||||
/* Dracula Red */
|
||||
.hljs-regexp {
|
||||
color: var(--dracula-red);
|
||||
}
|
||||
|
||||
/* Dracula Yellow */
|
||||
.hljs-string,
|
||||
.hljs-name,
|
||||
.hljs-type,
|
||||
.hljs-attr,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition,
|
||||
.hljs-template-tag {
|
||||
color: var(--dracula-yellow);
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-doctag,
|
||||
.hljs-type,
|
||||
.hljs-name,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-params,
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
svg[data-marp-fitting='svg'] {
|
||||
max-height: 580px;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 0.5em 0 0 0;
|
||||
color: var(--dracula-pink);
|
||||
}
|
||||
h1 strong,
|
||||
h2 strong,
|
||||
h3 strong,
|
||||
h4 strong,
|
||||
h5 strong,
|
||||
h6 strong {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
p,
|
||||
blockquote {
|
||||
margin: 1em 0 0 0;
|
||||
}
|
||||
|
||||
ul > li,
|
||||
ol > li {
|
||||
margin: 0.3em 0 0 0;
|
||||
color: var(--dracula-cyan);
|
||||
}
|
||||
ul > li > p,
|
||||
ol > li > p {
|
||||
margin: 0.6em 0 0 0;
|
||||
}
|
||||
|
||||
code {
|
||||
display: inline-block;
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 0.8em;
|
||||
letter-spacing: 0;
|
||||
margin: -0.1em 0.15em;
|
||||
padding: 0.1em 0.2em;
|
||||
vertical-align: baseline;
|
||||
color: var(--dracula-green);
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin: 1em 0 0 0;
|
||||
min-height: 1em;
|
||||
overflow: visible;
|
||||
}
|
||||
pre code {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
min-width: 100%;
|
||||
padding: 0.5em;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
pre code svg[data-marp-fitting='svg'] {
|
||||
max-height: calc(580px - 1em);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 1em 0 0 0;
|
||||
padding: 0 1em;
|
||||
position: relative;
|
||||
color: var(--dracula-orange);
|
||||
}
|
||||
blockquote::after,
|
||||
blockquote::before {
|
||||
content: '“';
|
||||
display: block;
|
||||
font-family: 'Times New Roman', serif;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
color: var(--dracula-green);
|
||||
}
|
||||
blockquote::before {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
blockquote::after {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
blockquote > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
mark {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
table {
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
margin: 1em 0 0 0;
|
||||
}
|
||||
table th,
|
||||
table td {
|
||||
padding: 0.2em 0.4em;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
section {
|
||||
font-size: 35px;
|
||||
font-family: 'IBM Plex Sans';
|
||||
line-height: 1.35;
|
||||
letter-spacing: 1.25px;
|
||||
padding: 70px;
|
||||
color: var(--dracula-foreground);
|
||||
background-color: var(--dracula-background);
|
||||
}
|
||||
section > *:first-child,
|
||||
section > header:first-child + * {
|
||||
margin-top: 0;
|
||||
}
|
||||
section a,
|
||||
section mark {
|
||||
color: var(--dracula-red);
|
||||
}
|
||||
section code {
|
||||
background: var(--dracula-current-line);
|
||||
color: var(--dracula-current-green);
|
||||
}
|
||||
section h1 strong,
|
||||
section h2 strong,
|
||||
section h3 strong,
|
||||
section h4 strong,
|
||||
section h5 strong,
|
||||
section h6 strong {
|
||||
color: var(--dracula-current-line);
|
||||
}
|
||||
section pre > code {
|
||||
background: var(--dracula-current-line);
|
||||
}
|
||||
section header,
|
||||
section footer,
|
||||
section section::after,
|
||||
section blockquote::before,
|
||||
section blockquote::after {
|
||||
color: var(--dracula-comment);
|
||||
}
|
||||
section table th,
|
||||
section table td {
|
||||
border-color: var(--dracula-current-line);
|
||||
}
|
||||
section table thead th {
|
||||
background: var(--dracula-current-line);
|
||||
color: var(--dracula-yellow);
|
||||
}
|
||||
section table tbody > tr:nth-child(even) td,
|
||||
section table tbody > tr:nth-child(even) th {
|
||||
background: var(--dracula-current-line);
|
||||
}
|
||||
|
||||
header,
|
||||
footer,
|
||||
section::after {
|
||||
box-sizing: border-box;
|
||||
font-size: 66%;
|
||||
height: 70px;
|
||||
line-height: 50px;
|
||||
overflow: hidden;
|
||||
padding: 10px 25px;
|
||||
position: absolute;
|
||||
color: var(--dracula-comment);
|
||||
}
|
||||
|
||||
header {
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
footer {
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
section::after {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
font-size: 80%;
|
||||
}
|
||||
30
02_advanced/.vscode/settings.json
vendored
Normal file
30
02_advanced/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"workbench.iconTheme": "vscode-icons",
|
||||
"workbench.colorTheme": "One Dark Pro",
|
||||
"prettier.printWidth": 120,
|
||||
"prettier.singleQuote": true,
|
||||
"editor.hover.enabled": "on",
|
||||
"editor.wordWrap": "on",
|
||||
"explorer.confirmDelete": false,
|
||||
"explorer.confirmDragAndDrop": false,
|
||||
"editor.quickSuggestionsDelay": 600,
|
||||
"editor.tabSize": 2,
|
||||
"editor.formatOnSave": true,
|
||||
"emmet.includeLanguages": {
|
||||
"javascript": "javascriptreact",
|
||||
"ejs": "html"
|
||||
},
|
||||
"html.format.unformatted": "wbr,%",
|
||||
"files.associations": {
|
||||
"*.ejs": "html"
|
||||
},
|
||||
"editor.fontFamily": "'MesloLGS NF', Hack, Consolas, 'Courier New', monospace",
|
||||
"oneDarkPro.markdownStyle": false,
|
||||
"explorer.compactFolders": false,
|
||||
"workbench.editor.labelFormat": "short",
|
||||
"editor.hover.delay": 800,
|
||||
"editor.bracketPairColorization.enabled": true,
|
||||
"editor.guides.bracketPairs": "active",
|
||||
"markdown.marp.themes": ["./.vscode/marp-theme.css"],
|
||||
"markdown-preview-github-styles.colorTheme": "light"
|
||||
}
|
||||
73
02_advanced/.vscode/snippets.code-snippets
vendored
Normal file
73
02_advanced/.vscode/snippets.code-snippets
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"Output HTML Element": {
|
||||
"scope": "html",
|
||||
"prefix": "output",
|
||||
"body": ["<div class=\"output alert alert-secondary my-3\"></div>"],
|
||||
"description": "generate a div Element with output alert and alert secondary class"
|
||||
},
|
||||
"Bootstrap html": {
|
||||
"scope": "html",
|
||||
"prefix": "!bs",
|
||||
"body": [
|
||||
"<!DOCTYPE html>",
|
||||
"<html lang=\"de\">",
|
||||
"\t<head>",
|
||||
"\t\t<meta charset=\"UTF-8\" />",
|
||||
"\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />",
|
||||
"\t\t<title>$0</title>",
|
||||
"\t\t<link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css\" rel=\"stylesheet\" />",
|
||||
"\t</head>",
|
||||
"\t<body>",
|
||||
"\t\t<main>",
|
||||
"\t\t\t<div class=\"container py-5\">",
|
||||
"\t\t\t\t<h1>$0</h1>",
|
||||
"\t\t\t</div>",
|
||||
"\t\t</main>",
|
||||
"\t\t<script>",
|
||||
"\t\t\t'use strict';",
|
||||
"\t\t\t",
|
||||
"\t\t</script>",
|
||||
"\t</body>",
|
||||
"</html>"
|
||||
],
|
||||
"description": "Generate HTML with Bootstrap CDN and script-tag"
|
||||
},
|
||||
"$ und $$ helper function": {
|
||||
"scope": "javascript,typescript",
|
||||
"prefix": "$$$",
|
||||
"body": [
|
||||
"const $ = (qs) => document.querySelector(qs);",
|
||||
"const $$ = (qs) => Array.from(document.querySelectorAll(qs));"
|
||||
],
|
||||
"description": "$ and $$ shorthand helper function"
|
||||
},
|
||||
|
||||
"JavaScript Dateivorlage": {
|
||||
"scope": "javascript,typescript",
|
||||
"prefix": "vjs",
|
||||
"body": [
|
||||
"'use strict';",
|
||||
"",
|
||||
"(() => {",
|
||||
"",
|
||||
"\t// === DOM & VARS =======",
|
||||
"\tconst DOM = {};",
|
||||
"",
|
||||
"\t// === INIT =============",
|
||||
"\tconst init = () => {",
|
||||
"",
|
||||
"\t}",
|
||||
"",
|
||||
"\t// === EVENTHANDLER =====",
|
||||
"",
|
||||
"\t// === XHR/FETCH ========",
|
||||
"",
|
||||
"\t// === FUNCTIONS ========",
|
||||
"",
|
||||
"\tinit();",
|
||||
"",
|
||||
"})();"
|
||||
],
|
||||
"description": "JavaScript Dateivorlage"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const foo = ({ a = 1, b = 2 }) => `a: ${a}, b: ${b}`;
|
||||
|
||||
console.log(foo({ a: 7 })); // => a: 7, b: 2
|
||||
console.log(foo({ b: 7 })); // => a: 1, b: 7
|
||||
console.log(foo({ a: 7, b: 8 })); // => a: 7, b: 8
|
||||
@@ -0,0 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
const productsFromCSV = (csv) =>
|
||||
csv
|
||||
.split('\n')
|
||||
.slice(1)
|
||||
.map((str) => str.trim());
|
||||
|
||||
const productsCSV = `name, category, price
|
||||
Klingon Letter Opener, Office Warfare, 19.99
|
||||
Backpack of Holding, Travel, 29.99
|
||||
Tardis Alarmclock, Merchandise, 15.99`;
|
||||
|
||||
const products = productsFromCSV(productsCSV);
|
||||
console.log(products);
|
||||
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
const productFromCSV = (productString) => {
|
||||
const [name, category, price] = productString.split(', ');
|
||||
return {
|
||||
name: name,
|
||||
category: category,
|
||||
price: price,
|
||||
};
|
||||
};
|
||||
|
||||
const product = productFromCSV('Backpack of Holding, Travel, 29.99');
|
||||
console.dir(product);
|
||||
@@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
const productFromCSV = (productString) => {
|
||||
const productArray = productString.split(', ');
|
||||
|
||||
const name = productArray[0];
|
||||
const category = productArray[1];
|
||||
const price = productArray[2];
|
||||
|
||||
return {
|
||||
name: name,
|
||||
category: category,
|
||||
price: price,
|
||||
};
|
||||
};
|
||||
|
||||
const product = productFromCSV('Backpack of Holding, Travel, 29.99');
|
||||
console.dir(product);
|
||||
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
const trim = (s) => s.match(/\W*(.+)\W*/)[1];
|
||||
|
||||
const productFromArray = ([name, category, price]) => ({
|
||||
name,
|
||||
category,
|
||||
price,
|
||||
});
|
||||
|
||||
const productsFromCSV = (csv) =>
|
||||
csv
|
||||
.split('\n')
|
||||
.slice(1)
|
||||
.map(trim)
|
||||
.map((s) => s.split(', '))
|
||||
.map(productFromArray);
|
||||
|
||||
const productsCSV = `name, category, price
|
||||
Klingon Letter Opener, Office Warfare, 19.99
|
||||
Backpack of Holding, Travel, 29.99
|
||||
Tardis Alarmclock, Merchandise, 15.99`;
|
||||
|
||||
const products = productsFromCSV(productsCSV);
|
||||
console.log(products);
|
||||
@@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
const trim = (s) => s.match(/\W*(.+)\W*/)[1];
|
||||
|
||||
const productFromCSV = (productString) => {
|
||||
const [name, category, price] = productString.split(', ');
|
||||
return {
|
||||
name,
|
||||
category,
|
||||
price,
|
||||
};
|
||||
};
|
||||
|
||||
const productsFromCSV = (csv) =>
|
||||
csv.split('\n').slice(1).map(trim).map(productFromCSV);
|
||||
|
||||
const productsCSV = `name, category, price
|
||||
Klingon Letter Opener, Office Warfare, 19.99
|
||||
Backpack of Holding, Travel, 29.99
|
||||
Tardis Alarmclock, Merchandise, 15.99`;
|
||||
|
||||
const products = productsFromCSV(productsCSV);
|
||||
console.log(products);
|
||||
@@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const formatProduct = ({ name, price }) =>
|
||||
`* ${name} - buy now for only $${price}`;
|
||||
|
||||
const product = {
|
||||
name: 'Klingon Letter Opener',
|
||||
category: 'Office Warfare',
|
||||
price: '19.99',
|
||||
};
|
||||
|
||||
console.log(formatProduct(product));
|
||||
@@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const distance = (
|
||||
{ x: xOrigin, y: yOrigin },
|
||||
{ x: xDestination, y: yDestination }
|
||||
) => Math.sqrt((yDestination - yOrigin) ** 2 + (xDestination - xOrigin) ** 2);
|
||||
|
||||
console.log(distance({ x: 1, y: 1 }, { x: 5, y: 1 }));
|
||||
@@ -0,0 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const logTransformedName = ({ firstName, lastName }) =>
|
||||
console.log(`${lastName}, ${firstName.charAt(0)}.`);
|
||||
|
||||
logTransformedName({ firstName: 'Ladislaus', lastName: 'Jones' });
|
||||
@@ -0,0 +1,13 @@
|
||||
function factorial(n) {
|
||||
// Base case: if n is 0, return 1
|
||||
if (n === 0) {
|
||||
return 1;
|
||||
}
|
||||
// Recursive case: n * factorial of (n - 1)
|
||||
return n * factorial(n - 1);
|
||||
}
|
||||
|
||||
// Test cases
|
||||
console.log(factorial(5)); // => 120
|
||||
console.log(factorial(3)); // => 6
|
||||
console.log(factorial(0)); // => 1
|
||||
@@ -0,0 +1,23 @@
|
||||
function fibonacci(n) {
|
||||
// Base cases
|
||||
if (n === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (n === 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Recursive case
|
||||
return fibonacci(n - 1) + fibonacci(n - 2);
|
||||
}
|
||||
|
||||
// Test cases
|
||||
console.log(fibonacci(0)); // => 0
|
||||
console.log(fibonacci(1)); // => 1
|
||||
console.log(fibonacci(2)); // => 1
|
||||
console.log(fibonacci(3)); // => 2
|
||||
console.log(fibonacci(4)); // => 3
|
||||
console.log(fibonacci(5)); // => 5
|
||||
console.log(fibonacci(6)); // => 8
|
||||
console.log(fibonacci(10)); // => 55
|
||||
@@ -0,0 +1,17 @@
|
||||
function fibonacciMemo(n, memo = {}) {
|
||||
// Base Cases
|
||||
if (n === 0) return 0;
|
||||
if (n === 1) return 1;
|
||||
|
||||
// Test if value already calculated
|
||||
if (memo[n]) {
|
||||
return memo[n];
|
||||
}
|
||||
|
||||
// Recursive Case with Memoization
|
||||
memo[n] = fibonacciMemo(n - 1, memo) + fibonacciMemo(n - 2, memo);
|
||||
return memo[n];
|
||||
}
|
||||
|
||||
// Test Cases
|
||||
console.log(fibonacciMemo(50)); // => 12586269025
|
||||
@@ -0,0 +1,13 @@
|
||||
function sumArray(arr) {
|
||||
// Base case: when the array is empty, return 0
|
||||
if (arr.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
// Recursive case: add the first element to the sum of the rest of the array
|
||||
return arr[0] + sumArray(arr.slice(1));
|
||||
}
|
||||
|
||||
// Test cases
|
||||
console.log(sumArray([1, 2, 3, 4, 5])); // => 15
|
||||
console.log(sumArray([10, -2, 33, 47])); // => 88
|
||||
console.log(sumArray([])); // => 0
|
||||
@@ -0,0 +1,13 @@
|
||||
function sumArrayIndex(arr, index = 0) {
|
||||
// Base case: when index is greater than or equal to the length of the array return 0
|
||||
if (index >= arr.length) {
|
||||
return 0;
|
||||
}
|
||||
// Recursive case: add the current element to the sum of the rest of the array
|
||||
return arr[index] + sumArrayIndex(arr, index + 1);
|
||||
}
|
||||
|
||||
// Test cases
|
||||
console.log(sumArrayIndex([1, 2, 3, 4, 5])); // => 15
|
||||
console.log(sumArrayIndex([10, -2, 33, 47])); // => 88
|
||||
console.log(sumArrayIndex([])); // => 0
|
||||
@@ -0,0 +1,19 @@
|
||||
function combinations(n, k) {
|
||||
// Base Cases
|
||||
if (k === 0 || k === n) {
|
||||
return 1;
|
||||
}
|
||||
// If k is greater than n, there are no combinations
|
||||
if (k > n) {
|
||||
return 0;
|
||||
}
|
||||
// Recursive Cases
|
||||
return combinations(n - 1, k - 1) + combinations(n - 1, k);
|
||||
}
|
||||
|
||||
// Test Cases
|
||||
console.log(combinations(5, 2)); // => 10
|
||||
console.log(combinations(6, 3)); // => 20
|
||||
console.log(combinations(4, 0)); // => 1
|
||||
console.log(combinations(4, 4)); // => 1
|
||||
console.log(combinations(5, 6)); // => 0
|
||||
@@ -0,0 +1,27 @@
|
||||
function findDeepestLevel(arr, currentLevel = 1) {
|
||||
// Base case: when the array is empty, return the current level
|
||||
if (arr.length === 0) {
|
||||
return currentLevel;
|
||||
}
|
||||
|
||||
let maxLevel = currentLevel;
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (Array.isArray(arr[i])) {
|
||||
// Recursive case: if the element is an array, call the function recursively
|
||||
const depth = findDeepestLevel(arr[i], currentLevel + 1);
|
||||
if (depth > maxLevel) {
|
||||
maxLevel = depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxLevel;
|
||||
}
|
||||
|
||||
// Test cases
|
||||
console.log(findDeepestLevel([1, [2, [3, [4]], 5]])); // => 4
|
||||
console.log(findDeepestLevel([1, 2, 3, 4, 5])); // => 1
|
||||
console.log(findDeepestLevel([])); // => 1
|
||||
console.log(findDeepestLevel([1, [2], [3, [4, [5]]]])); // => 4
|
||||
console.log(findDeepestLevel([1, [2, [3]], [4, [5, [6]]]])); // => 4
|
||||
@@ -0,0 +1,19 @@
|
||||
function findMax(arr) {
|
||||
// Base case: empty array
|
||||
if (arr.length === 0) {
|
||||
return null;
|
||||
}
|
||||
// Base case: array with one element
|
||||
if (arr.length === 1) {
|
||||
return arr[0];
|
||||
}
|
||||
// Recursive case: return the maximum of the first element and the maximum of the rest of the array
|
||||
const subMax = findMax(arr.slice(1));
|
||||
return arr[0] > subMax ? arr[0] : subMax;
|
||||
}
|
||||
|
||||
// Test cases
|
||||
console.log(findMax([1, 5, 3, 9, 2])); // => 9
|
||||
console.log(findMax([-10, -20, -3, -4])); // => -3
|
||||
console.log(findMax([42])); // => 42
|
||||
console.log(findMax([])); // => null
|
||||
@@ -0,0 +1,14 @@
|
||||
function reverseString(str) {
|
||||
// Base case: if the string has only one character, return it
|
||||
if (str.length <= 1) {
|
||||
return str;
|
||||
}
|
||||
// Recursive case: return the last character of the string and call the function with the rest of the string
|
||||
return reverseString(str.slice(1)) + str[0];
|
||||
}
|
||||
|
||||
// Test cases
|
||||
console.log(reverseString('hello')); // => "olleh"
|
||||
console.log(reverseString('Recursion')); // => "noisruceR"
|
||||
console.log(reverseString('')); // => ""
|
||||
console.log(reverseString('A')); // => "A"
|
||||
@@ -0,0 +1,26 @@
|
||||
function sumNestedArray(arr) {
|
||||
// Base case: when the array is empty, return 0
|
||||
if (arr.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let sum = 0;
|
||||
|
||||
for (let element of arr) {
|
||||
if (Array.isArray(element)) {
|
||||
// Recursive case: if the element is an array, sum its elements
|
||||
sum += sumNestedArray(element);
|
||||
} else if (typeof element === 'number') {
|
||||
sum += element;
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
// Test cases
|
||||
console.log(sumNestedArray([1, [2, [3, 4], 5], 6])); // => 21
|
||||
console.log(sumNestedArray([[[[1]]], 2, [3, [4, [5]]]])); // => 15
|
||||
console.log(sumNestedArray([])); // => 0
|
||||
console.log(sumNestedArray([10, [20, [30, [40]]]])); // => 100
|
||||
console.log(sumNestedArray([1, 'a', [2, 'b', [3, 4]], 5])); // => 15 (ignores non-numbers)
|
||||
@@ -0,0 +1,12 @@
|
||||
function sumRecursive(n) {
|
||||
if (n === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return n + sumRecursive(n - 1);
|
||||
}
|
||||
|
||||
// Test Cases
|
||||
console.log(sumRecursive(5)); // => 15 (5 + 4 + 3 + 2 + 1)
|
||||
console.log(sumRecursive(10)); // => 55 (10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1)
|
||||
console.log(sumRecursive(0)); // => 0
|
||||
@@ -0,0 +1,15 @@
|
||||
const tryWork = (resolve, reject) => {
|
||||
const ergebnis = 21 * 2;
|
||||
if (Math.random() < 0.5) {
|
||||
resolve(ergebnis);
|
||||
} else {
|
||||
reject('nope');
|
||||
}
|
||||
};
|
||||
|
||||
const p4 = new Promise(tryWork);
|
||||
|
||||
p4.then(
|
||||
(result) => console.log('OK: ' + result),
|
||||
(reason) => console.log('KO: ' + reason)
|
||||
);
|
||||
@@ -0,0 +1,17 @@
|
||||
const tryWork = (resolve, reject) => {
|
||||
const ergebnis = 21 * 2;
|
||||
if (Math.random() < 0.5) {
|
||||
resolve(ergebnis);
|
||||
} else {
|
||||
reject(new Error('nope'));
|
||||
}
|
||||
};
|
||||
|
||||
new Promise(tryWork)
|
||||
.then(() => new Promise(tryWork))
|
||||
.then(() => new Promise(tryWork))
|
||||
.then((result) => console.log('OK: ' + result))
|
||||
.catch((err) => {
|
||||
console.log('KO: ' + err.message);
|
||||
console.log(err.stack);
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
const wait = () => new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
|
||||
wait()
|
||||
.then(() => {
|
||||
console.log('The');
|
||||
return wait();
|
||||
})
|
||||
.then(() => {
|
||||
console.log('pyramid');
|
||||
return wait();
|
||||
});
|
||||
// etc...
|
||||
@@ -0,0 +1,26 @@
|
||||
// print a phrase, a word at a time:
|
||||
// the pyramid of doom appears
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('The');
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('pyramid');
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('of');
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('doom');
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('keeps');
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('growing.');
|
||||
}, 1000);
|
||||
}, 1000);
|
||||
}, 1000);
|
||||
}, 1000);
|
||||
}, 1000);
|
||||
}, 1000);
|
||||
@@ -0,0 +1,17 @@
|
||||
// print a phrase, a word at a time:
|
||||
// use promises to avoid the pyramid of doom
|
||||
|
||||
const printDelay = (time, str) =>
|
||||
new Promise((resolve) =>
|
||||
setTimeout(() => {
|
||||
console.log(str);
|
||||
resolve();
|
||||
}, time)
|
||||
);
|
||||
|
||||
printDelay(1000, 'The')
|
||||
.then(() => printDelay(1000, 'pyramid'))
|
||||
.then(() => printDelay(1000, 'of'))
|
||||
.then(() => printDelay(1000, 'doom'))
|
||||
.then(() => printDelay(1000, 'is'))
|
||||
.then(() => printDelay(1000, 'defeated.'));
|
||||
@@ -0,0 +1,9 @@
|
||||
const fs = require('fs');
|
||||
|
||||
fs.readFile('data/file.txt', 'UTF8', (error, content) => {
|
||||
if (error) {
|
||||
console.log('could not read file');
|
||||
} else {
|
||||
console.log(content);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const getFileContent = (path, encoding = 'utf-8') => {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.readFile(path, encoding, (error, data) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
getFileContent('data/file.txt')
|
||||
.then((data) => console.log(data))
|
||||
.catch((err) => console.error(`Something went wrong: ${err}`));
|
||||
@@ -0,0 +1,9 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const getFileContent = (path, encoding = 'utf-8') => {
|
||||
return fs.promises.readFile(path, encoding);
|
||||
};
|
||||
|
||||
getFileContent('data/file.txt')
|
||||
.then((data) => console.log(data))
|
||||
.catch((err) => console.error(`Something went wrong: ${err}`));
|
||||
@@ -0,0 +1,8 @@
|
||||
const fs = require('fs');
|
||||
const util = require('util');
|
||||
|
||||
const getFileContent = util.promisify(fs.readFile);
|
||||
|
||||
getFileContent('data/file.txt', 'UTF8')
|
||||
.then((data) => console.log(data))
|
||||
.catch((err) => console.error(`Something went wrong: ${err}`));
|
||||
@@ -0,0 +1,29 @@
|
||||
const dns = require('dns');
|
||||
|
||||
const IP_V = 4; // we use IP protocol version 4
|
||||
const URL = 'de.webmasters-europe.org';
|
||||
|
||||
// Solution 1: Detailed variant with Promise object
|
||||
const getIp = (url, ip) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
dns.lookup(url, ip, (error, data) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve({ address: data, family: ip });
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
getIp(URL, IP_V)
|
||||
.then((data) => console.log(`IP adress = ${data.address}`))
|
||||
.catch((err) => console.error(err));
|
||||
|
||||
// dns.lookup(URL, IP_V, (error, address) => {
|
||||
// if (error) {
|
||||
// console.log('error: could not lookup host');
|
||||
// } else {
|
||||
// console.log('IP address = ' + address);
|
||||
// }
|
||||
// });
|
||||
@@ -0,0 +1,21 @@
|
||||
const dns = require('dns');
|
||||
|
||||
const IP_V = 4; // we use IP protocol version 4
|
||||
const URL = 'de.webmasters-europe.org';
|
||||
|
||||
// Solution 2: Variant with promises subobject
|
||||
const getIpPromises = (url, ip) => {
|
||||
return dns.promises.lookup(url, ip);
|
||||
};
|
||||
|
||||
getIpPromises(URL, IP_V)
|
||||
.then((data) => console.log(`IP adress = ${data.address}`))
|
||||
.catch((err) => console.error(err));
|
||||
|
||||
// dns.lookup(URL, IP_V, (error, address) => {
|
||||
// if (error) {
|
||||
// console.log('error: could not lookup host');
|
||||
// } else {
|
||||
// console.log('IP address = ' + address);
|
||||
// }
|
||||
// });
|
||||
@@ -0,0 +1,20 @@
|
||||
const dns = require('dns');
|
||||
const util = require('util');
|
||||
|
||||
const IP_V = 4; // we use IP protocol version 4
|
||||
const URL = 'de.webmasters-europe.org';
|
||||
|
||||
// Solution 3: Variant with util module
|
||||
const getIpPromisify = util.promisify(dns.lookup);
|
||||
|
||||
getIpPromisify(URL, IP_V)
|
||||
.then((data) => console.log(`IP adress = ${data.address}`))
|
||||
.catch((err) => console.error(err));
|
||||
|
||||
// dns.lookup(URL, IP_V, (error, address) => {
|
||||
// if (error) {
|
||||
// console.log('error: could not lookup host');
|
||||
// } else {
|
||||
// console.log('IP address = ' + address);
|
||||
// }
|
||||
// });
|
||||
@@ -0,0 +1 @@
|
||||
This is the contents of file 01.
|
||||
@@ -0,0 +1 @@
|
||||
This is the contents of file 02.
|
||||
@@ -0,0 +1 @@
|
||||
This is the contents of file 03.
|
||||
@@ -0,0 +1 @@
|
||||
This is the contents of file 04.
|
||||
@@ -0,0 +1 @@
|
||||
This is the contents of file 05.
|
||||
@@ -0,0 +1 @@
|
||||
This is the contents of file 06.
|
||||
@@ -0,0 +1,30 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const getFileContent = (name, encoding = 'UTF8') => {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.readFile(name, encoding, (error, content) => {
|
||||
if (error) {
|
||||
reject(`could not read file ${name}`);
|
||||
} else {
|
||||
resolve(content);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Promise.all([
|
||||
getFileContent('data/file_1.txt'),
|
||||
getFileContent('data/file_2.txt'),
|
||||
getFileContent('data/file_3.txt'),
|
||||
getFileContent('data/file_4.txt'),
|
||||
getFileContent('data/file_5.txt'),
|
||||
getFileContent('data/file_6.txt'),
|
||||
])
|
||||
.then((contents) =>
|
||||
contents.forEach((content) => {
|
||||
console.log(content);
|
||||
})
|
||||
)
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
// print a phrase, a word at a time:
|
||||
// workaround to avoid the pyramid of doom
|
||||
|
||||
const words = 'The pyramid of doom keeps growing.';
|
||||
|
||||
const printWords = (str = '', idx = 0) => {
|
||||
const words = str.split(/\s/);
|
||||
// Guard
|
||||
if (idx >= words.length) return '';
|
||||
|
||||
console.log(words[idx]);
|
||||
|
||||
setTimeout(() => {
|
||||
printWords(str, ++idx);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
printWords(words);
|
||||
50
02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess.js
Normal file
50
02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess.js
Normal file
@@ -0,0 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
const board2string = (board) => board.map((row) => row.join('')).join('\n');
|
||||
|
||||
const execMove = (board, move) => {
|
||||
const originX = fieldToXPosition(originField(move));
|
||||
const originY = fieldToYPosition(originField(move));
|
||||
const targetX = fieldToXPosition(targetField(move));
|
||||
const targetY = fieldToYPosition(targetField(move));
|
||||
|
||||
board[targetY][targetX] = board[originY][originX];
|
||||
board[originY][originX] = emptyBoard()[originY][originX];
|
||||
return board;
|
||||
};
|
||||
|
||||
const boardInStartPosition = () => [
|
||||
['♜', '♞', '♝', '♛', '♚', '♝', '♞', '♜'],
|
||||
['♟', '♟', '♟', '♟', '♟', '♟', '♟', '♟'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['♙', '♙', '♙', '♙', '♙', '♙', '♙', '♙'],
|
||||
['♖', '♘', '♗', '♕', '♔', '♗', '♘', '♖'],
|
||||
];
|
||||
|
||||
const emptyBoard = () => [
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
];
|
||||
|
||||
const originField = (move) => move.substr(0, 2);
|
||||
const targetField = (move) => move.substr(2);
|
||||
|
||||
const fieldToXPosition = (field) => letterToChessIndex(field.charAt(0));
|
||||
const fieldToYPosition = (field) => numberToChessIndex(field.charAt(1));
|
||||
const letterToChessIndex = (letter) => 'abcdefgh'.indexOf(letter);
|
||||
const numberToChessIndex = (num) => 8 - num;
|
||||
|
||||
console.log(board2string(boardInStartPosition()));
|
||||
|
||||
console.log('\n');
|
||||
|
||||
console.log(board2string(execMove(boardInStartPosition(), 'e2e4')));
|
||||
@@ -0,0 +1,56 @@
|
||||
'use strict';
|
||||
|
||||
const board2string = (board) => board.map((row) => row.join('')).join('\n');
|
||||
|
||||
const execMoves = (moves) => moves.reduce(execMove, boardInStartPosition());
|
||||
|
||||
const execMove = (board, move) => {
|
||||
const originX = fieldToXPosition(originField(move));
|
||||
const originY = fieldToYPosition(originField(move));
|
||||
const targetX = fieldToXPosition(targetField(move));
|
||||
const targetY = fieldToYPosition(targetField(move));
|
||||
|
||||
board[targetY][targetX] = board[originY][originX];
|
||||
board[originY][originX] = emptyBoard()[originY][originX];
|
||||
return board;
|
||||
};
|
||||
|
||||
const boardInStartPosition = () => [
|
||||
['♜', '♞', '♝', '♛', '♚', '♝', '♞', '♜'],
|
||||
['♟', '♟', '♟', '♟', '♟', '♟', '♟', '♟'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['♙', '♙', '♙', '♙', '♙', '♙', '♙', '♙'],
|
||||
['♖', '♘', '♗', '♕', '♔', '♗', '♘', '♖'],
|
||||
];
|
||||
|
||||
const emptyBoard = () => [
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
];
|
||||
|
||||
const originField = (move) => move.substr(0, 2);
|
||||
const targetField = (move) => move.substr(2);
|
||||
|
||||
const fieldToXPosition = (field) => letterToChessIndex(field.charAt(0));
|
||||
const fieldToYPosition = (field) => numberToChessIndex(field.charAt(1));
|
||||
const letterToChessIndex = (letter) => 'abcdefgh'.indexOf(letter);
|
||||
const numberToChessIndex = (num) => 8 - num;
|
||||
|
||||
console.log(board2string(boardInStartPosition()));
|
||||
|
||||
console.log('\n');
|
||||
|
||||
console.log(board2string(execMove(boardInStartPosition(), 'e2e4')));
|
||||
|
||||
console.log('\n');
|
||||
|
||||
console.log(board2string(execMoves(['e2e4', 'e7e5', 'f2f4'])));
|
||||
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
const board2string = (board) => board.map((row) => row.join('')).join('\n');
|
||||
|
||||
const positionHistoryForMoves = (moves) =>
|
||||
moves.map((move, i) => moves.slice(0, i + 1)).map(execMoves);
|
||||
|
||||
const execMoves = (moves) => moves.reduce(execMove, boardInStartPosition());
|
||||
|
||||
const execMove = (board, move) => {
|
||||
const originX = fieldToXPosition(originField(move));
|
||||
const originY = fieldToYPosition(originField(move));
|
||||
const targetX = fieldToXPosition(targetField(move));
|
||||
const targetY = fieldToYPosition(targetField(move));
|
||||
|
||||
board[targetY][targetX] = board[originY][originX];
|
||||
board[originY][originX] = emptyBoard()[originY][originX];
|
||||
return board;
|
||||
};
|
||||
|
||||
const boardInStartPosition = () => [
|
||||
['♜', '♞', '♝', '♛', '♚', '♝', '♞', '♜'],
|
||||
['♟', '♟', '♟', '♟', '♟', '♟', '♟', '♟'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['♙', '♙', '♙', '♙', '♙', '♙', '♙', '♙'],
|
||||
['♖', '♘', '♗', '♕', '♔', '♗', '♘', '♖'],
|
||||
];
|
||||
|
||||
const emptyBoard = () => [
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
['◻', '▦', '◻', '▦', '◻', '▦', '◻', '▦'],
|
||||
['▦', '◻', '▦', '◻', '▦', '◻', '▦', '◻'],
|
||||
];
|
||||
|
||||
const originField = (move) => move.substr(0, 2);
|
||||
const targetField = (move) => move.substr(2);
|
||||
|
||||
const fieldToXPosition = (field) => letterToChessIndex(field.charAt(0));
|
||||
const fieldToYPosition = (field) => numberToChessIndex(field.charAt(1));
|
||||
const letterToChessIndex = (letter) => 'abcdefgh'.indexOf(letter);
|
||||
const numberToChessIndex = (num) => 8 - num;
|
||||
|
||||
const history = positionHistoryForMoves(['e2e4', 'e7e5', 'f2f4']);
|
||||
|
||||
console.log(history);
|
||||
|
||||
history.forEach((position) => console.log(board2string(position), '\n'));
|
||||
@@ -0,0 +1,14 @@
|
||||
const gradesTable = [
|
||||
['Name', 'Mathematics', 'English', 'Biology'],
|
||||
['Anna', 85, 92, 78],
|
||||
['Ben', 90, 88, 84],
|
||||
['Clara', 76, 95, 89],
|
||||
];
|
||||
|
||||
// Change Anna's math grade to 88
|
||||
gradesTable[1][1] = 88;
|
||||
|
||||
// Add a new row for another student
|
||||
gradesTable.push(['David', 82, 79, 91]);
|
||||
|
||||
console.log(gradesTable);
|
||||
@@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const inventory = [
|
||||
[
|
||||
// Category: Electronics
|
||||
['Shelf 1', 'Laptop', 10],
|
||||
['Shelf 2', 'Smartphone', 25],
|
||||
],
|
||||
[
|
||||
// Category: Clothing
|
||||
['Shelf 1', 'T-Shirts', 50],
|
||||
['Shelf 2', 'Jeans', 30],
|
||||
],
|
||||
[
|
||||
// Category: Groceries
|
||||
['Shelf 1', 'Milk', 100],
|
||||
['Shelf 2', 'Bread', 80],
|
||||
],
|
||||
];
|
||||
|
||||
// Increase the number of laptops
|
||||
inventory[0][0][2] += 5; // New quantity: 15
|
||||
|
||||
// Add a new shelf to a category
|
||||
inventory[1].push(['Shelf 3', 'Pants', 20]);
|
||||
|
||||
console.log(inventory);
|
||||
@@ -0,0 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
const isMixableWithMyIngredients = (cocktailRecipe) =>
|
||||
isMixableWith(cocktailRecipe, ingredientsFromMyBar);
|
||||
|
||||
const isMixableWith = (cocktailRecipe, availableIngredients) =>
|
||||
cocktailRecipe.every((ingredientFromRecipe) =>
|
||||
hasIngredient(availableIngredients, ingredientFromRecipe)
|
||||
);
|
||||
|
||||
const hasIngredient = (listOfIngredients, searchedIngredient) =>
|
||||
listOfIngredients.includes(searchedIngredient);
|
||||
|
||||
const honoluluFlip = [
|
||||
'Maracuja Juice',
|
||||
'Pineapple Juice',
|
||||
'Lemon Juice',
|
||||
'Grapefruit Juice',
|
||||
'Crushed Ice',
|
||||
];
|
||||
const casualFriday = ['Vodka', 'Lime Juice', 'Apple Juice', 'Cucumber'];
|
||||
|
||||
const pinkDolly = [
|
||||
'Vodka',
|
||||
'Orange Juice',
|
||||
'Pineapple Juice',
|
||||
'Grenadine',
|
||||
'Cream',
|
||||
'Coco Syrup',
|
||||
];
|
||||
const cocktailRecipes = [honoluluFlip, casualFriday, pinkDolly];
|
||||
|
||||
const ingredientsFromMyBar = [
|
||||
'Pineapple',
|
||||
'Maracuja Juice',
|
||||
'Cream',
|
||||
'Grapefruit Juice',
|
||||
'Crushed Ice',
|
||||
'Milk',
|
||||
'Vodka',
|
||||
'Apple Juice',
|
||||
'Aperol',
|
||||
'Pineapple Juice',
|
||||
'Lime Juice',
|
||||
'Lemons',
|
||||
'Cucumber',
|
||||
];
|
||||
|
||||
console.log(cocktailRecipes.find(isMixableWithMyIngredients));
|
||||
// => [ 'Vodka', 'Lime Juice', 'Apple Juice', 'Cucumber' ]
|
||||
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const countriesWithCapital = [
|
||||
['UK', 'London'],
|
||||
['France', 'Paris'],
|
||||
['Germany', 'Berlin'],
|
||||
['Switzerland', 'Bern'],
|
||||
['Austria', 'Vienna'],
|
||||
['Russia', 'Moscow'],
|
||||
];
|
||||
|
||||
const capitalOf = (country) => {
|
||||
const capitalIndex = 1;
|
||||
const countryIndex = 0;
|
||||
return countriesWithCapital.find(
|
||||
(countryWithCapital) => countryWithCapital[countryIndex] === country
|
||||
)[capitalIndex];
|
||||
};
|
||||
|
||||
console.log(capitalOf('Switzerland'));
|
||||
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const countriesWithCapital = [
|
||||
['UK', 'London'],
|
||||
['France', 'Paris'],
|
||||
['Germany', 'Berlin'],
|
||||
['Switzerland', 'Bern'],
|
||||
['Austria', 'Vienna'],
|
||||
['Russia', 'Moscow'],
|
||||
];
|
||||
|
||||
const countryForCapital = (capital) => {
|
||||
const capitalIndex = 1;
|
||||
const countryIndex = 0;
|
||||
return countriesWithCapital.find(
|
||||
(countryWithCapital) => countryWithCapital[capitalIndex] === capital
|
||||
)[countryIndex];
|
||||
};
|
||||
|
||||
console.log(countryForCapital('Berlin'));
|
||||
@@ -0,0 +1,46 @@
|
||||
'use strict';
|
||||
|
||||
const gradesTable = [
|
||||
['Name', 'Mathematics', 'English', 'Biology', 'History'],
|
||||
['Anna', 85, 92, 78, 88],
|
||||
['Ben', 90, 88, 84, 79],
|
||||
['Clara', 76, 95, 89, 91],
|
||||
['David', 82, 79, 91, 85],
|
||||
];
|
||||
|
||||
// Helper: Calculates average of an array of numbers
|
||||
const getAverage = (numbers) => {
|
||||
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
|
||||
const avg = sum / numbers.length;
|
||||
return Number(avg.toFixed(2));
|
||||
};
|
||||
|
||||
// 1. Calculate average per student
|
||||
const calculateAvgGrades = (table) => {
|
||||
// We take the rows (excluding header), and map each row to a single average value
|
||||
return table.slice(1).map((row) => {
|
||||
const grades = row.slice(1); // Remove student name
|
||||
return getAverage(grades);
|
||||
});
|
||||
};
|
||||
|
||||
// 2. Calculate average per subject
|
||||
const calculateAvgSubjects = (table) => {
|
||||
const headers = table[0].slice(1); // Get subject names ['Mathematics', 'English', ...]
|
||||
const rows = table.slice(1); // Get data rows
|
||||
|
||||
// We map over the headers to create a result for each subject column
|
||||
return headers.map((_, colIndex) => {
|
||||
// For the current column, extract the value from every row
|
||||
// Note: colIndex starts at 0, but in the row data, grades start at index 1
|
||||
const columnGrades = rows.map((row) => row[colIndex + 1]);
|
||||
return getAverage(columnGrades);
|
||||
});
|
||||
};
|
||||
|
||||
// Tests
|
||||
console.log('Student Averages:', calculateAvgGrades(gradesTable));
|
||||
// Expected: [85.75, 85.25, 87.75, 84.25]
|
||||
|
||||
console.log('Subject Averages:', calculateAvgSubjects(gradesTable));
|
||||
// Expected: [83.25, 88.50, 85.50, 85.75]
|
||||
@@ -0,0 +1,41 @@
|
||||
'use strict';
|
||||
|
||||
const image = [
|
||||
[
|
||||
// Row 1
|
||||
[100, 150, 200], // Pixel 1
|
||||
[50, 100, 150], // Pixel 2
|
||||
],
|
||||
[
|
||||
// Row 2
|
||||
[25, 75, 125], // Pixel 3
|
||||
[200, 225, 250], // Pixel 4
|
||||
],
|
||||
];
|
||||
|
||||
const increaseBrightness = (image, value) => {
|
||||
// Iterate through each line of the image
|
||||
return image.map((row) =>
|
||||
// Iterate through every pixel in the line
|
||||
row.map((pixel) =>
|
||||
// Increase each RGB value by 'value' and make sure that it does not exceed 255
|
||||
pixel.map((component) => Math.min(component + value, 255))
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const newImage = increaseBrightness(image, 30);
|
||||
console.log(newImage);
|
||||
/*
|
||||
Expected outcome:
|
||||
[
|
||||
[
|
||||
[130, 180, 230],
|
||||
[80, 130, 180],
|
||||
],
|
||||
[
|
||||
[55, 105, 155],
|
||||
[230, 255, 255],
|
||||
],
|
||||
]
|
||||
*/
|
||||
@@ -0,0 +1,47 @@
|
||||
'use strict';
|
||||
|
||||
const inventory = [
|
||||
[
|
||||
// Category: Electronics
|
||||
['Shelf 1', 'Laptop', 10],
|
||||
['Shelf 2', 'Smartphone', 25],
|
||||
],
|
||||
[
|
||||
// Category: Clothing
|
||||
['Shelf 1', 'T-Shirts', 50],
|
||||
['Shelf 2', 'Jeans', 30],
|
||||
],
|
||||
[
|
||||
// Category: Groceries
|
||||
['Shelf 1', 'Milk', 100],
|
||||
['Shelf 2', 'Bread', 80],
|
||||
],
|
||||
];
|
||||
|
||||
// Add new category “Books"
|
||||
inventory.push([
|
||||
['Shelf 1', 'Novels', 40],
|
||||
['Shelf 2', 'Non-fiction', 35],
|
||||
]);
|
||||
|
||||
console.log(inventory);
|
||||
/* Expected outcome:
|
||||
[
|
||||
[ // Electronics
|
||||
['Shelf 1', 'Laptop', 10],
|
||||
['Shelf 2', 'Smartphone', 25],
|
||||
],
|
||||
[ // Clothing
|
||||
['Shelf 1', 'T-Shirts', 50],
|
||||
['Shelf 2', 'Jeans', 30],
|
||||
],
|
||||
[ // Groceries
|
||||
['Shelf 1', 'Milk', 100],
|
||||
['Shelf 2', 'Bread', 80],
|
||||
],
|
||||
[ // Books
|
||||
['Shelf 1', 'Novels', 40],
|
||||
['Shelf 2', 'Non-fiction', 35],
|
||||
],
|
||||
]
|
||||
*/
|
||||
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
const evolutionStages = [
|
||||
['Pidgey', 'Pidgeotto', 'Pidgeot'],
|
||||
['Vulpix', 'Ninetales'],
|
||||
['Dratini', 'Dragonair', 'Dragonite'],
|
||||
];
|
||||
|
||||
const stagesFor = (pokemon) =>
|
||||
evolutionStages.find((stages) => stages.includes(pokemon));
|
||||
|
||||
const stagesAfter = (pokemon) =>
|
||||
stagesFor(pokemon).slice(stagesFor(pokemon).indexOf(pokemon) + 1);
|
||||
|
||||
const stagesBefore = (pokemon) =>
|
||||
stagesFor(pokemon).slice(0, stagesFor(pokemon).indexOf(pokemon));
|
||||
|
||||
console.log(stagesFor('Vulpix')); // => [ 'Vulpix', 'Ninetales' ]
|
||||
console.log(stagesAfter('Dratini')); // => [ 'Dragonair', 'Dragonite' ]
|
||||
console.log(stagesBefore('Pidgeot')); // => [ 'Pidgey', 'Pidgeotto' ]
|
||||
console.log(stagesBefore('Dragonair')); // => [ 'Dratini' ]
|
||||
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const shoppingList = [
|
||||
['Fruits', 'Apples', 'Bananas', 'Oranges'],
|
||||
['Vegetables', 'Carrots', 'Broccoli', 'Spinach'],
|
||||
['Dairy', 'Milk', 'Cheese', 'Yogurt'],
|
||||
];
|
||||
|
||||
// Your code here
|
||||
shoppingList[0][2] = 'Grapes'; // Replace 'Bananas' with 'Grapes'
|
||||
shoppingList[1][2] = 'Tomatoes'; // Replace 'Broccoli' with 'Tomatoes'
|
||||
shoppingList[2][2] = 'Butter'; // Replace 'Cheese' with 'Butter'
|
||||
|
||||
console.log(shoppingList);
|
||||
// Expected outcome:
|
||||
// [
|
||||
// ['Fruits', 'Apples', 'Grapes', 'Oranges'],
|
||||
// ['Vegetables', 'Carrots', 'Tomatoes', 'Spinach'],
|
||||
// ['Dairy', 'Milk', 'Butter', 'Yogurt'],
|
||||
// ]
|
||||
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Posts</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>List of Posts</h1>
|
||||
<ul id="post-list"></ul>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
async function displayPosts() {
|
||||
const postList = document.querySelector('#post-list');
|
||||
|
||||
try {
|
||||
const response = await fetch('https://dummyjson.com/posts');
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
data.posts.forEach((post) => {
|
||||
const listItem = document.createElement('li');
|
||||
listItem.textContent = post.title; // Display the title of each post
|
||||
postList.appendChild(listItem);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching posts:', error);
|
||||
|
||||
const errorItem = document.createElement('li');
|
||||
|
||||
errorItem.textContent = 'Error loading posts.';
|
||||
postList.appendChild(errorItem);
|
||||
}
|
||||
}
|
||||
|
||||
displayPosts();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Post Details</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>List of Posts</h1>
|
||||
<ul id="post-list"></ul>
|
||||
|
||||
<div
|
||||
id="post-details"
|
||||
style="
|
||||
display: none;
|
||||
border: 1px solid #ccc;
|
||||
padding: 1em;
|
||||
margin-top: 1em;
|
||||
"
|
||||
>
|
||||
<h2 id="post-title"></h2>
|
||||
<p id="post-body"></p>
|
||||
<button id="close-details">Close Details</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
async function loadAndDisplayPosts() {
|
||||
const postList = document.getElementById('post-list');
|
||||
const postDetails = document.getElementById('post-details');
|
||||
const postTitle = document.getElementById('post-title');
|
||||
const postBody = document.getElementById('post-body');
|
||||
const closeDetailsButton = document.getElementById('close-details');
|
||||
|
||||
try {
|
||||
const response = await fetch('https://dummyjson.com/posts');
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
const posts = await response.json();
|
||||
|
||||
posts.forEach((post) => {
|
||||
const listItem = document.createElement('li');
|
||||
listItem.textContent = post.title;
|
||||
listItem.style.cursor = 'pointer';
|
||||
|
||||
// Add click event listener to display post details
|
||||
listItem.addEventListener('click', () => {
|
||||
postTitle.textContent = post.title;
|
||||
postBody.textContent = post.body;
|
||||
postDetails.style.display = 'block';
|
||||
});
|
||||
|
||||
postList.appendChild(listItem);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching posts:', error);
|
||||
const errorItem = document.createElement('li');
|
||||
errorItem.textContent = 'Error loading posts.';
|
||||
postList.appendChild(errorItem);
|
||||
}
|
||||
|
||||
// Close details when the button is clicked
|
||||
closeDetailsButton.addEventListener('click', () => {
|
||||
postDetails.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
loadAndDisplayPosts();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
async function fetchData() {
|
||||
try {
|
||||
const response = await fetch('https://dummyjson.com/posts');
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
} catch (error) {
|
||||
console.error('Problem with the fetch operation:', error);
|
||||
}
|
||||
}
|
||||
|
||||
fetchData();
|
||||
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
const person = {
|
||||
name: 'John Doe',
|
||||
age: 30,
|
||||
profession: 'Web Developer',
|
||||
};
|
||||
|
||||
// Convert JavaScript object to JSON string
|
||||
const jsonString = JSON.stringify(person);
|
||||
console.log(jsonString);
|
||||
// => {"name":"John Doe","age":30,"profession":"Web Developer"}
|
||||
|
||||
try {
|
||||
// Convert JSON string back to JavaScript object
|
||||
const parsedPerson = JSON.parse(jsonString);
|
||||
console.log(parsedPerson.name); // => John Doe
|
||||
console.log(parsedPerson.age); // => 30
|
||||
} catch (error) {
|
||||
console.error('Invalid JSON:', error);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
async function getData(url) {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
// Handle HTTP errors by throwing an exception
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error) {
|
||||
// Centralized error logging and fallback behavior
|
||||
console.error('Error fetching data:', error);
|
||||
// Optionally, return a default value or handle the error gracefully
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
getData('https://dummyjson.com/posts')
|
||||
.then((data) => {
|
||||
if (data) {
|
||||
console.log('Data:', data);
|
||||
} else {
|
||||
console.log('No data received');
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error in getData:', error);
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
async function fetchUsers() {
|
||||
try {
|
||||
const response = await fetch('https://dummyjson.com/users');
|
||||
const data = await response.json();
|
||||
console.log(data.users);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Call the function
|
||||
fetchUsers();
|
||||
@@ -0,0 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const book = {
|
||||
title: 'The Great Gatsby',
|
||||
author: 'F. Scott Fitzgerald',
|
||||
year: 1925,
|
||||
};
|
||||
|
||||
const jsonString = JSON.stringify(book);
|
||||
console.log(jsonString);
|
||||
|
||||
const jsonObject = JSON.parse(jsonString);
|
||||
console.log(jsonObject.title);
|
||||
console.log(jsonObject.author);
|
||||
@@ -0,0 +1,9 @@
|
||||
Code,Short Description,Tagline,Quantity,Price
|
||||
MUG0007,coffee mug with LCD level indicator,never again reach for the empty mug,20,49.90
|
||||
MUG0013,coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling,put the smart into coffee reading,20,99.90
|
||||
OFF3145,pen with pre-warmed ink (tested on the South Pole),the pen is mightier than the cold,50,29.90
|
||||
COM1001,ambidextrous computer mouse,end the dictate of left and right,10,19.90
|
||||
COM0404,Easter egg themed webcam for your monitor,put an Easter egg on hardware too,20,149.90
|
||||
COM0001,Vulcan language vi cheatsheet,learn vi and Vulcan at the same time,3,9.90
|
||||
COM1536,Klingon language emacs cheatsheet,learn emacs and Klingon at the same time,50,9.90
|
||||
MOB0555,smartphone case with built-in screen,never miss a message,20,39.90
|
||||
|
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Products</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container py-5">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<h2>coffee mug with LCD level indicator</h2>
|
||||
<p>never again reach for the empty mug</p>
|
||||
<p><strong>Price:</strong> EUR 49.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling</h2>
|
||||
<p>put the smart into coffee reading</p>
|
||||
<p><strong>Price:</strong> EUR 99.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>pen with pre-warmed ink (tested on the South Pole)</h2>
|
||||
<p>the pen is mightier than the cold</p>
|
||||
<p><strong>Price:</strong> EUR 29.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>ambidextrous computer mouse</h2>
|
||||
<p>end the dictate of left and right</p>
|
||||
<p><strong>Price:</strong> EUR 19.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>Easter egg themed webcam for your monitor</h2>
|
||||
<p>put an Easter egg on hardware too</p>
|
||||
<p><strong>Price:</strong> EUR 149.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>Vulcan language vi cheatsheet</h2>
|
||||
<p>learn vi and Vulcan at the same time</p>
|
||||
<p><strong>Price:</strong> EUR 9.90</p>
|
||||
<p class="alert alert-warning">Last items in stock!</p>
|
||||
</li><li class="list-group-item">
|
||||
<h2>Klingon language emacs cheatsheet</h2>
|
||||
<p>learn emacs and Klingon at the same time</p>
|
||||
<p><strong>Price:</strong> EUR 9.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>smartphone case with built-in screen</h2>
|
||||
<p>never miss a message</p>
|
||||
<p><strong>Price:</strong> EUR 39.90</p>
|
||||
|
||||
</li>
|
||||
</ul></div>
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
const fs = require('fs');
|
||||
|
||||
fs.readFile('data/products.csv', 'UTF8', (error, data) => {
|
||||
console.log(data); // 2 output
|
||||
});
|
||||
|
||||
for (let i = 0; i < 2000000000; i++) {
|
||||
// be busy for a few seconds
|
||||
}
|
||||
console.log('ready'); // 1 output
|
||||
@@ -0,0 +1,32 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const data = fs.readFileSync('data/products.csv', 'UTF8');
|
||||
|
||||
const STOCK_WARN_AMOUNT = 5;
|
||||
|
||||
const products = data.split('\n');
|
||||
products.shift(); // remove header
|
||||
|
||||
const recordToHTML = (record) => {
|
||||
const fields = record.split(',');
|
||||
const html = `<li class="list-group-item">
|
||||
<h2>${fields[1]}</h2>
|
||||
<p>${fields[2]}</p>
|
||||
<p><strong>Price:</strong> EUR ${fields[4]}</p>
|
||||
${
|
||||
Number(fields[3]) <= STOCK_WARN_AMOUNT
|
||||
? '<p class="alert alert-warning">Last items in stock!</p>'
|
||||
: ''
|
||||
}
|
||||
</li>`;
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
const entries = products.filter((row) => row !== '').map(recordToHTML);
|
||||
|
||||
console.log('<ul class="list-group">');
|
||||
entries.forEach((entry) => console.log(entry));
|
||||
console.log('</ul>');
|
||||
|
||||
console.log('ready');
|
||||
@@ -0,0 +1,39 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const STOCK_WARN_AMOUNT = 5;
|
||||
|
||||
// Function to convert a CSV record to HTML
|
||||
const recordToHTML = (record) => {
|
||||
const fields = record.split(',');
|
||||
const html = `<li class="list-group-item">
|
||||
<h2>${fields[1]}</h2>
|
||||
<p>${fields[2]}</p>
|
||||
<p><strong>Price:</strong> EUR ${fields[4]}</p>
|
||||
${
|
||||
Number(fields[3]) <= STOCK_WARN_AMOUNT
|
||||
? '<p class="alert alert-warning">Last items in stock!</p>'
|
||||
: ''
|
||||
}
|
||||
</li>`;
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
// Asynchronous version
|
||||
fs.readFile('data/products.csv', 'UTF8', (err, data) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
const products = data.split('\n');
|
||||
products.shift(); // remove header
|
||||
|
||||
const entries = products.filter((row) => row !== '').map(recordToHTML);
|
||||
|
||||
console.log('<ul class="list-group">');
|
||||
entries.forEach((entry) => console.log(entry));
|
||||
console.log('</ul>');
|
||||
|
||||
console.log('ready');
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
const fs = require('fs'); // commonjs
|
||||
|
||||
const data = fs.readFileSync('data/products.csv', 'utf-8');
|
||||
|
||||
console.log(data);
|
||||
@@ -0,0 +1,34 @@
|
||||
// some, but not all fields are quoted - solution 1
|
||||
|
||||
const mixedCSV =
|
||||
'"very big, soft computer mouse","the cutest peripheral ever",10,39.90';
|
||||
|
||||
let fields = [];
|
||||
let index = 0;
|
||||
let state = 'outside';
|
||||
|
||||
mixedCSV.split('').forEach((char) => {
|
||||
if (state === 'quoted') {
|
||||
fields[index] += char; // => [",v,e,r,y..."]
|
||||
if (char === '"') {
|
||||
state = 'outside';
|
||||
index += 1;
|
||||
}
|
||||
} else if (state === 'unquoted') {
|
||||
if (char === ',') {
|
||||
state = 'outside';
|
||||
index += 1;
|
||||
} else {
|
||||
fields[index] += char;
|
||||
}
|
||||
} else if (state === 'outside') {
|
||||
fields[index] = char; //=> [",...
|
||||
if (char === '"') {
|
||||
state = 'quoted';
|
||||
} else if (char !== ',') {
|
||||
state = 'unquoted';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log(fields);
|
||||
@@ -0,0 +1,28 @@
|
||||
// some, but not all fields are quoted - solution 2/2
|
||||
|
||||
const mixedCSV =
|
||||
'"very big, soft computer mouse",' + '"the cutest peripheral ever",10,39.90';
|
||||
|
||||
let fields = [];
|
||||
|
||||
const mixedCSVToArray = (s) =>
|
||||
findCommaPositions(',' + s + ',')
|
||||
.map((position, i, positions) => s.slice(position, positions[i + 1] - 1))
|
||||
.slice(0, -1);
|
||||
|
||||
const findCommaPositions = (s) =>
|
||||
s
|
||||
.split('')
|
||||
.reduce(
|
||||
(positions, char, position) =>
|
||||
char === ',' && isEven(countQuotes(s.slice(0, position)))
|
||||
? positions.concat(position)
|
||||
: positions,
|
||||
[]
|
||||
);
|
||||
|
||||
const countQuotes = (s) => s.split('').filter((c) => c === '"').length;
|
||||
|
||||
const isEven = (num) => num % 2 === 0;
|
||||
|
||||
console.log(mixedCSVToArray(mixedCSV));
|
||||
@@ -0,0 +1,7 @@
|
||||
// all fields are quoted
|
||||
|
||||
const quotedCSV =
|
||||
'"very big, soft computer mouse","the cutest peripheral ever","10","39.90"';
|
||||
|
||||
const fields = quotedCSV.split('","');
|
||||
console.log(fields);
|
||||
@@ -0,0 +1,5 @@
|
||||
const fs = require('fs');
|
||||
const zlib = require('zlib');
|
||||
|
||||
const data = fs.readFileSync('data/products.html', 'UTF8');
|
||||
fs.writeFileSync('data/products.html.gz', zlib.gzipSync(data));
|
||||
@@ -0,0 +1,9 @@
|
||||
const fs = require('fs');
|
||||
const zlib = require('zlib');
|
||||
|
||||
const gzipCompressor = zlib.createGzip();
|
||||
|
||||
const inputStream = fs.createReadStream('data/products.html');
|
||||
const outputStream = fs.createWriteStream('data/products.html.gz');
|
||||
|
||||
inputStream.pipe(gzipCompressor).pipe(outputStream);
|
||||
@@ -0,0 +1,6 @@
|
||||
const crypto = require('crypto');
|
||||
|
||||
const data = 'Ich werde verschlüsselt!';
|
||||
const hash = crypto.createHash('sha256').update(data).digest('hex'); // 256-bit SHA-2 hash algorithm
|
||||
|
||||
console.log(hash); // 4803bce8b78d10b6bae3224c041f7c7311dedc056386870e50e6b56a109f4ee8
|
||||
@@ -0,0 +1 @@
|
||||
I am a text from a text file with the name file.txt
|
||||
@@ -0,0 +1 @@
|
||||
I am a text from a text file with the name file_1.txt
|
||||
@@ -0,0 +1 @@
|
||||
I am a text from a text file with the name file_2.txt
|
||||
@@ -0,0 +1 @@
|
||||
I am a text from a text file with the name file_3.txt
|
||||
@@ -0,0 +1,9 @@
|
||||
Code,Short Description,Tagline,Quantity,Price
|
||||
MUG0007,coffee mug with LCD level indicator,never again reach for the empty mug,20,49.90
|
||||
MUG0013,coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling,put the smart into coffee reading,20,99.90
|
||||
OFF3145,pen with pre-warmed ink (tested on the South Pole),the pen is mightier than the cold,50,29.90
|
||||
COM1001,ambidextrous computer mouse,end the dictate of left and right,10,19.90
|
||||
COM0404,Easter egg themed webcam for your monitor,put an Easter egg on hardware too,20,149.90
|
||||
COM0001,Vulcan language vi cheatsheet,learn vi and Vulcan at the same time,3,9.90
|
||||
COM1536,Klingon language emacs cheatsheet,learn emacs and Klingon at the same time,50,9.90
|
||||
MOB0555,smartphone case with built-in screen,never miss a message,20,39.90
|
||||
|
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Products</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container py-5">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<h2>coffee mug with LCD level indicator</h2>
|
||||
<p>never again reach for the empty mug</p>
|
||||
<p><strong>Price:</strong> EUR 49.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling</h2>
|
||||
<p>put the smart into coffee reading</p>
|
||||
<p><strong>Price:</strong> EUR 99.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>pen with pre-warmed ink (tested on the South Pole)</h2>
|
||||
<p>the pen is mightier than the cold</p>
|
||||
<p><strong>Price:</strong> EUR 29.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>ambidextrous computer mouse</h2>
|
||||
<p>end the dictate of left and right</p>
|
||||
<p><strong>Price:</strong> EUR 19.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>Easter egg themed webcam for your monitor</h2>
|
||||
<p>put an Easter egg on hardware too</p>
|
||||
<p><strong>Price:</strong> EUR 149.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>Vulcan language vi cheatsheet</h2>
|
||||
<p>learn vi and Vulcan at the same time</p>
|
||||
<p><strong>Price:</strong> EUR 9.90</p>
|
||||
<p class="alert alert-warning">Last items in stock!</p>
|
||||
</li><li class="list-group-item">
|
||||
<h2>Klingon language emacs cheatsheet</h2>
|
||||
<p>learn emacs and Klingon at the same time</p>
|
||||
<p><strong>Price:</strong> EUR 9.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>smartphone case with built-in screen</h2>
|
||||
<p>never miss a message</p>
|
||||
<p><strong>Price:</strong> EUR 39.90</p>
|
||||
|
||||
</li>
|
||||
</ul></div>
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
@@ -0,0 +1,72 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const STOCK_WARN_AMOUNT = 5;
|
||||
|
||||
// Function to convert a CSV record to HTML
|
||||
const recordToHTML = (record) => {
|
||||
const fields = record.split(',');
|
||||
const html = `<li class="list-group-item">
|
||||
<h2>${fields[1]}</h2>
|
||||
<p>${fields[2]}</p>
|
||||
<p><strong>Price:</strong> EUR ${fields[4]}</p>
|
||||
${
|
||||
Number(fields[3]) <= STOCK_WARN_AMOUNT
|
||||
? '<p class="alert alert-warning">Last items in stock!</p>'
|
||||
: ''
|
||||
}
|
||||
</li>`;
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
// Asynchronous version
|
||||
fs.readFile('data/products.csv', 'UTF8', (err, data) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
const products = data.split('\n');
|
||||
products.shift(); // remove header
|
||||
|
||||
const entries = products.filter((row) => row !== '').map(recordToHTML);
|
||||
|
||||
writeToFile(entries);
|
||||
});
|
||||
|
||||
const writeToFile = (entries) => {
|
||||
const headerStr = `<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Products</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container py-5">`;
|
||||
const footerStr = `</div>
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const html = `${headerStr}
|
||||
<ul class="list-group">
|
||||
${entries.join('')}
|
||||
</ul>${footerStr}`;
|
||||
|
||||
fs.writeFile('data/products.html', html, (err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
console.log('File written successfully');
|
||||
});
|
||||
|
||||
console.log('Writing file...');
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
Code,Short Description,Tagline,Quantity,Price
|
||||
MUG0007,coffee mug with LCD level indicator,never again reach for the empty mug,20,49.90
|
||||
MUG0013,coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling,put the smart into coffee reading,20,99.90
|
||||
OFF3145,pen with pre-warmed ink (tested on the South Pole),the pen is mightier than the cold,50,29.90
|
||||
COM1001,ambidextrous computer mouse,end the dictate of left and right,10,19.90
|
||||
COM0404,Easter egg themed webcam for your monitor,put an Easter egg on hardware too,20,149.90
|
||||
COM0001,Vulcan language vi cheatsheet,learn vi and Vulcan at the same time,3,9.90
|
||||
COM1536,Klingon language emacs cheatsheet,learn emacs and Klingon at the same time,50,9.90
|
||||
MOB0555,smartphone case with built-in screen,never miss a message,20,39.90
|
||||
|
Binary file not shown.
@@ -0,0 +1,73 @@
|
||||
const fs = require('fs');
|
||||
const zlib = require('zlib');
|
||||
|
||||
const STOCK_WARN_AMOUNT = 5;
|
||||
|
||||
// Function to convert a CSV record to HTML
|
||||
const recordToHTML = (record) => {
|
||||
const fields = record.split(',');
|
||||
const html = `<li class="list-group-item">
|
||||
<h2>${fields[1]}</h2>
|
||||
<p>${fields[2]}</p>
|
||||
<p><strong>Price:</strong> EUR ${fields[4]}</p>
|
||||
${
|
||||
Number(fields[3]) <= STOCK_WARN_AMOUNT
|
||||
? '<p class="alert alert-warning">Last items in stock!</p>'
|
||||
: ''
|
||||
}
|
||||
</li>`;
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
// Asynchronous version
|
||||
fs.readFile('data/products.csv', 'UTF8', (err, data) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
const products = data.split('\n');
|
||||
products.shift(); // remove header
|
||||
|
||||
const entries = products.filter((row) => row !== '').map(recordToHTML);
|
||||
|
||||
writeToFile(entries);
|
||||
});
|
||||
|
||||
const writeToFile = (entries) => {
|
||||
const headerStr = `<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Products</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container py-5">`;
|
||||
const footerStr = `</div>
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const html = `${headerStr}
|
||||
<ul class="list-group">
|
||||
${entries.join('')}
|
||||
</ul>${footerStr}`;
|
||||
|
||||
try {
|
||||
const compressed = zlib.gzipSync(html);
|
||||
fs.writeFileSync('data/products.html.gz', compressed);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('file written');
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
Code,Short Description,Tagline,Quantity,Price
|
||||
MUG0007,coffee mug with LCD level indicator,never again reach for the empty mug,20,49.90
|
||||
MUG0013,coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling,put the smart into coffee reading,20,99.90
|
||||
OFF3145,pen with pre-warmed ink (tested on the South Pole),the pen is mightier than the cold,50,29.90
|
||||
COM1001,ambidextrous computer mouse,end the dictate of left and right,10,19.90
|
||||
COM0404,Easter egg themed webcam for your monitor,put an Easter egg on hardware too,20,149.90
|
||||
COM0001,Vulcan language vi cheatsheet,learn vi and Vulcan at the same time,3,9.90
|
||||
COM1536,Klingon language emacs cheatsheet,learn emacs and Klingon at the same time,50,9.90
|
||||
MOB0555,smartphone case with built-in screen,never miss a message,20,39.90
|
||||
|
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Products</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container py-5">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<h2>coffee mug with LCD level indicator</h2>
|
||||
<p>never again reach for the empty mug</p>
|
||||
<p><strong>Price:</strong> EUR 49.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling</h2>
|
||||
<p>put the smart into coffee reading</p>
|
||||
<p><strong>Price:</strong> EUR 99.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>pen with pre-warmed ink (tested on the South Pole)</h2>
|
||||
<p>the pen is mightier than the cold</p>
|
||||
<p><strong>Price:</strong> EUR 29.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>ambidextrous computer mouse</h2>
|
||||
<p>end the dictate of left and right</p>
|
||||
<p><strong>Price:</strong> EUR 19.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>Easter egg themed webcam for your monitor</h2>
|
||||
<p>put an Easter egg on hardware too</p>
|
||||
<p><strong>Price:</strong> EUR 149.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>Vulcan language vi cheatsheet</h2>
|
||||
<p>learn vi and Vulcan at the same time</p>
|
||||
<p><strong>Price:</strong> EUR 9.90</p>
|
||||
<p class="alert alert-warning">Last items in stock!</p>
|
||||
</li><li class="list-group-item">
|
||||
<h2>Klingon language emacs cheatsheet</h2>
|
||||
<p>learn emacs and Klingon at the same time</p>
|
||||
<p><strong>Price:</strong> EUR 9.90</p>
|
||||
|
||||
</li><li class="list-group-item">
|
||||
<h2>smartphone case with built-in screen</h2>
|
||||
<p>never miss a message</p>
|
||||
<p><strong>Price:</strong> EUR 39.90</p>
|
||||
|
||||
</li>
|
||||
</ul></div>
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
const fs = require('fs');
|
||||
const zlib = require('zlib');
|
||||
|
||||
const inputStream = fs.createReadStream('data/products.html');
|
||||
const outputStream = fs.createWriteStream('data/products.html.gz');
|
||||
|
||||
inputStream.on('data', (data) => {
|
||||
outputStream.write(zlib.gzipSync(data));
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user