diff --git a/01_grundlagen/faq/xyz-example.js b/01_grundlagen/faq/xyz-example.js new file mode 100644 index 0000000..7f41cc2 --- /dev/null +++ b/01_grundlagen/faq/xyz-example.js @@ -0,0 +1,13 @@ +'use strict'; + +let x = () => { + a = 3; +}; +let y = () => (a = 5); +let z = () => { + console.log(a); +}; + +x(); +y(); +z(); diff --git a/01_grundlagen/uebungen/#o01_palindrom.html b/01_grundlagen/uebungen/#o01_palindrom.html index 6378d25..22562f5 100644 --- a/01_grundlagen/uebungen/#o01_palindrom.html +++ b/01_grundlagen/uebungen/#o01_palindrom.html @@ -1,4 +1,4 @@ - + @@ -40,6 +40,24 @@ diff --git a/01_grundlagen/uebungen/#u46_richtige-gewinner.html b/01_grundlagen/uebungen/#u46_richtige-gewinner.html deleted file mode 100644 index 48528b4..0000000 --- a/01_grundlagen/uebungen/#u46_richtige-gewinner.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - Übung 46: Richtige Gewinner - - - -
-
-
-

Übung 46: Richtige Gewinner

-

- Die Ausgabe der Gewinner aus dem letzten Beispiel (Codebeispiel 324) ist immer noch nicht ideal. Am Besten - wäre das folgende Ergebnis-Array: -

-
-            
-  [
-    '1st place: Heribert',
-    '2nd place: Friedlinde',
-    '3rd place: Tusnelda',
-    'Oswine',
-    'Ladislaus',
-  ]
-            
-          
-
-
-
-
- - - diff --git a/01_grundlagen/uebungen/#u47_higher-order-fn-lueckentext.html b/01_grundlagen/uebungen/#u47_higher-order-fn-lueckentext.html deleted file mode 100644 index 8b0f6d2..0000000 --- a/01_grundlagen/uebungen/#u47_higher-order-fn-lueckentext.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - Übung 47: Lückentext zu Higher-Order-Funktionen - - - -
-
-

Übung 47: Lückentext zu Higher-Order-Funktionen

-

- Das ist garantiert der letzte Lückentext für diese Lektion. Ersetzen Sie wieder die Kommentare - /* ??? */ durch den richtigen Code, um das angegebene Ergebnis zu erzielen. -

-
-
- - - diff --git a/01_grundlagen/uebungen/u46_richtige-gewinner.html b/01_grundlagen/uebungen/u46_richtige-gewinner.html new file mode 100644 index 0000000..fde3da0 --- /dev/null +++ b/01_grundlagen/uebungen/u46_richtige-gewinner.html @@ -0,0 +1,100 @@ + + + + + + Übung 46: Richtige Gewinner + + + +
+
+
+

Übung 46: Richtige Gewinner

+

+ Die Ausgabe der Gewinner aus dem letzten Beispiel (Codebeispiel 324) ist immer noch nicht ideal. Am Besten + wäre das folgende Ergebnis-Array: +

+
+            
+  [
+    '1st place: Heribert',
+    '2nd place: Friedlinde',
+    '3rd place: Tusnelda',
+    'Oswine',
+    'Ladislaus',
+  ]
+            
+          
+
+
+
+
+ + + diff --git a/01_grundlagen/uebungen/u47_higher-order-fn-lueckentext.html b/01_grundlagen/uebungen/u47_higher-order-fn-lueckentext.html new file mode 100644 index 0000000..67cc15e --- /dev/null +++ b/01_grundlagen/uebungen/u47_higher-order-fn-lueckentext.html @@ -0,0 +1,173 @@ + + + + + + Übung 47: Lückentext zu Higher-Order-Funktionen + + + +
+
+

Übung 47: Lückentext zu Higher-Order-Funktionen

+

+ Das ist garantiert der letzte Lückentext für diese Lektion. Ersetzen Sie wieder die Kommentare + /* ??? */ durch den richtigen Code, um das angegebene Ergebnis zu erzielen. +

