diff --git a/content/cz/2-1-Identifiers.md b/content/cz/2-1-Identifiers.md index a3298ae..91744b7 100644 --- a/content/cz/2-1-Identifiers.md +++ b/content/cz/2-1-Identifiers.md @@ -1,3 +1,38 @@ ## 2.1. Hodnota, identifikátor, proměnná a konstanta, literál, přiřazení -No translation +```js +const INTERVAL = 500; +let counter = 0; +const MAX_VALUE = 10; +let timer = null; + +const event = () => { + if (counter === MAX_VALUE) { + console.log('The end'); + clearInterval(timer); + return; + } + console.dir({ counter, date: new Date() }); + counter++; +}; + +console.log('Begin'); +timer = setInterval(event, INTERVAL); +``` + +```js +// Constants + +const SALUTATION = 'Ave'; + +const COLORS = [ + /* 0 */ 'černá', + /* 1 */ 'červená', + /* 2 */ 'zelená', + /* 3 */ 'žlutá', + /* 4 */ 'modrá', + /* 5 */ 'magenta', + /* 6 */ 'cyan', + /* 7 */ 'bílá', +]; +``` diff --git a/content/cz/2-2-Types.md b/content/cz/2-2-Types.md index 3566c1c..068a046 100644 --- a/content/cz/2-2-Types.md +++ b/content/cz/2-2-Types.md @@ -1,3 +1,42 @@ ## 2.2. Datové typy, skalární, referenční a strukturované typy -No translation +> Typ — množina hodnot a operací, které lze na těchto hodnotách provádět. + +Například v `JavaScript` typ `Boolean` předpokládá dvě hodnoty `true` a `false` a logické operace na nich, typ `Null` předpokládá jednu hodnotu `null` a typ `Number` je množina racionálních čísel s dodatečnými omezeními na minimální a maximální hodnoty, stejně jako omezení na přesnost a matematické operace `+ - * ** / % ++ -- > < >= <= & | ~ ^ << >>`. + +> Datové typy + +```js +const values = [5, 'Praha', true, { size: 10 }, (a) => ++a]; + +const types = values.map((x) => typeof x); +console.log({ types }); +``` + +> Skalární (Primitivní, Atomická hodnota) — hodnota primitivního datového typu. + +Skalární hodnota se kopíruje při přiřazení a předává se funkci hodnotou. + +> Reference ukazuje na hodnotu referenčního typu, tj. ne skalární hodnotu. + +Pro `JavaScript` jsou to podtypy: `Object`, `Function`, `Array`. + +> Strukturované typy (Složené typy) — složené typy nebo struktury, které se skládají z několika skalárních hodnot. + +Skalární hodnoty jsou kombinovány do jedné takovým způsobem, že na této kombinované hodnotě lze provádět sadu operací. Například: objekt, pole, množina, n-tice. + +> Výčtový typ + +> Příznak — logická hodnota, která určuje stav něčeho. + +Například: stav uzavřeného připojení, stav dokončení vyhledávání nad datovou strukturou atd. + +```js +let flagName = false; +``` + +Někdy se příznaky mohou nazývat ne logické, ale výčtové typy. + +> Řetězec — posloupnost znaků + +Ve většině jazyků lze ke každému znaku přistupovat pomocí syntaxe přístupu k poli, jako jsou hranaté závorky. diff --git a/content/cz/2-3-Blocks.md b/content/cz/2-3-Blocks.md index 8567917..f0a21a1 100644 --- a/content/cz/2-3-Blocks.md +++ b/content/cz/2-3-Blocks.md @@ -1,3 +1,15 @@ ## 2.3. Operátor a výraz, blok kódu, funkce, smyčka, podmínka -No translation +```js +(len - 1) * f(x, INTERVAL); +``` + +```js +const MAX_VALUE = 10; + +console.log('Begin'); +for (let i = 0; i < MAX_VALUE; i++) { + console.dir({ i, date: new Date() }); +} +console.log('The end'); +``` diff --git a/content/cz/2-4-Context.md b/content/cz/2-4-Context.md index 5eef6af..8c8dfeb 100644 --- a/content/cz/2-4-Context.md +++ b/content/cz/2-4-Context.md @@ -1,3 +1,47 @@ ## 2.4. Kontexty a lexikální rozsah -No translation +> Oblast viditelnosti (Scope) + +Oblast viditelnosti - část kódu, ze které je "viditelný" identifikátor. Podívejme se na příklad: + +```js +const level = 1; + +const f = () => { + const level = 2; + { + const level = 3; + console.log(level); // 3 + } + console.log(level); // 2 +}; +``` + +V moderním standardu JavaScript je oblast viditelnosti vytvářena funkcí nebo jakýmkoli blokem příkazů, který má složené závorky {}. V Pythonu je scope vytvářen pouze funkcemi. Porovnejte tento kód s předchozím příkladem: + +```py +level = 1 + +def f(): + level = 2 + if level == 2: + level = 3 + print(level) // 3 + print(level) // 3 + +f() +``` + +> Lexikální kontext (Lexical environment) + +Sada identifikátorů dostupných v lokálním bloku nebo funkci. Pokud identifikátor není nalezen v lexikálním kontextu, vyhledávání pokračuje v nadřazeném kontextu, protože kontexty mají vnořenou strukturu. Pokud se po dosažení kořene identifikátor nenajde, bude provedeno vyhledávání v globálním kontextu. Pro JavaScript jsou lexikální kontexty omezeny bloky {} a funkcemi, pro Python pouze funkcemi. + +Lexikální kontext nebo lexikální prostředí má vnořenost, tj. kromě lokálních proměnných v bloku, který vytváří kontext, existuje i nadřazený blok se svým kontextem. Pokud je identifikátor definován v nadřazeném kontextu, je viditelný ve všech vnořených, pokud nedochází k překrytí názvů. Překrytí je případ, kdy je ve vnořeném kontextu znovu deklarován identifikátor, který již existuje ve vnějším, pak se hodnota z vnějšího kontextu stává nedostupnou a můžeme přistupovat pouze k vnitřnímu. + +> Objektový kontext + +Objekt dostupný z metod a funkcí prostřednictvím speciálního identifikátoru `this` se také používá jako kontext. Ve většině programovacích jazyků se metoda váže s `this` při vytváření objektu třídy. Ale v JavaScriptu mohou být funkce připojeny k `this` pomocí `bind` nebo jednorázově volány v kontextu objektu prostřednictvím `call` a `apply`. Všechny funkce kromě šipkových mohou být vázány s objekty. + +> Globální kontext (Global context) + +Pokud identifikátor není nalezen v žádném z vnořených lexikálních kontextů, bude provedeno jeho vyhledávání v globálním objektu-referenčním, který je globálním kontextem (v JavaScriptu `global` nebo `window`). diff --git a/content/cz/2-5-Procedure.md b/content/cz/2-5-Procedure.md index d559a0f..c5b8ba5 100644 --- a/content/cz/2-5-Procedure.md +++ b/content/cz/2-5-Procedure.md @@ -1,3 +1,53 @@ ## 2.5. Procedurální paradigma, volání, zásobník a halda -No translation +> Procedura nebo podprogram (Procedure, Subroutine) - logicky související skupina instrukcí nebo operátorů, která má jméno. + +Procedura podporuje opakované použití kódu a může být volána z různých částí programu mnohokrát a s různými argumenty. Procedura nevrací hodnoty, na rozdíl od funkcí, ale v některých jazycích (ale ne v JavaScript) může modifikovat své argumenty. V mnoha jazycích je procedura popsána pomocí syntaxe funkcí (například typu void). + +> Funkce (Function) - abstrakce transformace hodnot. Funkce jednoznačně mapuje jednu množinu hodnot na jinou množinu hodnot. + +Funkce může být zadána blokem operátorů nebo výrazem. Funkce má sadu argumentů. Funkce může být volána podle jména nebo prostřednictvím ukazatele. Funkce podporuje opakované použití kódu a může být volána z různých částí programu mnohokrát a s různými argumenty. V JavaScriptu je funkce popsána pomocí `function` nebo syntaxe šipek (lambda funkcí). + +Signatura funkce (Function signature) zahrnuje: jméno (identifikátor), počet argumentů a jejich typy (a někdy i jména argumentů), typ výsledku. + +> Metoda - funkce nebo procedura spojená s objektem nebo třídou. + +```js +{ + a: 10, + b: 10, + sum() { + return this.a + this.b; + } +} +``` + +```js +const colorer = (s, color) => `\x1b[3${color}m${s}\x1b[0m`; + +const colorize = (name) => { + let res = ''; + const letters = name.split(''); + let color = 0; + for (const letter of letters) { + res += colorer(letter, color++); + if (color > COLORS.length) color = 0; + } + return res; +}; + +const greetings = (name) => + name.includes('Augustus') + ? `${SALUTATION}, ${colorize(name)}!` + : `Hello, ${name}!`; +``` + +> Použití + +```js +const fullName = 'Marcus Aurelius Antoninus Augustus'; +console.log(greetings(fullName)); + +const shortName = 'Marcus Aurelius'; +console.log(greetings(shortName)); +``` diff --git a/content/cz/2-6-Function.md b/content/cz/2-6-Function.md index 768ecb9..e97316e 100644 --- a/content/cz/2-6-Function.md +++ b/content/cz/2-6-Function.md @@ -1,3 +1,118 @@ ## 2.6. Funkce vyššího řádu, čistá funkce, vedlejší účinky -No translation +Deklarace funkce (Function definition) - v `JavaScript` je to způsob deklarace funkce, který je viditelný odkudkoli v lexikálním kontextu, ve kterém je funkce deklarována, příklad: + +```js +function sum(a, b) { + return a + b; +} +``` + +Funkční výraz (Function expression) - propojení funkce s identifikátorem pomocí přiřazení, kde hodnota je dostupná prostřednictvím identifikátoru ne v celém lexikálním kontextu, ale pouze po místě přiřazení. Má několik syntaktických variant: + +Funkční výraz s pojmenovanou funkcí (Named function expression): + +```js +const sum = function sum(a, b) { + return a + b; +}; +``` + +Anonymní funkční výraz (Anonymous function expression): + +```js +const sum = function (a, b) { + return a + b; +}; +``` + +Šipková nebo lambda funkce (Arrow, Lambda function): + +```js +const sum = (a, b) => { + return a + b; +}; +``` + +Lambda výraz, šipková funkce s výrazem jako tělem (Lambda expression, Arrow function): + +```js +const sum = (a, b) => a + b; +``` + +> Čistá funkce (Pure Function) - deterministická funkce bez vedlejších účinků. + +Čistá funkce je funkce, která počítá výsledek pouze na základě argumentů, nemá stav a nepřistupuje k operacím vstupu-výstupu. Výsledek takové funkce je vždy deterministický a bez vedlejších účinků (viz vedlejší účinek). + +> Uzávěr (Closure) - funkce spojená s lexikálním prostředím v okamžiku svého vytvoření. + +Pokud je funkce `g` vrácena z funkce `f`, pak `g` uvidí kontext funkce `f`, stejně jako své vlastní argumenty. Pokud `f` vrací `g`, říká se, že instance `g` uzavřela kontext `f`. Uzávěr je způsob, jak propojit funkci s kontextem (s daty nebo kontextovými proměnnými). Uzávěr umožňuje vytvořit efekt podobný stavu objektu (sadě jeho vlastností) v OOP. Vlastnosti jsou propojeny s metodami prostřednictvím objektu, v podstatě je objekt v OOP sám kontextem propojení. Uzávěr také vytváří podobný kontext, ale na základě funkcí první třídy a lexikálního kontextu, ne objektově orientovaného. + +Pomocí uzávěrů lze implementovat funkční dědičnost. + +Příklady: + +```js +const sum = (a) => (b) => a + b; + +const hash = + (data = {}) => + (key, value) => ((data[key] = value), data); +``` + +> Superpozice (Superposition) - kombinace volání funkcí ve výrazech tak, že výsledek některých funkcí se stává argumenty jiných funkcí. + +```js +const expr2 = sum( + pow(mul(5, 8), 2), + div(inc(sqrt(20)), log(2, 7)) +); +``` + +> Kompozice (Composition) - vytvoření nové funkce kombinací jednodušších. + +```js +const compose = (f1, f2) => (x) => f2(f1(x)); +``` + +```js +// prettier-ignore +const compose = (...funcs) => (...args) => + funcs.reduce((args, fn) => [fn(...args)], args); +``` + +> Částečná aplikace (Partial application) + +```js +// prettier-ignore +const partial = (fn, x) => (...args) => fn(x, ...args); +``` + +> Curryfikace (Currying) + +```js +const result = curry((a, b, c) => a + b + c)(1, 2)(3); +``` + +> Vedlejší účinky (Side effects) + +> Funkce vyššího řádu (Higher-order Function) + +1. Pokud je funkce předána jako argument jiné funkci, je to callback. +2. Pokud je funkce vrácena jako výsledek, je to továrna funkcí na uzávěrech. +3. Pokud má vrácená funkce stejnou sémantiku jako přijatá v argumentech, ale s dodatečným (rozšířeným) chováním, je to wrapper funkce. +4. Zřídka se stává, že vrácená funkce není propojena s funkcí z argumentů nebo není propojena přímo a má také jinou sémantiku a není wrapper funkcí. +5. Pokud na výstupu je třída nebo konstruktorová funkce, jsou to továrny pro třídy a prototypy. + +> Wrapper funkce (Wrapper) + +Funkce, která obaluje jinou funkci (někdy objekt, rozhraní nebo funkční objekt) a přidává jí dodatečné chování. Můžete obalit celé API rozhraní a dokonce asynchronní funkci spolu s callbacky (pokud je známá smlouva). + +```js +const sum = (a, b) => a + b; + +console.log(`Add nums: ${sum(5, 2)}`); +console.log(`Add float: ${sum(5.1, 2.3)}`); +console.log(`Concatenate: ${sum('5', '2')}`); +console.log(`Subtraction: ${sum(5, -2)}`); +``` diff --git a/content/cz/2-7-Closure.md b/content/cz/2-7-Closure.md index 4299912..099d510 100644 --- a/content/cz/2-7-Closure.md +++ b/content/cz/2-7-Closure.md @@ -1,3 +1,315 @@ ## 2.7. Uzávěry, funkce zpětného volání, zabalení a události -No translation +> Uzávěr + +```js +const add = (x) => (y) => { + const z = x + y; + console.log(`${x} + ${y} = ${z}`); + return z; +}; +``` + +```js +const res = add(3)(6); +console.log(res); +``` + +```js +const add = (x) => (y) => x + y; +``` + +> Rekurzivní uzávěr + +```js +const add = (x) => (y) => { + const z = x + y; + console.log(`${x} + ${y} = ${z}`); + return add(z); +}; +``` + +```js +const add = (x) => (y) => add(x + y); +``` + +```js +const a1 = add(5); +const a2 = a1(2); +const a3 = a2(3); +const a4 = a1(1); +const a5 = a2(10); +console.log(a1, a2, a3, a4, a5); +``` + +> Řetězení funkcí + +```js +const res = add(5)(2)(3)(7); +console.log(res); +``` + +> Abstrakce (náhrada třídy) + +```js +const COLORS = { + warning: '\x1b[1;33m', + error: '\x1b[0;31m', + info: '\x1b[1;37m', +}; + +const logger = (kind) => { + const color = COLORS[kind] || COLORS.info; + return (s) => { + const date = new Date().toISOString(); + console.log(color + date + '\t' + s); + }; +}; +``` + +```js +const warning = logger('warning'); +const error = logger('error'); +const debug = logger('debug'); +const slow = logger('slow'); + +slow('I am slow logger'); +warning('Hello'); +error('World'); +debug('Bye!'); +``` + +> Řetězení metod objektu + +```js +const adder = (a) => { + const value = () => a; + const add = (b) => adder(a + b); + return { add, value }; +}; +``` + +```js +const v = adder(3).add(-9).add(12).value(); +console.log(v); +``` + +> Alternativní syntaxe + +```js +const adder = (a) => ({ + value() { + return a; + }, + add(b) { + a += b; + return this; + }, +}); +``` + +```js +const v = adder(3).add(-9).add(12).value(); +console.log(v); +``` + +> Alternativní syntaxe + +```js +const adder = (a) => ({ + value: () => a, + add: (b) => adder(a + b), +}); +``` + +```js +const v = adder(3).add(-9).add(12).value(); +console.log(v); +``` + +> Složitý příklad + +```js +const adder = (a) => { + let onZerro = null; + const obj = {}; + const value = () => a; + const add = (b) => { + let x = a + b; + if (x < 0) { + x = 0; + if (onZerro) onZerro(); + } + return adder(x); + }; + const on = (name, callback) => { + if (name === 'zero') onZerro = callback; + return obj; + }; + return Object.assign(obj, { add, value, on }); +}; +``` + +```js +const a = adder(3) + .on('zero', () => console.log('Less than zero')) + .add(-9) + .add(12) + .add(5) + .value(); + +console.log(a); +``` + +> Callback + +```js +// Normální vrácení výsledku +const sum = (a, b) => a + b; + +// Vrácení výsledku do callback funkce +const sum = (a, b, callback) => callback(a + b); +``` + +```js +console.log('sum(5, 2) =', sum(5, 2)); +sum(5, 2, console.log.bind(null, 'sum(5, 2) =')); +``` + +```js +const fs = require('fs'); + +const reader = (err, data) => { + console.log({ lines: data.split('\n').length }); +}; + +fs.readFile('./file.txt', 'utf8', reader); +``` + +> Pojmenované callbacky + +```js +const fs = require('fs'); + +const print = (fileName, err, data) => { + console.log({ lines: data.split('\n').length }); +}; + +const fileName = './file.txt'; +const callback = print.bind(null, fileName); +fs.readFile(fileName, 'utf8', callback); +``` + +> Implementace timeru s callbackem + +```js +const fn = () => { + console.log('Callback from from timer'); +}; + +const timeout = (interval, fn) => { + setTimeout(fn, interval); +}; + +timeout(5000, fn); +``` + +> Curry timeru + +```js +const curry = (fn, ...par) => { + const curried = (...args) => { + if (fn.length <= args.length) return fn(...args); + return curry(fn.bind(null, ...args)); + }; + return par.length ? curried(...par) : curried; +}; +``` + +```js +const fn = () => { + console.log('Callback from from timer'); +}; + +const timeout = (interval, fn) => { + setTimeout(fn, interval); +}; + +const timer = curry(timeout); +timer(2000)(fn); + +const timer2s = timer(2000); +timer2s(fn); +``` + +> Callbacky iterace + +```js +const iterate = (array, listener) => { + for (const item of array) { + listener(item); + } +}; + +const cities = ['Kiev', 'London', 'Beijing']; + +const print = (city) => { + console.log('City:', city); +}; + +iterate(cities, print); +``` + +> Události + +```js +const adder = (initial) => { + let value = initial; + const add = (delta) => { + value += delta; + if (value >= add.maxValue) add.maxEvent(value); + return add; + }; + add.max = (max, event) => { + add.maxValue = max; + add.maxEvent = event; + return add; + }; + return add; +}; +``` + +```js +const maxReached = (value) => { + console.log('max value reached, value: ' + value); +}; + +const a1 = adder(10).max(100, maxReached)(-12); + +a1(25); +a1(50); +a1(75); +a1(100); +a1(-200)(50)(30); +``` + +> EventEmitter + +```js +const { EventEmitter } = require('events'); + +const emitter = new EventEmitter(); + +emitter.on('new city', (city) => { + console.log('Emitted city:', city); +}); + +emitter.on('data', (array) => { + console.log(array.reduce((a, b) => a + b)); +}); + +emitter.emit('new city', 'Delhi'); +emitter.emit('new city', 'Berlin'); +emitter.emit('new city', 'Tokyo'); +emitter.emit('data', [5, 10, 7, -3]); +``` diff --git a/content/cz/2-8-Errors.md b/content/cz/2-8-Errors.md index 5150443..ff1bfde 100644 --- a/content/cz/2-8-Errors.md +++ b/content/cz/2-8-Errors.md @@ -1,3 +1,145 @@ ## 2.8. Výjimky a řešení chyb -No translation +> Ladění (Debug) - proces detekce a odstraňování chyb v softwaru. + +Ladění je implementováno pomocí výstupu zpráv nebo nástrojů: debugger, profiler, dekompilátor, systémy pro monitorování zdrojů a protokolování, systémy pro kontinuální integraci a testování. + +„Ladění je dvakrát těžší než psaní kódu. Pokud tedy píšete kód tak chytře, jak můžete, pak jste podle definice ne dostatečně chytří na to, abyste ho ladili." // Brian Kernighan + +„Pokud je ladění procesem odstraňování chyb, pak musí být programování procesem jejich zavádění" // Edsger Dijkstra + +> Throw + +```js +const isNumber = (value) => typeof value === 'number'; + +const sum = (a, b) => { + if (isNumber(a) && isNumber(b)) { + return a + b; + } + throw new Error('a and b should be numbers'); +}; +``` + +```js +try { + console.log(sum(2, 3)); +} catch (err) { + console.log(err.message); +} +``` + +```js +try { + console.log(sum(7, 'A')); +} catch (err) { + console.log(err.message); +} +``` + +> Vrácení tuple nebo struktury + +```js +const sum = (a, b) => { + if (isNumber(a) && isNumber(b)) { + return [null, a + b]; + } + return [new Error('a and b should be numbers')]; +}; + +console.log(sum(2, 3)); + +console.log(sum(7, 'A')); +``` + +> Callback + +```js +const sum = (a, b, callback) => { + if (isNumber(a) && isNumber(b)) { + callback(null, a + b); + } else { + callback(new Error('a and b should be numbers')); + } +}; +``` + +```js +sum(2, 3, (err, result) => { + if (err) { + console.log(err.message); + return; + } + console.log(result); +}); +``` + +```js +sum(7, 'A', (err, result) => { + if (err) { + console.log(err.message); + return; + } + console.log(result); +}); +``` + +> Promise + +```js +const sum = (a, b) => + new Promise((resolve, reject) => { + if (isNumber(a) && isNumber(b)) { + resolve(a + b); + } else { + reject(new Error('a and b should be numbers')); + } + }); +``` + +```js +sum(2, 3) + .then((data) => { + console.log(data); + }) + .catch((err) => { + console.log(err.message); + }); +``` + +```js +sum(7, 'A') + .then((data) => { + console.log(data); + }) + .catch((err) => { + console.log(err.message); + }); +``` + +> Asynchronní throw + +```js +const sum = async (a, b) => { + if (isNumber(a) && isNumber(b)) { + return a + b; + } + throw new Error('a and b should be numbers'); +}; +``` + +```js +try { + console.log(await sum(2, 3)); +} catch (e) { + console.log(e.message); +} +``` + +```js +try { + console.log(await sum(7, 'A')); +} catch (err) { + console.log(err.message); +} +``` diff --git a/content/cz/2-9-Tasks.md b/content/cz/2-9-Tasks.md index e63071e..a9a1bd5 100644 --- a/content/cz/2-9-Tasks.md +++ b/content/cz/2-9-Tasks.md @@ -1,3 +1,47 @@ ## 2.9. Úkoly -No translation +`Úkol 1.` Vezměme si příklad, který jsme již zvažovali, ale kterému byly přidány některé chyby. Zkopírujte tento kód do samostatného souboru a opravte ho tak, aby nejen fungoval, ale byl také krásný a srozumitelný. Jako referenci můžete použít kód z knihy a přednášek. + +```js +const Items = [ + { CENA: 40 } ,{ CENA : 120 },{ + CENA: '505', + }, { CENA: 350 }]; + +For (const ITEM of items){ +console.log(`Price: ${item.price}`); +} +``` + +`Úkol 2.` Nyní vytvořme funkci, která vypočítá součet celého nákupu. Dejte funkci srozumitelné jméno a přidejte následující pravidla: musí se zkontrolovat, zda je cena číslo (pomocí `typeof`), sčítáme pouze kladné ceny, a pokud najdeme nečíslo nebo záporné číslo, vydáme chybu pomocí `throw`. + +Během plnění úkolu hledejte na internetu dokumentaci k `for..of`, `throw`, `console.log`, funkcím a polím. Nejlépe hledejte v MDN (mozilla developers network). + +Ujistěte se, že kód běží v příkazovém řádku přes node.js nebo v prohlížeči. + +`Úkol 3.` Vezměte tuto datovou strukturu a doplňte ji zbožím a skupinami zboží podle příkladu těch, které již existují: + +```js +const purchase = { + Electronics: [ + { name: 'Laptop', price: 1500 }, + { name: 'Keyboard', price: 100 }, + ], + Textile: [{ name: 'Bag', price: 50 }], +}; +``` + +Umístěte kód do souboru a vypište celou strukturu na obrazovku spuštěním kódu v node.js nebo v prohlížeči. + +`Úkol 4.` Napište funkci `find`, která projde strukturou z předchozího úkolu a najde produkt podle jeho jména (zkontroluje všechny skupiny produktů). Jména se mohou opakovat, ale tentokrát nás zajímá pouze první produkt, jehož jméno se shoduje. + +Příklad použití funkce `find`: + +```js +const result = find(purchase, 'Laptop'); +console.log(result); +``` + +Mělo by vypsat: `{ name: 'Laptop', price: 1500 }` + +`Úkol 5.` Nyní rozšíříme předchozí úkol: funkce `find` musí být změněna tak, aby vracela pole obsahující všechny produkty se zadaným jménem. Pokud se žádný nenajde, pak prázdné pole. diff --git a/content/cz/2-Basic.md b/content/cz/2-Basic.md index a6a86a0..73dab87 100644 --- a/content/cz/2-Basic.md +++ b/content/cz/2-Basic.md @@ -1,6 +1,10 @@ # 2. Základní pojmy -No translation +Potřebujeme komentáře k dočasnému zabránění spuštění nebo kompilace bloku kódu, k uložení strukturovaných anotací nebo metadat (interpretovaných speciálními nástroji), k uchování `TODOs` nebo vysvětlení čitelných pro vývojáře. + +> `Komentář` je posloupnost znaků v kódu ignorovaná kompilátorem nebo interpretem. + +Komentáře ve všech jazycích rodiny `C`, jako jsou `C++`, `JavaScript`, `Java`, `C#`, `Swift`, `Kotlin`, `Go` atd., mají stejnou syntaxi. ```js // Single-line comment @@ -13,10 +17,16 @@ No translation */ ``` +Nedržte v komentářích zřejmé věci, neopakujte něco, co je jasné z samotného kódu. + +V bash (shell-skriptech) a Python používáme znak čísla (křížek nebo hash symbol) pro komentování. + ```py # Single-line comment ``` +Python používá víceřádkové řetězce jako víceřádkové komentáře s trojitou syntaxí uvozovek. Ale pamatujte, že se jedná o řetězcový literál nepřiřazený k proměnné. + ```py """ Multi-line @@ -24,14 +34,20 @@ No translation """ ``` +SQL používá dvě pomlčky k zahájení jednořádkového komentáře do konce řádku. + ```sql select name from PERSON -- comments in sql ``` +HTML komentáře mají pouze víceřádkovou syntaxi. + ```html ``` +V Assembleru a mnoha dialektech LISP používáme středníky (nebo více středníků) pro různé typy komentářů. + ``` ; Single-line comment in Assembler and LISP ``` diff --git a/content/cz/3-3-Collections.md b/content/cz/3-3-Collections.md index a128b72..9dd932f 100644 --- a/content/cz/3-3-Collections.md +++ b/content/cz/3-3-Collections.md @@ -1,3 +1,222 @@ ## 3.3. Pole, seznam, sada, n-tice -No translation +> Pole + +```js +const ages = [10, 12, 15, 15, 17, 18, 18, 19, 20]; + +const first = ages[0]; +const last = ages[ages.length - 1]; + +console.log({ first, last }); +``` + +> Seznam + +```py +ages = [10, 12, 15, 15, 17, 18, 18, 19, 20] + +first = ages[0] +last = ages[-1] + +print({ 'first': first, 'last': last }) +``` + +> Pole + +```c +#include + +int main() { + int ages[] = { 10, 12, 15, 15, 17, 18, 18, 19, 20 }; + + int first = ages[0]; + int length = sizeof(ages) / sizeof(ages[0]); + int last = ages[length - 1]; + + printf("first: %d\n", first); + printf("last: %d\n", last); +} +``` + +> Přístup k prvkům + +```js +const getFirstAndLast = (array) => { + const first = array[0]; + const last = array[array.length - 1]; + return { first, last }; +}; +``` + +```js +const ages = [10, 12, 15, 15, 17, 18, 18, 19, 20]; +const { first, last } = getFirstAndLast(ages); +console.log({ first, last }); +``` + +```py +def getFirstAndLast(array): + first = ages[0] + last = ages[-1] + return first, last +``` + +```py +ages = [10, 12, 15, 15, 17, 18, 18, 19, 20] +first, last = getFirstAndLast(ages) +print({ 'first': first, 'last': last }) +``` + +```js +const getFirstAndLast = (array) => ({ + first: array[0], + last: array[array.length - 1], +}); +``` + +```py +getFirstAndLast = lambda array: (array[0], array[-1]) +``` + +```js +const concat = (arr1, arr2) => { + const arr = arr1.slice(); + arr.push(...arr2); + return arr; +}; +``` + +```js +const schoolAges = [10, 12, 15, 15]; +const studentAges = [17, 18, 18, 19, 20]; +const ages = concat(schoolAges, studentAges); +``` + +```py +concat = lambda arr1, arr2: arr1 + arr2 +``` + +```py +schoolAges = [10, 12, 15, 15] +studentAges = [17, 18, 18, 19, 20] +ages = schoolAges + studentAges +``` + +```c +#include + +int main() { + int schoolAges[] = { 10, 12, 15, 15 }; + int studentAges[] = { 17, 18, 18, 19, 20 }; + + int schoolLength = sizeof(schoolAges) / sizeof(int); + int studentLength = sizeof(studentAges) / sizeof(int); + int length = schoolLength + studentLength; + int ages[length]; + + for (int i = 0; i < schoolLength; i++) { + ages[i] = schoolAges[i]; + } + + for (int i = 0; i < studentLength; i++) { + ages[i + schoolLength] = studentAges[i]; + } + + for (int i = 0; i < length; i++) { + printf("ages[%d]: %d\n", i, ages[i]); + } +} +``` + +```js +const concat = (arr1, arr2) => [...arr1, ...arr2]; +``` + +> Sada + +```js +const ages = new Set([10, 12, 15, 15, 17, 18, 18, 19, 20]); +console.log({ ages }); + +ages.add(16); +ages.delete(20); + +console.log({ + 10: ages.has(10), + 16: ages.has(16), + 19: ages.has(19), + 20: ages.has(20), +}); + +ages.clear(); +console.log({ ages }); +``` + +> Sjednocení + +```js +const union = (s1, s2) => { + const ds = s1.slice(0); + for (let i = 0; i < s2.length; i++) { + const item = s2[i]; + if (!ds.includes(item)) ds.push(item); + } + return ds; +}; +``` + +```js +const cities1 = ['Beijing', 'Kiev']; +const cities2 = ['Kiev', 'London', 'Baghdad']; +console.dir({ cities1, cities2 }); + +const results = union(cities1, cities2); +console.dir(results); +``` + +```js +const union = (s1, s2) => new Set([...s1, ...s2]); +``` + +> Průnik + +```js +const intersection = (s1, s2) => { + const ds = []; + for (let i = 0; i < s1.length; i++) { + const item = s1[i]; + if (s2.includes(item)) ds.push(item); + } + return ds; +}; +``` + +```js +const intersection = (s1, s2) => + new Set([...s1].filter((v) => s2.has(v))); +``` + +> Rozdíl + +```js +const difference = (s1, s2) => { + const ds = []; + for (let i = 0; i < s1.length; i++) { + const item = s1[i]; + if (!s2.includes(item)) ds.push(item); + } + return ds; +}; +``` + +```js +const difference = (s1, s2) => + new Set([...s1].filter((v) => !s2.has(v))); +``` + +> Doplněk + +```js +const complement = (s1, s2) => difference(s2, s1); +``` diff --git a/content/cz/3-4-Hash.md b/content/cz/3-4-Hash.md index 38aa185..9c51d61 100644 --- a/content/cz/3-4-Hash.md +++ b/content/cz/3-4-Hash.md @@ -1,3 +1,97 @@ ## 3.4. Slovník, hashovací tabulka a asociativní pole -No translation +> Objekt + +```js +const ages = { + 'Vasia Pupkin': 19, + 'Marcus Aurelius': 1860, +}; + +console.log({ ages }); +``` + +```js +ages['Vasia Pupkin'] = 20; +console.log({ ages }); +``` + +```js +Reflect.deleteProperty(ages, 'Vasia Pupkin'); +console.log({ ages }); +``` + +```js +console.log({ + 'Vasia Pupkin': Reflect.has(ages, 'Vasia Pupkin'), + 'Marcus Aurelius': Reflect.has(ages, 'Marcus Aurelius'), +}); +``` + +> Map + +```js +const ages = new Map(); + +ages.set('Vasia Pupkin', 19); +ages.set('Marcus Aurelius', 1860); + +console.log({ ages }); +``` + +```js +ages.set('Vasia Pupkin', 20); +console.log({ ages }); +``` + +```js +ages.delete('Vasia Pupkin'); +console.log({ ages }); +``` + +```js +console.log({ + 'Vasia Pupkin': ages.has('Vasia Pupkin'), + 'Marcus Aurelius': ages.has('Marcus Aurelius'), +}); +``` + +```js +ages.clear(); +console.log({ ages }); +``` + +> Složitý příklad: distinct + +```js +const distinct = (dataset) => { + const keys = new Set(); + return dataset.filter((record) => { + const cols = Object.keys(record).sort(); + const key = cols + .map((field) => record[field]) + .join('\x00'); + const has = keys.has(key); + if (!has) keys.add(key); + return !has; + }); +}; +``` + +```js +const flights = [ + { from: 'Kiev', to: 'Rome' }, + { from: 'Kiev', to: 'Warsaw' }, + { from: 'Dublin', to: 'Riga' }, + { from: 'Riga', to: 'Dublin' }, + { from: 'Kiev', to: 'Rome' }, + { from: 'Cairo', to: 'Paris' }, +]; + +console.table(flights); +``` + +```js +const directions = distinct(flights); +console.table(directions); +``` diff --git a/content/cz/3-5-Deque.md b/content/cz/3-5-Deque.md index 7e3fd76..cac6285 100644 --- a/content/cz/3-5-Deque.md +++ b/content/cz/3-5-Deque.md @@ -1,3 +1,164 @@ ## 3.5. Zásobník, fronta, deque -No translation +```js +class Stack { + constructor() { + this.last = null; + } + + push(item) { + const prev = this.last; + const element = { prev, item }; + this.last = element; + } + + pop() { + const element = this.last; + if (!element) return null; + this.last = element.prev; + return element.item; + } +} +``` + +```js +const obj1 = { name: 'first' }; +const obj2 = { name: 'second' }; +const obj3 = { name: 'third' }; +const list = new Stack(); +list.push(obj1); +list.push(obj2); +list.push(obj3); +``` + +```js +console.dir(list.pop()); // { name: 'third' } +console.dir(list.pop()); // { name: 'second' } +console.dir(list.pop()); // { name: 'first' } +console.dir(list.pop()); // null +``` + +> Fronta + +```js +class Queue { + constructor() { + this.first = null; + this.last = null; + } + + put(item) { + const last = this.last; + const element = { next: null, item }; + if (last) { + last.next = element; + this.last = element; + } else { + this.first = element; + this.last = element; + } + } + + pick() { + const element = this.first; + if (!element) return null; + if (this.last === element) { + this.first = null; + this.last = null; + } else { + this.first = element.next; + } + return element.item; + } +} +``` + +```js +const obj1 = { name: 'first' }; +const obj2 = { name: 'second' }; +const obj3 = { name: 'third' }; + +const queue = new Queue(); +queue.put(obj1); +queue.put(obj2); +queue.put(obj3); + +console.dir(queue.pick()); // { name: 'first' } +console.dir(queue.pick()); // { name: 'second' } +console.dir(queue.pick()); // { name: 'third' } +console.dir(queue.pick()); // null +``` + +> Deque + +```js +class Dequeue { + constructor() { + this.first = null; + this.last = null; + } + + push(item) { + const last = this.last; + const element = { prev: last, next: null, item }; + if (last) { + last.next = element; + this.last = element; + } else { + this.first = element; + this.last = element; + } + } + + pop() { + const element = this.last; + if (!element) return null; + if (this.first === element) { + this.first = null; + this.last = null; + } else { + this.last = element.prev; + } + return element.item; + } + + unshift(item) { + const first = this.first; + const element = { prev: null, next: first, item }; + if (first) { + first.prev = element; + this.first = element; + } else { + this.first = element; + this.last = element; + } + } + + shift() { + const element = this.first; + if (!element) return null; + if (this.last === element) { + this.first = null; + this.last = null; + } else { + this.first = element.next; + } + return element.item; + } +} +``` + +```js +const obj1 = { name: 'first' }; +const obj2 = { name: 'second' }; +const obj3 = { name: 'third' }; + +const list = new Dequeue(); +list.push(obj1); +list.push(obj2); +list.unshift(obj3); + +console.dir(list.pop()); // { name: 'second' } +console.dir(list.shift()); // { name: 'third' } +console.dir(list.shift()); // { name: 'first' } +``` diff --git a/content/cz/3-6-Graph.md b/content/cz/3-6-Graph.md index 4838095..5800254 100644 --- a/content/cz/3-6-Graph.md +++ b/content/cz/3-6-Graph.md @@ -1,3 +1,106 @@ ## 3.6. Stromy a grafy -No translation +> Matice sousednosti - ukládá spojení uzlů grafu + +``` + 1 +---+ const graph = [ + +--------------+ B +--+ [0, 1, 1, 0, 1], + | +---+ | [1, 0, 0, 1, 0], + | | [1, 0, 0, 1, 0], ++-+-+ 2 | [0, 1, 1, 0, 0], +|| A +----------+ |3 [1, 0, 0, 0, 0], +|+-+ | | ]; + | | | + | +-+-+ | const graph = { + |5 | C | | A: [0, 1, 1, 0, 1], + | +-+-+ | B: [1, 0, 0, 1, 0], + +--+ | | C: [1, 0, 0, 1, 0], + | | | D: [0, 1, 1, 0, 0], + +-+-+ 4 | +-+-+ E: [1, 0, 0, 0, 0], + | E | +------+ D | }; + +---+ +---+ +``` + +> Matice sousednosti jako ploché pole + +``` + 1 +---+ const graph = [ + +--------------+ B +--+ 0, 1, 1, 0, 1, + | +---+ | 1, 0, 0, 1, 0, + | | 1, 0, 0, 1, 0, ++-+-+ 2 | 0, 1, 1, 0, 0, +|| A +----------+ |3 1, 0, 0, 0, 0, +|+-+ | | ]; + | | | + | +-+-+ | + |5 | C | | + | +-+-+ | + +--+ | | + | | | + +-+-+ 4 | +-+-+ + | E | +------+ D | + +---+ +---+ +``` + +> Matice incidence - spojení uzlů (řádky pole) s hranami (sloupce pole) + +``` + 1 +---+ const graph = [ + +--------------+ B +--+ [1, 1, 0, 0, 1], + | +---+ | [1, 0, 1, 0, 0], + | | [0, 1, 0, 1, 0], ++-+-+ 2 | [0, 0, 1, 1, 0], +|| A +----------+ |3 [0, 0, 0, 0, 1], +|+-+ | | ]; + | | | + | +-+-+ | const graph = { + |5 | C | | A: [1, 1, 0, 0, 1], + | +-+-+ | B: [1, 0, 1, 0, 0], + +--+ | | C: [0, 1, 0, 1, 0], + | | | D: [0, 0, 1, 1, 0], + +-+-+ 4 | +-+-+ E: [0, 0, 0, 0, 1], + | E | +------+ D | ]; + +---+ +---+ +``` + +> Seznam sousednosti - seznam uzlů, pro každý seznam sousedních uzlů + +``` + 1 +---+ const graph = { + +--------------+ B +--+ A: [], + | +---+ | B: [], + | | C: [], ++-+-+ 2 | D: [], +|| A +----------+ |3 E: [], +|+-+ | | }; + | | | + | +-+-+ | const { A, B, C, D, E } = graph; + |5 | C | | A.push(B, C, E); + | +-+-+ | B.push(A, D); + +--+ | | C.push(A, D); + | | | D.push(B, C); + +-+-+ 4 | +-+-+ E.push(A); + | E | +------+ D | + +---+ +---+ console.dir({ graph }); +``` + +> Seznam hran - seznam s uvedením hrany jako dvojice uzlů + +``` + 1 +---+ const graph = [ + +--------------+ B +--+ [A, B], + | +---+ | [A, C], + | | [B, D], ++-+-+ 2 | [C, D], +|| A +----------+ |3 [A, E], +|+-+ | | ]; + | | | + | +-+-+ | const graph = [ + |5 | C | | { from: A, to: B }, + | +-+-+ | { from: A, to: C }, + +--+ | | { from: B, to: D }, + | | | { from: C, to: D }, + +-+-+ 4 | +-+-+ { from: A, to: E }, + | E | +------+ D | ]; + +---+ +---+ +```