├── .eleventy.js ├── .eleventyignore ├── .gitignore ├── 01-IntroToCS ├── README.json ├── README.md └── homework │ ├── README.md │ ├── homework.js │ ├── package.json │ └── tests │ └── CS.test.js ├── 02-JavaScriptAvanzado-I ├── OOP.md ├── README.json ├── README.md ├── debugging │ ├── README.md │ ├── demo │ │ └── index.html │ └── img │ │ ├── botones.jpg │ │ ├── bps.png │ │ ├── panels.png │ │ └── subpanels.png ├── demo │ └── execution context.js ├── errores.md └── homework │ ├── homework.js │ └── homework.md ├── 03-JavaScriptAvanzado-II ├── README.json ├── README.md └── homework │ ├── README.md │ ├── homework.js │ ├── package.json │ └── tests │ └── JSAI.test.js ├── 04-EstructuraDeDatos-I ├── README.json ├── README.md └── homework │ ├── README.md │ ├── homework.js │ ├── package.json │ └── tests │ └── DataStructureI.test.js ├── 05-EstructuraDeDatos-II ├── Ejemplos │ ├── arrays.js │ ├── listas.js │ ├── matriz.js │ ├── pilas.js │ ├── torreDeHanoi.js │ ├── torredeHanoi.py │ └── torredehanoiFacu.js ├── README.json ├── README.md └── homework │ ├── README.md │ ├── homework.js │ ├── package.json │ └── tests │ └── DataStructureII.test.js ├── 06-EstructuraDeDatos-III ├── Ejemplos │ └── arbolBusqueda │ │ ├── arbolBinarioBusqueda.js │ │ ├── package.json │ │ └── tests.js ├── README.json ├── README.md └── homework │ ├── README.md │ ├── bst.png │ ├── homework.js │ ├── package.json │ └── tests │ └── DataStructureIII.test.js ├── 07-Algoritmos-I ├── README.json ├── README.md └── homework │ ├── README.md │ ├── homework.js │ ├── package.json │ └── tests │ └── AlgoritmosI.test.js ├── 08-Algoritmos-II ├── README.json ├── README.md └── homework │ ├── README.md │ ├── homework.js │ ├── package.json │ └── tests │ └── AlgoritmosII.test.js ├── EXTRA-Testing ├── README.json ├── README.md ├── demo │ ├── matchers.test.js │ ├── package.json │ ├── sum-describe.test.js │ ├── sum.js │ └── sum.test.js └── homework │ ├── README.md │ ├── homework.js │ ├── package.json │ └── tests │ └── index.test.js ├── EjerciciosExtras └── homework │ ├── DS.js │ ├── Repaso-M1.js │ ├── Test │ └── repaso-M1.test.js │ └── package.json ├── README.json ├── README.md ├── _src ├── assets │ ├── 01-IntroToCS │ │ ├── AND.png │ │ ├── OR.png │ │ ├── ascii.png │ │ ├── assembly.png │ │ ├── binario.png │ │ ├── compilation.png │ │ ├── floating.png │ │ ├── i747decimal.png │ │ ├── ie747.png │ │ ├── negativo.png │ │ └── utf8.png │ ├── 02-JavaScriptAvanzado-I │ │ ├── Closure.png │ │ ├── closure2.png │ │ ├── context.jpg │ │ ├── executionContext.png │ │ ├── executionStack.png │ │ ├── fasecreacion.png │ │ ├── function.png │ │ ├── functionFactory.png │ │ ├── globalObject.png │ │ ├── mthread.gif │ │ ├── notaciones.png │ │ ├── protoypeInheritance.png │ │ ├── protoypeInheritance2.png │ │ └── protoypeInheritance3.png │ ├── 04-EstructuraDeDatos-I │ │ ├── Balanced_vs_unbalanced_BST.png │ │ ├── array.jpg │ │ ├── avl.gif │ │ ├── binaryArray.png │ │ ├── binaryTree.png │ │ ├── cola.jpg │ │ ├── dom_tree.gif │ │ ├── doueblelist.png │ │ ├── hashfunction.png │ │ ├── heap.png │ │ ├── listAdd.gif │ │ ├── listaRemove.gif │ │ ├── listaRemove.png │ │ ├── notatree1.png │ │ ├── notatree2.png │ │ ├── singlelist.png │ │ └── stack.jpg │ ├── 07-Algoritmos-I │ │ ├── Sorting_quicksort_anim.gif │ │ ├── asintotica.png │ │ ├── ayudin.png │ │ ├── ayudin2.png │ │ ├── ayudin3.png │ │ ├── bigo.png │ │ ├── binarySearch.gif │ │ ├── bubblesort.gif │ │ ├── cat.jpg │ │ ├── chemestrydog.jpg │ │ ├── countsort.gif │ │ ├── countsort.png │ │ ├── hanoi.gif │ │ ├── heapSort.gif │ │ ├── insertion.gif │ │ ├── insertionbest.gif │ │ ├── mergesort.gif │ │ ├── mergesortTime.png │ │ ├── nnn.png │ │ ├── quicksortBest.png │ │ ├── quicksortWorst.png │ │ ├── radixsort.gif │ │ ├── recursion.jpg │ │ ├── recursionof.jpg │ │ ├── selection.gif │ │ ├── tablasegundo.png │ │ └── tablatiempo.png │ └── EXTRA-Testing │ │ ├── TDD.png │ │ ├── always-true.png │ │ ├── checkSeatStatus-1-error.png │ │ ├── checkSeatStatus-1-pass.png │ │ ├── demo-test.png │ │ ├── describe-demo.png │ │ ├── describe-only.png │ │ ├── describe.png │ │ ├── fine.jpg │ │ ├── i-can.jpg │ │ ├── it-only.png │ │ ├── never-ends.jpg │ │ ├── piramide.png │ │ ├── skip.png │ │ ├── something-wrong.jpg │ │ ├── stop.png │ │ └── testOverhead.jpg ├── data │ ├── config.json │ ├── layout.js │ └── styles │ │ ├── code.js │ │ ├── fonts.js │ │ ├── footer.js │ │ ├── header.js │ │ ├── lesson.js │ │ ├── lessonIntro.js │ │ ├── main.js │ │ ├── responsive.js │ │ ├── sidebar.js │ │ └── topbar.js └── layouts │ ├── intro.njk │ └── lesson.njk └── package.json /.eleventy.js: -------------------------------------------------------------------------------- 1 | const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight'); 2 | const eleventyNavigationPlugin = require('@11ty/eleventy-navigation'); 3 | const toBootstrapNav = require('eleventy-navigation-bootstrap'); 4 | const pluginTOC = require('eleventy-plugin-toc'); 5 | const markdownIt = require('markdown-it'); 6 | const markdownItAnchor = require('markdown-it-anchor'); 7 | const markdownItHighlightJS = require('markdown-it-highlightjs'); 8 | const readerBar = require('henry-reader-bar'); 9 | const readingTime = require('henry-reading-time'); 10 | 11 | const mdOptions = { 12 | html: true, 13 | breaks: true, 14 | linkify: true, 15 | typographer: true, 16 | }; 17 | 18 | const mdAnchorOpts = { 19 | permalink: true, 20 | permalinkClass: 'anchor-link', 21 | permalinkSymbol: '', 22 | level: [1, 2, 3, 4], 23 | }; 24 | 25 | module.exports = function (eleventyConfig) { 26 | eleventyConfig.setLibrary( 27 | 'md', 28 | markdownIt(mdOptions) 29 | .use(markdownItAnchor, mdAnchorOpts) 30 | .use(markdownItHighlightJS) 31 | ); 32 | 33 | eleventyConfig.addPlugin(eleventyNavigationPlugin); 34 | eleventyConfig.addPlugin(readingTime); 35 | eleventyConfig.addPlugin(readerBar); 36 | eleventyConfig.addPlugin(syntaxHighlight); 37 | 38 | eleventyConfig.addPlugin(pluginTOC, { 39 | tags: ['h2', 'h3'], 40 | ul: true, 41 | }); 42 | 43 | eleventyConfig.addPassthroughCopy('_src/assets'); 44 | eleventyConfig.addPassthroughCopy('_src/localStyles'); 45 | 46 | eleventyConfig.addNunjucksFilter('bootstrapNav', toBootstrapNav); 47 | 48 | eleventyConfig.addLinter( 49 | 'Spelling check', 50 | function (content, inputPath, outputPath) { 51 | let words = 'lenght, .lenght, .rigth'.split(','); 52 | 53 | // Eleventy 1.0+: use this.inputPath and this.outputPath instead 54 | if (inputPath.endsWith('.md')) { 55 | for (let word of words) { 56 | let regexp = new RegExp('\\b(' + word + ')\\b', 'gi'); 57 | if (content.match(regexp)) { 58 | console.warn(`Spelling check (${inputPath}) Found: ${word}`); 59 | } 60 | } 61 | } 62 | } 63 | ); 64 | 65 | return { 66 | dir: { 67 | includes: '/_src/layouts', 68 | data: '/_src/data', 69 | output: '_dist', 70 | }, 71 | }; 72 | }; 73 | -------------------------------------------------------------------------------- /.eleventyignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/homework -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 3 | 4 | # dependencies 5 | /node_modules 6 | /.pnp 7 | .pnp.js 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | 15 | # Eleventy 16 | _dist 17 | _cache 18 | /_src/localStyles 19 | 20 | # misc 21 | .DS_Store 22 | .env.local 23 | .env.development.local 24 | .env.test.local 25 | .env.production.local 26 | 27 | npm-debug.log* 28 | yarn-debug.log* 29 | yarn-error.log* 30 | package-lock.json 31 | -------------------------------------------------------------------------------- /01-IntroToCS/README.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "lesson", 3 | "lessonTitle": "Computer Science", 4 | "feedbackID": "00-IntroToCS", 5 | "permalink": "/Intro_CS/", 6 | "homeworkUrl": "https://github.com/soyHenry/FT-M1/tree/master/01-IntroToCS/homework", 7 | "eleventyNavigation": { 8 | "key": "Intro CS", 9 | "order": 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /01-IntroToCS/homework/README.md: -------------------------------------------------------------------------------- 1 | # INTRODUCTION TO COMPUTER SCIENCE | Homework 2 | 3 | ## 📒 Temas de la clase 4 | 5 | - Lenguaje y teoría computacional. 6 | 7 | - Sistemas de numeración. 8 | 9 | --- 10 | 11 | ## 👀 Aprendizaje esperado 12 | 13 | Al finalizar esta homework comprenderás la lógica computacional a través de la construcción de funciones que cumplan con un comportamiento específico. 14 | 15 | --- 16 | 17 | ## ⏱ Duración estimada 18 | 19 | > 45 minutos 20 | 21 | --- 22 | 23 | ## 📋 Instrucciones preliminares 24 | 25 | 1. Para ubicarte dentro de la carpeta homework escribe en tu terminal los siguientes comandos: 26 | - cd + [01-IntroToCS]. 27 | - cd + [homework]. 28 | 2. Luego, instalaremos las dependencias con el comando: 29 | 30 | ```javascript 31 | npm install 32 | ``` 33 | 34 | 3. Listo! Ya puedes correr los test con el comando: 35 | 36 | ```javascript 37 | npm test 38 | ``` 39 | 40 | --- 41 | 42 | ## 👩‍💻 **CONSIGNA** 43 | 44 | Esta homework consta de dos ejercicios sencillos. En ambos deberás declarar funciones. Cada función tiene que permitir traducir un número a los dos diferentes sistemas numéricos que vimos en clase. 45 | 46 | En el archivo **_homework.js_** resuelve los siguientes ejercicios: 47 | 48 |
49 | 50 | ### 🟡 **Ejercicio 1: BinarioADecimal** 51 | 52 | Declara una función que reciba por parámetro un número en formato string en base binaria y retorne el mismo número en base decimal. El valor retornado debe ser de tipo number. Por ejemplo: 53 | 54 | ```javascript 55 | BinarioADecimal('1100'); // debe retornar 12 56 | ``` 57 | 58 |
59 | 60 | ### 🟡 **Ejercicio 2: DecimalABinario** 61 | 62 | Escribe una función que reciba por parámetro un número en base decimal y retorne el mismo número en base binaria. El valor retornado debe ser de tipo string. Por ejemplo: 63 | 64 | ```javascript 65 | DecimalABinario(8); // debe retornar '1000' 66 | ``` 67 | 68 | --- 69 | 70 | ## 🧠 Recuerda que... 71 | 72 | Las ciencias de la computación han avanzado a pasos agigantados, pero aún las operaciones más complejas se reducen, dentro de la computadora, a ceros y unos. Es decir: el sistema binario. 73 | 74 |
75 | 76 | --- 77 | 78 | ## **✅ FEEDBACK** 79 | 80 | ### Usa este [**formulario**](https://docs.google.com/forms/d/e/1FAIpQLSe1MybH_Y-xcp1RP0jKPLndLdJYg8cwyHkSb9MwSrEjoxyzWg/viewform) para reportar tus observaciones de mejora o errores. Tu feedback es muy importante para seguir mejorando el modelo educativo. 81 | -------------------------------------------------------------------------------- /01-IntroToCS/homework/homework.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function BinarioADecimal(num) { 4 | // '101101' 5 | var binary = num.split('').reverse().join('') // ['1', '0', '1', '1', '0', '1'] 6 | var suma = 0; 7 | 8 | for (let i = 0; i < binary.length; i++) { 9 | suma += parseInt(binary[i]) * 2 ** i 10 | } 11 | 12 | return suma; 13 | } 14 | 15 | function DecimalABinario(num) { 16 | var binary = [] 17 | 18 | while (num !== 0) { 19 | var digito = num % 2 20 | num = Math.floor(num / 2) 21 | binary = digito + binary 22 | } 23 | return binary; 24 | 25 | } 26 | 27 | module.exports = { 28 | BinarioADecimal, 29 | DecimalABinario, 30 | }; 31 | -------------------------------------------------------------------------------- /01-IntroToCS/homework/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "01-intro-to-cs", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "jest --collectCoverage=false CS.test.js", 7 | "grade": "jest --useStderr --json --outputFile=./tests/result.json" 8 | }, 9 | "devDependencies": { 10 | "jest": "^27.5.1" 11 | }, 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /01-IntroToCS/homework/tests/CS.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | 'use strict' 3 | 4 | const { 5 | BinarioADecimal, 6 | DecimalABinario, 7 | } = require('../homework.js'); 8 | 9 | describe('BinarioADecimal(num)', function() { 10 | it('should return 2', function() { 11 | expect(BinarioADecimal('10')).toBe(2); 12 | }); 13 | it('should return 7', function() { 14 | expect(BinarioADecimal('111')).toBe(7); 15 | }); 16 | }); 17 | 18 | describe('DecimalABinario(num)', function() { 19 | it('should return "100"', function() { 20 | expect(DecimalABinario(4)).toBe('100'); 21 | }); 22 | it('should return "111"', function() { 23 | expect(DecimalABinario(7)).toBe('111'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/README.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "lesson", 3 | "lessonTitle": "JavaScript Avanzado I", 4 | "feedbackID": "01-JavaScriptAvanzado-I", 5 | "permalink": "/JS_Avanzado_I/", 6 | "quizzID" : "6057d0a5656c8d23c2e60e3e", 7 | "homeworkUrl": "https://github.com/soyHenry/FT-M1/tree/master/02-JavaScriptAvanzado-I/homework", 8 | "eleventyNavigation": { 9 | "key": "JS Avanzado I", 10 | "order": 2 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/debugging/README.md: -------------------------------------------------------------------------------- 1 | # Browser Dev Tools: Debugger 2 | 3 | Una de las tantas opciones que nos ofrecen los navegadores dentro de sus herramientas para desarrolladores es el debugger ó "depurador". Esta herramienta nos permite encontrar y reparar errores en el código más fácil y rápidamente. Cuando nos iniciamos en el mundo de la programación una de las primeras cosas que aprendemos en Javascript es a utilizar el console.log(). Si bien puede ser útil y sencillo de aplicar, tiene sus limitaciones. Con este método debemos abrir manualmente los archivos de código, buscar lugares estratégicos donde insertar los console.log() y luego volver a cargar la página ó ejecutar el código para ver los mensajes en la consola. Luego, debemos repetir esta acción por cada nuevo console.log() que queramos agregar, siendo esto lento y poco práctico si necesitamos revisar archivos con muchas líneas de código o proyectos grandes. 4 | En este sentido el debugger tiene algunas ventajas sobre el método log, ya que con él 5 | no sólo vamos a poder imprimir mensajes en la cosola si no que vamos a poder revisar el estado de nuestras variables y cómo van cambiando a lo largo de la ejecución. También podremos ver los contextos de ejecución que se van sumando al call stack por cada llamado de función entre muchas otras cosas. Asi también tiene una curva de aprendizaje un poco mayor. 6 | 7 | ### ¿Dónde lo encontramos?
8 | Para eso tenemos que abrir el inspector en el navegador haciendo click derecho --> Inspeccionar ó con F12
9 | En la pestaña Sources vamos a visualizar 3 secciones o paneles: 10 | 11 | ![Panels debugger](img/panels.png) 12 | 13 | En el primero de ellos vamos a tener las carpetas con archivos que vamos a ejecutar y depurar con la herramienta debugger. En el panel del medio tenemos la vista completa de los archivos con el código y en el tercer panel tenemos los botones de control y los diferentes paneles más pequeños donde vamos a poder distinguir: 14 | 15 | * Breakpoints: son puntos en el código con los cuales le indicamos al debugger donde tiene que hacer pausas durante la ejecución. Mientras se pausa el código, podemos examinar las variables actuales, ejecutar comandos en la consola, entre muchas de otras acciones. Para colocar un breakpoint tenemos que hacer click en el número de linea de código donde queremos que el debugger frene la ejecución. En la siguiente imágen podemos ver que se han colocado BPs en las líneas 29 y 35 y a la derecha en el panel más pequeño nos indica en que líneas están. Desde ahí también podemos activarlos o desactivarlos de a uno. 16 | 17 | ![Breakpoints](img/bps.png) 18 | 19 | Tambien podemos crear breakpoints condicionales haciendo click derecho sobre el número de linea de código y aclarando que expresión queremos que se evalúe. En estos casos sólos se frenará la ejecución cuando la expresión evalúe en true. 20 | 21 | Importante: Vale mencionar que Js también nos ofrece de forma nativa una palabra reservada debugger 22 | Esta sentencia funciona de igual manera que los breakpoints, vamos a colocarla en la linea de código donde queremos que se frene la ejecución. Si estamos en un editor de código es muy útil ya que no necesitamos abrir las herramientas de desarrollador en el browser para depurar el código. 23 | 24 | * Scope: en esta sección vamos a examinar que contienen las variables. Vamos a poder revisar variables locales de la función, variables globales y sus valores. También nos indica a qué apunta el this y variables de closure en caso que existan. 25 | 26 | * Call stack: nos muestra las llamadas a las funciones apiladas, a medida que se van resolviendo salen de la pila. Si hacemos click en alguna de los elementos de la pila, nos posicionamos en esa función y podemos seguir inspeccionando el código desde ahi con los botones de control. Los veremos más adelante ⬇️ 27 | 28 | * Watch: podemos colocar cualquier tipo de expresión válida para javascript y al ejecutar el código esta se resolverá. Para agregarla hacemos click en el botón ➕ que está al desplegar la sección watch. Por ejemplo: si queremos saber el tipo de dato que está guardando una de nuestras variables podemos escribir la expresión --> typeof "nombre de la variable", dependiendo del momento de la ejecución esto puede ir variando. 29 | 30 | ![Subpanels](img/subpanels.png) 31 | 32 | * Event listener breakpoints: en esta sección hay una lista de todos los diferentes tipos de eventos como clicks, mouse, animaciones, etc. Podemos colocar un breakpoint en el momento en que se dispara un evento determinado elegiendo desde este listado. 33 | 34 | * Barra de control: en esta barra tenemos los botones que necesitamos para recorrer el código mientras la ejecución está pausada por los breakpoints. Veamos que hace cada uno de ellos. 35 | 36 | ![Botones](img/botones.jpg) 37 | 38 | 1) Pause/Resume: con este botón podemos reanudar la ejecución del script una vez que fue frenada por un breakpoint. La secuencia de comandos continúa ejecutándose hasta que llegue al siguiente breakpoint, si es que lo hay. 39 | 2) Step over: nos permite pasar a la siguiente llamada de función. Es decir, pasa al siguiente llamado de función sin entrar en ella y detenerse en cada una de las líneas de código. 40 | 3) Step into: Nos metemos a inspeccionar una función. Podemos seguir recorriendo linea por linea el código dentro de ella. 41 | 4) Step out: Salimos de la función que estamos inspeccionado y saltamos a la siguiente linea de código en la ejecución. 42 | 5) Step: este botón funciona igual que step into (3) sólo que en caso de funciones asincrónicas, se comporta como antiguamente lo hacía en su versión de Chrome 63. Cuando nos paramos en una función asincrónica, devtools hará una pausa y luego saltará a la siguiente función, sólo mostrando el hilo principal de ejecución. En cambio, el botón Step into (3) cuando se para sobre una función asincrónica, nos llevará a revisar que pasa en la llamada a la función y luego seguiremos ejecutando la siguiente línea de código. Este botón puede no estar presente en dev-tools de otros navegadores.
43 | Pueden ver una explicación más detallada sobre este punto acá: https://developer.chrome.com/blog/new-in-devtools-65/#async 44 | 6) Activate/Deactivate: Este botón no mueve la ejecución. Solo prende y apaga los breakpoints. 45 | 7) Pause/Don't pause on exceptions: con esta opción le indicamos al debugger si queremos que pause la ejecución en casos de excepción o no. Por ejemplo, si tenemos un error en el código y es por este motivo que se frena la ejecución, queremos que lo detecte. En este caso, se va a frenar la ejecución no por un breakpoint sino por un error extra que no habíamos tenido en cuenta así podremos examinar el estado de nuestras variables al momento que rompe y corregirlo. 46 | 47 | Podés probar vos mismo/a como funciona el debugger con una demo de Google acá: https://googlechrome.github.io/devtools-samples/debug-js/get-started
48 | La explicación de la demo la encontras acá: https://developer.chrome.com/docs/devtools/javascript/ 49 | 50 | Además, en este mismo módulo vas a encontrar una carpeta `demo` que contiene un ejercicio para que descubras más funcionalidades del debugger. Acá te dejamos una muestra del código: 51 | 52 | ```js 53 | var obj = { 54 | fullname: 'Natalia Nerea', 55 | prop: { 56 | fullname: 'Aurelio De Rosa', 57 | getFullname: function() { 58 | return this.fullname; //A qué apunta este this? 59 | } 60 | } 61 | }; 62 | var test; 63 | function saludar( saludo, obj ){ //A qué apunta el this en este momento? 64 | test = obj.prop.getFullname() 65 | return function( nombre, test ){ 66 | alert(saludo + ' ' + nombre); 67 | console.log(test) //Qué quedó guardado en la variable test? 68 | } 69 | } 70 | 71 | var saludarHola = saludar('Hola', obj); //Soy la primer llamada de función 72 | 73 | saludarHola('Toni', test); //Fijate que aparece en Scope cuando ejecutamos esta función... 74 | ``` 75 | 76 | 77 | No vas a ver nada en el navegador cuando abras el html. Tenés que abrir el inspector, pestaña sources y colocar los breakpoints en diferentes lineas de código. Donde vos quieras! Por ejemplo, podría ser en las lineas 17, 23, 25, 30 y 32. Fijate que va pasando en las subpestañas Call stack y Scope a medida que avanzas con los los botones del panel de control 😉 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/debugging/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Demo 8 | 9 | 10 | 76 | 77 | -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/debugging/img/botones.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/02-JavaScriptAvanzado-I/debugging/img/botones.jpg -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/debugging/img/bps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/02-JavaScriptAvanzado-I/debugging/img/bps.png -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/debugging/img/panels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/02-JavaScriptAvanzado-I/debugging/img/panels.png -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/debugging/img/subpanels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/02-JavaScriptAvanzado-I/debugging/img/subpanels.png -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/demo/execution context.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var sayHello = 'Hello'; 4 | 5 | function person() { 6 | var first = 'David'; 7 | var last = 'Shariff'; 8 | 9 | function firstName() { 10 | return first; 11 | } 12 | function lastName() { 13 | return last; 14 | } 15 | alert(sayHello + ' ' + firstName() + ' ' + lastName()); 16 | } -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/errores.md: -------------------------------------------------------------------------------- 1 | # Manejo de Errores en JavaScript 2 | 3 | Escribir programas que anden bien cuando todo funciona como esperabamos es un buen comienzo. Pero esto no sucede todo el tiempo, siempre vamos a encontrar situaciones que estaban más allá de lo que podiamos esperar que suceda (usuarios). Y acá es donde se pone un poco más díficil. Veamos como podemos manejar situaciones inesperadas dentro de nuestro código, para eso vamos a aprender sobre __errores__ en JavaScript. 4 | 5 | ## Tipos de Errores 6 | 7 | Mientras codeamos, o mientras ejecutamos nuestro programas pueden aparecer distintos tipos de errores en distintos momentos según quién causa el error, el tipo de error y cuando ocurre. Vamos a poder distinguir entre los siguientes tipos: 8 | * __Errores de Sintaxis__: Se producen porque el programador no respeta las reglas sintácticas del lenguaje. 9 | * __Errores Semánticos__: Se dan por el mal uso de algún _Statement_ del lenguaje. ej: Loop infinito. 10 | * __Errores Lógicos__: Aparecen porque el código no realiza lo que esperabamos que haga. 11 | 12 | Desde el punto de vista de _cuando_ surge el error, podemos tener: 13 | * __Errores en tiempo de Compilación__: Aparecen cuando nuestro código es parseado por un compilador o intérprete (errores de sintaxis). 14 | * __Errores de Runtime__: Los errores semánticos y de lógica van a aparecer cuando el código se este ejecutando. 15 | 16 | Según quien causa el error: 17 | * __Errores de Programación__: Es causado por un error del programador, por ejemplo: Utiliza mal una función y pasa argumentos incorrectos. Estos son los famosos `bugs`. 18 | * __Problemas Genuinos__: Escapa a las manos del programador y ocurren en programas que están bien codeados, por ejemplo, cunado un usuario ingresa un input que la función no esperaba o el servidor al que nos queríamos conectar está caído, etc... 19 | 20 | Podemos intentar resolver estos problemas (o alertar que ocurren) usando algunas funciones conocidas del lenguaje, como hacer un console.log() con un mensaje, o retornar un valor extraño cuando ocurra un error (por ejemplo -1), etc... Pero todo esto sólo nos servirá para controlar algunos errores en ambientes semi controlados (yo mismo invoco las funciones que estoy armando, y voy a entender cómo manejar los errores). Para los demás errores, o cuando sucede algo extraño, queremos se frene la ejecución (o cambie de rumbo) y continuar en un lugar en donde se sepa como _manejar_ el error. Hacer esto, en varios lenguajes, es conocido como __manejo de excepciones__. 21 | 22 | ## Manejo de excepciones 23 | 24 | Básicamente, es posible que el código _levante (raise)_ o _tire (throw)_ una excepción, que es un valor (un objeto). Podríamos decir que es parecido a un `return`, pero con superpoderes, porque este `return` puede volver no sólo _salir_ de la función en la que está, si no saltear varios execution contexts hasta llegar el entorno más alto donde se haya iniciado la serie de invocaciones que llegaron a generar una excepción. En inglés este proceso se conoce como _unwinding the stack_. 25 | Por suerte, cuando programamos podemos intentar _agarrar (catch)_ una excepción que va _subiendo_ (o _bajando_) por el stack de ejecución, de tal forma que ejecutemos código en donde agarramos la excepción y seguir desde ahí. 26 | Para hacer esto en JavaScript vamos a usar el statement: `try` y `catch`: 27 | 28 | ```javascript 29 | try { 30 | //Código a ejecutar 31 | [break;] 32 | } 33 | 34 | catch ( e ) { 35 | // Código a ejecutar si ocurre una excepción (acá la agarramos) 36 | [break;] 37 | } 38 | // el finally es opcional 39 | [ finally { 40 | // Siempre se ejecuta este código, haya o no una excepción 41 | }] 42 | ``` 43 | 44 | Por ejemplo: 45 | 46 | ```javascript 47 | function lastElement(array) { 48 | if (array.length > 0) 49 | return array[array.length - 1]; 50 | else 51 | throw "No existe el último elemento de un arreglo vacío."; 52 | } 53 | 54 | function lastElementPlusTen(array) { 55 | return lastElement(array) + 10; 56 | } 57 | 58 | try { 59 | print(lastElementPlusTen([])); 60 | } 61 | catch (error) { 62 | print("Hubo un problema ", error); 63 | } 64 | ``` 65 | 66 | Cómo vemos en el ejemplo, `throw` es el _keyword_ usado para crear una excepción. Ahora, cualquier código que se ejecute, o haya sido ejecutado desde lo que esté dentro del `try` statement, al generar una excepción, va a frenar su ejecución y devolver la excepción al `catch` statement. La variable `error`, en este caso, es el __nombre__ que le damos a la _excepción_ que acabamos de capturar. 67 | 68 | > Si no hay excepciones, entonces nunca se ejecuta lo que está en `catch`. 69 | 70 | Noten que la función `lastElementPlusTen` no tiene idea que `lastElement` puede no funcionar, simplemente la invoca. Eso es lo bueno de manejar excepciones, sólo nos tenemos que concentrar en donde se produce, y donde la atrapamos, todas las invocaciones en el medio, no tienen que enterarse. 71 | 72 | --- 73 | 74 | Tal vez no lo sabíamos, pero muchos errores en realidad lo que hacen es tirar una excepción. Por ejemplo: 75 | 76 | ```javascript 77 | try { 78 | console.log(hola); 79 | }catch (error) { 80 | console.log("Atrapado: " + error.message); 81 | } 82 | ``` 83 | 84 | En casos como este, Objetos especiales son tirados como error. Estos objetos contienen una propiedad `message`, que contiene una descripción del problema. Podemos crear nosotros mismos este tipo de Objetos usando el constructor: 85 | 86 | ```javascript 87 | throw new Error('Hola no existe!!!'); 88 | ``` 89 | 90 | Cuando una excepción es _tirada_, pero no hay nadie que la _atrape_, empieza a subir por el stack de ejecución, hasta que finalmente llega hasta el ambiente global, en donde es _atrapada_ por este. Por lo tanto, cada _enviroment_ va a manejar como quiera la excepción, en general dejan de ejecutar lo que estaban haciendo y te muestran la excepción con un formato particular. 91 | 92 | ### Errores con el Event Emitter 93 | 94 | En ciertos casos, por la naturaleza asincrónica de JavaScript, podemos perder el rastro de cómo suben las excepciones, o tal vez queremos saber si hay un error o no en otro contexto por el cúal no _subirá_ la excepción. Para resolver esto, podemos usar el __event emitter__ como un emisor de errores. Básicamente, pondríamos un _listener_ a escuchar por un evento de tipo __Error__, y luego, en nuestro código simplemente emitiriamos un evento de este tipo cuando encontremos un error. 95 | 96 | ### Error-Fist callback 97 | 98 | Cuando codeamos funciones que ejecutan callbacks, si existió un error podemos crear un nuevo `Error` y pasarlo como __primer parámetro__ cuando invocamos el callback: 99 | 100 | ```javascript 101 | //hubo un error 102 | return cb(new Error('pasó tal cosa'), null); 103 | 104 | // no hubo problemas 105 | return cb(null, datos); 106 | ``` 107 | 108 | Noten, que cuando hacemos esto no ejecutamos un `throw`, ya que esperamos que alguien lo haga cuando vea el resultado del callback. De esta forma, estamos generando errores __Asincrónicos__. 109 | 110 | > Si usamos el patrón de Event Emitter o error first callback los errores se generan asincrónicamente, si lo hacemos con `throw` lo estamos haciendo de manera sincrónica. 111 | 112 | ### Ejemplos de funciones conocidas y cómo manejan los errores 113 | 114 | | __Función__ | __Tipo de función__| __Ejemplo de error__ | __Tipo de error__ | __Qué usa__ | __Como lo manejamos__| 115 | |-------- | ----:| ----:| ----: | ----: | ----: | 116 | |`fs.stat`| asincrónico | archivo no encontrado | genuino| callback | manejamos el error del callback | 117 | |`JSON.parse`| sincrónico | input incorrecto | genuino| `throw` | `try / catch` | 118 | |`fs.stat`| asincrónico | `null` como input | programación| `throw` | arreglamos el bug | 119 | 120 | > `fs.stat` devuelve datos sobre un archivo en particular, está en la librería core `fs`. 121 | 122 | 123 | Links copados: 124 | 125 | * [Joyent](https://www.joyent.com/node-js/production/design/errors) -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/homework/homework.js: -------------------------------------------------------------------------------- 1 | function printing() { 2 | console.log(1); 3 | setTimeout(function () { 4 | console.log(2); 5 | }, 1000); 6 | setTimeout(function () { 7 | console.log(3); 8 | }, 0); 9 | console.log(4); 10 | } 11 | 12 | printing(); -------------------------------------------------------------------------------- /02-JavaScriptAvanzado-I/homework/homework.md: -------------------------------------------------------------------------------- 1 | # Homework JavaScript Avanzado I 2 | 3 | ## Scope & Hoisting 4 | 5 | Determiná que será impreso en la consola, sin ejecutar el código. 6 | 7 | > Investiga cuál es la diferencia entre declarar una variable con `var` y directamente asignarle un valor. 8 | 9 | ```javascript 10 | x = 1; 11 | var a = 5; 12 | var b = 10; 13 | var c = function (a, b, c) { 14 | var x = 10; 15 | console.log(x); 16 | console.log(a); 17 | var f = function (a, b, c) { 18 | b = a; 19 | console.log(b); 20 | b = c; 21 | var x = 5; 22 | }; 23 | f(a, b, c); 24 | console.log(b); 25 | }; 26 | c(8, 9, 10); 27 | console.log(b); 28 | console.log(x); 29 | ``` 30 | 31 | ```javascript 32 | console.log(bar); 33 | console.log(baz); 34 | foo(); 35 | function foo() { 36 | console.log('Hola!'); 37 | } 38 | var bar = 1; 39 | baz = 2; 40 | ``` 41 | 42 | ```javascript 43 | var instructor = 'Tony'; 44 | if (true) { 45 | var instructor = 'Franco'; 46 | } 47 | console.log(instructor); 48 | ``` 49 | 50 | ```javascript 51 | var instructor = 'Tony'; 52 | console.log(instructor); 53 | (function () { 54 | if (true) { 55 | var instructor = 'Franco'; 56 | console.log(instructor); 57 | } 58 | })(); 59 | console.log(instructor); 60 | ``` 61 | 62 | ```javascript 63 | var instructor = 'Tony'; 64 | let pm = 'Franco'; 65 | if (true) { 66 | var instructor = 'The Flash'; 67 | let pm = 'Reverse Flash'; 68 | console.log(instructor); 69 | console.log(pm); 70 | } 71 | console.log(instructor); 72 | console.log(pm); 73 | ``` 74 | 75 | ### Coerción de Datos 76 | 77 | ¿Cuál crees que será el resultado de la ejecución de estas operaciones?: 78 | 79 | ```javascript 80 | 6 / "3" 81 | "2" * "3" 82 | 4 + 5 + "px" 83 | "$" + 4 + 5 84 | "4" - 2 85 | "4px" - 2 86 | 7 / 0 87 | {}[0] 88 | parseInt("09") 89 | 5 && 2 90 | 2 && 5 91 | 5 || 0 92 | 0 || 5 93 | [3]+[3]-[10] 94 | 3>2>1 95 | [] == ![] 96 | ``` 97 | 98 | > Si te quedó alguna duda repasá con [este artículo](http://javascript.info/tutorial/object-conversion). 99 | 100 | ### Hoisting 101 | 102 | ¿Cuál es el output o salida en consola luego de ejecutar este código? Explicar por qué: 103 | 104 | ```javascript 105 | function test() { 106 | console.log(a); 107 | console.log(foo()); 108 | 109 | var a = 1; 110 | function foo() { 111 | return 2; 112 | } 113 | } 114 | 115 | test(); 116 | ``` 117 | 118 | Y el de este código? : 119 | 120 | ```javascript 121 | var snack = 'Meow Mix'; 122 | 123 | function getFood(food) { 124 | if (food) { 125 | var snack = 'Friskies'; 126 | return snack; 127 | } 128 | return snack; 129 | } 130 | 131 | getFood(false); 132 | ``` 133 | 134 | ### This 135 | 136 | ¿Cuál es el output o salida en consola luego de ejecutar esté código? Explicar por qué: 137 | 138 | ```javascript 139 | var fullname = 'Juan Perez'; 140 | var obj = { 141 | fullname: 'Natalia Nerea', 142 | prop: { 143 | fullname: 'Aurelio De Rosa', 144 | getFullname: function () { 145 | return this.fullname; 146 | }, 147 | }, 148 | }; 149 | 150 | console.log(obj.prop.getFullname()); 151 | 152 | var test = obj.prop.getFullname; 153 | 154 | console.log(test()); 155 | ``` 156 | 157 | ### Event loop 158 | 159 | Considerando el siguiente código, ¿Cuál sería el orden en el que se muestra por consola? ¿Por qué? 160 | 161 | ```javascript 162 | function printing() { 163 | console.log(1); 164 | setTimeout(function () { 165 | console.log(2); 166 | }, 1000); 167 | setTimeout(function () { 168 | console.log(3); 169 | }, 0); 170 | console.log(4); 171 | } 172 | 173 | printing(); 174 | ``` 175 | 176 |
177 | 178 | --- 179 | 180 | ## **✅ FEEDBACK** 181 | 182 | ### Usa este [**formulario**](https://docs.google.com/forms/d/e/1FAIpQLSe1MybH_Y-xcp1RP0jKPLndLdJYg8cwyHkSb9MwSrEjoxyzWg/viewform) para reportar tus observaciones de mejora o errores. Tu feedback es muy importante para seguir mejorando el modelo educativo. 183 | -------------------------------------------------------------------------------- /03-JavaScriptAvanzado-II/README.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "lesson", 3 | "lessonTitle": "JavaScript Avanzado II", 4 | "feedbackID": "02-JavaScriptAvanzado-II", 5 | "permalink": "/JS_Avanzado_II/", 6 | "quizzID" : "60662c1a656c8d23c2e60e66", 7 | "homeworkUrl": "https://github.com/soyHenry/FT-M1/tree/master/03-JavaScriptAvanzado-II/homework", 8 | "eleventyNavigation": { 9 | "key": "JS Avanzado II", 10 | "order": 3 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /03-JavaScriptAvanzado-II/homework/README.md: -------------------------------------------------------------------------------- 1 | # JAVASCRIPT AVANZADO II | Homework 2 | 3 | ## 📒 Temas de la clase 4 | 5 | - Closures (cláusulas). 6 | - Objeto `this`. 7 | - Métodos de funciones. 8 | 9 | --- 10 | 11 | ## 👀 Aprendizaje esperado 12 | 13 | Al finalizar esta homework habrás aprendido a: 14 | 15 | - Definir una **_closure_** y cómo es su funcionamiento. 16 | - Cómo opera el objeto this y qué métodos podemos utilizar para enlazarlo a otros contextos 17 | 18 | --- 19 | 20 | ## ⏱ Duración estimada 21 | 22 | > 60 minutos 23 | 24 | --- 25 | 26 | ## 📋 Instrucciones preliminares 27 | 28 | 1. Para ubicarte dentro de la carpeta homework escribe en tu terminal los siguientes comandos: 29 | - cd + [03-JavascriptAvanzado-II]. 30 | - cd + [homework]. 31 | 2. Luego, instalaremos las dependencias con el comando: 32 | 33 | ```javascript 34 | npm install 35 | ``` 36 | 37 | 3. Listo! Ya puedes correr los test con el comando: 38 | 39 | ```javascript 40 | npm test 41 | ``` 42 | 43 | --- 44 | 45 | ## 👩‍💻 **CONSIGNA** 46 | 47 | En este homework tendremos un total de 5 ejercicios. 48 | 49 |
50 | 51 | ### 🟡 **Ejercicios 1 y 2** 52 | 53 | En estos ejercicios trabajaremos con closures. Crearemos un contador automático y una función para guardar caché. ¡Consejo del día :D!: puedes ayudarte o guiarte con los ejemplos y el material que se vieron en vivo. Esto te facilitará el pensamiento lógico. 54 | 55 |
56 | 57 | ### 🟡 **Ejercicio 3** 58 | 59 | Aquí resolveremos algunas funciones en las que redireccionaremos el objeto this. 60 | 61 |
62 | 63 | ### 🟡 **Ejercicios 4 y 5** 64 | 65 | estos ejercicios son **_EXTRA CREDIT_**, por lo que tienen menor prioridad que los anteriores. Pero si logras resolverlos puedes conciderarte un profesional del código. En ambos trabajarás con `clases` y el objeto `this`. 66 | 67 |
68 | 69 | En este punto puedes comenzar a codear, verás instrucciones dentro del archivo homework.js 70 | 71 | --- 72 | 73 | ## 🧠 Recuerda que... 74 | 75 | - Con clausuras / closures puedes acceder a valores de una función que ya terminó de ejecutarse, esto te permite “hacer privados” ciertos datos, ya que solo podrás accederlos desde la función retornada. 76 | - Si el objeto this no toma la referencia del contexto que esperas, o no se comporta como necesitas, podrás modificar su scope con la función que aprendiste: bind. 77 | 78 | --- 79 | 80 | ## 🔎 Recursos adicionales 81 | 82 | - **[Closures](https://developer.mozilla.org/es/docs/Web/JavaScript/Closures)** 83 | - **[Método bind](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)** 84 | 85 |
86 | 87 | --- 88 | 89 | ## **✅ FEEDBACK** 90 | 91 | ### Usa este [**formulario**](https://docs.google.com/forms/d/e/1FAIpQLSe1MybH_Y-xcp1RP0jKPLndLdJYg8cwyHkSb9MwSrEjoxyzWg/viewform) para reportar tus observaciones de mejora o errores. Tu feedback es muy importante para seguir mejorando el modelo educativo. 92 | -------------------------------------------------------------------------------- /03-JavaScriptAvanzado-II/homework/homework.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Closures 4 | 5 | /* Ejercicio 1 6 | La función counter debe retornar otra función. Esta función retornada debe actuar como un contador, retornando 7 | un valor numérico que empieza en 1 e incrementa con cada invocación. 8 | EJEMPLO 9 | const nuevoContador = counter() 10 | nuevoContador() // 1 11 | nuevoContador() // 2 12 | 13 | const otroContador = counter() 14 | otroContador() // 1 15 | otroContador() // 2 */ 16 | function counter() { 17 | let countNumber = 1; 18 | return function () { 19 | return countNumber++; 20 | } 21 | } 22 | 23 | /* Ejercicio 2 24 | Tu tarea aquí es lograr, mediante un closure, que cacheFunction actúe como una memoria caché para el callback 25 | que recibe por parámetro (cb); es decir, que "recuerde" el resultado de cada operación que hace, de manera que, 26 | al realizar una operación por segunda vez, se pueda obtener el resultado de esa "memoria" sin tener que efectuar 27 | otra vez cálculos que ya se hicieron anteriormente. 28 | 29 | - cacheFunction debe retornar una función. Esta función debe aceptar un argumento (arg) e invocar a cb con ese argumento; hecho eso, debe guardar el argumento junto con el 30 | resultado de la invocación (tip: usá un objeto donde cada propiedad sea el argumento, y su valor el resultado de la correspondiente invocación a cb) de manera que, 31 | la próxima vez que reciba el mismo argumento, no sea necesario volver a invocar a cb, porque el resultado estará guardado en la "memoria caché". 32 | 33 | Ejemplo: 34 | function square(n){ 35 | return n * n 36 | } 37 | 38 | const squareCache = cacheFunction(square) 39 | 40 | squareCache(5) // invocará a square(5), almacenará el resultado y lo retornará 41 | squareCache(5) // no volverá a invocar a square, simplemente buscará en la caché cuál es el resultado de square(5) y lo retornará (tip: si usaste un objeto, podés 42 | usar hasOwnProperty) */ 43 | 44 | function cacheFunction(cb) { 45 | let cache = {} 46 | return function (arg) { 47 | if (cache.hasOwnProperty(arg)) { 48 | return cache[arg]; 49 | } else { 50 | cache[arg] = cb(arg) 51 | return cache[arg]; 52 | } 53 | } 54 | } 55 | 56 | // * Vamos a tener que ejecutar el arg con la cb 57 | // * Deberiamos de verificar si ya se ejecutó en un pasado la cb con el arg recibido. LISTO 58 | // ! SINO se ha ejecutado, deberia ejecutarse y ádemas almacenar el resultado en la caché 59 | //---------------------------------------- 60 | 61 | // Bind 62 | 63 | var instructor = { 64 | nombre: 'Franco', 65 | edad: 25, 66 | }; 67 | 68 | var alumno = { 69 | nombre: 'Juan', 70 | curso: 'FullStack', 71 | }; 72 | 73 | function getNombre() { 74 | return this.nombre; 75 | } 76 | 77 | /* 78 | Ejercicio 3 79 | IMPORTANTE: no modificar el código de arriba (variables instructor y alumno, y función getNombre) 80 | Usando el método bind() guardar, en las dos variables declaradas a continuación, dos funciones que actúen como getNombre pero retornen el nombre del instructor y del alumno, 81 | respectivamente. 82 | */ 83 | 84 | let getNombreInstructor = getNombre.bind(instructor); 85 | let getNombreAlumno = getNombre.bind(alumno); 86 | 87 | /* 88 | Ejercicio 4 89 | Sin modificar la función crearCadena, usar bind para guardar, en las tres variables declaradas a continuación, tres funciones que retornen una cadena (string) y 90 | el delimitador especificado (asteriscos, guiones, y guiones bajos, respectivamente). Las funciones obtenidas deberían recibir solamente un argumento - 91 | la cadena de texto - ya que los otros argumentos habrán sido "bindeados". 92 | */ 93 | 94 | function crearCadena(delimitadorIzquierda, delimitadorDerecha, cadena) { 95 | return delimitadorIzquierda + cadena + delimitadorDerecha; 96 | } 97 | 98 | let textoAsteriscos = crearCadena.bind(null, '*', '*'); 99 | let textoGuiones = crearCadena.bind(null, '-', '-'); 100 | let textoUnderscore = crearCadena.bind(null, '_', '_'); 101 | 102 | console.log(textoAsteriscos('hola')) 103 | console.log(textoGuiones('hola')) 104 | console.log(textoUnderscore('hola')) 105 | 106 | // No modifiquen nada debajo de esta linea 107 | // -------------------------------- 108 | 109 | module.exports = { 110 | counter, 111 | cacheFunction, 112 | getNombreInstructor, 113 | getNombreAlumno, 114 | textoAsteriscos, 115 | textoGuiones, 116 | textoUnderscore, 117 | }; 118 | -------------------------------------------------------------------------------- /03-JavaScriptAvanzado-II/homework/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "03-js-2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "jest --collectCoverage=false JSAI.test.js", 7 | "grade": "jest --useStderr --json --outputFile=./tests/result.json" 8 | }, 9 | "devDependencies": { 10 | "jest": "^27.5.1" 11 | }, 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /03-JavaScriptAvanzado-II/homework/tests/JSAI.test.js: -------------------------------------------------------------------------------- 1 | // /* eslint-disable no-undef */ 2 | 'use strict' 3 | 4 | const { 5 | counter, 6 | cacheFunction, 7 | getNombreInstructor, 8 | getNombreAlumno, 9 | textoAsteriscos, 10 | textoGuiones, 11 | textoUnderscore 12 | } = require('../homework'); 13 | 14 | describe('counter', () => { 15 | it('should return a function', () => { 16 | expect(typeof counter()).toBe('function'); 17 | }); 18 | it('should return 1 when the returned function is invoked', () => { 19 | expect(counter()()).toBe(1); 20 | }); 21 | it('should increment and return the number each time the function is invoked', () => { 22 | const counterFunction = counter(); 23 | expect(counterFunction()).toBe(1); 24 | expect(counterFunction()).toBe(2); 25 | expect(counterFunction()).toBe(3); 26 | expect(counterFunction()).toBe(4); 27 | expect(counterFunction()).toBe(5); 28 | }); 29 | it('should have two diferent acumulators if two counters are created', () => { 30 | const counterOne = counter(); 31 | const counterTwo = counter(); 32 | expect(counterOne()).toBe(1); 33 | expect(counterOne()).toBe(2); 34 | expect(counterOne()).toBe(3); 35 | expect(counterOne()).toBe(4); 36 | expect(counterTwo()).toBe(1); 37 | expect(counterTwo()).toBe(2); 38 | }); 39 | }); 40 | 41 | describe('cacheFunction(cb)', function() { 42 | const cb = function(x) { 43 | return x * 2; 44 | }; 45 | it('should return the callback function', function() { 46 | expect(typeof cacheFunction(cb)).toEqual('function'); 47 | }); 48 | it('should return the callback functions result when the cached function is invoked', function() { 49 | const cachedFunction = cacheFunction(cb); 50 | expect(cachedFunction(5)).toBe(10); 51 | }); 52 | it('should cache function results', function() { 53 | const cachedFunction = cacheFunction(cb); 54 | var resultOne = cachedFunction(2); 55 | expect(resultOne).toBe(4); 56 | var resultTwo = cachedFunction(3); 57 | expect(resultTwo).toBe(6); 58 | var resultTwo = cachedFunction(2); 59 | expect(resultTwo).toBe(4); 60 | }); 61 | it('should avoid calling cb function when not necessary', function() { 62 | const cb = jest.fn(); 63 | const cachedFunction = cacheFunction(cb); 64 | cachedFunction(true); 65 | cachedFunction(true); 66 | cachedFunction(true); 67 | cachedFunction(true); 68 | cachedFunction(true); 69 | cachedFunction(10); 70 | cachedFunction(10); 71 | cachedFunction(10); 72 | cachedFunction(10); 73 | expect(cb).toHaveBeenCalledTimes(2); 74 | }); 75 | }); 76 | 77 | describe('Bind', function() { 78 | it('should return the correct name "Franco"', function() { 79 | expect(getNombreInstructor()).toEqual('Franco'); 80 | }); 81 | it('should return the correct name "Juan"', function() { 82 | expect(getNombreAlumno()).toEqual('Juan'); 83 | }); 84 | it('should return the correct string "*Hola*"', function() { 85 | expect(textoAsteriscos('Hola')).toEqual('*Hola*'); 86 | }); 87 | it('should return the correct string "-Hola-"', function() { 88 | expect(textoGuiones('Hola')).toEqual('-Hola-'); 89 | }); 90 | it('should return the correct string "_Hola_"', function() { 91 | expect(textoUnderscore('Hola')).toEqual('_Hola_'); 92 | }); 93 | }); 94 | -------------------------------------------------------------------------------- /04-EstructuraDeDatos-I/README.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "lesson", 3 | "lessonTitle": "Estructura de datos I", 4 | "feedbackID": "03-EstructuraDeDatos-I", 5 | "permalink": "/Estructura_de_datos_I/", 6 | "quizzID" : "6066323c656c8d23c2e60e75", 7 | "homeworkUrl": "https://github.com/soyHenry/FT-M1/tree/master/04-EstructuraDeDatos-I/homework", 8 | "eleventyNavigation": { 9 | "key": "Datos I", 10 | "order": 4 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /04-EstructuraDeDatos-I/homework/README.md: -------------------------------------------------------------------------------- 1 | # ESTRUCTURA DE DATOS I | Homework 2 | 3 | ## 📒 Temas de la clase 4 | 5 | - Recursión. 6 | - Estructuras de datos: 7 | - Stacks (Pilas). 8 | - Queues (Colas). 9 | 10 | --- 11 | 12 | ## 👀 Aprendizaje esperado 13 | 14 | Al finalizar esta homework podrás: 15 | 16 | - Identificar en que casos es conveniente utilizar la recursión y cómo aplicarla en la resolución de los problemas. 17 | - Construir dos estructuras de datos básicas: Stacks & Queues. También serás capaz de responder a las preguntas ¿Cómo se añade elementos en cada estructura? ¿Y cómo se eliminan? 18 | 19 | --- 20 | 21 | ## ⏱ Duración estimada 22 | 23 | > 90 minutos 24 | 25 | --- 26 | 27 | ## 📋 Instrucciones preliminares 28 | 29 | 1. Para ubicarte dentro de la carpeta homework escribe en tu terminal los siguientes comandos: 30 | - cd + [04-EstructuraDeDatos-I]. 31 | - cd + [homework]. 32 | 2. Luego, instalaremos las dependencias con el comando: 33 | 34 | ```javascript 35 | npm install 36 | ``` 37 | 38 | 3. Listo! Ya puedes correr los test con el comando: 39 | 40 | ```javascript 41 | npm test 42 | ``` 43 | 44 | --- 45 | 46 | ## 👩‍💻 **CONSIGNA** 47 | 48 | Este homework se compone de 3 ejercicios. 49 | 50 |
51 | 52 | ### 🟡 **Ejercicio 1** 53 | 54 | En este ejercicio tendrás que crear una función que utilice recursividad. Su objetivo es calcular el factorial del número recibido por parámetro (puede ser cero o positivo, pero nunca negativo). Si no sabes cuál es el factorial de un número te invitamos a investigarlo en la web! 55 | 56 |
57 | 58 | ### 🟡 **Ejercicio 2** 59 | 60 | ¿Alguna vez has escuchado sobre la secuencia de Fibonacci? En caso de que no, ¡te la recordamos! Esta es una sucesión de números positivos que inicia en cero. No está dictada al azar, sino que tiene un orden lógico. Cada número de está secuencia está formado por la suma de los dos números anteriores. Te mostramos cómo es el inicio de la secuencia de Fibonacci: 61 | 62 | 0 1 1 2 3 5 8 13 21 34 55 89 144 ... 63 | 64 | **¿Cuál es el objetivo de este ejercicio?** ¡Simple! Tienes que crear una función que devuelva el número de la secuencia que esté en la posición pasada por parámetro. ¡Recuerda que debes utilizar recursión para resolver este ejercicio! 65 | 66 |
67 | 68 | ### 🟡 **Ejercicio 3** 69 | 70 | En este último ejercicio no será necesario que utilices recursión. Aquí deberás implementar una clase llamada Queue. Esta clase tendrá distintos métodos que reflejarán el comportamiento característico de la estructura de datos. Te invitamos a que resuelvas este ejercicio de las dos maneras posibles: 71 | 72 | - Con clases normales (ECMAscript 2015). 73 | - Con una función constructora. 74 | 75 |
76 | 77 | En este punto puedes comenzar a codear, verás instrucciones dentro del archivo **_homework.js_**. 78 | 79 | --- 80 | 81 | ## 🧠 Recuerda que... 82 | 83 | - El navegador es tu mejor amigo. ¡Investiga todas tus dudas, curiosidades y errores! Esto te permitirá adquirir práctica para el día de mañana, ya que incluso el mejor programador investiga en internet ;). 84 | - Siempre puedes intentar buscar una solución recursiva. Suelen ser una alternativa a problemas complejos donde la iteratividad no es el camino más óptimo. 85 | - Javascript ofrece algunas estructuras de datos nativas (por ejemplo: Array). Puedes implementar otras a través de funciones constructoras, dándoles comportamiento a través de métodos. 86 | 87 | --- 88 | 89 | ## 📢 Extra Credit 90 | 91 | Como ejercicio adicional y completamente opcional, al terminar de resolver este problema puedes intentar redefinir las funciones de los ejercicios 1 y 2, de manera que logren los mismos resultados pero de manera iterativa. 92 | 93 |
94 | 95 | --- 96 | 97 | ## **✅ FEEDBACK** 98 | 99 | ### Usa este [**formulario**](https://docs.google.com/forms/d/e/1FAIpQLSe1MybH_Y-xcp1RP0jKPLndLdJYg8cwyHkSb9MwSrEjoxyzWg/viewform) para reportar tus observaciones de mejora o errores. Tu feedback es muy importante para seguir mejorando el modelo educativo. 100 | -------------------------------------------------------------------------------- /04-EstructuraDeDatos-I/homework/homework.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* 4 | Definir las funciones recursivas nFactorial y nFibonacci. 5 | 6 | nFactorial(n) debe retornar el factorial de n sabiendo que, siendo n un número natural, su factorial (representado como n!) 7 | es el producto de n por todos los números naturales menores que él y mayores a 0. Ejemplo: 5! = 5 * 4 * 3 * 2 * 1 8 | 9 | nFibonacci(n) debe retornar el enésimo número de la secuencia de Fibonacci, tomando al 0 y al 1, respectivamente, como primer y segundo elementos de la misma, 10 | y sabiendo que cualquier elemento que se agregue a esta secuencia será el resultado de la suma del último elemento y el anterior. 11 | Ejemplo: nFibonacci(7) retornará 13, ya que 13 es el dígito que está en la posición 7 de la secuencia. 12 | 13 | Secuencia: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 14 | 15 | 16 | Como ejercicio adicional y completamente opcional, al terminar de resolver este problema pueden intentar definir funciones que logren los mismos resultados pero de manera iterativa. 17 | */ 18 | 19 | function nFactorial(n) { 20 | // Ejemplo: 5! = 5 * 4 * 3 * 2 * 1 21 | // n! = n * (n-1)! 22 | // 1! = 1 y 0! = 1 23 | // n < 0 = 0 24 | if (n < 0) return 0; 25 | if (n === 0 || n === 1) return 1; 26 | 27 | return n * nFactorial(n - 1) 28 | } 29 | 30 | function nFibonacci(n) { 31 | // Secuencia: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 32 | // F(n) = F(n-1) + F(n-2) 33 | // nFibonacci(0) // 0 CASO BASE 34 | // nFibonacci(1) // 1 CASO BASE 35 | if (n < 0) return 'No es posible.' 36 | if (n === 0) return 0; 37 | if (n === 1) return 1; 38 | 39 | return nFibonacci(n - 1) + nFibonacci(n - 2) 40 | } 41 | 42 | 43 | 44 | // nFibonacci(4) = 2 + 1 => 3 45 | // nFibonacci(3) = 1 + 1 46 | // nFibonacci(2) = 1 + 0 47 | 48 | /* 49 | Implementar la clase Queue, sabiendo que es una estructura de tipo FIFO, donde el primer elemento que ingresa es el primero que se quita. Definir los siguientes métodos: 50 | - enqueue: agrega un valor respetando el orden. 51 | - dequeue: remueve un valor respetando el orden. Retorna undefined cuando la queue está vacía. 52 | - size: retorna el tamaño (cantidad de elementos) de la queue. 53 | 54 | Pueden utilizar class o función constructora. 55 | */ 56 | 57 | function Queue() { 58 | this.array = [] 59 | } 60 | 61 | Queue.prototype.enqueue = function (elemento) { 62 | this.array.push(elemento) 63 | } 64 | 65 | Queue.prototype.dequeue = function () { 66 | return this.array.shift() 67 | } 68 | Queue.prototype.size = function () { 69 | return this.array.length 70 | } 71 | 72 | /*⚠️ No modificar nada debajo de esta línea ⚠️*/ 73 | module.exports = { 74 | Queue, 75 | nFactorial, 76 | nFibonacci, 77 | }; 78 | -------------------------------------------------------------------------------- /04-EstructuraDeDatos-I/homework/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "04-ds-1", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "jest --collectCoverage=false DataStructureI.test.js", 7 | "grade": "jest --useStderr --json --outputFile=./tests/result.json" 8 | }, 9 | "devDependencies": { 10 | "jest": "^27.5.1" 11 | }, 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /04-EstructuraDeDatos-I/homework/tests/DataStructureI.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | 'use strict' 3 | 4 | const { 5 | Queue, 6 | nFactorial, 7 | nFibonacci 8 | } = require('../homework'); 9 | 10 | describe('nFactorial(n)', function() { 11 | it('debe devolver el factorial de n', function() { 12 | expect(nFactorial(5)).toBe(120); 13 | expect(nFactorial(15)).toBe(1307674368000); 14 | }); 15 | }); 16 | 17 | describe('nFibonacci(n)', function() { 18 | // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,… 19 | it('debe bevolver el enesimo número de la serie de fibonacci', () => { 20 | const fib1 = nFibonacci(0); 21 | const fib2 = nFibonacci(6); 22 | const fib3 = nFibonacci(9); 23 | const fib4 = nFibonacci(2); 24 | expect(fib1).toBe(0); 25 | expect(fib2).toBe(8); 26 | expect(fib3).toBe(34); 27 | expect(fib4).toBe(1); 28 | }); 29 | }); 30 | 31 | 32 | describe('Un queue', function() { 33 | var queue; 34 | 35 | beforeEach(function() { 36 | queue = new Queue(); 37 | }); 38 | 39 | it('tiene los metodos `enqueue`, `dequeue`, y `size`', function() { 40 | expect(typeof queue.enqueue).toBe('function'); 41 | expect(typeof queue.dequeue).toBe('function'); 42 | expect(typeof queue.size).toBe('function'); 43 | }); 44 | 45 | it('tiene size 0 inicialmente', function() { 46 | expect(queue.size()).toBe(0); 47 | }); 48 | 49 | it('incrementa en size cuando agregamos items', function() { 50 | queue.enqueue('first in line'); 51 | expect(queue.size()).toBe(1); 52 | }); 53 | 54 | it('decrementa en size cuando removemos elementos', function() { 55 | queue.enqueue('first'); 56 | queue.enqueue('second'); 57 | queue.enqueue('third'); 58 | queue.dequeue(); 59 | expect(queue.size()).toBe(2); 60 | }); 61 | 62 | it('devuelve el item correcto cuando dequeeamos', function() { 63 | queue.enqueue('first'); 64 | queue.enqueue('second'); 65 | queue.enqueue('third'); 66 | expect(queue.size()).toBe(3); 67 | expect(queue.dequeue()).toBe('first'); 68 | expect(queue.size()).toBe(2); 69 | expect(queue.dequeue()).toBe('second'); 70 | expect(queue.size()).toBe(1); 71 | expect(queue.dequeue()).toBe('third'); 72 | expect(queue.size()).toBe(0); 73 | }); 74 | 75 | it('maneja bien el underflow, cuando no hay elementos dequeue devuelve undefined', function() { 76 | queue.enqueue('first in line'); 77 | expect(queue.size()).toBe(1); 78 | expect(queue.dequeue()).toBe('first in line'); 79 | expect(queue.size()).toBe(0); 80 | expect(queue.dequeue()).toBe(undefined); 81 | expect(queue.size()).toBe(0); 82 | expect(queue.dequeue()).toBe(undefined); 83 | expect(queue.size()).toBe(0); 84 | }); 85 | 86 | it('maneja bien varios enqueue y dequeue', function(){ 87 | queue.enqueue(1); 88 | expect(queue.dequeue()).toBe(1); 89 | queue.enqueue(2); 90 | queue.enqueue(3); 91 | expect(queue.dequeue()).toBe(2); 92 | queue.enqueue(4); 93 | expect(queue.dequeue()).toBe(3); 94 | expect(queue.dequeue()).toBe(4); 95 | expect(queue.dequeue()).toBe(undefined); 96 | }); 97 | 98 | it('agrega y remueve sus propios items', function(){ 99 | var q2 = new Queue(); 100 | queue.enqueue('fullstack'); 101 | q2.enqueue('JavaScript'); 102 | expect(q2.dequeue()).toBe('JavaScript'); 103 | expect(q2.dequeue()).toBe(undefined); 104 | expect(queue.dequeue()).toBe('fullstack'); 105 | expect(queue.dequeue()).toBe(undefined); 106 | }); 107 | 108 | }); 109 | -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/Ejemplos/arrays.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /* ARRAYS FUNCTIONS */ 4 | 5 | // MENOR 6 | 7 | function minimo(arr) { 8 | var aux = arr[0]; 9 | for (var i=1; iaux) aux = arr[i]; 22 | } 23 | console.log('El mayor es: ',aux); 24 | return aux; 25 | } 26 | 27 | // TOTAL 28 | 29 | function total(arr) { 30 | var aux = arr.reduce(function(tot,num){ 31 | return tot+num; 32 | }) 33 | console.log('El total es: ', aux); 34 | return aux; 35 | } 36 | 37 | function totalBis(arr) { 38 | var aux = 0; 39 | for (var i=0; i 1) { 50 | pos--; 51 | pointer = pointer.next; 52 | } 53 | newNodo.next = pointer.next; 54 | pointer.next = newNodo; 55 | } 56 | 57 | Lista.prototype.print = function() { 58 | pointer = this.point; 59 | while (pointer.next!=null) { 60 | console.log(pointer.data); 61 | pointer = pointer.next; 62 | } 63 | console.log(pointer.data); 64 | } 65 | 66 | Lista.prototype.printOne = function(pos) { 67 | if (pos > this.len) return console.log('Posicion fuera de rango.'); 68 | pointer = this.point; 69 | var aux = pos; 70 | while (aux > 1) { 71 | aux--; 72 | pointer = pointer.next; 73 | } 74 | console.log('Data ['+pos+'] = '+pointer.data) 75 | } 76 | 77 | Lista.prototype.deleteFirst = function() { 78 | if (this.len == 0) return console.log('Es una lista vacia'); 79 | this.point = this.point.next; 80 | this.len--; 81 | } 82 | 83 | Lista.prototype.deleteLast = function() { 84 | pointer = this.point; 85 | while (pointer.next.next!=null) { 86 | pointer = pointer.next; 87 | } 88 | pointer.next = null; 89 | this.len--; 90 | } 91 | 92 | Lista.prototype.find = function(val) { 93 | if (this.len == 0) return console.log('Es una lista vacia'); 94 | var pointer = this.point; 95 | var check = false; 96 | if (pointer.data == val) check = true; 97 | while (!check && pointer.next != null) { 98 | pointer = pointer.next; 99 | if (pointer.data == val) check = true; 100 | } 101 | if (check) { 102 | return pointer; 103 | } else { 104 | return undefined; 105 | } 106 | } 107 | 108 | // var list = new Lista(); 109 | 110 | // list.push(1); 111 | // list.push(2); 112 | // list.push(3); 113 | // list.push(4); 114 | 115 | // list.print() 116 | -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/Ejemplos/matriz.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // MATRIZ 3 | 4 | class Matriz { 5 | 6 | constructor(alto, ancho) { 7 | this.data = []; 8 | for (var i=0; i 0) { 43 | pila.push(arr.shift()); 44 | } 45 | return function vaciar(pila,array) { 46 | if (pila.head == null) return array; 47 | array.push(pila.pop().data); 48 | return vaciar(pila,array); 49 | }(pila,arr); 50 | } 51 | -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/Ejemplos/torreDeHanoi.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | function Pila(){ 4 | this._arr = []; 5 | } 6 | 7 | Pila.prototype.push = function(v){ 8 | return this._arr.push(v); 9 | } 10 | 11 | Pila.prototype.pop = function(){ 12 | return this._arr.pop(); 13 | } 14 | 15 | Pila.prototype.len = function(){ 16 | return this._arr.length; 17 | } 18 | 19 | function Torre(){ 20 | this._t1 = new Pila(); 21 | this._t2 = new Pila(); 22 | this._t3 = new Pila(); 23 | } 24 | 25 | Torre.prototype.init = function(n){ 26 | for(var i = 1; i <=n ; i++){ 27 | this._t1.push(i); 28 | } 29 | return this; 30 | } 31 | /* 32 | Función Recursiva que realiza los movimientos para resolver la torre de Hanoi. 33 | @disk: Cantidad de platos a mover (pila de n platos). 34 | @source: Torre principal, sobre la que empezas a jugar (primera pila); 35 | @aux: Torre que vas a usar como auxiliar para poner los platos en movimientos intermedios. 36 | @dest: Torre objetivo, donde queres que lleguen los platos. 37 | */ 38 | Torre.prototype.solve = function(disk, source, dest, aux){ 39 | // Al principio no le paso parametro, por defecto quiero que mueva todos los platos de la primera 40 | // Pila hacia la última Pila. 41 | if(!disk){ 42 | mov = 0; 43 | var source = this._t1; 44 | var disk = source.len(); 45 | var dest = this._t3; 46 | var aux = this._t2; 47 | } 48 | if(disk == 1 ){ 49 | // Cuando a la pila de la izquierda le quede sólo un plato 50 | // hacemos el último movimiento y terminamos. 51 | dest.push(source.pop()); 52 | return; 53 | } else { 54 | //Mueve los platos de arriba del que queres move para hacer espacio 55 | // desde la origen a el auxiliar. 56 | this.solve(disk-1, source, aux, dest); 57 | //Mueve el ultimo plato del origen al destino 58 | dest.push(source.pop()); 59 | // Tiene que mover la torre que esta en auxiliar al destino, usando como auxiliar el origen que esta vacio 60 | this.solve(disk-1, aux, dest, source); 61 | } 62 | } 63 | 64 | let torreHanoi = new Torre(); 65 | torreHanoi.init(29).solve(); 66 | 67 | // console.log(torreHanoi); -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/Ejemplos/torredeHanoi.py: -------------------------------------------------------------------------------- 1 | _t1 = range(1,9) 2 | _t2 = [] 3 | _t3 = [] 4 | def solve(disk , source, dest, aux): 5 | if disk >= 1: 6 | solve(disk-1, source, aux, dest) 7 | dest.append(source.pop()) 8 | solve(disk-1, aux, dest, source) 9 | else: 10 | return; 11 | 12 | print len(_t1) 13 | solve(len(_t1), _t1, _t3, _t2) 14 | print _t3 -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/Ejemplos/torredehanoiFacu.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // TORRE DE HANOI // 3 | 4 | function Torre(){ 5 | this.head = null; 6 | this.high = 0; 7 | this.push = function(data){ 8 | var newDisc = new disc(data) 9 | if(this.head == null) { 10 | this.head = newDisc; 11 | }else{ 12 | newDisc.under = this.head; 13 | this.head = newDisc; 14 | } 15 | this.high++; 16 | } 17 | this.pop = function(){ 18 | if(this.head == null){ 19 | return null 20 | } 21 | var popDisc = this.head; 22 | this.head = popDisc.under; 23 | this.high--; 24 | popDisc.under = null; 25 | return popDisc; 26 | } 27 | this.move = function(pila){ 28 | if(pila.head == null || this.head.size < pila.head.size){ 29 | pila.push(this.pop().size); 30 | }else if(this.head.size > pila.head.size){ 31 | return console.log('Disco mas grande que la base pretendida'); 32 | }else{ 33 | return console.log('Torre vacia'); 34 | } 35 | 36 | } 37 | this.print = function(){ 38 | if ( this.head == null ) return console.log('Torre vacia'); 39 | var pointer = this.head; 40 | while( pointer != null ){ 41 | console.log( pointer.size ); 42 | pointer = pointer.under; 43 | } 44 | } 45 | function disc(data) { 46 | this.size = data; 47 | this.under = null; 48 | } 49 | } 50 | 51 | function torreDeHanoi(val){ 52 | 53 | var t1 = new Torre(); 54 | var t2 = new Torre(); 55 | var t3 = new Torre(); 56 | for(var i=val;i>0;i--){ 57 | t1.push(i) 58 | }; 59 | imprimirTorres(); 60 | makeMove(t1,t2,t3,val); 61 | function makeMove( ppal , aux , final , altTorre ){ 62 | if( altTorre == 1 ){ 63 | ppal.move(final); 64 | return 65 | } 66 | makeMove( ppal , final , aux , altTorre-1 ); 67 | ppal.move(final) 68 | makeMove( aux , ppal , final , altTorre-1 ); 69 | }; 70 | 71 | // Comentar la impresion para mejor rendimiento 72 | imprimirTorres(); 73 | function imprimirTorres(){ 74 | console.log('Torre 1 :'); 75 | t1.print(); 76 | console.log('Torre 2 :'); 77 | t2.print(); 78 | console.log('Torre 3 :'); 79 | t3.print(); 80 | }; 81 | }; 82 | 83 | // torreDeHanoi(6); -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/README.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "lesson", 3 | "lessonTitle": "Estructura de datos II", 4 | "feedbackID": "04-EstructuraDeDatos-II", 5 | "permalink": "/Estructura_de_datos_II/", 6 | "quizzID": "606eed05656c8d23c2e60efa", 7 | "homeworkUrl": "https://github.com/soyHenry/FT-M1/tree/master/05-EstructuraDeDatos-II/homework", 8 | "eleventyNavigation": { 9 | "key": "Datos II", 10 | "order": 5 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/README.md: -------------------------------------------------------------------------------- 1 | ![HenryLogo](https://d31uz8lwfmyn8g.cloudfront.net/Assets/logo-henry-white-lg.png) 2 | 3 | 4 | 5 | 12 | 19 | 20 |
6 | 7 | 8 |
9 | Hacé click acá para dejar tu feedback sobre esta clase. 10 |
11 |
13 | 14 | 15 |
16 | Hacé click acá completar el quizz teórico de esta lecture. 17 |
18 |
21 | 22 | # Estructuras de Datos II 23 | 24 | ## Listas Enlazadas 25 | 26 | Básicamente, las listas enlazadas, son una secuencia de nodos enlazados entre ellos y que contienen información. Podemos decir que cada nodo contiene datos y además uno o más links a otros nodos. Según las restricciones que tengan la cantidad de links, estas pueden ser simplemente enlazadas, dobles o múltiples. 27 | 28 | ![no-box](../_src/assets/04-EstructuraDeDatos-I/singlelist.png) 29 | 30 | ¿Donde podemos usar una lista enlazada? Por ejemplo, si tenemos que modelar el plan de vuelo de un avión una buena posibilidad sería una lista enlazada de aeropuertos. O en el browser para poder ir hacia atrás y adelante en las páginas web del historial también podríamos usar una lista doblemente enlazada, o también las podes usar para representar un mazo de cartas para jugar blackjack. :smile: 31 | 32 | ### Lista Enlazada simple en Javascript 33 | 34 | Hagamos nuestra primera lista enlazada. 35 | Como cada nodo puede ser un objeto por sí mismo, vamos a codear dos constructores: el _nodo_ y la _lista_ en si. 36 | 37 | El nodo contiene datos y un puntero o un link al siguiente nodo, por defecto el nodo no va a apuntar a ningún otro nodo. 38 | 39 | ```javascript 40 | function Node(data) { 41 | this.data = data; 42 | this.next = null; 43 | } 44 | ``` 45 | 46 | La clase lista, necesita sólamente un puntero o link que apunte al primer nodo de la lista. Adicionalmente vamos a agregar la propiedad length, para poder saber siempre la longitud de nuestra lista enlazada. Al crear una lista va a estar vacía por o tanto la cabeza es `null` y _length_ es cero. 47 | 48 | ```javascript 49 | function List() { 50 | this._length = 0; 51 | this.head = null; 52 | } 53 | ``` 54 | 55 | ### Operaciones en una lista 56 | 57 | Veamos que operaciones podemos hacer en una lista: 58 | 59 | * _Iterar sobre la lista_: Recorrer la lista viendo sus elementos o hasta que encontremos el elemento deseado. 60 | * _Insertar un nodo_: La operación va a cambiar según el lugar donde querramos insertar el nodo nuevo: 61 | * Al principio de la lista. 62 | * En el medio de la lista. 63 | * Al final de la lista. 64 | 65 | ![InsertarTop](../_src/assets/04-EstructuraDeDatos-I/listAdd.gif) 66 | 67 | _El orden en el que actualizan los punteros es muy importante. Si actualizan el la cabeza de la lista primero, pierden la lista!!_ 68 | 69 | * _Sacar un nodo_: 70 | * Del principio de la lista. 71 | * Del medio de la lista. 72 | 73 | ![ScarNodo](../_src/assets/04-EstructuraDeDatos-I/listaRemove.gif) 74 | 75 | ![Remove](../_src/assets/04-EstructuraDeDatos-I/listaRemove.png) 76 | 77 | _Para sacar un item, directamente hacemos que no se pueda alcanzar desde el comienzo de la lista_ 78 | 79 | Implementación de la función insertar al final: 80 | 81 | ```javascript 82 | List.prototype.add = function(data) { 83 | var node = new Node(data), 84 | current = this.head; 85 | // Si está vacia 86 | if (!current) { 87 | this.head = node; 88 | this._length++; 89 | return node; 90 | } 91 | // Si no esta vacia, recorro hasta encontrar el último 92 | while (current.next) { 93 | current = current.next; 94 | } 95 | current.next = node; 96 | this._length++; 97 | return node; 98 | }; 99 | ``` 100 | 101 | Escribamos algo para poder ver la lista que hemos creado y sus nodos: 102 | 103 | ```javascript 104 | List.prototype.getAll = function(){ 105 | current = this.head //empezamos en la cabeza 106 | if(!current){ 107 | console.log('La lista esta vacia!') 108 | return 109 | } 110 | while(current){ 111 | console.log(current.data); 112 | current = current.next; 113 | } 114 | return 115 | }; 116 | ``` 117 | 118 | Genial! Como ejercicio van a tener que implementar las demás funcionalidades ustedes mismos. 119 | 120 | ### Listas Doblemente Enlazadas 121 | 122 | En la lista que vimos antes, sólo podemos recorrer la lista en un solo sentido. En algunos casos nos puede servir recorrer la lista en los dos sentidos, para tales casos lo que vamos a usar es una lista doblemente enlazada. 123 | Como se puede imaginar, una lista doblemente enlazada es aquella que cada nodo tiene dos links, uno para el nodo siguiente, y otro para el nodo anterior. 124 | 125 | ![no-box](../_src/assets/04-EstructuraDeDatos-I/doueblelist.png) 126 | 127 | Ahora es fácil ir y venir entre los items. Ahora las operaciones tienen un paso más, que es hacer que los nuevos links apunten al nodo correcto. 128 | 129 | ## Tablas Hash (Hash tables) 130 | 131 | Esta estructura que guarda los datos de una manera asociativa, o sea con un par clave-valor o key-value. Los datos son guardados como en un arreglo, pero los índices tienen que ver con lo qué está guardado adentro. Esto hace que sean muy rápidas para buscar datos. 132 | 133 | ![no-box](../_src/assets/04-EstructuraDeDatos-I/hashfunction.png) 134 | 135 | De hecho, la función que transforman un elemento en una cadena de longitud finita (a esto se lo conoce como _hash_) se llama función _hash_. El término hash proviene, aparentemente, de la analogía con el significado estándar (en inglés) de dicha palabra en el mundo real: picar y mezclar. Donald Knuth cree que H. P. Luhn, empleado de IBM, fue el primero en utilizar el concepto en un memorándum fechado en enero de 1953. Su utilización masiva no fue hasta después de 10 años. 136 | 137 | Como las funciones hash nos devuelven un número finito de posibilidades, vamos a tener que reservar la misma cantidad de memoria para poder guardar cualquier cosa que, al ser hasheada, 'caiga' en esa key. Por lo tanto, las tablas hash van a ocupar más espacio, con el objetivo de ganar velocidad. De nuevo, según la naturaleza del problema te a convenir o no usarlas. 138 | 139 | Para construir una hash table vamos a necesitar: 140 | 141 | * _Una estrucura de datos_: Acá vamos a guardar los datos y buscarlos por el índice. Puede ser un arreglo, o un árbol, etc.. 142 | * _Una función hasheadora_: Vamos a necesitar una función que nos transforme lo que elegimos de key a un hash que será nuestro índice. 143 | * _Una política de resolución de colisiones_: Es la política que definiremos para decidir qué pasa cuando dos keys distintas generar dos hash iguales (las funciones no son perfectas !). 144 | 145 | ## Homework 146 | 147 | Completa la tarea descrita en el archivo [README](https://github.com/soyHenry/FT-M1/blob/master/05-EstructuraDeDatos-II/homework/README.md) 148 | -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/homework/README.md: -------------------------------------------------------------------------------- 1 | # ESTRUCTURA DE DATOS II | Homework 2 | 3 | ## 📒 Temas de la clase 4 | 5 | - Listas enlazadas. 6 | - Hash table. 7 | 8 | --- 9 | 10 | ## 👀 Aprendizaje esperado 11 | 12 | Al finalizar este homework serás capaz de construir dos nuevas estructuras de datos: Listas Enlazadas y Hash Tables. También habrás aprendido a configurar sus distintos métodos básicos. 13 | 14 | --- 15 | 16 | ## ⏱ Duración estimada 17 | 18 | > 120 minutos 19 | 20 | --- 21 | 22 | ## 📋 Instrucciones preliminares 23 | 24 | 1. Para ubicarte dentro de la carpeta homework escribe en tu terminal los siguientes comandos: 25 | - cd + [05-EstructuraDeDatos-II]. 26 | - cd + [homework]. 27 | 2. Luego, instalaremos las dependencias con el comando: 28 | 29 | ```javascript 30 | npm install 31 | ``` 32 | 33 | 3. Listo! Ya puedes correr los test con el comando: 34 | 35 | ```javascript 36 | npm test 37 | ``` 38 | 39 | --- 40 | 41 | ## 👩‍💻 **CONSIGNA** 42 | 43 | En este homework encontrarás 2 ejercicios. 44 | 45 |
46 | 47 | ### 🟡 **Ejercicio 1** 48 | 49 | El objetivo de este ejercicio es desarrollar una lista enlazada. Para esto deberemos crear dos clases distintas: LinkedList y Node. En la clase LinkedList iremos acumulando los distintos nodos que queramos agregar. En cambio, la clase Node, nos servirá como cápsula de la información que queramos agregar en nuestra lista enlazada. 50 | 51 | Te proponemos como desafío que realices este ejercicio 2 veces! Una utilizando las clases introducidas en ECMAscript 2015. La otra utilizando funciones constructoras. Esto te permitirá tener mayor entendimiento y facilidad a la hora de utilizar clases 😀. 52 | 53 |
54 | 55 | ### 🟡 **Ejercicio 2** 56 | 57 | En este ejercicio crearemos una clase llamada **HashTable** que simulará el funcionamiento de una real. Esta deberá contar con 4 métodos: _**hash**_, **_set_**, **_get_** y **_hasKey_**. 58 | 59 |
60 | 61 | En este punto puedes comenzar a codear, verás instrucciones dentro del archivo _**homework.js**_. 62 | 63 | --- 64 | 65 | ## 🧠 Recuerda que... 66 | 67 | - Una lista enlazada siempre comienza por un HEAD. Esto quiere decir que los datos no se almacenan ni se leen de forma aleatoria. Cada vez que quiero almacenar o leer esos datos debo realizar un proceso para poder llegar a su posición. 68 | - La Hash Table nos servirá para hashear (cifrar o encriptar) un dato. Una vez que el dato queda cifrado obtendremos un identificador único e irrepetible asociado a ese dato. Los hashes son una pieza clave en la tecnología blockchain y tiene una amplia utilidad. 69 | 70 | --- 71 | 72 | ## 🔎 Recursos adicionales 73 | 74 | - **[HashTables](https://www.youtube.com/watch?v=9tZsDJ3JBUA)** 75 | 76 |
77 | 78 | --- 79 | 80 | ## **✅ FEEDBACK** 81 | 82 | ### Usa este [**formulario**](https://docs.google.com/forms/d/e/1FAIpQLSe1MybH_Y-xcp1RP0jKPLndLdJYg8cwyHkSb9MwSrEjoxyzWg/viewform) para reportar tus observaciones de mejora o errores. Tu feedback es muy importante para seguir mejorando el modelo educativo. 83 | -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/homework/homework.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* EJERCICIO 1 4 | Implementar la clase LinkedList, definiendo los siguientes métodos: 5 | - add: agrega un nuevo nodo al final de la lista; 6 | - remove: elimina el último nodo de la lista y retorna su valor (tener en cuenta el caso particular de una lista de un solo nodo y de una lista vacía); 7 | - search: recibe un parámetro y lo busca dentro de la lista, con una particularidad: el parámetro puede ser un valor o un callback. En el primer caso, 8 | buscamos un nodo cuyo valor coincida con lo buscado; en el segundo, buscamos un nodo cuyo valor, al ser pasado como parámetro del callback, retorne true. 9 | EJEMPLO 10 | search(3) busca un nodo cuyo valor sea 3; 11 | search(isEven), donde isEven es una función que retorna true cuando recibe por parámetro un número par, busca un nodo cuyo valor sea un número par. 12 | En caso de que la búsqueda no arroje resultados, search debe retornar null. 13 | */ 14 | function LinkedList() { 15 | this.head = null; 16 | } 17 | 18 | function Node(value) { 19 | this.value = value; 20 | this.next = null; 21 | } 22 | 23 | LinkedList.prototype.add = function (value) { 24 | let newNode = new Node(value) 25 | let current = this.head 26 | if (!current) { 27 | this.head = newNode 28 | return newNode 29 | } 30 | while (current.next) { 31 | current = current.next 32 | } 33 | current.next = newNode 34 | return newNode 35 | } 36 | LinkedList.prototype.remove = function () { 37 | let current = this.head 38 | // Cuando no hay un head o hay un solo nodo 39 | if (!current) return null 40 | if (!current.next) { 41 | this.head = null 42 | return current.value 43 | } 44 | while (current.next.next) { 45 | current = current.next 46 | } 47 | 48 | let aux = current.next.value 49 | current.next = null 50 | return aux; 51 | 52 | } 53 | 54 | LinkedList.prototype.search = function (value) { 55 | let current = this.head 56 | if (!current) return null 57 | 58 | while (current) { 59 | if (typeof value === 'function') { 60 | if (value(current.value)) return current.value 61 | } 62 | if (current.value === value) return value; 63 | current = current.next 64 | } 65 | return null 66 | } 67 | 68 | /* EJERCICIO 2 69 | Implementar la clase HashTable. 70 | Nuetra tabla hash, internamente, consta de un arreglo de buckets (slots, contenedores, o casilleros; es decir, posiciones posibles para almacenar la información), 71 | donde guardaremos datos en formato clave-valor (por ejemplo, {instructora: 'Iván'}). 72 | Para este ejercicio, la tabla debe tener 35 buckets (numBuckets = 35). (Luego de haber pasado todos los tests, a modo de ejercicio adicional, 73 | pueden modificar un poco la clase para que reciba la cantidad de buckets por parámetro al momento de ser instanciada.) 74 | 75 | La clase debe tener los siguientes métodos: 76 | - hash: función hasheadora que determina en qué bucket se almacenará un dato. Recibe un input alfabético, suma el código numérico de cada caracter del input 77 | (investigar el método charCodeAt de los strings) y calcula el módulo de ese número total por la cantidad de buckets; de esta manera determina la posición de la 78 | tabla en la que se almacenará el dato. 79 | - set: recibe el conjunto clave valor (como dos parámetros distintos), hashea la clave invocando al método hash, y almacena todo el conjunto en el bucket correcto. 80 | - get: recibe una clave por parámetro, y busca el valor que le corresponde en el bucket correcto de la tabla. 81 | - hasKey: recibe una clave por parámetro y consulta si ya hay algo almacenado en la tabla con esa clave (retorna un booleano). 82 | 83 | Ejemplo: supongamos que quiero guardar {instructora: 'Ani'} en la tabla. Primero puedo chequear, con hasKey, si ya hay algo en la tabla con el nombre 'instructora'; 84 | luego, invocando set('instructora', 'Ani'), se almacenará el par clave-valor en un bucket específico (determinado al hashear la clave) 85 | */ 86 | function HashTable() { 87 | this.numBuckets = 35 88 | this.buckets = [] 89 | } 90 | 91 | HashTable.prototype.hash = function (string) { 92 | let suma = 0 93 | for (let i = 0; i < string.length; i++) { 94 | suma += string.charCodeAt(i) 95 | } 96 | return suma % this.numBuckets 97 | } 98 | 99 | HashTable.prototype.set = function (key, value) { 100 | if (typeof key !== 'string') { 101 | throw new TypeError('Keys must be strings') 102 | } 103 | let index = this.hash(key) // RETORNA EL INDICE 104 | if (!this.buckets[index]) this.buckets[index] = {} 105 | this.buckets[index][key] = value // GUARDANDO EL VALOR EN EL INDICE 106 | } 107 | HashTable.prototype.get = function (key) { 108 | let index = this.hash(key) 109 | return this.buckets[index][key] 110 | } 111 | HashTable.prototype.hasKey = function (key) { 112 | let index = this.hash(key) 113 | if (this.buckets[index][key]) return true; 114 | return false; 115 | } 116 | 117 | // No modifiquen nada debajo de esta linea 118 | // -------------------------------- 119 | 120 | module.exports = { 121 | Node, 122 | LinkedList, 123 | HashTable, 124 | }; 125 | -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/homework/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "05-ds-2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "jest --collectCoverage=false DataStructureII.test.js", 7 | "grade": "jest --useStderr --json --outputFile=./tests/result.json" 8 | }, 9 | "devDependencies": { 10 | "jest": "^27.5.1" 11 | }, 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /05-EstructuraDeDatos-II/homework/tests/DataStructureII.test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const { 4 | Node, 5 | LinkedList, 6 | HashTable 7 | } = require('../homework'); 8 | 9 | describe('Una linked list', function () { 10 | var linkedList; 11 | 12 | beforeEach(function () { 13 | linkedList = new LinkedList(); 14 | }); 15 | 16 | it('tiene metodos `add`, `remove`, y `search`', function () { 17 | expect(typeof linkedList.add).toBe('function'); 18 | expect(typeof linkedList.remove).toBe('function'); 19 | expect(typeof linkedList.search).toBe('function'); 20 | }); 21 | 22 | it('empiezan head como null', function () { 23 | expect(linkedList.hasOwnProperty('head')).toBe(true); 24 | expect(linkedList.head).toBeFalsy(); 25 | expect(linkedList.remove()).toBeFalsy(); 26 | }); 27 | 28 | it('tiene una clase Node para representar un nodo', function () { 29 | expect(typeof Node).toBe('function'); 30 | expect(isNative(Node)).toBe(false); 31 | function isNative(fn) { 32 | return (/\{\s*\[native code]\s*\}/).test('' + fn); 33 | } 34 | }); 35 | 36 | it('La clase Node deberia tomar un valor como argumento y definir next como null por default', function () { 37 | var node = new Node('test'); 38 | expect(node.value).toBe('test'); 39 | expect(node.next).toBe(null); 40 | }); 41 | 42 | it('linkedlist deberia usar la clase Node para agregar nodos en add', function () { 43 | linkedList.add('first'); 44 | expect(linkedList.head instanceof Node).toBe(true); 45 | }); 46 | 47 | it('add agrega los elementos linkeandolos entre ellos a traves del next', function () { 48 | linkedList.add('first'); 49 | linkedList.add('second'); 50 | expect(linkedList.head.value).toBe('first'); 51 | expect(linkedList.head.next.value).toBe('second'); 52 | expect(linkedList.head.next.next).toBe(null); 53 | }); 54 | 55 | it('remove deberia retornar null si la lista esta vacia', function () { 56 | expect(linkedList.remove()).toBeFalsy(); 57 | }); 58 | 59 | it('remove deberia sacar el ultimo nodo ingresado y devolver su valor', function () { 60 | linkedList.add('first'); 61 | linkedList.add('second'); 62 | expect(linkedList.remove()).toBe('second'); 63 | expect(linkedList.remove()).toBe('first'); 64 | }); 65 | 66 | it('el head deberia ser null cuando se sacan todos los nodos', function () { 67 | expect(linkedList.remove()).toBeFalsy(); 68 | linkedList.add('one'); 69 | expect(linkedList.remove()).toBe('one'); 70 | expect(linkedList.remove()).toBeFalsy(); 71 | expect(linkedList.head).toBeFalsy(); 72 | }); 73 | 74 | 75 | it('deberia devolver los valores correctos para buscar', function () { 76 | linkedList.add('one'); 77 | linkedList.add('two'); 78 | linkedList.add('three'); 79 | linkedList.add('four'); 80 | expect(linkedList.search('two')).toBe('two'); 81 | expect(linkedList.search('sdd')).toBe(null); 82 | expect(linkedList.search('one')).toBe('one'); 83 | expect(linkedList.search('four')).toBe('four'); 84 | }); 85 | 86 | it('deberia poder tomar strings y funciones ambos como search inputs', function () { 87 | linkedList.add('one'); 88 | linkedList.add('two'); 89 | expect(linkedList.search(function (nodeValue) { 90 | return nodeValue === 'two'; 91 | })).toBe('two'); 92 | }); 93 | 94 | it('deberia poder buscar por lo tanto no solo strings pero tambien objetos', function () { 95 | function UserNode(name, email, city) { 96 | this.name = name; 97 | this.email = email; 98 | this.city = city; 99 | } 100 | 101 | linkedList.add(new UserNode('Nimit', 'nimit@fs.com', 'New York')); 102 | linkedList.add(new UserNode('David', 'david@fs.com', 'New York')); 103 | linkedList.add(new UserNode('Paul', 'paul@yc.com', 'Mountain View')); 104 | 105 | expect(linkedList.search(function (userNode) { 106 | return userNode.name === 'Nimit'; 107 | }).email).toBe('nimit@fs.com'); 108 | 109 | expect(linkedList.search(function (userNode) { 110 | return userNode.email === 'david@fs.com'; 111 | }).city).toBe('New York'); 112 | 113 | expect(linkedList.search(function (userNode) { 114 | return userNode.city === 'Mountain View'; 115 | }).name).toBe('Paul'); 116 | }); 117 | 118 | }); 119 | 120 | describe('HashTable', function () { 121 | var hashTable; 122 | 123 | beforeEach(function () { 124 | hashTable = new HashTable(); 125 | }); 126 | 127 | it('deberia tener 35 buckets', function () { 128 | expect(hashTable.numBuckets).toBe(35); 129 | }); 130 | 131 | it('deberia tener metodos `set`, `get`, y `hasKey`', function () { 132 | expect(typeof hashTable.set).toBe('function'); 133 | expect(typeof hashTable.get).toBe('function'); 134 | expect(typeof hashTable.hasKey).toBe('function'); 135 | }); 136 | 137 | it('deberia `hash` correctament', function () { 138 | // esta funcion hasheadora deberia sumar los key code de las letras de la palabra, 139 | // y hacer el mod de ese numero por el numero de buckets . 140 | expect(hashTable.hash('foo')).toBe(9); 141 | expect(hashTable.hash('this is a key')).toBe(27); 142 | expect(hashTable.hash('what about this one')).toBe(13); 143 | }); 144 | 145 | it('deberia guardar y buscar valores por key', function () { 146 | hashTable.set('key1', 'val1'); 147 | hashTable.set('key2', 'val2'); 148 | hashTable.set('this is a very different string', 44.4); 149 | expect(hashTable.get('key1')).toBe('val1'); 150 | expect(hashTable.get('key2')).toBe('val2'); 151 | expect(hashTable.get('this is a very different string')).toBe(44.4); 152 | }); 153 | 154 | it('deberia devolver un error cuando el key no es un string', function () { 155 | expect(function () { 156 | hashTable.set(false, 'hi'); 157 | }).toThrowError(TypeError, 'Keys must be strings'); 158 | }); 159 | 160 | it('deberia manejar colisiones', function () { 161 | hashTable.set('foo', 'bar1'); 162 | hashTable.set('ofo', 'bar2'); 163 | expect(hashTable.get('ofo')).toBe('bar2'); 164 | expect(hashTable.get('foo')).toBe('bar1'); 165 | }); 166 | 167 | it('deberia sobreescribir keys', function () { 168 | hashTable.set('foo', 'bar1'); 169 | hashTable.set('foo', 'bar2'); 170 | expect(hashTable.get('foo')).toBe('bar2'); 171 | }); 172 | 173 | it('deberia devolver booleanos para el metodo #hasKey', function () { 174 | hashTable.set('foobar', 'fluf cats'); 175 | expect(hashTable.hasKey('foobar')).toBe(true); 176 | expect(hashTable.hasKey('raboof')).toBe(false); 177 | }); 178 | 179 | }); 180 | -------------------------------------------------------------------------------- /06-EstructuraDeDatos-III/Ejemplos/arbolBusqueda/arbolBinarioBusqueda.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var abs = Math.abs; 4 | var max = Math.max; 5 | var min = Math.min; 6 | 7 | function Node(data){ 8 | this.data = data; 9 | this.left = null; 10 | this.right = null; 11 | } 12 | 13 | Node.prototype.search = function(s){ 14 | if(this.data === s){ 15 | return this; 16 | } 17 | if(s <= this.data && this.left !== null){ 18 | return this.left.search(s); 19 | }else if(s > this.data && this.right !== null){ 20 | return this.right.search(s) 21 | }else{ 22 | return undefined; 23 | } 24 | } 25 | 26 | Node.prototype.isBalanced = function(){ 27 | if(!this.right && !this.left) return true 28 | if(abs(this.balanceFactor())>1){ 29 | return false 30 | } 31 | if(!this.right){ 32 | return this.left.isBalanced(); 33 | }else if(!this.left){ 34 | return this.right.isBalanced(); 35 | } 36 | else{ 37 | return this.right.isBalanced() && this.left.isBalanced(); 38 | } 39 | } 40 | 41 | Node.prototype.height = function(){ 42 | if(!this.left && !this.right){ 43 | return 0; 44 | }else{ 45 | if(this.left && !this.right){ 46 | return this.left.height() + 1; 47 | }else if(!this.left && this.right){ 48 | return this.right.height() + 1; 49 | }else{ 50 | return max(this.left.height() + 1, this.right.height() + 1 ); 51 | } 52 | } 53 | } 54 | 55 | Node.prototype.balanceFactor = function(){ 56 | if(!this.left && !this.right){ 57 | return 0; 58 | }else{ 59 | if(this.left && !this.right){ 60 | return - this.left.height() - 1 ; 61 | }else if(!this.left && this.right){ 62 | return this.right.height() + 1; 63 | }else{ 64 | return this.right.height() - this.left.height() ; 65 | } 66 | } 67 | } 68 | 69 | Node.prototype.rotate = function(){ 70 | var aux; 71 | if(this.balanceFactor() <= -2){ 72 | if(this.left.left && this.left.balanceFactor() <= 0){ 73 | //Left Left 74 | // console.log('ll','pivot:', this.data); 75 | aux = this.left; 76 | this.left = aux.right; 77 | aux.right = this; 78 | 79 | }else if(this.left.right){ 80 | //Left Right 81 | // console.log('lr','pivot:', this.data); 82 | aux = this.left.right; 83 | this.left.right = aux.left; 84 | aux.left = this.left; 85 | this.left = aux.right; 86 | aux.right = this; 87 | } 88 | }else if (this.balanceFactor() >=2 ){ 89 | if(this.right.right && this.right.balanceFactor() >= 0){ 90 | //Right Right 91 | // console.log('rr','pivot:', this.data); 92 | aux = this.right; 93 | this.right = aux.left; 94 | aux.left = this; 95 | }else if(this.right.left){ 96 | //Right Left 97 | // console.log('rl','pivot:', this.data); 98 | aux = this.right.left; 99 | this.right.left = aux.right; 100 | aux.right = this.right; 101 | this.right = aux.left; 102 | aux.left = this; 103 | } 104 | } 105 | return aux; 106 | } 107 | 108 | Node.prototype.print = function(s){ 109 | if(!s){ 110 | s=0; 111 | console.log('==================='); 112 | } 113 | console.log('--'.repeat(s)+this.data); 114 | ++s; 115 | if(this.left) this.left.print(s); 116 | if(this.right) this.right.print(s); 117 | } 118 | 119 | Node.prototype.add = function(v,r){ 120 | if(!r) var r = this; 121 | if( v < this.data){ 122 | if(this.left === null){ 123 | this.left = new Node(v); 124 | }else{ 125 | this.left.add(v,r); 126 | } 127 | } 128 | if( v >= this.data){ 129 | if(this.right === null){ 130 | this.right = new Node(v); 131 | }else{ 132 | this.right.add(v,r); 133 | } 134 | } 135 | return this; 136 | } 137 | 138 | Node.prototype.insert = function(v){ 139 | var tree = this; 140 | this.add(v); 141 | while(!this.isBalanced()){ 142 | tree = tree.balance(); 143 | } 144 | return tree; // always return the root 145 | } 146 | 147 | Node.prototype.maxBalanceFactor = function(m){ 148 | if(m === undefined) var m = 0; 149 | else{ 150 | if (abs(this.balanceFactor()) > m) m = abs(this.balanceFactor()); 151 | } 152 | if(!this.left && this.right) return max(this.right.maxBalanceFactor(m), m); 153 | if(!this.right && this.left) return max(this.left.maxBalanceFactor(m), m); 154 | if(this.right && this.left) return max(this.right.maxBalanceFactor(m), this.left.maxBalanceFactor(m)) 155 | if(!this.right && !this.left) return 1; 156 | } 157 | 158 | Node.prototype.balance = function(anterior, arbol, from){ 159 | if(!arbol) arbol = this; 160 | if(!anterior) anterior = this; 161 | let thisbf = this.balanceFactor(); 162 | let leftbf = Infinity; 163 | let rightbf = Infinity; 164 | if(this.isBalanced()) return arbol; 165 | if(this.left) leftbf = this.left.balanceFactor(); 166 | if(this.right) rightbf = this.right.balanceFactor(); 167 | 168 | // console.log( 'node:',this.data,'l:', leftbf, 'this:', thisbf , 'r:', rightbf); 169 | if((thisbf < 0 && this.maxBalanceFactor() >= abs(thisbf) )){ 170 | //el desbalance está a la izquierda 171 | if(this.left){ 172 | return this.left.balance(this,arbol, 'left'); 173 | } 174 | }else if(( thisbf > 0 && this.maxBalanceFactor() >= thisbf)){ 175 | //desbalance a la derecha 176 | if(this.right){ 177 | return this.right.balance(this, arbol, 'right'); 178 | } 179 | }else{ 180 | if(this.right) if( !this.right.isBalanced()) return this.right.balance(this, arbol, 'right'); 181 | if(this.left) if( !this.left.isBalanced()) return this.left.balance(this, arbol, 'right'); 182 | //este arbol esta desbalanceado 183 | if(this == arbol) { return this.rotate() } 184 | else{anterior[from] = this.rotate(); } 185 | } 186 | return arbol; 187 | 188 | } 189 | 190 | Node.prototype.findMin = function(){ 191 | if(this.left && this.right){ 192 | var l = this.left.findMin(); 193 | var r = this.right.findMin(); 194 | if(l.data < r.data) return l; 195 | else return r 196 | }else{ 197 | if(this.left){ 198 | minL = this.left.findMin(); 199 | return minL.data <= this.data ? minL: this; 200 | } 201 | if(this.right){ 202 | minR = this.right.findMin(); 203 | return minR.data <= this.data ? minR: this; 204 | } 205 | } 206 | if(!this.left && !this.right) return this; 207 | } 208 | 209 | Node.prototype.findMax = function(){ 210 | if(this.left && this.right){ 211 | var l = this.left.findMax(); 212 | var r = this.right.findMax(); 213 | if(l.data > r.data) return l; 214 | else return r 215 | }else{ 216 | if(this.left){ 217 | let maxL = this.left.findMax(); 218 | return maxL.data > this.data ? maxL: this; 219 | 220 | } 221 | if(this.right){ 222 | let maxR = this.right.findMax() 223 | return maxR.data > this.data ? maxR: this 224 | } 225 | } 226 | if(!this.left && !this.right) return this; 227 | } 228 | 229 | Node.prototype.delete = function(v){ 230 | var tree = this; 231 | var node = this.search(v); 232 | if(!this.left && !this.right && this === node) return null; 233 | if(!node) return this; 234 | if(node.left){ 235 | var target = node.left.findMax(); 236 | if(node.left == target) node.left = target.left; 237 | node.destroy(target); 238 | node.data = target.data; 239 | }else if(node.right){ 240 | var target = node.right.findMin() 241 | if(node.left === target) node.left = target.left; 242 | node.destroy(target); 243 | node.data = target.data; 244 | node.right = target.right; 245 | }else{ 246 | this.destroy(node); 247 | } 248 | while(!this.isBalanced()){ 249 | tree = tree.balance(); 250 | } 251 | return tree; 252 | } 253 | 254 | Node.prototype.destroy = function(n, anterior, next){ 255 | if(!anterior) var anterior = this; 256 | if(this == n ){ 257 | if( anterior == this){ //Is the root element 258 | return null; 259 | }else{ 260 | return anterior[next] = null; 261 | } 262 | } 263 | if(n.data < this.data){ 264 | if(this.left){ 265 | this.left.destroy(n, this, 'left' ) 266 | } 267 | }else{ 268 | if(this.right){ 269 | this.right.destroy(n, this, 'right' ) 270 | } 271 | } 272 | return this; 273 | } 274 | // var tree = new Node(22).insert(20).insert(62).insert(36).insert(60).insert(78).insert(68) 275 | // .insert(5).insert(37).insert(49) 276 | 277 | // var tree= new Node(60).add(68).add(62).add(78).add(22).add(20).add(5).add(36).add(37).add(49).balance2() 278 | // tree = new Node(100).insert(62).insert(34).insert(15).insert(21).insert(86).insert(12) 279 | // .insert(8).insert(8).insert(92); 280 | // var tree = new Node(87).insert(93).insert(61).insert(80).insert(8).insert(89).insert(22) 281 | // .insert(91).insert(60).insert(33); 282 | 283 | let tree = new Node(87).insert(93).insert(61).insert(80).insert(8).insert(91).insert(60).insert(33).insert(34).insert(35).insert(36); 284 | //.delete(8).delete(7).delete(6).delete(5).delete(4).delete(3).delete(2).delete(1); 285 | // console.log('arbol:\n',tree); 286 | console.log('arbol:\n',tree); 287 | 288 | module.exports = Node; -------------------------------------------------------------------------------- /06-EstructuraDeDatos-III/Ejemplos/arbolBusqueda/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "arbolbusqueda", 3 | "version": "0.0.1", 4 | "description": "Implementacion en JavaScript de arbol binario de busqueda AVL autobalanceado.", 5 | "main": "arbolBinarioBusqueda.js", 6 | "dependencies": { 7 | "tape": "^4.6.3", 8 | "underscore": "^1.8.3" 9 | }, 10 | "devDependencies": {}, 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "author": "Toni Tralice", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /06-EstructuraDeDatos-III/Ejemplos/arbolBusqueda/tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var N = require('./arbolBinarioBusqueda.js'); 4 | var _ = require('underscore'); 5 | var test = require('tape'); 6 | 7 | test('Rotations', function (t) { 8 | var tree = new N(3).add(2).add(1).rotate(); 9 | t.deepEqual(tree, new N(2).add(1).add(3), 'Left Left Rotation.') 10 | 11 | tree = new N(5).add(2).add(3).rotate(); 12 | t.deepEqual(tree, new N(3).add(2).add(5) , 'Left Right Rotation.') 13 | 14 | tree = new N(6).add(7).add(4).add(5).add(3).add(2).rotate(); 15 | t.deepEqual(tree, new N(4).add(3).add(2).add(6).add(5).add(7) , 'Left Left Rotation 2.') 16 | 17 | tree = new N(1).add(2).add(3).rotate(); 18 | t.deepEqual(tree, new N(2).add(1).add(3) , 'Right Right Rotation 1.') 19 | 20 | tree = new N(2).add(1).add(4).add(3).add(5).add(6).rotate(); 21 | t.deepEqual(tree, new N(4).add(2).add(1).add(3).add(5).add(6) , 'Right Right Rotation 2.'); 22 | 23 | tree = new N(1).add(3).add(2).rotate(); 24 | t.deepEqual(tree, new N(2).add(1).add(3), 'Right Left Rotation.'); 25 | 26 | t.end(); 27 | }); 28 | 29 | test('Height', function (t) { 30 | var tree = new N(1).add(2).add(3).add(4).add(5).add(6); 31 | t.equal(tree.height(), 5, 'Height of the tree 1.'); 32 | 33 | tree = new N(6).add(4).add(3).add(5).add(8).add(7).add(9); 34 | t.equal(tree.height(), 2, 'Height of the tree 2.'); 35 | 36 | t.end(); 37 | }); 38 | 39 | 40 | test('Searches', function (t) { 41 | 42 | var tree = new N(1).add(2).add(3).add(4).add(5).add(6); 43 | t.equal(tree.search(2).data,2,'Search 1.'); 44 | 45 | tree = new N(6).add(4).add(3).add(5).add(8).add(7).add(9); 46 | t.notOk(tree.search(99), 'Search 2.'); 47 | 48 | t.end(); 49 | }); 50 | 51 | 52 | test('Balance', function (t) { 53 | var tree = new N(1).add(2).add(3).add(4).add(5).add(6); 54 | t.notOk(tree.isBalanced(), 'Balance of Tree.'); 55 | 56 | tree = new N(6).add(4).add(3).add(5).add(8).add(7).add(9); 57 | t.ok(tree.isBalanced(), 'Balance of Tree 2.'); 58 | 59 | tree = new N(4).add(3).add(2).add(1).add(6).add(5).add(7); 60 | t.notOk(tree.isBalanced(), 'Balance of Tree 3.') 61 | t.end(); 62 | }); 63 | 64 | test('Balance Factor', function (t) { 65 | var tree = new N(1).add(2).add(3).add(4).add(5).add(6); 66 | t.equal(tree.balanceFactor(), 5, 'Balance Factor of Node.'); 67 | 68 | tree = new N(1).add(2).add(3).add(4).add(5).add(6).add(0); 69 | t.equal(tree.balanceFactor(), 4, 'Balance Factor of Node 2.'); 70 | 71 | tree = new N(6).add(4).add(3).add(5).add(8).add(7).add(9); 72 | t.equal(tree.balanceFactor(), 0, 'Balance Factor of Node 3.'); 73 | 74 | t.end(); 75 | }); 76 | 77 | test('Auto Balance', function (t) { 78 | var tree = new N(1).insert(2).insert(3).insert(4).insert(5).insert(6).insert(7); 79 | t.deepEqual(tree, new N(4).add(2).add(1).add(3).add(6).add(5).add(7) , 'Auto Balance on Insert 1.'); 80 | 81 | 82 | tree = new N(7).insert(6).insert(5).insert(4).insert(3).insert(2).insert(1); 83 | t.deepEqual(tree, new N(4).add(2).add(1).add(3).add(6).add(5).add(7) , 'Auto Balance on Insert 2.'); 84 | 85 | 86 | tree = new N(22).insert(20).insert(62).insert(36).insert(60).insert(78).insert(68) 87 | .insert(5).insert(37).insert(49); 88 | var correct = new N(60).add(22).add(20).add(37).add(5).add(36).add(49).add(68).add(62).add(78); 89 | t.deepEqual(tree, correct , 'Auto Balance on Insert random numbers 1.'); 90 | 91 | tree = new N(100).insert(62).insert(34).insert(15).insert(21).insert(86).insert(12) 92 | .insert(8).insert(8).insert(92); 93 | correct = new N(62).add(12).add(8).add(8).add(21).add(15).add(34).add(92).add(86).add(100); 94 | t.deepEqual(tree, correct , 'Auto Balance on Insert random numbers 2.'); 95 | 96 | tree = new N(87).insert(93).insert(61).insert(80).insert(8).insert(89).insert(22) 97 | .insert(91).insert(60).insert(33); 98 | correct = new N(87).add(60).add(22).add(8).add(33).add(61).add(80).add(91).add(89).add(93); 99 | t.deepEqual(tree, correct , 'Auto Balance on Insert random numbers 3.'); 100 | 101 | tree = new N(100).insert(62).insert(34).insert(15).insert(21).insert(86).insert(12) 102 | .insert(8).insert(8).insert(92).insert(25).insert(70).insert(55).insert(6).insert(22); 103 | correct = new N(21).add(12).add(8).add(6).add(8).add(15).add(62).add(34).add(25).add(55).add(22).add(92).add(86).add(100).add(70); 104 | t.deepEqual(tree, correct , 'Auto Balance on Insert random numbers 4.'); 105 | 106 | t.end(); 107 | }); 108 | 109 | 110 | test('Deleting Nodes', function (t) { 111 | var tree = new N(1).insert(2).insert(3).insert(4).insert(5).delete(4); 112 | var correct = new N(2).add(1).add(3).add(5); 113 | t.deepEqual(tree, correct, 'Deleting Nodes 1.') 114 | 115 | tree = new N(1).insert(2).insert(3).insert(4).insert(5).delete(2); 116 | correct = new N(4).add(1).add(3).add(5); 117 | t.deepEqual(tree, correct, 'Deleting Nodes 2.') 118 | 119 | tree = new N(87).insert(93).insert(61).insert(80).insert(8).insert(89).insert(22) 120 | .insert(91).insert(60).insert(33).delete(60); 121 | correct = new N(87).add(33).add(22).add(8).add(61).add(80).add(91).add(89).add(93); 122 | t.deepEqual(tree, correct , 'Delete with random numbers 3.'); 123 | 124 | tree = new N(87).insert(33).insert(22).insert(8).insert(61).insert(80).insert(91).insert(89).delete(33); 125 | correct = new N(80).add(22).add(8).add(61).add(89).add(87).add(91); 126 | t.deepEqual(tree, correct , 'Delete with random numbers 4.'); 127 | 128 | tree = new N(87).insert(93).insert(61).insert(80).insert(8).insert(89).insert(22) 129 | .insert(91).insert(60).insert(33).delete(60).delete(33); 130 | correct = new N(87).add(22).add(8).add(61).add(80).add(91).add(89).add(93); 131 | t.deepEqual(tree, correct , 'Delete with random numbers 5.'); 132 | 133 | tree = new N(1).insert(2).insert(3).insert(4).insert(5).insert(6).insert(7).insert(8) 134 | .delete(8).delete(7).delete(6).delete(5).delete(4).delete(3).delete(2).delete(1); 135 | t.deepEqual(tree, null , 'Completely delete 6.'); 136 | 137 | tree = new N(8).insert(7).insert(6).insert(5).insert(4).insert(3).insert(2).insert(1) 138 | .delete(8).delete(7).delete(6).delete(5).delete(4).delete(3).delete(2).delete(1); 139 | t.deepEqual(tree, null , 'Completely delete Same order 7.'); 140 | 141 | tree = new N(8).insert(7).insert(6).insert(5).insert(4).insert(3).insert(2).insert(1) 142 | .delete(1).delete(2).delete(3).delete(4).delete(5).delete(6).delete(7).delete(8); 143 | t.deepEqual(tree, null , 'Completely delete Inversed order 8.'); 144 | 145 | t.end(); 146 | }); -------------------------------------------------------------------------------- /06-EstructuraDeDatos-III/README.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "lesson", 3 | "lessonTitle": "Estructura de datos III", 4 | "feedbackID": "05-EstructuraDeDatos-III", 5 | "permalink": "/Estructura_de_datos_III/", 6 | "quizzID": "60745c49656c8d23c2e610b7", 7 | "homeworkUrl": "https://github.com/soyHenry/FT-M1/tree/master/06-EstructuraDeDatos-III/homework", 8 | "eleventyNavigation": { 9 | "key": "Datos III", 10 | "order": 6 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /06-EstructuraDeDatos-III/README.md: -------------------------------------------------------------------------------- 1 | ![HenryLogo](https://d31uz8lwfmyn8g.cloudfront.net/Assets/logo-henry-white-lg.png) 2 | 3 | 4 | 5 | 12 | 19 | 20 |
6 | 7 | 8 |
9 | Hacé click acá para dejar tu feedback sobre esta clase. 10 |
11 |
13 | 14 | 15 |
16 | Hacé click acá completar el quizz teórico de esta lecture. 17 |
18 |
21 | 22 | # Estructuras de Datos III 23 | 24 | ## Arboles (Trees) 25 | 26 | Los árboles son estructuras de datos que consiste en una serie de nodos conectados entre ellos y que se asemeja a un árbol (al revés). Cuando hablemos de árboles vamos a usar la siguiente terminología: 27 | 28 | * __Raíz__ - El nodo superior del árbol. 29 | * __Padre__ - Nodo con hijos. 30 | * __Hijo__ - Nodo descendiente de otro nodo. 31 | * __Hermanos__ - Nodos que comparten el mismo padre. 32 | * __Hojas__ - Nodos sin hijos. 33 | * __Nivel__ - El nivel de un nodo está definido por el número de conexiones entre el nodo y la raíz. 34 | * __Camino__ - Una secuencia de nodos por los que tenemos que pasar para llegar de un nodo a otro. 35 | 36 | Para que una estructura de nodos sea un árbol tiene que ser dirigido (o sea que se pueda ir de un nodo al hijo, pero no al revés, como en las listas enlazadas), no tiene que tener ciclos ( o sea que no exista un camino para llegar de un nodo al mismo nodo sin pasar dos veces por otro nodo.), tiene que ser conexo, es decir que no haya nodos 'sueltos', y además dos nodos cualesquiera tienen que estar conectados _sólo_ por un único camino. 37 | 38 | El siguiente no es un árbol porque tiene nodos no _conexos_: 39 | 40 | ![no-box](../_src/assets/04-EstructuraDeDatos-I/notatree2.png) 41 | 42 | Este otro no es un árbol porque tiene un ciclo: 43 | 44 | ![no-box](../_src/assets/04-EstructuraDeDatos-I/notatree1.png) 45 | 46 | Esta estructura es ampliamente usada, de hecho todos ustedes ya vienen trabajando hace mucho con una estructura de tipo árbol, ¿sabén de que les estoy hablando? 47 | 48 | ![Dom](../_src/assets/04-EstructuraDeDatos-I/dom_tree.gif) 49 | 50 | Sí, el DOM. La forma que usa el browser para mantener una representación del HTML en su cerebro es la de un árbol. 51 | 52 | ### Tipos de Arboles 53 | 54 | En realidad, la definición de árbol es muy general, por ejemplo, una lista enlazada ES un árbol, cuyo root es la cabeza y cada nodo tiene un sólo hijo; es un caso _particular_ de un árbol. Es más, un árbol es un caso particular de un _grafo_. 55 | También podemos definir al árbol de forma recursiva, ya que si lo pensamos, cada nodo ES un árbol, o sea que un árbol está formado por árboles; pero estos temas ya se vuelven muy filosóficos. 56 | Veamos algunos tipos de árboles que vamos a usar. 57 | 58 | ### Árbol binario 59 | 60 | Este es un árbol particular que tiene como característica que la cantidad de hijos que puede tener un nodo está restringida a dos (por eso se llama árbol binario). 61 | 62 | ![no-box](../_src/assets/04-EstructuraDeDatos-I/binaryTree.png) 63 | 64 | Un árbol de este estilo puede estar _balanceado_ o no: vamos a decir que un árbol es _balanceado_ cuando la cantidad de nodos que haya a la izquierda del root sea igual (o no difiera en más de una unidad) a la cantidad de nodos en la parte izquierda. 65 | 66 | ![BalancedUnBalanced](../_src/assets/04-EstructuraDeDatos-I/Balanced_vs_unbalanced_BST.png) 67 | 68 | Lo bueno de estos árboles, es que si se encuentra _balanceado_, necesitamos no más de _log n_ pasos para llegar a cualquier nodo! Esto los hace excelente estructuras de datos para guardar información que luego vamos a tener que buscar. 69 | 70 | Veamos una manera rápida de implementar un árbol binario en Javascript usando arreglos. Básicamente lo que vamos a hacer es ir guardando cada nodo con sus hijos en una posición particular. Empezamos poniendo el nodo root como primer elemento del arreglo. Luego vamos a poner su hijo izquierdo en la posición 1 y el derecho en la 2. El hijo izquierdo de 1 iria en la posición 3 y el derecho en la 4. Los hijos de 2 irian en 5 y 6, respectivamente. En esta imagen se va a entender mejor: 71 | 72 | ![BinaryArray](../_src/assets/04-EstructuraDeDatos-I/binaryArray.png) 73 | 74 | Ahora, si lo pensamos cada hijo de un nodo está en la posición ubicado en `i*2+1` y `i*2+2` siendo `i` el índice del arreglo. Por lo tanto podemos implementar este árbol usando lo siguiente: 75 | 76 | ```javascript 77 | izquierdo(i) = 2*i + 1 // el hijo izquierdo del nodo que está en i 78 | derecho(i) = 2*i + 2 // el hijo derecho del nodo que está en i 79 | ``` 80 | 81 | ### Arbol AVL 82 | 83 | Los árboles AVL (por sus inventores Georgy Adelson-Velsky y Evgenii Landis) es un árbol binario de búsqueda, pero que mantiene todo el tiempo al árbol _balanceado_. Básicamente lo que hace es, cada vez que se inserta o saca un nodo controla que todos los nodos estén balanceados. Y si no lo están reacomoda el árbol de tal forma que queden balanceados. 84 | 85 | ![avl](../_src/assets/04-EstructuraDeDatos-I/avl.gif) 86 | 87 | Lo malo de este árbol, es que las operaciones de insertar y sacar son muchos más caras que las de cualquier otra estructura. Pero nos da la posibilidad de estar __seguros__ que nunca vamos a tardar más de log n pasos en buscar un elemento. Según la naturaleza del problema que tengamos, nos va a convenir este método o no. 88 | 89 | ## Heap 90 | 91 | Un heap es un árbol binario, con las condiciónes que cada nodo tiene que contener un valor igual o mayor que los de sus hijos y que sea completo, es decir que todas las hojas estén en el último nivel del árbol (o uno menos) y además que esté completo desde la izquierda. 92 | 93 | ![no-box](../_src/assets/04-EstructuraDeDatos-I/heap.png) 94 | 95 | Cuando se construye un heap al agregar cada valor, tenemos que buscar la posición que les corresponde. O sea, que en cada paso vamos a tener que ir reacomodando el árbol para que siga siendo un _heap_. 96 | 97 | ## Otras estructuras de Datos 98 | 99 | Obviamente, existen muchas más estructuras de datos, estas son las más generales y las que todo ing. de software debe conocer. De todos modos, la mejor estructura de datos la vas a elegir según el problema que quieras resolver y después de investigar cuál es la que más te sirve. 100 | 101 | ## Tabla Resumen 102 | 103 | Felicitaciones! has terminado la saga de estructura de datos (I - La amenaza recursiva, II - El ataque de las listas, III - La venganza de los trees). 104 | 105 | Les dejo una tablita con ventajas y desventajas de las estructuras que hemos visto, para saber cuando utilizarlas y cuando no. 106 | 107 | | Estuctura | Ventajas | Desventajas | 108 | | -------------------- |:-------------:| ------------:| 109 | | Arreglo | Rápida inserción, acceso muy rápido si conocemos el index. | Búsqueda Lenta, borrado lento. | 110 | | Arreglo Ordenado | Mejor búsqueda que el arreglo normal | idem arreglo | 111 | | Pila | Asegura LIFO | Acceso lento a los demás items | 112 | | Cola | Asegura FIFO | Acceso lento a los demás items | 113 | | Lista Enlazada | Rápida inserción, rapido borrado | Búsqueda Lenta | 114 | | Árbol Binario | Muy rápido si está balanceado | Algoritmo de borrar es complejo, hay que balancear | 115 | | Árbol Red-black | Rápido y siempre está balanceado | Es Complejo | 116 | | Árbol 2-3-4 | Muy bueno para guardar datos | Es Complejo | 117 | | Hash | Muy rápido si conocemos el key. Insercion rapida | Borrado lento, buscado lento, consume mucha memoria | 118 | | Heap | Rápida inserción, borrado y acceso al item mas grande | Acceso lento a los demás items | 119 | 120 | ## Homework 121 | 122 | Completa la tarea descrita en el archivo [README](https://github.com/soyHenry/FT-M1/blob/master/06-EstructuraDeDatos-III/homework/README.md) 123 | -------------------------------------------------------------------------------- /06-EstructuraDeDatos-III/homework/README.md: -------------------------------------------------------------------------------- 1 | # ESTRUCTURA DE DATOS III | Homework 2 | 3 | ## 📒 Temas de la clase 4 | 5 | - Árboles binarios. 6 | - Árboles binarios de búsqueda. 7 | - Recorridos. 8 | 9 | --- 10 | 11 | ## 👀 Aprendizaje esperado 12 | 13 | Al finalizar este homework serás capaz de construir un árbol binario de búsqueda a partir de una clase o función constructora y modelar su comportamiento a través de sus métodos característicos. 14 | 15 | --- 16 | 17 | ## ⏱ Duración estimada 18 | 19 | > 90 minutos 20 | 21 | --- 22 | 23 | ## 📋 Instrucciones preliminares 24 | 25 | 1. Para ubicarte dentro de la carpeta homework escribe en tu terminal los siguientes comandos: 26 | - cd + [06-EstructuraDeDatos-III]. 27 | - cd + [homework]. 28 | 2. Luego, instalaremos las dependencias con el comando: 29 | 30 | ```javascript 31 | npm install 32 | ``` 33 | 34 | 3. Listo! Ya puedes correr los test con el comando: 35 | 36 | ```javascript 37 | npm test 38 | ``` 39 | 40 | --- 41 | 42 | ## 👩‍💻 **CONSIGNA** 43 | 44 | En este homework trabajarás de manera similar que en el homework anterior, solo que esta vez construiremos un árbol binario de búsqueda. Este árbol tendrá, por un lado, 3 métodos básicos: **size** (para saber la cantidad de nodos que incluye), **insert** (para agregar un nuevo nodo) y **contains** (para saber si un número ya está incluido en el árbol). Por otro lado crearemos 2 métodos vistos en clase para recorrer este árbol: **breadth first search** y **depth first search**. 45 | 46 | **⛔️ ¡STOP!** Como en las homeworks anteriores te desafiamos a que resuelvas este ejercicio con clases introducidas en ECMAscript 2015 y funciones constructoras. 47 | 48 | En este punto puedes comenzar a codear, verás instrucciones dentro del archivo _**homework.js**_. 49 | 50 | --- 51 | 52 | ## 🧠 Recuerda que... 53 | 54 | Los árboles binarios de búsqueda son estructuras de datos que tienen como objetivo la búsqueda eficiente de información. Los recorridos que se les aplican están pensados para que realicen la menor cantidad de pasos posibles. Esto permite encontrar información rápidamente. Esto es muy utilizado en matemáticas y sistemas de información. 55 | 56 | --- 57 | 58 | ## 🔎 Recursos adicionales 59 | 60 | - **[Recorridos de árboles](https://es.wikipedia.org/wiki/Recorrido_de_%C3%A1rboles)** 61 | 62 | --- 63 | 64 | ## 📢 Extra Credit 65 | 66 | Es tiempo de crear la función constructora / clase, y métodos de las siguientes estructuras: 67 | 68 | **Arbol binario** 69 | 70 | - Crea la clase / función constructora 71 | - Crea una función/método que balancee el arbol binario 72 | 73 | **Arbol AVL (God Mode)** 74 | 75 | - Crea la clase / función constructora 76 | - Crea los siguientes métodos para: 77 | - **add** Inserta un elemento 78 | - **delete** Borra un elemento 79 | - **search** Busca un elemento 80 | - **isBalanced**, devuelve true o false para saber si el árbol se encuentra balanceado. 81 | 82 |
83 | 84 | --- 85 | 86 | ## **✅ FEEDBACK** 87 | 88 | ### Usa este [**formulario**](https://docs.google.com/forms/d/e/1FAIpQLSe1MybH_Y-xcp1RP0jKPLndLdJYg8cwyHkSb9MwSrEjoxyzWg/viewform) para reportar tus observaciones de mejora o errores. Tu feedback es muy importante para seguir mejorando el modelo educativo. 89 | -------------------------------------------------------------------------------- /06-EstructuraDeDatos-III/homework/bst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/06-EstructuraDeDatos-III/homework/bst.png -------------------------------------------------------------------------------- /06-EstructuraDeDatos-III/homework/homework.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* 4 | Implementar la clase BinarySearchTree, definiendo los siguientes métodos recursivos: 5 | - size: retorna la cantidad total de nodos del árbol 6 | - insert: agrega un nodo en el lugar correspondiente 7 | - contains: retorna true o false luego de evaluar si cierto valor existe dentro del árbol 8 | - depthFirstForEach: recorre el árbol siguiendo el orden depth first (DFS) en cualquiera de sus variantes, 9 | según se indique por parámetro ("post-order", "pre-order", o "in-order"). Nota: si no se provee ningún parámetro, 10 | hará el recorrido "in-order" por defecto. 11 | - breadthFirstForEach: recorre el árbol siguiendo el orden breadth first (BFS) 12 | El ábrol utilizado para hacer los tests se encuentra representado en la imagen bst.png dentro del directorio homework. 13 | */ 14 | function BinarySearchTree(value) { 15 | this.value = value 16 | this.left = null 17 | this.right = null 18 | } 19 | 20 | BinarySearchTree.prototype.insert = function (value) { 21 | // Miraremos si tenemos root o raíz 22 | // Si el valor es mayor o menor al root 23 | // value > root => derecha 24 | // value < root => izquierda 25 | // si hay dere o izq => reevaluar (Recursión) 26 | 27 | if (value > this.value) { 28 | if (this.right !== null) { 29 | this.right.insert(value) 30 | } else { 31 | this.right = new BinarySearchTree(value) 32 | } 33 | } 34 | 35 | if (value < this.value) { 36 | if (this.left !== null) { 37 | this.left.insert(value) 38 | } else { 39 | this.left = new BinarySearchTree(value) 40 | } 41 | } 42 | } 43 | 44 | BinarySearchTree.prototype.contains = function (value) { 45 | // determinemos si el valor es nuestra root 46 | if (this.value === value) { 47 | return true 48 | } 49 | if (value > this.value) { 50 | if (this.right === null) { // Cuando no tengo hijos por derecha 51 | return false; 52 | } else { 53 | return this.right.contains(value) 54 | } 55 | } else { 56 | if (this.left === null) { // Cuando no tengo hijos por izquierda 57 | return false; 58 | } else { 59 | return this.left.contains(value) 60 | } 61 | } 62 | } 63 | 64 | BinarySearchTree.prototype.size = function () { 65 | // Plantearnos caso de corte. 66 | if (this.right === null && this.left === null) return 1 // Esta solo 67 | if (this.left !== null && this.right === null) return 1 + this.left.size() // Tiene left y va a la izquierda 68 | if (this.right !== null && this.left === null) return 1 + this.right.size() // Tiene Right y va a la derecha 69 | if (this.right !== null && this.left !== null) return 1 + this.left.size() + this.right.size() // tiene los 2. 70 | } 71 | BinarySearchTree.prototype.depthFirstForEach = function (cb, order) { 72 | if (order === 'pre-order') { 73 | // Pre-order => root, izq y der 74 | cb(this.value); 75 | if (this.left !== null) this.left.depthFirstForEach(cb, order) 76 | if (this.right !== null) this.right.depthFirstForEach(cb, order) 77 | } else if (order === 'post-order') { 78 | // Post-order => izq, der y root 79 | if (this.left !== null) this.left.depthFirstForEach(cb, order) 80 | if (this.right !== null) this.right.depthFirstForEach(cb, order) 81 | cb(this.value); 82 | } else { // Este seria mi caso de 'in-order' 83 | // in-order => izq, root y der 84 | if (this.left !== null) this.left.depthFirstForEach(cb, order) 85 | cb(this.value); 86 | if (this.right !== null) this.right.depthFirstForEach(cb, order) 87 | } 88 | 89 | } 90 | 91 | 92 | BinarySearchTree.prototype.breadthFirstForEach = function (cb, pendientes = []) { 93 | // primero izquierdas y luego derechas NIVEL x NIVEL 94 | // Guardamos nuestros valores en PENDIENTES y consumo en orden FIFO 95 | if (this.left !== null) { 96 | pendientes.push(this.left) 97 | } 98 | if (this.right !== null) { 99 | pendientes.push(this.right) 100 | } 101 | cb(this.value) 102 | 103 | if (pendientes.length > 0) { 104 | pendientes.shift().breadthFirstForEach(cb, pendientes) 105 | } 106 | } 107 | 108 | // No modifiquen nada debajo de esta linea 109 | // -------------------------------- 110 | 111 | module.exports = { 112 | BinarySearchTree, 113 | }; 114 | -------------------------------------------------------------------------------- /06-EstructuraDeDatos-III/homework/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "06-ds-3", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "jest --collectCoverage=false DataStructureIII.test.js", 7 | "grade": "jest --useStderr --json --outputFile=./tests/result.json" 8 | }, 9 | "devDependencies": { 10 | "jest": "^27.5.1" 11 | }, 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /06-EstructuraDeDatos-III/homework/tests/DataStructureIII.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | 'use strict' 3 | 4 | const { 5 | BinarySearchTree 6 | } = require('../homework'); 7 | 8 | describe('binarySearchTree', function() { 9 | var tree, 10 | testArr, 11 | valuesToInsert = [15, 25, 5, 17, 21, 28, 0, 14, 50, 1, 45, 13, 12, 11, 30, 35, 33, 31, 34]; 12 | 13 | beforeEach(function() { 14 | tree = new BinarySearchTree(20); 15 | testArr = []; 16 | }); 17 | 18 | it('tiene metodos llamados `insert`, `contains`, `depthFirstForEach`, y `size`', function() { 19 | expect(typeof tree.insert).toBe('function'); 20 | expect(typeof tree.contains).toBe('function'); 21 | expect(typeof tree.depthFirstForEach).toBe('function'); 22 | expect(typeof tree.breadthFirstForEach).toBe('function'); 23 | expect(typeof tree.size).toBe('function'); 24 | }); 25 | 26 | it('toma valores y reporta tamaño correctamente', function () { 27 | tree.insert(12); 28 | expect(tree.size()).toBe(2); 29 | }); 30 | 31 | it('hace nodos en la rama correcta', function () { 32 | tree.insert(12); 33 | tree.insert(22); 34 | expect(tree.size()).toBe(3); 35 | expect(tree.left.value).toBe(12); 36 | expect(tree.right.value).toBe(22); 37 | }); 38 | 39 | it('ordena valores cuando agrega', function() { 40 | expect(tree.value).toBe(20); 41 | tree.insert(15); 42 | expect(tree.left.value).toBe(15); 43 | tree.insert(25); 44 | expect(tree.right.value).toBe(25); 45 | tree.insert(5); 46 | expect(tree.left.left.value).toBe(5); 47 | tree.insert(17); 48 | tree.insert(21); 49 | tree.insert(28); 50 | tree.insert(0); 51 | tree.insert(14); 52 | tree.insert(50); 53 | tree.insert(1); 54 | tree.insert(45); 55 | tree.insert(13); 56 | tree.insert(12); 57 | tree.insert(11); 58 | expect(tree.left.left.right.left.left.left.value).toBe(11); 59 | tree.insert(30); 60 | tree.insert(35); 61 | tree.insert(33); 62 | tree.insert(31); 63 | tree.insert(34); 64 | expect(tree.right.right.right.left.left.right.left.right.value).toBe(34); 65 | }); 66 | 67 | it('`contains` devuelve true si el valor esta en el tree', function() { 68 | valuesToInsert.forEach(function(value){ 69 | tree.insert(value); 70 | }); 71 | valuesToInsert.forEach(function(value){ 72 | expect(tree.contains(value)).toBe(true); 73 | }); 74 | }); 75 | 76 | it('`contains` devuelve false si el valor no esta en el tree', function() { 77 | valuesToInsert.forEach(function(value){ 78 | tree.insert(value); 79 | }); 80 | [6, 23, 37, 51].forEach(function(value){ 81 | expect(tree.contains(value)).toBe(false); 82 | }); 83 | }); 84 | 85 | // ventaja obvia: valores son procesados respetando su orden lógico 86 | it('corre depth-first (en recorrido "in-order") cuando depthFirstForEach() es ejecutado sin ninguna opcion o con la opcion "in-order"', function() { 87 | valuesToInsert.forEach(function(value){ 88 | tree.insert(value); 89 | }); 90 | tree.depthFirstForEach(function(val){ testArr.push(val); }); 91 | expect(testArr).toEqual([ 0, 1, 5, 11, 12, 13, 14, 15, 17, 20, 21, 25, 28, 30, 31, 33, 34, 35, 45, 50 ]); 92 | testArr = []; 93 | tree.depthFirstForEach(function(val){ testArr.push(val); }, 'in-order'); 94 | expect(testArr).toEqual([ 0, 1, 5, 11, 12, 13, 14, 15, 17, 20, 21, 25, 28, 30, 31, 33, 34, 35, 45, 50 ]); 95 | }); 96 | 97 | // caso de uso: copiar el arbol (procesa primero la raiz) 98 | it('corre depth-first (en recorrido "pre-order") cuando depthFirstForEach() es ejecutado con la opcion "pre-order"', function() { 99 | valuesToInsert.forEach(function(value){ 100 | tree.insert(value); 101 | }); 102 | tree.depthFirstForEach(function(val){ testArr.push(val); }, 'pre-order'); 103 | expect(testArr).toEqual([20, 15, 5, 0, 1, 14, 13, 12, 11, 17, 25, 21, 28, 50, 45, 30, 35, 33, 31, 34]); 104 | }); 105 | 106 | // caso de uso: borrar un arbol, procesa primero las hojas 107 | it('corre depth-first (en recorrido "post-order" cuando depthFirstForEach() es ejecutado con la opcion "post-order"', function() { 108 | valuesToInsert.forEach(function(value){ 109 | tree.insert(value); 110 | }); 111 | tree.depthFirstForEach(function(val){ testArr.push(val); }, 'post-order'); 112 | expect(testArr).toEqual([ 1, 0, 11, 12, 13, 14, 5, 17, 15, 21, 31, 34, 33, 35, 30, 45, 50, 28, 25, 20 ]); 113 | }); 114 | 115 | // util cuando los niveles del arbol tienen significado (org chart? DOM elements?) 116 | it('corre breadth-first cuando breadthFirstForEach() es ejecutado', function() { 117 | valuesToInsert.forEach(function(value){ 118 | tree.insert(value); 119 | }); 120 | var depth = []; 121 | tree.breadthFirstForEach(function(val){ depth.push(val); }); 122 | expect(depth).toEqual([20, 15, 25, 5, 17, 21, 28, 0, 14, 50, 1, 13, 45, 12, 30, 11, 35, 33, 31, 34]); 123 | }); 124 | }); -------------------------------------------------------------------------------- /07-Algoritmos-I/README.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "lesson", 3 | "lessonTitle": "Algoritmos I", 4 | "feedbackID": "06-Algoritmos-I", 5 | "permalink": "/Algoritmos_I/", 6 | "quizzID" : "6053bc3f656c8d23c2e60e16", 7 | "homeworkUrl": "https://github.com/soyHenry/FT-M1/tree/master/07-Algoritmos-I/homework", 8 | "eleventyNavigation": { 9 | "key": "Algoritmos I", 10 | "order": 7 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /07-Algoritmos-I/homework/README.md: -------------------------------------------------------------------------------- 1 | # ALGORITMOS I | Homework 2 | 3 | ## 📒 Temas de la clase 4 | 5 | - Pseudocódigo. 6 | - Algoritmos. 7 | - Eficiencia. 8 | - Complejidad - Big O Notation. 9 | - Bubble Sort. 10 | - Insertion Sort. 11 | - Selection Sort. 12 | 13 | --- 14 | 15 | ## 👀 Aprendizaje esperado 16 | 17 | Al finalizar este homework estarás en la capacidad de: 18 | 19 | - Diseñar algoritmos como método lógico para la resolución de problemas. 20 | - Implementar algoritmos creados en pseudocódigo con Javascript para ejecutarlos y comprobar su eficiencia. 21 | 22 | --- 23 | 24 | ## ⏱ Duración estimada 25 | 26 | > 2 horas 27 | 28 | --- 29 | 30 | ## 📋 Instrucciones preliminares 31 | 32 | 1. Para ubicarte dentro de la carpeta homework escribe en tu terminal los siguientes comandos: 33 | - cd + [06-Algoritmos-I]. 34 | - cd + [homework]. 35 | 2. Luego, instalaremos las dependencias con el comando: 36 | 37 | ```javascript 38 | npm install 39 | ``` 40 | 41 | 3. Listo! Ya puedes correr los test con el comando: 42 | 43 | ```javascript 44 | npm test 45 | ``` 46 | 47 | --- 48 | 49 | ## 👩‍💻 **CONSIGNA** 50 | 51 | Tu tarea será definir 4 algoritmos. Cada uno deberá cumplir un objetivo específico, pero el procedimiento para construirlos es similar: 52 | 53 |
54 | 55 | ### 🟡 **Ejercicio 1** 56 | 57 | Comienza por entender el objetivo, los tipos de datos con los que estarás trabajando (inputs y outputs esperados), y las operaciones que se verán involucradas. 58 | 59 |
60 | 61 | ### 🟡 **Ejercicio 2** 62 | 63 | Define los pasos a seguir para alcanzar dicho objetivo. Recuerda contemplar casos límites (por ejemplo, ¿qué pasa si el input es 0?). 64 | 65 |
66 | 67 | ### 🟡 **Ejercicio 3** 68 | 69 | Una vez tengas una solución planteada en pseudocódigo, ¡puedes comenzar a trabajar en código Javascript! 70 | 71 |
72 | 73 | ### 🟡 **Ejercicio 4** 74 | 75 | Cuando hayas logrado una solución que cumpla el objetivo y pase los tests, observa: ¿Qué complejidad tiene tu algoritmo? ¿Podrías refactorizarlo para que sea más eficiente? 76 | 77 |
78 | 79 | En este punto puedes comenzar a codear, verás instrucciones dentro del archivo _**homework.js**_. 80 | 81 | --- 82 | 83 | ## 🧠 Recuerda que... 84 | 85 | - Un algoritmo es una secuencia ordenada de instrucciones para resolver un problema. 86 | - La calidad de un algoritmo no está definida exclusivamente por el cumplimiento del objetivo sino también por la eficiencia del procedimiento. 87 | 88 |
89 | 90 | --- 91 | 92 | ## **✅ FEEDBACK** 93 | 94 | ### Usa este [**formulario**](https://docs.google.com/forms/d/e/1FAIpQLSe1MybH_Y-xcp1RP0jKPLndLdJYg8cwyHkSb9MwSrEjoxyzWg/viewform) para reportar tus observaciones de mejora o errores. Tu feedback es muy importante para seguir mejorando el modelo educativo. 95 | -------------------------------------------------------------------------------- /07-Algoritmos-I/homework/homework.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // No cambies los nombres de las funciones. 3 | 4 | function factorear(num) { 5 | // Factorear el número recibido como parámetro y devolver en un array 6 | // los factores por los cuales se va dividiendo a dicho número (De menor a mayor) 7 | // Ej: factorear(180) --> [1, 2, 2, 3, 3, 5] Ya que 1x2x2x3x3x5 = 180 y son todos números primos 8 | // Tu código: 9 | let rta = [1] 10 | let aux = 2 11 | 12 | while (num !== 1) { 13 | if (num % aux === 0) { 14 | rta.push(aux) 15 | num = num / aux 16 | } else { 17 | aux++ 18 | } 19 | } 20 | return rta; 21 | } 22 | 23 | function bubbleSort(array) { 24 | // Implementar el método conocido como bubbleSort para ordenar de menor a mayor 25 | // el array recibido como parámetro 26 | // Devolver el array ordenado resultante 27 | // [0,1,2] 28 | // Tu código: 29 | let swap = true; 30 | while (swap) { 31 | swap = false; 32 | for (let i = 0; i < array.length - 1; i++) { 33 | if (array[i] > array[i + 1]) { 34 | let aux = array[i] 35 | array[i] = array[i + 1] 36 | array[i + 1] = aux 37 | swap = true; 38 | } 39 | } 40 | } 41 | return array; 42 | } 43 | 44 | 45 | function insertionSort(array) { 46 | // Implementar el método conocido como insertionSort para ordenar de menor a mayor 47 | // el array recibido como parámetro utilizando arreglos 48 | // Devolver el array ordenado resultante 49 | // Tu código: 50 | // [5,9,1,3,4] 51 | // i 52 | //j 53 | 54 | 55 | for (let i = 1; i < array.length; i++) { 56 | let j = i - 1 // 0 57 | let aux = array[i] // 5 58 | while (j >= 0 && array[j] > aux) { // 9 > 5 59 | array[j + 1] = array[j] // 60 | j-- 61 | } 62 | array[j + 1] = aux; 63 | } 64 | return array; 65 | } 66 | 67 | 68 | function selectionSort(array) { 69 | // Implementar el método conocido como selectionSort para ordenar de menor a mayor 70 | // el array recibido como parámetro utilizando dos arreglos 71 | // Devolver el array ordenado resultante 72 | // Tu código: 73 | // [5,9,1,3,4] 74 | // 75 | // 76 | 77 | for (let j = 0; j < array.length - 1; j++) { 78 | let min = j // índice 79 | for (let i = j + 1; i < array.length; i++) { 80 | if (array[i] < array[min]) { 81 | min = i; 82 | } 83 | } 84 | // Si sigo parado en el ultimo lugar no hago el cambio 85 | if (j !== min) { 86 | let aux = array[j] 87 | array[j] = array[min] 88 | array[min] = aux 89 | } 90 | } 91 | return array; 92 | } 93 | 94 | 95 | // No modificar nada debajo de esta línea 96 | // -------------------------------- 97 | 98 | module.exports = { 99 | factorear, 100 | bubbleSort, 101 | insertionSort, 102 | selectionSort, 103 | }; 104 | -------------------------------------------------------------------------------- /07-Algoritmos-I/homework/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "07-algoritmos-1", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "jest --collectCoverage=false AlgoritmosI.test.js", 7 | "grade": "jest --useStderr --json --outputFile=./tests/result.json" 8 | }, 9 | "devDependencies": { 10 | "jest": "^27.5.1" 11 | }, 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /07-Algoritmos-I/homework/tests/AlgoritmosI.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | 'use strict' 3 | const { 4 | factorear, 5 | bubbleSort, 6 | insertionSort, 7 | selectionSort, 8 | } = require('../homework'); 9 | 10 | describe('factorear(num)', function() { 11 | it('Debería devolver ...?', function() { 12 | expect(factorear(180)).toEqual([1,2,2,3,3,5]); 13 | expect(factorear(32)).toEqual([1,2,2,2,2,2]); 14 | expect(factorear(33)).toEqual([1,3,11]); 15 | expect(factorear(1)).toEqual([1]); 16 | }); 17 | }); 18 | 19 | describe('bubbleSort(array)', function() { 20 | it('Debe retornar el array ordenado de menor a mayor', function() { 21 | expect(bubbleSort([5, 1, 4, 2, 8])).toEqual([1, 2, 4, 5, 8]); 22 | expect(bubbleSort([10, 10, 16, 12])).toEqual([10, 10, 12, 16]); 23 | expect(bubbleSort([10, -2, -7, 4])).toEqual([-7, -2, 4, 10]); 24 | }); 25 | }); 26 | 27 | describe('insertionSort(array)', function() { 28 | it('Debe retornar el array ordenado de menor a mayor', function() { 29 | expect(insertionSort([5, 1, 4, 2, 8])).toEqual([1, 2, 4, 5, 8]); 30 | expect(insertionSort([10, 10, 16, 12])).toEqual([10, 10, 12, 16]); 31 | expect(insertionSort([10, -2, -7, 4])).toEqual([-7, -2, 4, 10]); 32 | }); 33 | }); 34 | 35 | 36 | describe('selectionSort(array)', function() { 37 | it('Debe retornar el array ordenado de menor a mayor', function() { 38 | expect(selectionSort([5, 1, 4, 2, 8])).toEqual([1, 2, 4, 5, 8]); 39 | expect(selectionSort([10, 10, 16, 12])).toEqual([10, 10, 12, 16]); 40 | expect(selectionSort([10, -2, -7, 4])).toEqual([-7, -2, 4, 10]); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /08-Algoritmos-II/README.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "lesson", 3 | "lessonTitle": "Algoritmos II", 4 | "feedbackID": "07-Algoritmos-II", 5 | "permalink": "/Algoritmos_II/", 6 | "quizzID": "607dd05356b4056ff0328371", 7 | "homeworkUrl": "https://github.com/soyHenry/FT-M1/tree/master/08-Algoritmos-II/homework", 8 | "eleventyNavigation": { 9 | "key": "Algoritmos II", 10 | "order": 8 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /08-Algoritmos-II/homework/README.md: -------------------------------------------------------------------------------- 1 | # ALGORITMOS II | Homework 2 | 3 | ## 📒 Temas de la clase 4 | 5 | - Quick sort. 6 | - Merge sort. 7 | 8 | --- 9 | 10 | ## 👀 Aprendizaje esperado 11 | 12 | Al finalizar la homework, serás capaz de: 13 | 14 | - Diferenciar el funcionamiento de los algoritmos de ordenamiento quick sort y merge sort. 15 | - Construir los algoritmos de ordenamiento (quick sort y merge) integrando una lógica recursiva. 16 | 17 | --- 18 | 19 | ## ⏱ Duración estimada 20 | 21 | > 2 horas 22 | 23 | --- 24 | 25 | ## 📋 Instrucciones preliminares 26 | 27 | 1. Para ubicarte dentro de la carpeta homework escribe en tu terminal los siguientes comandos: 28 | - cd + [07-Algoritmos-II]. 29 | - cd + [homework]. 30 | 2. Luego, instalaremos las dependencias con el comando: 31 | 32 | ```javascript 33 | npm install 34 | ``` 35 | 36 | 3. Listo! Ya puedes correr los test con el comando: 37 | 38 | ```javascript 39 | npm test 40 | ``` 41 | 42 | --- 43 | 44 | ## 👩‍💻 **CONSIGNA** 45 | 46 | Vamos a implementar 2 funciones: quickSort y mergeSort. Ambas recibirán un arreglo por parámetro. Deberás crear la lógica para generar el proceso de cada algoritmo, tal como se vio en la Lecture. El resultado de las dos funciones será el mismo arreglo recibido pero esta vez ordenado. 47 | 48 | En este punto puedes comenzar a codear, verás instrucciones dentro del archivo _**homework.js**_. 49 | 50 | --- 51 | 52 | ## 🧠 Recuerda que... 53 | 54 | - Muchas veces los algoritmos más eficientes pueden ser los más difíciles de diseñar. Por eso es importante dedicar tiempo en plantear correctamente el pseudocódigo. 55 | - Los algoritmos recursivos tienen menor complejidad temporal pero mayor complejidad espacial. 56 | 57 | --- 58 | 59 | ## 📢 Extra Credit 60 | 61 | **HeapSort** 62 | 63 | - Implementa el algoritmo en: Un árbol binario En un arreglo (recuerda cómo guardar árboles binarios en un arreglo) 64 | 65 | **BFS y DFS** 66 | 67 | - Implementar un algoritmo para recorrer un árbol de las dos formas. Usar el algoritmo implementado para poder buscar un elemento dentro del árbol. 68 | 69 |
70 | 71 | --- 72 | 73 | ## **✅ FEEDBACK** 74 | 75 | ### Usa este [**formulario**](https://docs.google.com/forms/d/e/1FAIpQLSe1MybH_Y-xcp1RP0jKPLndLdJYg8cwyHkSb9MwSrEjoxyzWg/viewform) para reportar tus observaciones de mejora o errores. Tu feedback es muy importante para seguir mejorando el modelo educativo. 76 | -------------------------------------------------------------------------------- /08-Algoritmos-II/homework/homework.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // No cambies los nombres de las funciones. 3 | 4 | function quickSort(array) { 5 | // Implementar el método conocido como quickSort para ordenar de menor a mayor 6 | // el array recibido como parámetro 7 | // Devolver el array ordenado resultante 8 | // Tu código: 9 | 10 | if (array.length <= 1) return array; 11 | 12 | // Debemos establecer un pivote, y este es aleatorio. 13 | // tendremos unos arrays: left, rigth y equals 14 | // Math.random => retorna un valor entre 0 y 0.9 15 | let pivot = array[Math.floor(Math.random() * array.length)] 16 | let left = [] 17 | let right = [] 18 | let equal = [] 19 | 20 | for (let i = 0; i < array.length; i++) { 21 | if (array[i] < pivot) { 22 | left.push(array[i]) 23 | } else if (array[i] > pivot) { 24 | right.push(array[i]) 25 | } else { 26 | equal.push(array[i]) 27 | } 28 | } 29 | 30 | return quickSort(left).concat(equal).concat(quickSort(right)) 31 | } 32 | 33 | function mergeSort(array) { 34 | // Implementar el método conocido como mergeSort para ordenar de menor a mayor 35 | // el array recibido como parámetro 36 | // Devolver el array ordenado resultante 37 | // Tu código: 38 | if (array.length <= 1) return array 39 | 40 | let div = split(array) 41 | let left = div[0] 42 | let right = div[1] 43 | 44 | //okey probemos ahora 45 | return combine(mergeSort(left), mergeSort(right)) 46 | } 47 | 48 | function combine(left, right) { 49 | let leftIndex = 0 50 | let rightIndex = 0 51 | let array = [] 52 | 53 | while (leftIndex < left.length && rightIndex < right.length) { 54 | if (left[leftIndex] < right[rightIndex]) { 55 | array.push(left[leftIndex]) 56 | leftIndex++ 57 | } else { 58 | array.push(right[rightIndex]) 59 | rightIndex++ 60 | } 61 | } 62 | 63 | return array.concat(left.slice(leftIndex)).concat(right.slice(rightIndex)) 64 | } 65 | 66 | function split(array) { 67 | let middle = Math.floor(array.length / 2) 68 | let left = array.slice(0, middle) 69 | let right = array.slice(middle) 70 | 71 | return [left, right] 72 | } 73 | 74 | // No modificar nada debajo de esta línea 75 | // -------------------------------- 76 | 77 | module.exports = { 78 | quickSort, 79 | mergeSort, 80 | }; 81 | -------------------------------------------------------------------------------- /08-Algoritmos-II/homework/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "08-algoritmos-2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "jest --collectCoverage=false AlgoritmosII.test.js", 7 | "grade": "jest --useStderr --json --outputFile=./tests/result.json" 8 | }, 9 | "devDependencies": { 10 | "jest": "^27.5.1" 11 | }, 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /08-Algoritmos-II/homework/tests/AlgoritmosII.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | 'use strict' 3 | 4 | const { 5 | quickSort, 6 | mergeSort, 7 | } = require('../homework'); 8 | 9 | describe('quickSort(array)', function() { 10 | it('Debe retornar el array ordenado de menor a mayor', function() { 11 | expect(quickSort([5, 1, 4, 2, 8])).toEqual([1, 2, 4, 5, 8]); 12 | expect(quickSort([10, 10, 16, 12])).toEqual([10, 10, 12, 16]); 13 | expect(quickSort([10, -2, -7, 4])).toEqual([-7, -2, 4, 10]); 14 | }); 15 | }); 16 | 17 | describe('mergeSort(array)', function() { 18 | it('Debe retornar el array ordenado de menor a mayor', function() { 19 | expect(mergeSort([5, 1, 4, 2, 8])).toEqual([1, 2, 4, 5, 8]); 20 | expect(mergeSort([10, 10, 16, 12])).toEqual([10, 10, 12, 16]); 21 | expect(mergeSort([10, -2, -7, 4])).toEqual([-7, -2, 4, 10]); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /EXTRA-Testing/README.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "lesson", 3 | "lessonTitle": "Software Testing", 4 | "feedbackID": "EXTRA-Testing", 5 | "permalink": "/Software_Testing/", 6 | "homeworkUrl": "https://github.com/soyHenry/FT-M1/tree/master/EXTRA-Testing/homework", 7 | "eleventyNavigation": { 8 | "key": "Testing", 9 | "order": 9 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /EXTRA-Testing/demo/matchers.test.js: -------------------------------------------------------------------------------- 1 | xdescribe('Tests that will pass', () => { 2 | it('should pass if exact match', () => { 3 | const number = 3; 4 | const string = 'Franco'; 5 | expect(number).toBe(3); 6 | expect(string).toBe('Franco'); 7 | }); 8 | it('should pass if recursively match (object)', () => { 9 | const obj = {name: 'Franco', age: 27}; 10 | expect(obj).toEqual({name: 'Franco', age: 27}); 11 | }); 12 | 13 | it('should pass if recursively match (array)', () => { 14 | const array = [1,2,3,4,5]; 15 | expect(array).toEqual([1,2,3,4,5]); 16 | }); 17 | }) 18 | 19 | xdescribe('Tests that will not pass', () => { 20 | it('should fail if not exact match (object)', () => { 21 | const obj = {name: 'Franco', age: 27}; 22 | expect(obj).toBe({name: 'Franco', age: 27}); 23 | }); 24 | 25 | it('should fail if not exact match (array)', () => { 26 | const array = [1,2,3,4,5]; 27 | expect(array).toBe([1,2,3,4,5]); 28 | }); 29 | }) 30 | 31 | xdescribe('Extra matchers', () => { 32 | 33 | it('toBeNull', () => { 34 | expect(null).toBeNull(); 35 | // expect(undefined).toBeNull(); 36 | }); 37 | 38 | it('toBeUndefined', () => { 39 | expect(undefined).toBeUndefined(); 40 | // expect(null).toBeUndefined(); 41 | }); 42 | 43 | it('toBeDefined', () => { 44 | expect(2).toBeDefined(); 45 | expect(0).toBeDefined(); 46 | expect('').toBeDefined(); 47 | expect('Franco').toBeDefined(); 48 | expect([]).toBeDefined(); 49 | expect([1,2,3]).toBeDefined(); 50 | expect({}).toBeDefined(); 51 | expect({a: 1}).toBeDefined(); 52 | expect(null).toBeDefined(); 53 | // expect(undefined).toBeDefined(); 54 | }); 55 | 56 | // toBeFalsy --> opposite 57 | it('toBeTruthy', () => { 58 | expect(true).toBeTruthy(); 59 | expect(2).toBeTruthy(); 60 | expect('Franco').toBeTruthy(); 61 | expect([]).toBeTruthy(); 62 | expect([1,2,3]).toBeTruthy(); 63 | expect({}).toBeTruthy(); 64 | expect({a: 1}).toBeTruthy(); 65 | // expect(0).toBeTruthy(); 66 | // expect('').toBeTruthy(); 67 | // expect(undefined).toBeTruthy(); 68 | // expect(null).toBeTruthy(); 69 | }); 70 | 71 | it('toBeCloseTo', () => { 72 | // expect(0.1 + 0.2).toEqual(0.3); 73 | expect(0.1 + 0.2).toBeCloseTo(0.3); 74 | // expect(0.11).toBeCloseTo(0.1); 75 | expect(0.11).toBeCloseTo(0.1, 1); 76 | expect(0.174927142).toBeCloseTo(0.17492, 4); 77 | }); 78 | 79 | it('toMatch', () => { 80 | expect('Un texto largo que tiene Franco dentro de sus palabras').toMatch('Franco'); 81 | expect('Un texto largo que tiene Franco dentro de sus palabras').toMatch(/Franco/); 82 | expect('Un texto largo que tiene Franco dentro de sus palabras').toMatch(/palabras$/); 83 | }); 84 | 85 | it('toContain', () => { 86 | const array = ['Franco', 'Toni', 'Martu', 'Mati']; 87 | expect(array).toContain('Martu'); 88 | expect(array).not.toContain('Diego'); 89 | 90 | expect('Soy Henry').toContain('Henry'); 91 | }); 92 | 93 | // also used as .toThrowError 94 | it('toThrow', () => { 95 | function error() { 96 | throw new TypeError('An error'); 97 | } 98 | 99 | // function definition, not executed! 100 | expect(error).toThrow(); 101 | expect(error).toThrow('An error'); 102 | // expect(error).toThrow('An errorrrrs'); 103 | expect(error).toThrow('error'); 104 | expect(error).toThrow(/error$/); 105 | expect(error).toThrow(TypeError); 106 | // expect(error).toThrow(SyntaxError); 107 | expect(error).toThrow(new TypeError('An error')); 108 | }); 109 | }); 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /EXTRA-Testing/demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testing-demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest --verbose --detectOpenHandles" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "jest": "^27.0.6" 13 | }, 14 | "dependencies": { 15 | "express": "^4.17.1", 16 | "supertest": "^6.1.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /EXTRA-Testing/demo/sum-describe.test.js: -------------------------------------------------------------------------------- 1 | const sum = require('./sum'); 2 | 3 | describe('Integer numbers', () => { 4 | it('should return 8 if adding 3 and 5', () => { 5 | expect(sum(3, 5)).toBe(8); 6 | }); 7 | 8 | it('should return 15 if adding 7 and 8', () => { 9 | expect(sum(7, 8)).toBe(15); 10 | }); 11 | }); 12 | 13 | describe('Decimal numbers', () => { 14 | it('should return 8.33 if adding 3.32 and 5.01', () => { 15 | expect(sum(3.32, 5.01)).toBe(8.33); 16 | }); 17 | 18 | it('should return 15.82 if adding 7.72 and 8.1', () => { 19 | expect(sum(7.72, 8.1)).toBe(15.82); 20 | }); 21 | }); 22 | 23 | describe.only('Invalid inputs', () => { 24 | it('should throw an TypeError if first parameter is not a number', () => { 25 | expect(() => sum('Franco', 5)).toThrow(TypeError); 26 | }); 27 | 28 | it('should throw an TypeError if second parameter is not a number', () => { 29 | expect(() => sum(3, true)).toThrow(TypeError); 30 | }); 31 | }); -------------------------------------------------------------------------------- /EXTRA-Testing/demo/sum.js: -------------------------------------------------------------------------------- 1 | function sum(a, b) { 2 | return a + b; 3 | } 4 | 5 | module.exports = sum; -------------------------------------------------------------------------------- /EXTRA-Testing/demo/sum.test.js: -------------------------------------------------------------------------------- 1 | const sum = require('./sum'); 2 | 3 | // it === test 4 | xit('should return 8 if adding 3 and 5', () => { 5 | // console.log(expect(sum(3,5))); 6 | expect(sum(3, 5)).toBe(8); 7 | }); 8 | 9 | xit('should return 15 if adding 7 and 8', () => { 10 | // console.log(expect(sum(3,5))); 11 | expect(sum(7, 8)).toBe(15); 12 | }); -------------------------------------------------------------------------------- /EXTRA-Testing/homework/homework.js: -------------------------------------------------------------------------------- 1 | const layout = [ 2 | [ 3 | { type: 'VIP', booked: false }, 4 | { type: 'VIP', booked: true }, 5 | { type: 'VIP', booked: true }, 6 | { type: 'VIP', booked: false }, 7 | ], 8 | [ 9 | { type: 'NORMAL', booked: false }, 10 | { type: 'VIP', booked: true }, 11 | { type: 'VIP', booked: false }, 12 | { type: 'NORMAL', booked: false }, 13 | ], 14 | [ 15 | { type: 'NORMAL', booked: false }, 16 | { type: 'NORMAL', booked: true }, 17 | { type: 'NORMAL', booked: true }, 18 | { type: 'NORMAL', booked: false }, 19 | ], 20 | [ 21 | { type: 'ECONOMIC', booked: true }, 22 | { type: 'NORMAL', booked: true }, 23 | { type: 'NORMAL', booked: true }, 24 | { type: 'ECONOMIC', booked: false }, 25 | ], 26 | [ 27 | { type: 'ECONOMIC', booked: false }, 28 | { type: 'ECONOMIC', booked: true }, 29 | { type: 'ECONOMIC', booked: false }, 30 | { type: 'ECONOMIC', booked: false }, 31 | ], 32 | ]; 33 | 34 | function checkSeatStatus(row, number) { 35 | if (typeof row !== 'string') { throw new TypeError('El primer parametro no es un string') } 36 | if (typeof number !== 'number') { throw new TypeError('El segundo parametro no es un número') } 37 | 38 | let rowNumber = getRowNumber(row) 39 | 40 | return layout[rowNumber][number].booked 41 | } 42 | 43 | function getRowNumber(letter) { 44 | return letter.charCodeAt(0) - 65; 45 | } 46 | 47 | function book(row, number) { 48 | if (checkSeatStatus(row, number)) { 49 | return `La silla ${row}${number} ya se encuentra reservada` 50 | } 51 | 52 | let rowNumber = getRowNumber(row) 53 | layout[rowNumber][number].booked = true; 54 | return `La silla ${row}${number} fue reservada con éxito` 55 | } 56 | 57 | module.exports = { checkSeatStatus, getRowNumber, book } -------------------------------------------------------------------------------- /EXTRA-Testing/homework/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "homework", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest --verbose" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "jest": "^27.5.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /EXTRA-Testing/homework/tests/index.test.js: -------------------------------------------------------------------------------- 1 | const { checkSeatStatus, getRowNumber, book } = require('../homework') 2 | 3 | describe('checkSeatStatus tests', () => { 4 | // TEST 1 5 | it('checkSeatStatus is a function', () => { 6 | expect(typeof checkSeatStatus).toBe('function') 7 | }) 8 | 9 | // TEST 2 10 | it('El primer parametro debe ser un string', () => { 11 | expect(() => checkSeatStatus(2)).toThrow(new TypeError('El primer parametro no es un string')) 12 | }) 13 | 14 | // TEST 3 15 | it('El primer parametro debe ser un string', () => { 16 | expect(() => checkSeatStatus('A', '2')).toThrow(new TypeError('El segundo parametro no es un número')) 17 | }) 18 | 19 | // TEST 5 20 | it('Deberia retornar true si la butaca esta reservada', () => { 21 | expect(checkSeatStatus('A', 1)).toBe(true) 22 | }) 23 | 24 | it('Deberia retornar false si la butaca no esta reservada', () => { 25 | expect(checkSeatStatus('E', 3)).toBe(false) 26 | }) 27 | }) 28 | 29 | describe('getRowNumber tests', () => { 30 | // TEST 4 31 | it('Deberia retornar 0 si le pasamos A', () => { 32 | expect(getRowNumber('A')).toBe(0) 33 | }) 34 | 35 | it('Deberia retornar 2 si le pasamos C', () => { 36 | expect(getRowNumber('C')).toBe(2) 37 | }) 38 | }) 39 | 40 | describe('book', () => { 41 | it(`Deberia retornar 'La silla XX fue reservada con éxito', si la silla no esta reservada`, () => { 42 | expect(book('E', 3)).toBe('La silla E3 fue reservada con éxito') 43 | }) 44 | it(`Deberia retornar 'La silla XX ya se encuentra reservada', si la silla esta reservada`, () => { 45 | expect(book('A', 1)).toBe('La silla A1 ya se encuentra reservada') 46 | }) 47 | }) 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /EjerciciosExtras/homework/DS.js: -------------------------------------------------------------------------------- 1 | function Queue() { 2 | this.array = []; 3 | } 4 | 5 | Queue.prototype.enqueue = function(elemento) { 6 | return this.array.push(elemento); 7 | } 8 | 9 | Queue.prototype.dequeue = function() { 10 | return this.array.shift(); 11 | } 12 | 13 | Queue.prototype.size = function() { 14 | return this.array.length; 15 | } 16 | 17 | function LinkedList() { 18 | this.head = null; 19 | } 20 | 21 | LinkedList.prototype.add = function(valor) { 22 | var nuevoNodo = new Node(valor); 23 | 24 | if(!this.head){ 25 | this.head = nuevoNodo; 26 | } else { 27 | var tailActual = this.head; 28 | while (tailActual.next !== null) { 29 | tailActual = tailActual.next; 30 | } 31 | tailActual.next = nuevoNodo; 32 | } 33 | } 34 | 35 | LinkedList.prototype.remove = function() { 36 | if(!this.head){ 37 | return undefined; 38 | } 39 | 40 | if(this.head.next === null){ 41 | var unicoNodo = this.head; 42 | this.head = null; 43 | return unicoNodo.value; 44 | } 45 | 46 | var nodoActual = this.head.next; 47 | var nodoPrevious = this.head; 48 | while (nodoActual.next !== null) { 49 | nodoPrevious = nodoActual; 50 | nodoActual = nodoActual.next; 51 | } 52 | nodoPrevious.next = null; 53 | return nodoActual.value; 54 | } 55 | 56 | LinkedList.prototype.search = function(arg) { 57 | var nodoActual = this.head; 58 | 59 | if(nodoActual === null){ 60 | return null; 61 | } 62 | 63 | while (nodoActual !== null) { 64 | if(typeof arg === "function"){ 65 | if(arg(nodoActual.value)){ 66 | return nodoActual.value; 67 | } 68 | } else if(nodoActual.value === arg){ 69 | return nodoActual.value; 70 | } 71 | nodoActual = nodoActual.next; 72 | } 73 | 74 | return null; 75 | } 76 | 77 | function Node(valor){ 78 | this.value = valor; 79 | this.next = null; 80 | } 81 | 82 | function BinarySearchTree(valor) { 83 | this.value = valor; 84 | this.left = null; 85 | this.right = null; 86 | } 87 | 88 | BinarySearchTree.prototype.insert = function(value) { 89 | 90 | if(value < this.value){ 91 | if(this.left === null){ 92 | var newTree = new BinarySearchTree(value); 93 | this.left = newTree; 94 | } else { 95 | this.left.insert(value); 96 | } 97 | } else { 98 | if(this.right === null){ 99 | var newTree = new BinarySearchTree(value); 100 | this.right = newTree; 101 | } else { 102 | this.right.insert(value); 103 | } 104 | } 105 | } 106 | 107 | BinarySearchTree.prototype.size = function() { 108 | if(this.value === null){ 109 | return 0; 110 | } 111 | 112 | if(this.left === null && this.right === null){ 113 | return 1; 114 | } 115 | 116 | if(this.left === null){ 117 | return 1 + this.right.size(); 118 | } 119 | 120 | if(this.right === null){ 121 | return 1 + this.left.size(); 122 | } 123 | 124 | return 1 + this.left.size() + this.right.size(); 125 | } 126 | 127 | 128 | module.exports = { 129 | Queue, 130 | Node, 131 | LinkedList, 132 | BinarySearchTree 133 | }; -------------------------------------------------------------------------------- /EjerciciosExtras/homework/Repaso-M1.js: -------------------------------------------------------------------------------- 1 | const { 2 | Queue, 3 | Node, 4 | LinkedList, 5 | BinarySearchTree 6 | } = require('./DS.js') 7 | 8 | // Implementar la función countArray: a partir de un array en el cual cada posición puede ser un único 9 | // número u otro array anidado de números, determinar la suma de todos los números contenidos en el array. 10 | // El array será recibido por parámetro. 11 | // Ejemplo: 12 | // const array = [1, [2, [3,4]], [5,6], 7]; 13 | // countArray(array); --> Debería devolver 28 (1 + 2 + 3 + 4 + 5 + 6 + 7) 14 | // Pista: utilizar el método Array.isArray() para determinar si algun elemento de array es un array anidado 15 | // [Para más información del método: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/isArray] 16 | 17 | var countArray = function(array) { 18 | // Tu código aca: 19 | 20 | } 21 | 22 | 23 | // Implementar la función countProps: a partir de un objeto en el cual cada propiedad puede contener 24 | // cualquier tipo de dato, determinar la cantidad de propiedades de objetos en cualquier nivel, ya sea el inicial 25 | // u objetos anidados 26 | // Ejemplo: 27 | // var obj = { 28 | // a: { 29 | // a1: 10, 30 | // a2: 'Franco', 31 | // a3: {f: 'r', a: 'n', c: {o: true}} 32 | // }, 33 | // b: 2, 34 | // c: [1, {a: 1}, 'Franco'] 35 | // } 36 | // countProps(obj)--> Deberia devolver 10 ya que el objeto inicial tiene 3 propiedades, pero a su vez 37 | // dentro de a tenemos 3 propiedades mas, luego a3 tiene otras 3 y por ultimo c tiene una extra. 38 | // Propiedades: a, a1, a2, a3, f, a, c, o, b, c --> 10 en total 39 | 40 | var countProps = function(obj) { 41 | // Tu código aca: 42 | 43 | } 44 | 45 | 46 | // Implementar el método changeNotNumbers dentro del prototype de LinkedList que deberá cambiar 47 | // aquellos valores que no puedan castearse a numeros por 'Kiricocho' y devolver la cantidad de cambios que hizo 48 | // Aclaracion: si el valor del nodo puede castearse a número NO hay que reemplazarlo 49 | // Ejemplo 1: 50 | // Suponiendo que la lista actual es: Head --> [1] --> ['2'] --> [false] --> ['Franco'] 51 | // lista.changeNotNumbers(); 52 | // Ahora la lista quedaría: Head --> [1] --> ['2'] --> [false] --> ['Kirikocho] y la función debería haber devuelto el valor 1 53 | 54 | LinkedList.prototype.changeNotNumbers = function(){ 55 | // Tu código aca: 56 | 57 | } 58 | 59 | 60 | // Implementar la función mergeQueues que a partir de dos queues recibidas por parametro 61 | // debe devolver una nueva Queue que vaya mergeando los nodos de las anteriores. 62 | // Ejemplo: 63 | // - queueOne: [7,3,5] 64 | // - queueTwo: [2,4,6] 65 | // mergeQueues(queueOne, queueTwo) --> [7,2,3,4,5,6] 66 | // IMPORTANTE: NO son arreglos sino que son Queues. 67 | 68 | var mergeQueues = function(queueOne, queueTwo) { 69 | // Tu código aca: 70 | 71 | } 72 | 73 | 74 | // Implementar la funcion closureMult que permita generar nuevas funciones que representen 75 | // las tablas de multiplicación de distintos numeros 76 | // Ejemplo: 77 | // - var multByFour = closureMult(4); 78 | // - multByFour(2) --> 8 (2 * 4) 79 | // - multByFour(5) --> 20 80 | // - var multBySix = closureMult(6); 81 | // - multBySix(4) --> 24 82 | 83 | var closureMult = function(multiplier) { 84 | // Tu código aca: 85 | 86 | } 87 | 88 | // Implementar el método sum dentro del prototype de BinarySearchTree 89 | // que debe retornar la suma total de los valores dentro de cada nodo del arbol 90 | BinarySearchTree.prototype.sum = function() { 91 | // Tu código aca: 92 | 93 | } 94 | 95 | module.exports = { 96 | countArray, 97 | countProps, 98 | mergeQueues, 99 | closureMult 100 | } -------------------------------------------------------------------------------- /EjerciciosExtras/homework/Test/repaso-M1.test.js: -------------------------------------------------------------------------------- 1 | const { 2 | countArray, 3 | countProps, 4 | mergeQueues, 5 | closureMult 6 | } = require('../Repaso-M1.js') 7 | 8 | const { 9 | LinkedList, 10 | Queue, 11 | BinarySearchTree 12 | } = require('../DS.js') 13 | 14 | describe('countArray', () => { 15 | it("debe determinar la suma de todos los números contenidos en el array.", () => { 16 | expect(countArray([1,1,1,1,1,1,1,1,1,1])).toBe(10) 17 | }) 18 | it("debe determinar la suma de todos los números incluso si existen arrays anidados.", () => { 19 | expect(countArray([1, [2, [3,4]], [5,6], 7])).toBe(28) 20 | }) 21 | it("debe determinar la suma de todos los números incluso si existen mas arrays anidados.", () => { 22 | expect(countArray([1, [2, [3,[4,4,4]]], [5,6], 7])).toBe(36) 23 | }) 24 | }) 25 | 26 | describe('countProps', () => { 27 | it('debe determinar la cantidad correcta de propiedades de un objeto', () => { 28 | const objeto = { 29 | a: 1, 30 | b: 2, 31 | c: 3, 32 | d: 4 33 | } 34 | expect(countProps(objeto)).toBe(4) 35 | }) 36 | 37 | it('debe determinar la cantidad correcta de propiedades de un objeto, incluso con objetos aninados dentro del primero', () => { 38 | const objeto = { 39 | a: { 40 | a1: 10, 41 | a2: 'Franco', 42 | a3: {f: 'r', a: 'n', c: {o: true}} 43 | }, 44 | b: 2, 45 | c: [1, {a: 1}, 'Franco'] 46 | } 47 | expect(countProps(objeto)).toBe(10) 48 | }) 49 | }) 50 | 51 | describe('changeNotNumbers', () =>{ 52 | it('deberá cambiar aquellos valores que no puedan castearse(convertirse) a numeros por `Kiricocho` y devolver la cantidad de cambios que hizo', () => { 53 | let listOne = new LinkedList(); 54 | listOne.add(1); 55 | listOne.add('2'); 56 | listOne.add(false); 57 | listOne.add('Franco'); 58 | 59 | expect(listOne.changeNotNumbers()).toBe(1) 60 | expect(listOne.search(1)).toBe(1) 61 | expect(listOne.search('2')).toBe('2') 62 | expect(listOne.search(false)).toBe(false) 63 | expect(listOne.search('Franco')).toBe(null) 64 | expect(listOne.search('Kiricocho')).toBe('Kiricocho') 65 | 66 | }) 67 | 68 | it('deberá cambiar aquellos valores que no puedan castearse(convertirse) a numeros por `Kiricocho` y devolver la cantidad de cambios que hizo, en una nueva lista!', () => { 69 | let listTwo = new LinkedList(); 70 | listTwo.add('uno'); 71 | listTwo.add('2'); 72 | listTwo.add(3); 73 | listTwo.add('cuatro'); 74 | listTwo.add('cinco'); 75 | 76 | expect(listTwo.changeNotNumbers()).toBe(3) 77 | expect(listTwo.search('uno')).toBe(null) 78 | expect(listTwo.search('2')).toBe('2') 79 | expect(listTwo.search(3)).toBe(3) 80 | expect(listTwo.search('cuatro')).toBe(null) 81 | expect(listTwo.search('cinco')).toBe(null) 82 | expect(listTwo.search('Kiricocho')).toBe('Kiricocho') 83 | }) 84 | }) 85 | 86 | describe('mergeQueues', () => { 87 | it('a partir de dos queues recibidas por parametro debe devolver una nueva Queue que vaya mergeando los nodos de las anteriores.', () => { 88 | var queueOne = new Queue(); 89 | queueOne.enqueue(1); 90 | queueOne.enqueue(3); 91 | queueOne.enqueue(5); 92 | queueOne.enqueue(7); 93 | queueOne.enqueue(9); 94 | var queueTwo = new Queue(); 95 | queueTwo.enqueue(2); 96 | queueTwo.enqueue(4); 97 | queueTwo.enqueue(6); 98 | 99 | let newQ = mergeQueues(queueOne, queueTwo) 100 | expect(typeof mergeQueues(queueOne, queueTwo)).toBe('object'); 101 | expect(typeof newQ).toBe('object'); 102 | expect(newQ.size()).toBe(8); 103 | expect(newQ.dequeue()).toBe(1); 104 | expect(newQ.dequeue()).toBe(2); 105 | expect(newQ.dequeue()).toBe(3); 106 | expect(newQ.dequeue()).toBe(4); 107 | expect(newQ.dequeue()).toBe(5); 108 | expect(newQ.dequeue()).toBe(6); 109 | expect(newQ.dequeue()).toBe(7); 110 | expect(newQ.dequeue()).toBe(9); 111 | 112 | }) 113 | 114 | it('a partir de dos nuevas queues recibidas por parametro debe devolver una nueva Queue que vaya mergeando los nodos de las anteriores.', () => { 115 | var queueTree = new Queue(); 116 | queueTree.enqueue(7); 117 | queueTree.enqueue(3); 118 | queueTree.enqueue(5); 119 | var queueFour = new Queue(); 120 | queueFour.enqueue(2); 121 | queueFour.enqueue(4); 122 | queueFour.enqueue(6); 123 | 124 | let newQ = mergeQueues(queueTree, queueFour) 125 | expect(typeof mergeQueues(queueTree, queueFour)).toBe('object'); 126 | expect(typeof newQ).toBe('object'); 127 | expect(newQ.size()).toBe(6); 128 | expect(newQ.dequeue()).toBe(7); 129 | expect(newQ.dequeue()).toBe(2); 130 | expect(newQ.dequeue()).toBe(3); 131 | expect(newQ.dequeue()).toBe(4); 132 | expect(newQ.dequeue()).toBe(5); 133 | expect(newQ.dequeue()).toBe(6); 134 | }) 135 | }) 136 | 137 | describe('closureMult', () => { 138 | it('debe generar nuevas funciones que representen las tablas de multiplicacion de dinstintos numeros, como la tabla del 4.', () => { 139 | let multByFour = closureMult(4); 140 | expect(multByFour(2)).toBe(8); 141 | expect(multByFour(5)).toBe(20); 142 | expect(multByFour(6)).toBe(24); 143 | expect(multByFour(10)).toBe(40); 144 | }) 145 | 146 | it('debe generar nuevas funciones que representen las tablas de multiplicacion de dinstintos numeros, como la tabla del 9.', () => { 147 | let multByFour = closureMult(9); 148 | expect(multByFour(2)).toBe(18); 149 | expect(multByFour(5)).toBe(45); 150 | expect(multByFour(6)).toBe(54); 151 | expect(multByFour(10)).toBe(90); 152 | }) 153 | }) 154 | 155 | describe('Sum', () => { 156 | it('el método sum dentro del prototype de BinarySearchTree que debe retornar la suma total de los valores dentro de cada nodo del arbol', () => { 157 | var bst = new BinarySearchTree(15); 158 | bst.insert(10); 159 | bst.insert(17); 160 | bst.insert(5); 161 | bst.insert(7); 162 | bst.insert(3); 163 | bst.insert(25); 164 | expect(bst.sum()).toBe(82) 165 | }) 166 | 167 | it('el método sum dentro del prototype de BinarySearchTree que debe retornar la suma total de los valores dentro de cada nodo del arbol, para un nuevo Arbol', () => { 168 | var bst = new BinarySearchTree(10); 169 | bst.insert(10); 170 | bst.insert(10); 171 | bst.insert(10); 172 | bst.insert(10); 173 | bst.insert(10); 174 | expect(bst.sum()).toBe(60) 175 | }) 176 | }) 177 | -------------------------------------------------------------------------------- /EjerciciosExtras/homework/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "homework", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest repaso-M1.test.js" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "jest": "^27.5.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /README.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "intro", 3 | "permalink": "/index.html", 4 | "eleventyNavigation": { 5 | "key": "Intro", 6 | "order": 0 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![HenryLogo](https://d31uz8lwfmyn8g.cloudfront.net/Assets/logo-henry-white-lg.png) 2 | 3 | --- 4 | 5 | ### Podes ver el contenido de todo el repositorio en formato web tipeando `npm install` y `npm start` e ingresando luego a 6 | 7 | --- 8 | 9 | # Módulo 1 10 | 11 | #### Fundamentos de JavaScript 12 | 13 |
14 | 15 | - [Intro to Computer Science](./01-IntroToCS) 16 | - [Javascript Avanzado I](./02-JavaScriptAvanzado-I) 17 | - [Javascript Avanzado II](./03-JavaScriptAvanzado-II) 18 | - [Estructura de Datos I](./04-EstructuraDeDatos-I) 19 | - [Estructura de Datos II](./05-EstructuraDeDatos-II) 20 | - [Estructura de Datos III](./06-EstructuraDeDatos-III) 21 | - [Algoritmos I](./07-Algoritmos-I) 22 | - [Algoritmos II](./08-Algoritmos-II) 23 | 24 |
25 | 26 | ## Proceso de subida de homeworks 27 | 28 | **IMPORTANTE:** Luego de completar cada una de las homeworks del día deberán ejecutar los siguientes comandos para subir sus trabajos a sus repositorios (Deben estar posicionados sobre la carpeta del repositorio): 29 | 30 | ```bash 31 | git add . 32 | git commit -m "el mensaje que ustedes quieran" 33 | git push 34 | ``` 35 | 36 | ### Extra 37 | 38 | - [Patrones de JavaScript](https://addyosmani.com/resources/essentialjsdesignpatterns/book/) 39 | - [Manejo de errores](./02-JavaScriptAvanzado-I/errores.md) 40 | - [JS orientado a Objetos](./02-JavaScriptAvanzado-I/OOP.md) 41 | 42 | ### Links copados 43 | 44 | > [En esta página Dmitry Soshnikov](http://dmitrysoshnikov.com/ecmascript/javascript-the-core/#this-value) explica muy a fondo varios conceptos del lenguaje, casi a nivel de la especificación técnica. 45 | 46 | - **Streams y pipes**: [substack](https://github.com/substack/stream-handbook) 47 | - [**Event loop**](https://www.youtube.com/watch?v=8aGhZQkoFbQ) 48 | - [**Inheritance Patterns**](http://davidshariff.com/blog/javascript-inheritance-patterns/#first-article) 49 | 50 |
51 | 52 | --- 53 | 54 | ## **✅ FEEDBACK** 55 | 56 | ### Usa este [**formulario**](https://docs.google.com/forms/d/e/1FAIpQLSe1MybH_Y-xcp1RP0jKPLndLdJYg8cwyHkSb9MwSrEjoxyzWg/viewform) para reportar tus observaciones de mejora o errores. Tu feedback es muy importante para seguir mejorando el modelo educativo. 57 | -------------------------------------------------------------------------------- /_src/assets/01-IntroToCS/AND.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/01-IntroToCS/AND.png -------------------------------------------------------------------------------- /_src/assets/01-IntroToCS/OR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/01-IntroToCS/OR.png -------------------------------------------------------------------------------- /_src/assets/01-IntroToCS/ascii.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/01-IntroToCS/ascii.png -------------------------------------------------------------------------------- /_src/assets/01-IntroToCS/assembly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/01-IntroToCS/assembly.png -------------------------------------------------------------------------------- /_src/assets/01-IntroToCS/binario.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/01-IntroToCS/binario.png -------------------------------------------------------------------------------- /_src/assets/01-IntroToCS/compilation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/01-IntroToCS/compilation.png -------------------------------------------------------------------------------- /_src/assets/01-IntroToCS/ie747.png: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /_src/assets/01-IntroToCS/negativo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/01-IntroToCS/negativo.png -------------------------------------------------------------------------------- /_src/assets/01-IntroToCS/utf8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/01-IntroToCS/utf8.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/Closure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/Closure.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/closure2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/closure2.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/context.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/context.jpg -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/executionContext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/executionContext.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/executionStack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/executionStack.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/fasecreacion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/fasecreacion.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/function.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/functionFactory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/functionFactory.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/globalObject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/globalObject.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/mthread.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/mthread.gif -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/notaciones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/notaciones.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/protoypeInheritance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/protoypeInheritance.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/protoypeInheritance2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/protoypeInheritance2.png -------------------------------------------------------------------------------- /_src/assets/02-JavaScriptAvanzado-I/protoypeInheritance3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/02-JavaScriptAvanzado-I/protoypeInheritance3.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/Balanced_vs_unbalanced_BST.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/Balanced_vs_unbalanced_BST.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/array.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/array.jpg -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/avl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/avl.gif -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/binaryArray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/binaryArray.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/binaryTree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/binaryTree.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/cola.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/cola.jpg -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/dom_tree.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/dom_tree.gif -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/doueblelist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/doueblelist.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/hashfunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/hashfunction.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/heap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/heap.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/listAdd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/listAdd.gif -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/listaRemove.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/listaRemove.gif -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/listaRemove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/listaRemove.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/notatree1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/notatree1.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/notatree2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/notatree2.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/singlelist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/singlelist.png -------------------------------------------------------------------------------- /_src/assets/04-EstructuraDeDatos-I/stack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/04-EstructuraDeDatos-I/stack.jpg -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/Sorting_quicksort_anim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/Sorting_quicksort_anim.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/asintotica.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/asintotica.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/ayudin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/ayudin.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/ayudin2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/ayudin2.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/ayudin3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/ayudin3.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/bigo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/bigo.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/binarySearch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/binarySearch.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/bubblesort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/bubblesort.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/cat.jpg -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/chemestrydog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/chemestrydog.jpg -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/countsort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/countsort.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/countsort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/countsort.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/hanoi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/hanoi.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/heapSort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/heapSort.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/insertion.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/insertion.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/insertionbest.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/insertionbest.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/mergesort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/mergesort.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/mergesortTime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/mergesortTime.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/nnn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/nnn.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/quicksortBest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/quicksortBest.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/quicksortWorst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/quicksortWorst.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/radixsort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/radixsort.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/recursion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/recursion.jpg -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/recursionof.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/recursionof.jpg -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/selection.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/selection.gif -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/tablasegundo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/tablasegundo.png -------------------------------------------------------------------------------- /_src/assets/07-Algoritmos-I/tablatiempo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/07-Algoritmos-I/tablatiempo.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/TDD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/TDD.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/always-true.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/always-true.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/checkSeatStatus-1-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/checkSeatStatus-1-error.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/checkSeatStatus-1-pass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/checkSeatStatus-1-pass.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/demo-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/demo-test.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/describe-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/describe-demo.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/describe-only.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/describe-only.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/describe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/describe.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/fine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/fine.jpg -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/i-can.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/i-can.jpg -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/it-only.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/it-only.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/never-ends.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/never-ends.jpg -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/piramide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/piramide.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/skip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/skip.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/something-wrong.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/something-wrong.jpg -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/stop.png -------------------------------------------------------------------------------- /_src/assets/EXTRA-Testing/testOverhead.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Broflotsky/M1-PT-15A/e7da6dd36bdde3f2f10adb78f07dd442bfd825e6/_src/assets/EXTRA-Testing/testOverhead.jpg -------------------------------------------------------------------------------- /_src/data/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "repoTitle": "Módulo 1 - JavaScript", 3 | "airtableFormId": "shr5KEX8NFdrG14j9" 4 | } 5 | -------------------------------------------------------------------------------- /_src/data/layout.js: -------------------------------------------------------------------------------- 1 | module.exports = 'lesson.njk' -------------------------------------------------------------------------------- /_src/data/styles/code.js: -------------------------------------------------------------------------------- 1 | const Cache = require('@11ty/eleventy-cache-assets') 2 | 3 | module.exports = async function () { 4 | const url = 'https://d31uz8lwfmyn8g.cloudfront.net/Styles/code.css' 5 | const style = await Cache(url, { 6 | duration: '1d', 7 | type: 'txt', 8 | directory: '_cache' 9 | }) 10 | return style 11 | } 12 | -------------------------------------------------------------------------------- /_src/data/styles/fonts.js: -------------------------------------------------------------------------------- 1 | const Cache = require('@11ty/eleventy-cache-assets') 2 | 3 | module.exports = async function () { 4 | const url = 'https://d31uz8lwfmyn8g.cloudfront.net/Styles/fonts.css' 5 | const style = await Cache(url, { 6 | duration: '1d', 7 | type: 'txt', 8 | directory: '_cache' 9 | }) 10 | return style 11 | } 12 | -------------------------------------------------------------------------------- /_src/data/styles/footer.js: -------------------------------------------------------------------------------- 1 | const Cache = require('@11ty/eleventy-cache-assets') 2 | 3 | module.exports = async function () { 4 | const url = 'https://d31uz8lwfmyn8g.cloudfront.net/Styles/footer.css' 5 | const style = await Cache(url, { 6 | duration: '1d', 7 | type: 'txt', 8 | directory: '_cache' 9 | }) 10 | return style 11 | } 12 | -------------------------------------------------------------------------------- /_src/data/styles/header.js: -------------------------------------------------------------------------------- 1 | const Cache = require('@11ty/eleventy-cache-assets') 2 | 3 | module.exports = async function () { 4 | const url = 'https://d31uz8lwfmyn8g.cloudfront.net/Styles/header.css' 5 | const style = await Cache(url, { 6 | duration: '1d', 7 | type: 'txt', 8 | directory: '_cache' 9 | }) 10 | return style 11 | } 12 | -------------------------------------------------------------------------------- /_src/data/styles/lesson.js: -------------------------------------------------------------------------------- 1 | const Cache = require('@11ty/eleventy-cache-assets') 2 | 3 | module.exports = async function () { 4 | const url = 'https://d31uz8lwfmyn8g.cloudfront.net/Styles/lesson.css' 5 | const style = await Cache(url, { 6 | duration: '1d', 7 | type: 'txt', 8 | directory: '_cache' 9 | }) 10 | return style 11 | } 12 | -------------------------------------------------------------------------------- /_src/data/styles/lessonIntro.js: -------------------------------------------------------------------------------- 1 | const Cache = require('@11ty/eleventy-cache-assets') 2 | 3 | module.exports = async function () { 4 | const url = 'https://d31uz8lwfmyn8g.cloudfront.net/Styles/lessonIntro.css' 5 | const style = await Cache(url, { 6 | duration: '1d', 7 | type: 'txt', 8 | directory: '_cache' 9 | }) 10 | return style 11 | } 12 | -------------------------------------------------------------------------------- /_src/data/styles/main.js: -------------------------------------------------------------------------------- 1 | const Cache = require('@11ty/eleventy-cache-assets') 2 | 3 | module.exports = async function () { 4 | const url = 'https://d31uz8lwfmyn8g.cloudfront.net/Styles/main.css' 5 | const style = await Cache(url, { 6 | duration: '1d', 7 | type: 'txt', 8 | directory: '_cache' 9 | }) 10 | return style 11 | } 12 | -------------------------------------------------------------------------------- /_src/data/styles/responsive.js: -------------------------------------------------------------------------------- 1 | const Cache = require('@11ty/eleventy-cache-assets') 2 | 3 | module.exports = async function () { 4 | const url = 'https://d31uz8lwfmyn8g.cloudfront.net/Styles/responsive.css' 5 | const style = await Cache(url, { 6 | duration: '1d', 7 | type: 'txt', 8 | directory: '_cache' 9 | }) 10 | return style 11 | } 12 | -------------------------------------------------------------------------------- /_src/data/styles/sidebar.js: -------------------------------------------------------------------------------- 1 | const Cache = require('@11ty/eleventy-cache-assets') 2 | 3 | module.exports = async function () { 4 | const url = 'https://d31uz8lwfmyn8g.cloudfront.net/Styles/sidebar.css' 5 | const style = await Cache(url, { 6 | duration: '1d', 7 | type: 'txt', 8 | directory: '_cache' 9 | }) 10 | return style 11 | } 12 | -------------------------------------------------------------------------------- /_src/data/styles/topbar.js: -------------------------------------------------------------------------------- 1 | const Cache = require('@11ty/eleventy-cache-assets') 2 | 3 | module.exports = async function () { 4 | const url = 'https://d31uz8lwfmyn8g.cloudfront.net/Styles/topbar.css' 5 | const style = await Cache(url, { 6 | duration: '1d', 7 | type: 'txt', 8 | directory: '_cache' 9 | }) 10 | return style 11 | } 12 | -------------------------------------------------------------------------------- /_src/layouts/intro.njk: -------------------------------------------------------------------------------- 1 | --- 2 | logoNav: 'https://d31uz8lwfmyn8g.cloudfront.net/Assets/logo-henry-white-sm.png' 3 | favicon: 'https://d31uz8lwfmyn8g.cloudfront.net/Assets/favicon.png' 4 | --- 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {# #} 16 | {{ config.repoTitle }} 17 | 18 | {% set css %} 19 | {{ styles.fonts | safe }} 20 | {{ styles.header | safe }} 21 | {{ styles.main | safe }} 22 | {{ styles.topbar | safe }} 23 | {{ styles.sidebar | safe }} 24 | {{ styles.lessonIntro | safe }} 25 | {{ styles.code | safe }} 26 | {{ styles.footer | safe }} 27 | {{ styles.responsive | safe }} 28 | {% endset %} 29 | 30 | 33 | 34 | 35 | 36 | 37 |
38 |
39 | logo Henry{{ config.repoTitle }} 40 |
41 | 49 |
50 | 51 |
52 |
53 | logo Henry 54 |
55 | {{ config.repoTitle }} 56 |
57 |
58 |
59 | 60 |
61 |
62 | {# Navigation #} 63 | {{ collections.all | eleventyNavigation | bootstrapNav({ 64 | listChildItemClass: "dropdown-menu shadow", 65 | activeKey: eleventyNavigation.key, 66 | listItemClass: "link", 67 | activeListItemClass: "activeLink" 68 | }) | safe }} 69 |
70 | 71 |
72 |
73 | {# Lesson (markdown content) #} 74 | {{ content | safe }} 75 |
76 |
77 | 78 |
79 | 80 | 81 | -------------------------------------------------------------------------------- /_src/layouts/lesson.njk: -------------------------------------------------------------------------------- 1 | --- 2 | logoNav: 'https://d31uz8lwfmyn8g.cloudfront.net/Assets/logo-henry-white-sm.png' 3 | favicon: 'https://d31uz8lwfmyn8g.cloudfront.net/Assets/favicon.png' 4 | --- 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {{ lessonTitle }} | {{ config.repoTitle }} 16 | {# #} 17 | 18 | {% set css %} 19 | {{ styles.fonts | safe }} 20 | {{ styles.header | safe }} 21 | {{ styles.main | safe }} 22 | {{ styles.topbar | safe }} 23 | {{ styles.sidebar | safe }} 24 | {{ styles.lesson | safe }} 25 | {{ styles.code | safe }} 26 | {{ styles.footer | safe }} 27 | {{ styles.responsive | safe }} 28 | {% endset %} 29 | 30 | 33 | 34 | 35 | 36 | 37 |
38 | 39 |
40 |
41 | logo Henry{{ lessonTitle }} 42 |
43 | 51 |
52 | 53 |
54 |
55 | logo Henry 56 |
57 | {{ lessonTitle }} | {{ config.repoTitle }} 58 |
59 |
60 |
61 | 62 |
63 |
64 | {# Navigation #} 65 | {{ collections.all | eleventyNavigation | bootstrapNav({ 66 | listChildItemClass: "dropdown-menu shadow", 67 | activeKey: eleventyNavigation.key, 68 | listItemClass: "link", 69 | activeListItemClass: "activeLink" 70 | }) | safe }} 71 |
72 | 73 | 82 | 83 |
84 |
85 | Tiempo de lectura {{ content | readingTime }} 86 |
87 | {% if quizzID %} 88 |
89 | Quizz 📚 90 |
91 | {% endif %} 92 | 93 | {% if homeworkUrl %} 94 |
95 | Homework 📝 96 |
97 | {% endif %} 98 |
99 | 100 |
101 | {# Lesson (markdown content) #} 102 | {{ content | safe }} 103 |
104 | 105 |
106 | 107 | {% if feedbackID %} 108 | 113 | {% endif %} 114 | 115 |
116 |
117 |

Hecho con 💛 por alumnos de Henry

118 |
119 |
120 | 121 |
122 | {% readerBar "3px", 123 | "black", 124 | "yellow" %} 125 |
126 | 127 | 128 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "m1", 3 | "version": "2.0.0", 4 | "description": "

", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "eleventy --serve", 8 | "build": "eleventy" 9 | }, 10 | "devDependencies": { 11 | "@11ty/eleventy-plugin-syntaxhighlight": "^4.0.0" 12 | }, 13 | "author": "Henry", 14 | "license": "ISC", 15 | "jest": { 16 | "testURL": "http://localhost/" 17 | }, 18 | "dependencies": { 19 | "@11ty/eleventy": "^1.0.0", 20 | "@11ty/eleventy-cache-assets": "^2.3.0", 21 | "@11ty/eleventy-navigation": "^0.3.2", 22 | "bootstrap": "^5.1.3", 23 | "eleventy-navigation-bootstrap": "^0.1.2", 24 | "eleventy-plugin-toc": "^1.1.5", 25 | "henry-reader-bar": "https://d31uz8lwfmyn8g.cloudfront.net/Modules/henry-reader-bar-0.2.0.tgz", 26 | "henry-reading-time": "https://d31uz8lwfmyn8g.cloudfront.net/Modules/henry-reading-time-0.1.0.tgz", 27 | "markdown-it": "^12.3.2", 28 | "markdown-it-anchor": "^8.4.1", 29 | "markdown-it-highlightjs": "^3.6.0" 30 | } 31 | } 32 | --------------------------------------------------------------------------------