+
+
+ + + diff --git a/01_grundlagen/uebungen/#u48_froehliches-mixen.html b/01_grundlagen/uebungen/u48_froehliches-mixen.html similarity index 80% rename from 01_grundlagen/uebungen/#u48_froehliches-mixen.html rename to 01_grundlagen/uebungen/u48_froehliches-mixen.html index 9508b77..dfb529d 100644 --- a/01_grundlagen/uebungen/#u48_froehliches-mixen.html +++ b/01_grundlagen/uebungen/u48_froehliches-mixen.html @@ -1,4 +1,4 @@ - + @@ -28,7 +28,13 @@ ", + "\t", + "" + ], + "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" + } +} diff --git a/02_advanced/MATERIAL/advanced-js/lesson_01/examples/names_params.js b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/names_params.js new file mode 100644 index 0000000..e11c920 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/names_params.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv.js b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv.js new file mode 100644 index 0000000..54a1c98 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_dest.js b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_dest.js new file mode 100644 index 0000000..e34db47 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_dest.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_object.js b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_object.js new file mode 100644 index 0000000..fb59358 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_object.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_params.js b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_params.js new file mode 100644 index 0000000..28f7334 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_params.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_trim.js b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_trim.js new file mode 100644 index 0000000..abd7f26 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_csv_trim.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_obj_dest.js b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_obj_dest.js new file mode 100644 index 0000000..6a1489a --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_01/examples/prod_obj_dest.js @@ -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)); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_01/solutions/distance/index.js b/02_advanced/MATERIAL/advanced-js/lesson_01/solutions/distance/index.js new file mode 100644 index 0000000..eedc0e2 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_01/solutions/distance/index.js @@ -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 })); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_01/solutions/transformed_name/index.js b/02_advanced/MATERIAL/advanced-js/lesson_01/solutions/transformed_name/index.js new file mode 100644 index 0000000..de83190 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_01/solutions/transformed_name/index.js @@ -0,0 +1,6 @@ +'use strict'; + +const logTransformedName = ({ firstName, lastName }) => + console.log(`${lastName}, ${firstName.charAt(0)}.`); + +logTransformedName({ firstName: 'Ladislaus', lastName: 'Jones' }); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/examples/factorial.js b/02_advanced/MATERIAL/advanced-js/lesson_02/examples/factorial.js new file mode 100644 index 0000000..c3f11bc --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/examples/factorial.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/examples/fibonacci.js b/02_advanced/MATERIAL/advanced-js/lesson_02/examples/fibonacci.js new file mode 100644 index 0000000..b533f92 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/examples/fibonacci.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/examples/fibonacciMemo.js b/02_advanced/MATERIAL/advanced-js/lesson_02/examples/fibonacciMemo.js new file mode 100644 index 0000000..536cfaf --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/examples/fibonacciMemo.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/examples/sumArray.js b/02_advanced/MATERIAL/advanced-js/lesson_02/examples/sumArray.js new file mode 100644 index 0000000..87013cd --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/examples/sumArray.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/examples/sumArrayIndex.js b/02_advanced/MATERIAL/advanced-js/lesson_02/examples/sumArrayIndex.js new file mode 100644 index 0000000..fe1c852 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/examples/sumArrayIndex.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/combinations/index.js b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/combinations/index.js new file mode 100644 index 0000000..513928d --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/combinations/index.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/deepestLevel/index.js b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/deepestLevel/index.js new file mode 100644 index 0000000..7cd1551 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/deepestLevel/index.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/findMax/index.js b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/findMax/index.js new file mode 100644 index 0000000..fa4a584 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/findMax/index.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/reverseString/index.js b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/reverseString/index.js new file mode 100644 index 0000000..128e926 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/reverseString/index.js @@ -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" diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/sumNestedArray/index.js b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/sumNestedArray/index.js new file mode 100644 index 0000000..34a326a --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/sumNestedArray/index.js @@ -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) diff --git a/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/sumRecursive/index.js b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/sumRecursive/index.js new file mode 100644 index 0000000..33b0c6e --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_02/solutions/sumRecursive/index.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/examples/promise_4.js b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/promise_4.js new file mode 100644 index 0000000..a283095 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/promise_4.js @@ -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) +); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/examples/promise_stack_trace.js b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/promise_stack_trace.js new file mode 100644 index 0000000..1eece7b --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/promise_stack_trace.js @@ -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); + }); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/examples/promise_wait.js b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/promise_wait.js new file mode 100644 index 0000000..1976a53 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/promise_wait.js @@ -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... diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/examples/pyramid_of_doom.js b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/pyramid_of_doom.js new file mode 100644 index 0000000..61c36f5 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/pyramid_of_doom.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/examples/pyramid_of_doom_avoided.js b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/pyramid_of_doom_avoided.js new file mode 100644 index 0000000..f72d23b --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/pyramid_of_doom_avoided.js @@ -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.')); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_async.js b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_async.js new file mode 100644 index 0000000..eee6b85 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_async.js @@ -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); + } +}); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_promise.js b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_promise.js new file mode 100644 index 0000000..babb5e8 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_promise.js @@ -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}`)); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_promises.js b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_promises.js new file mode 100644 index 0000000..6f10bc7 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_promises.js @@ -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}`)); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_util_promisify.js b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_util_promisify.js new file mode 100644 index 0000000..4140c18 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/examples/read_file_util_promisify.js @@ -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}`)); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/dns_lookup/solution_1.js b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/dns_lookup/solution_1.js new file mode 100644 index 0000000..74387dd --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/dns_lookup/solution_1.js @@ -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); +// } +// }); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/dns_lookup/solution_2.js b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/dns_lookup/solution_2.js new file mode 100644 index 0000000..2133e5f --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/dns_lookup/solution_2.js @@ -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); +// } +// }); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/dns_lookup/solution_3.js b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/dns_lookup/solution_3.js new file mode 100644 index 0000000..b086b54 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/dns_lookup/solution_3.js @@ -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); +// } +// }); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_1.txt b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_1.txt new file mode 100644 index 0000000..62d7e98 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_1.txt @@ -0,0 +1 @@ +This is the contents of file 01. \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_2.txt b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_2.txt new file mode 100644 index 0000000..77e704a --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_2.txt @@ -0,0 +1 @@ +This is the contents of file 02. \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_3.txt b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_3.txt new file mode 100644 index 0000000..d1837d5 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_3.txt @@ -0,0 +1 @@ +This is the contents of file 03. \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_4.txt b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_4.txt new file mode 100644 index 0000000..5eed5fe --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_4.txt @@ -0,0 +1 @@ +This is the contents of file 04. \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_5.txt b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_5.txt new file mode 100644 index 0000000..1e63085 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_5.txt @@ -0,0 +1 @@ +This is the contents of file 05. \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_6.txt b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_6.txt new file mode 100644 index 0000000..996b394 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/data/file_6.txt @@ -0,0 +1 @@ +This is the contents of file 06. \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/index.js b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/index.js new file mode 100644 index 0000000..e743cf2 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/getFileContent/index.js @@ -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); + }); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/printWords/index.js b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/printWords/index.js new file mode 100644 index 0000000..c2a221c --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_03/solutions/printWords/index.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess.js b/02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess.js new file mode 100644 index 0000000..6e553e1 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess.js @@ -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'))); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess_exec.js b/02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess_exec.js new file mode 100644 index 0000000..284cb05 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess_exec.js @@ -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']))); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess_final.js b/02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess_final.js new file mode 100644 index 0000000..8280ec6 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/examples/chess_final.js @@ -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')); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/examples/grades_table.js b/02_advanced/MATERIAL/advanced-js/lesson_04/examples/grades_table.js new file mode 100644 index 0000000..6427e39 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/examples/grades_table.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/examples/inventory.js b/02_advanced/MATERIAL/advanced-js/lesson_04/examples/inventory.js new file mode 100644 index 0000000..4a93baf --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/examples/inventory.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/cocktails/index.js b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/cocktails/index.js new file mode 100644 index 0000000..c1a2abd --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/cocktails/index.js @@ -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' ] diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/geoquiz_1/index.js b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/geoquiz_1/index.js new file mode 100644 index 0000000..a1ee9b8 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/geoquiz_1/index.js @@ -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')); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/geoquiz_2/index.js b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/geoquiz_2/index.js new file mode 100644 index 0000000..0b1b56b --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/geoquiz_2/index.js @@ -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')); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/grades_table/index.js b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/grades_table/index.js new file mode 100644 index 0000000..534d1e3 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/grades_table/index.js @@ -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] diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/image_edit/index.js b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/image_edit/index.js new file mode 100644 index 0000000..0b61d39 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/image_edit/index.js @@ -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], + ], + ] +*/ diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/inventory/index.js b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/inventory/index.js new file mode 100644 index 0000000..5d5ba81 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/inventory/index.js @@ -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], + ], +] +*/ diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/pokemon/index.js b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/pokemon/index.js new file mode 100644 index 0000000..3fb0b4d --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/pokemon/index.js @@ -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' ] diff --git a/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/shopping_list/index.js b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/shopping_list/index.js new file mode 100644 index 0000000..7903be1 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_04/solutions/shopping_list/index.js @@ -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'], +// ] diff --git a/02_advanced/MATERIAL/advanced-js/lesson_05/examples/displayPosts.html b/02_advanced/MATERIAL/advanced-js/lesson_05/examples/displayPosts.html new file mode 100644 index 0000000..4fb53c3 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_05/examples/displayPosts.html @@ -0,0 +1,45 @@ + + + + + + Display Posts + + +

List of Posts

+ + + + + diff --git a/02_advanced/MATERIAL/advanced-js/lesson_05/examples/displayPostsDetails.html b/02_advanced/MATERIAL/advanced-js/lesson_05/examples/displayPostsDetails.html new file mode 100644 index 0000000..9496034 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_05/examples/displayPostsDetails.html @@ -0,0 +1,73 @@ + + + + + + Display Post Details + + +

List of Posts

+ + +
+

+

+ +
+ + + + diff --git a/02_advanced/MATERIAL/advanced-js/lesson_05/examples/fetchAPIData.js b/02_advanced/MATERIAL/advanced-js/lesson_05/examples/fetchAPIData.js new file mode 100644 index 0000000..c99cd3e --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_05/examples/fetchAPIData.js @@ -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(); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_05/examples/jsonToObj.js b/02_advanced/MATERIAL/advanced-js/lesson_05/examples/jsonToObj.js new file mode 100644 index 0000000..9a6e96b --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_05/examples/jsonToObj.js @@ -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); +} diff --git a/02_advanced/MATERIAL/advanced-js/lesson_05/examples/try_catch.js b/02_advanced/MATERIAL/advanced-js/lesson_05/examples/try_catch.js new file mode 100644 index 0000000..0dd9dde --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_05/examples/try_catch.js @@ -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); + }); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_05/solutions/fetchUsers/index.js b/02_advanced/MATERIAL/advanced-js/lesson_05/solutions/fetchUsers/index.js new file mode 100644 index 0000000..860da25 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_05/solutions/fetchUsers/index.js @@ -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(); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_05/solutions/jsonBook/index.js b/02_advanced/MATERIAL/advanced-js/lesson_05/solutions/jsonBook/index.js new file mode 100644 index 0000000..233c47c --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_05/solutions/jsonBook/index.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_07/examples/data/products.csv b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/data/products.csv new file mode 100644 index 0000000..38fe75a --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/data/products.csv @@ -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 \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_07/examples/data/products.html b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/data/products.html new file mode 100644 index 0000000..ceecd0f --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/data/products.html @@ -0,0 +1,61 @@ + + + + + + Products + + + +
+
+
+
+ + + \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_07/examples/data/products.html.gz b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/data/products.html.gz new file mode 100644 index 0000000..c670ddf Binary files /dev/null and b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/data/products.html.gz differ diff --git a/02_advanced/MATERIAL/advanced-js/lesson_07/examples/products_async_busy.js b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/products_async_busy.js new file mode 100644 index 0000000..e3a7dac --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/products_async_busy.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_07/examples/products_to_html.js b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/products_to_html.js new file mode 100644 index 0000000..e602bea --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/products_to_html.js @@ -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 = `
  • +

    ${fields[1]}

    +

    ${fields[2]}

    +

    Price: EUR ${fields[4]}

    + ${ + Number(fields[3]) <= STOCK_WARN_AMOUNT + ? '

    Last items in stock!

    ' + : '' + } +
  • `; + + return html; +}; + +const entries = products.filter((row) => row !== '').map(recordToHTML); + +console.log(''); + +console.log('ready'); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_07/examples/products_to_html_async.js b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/products_to_html_async.js new file mode 100644 index 0000000..f30465f --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/products_to_html_async.js @@ -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 = `
  • +

    ${fields[1]}

    +

    ${fields[2]}

    +

    Price: EUR ${fields[4]}

    + ${ + Number(fields[3]) <= STOCK_WARN_AMOUNT + ? '

    Last items in stock!

    ' + : '' + } +
  • `; + + 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(''); + + console.log('ready'); +}); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_07/examples/read_products.js b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/read_products.js new file mode 100644 index 0000000..fe01e55 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_07/examples/read_products.js @@ -0,0 +1,5 @@ +const fs = require('fs'); // commonjs + +const data = fs.readFileSync('data/products.csv', 'utf-8'); + +console.log(data); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_07/solutions/mixedCSV/solution_1.js b/02_advanced/MATERIAL/advanced-js/lesson_07/solutions/mixedCSV/solution_1.js new file mode 100644 index 0000000..23cb653 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_07/solutions/mixedCSV/solution_1.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_07/solutions/mixedCSV/solution_2.js b/02_advanced/MATERIAL/advanced-js/lesson_07/solutions/mixedCSV/solution_2.js new file mode 100644 index 0000000..47f3585 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_07/solutions/mixedCSV/solution_2.js @@ -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)); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_07/solutions/quotedCSV/index.js b/02_advanced/MATERIAL/advanced-js/lesson_07/solutions/quotedCSV/index.js new file mode 100644 index 0000000..7832a01 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_07/solutions/quotedCSV/index.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/compress_file.js b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/compress_file.js new file mode 100644 index 0000000..eedfc40 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/compress_file.js @@ -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)); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/compress_streams.js b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/compress_streams.js new file mode 100644 index 0000000..224710b --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/compress_streams.js @@ -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); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/create_hash.js b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/create_hash.js new file mode 100644 index 0000000..920fc4a --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/create_hash.js @@ -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 diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file.txt b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file.txt new file mode 100644 index 0000000..0cdffb2 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file.txt @@ -0,0 +1 @@ +I am a text from a text file with the name file.txt \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file_1.txt b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file_1.txt new file mode 100644 index 0000000..78686f0 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file_1.txt @@ -0,0 +1 @@ +I am a text from a text file with the name file_1.txt \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file_2.txt b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file_2.txt new file mode 100644 index 0000000..cfde461 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file_2.txt @@ -0,0 +1 @@ +I am a text from a text file with the name file_2.txt \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file_3.txt b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file_3.txt new file mode 100644 index 0000000..22b9a04 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/file_3.txt @@ -0,0 +1 @@ +I am a text from a text file with the name file_3.txt \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/products.csv b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/products.csv new file mode 100644 index 0000000..38fe75a --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/products.csv @@ -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 \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/products.html b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/products.html new file mode 100644 index 0000000..ceecd0f --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/products.html @@ -0,0 +1,61 @@ + + + + + + Products + + + +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/products.html.gz b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/products.html.gz new file mode 100644 index 0000000..c670ddf Binary files /dev/null and b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/data/products.html.gz differ diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/examples/products_to_html_file.js b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/products_to_html_file.js new file mode 100644 index 0000000..9cc1350 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/examples/products_to_html_file.js @@ -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 = `
  • +

    ${fields[1]}

    +

    ${fields[2]}

    +

    Price: EUR ${fields[4]}

    + ${ + Number(fields[3]) <= STOCK_WARN_AMOUNT + ? '

    Last items in stock!

    ' + : '' + } +
  • `; + + 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 = ` + + + + + Products + + + +
    +
    `; + const footerStr = `
    +
    + + +`; + + const html = `${headerStr} + ${footerStr}`; + + fs.writeFile('data/products.html', html, (err) => { + if (err) { + console.error(err); + return; + } + console.log('File written successfully'); + }); + + console.log('Writing file...'); +}; diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products/data/products.csv b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products/data/products.csv new file mode 100644 index 0000000..38fe75a --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products/data/products.csv @@ -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 \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products/data/products.html.gz b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products/data/products.html.gz new file mode 100644 index 0000000..c670ddf Binary files /dev/null and b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products/data/products.html.gz differ diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products/index.js b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products/index.js new file mode 100644 index 0000000..cd4ed48 --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products/index.js @@ -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 = `
  • +

    ${fields[1]}

    +

    ${fields[2]}

    +

    Price: EUR ${fields[4]}

    + ${ + Number(fields[3]) <= STOCK_WARN_AMOUNT + ? '

    Last items in stock!

    ' + : '' + } +
  • `; + + 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 = ` + + + + + Products + + + +
    +
    `; + const footerStr = `
    +
    + + +`; + + const html = `${headerStr} + ${footerStr}`; + + try { + const compressed = zlib.gzipSync(html); + fs.writeFileSync('data/products.html.gz', compressed); + } catch (err) { + console.error(err); + return; + } + + console.log('file written'); +}; diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/data/products.csv b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/data/products.csv new file mode 100644 index 0000000..38fe75a --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/data/products.csv @@ -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 \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/data/products.html b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/data/products.html new file mode 100644 index 0000000..ceecd0f --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/data/products.html @@ -0,0 +1,61 @@ + + + + + + Products + + + +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/data/products.html.gz b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/data/products.html.gz new file mode 100644 index 0000000..c670ddf Binary files /dev/null and b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/data/products.html.gz differ diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/index.js b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/index.js new file mode 100644 index 0000000..1bfb57d --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/compress_products_nopipe/index.js @@ -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)); +}); diff --git a/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/password_generator/index.js b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/password_generator/index.js new file mode 100644 index 0000000..909a38f --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_08/solutions/password_generator/index.js @@ -0,0 +1,17 @@ +const crypto = require('crypto'); + +const PASSWORD_LENGTH = 10; +const s = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ!.,;#$%/+*'; + +const buf = crypto.randomBytes(PASSWORD_LENGTH); + +console.log(buf); // gibt ein Buffer Objekt zurück (z.B. ) +const password = Array.from(buf); + +constole.log(password); // gibt ein Array zurück mit Werten zwischen 0 und 255 (z.B. [ 144, 127, 61, 29, 31, 125, 125, 125, 125, 125 ]) + +password + .map((byte) => s.charAt(byte % s.length)) // gibt ein Array zurück mit den Zeichen aus s (z.B. [ '3', '7', 'h', 'G', 'J', 'z', 'z', 'z', 'z', 'z' ]) + .join(''); // wandelt das Array in einen String um. + +console.log(password); // gibt das generierte Passwort zurück (z.B. '37hGJzzzzz') diff --git a/02_advanced/MATERIAL/advanced-js/lesson_09/solutions/os_cores/index.js b/02_advanced/MATERIAL/advanced-js/lesson_09/solutions/os_cores/index.js new file mode 100644 index 0000000..b8fb79b --- /dev/null +++ b/02_advanced/MATERIAL/advanced-js/lesson_09/solutions/os_cores/index.js @@ -0,0 +1,12 @@ +'use strict'; + +// Import the 'os' module to access operating system-related utility methods +const os = require('os'); + +// Get the platform of the operating system (e.g., 'linux', 'win32', 'darwin') +const system = os.platform(); + +// Get the number of CPU cores available on the machine +const cpus = os.cpus().length; + +console.log(`I am running on a machine with ${system} and ${cpus} cores.`); diff --git a/01_grundlagen/agenda.md b/02_advanced/agenda.md similarity index 89% rename from 01_grundlagen/agenda.md rename to 02_advanced/agenda.md index c8a4774..517a01a 100644 --- a/01_grundlagen/agenda.md +++ b/02_advanced/agenda.md @@ -192,7 +192,7 @@ theme: default **Übungen:** -Übung 04 - 06 +Übung 04 - 08 --- @@ -200,7 +200,7 @@ theme: default **Inhalt:** -- Installation von node (npm) +- Installation von node (npm) und Windows Terminal (für Node) - **Exkurs: Switch Case Abfragen** - **Exkurs: Statische Webseite mit Sass und HTML** - **Exkurs: Versionierung mit Github Part I** @@ -213,11 +213,26 @@ theme: default **Inhalt:** +- Promise Aufbau +- Promise in Funktionen +- File System von Node - commonjs vs esm - async await -- Wiederholung der Inhalte -- 1:1 Meeting **Übungen:** -Übung 05 - 10 +Übung 09 - 10 + +--- + +#### Tag 15 + +**Inhalt:** + +- Wiederholung der Inhalte +- commonjs vs esm +- async await +- Promise.all() +- **Exkurs: Statische Webseite mit Sass und HTML** +- **Exkurs: Versionierung mit Github Part I** +- 1:1 Meeting diff --git a/01_grundlagen/linksammlung.md b/02_advanced/linksammlung.md similarity index 100% rename from 01_grundlagen/linksammlung.md rename to 02_advanced/linksammlung.md