diff --git a/Basic/03-beginner-exercises.js b/Basic/03-beginner-exercises.js index 2e7dd657..3f6fe244 100644 --- a/Basic/03-beginner-exercises.js +++ b/Basic/03-beginner-exercises.js @@ -4,21 +4,93 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=4733 */ // 1. Escribe un comentario en una línea +// Este es un comentario en una línea // 2. Escribe un comentario en varias líneas +/* +Este es un comentario multilinea +que se extiende por varias líneas +*/ // 3. Declara variables con valores asociados a todos los datos de tipo primitivos +let myBoolean = true; +// Para números enteros y decimales se utiliza el mismo tipo de dato: number +let myNumber = 42; +let myFloat = 3.14; +// strings pueden ser con comillas simples, dobles o backticks +let myStringWithDoubleQuotes = "Hello, world!"; +let myStringWithSingleQuotes = 'Hello, world!'; +let myStringWithBackticks = `Hello, world!`; +let myNull = null; +let myUndefined; +let mySymbol = Symbol("mySymbol"); // 4. Imprime por consola el valor de todas las variables +console.log(myBoolean); +console.log(myNumber); +console.log(myFloat); +console.log(myStringWithDoubleQuotes); +console.log(myStringWithSingleQuotes); +console.log(myStringWithBackticks); +console.log(myNull); +console.log(myUndefined); +console.log(mySymbol); // 5. Imprime por consola el tipo de todas las variables +console.log(typeof myBoolean) +console.log(typeof myNumber) +console.log(typeof myFloat) +console.log(typeof myStringWithDoubleQuotes) +console.log(typeof myStringWithSingleQuotes) +console.log(typeof myStringWithBackticks) +console.log(typeof myNull) // typeof null devuelve "object", es un error histórico de JavaScript +console.log(typeof myUndefined) +console.log(typeof mySymbol) // 6. A continuación, modifica los valores de las variables por otros del mismo tipo +myBoolean = false +myNumber = 100 +myFloat = 2.718 +myStringWithDoubleQuotes = "Goodbye, world!" +myStringWithSingleQuotes = 'Goodbye, world!' +myStringWithBackticks = `Goodbye, world!` +myNull = null // null solo puede ser null, no se puede asignar otro valor +myUndefined = undefined +mySymbol = Symbol("anotherSymbol") // 7. A continuación, modifica los valores de las variables por otros de distinto tipo +myBoolean = "This is a string now" +myNumber = true +myFloat = null +myStringWithDoubleQuotes = 12345 +myStringWithSingleQuotes = false +myStringWithBackticks = undefined +myNull = 'Now I\'m a string' +console.log(myNull) // Comprobando que escapé correctamente la comilla simple +myUndefined = 3.14 +mySymbol = `Not a symbol anymore` // 8. Declara constantes con valores asociados a todos los tipos de datos primitivos +const myConstBoolean = true; +const myConstNumber = 42; +const myConstFloat = 3.14; +const myConstStringWithDoubleQuotes = "Hello, world!"; +const myConstStringWithSingleQuotes = 'Hello, world!'; +const myConstStringWithBackticks = `Hello, world!`; +const myConstNull = null; +const myConstUndefined = undefined; +const myConstSymbol = Symbol("myConstSymbol"); // 9. A continuación, modifica los valores de las constantes - +/* +myConstBoolean = false; +myConstNumber = 100; +myConstFloat = 2.718; +myConstStringWithDoubleQuotes = "Goodbye, world!"; +myConstStringWithSingleQuotes = 'Goodbye, world!'; +myConstStringWithBackticks = `Goodbye, world!`; +myConstNull = {}; */ +myConstUndefined = undefined; /* +myConstSymbol = Symbol("anotherConstSymbol"); +*/ // 10. Comenta las líneas que produzcan algún tipo de error al ejecutarse \ No newline at end of file diff --git a/Basic/05-operators-exercises.js b/Basic/05-operators-exercises.js index a6265eac..4ce31330 100644 --- a/Basic/05-operators-exercises.js +++ b/Basic/05-operators-exercises.js @@ -4,22 +4,91 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=6458 */ // 1. Crea una variable para cada operación aritmética +let sum = 5 + 3 // Suma +let difference = 10 - 9 // Resta +let product = 2 * 3 // Multiplicación +let quotient = 10 / 2 // División +let remainder = 10 % 7 // Módulo +let exponentiation = 2 ** 3 // Exponenciación // 2. Crea una variable para cada tipo de operación de asignación, // que haga uso de las variables utilizadas para las operaciones aritméticas +console.log("\nResultados de las operaciones de asignación:") +let sumAssignment = 0 +process.stdout.write(`${sumAssignment} += ${sum} = `) +sumAssignment += sum +console.log(sumAssignment) + +let differenceAssignment = 0 +process.stdout.write(`${differenceAssignment} -= ${difference} = `) +differenceAssignment -= difference +console.log(differenceAssignment) + +let productAssignment = 2 +process.stdout.write(`${productAssignment} *= ${product} = `) +productAssignment *= product +console.log(productAssignment) + +let quotientAssignment = 2 +process.stdout.write(`${quotientAssignment} /= ${quotient} = `) +quotientAssignment /= quotient +console.log(quotientAssignment) + +let remainderAssignment = 10 +process.stdout.write(`${remainderAssignment} %= ${remainder} = `) +remainderAssignment %= remainder +console.log(remainderAssignment) + +let exponentiationAssignment = 2 +process.stdout.write(`${exponentiationAssignment} **= ${exponentiation} = `) +exponentiationAssignment **= exponentiation +console.log(exponentiationAssignment) + // 3. Imprime 5 comparaciones verdaderas con diferentes operadores de comparación +console.log("Comparaciones verdaderas:") +console.log(5 > 3) // Mayor que +console.log(5 < 10) // Menor que +console.log(5 >= 5) // Mayor o igual que +console.log(5 === 5) // Igualdad por identidad (por tipo y valor) o igualdad estricta +console.log(5 == 5) // Igualdad por valor // 4. Imprime 5 comparaciones falsas con diferentes operadores de comparación +console.log("Comparaciones falsas:") +console.log(5 < 3) // Menor que +console.log(5 > 10) // Mayor que +console.log(5 > 5) // Mayor que +console.log(5 !== 5) // Desigualdad por identidad (por tipo y valor) o desigualdad estricta +console.log(5 != 5) // Desigualdad por valor + // 5. Utiliza el operador lógico and +console.log("AND:") +let trueVar = !("hola" == false) && 1 == true +console.log(`${trueVar}, que es de tipo ${typeof trueVar}`) // 6. Utiliza el operador lógico or +console.log(`OR:`) +console.log(trueVar || false) // 7. Combina ambos operadores lógicos +console.log(`AND combinado con OR:`) +console.log((trueVar && false) || (5 > 3)) // 8. Añade alguna negación +console.log(`Negación:`) +console.log(!trueVar) // 9. Utiliza el operador ternario +let randomBoolean = !!Math.floor(Math.random() * 2) // coercion de tipos +let result = randomBoolean ? "True" : "False" +console.log(`${randomBoolean} (${typeof randomBoolean}) -> ${result}`) +// Math.random() devuelve un numero decimal en el rango [0, 1), de modo que la probabilidad es 50/50 +let anotherRandomBoolean = Math.floor(Math.random() < 0.5) +let anotherResult = anotherRandomBoolean ? "True" : "False" +console.log(`${anotherRandomBoolean} (${typeof anotherRandomBoolean}) -> ${anotherResult}`) -// 10. Combina operadores aritméticos, de comparáción y lógicas \ No newline at end of file +// 10. Combina operadores aritméticos, de comparáción y lógicas +console.log(`Combinación de operadores:`) +let complexExpression = (5 + 3) > (10 - 9) && (2 * 3) <= (10 / 2) +console.log(`(5 + 3) > (10 - 9) && (2 * 3) <= (10 / 2) -> ${complexExpression}`) \ No newline at end of file diff --git a/Basic/06-strings.js b/Basic/06-strings.js index 8c257b7b..d101c4a2 100644 --- a/Basic/06-strings.js +++ b/Basic/06-strings.js @@ -19,20 +19,22 @@ console.log(greeting.length) // Acceso a caracteres console.log(greeting[0]) -console.log(greeting[11]) +console.log(greeting[greeting.length - 2]) // Métodos comunes console.log(greeting.toUpperCase()) // Mayúsculas console.log(greeting.toLowerCase()) // Minúsculas +// El método indexOf devuelve la posición de la primera aparición de una subcadena dentro de la cadena original. +// Si la subcadena no se encuentra, devuelve -1. console.log(greeting.indexOf("Hola")) // Índice console.log(greeting.indexOf("Brais")) console.log(greeting.indexOf("MoureDev")) -console.log(greeting.includes("Hola")) // Incluye +console.log(greeting.includes("Hola")) // Incluye la subcadena console.log(greeting.includes("Brais")) console.log(greeting.includes("MoureDev")) console.log(greeting.slice(0, 10)) // Sección -console.log(greeting.replace("Brais", "MoureDev")) // Reemplazo +console.log(greeting.replace("Brais", "MoureDev")) // Reemplaza una subcadena por otra // Template literals (plantillas literales) diff --git a/Basic/07-strings-exercises.js b/Basic/07-strings-exercises.js index c08f0166..2ca93624 100644 --- a/Basic/07-strings-exercises.js +++ b/Basic/07-strings-exercises.js @@ -5,20 +5,50 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=7226 // 1. Concatena dos cadenas de texto +let firstName = "Cristofer" +let lastName = "Montes" +let fullName = firstName + " " + lastName + // 2. Muestra la longitud de una cadena de texto +console.log(`The length of "${fullName}" is: ${fullName.length} characters`) // 3. Muestra el primer y último carácter de un string +console.log("The first character is: " + fullName[0]) +console.log("The last character is:" + fullName[fullName.length - 1]) // 4. Convierte a mayúsculas y minúsculas un string +let toUpperCase = fullName.toUpperCase() +console.log("My full name in upper case is " + toUpperCase) + +let toLowerCase = fullName.toLowerCase() +console.log(`Me full name to lower case is ` + toLowerCase) // 5. Crea una cadena de texto en varias líneas +let multiLineString = ` +this +is a +multiline string +` +console.log(multiLineString) // 6. Interpola el valor de una variable en un string +console.log(`The string "${multiLineString}" has a size of ${multiLineString.length} characters`) // 7. Reemplaza todos los espacios en blanco de un string por guiones +//multiLineString.replaceAll(" ", "-") +//console.log(multiLineString) <- this is wrong because the replaceAll method does not modify the original string, it returns a new string with the replacements +multiLineString = multiLineString.replaceAll(" ", "-") +console.log(multiLineString) //<- this is correct because we are assigning the result of the replaceAll method to the original var // 8. Comprueba si una cadena de texto contiene una palabra concreta +let myString = "Este texto no fue escrito por una IA" +let stringToSearch = "iA" +let result = myString.toLowerCase().includes(stringToSearch.toLocaleLowerCase()) ? "contiene" : "no contiene"; +console.log(`La cadena "${myString}" ${result} la cadena ${stringToSearch}, no contemplando mayúsculas/minúsculas`) // 9. Comprueba si dos strings son iguales +console.log(`Los strings "${myString}" y "${stringToSearch}" son iguales: ${myString === stringToSearch}`) +console.log(myString === stringToSearch) -// 10. Comprueba si dos strings tienen la misma longitud \ No newline at end of file +// 10. Comprueba si dos strings tienen la misma longitud +console.log(`Los strings "${myString}" y "${stringToSearch}" tienen la misma longitud: ${myString.length === stringToSearch.length}`) \ No newline at end of file diff --git a/Basic/09-conditionals-exercises.js b/Basic/09-conditionals-exercises.js index 380e6542..da445368 100644 --- a/Basic/09-conditionals-exercises.js +++ b/Basic/09-conditionals-exercises.js @@ -6,24 +6,170 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=8652 // if/else/else if/ternaria // 1. Imprime por consola tu nombre si una variable toma su valor +console.log("Excercise 1:") + +const MY_NAME = "Cristofer" + +const names = ["Cristofer", "Ana", "Bob"] +const number = Math.floor(Math.random() * names.length) +const randomName = names[number] + +console.log("The random name is " + randomName) + +if (randomName === MY_NAME) + console.log(`Hello, my name is ${randomName}!`) // 2. Imprime por consola un mensaje si el usuario y contraseña concide con unos establecidos +console.log("\nExcercise 2:") + +const knownCredentials = new Map([ + ["user", "admin"], + ["password", "123"] + +]) + +const users = ["admin", "root"] +const passwords = ["123", "qwerty"] + +const user = users[Math.floor(Math.random() * 2)] +const password = passwords[Math.floor(Math.random() * 2)] + +const hiddenPassword = "*".repeat(password.length) + +console.log(`The user entered is ${user} and the password entered is ${hiddenPassword}`) + +if (user === knownCredentials.get("user") && password === knownCredentials.get("password")) console.log("Login successful!") +else console.log("Login not successful! Please contact the owner of the account if you forgot its credentials") // 3. Verifica si un número es positivo, negativo o cero e imprime un mensaje +console.log("\nExcercise 3:") + +const randomNumber = Math.floor(Math.random() * 2) // numero en [0, 100] +const sign = Math.random() < 0.5 ? -1 : 1 // signo aleatorio +const myNumber = randomNumber * sign +if (myNumber < 0) console.log(`El numero ${myNumber} es negativo`) +else if (myNumber === 0) console.log(`El numero ${myNumber} es cero`) +else console.log(`El numero ${myNumber} es positivo`) // 4. Verifica si una persona puede votar o no (mayor o igual a 18) e indica cuántos años le faltan +console.log("\nExcercise 4:") + +const randomAge = Math.floor(Math.random() * 34) + 1 // probabilidades iguales de ser menor o mayor de edad, rango [1, 34] +if(randomAge >= 18) console.log(`${randomName} tiene ${randomAge} anio(s). Puede votar!`) +else { + const ADULT_AGE = 18 + const missingYears = ADULT_AGE - randomAge + console.log(`${randomName} tiene ${randomAge} anio(s). Le faltan ${missingYears} para poder votar :c`) +} // 5. Usa el operador ternario para asignar el valor "adulto" o "menor" a una variable // dependiendo de la edad +console.log("\nExcercise 5:") +const ageGroup = randomAge >= 18 ? "adulto" : "menor" +console.log(ageGroup) // 6. Muestra en que estación del año nos encontramos dependiendo del valor de una variable "mes" +console.log("\nExcercise 6:") +const mes = Math.floor(Math.random() * 12) + 1 // numero en [1, 12] + +const monthNumber = new Map([ + [1, "january"], + [2, "february"], + [3, "march"], + [4, "april"], + [5, "may"], + [6, "june"], + [7, "july"], + [8, "august"], + [9, "september"], + [10, "october"], + [11, "november"], + [12, "december"] +]) + +const monthSeason = new Map([ + ["january", "winter"], + ["february", "winter"], + ["march", "spring"], + ["april", "spring"], + ["may", "spring"], + ["june", "summer"], + ["july", "summer"], + ["august", "summer"], + ["september", "autumn"], + ["october", "autumn"], + ["november", "autumn"], + ["december", "winter"] +]) +console.log(`The month is ${monthNumber.get(mes)} and the season is ${monthSeason.get(monthNumber.get(mes))}`) // 7. Muestra el número de días que tiene un mes dependiendo de la variable del ejercicio anterior +console.log("\nExcercise 7:") +const monthNumberDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] +console.log(`${monthNumber.get(mes)} has ${monthNumberDays[mes-1]} days`) // switch // 8. Usa un switch para imprimir un mensaje de saludo diferente dependiendo del idioma - +console.log("\nExcercise 8:") +const language = Math.floor(Math.random() * 4) // numero en [0, 3] +switch (language) { + case 0: + console.log("Hello! I speak english") + break + case 1: + console.log("¡Hola! Hablo español") // se pronuncia "hola" y está en español + break + case 2: + console.log("Bonjour! Je parle français") // se pronuncia "bonshur" y está en francés + break + case 3: + console.log("Ciao! Parlo italiano") // se pronuncia "chao" y está en italiano + break +} // 9. Usa un switch para hacer de nuevo el ejercicio 6 +console.log("\nExcercise 9:") +switch (monthNumber.get(mes)) { + case "january": + case "february": + case "december": + console.log(`The month is ${monthNumber.get(mes)} and the season is winter`) + break + case "march": + case "april": + case "may": + console.log(`The month is ${monthNumber.get(mes)} and the season is spring`) + break + case "june": + case "july": + case "august": + console.log(`The month is ${monthNumber.get(mes)} and the season is summer`) + break + case "september": + case "october": + case "november": + console.log(`The month is ${monthNumber.get(mes)} and the season is autumn`) + break +} -// 10. Usa un switch para hacer de nuevo el ejercicio 7 \ No newline at end of file +// 10. Usa un switch para hacer de nuevo el ejercicio 7 +console.log("\nExcercise 10:") +switch(monthNumber.get(mes)){ + case "january": + case "march": + case "may": + case "july": + case "august": + case "october": + case "december": + console.log(`${monthNumber.get(mes)} has 31 days`) + break + case "february": + console.log("february has 28 days") + break + case "april": + case "june": + case "september": + case "november": + console.log(`${monthNumber.get(mes)} has 30 days`) +} \ No newline at end of file diff --git a/Basic/13-structures-exercises.js b/Basic/13-structures-exercises.js index 1b094502..155b4eed 100644 --- a/Basic/13-structures-exercises.js +++ b/Basic/13-structures-exercises.js @@ -4,21 +4,66 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=11451 */ // 1. Crea un array que almacene cinco animales +const animals = ['dog', 'cat', 'rabbit', 'hamster', 'fish']; +console.log("first array:", animals); // 2. Añade dos más. Uno al principio y otro al final +animals.unshift('turtle'); // Añade al principio +console.log("after adding at beginning:", animals); + +animals.push('parrot'); // Añade al final +console.log("after adding at end:", animals); // 3. Elimina el que se encuentra en tercera posición +animals.splice(2, 1) +console.log("after removing third one:", animals); // 4. Crea un set que almacene cinco libros +const books = new Set(); +books.add("El Quijote"); +books.add("Cien años de soledad"); +books.add("1984"); +books.add("To Kill a Mockingbird"); +books.add("The Great Gatsby"); +console.log("first set:", books); // 5. Añade dos más. Uno de ellos repetido +books.add("El Ingenioso Hidalgo Don Quijote de la Mancha"); +books.add("El Quijote"); +console.log("after adding more books:", books); // 6. Elimina uno concreto a tu elección +books.delete("1984"); +console.log("after deleting one book:", books); // 7. Crea un mapa que asocie el número del mes a su nombre +const months = new Map(); +months.set(1, "Enero"); +months.set(2, "Febrero"); +months.set(3, "Marzo"); +months.set(4, "Abril"); +months.set(5, "Mayo"); +months.set(6, "Junio"); +months.set(7, "Julio"); +months.set(8, "Agosto"); +months.set(9, "Septiembre"); +months.set(10, "Octubre"); +months.set(11, "Noviembre"); +months.set(12, "Diciembre"); +console.log("months map:", months); // 8. Comprueba si el mes número 5 existe en el map e imprime su valor +if (months.has(5)) { + console.log("The value for month 5 is:", months.get(5)); +} // 9. Añade al mapa una clave con un array que almacene los meses de verano +months.set("summer", ["Junio", "Julio", "Agosto"]); +console.log("months map with summer:", months); -// 10. Crea un Array, transfórmalo a un Set y almacénalo en un Map \ No newline at end of file +// 10. Crea un Array, transfórmalo a un Set y almacénalo en un Map +const myArray = ["A", "B", "C", "D", "E"]; +const mySet = new Set(myArray); +const myMap = new Map(); +myMap.set("set", mySet); +console.log("map with set from array:", myMap); \ No newline at end of file diff --git a/Basic/15-loops-exercises.js b/Basic/15-loops-exercises.js index 2a27cdd0..94b8974f 100644 --- a/Basic/15-loops-exercises.js +++ b/Basic/15-loops-exercises.js @@ -6,21 +6,92 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=12732 // NOTA: Explora diferentes sintaxis de bucles para resolver los ejercicios // 1. Crea un bucle que imprima los números del 1 al 20 +console.log("Print the numbers from 1 to 20") +for (let i = 1; i <=20; i++){ + process.stdout.write(i + " ") +} // 2. Crea un bucle que sume todos los números del 1 al 100 y muestre el resultado +process.stdout.write("\n\nThe sum of 1 + 2 + ... + (n - 1) + n + (n + 1) + ... + 100 is ") +let sum = 1 +for(let i = 2; i <= 100; i++){ + sum += i +} +console.log(sum) // 3. Crea un bucle que imprima todos los números pares entre 1 y 50 +console.log("\nPrint even numbers from 1 to 50:") +let even = 2 +do{ + process.stdout.write(even + " ") + even += 2 +}while (even <= 50) // 4. Dado un array de nombres, usa un bucle para imprimir cada nombre en la consola +console.log("\n\nTraverse an array of names to print every name:") +const names = ["Alice", "Bob", "Candy"] +for (let name of names){ + console.log(name) +} // 5. Escribe un bucle que cuente el número de vocales en una cadena de texto +const string_ = "This is javascript, BABY!" +const vowels = new Set([ + "a", "e", "i", "o", "u" +]) +let counter = 0; +for(let idx = 0; idx < string_.length; idx++){ + if (vowels.has(string_.charAt(idx).toLowerCase())) counter++; +} +console.log(`\n\nThe string "${string_}" has ${counter} vowels`) // 6. Dado un array de números, usa un bucle para multiplicar todos los números y mostrar el producto +const numbers = [1,2,3,4,5] +let i = 0, product = 1; +while(i < numbers.length){ + product *= numbers[i] + i++ +} +console.log(`\nThe product of the numbers in [${numbers}] is ${product}`) // 7. Escribe un bucle que imprima la tabla de multiplicar del 5 +console.log("\nHere you have the five times table:") +let tr = 1, result = 0 +const MY_BASE = 5 + +while(tr <= 10){ + process.stdout.write(`${MY_BASE} x ${tr} = `) + result = MY_BASE * tr + console.log(result) + tr++ +} // 8. Usa un bucle para invertir una cadena de texto +let str = "Hola", reverseStr = "" +const halfLength = str.length / 2 +for(let i = str.length - 1; i >= 0; i--){ + reverseStr += str.charAt(i) +} +console.log(`\n\nThe reverse of ${str} is "${reverseStr}"`) // 9. Usa un bucle para generar los primeros 10 números de la secuencia de Fibonacci +console.log("\nThe first ten numbers in the Fibonacci sequence:") +let old = 0, current = 1, next; +process.stdout.write(`${old} ${current} `) +for (let counter = 2; counter < 10; counter++){ + next = old + current; + process.stdout.write(next + " ") + old = current; + current = next; +} + +// 10. Dado un array de números, usa un bucle para crear un nuevo array que contenga solo los números mayores a 10 +const arr = [34, 1, 76, 9, 3] -// 10. Dado un array de números, usa un bucle para crear un nuevo array que contenga solo los números mayores a 10 \ No newline at end of file +let filtered = [] +for(const element of arr){ + if (element > 10) { + filtered.push(element) + } +} +console.log(`\n\nThe numbers grater than 10 in ${arr} are ${filtered}`) \ No newline at end of file diff --git a/Basic/17-functions-exercises.js b/Basic/17-functions-exercises.js index fb7eb4e5..13f51410 100644 --- a/Basic/17-functions-exercises.js +++ b/Basic/17-functions-exercises.js @@ -6,21 +6,140 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=14146 // NOTA: Explora diferentes sintaxis de funciones para resolver los ejercicios // 1. Crea una función que reciba dos números y devuelva su suma +const sum = (a = 0, b = 0) => { + if (typeof a !== "number" || typeof b !== "number") { + throw new TypeError("Both arguments must be numbers") + } + return a + b +} +//console.log("The sum of 5 and \"10\" is: ", sum(5, "10")) // TypeError: Both arguments must be numbers +console.log("The sum of 5 and 10 is: ", sum(5, 10)) // 2. Crea una función que reciba un array de números y devuelva el mayor de ellos +function getGreaterNumber(numbers){ + if(!Array.isArray(numbers)) { + throw new TypeError("Expected an array!") + } + let greater = -Infinity + for (const number of numbers){ + if (typeof number !== "number") { + throw new TypeError("Expected an array of numbers!") + } + if(number > greater) greater = number + } + return greater +} + +//const numbers = "5, 10, 3, 8, 2" // TypeError: Expected an array! +//const numbers = [3, 7, 1, 9, "a"] // TypeError: Expected an array of numbers! +const numbers = [3, 7, 1, 9, 7] +console.log(`The greater in ${numbers} is ${getGreaterNumber(numbers)}`) // 3. Crea una función que reciba un string y devuelva el número de vocales que contiene +function countVowels(str){ + const vowels = "aeiouAEIOU" + let count = 0 + for (const char of str){ + if(vowels.includes(char)) count++ + } + return count +} +console.log(`"Hello, World!" has ${countVowels("Hello, World!")} vowels`) // 4. Crea una función que reciba un array de strings y devuelva un nuevo array con las strings en mayúsculas +function getArrayToUpperCase(lowerCaseStrings){ + if(!Array.isArray(lowerCaseStrings)) { + throw new TypeError("Expected an array!") + } + const upperCaseStrings = [] + for(const str of lowerCaseStrings){ + if (typeof str !== "string") { + throw new TypeError("Expected an array of strings!") + } + upperCaseStrings.push(str.toUpperCase()) + } + return upperCaseStrings +} + +const strings = ["hola", "Como", "eStAs"] +const myStrings = getArrayToUpperCase(["hola", "Como", "eStAs"]) +console.log(`The strings [${strings}] in upper case is [${myStrings}]`) +//let myStrings2 = getArrayToUpperCase("hola") +//console.log(myStrings2) // 5. Crea una función que reciba un número y devuelva true si es primo, y false en caso contrario +function isPrime(num){ + if (num <= 1) return false + const limit = Math.sqrt(num) + for (let i = 2; i <= limit; i++){ + if (num % i === 0) return false + } + return true +} +console.log("Is 7 prime? ", isPrime(7)) +console.log("Is 101 prime? ", isPrime(101)) +console.log("Is 321654987 prime? ", isPrime(321654987)) // 6. Crea una función que reciba dos arrays y devuelva un nuevo array que contenga los elementos comunes entre ambos +const getCommonElements = (arr1, arr2) => { + if (!Array.isArray(arr1) || !Array.isArray(arr2)) { + throw new TypeError("Expected two arrays!") + } + const commonElements = [] + for (const element of arr1){ + if (arr2.includes(element) && !commonElements.includes(element)) { + commonElements.push(element) + } + } + return commonElements +} +const array1 = [1, 2, 3, 4, 5] +const array2 = [4, 5, 6, 7, 8] +console.log(`Common elements between ${array1} and ${array2} are: ${getCommonElements(array1, array2)}`) // 7. Crea una función que reciba un array de números y devuelva la suma de todos los números pares +const getSumOfEvensInArray = function (array){ + function isEven(number){ + return number % 2 === 0 + } + + let sum = 0 + for(const number of array){ + if(isEven(number)) sum += number + } + return sum +} + +const array = [1, 2, 3, 4, 5, 6] +console.log(`The sum of even numbers in ${array} is ${getSumOfEvensInArray(array)}`) // 8. Crea una función que reciba un array de números y devuelva un nuevo array con cada número elevado al cuadrado +function getSqures(array){ + const squares = [] + for(const number of array) squares.push(number * number) + return squares +} +const nums = [1, 2, 3, 4, 5] +console.log(`The squares in ${nums} are ${getSqures(nums)}, respectively`) // 9. Crea una función que reciba una cadena de texto y devuelva la misma cadena con las palabras en orden inverso +const getInverseOrderWords = (string_) => { + if(typeof string_ === "string"){ + const words = string_.split(" ").reverse() + const myReversedString = words.join(" ") + return myReversedString + } + throw new TypeError("Expected a string") +} +const myString = "Hola como estas" +const myReversedString = getInverseOrderWords(myString) +console.log(`The reversing of "${myString}" is "${myReversedString}"`) -// 10. Crea una función que calcule el factorial de un número dado \ No newline at end of file +// 10. Crea una función que calcule el factorial de un número dado +const factorial = (number) => { + if (number > 0) return number * factorial(number - 1) + else if (number === 0) return 1 + return undefined +} +const MY_NUMBER = 5 +console.log(`The factorial of ${MY_NUMBER} is ${factorial(MY_NUMBER)}`) \ No newline at end of file diff --git a/Basic/18-objects.js b/Basic/18-objects.js index 4e71a6b2..a000a9ee 100644 --- a/Basic/18-objects.js +++ b/Basic/18-objects.js @@ -93,10 +93,10 @@ let person4 = { console.log(person) console.log(person4) -console.log(person == person4) -console.log(person === person4) +console.log(person == person4) // false, porque compara referencias en memoria, no el contenido de los objetos +console.log(person === person4) //false porque compara referencias en memoria, no el contenido de los objetos -console.log(person.name == person4.name) +console.log(person.name == person4.name) // true, porque compara el valor de las propiedades name de ambos objetos, que es "Brais Moure" en ambos casos // Iteración diff --git a/Basic/19-objects-exercises.js b/Basic/19-objects-exercises.js index 5dbbd628..aae3a6e0 100644 --- a/Basic/19-objects-exercises.js +++ b/Basic/19-objects-exercises.js @@ -4,21 +4,85 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=15675 */ // 1. Crea un objeto con 3 propiedades +const person = { + name: "Cristofer", + age: 24, + alias: "cmontes" +} +console.log("Person object: ", person, "created") // 2. Accede y muestra su valor +console.log("\nProperties in person object:") +console.log(person.name) +console.log(person["age"]) +console.log(person["alias"]) // 3. Agrega una nueva propiedad +const email = "cmontes@example.com" +console.log(`\nAdding new property "email" with value "${email}" to person object...`) +person.email = email +console.log("Updated person object: ", person) // 4. Elimina una de las 3 primeras propiedades +console.log("\nDeleting property \"age\" from person object...") +delete person.age +console.log("Updated person object: ", person) // 5. Agrega una función e invócala +console.log("\nAdding method \"greet\" to person object and calling it...") +person.greet = function() { + console.log(`¡Hola, mi nombre es ${this.name} y mi alias es ${this.alias}!`) +} +person.greet() +console.log("Updated person object: ", person) // 6. Itera las propiedades del objeto +console.log("\nIterating properties of person object:") +for(const property in person){ + console.log(`${property}: ${person[property]}`) +} // 7. Crea un objeto anidado +console.log("\nCreating nested object \"persona\"...") +const persona = { + nombreCompleto: { + nombre: "Cristofer", + apellido: "Montes" + }, + edad: 24, + escuela: { + nombre: "Escuela Superior de Cómputo", + carrera: { + nombre: "Ingeniería en Sistemas Computacionales", + planDeEstudios: 2020 + } + } +} +console.log("Object created: ", persona) // 8. Accede y muestra el valor de las propiedades anidadas +console.log("\nAccessing nested properties in persona object:") +console.log(persona.nombreCompleto.nombre) +console.log(persona.nombreCompleto.apellido) +console.log(persona.escuela.nombre) +console.log(persona.escuela.carrera.nombre) +console.log(persona.escuela.carrera.planDeEstudios) // 9. Comprueba si los dos objetos creados son iguales +console.log("\nComparing objects with lodash isEqual:") +function Person(name, age = 0) { + this.name = name + this.age = age +} +const person4 = new Person("juan") +const person5 = new Person("juan") +const person6 = new Person("Juan") -// 10. Comprueba si dos propiedades diferentes son iguales \ No newline at end of file +import isEqual from 'lodash/isEqual.js'; + +console.log(`isEqual(${JSON.stringify(person4)}, ${JSON.stringify(person5)}): ${isEqual(person4, person5)}`) +console.log(`isEqual(${JSON.stringify(person4)}, ${JSON.stringify(person6)}): ${isEqual(person4, person6)}`) + +// 10. Comprueba si dos propiedades diferentes son iguales +console.log("\nComparing different properties:") +console.log(`person4.name === person4.age: ${person4.name === person4.age}`) \ No newline at end of file diff --git a/Basic/21-destructuring-spreading-exercises.js b/Basic/21-destructuring-spreading-exercises.js index feadceb3..ee44039c 100644 --- a/Basic/21-destructuring-spreading-exercises.js +++ b/Basic/21-destructuring-spreading-exercises.js @@ -4,22 +4,104 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=16802 */ // 1. Usa desestructuración para extraer los dos primeros elementos de un array +console.log("Excercise 1: Usa desestructuración para extraer los dos primeros elementos de un array") +const arr = [1, 2, 3] +const [item1, item2] = arr +console.log(arr) +console.log(item1) +console.log(item2) // 2. Usa desestructuración en un array y asigna un valor predeterminado a una variable +console.log("Excercise 2: Usa desestructuración en un array y asigna un valor predeterminado a una variable") +const [item3, item4, item5, item6 = 0] = arr +console.log(arr) +console.log(item3) +console.log(item4) +console.log(item5) +console.log(item6) // 3. Usa desestructuración para extraer dos propiedades de un objeto +console.log("Excercise 3: Usa desestructuración para extraer dos propiedades de un objeto") +const obj = {prop1: "hola", prop2: "mundo", prop3: 7} +const {prop1, prop3} = obj +console.log(obj) +console.log(prop1) +console.log(prop3) // 4. Usa desestructuración para extraer dos propiedades de un objeto y asígnalas // a nuevas variables con nombres diferentes +console.log("Excercise 4: Usa desestructuración para extraer dos propiedades de un objeto y asígnalas a nuevas variables con nombres diferentes") +const {prop1:saludo, prop2:parte2} = obj +console.log(obj) +console.log(saludo) +console.log(parte2) // 5. Usa desestructuración para extraer dos propiedades de un objeto anidado +console.log("Excercise 5: Usa desestructuración para extraer dos propiedades de un objeto anidado") +const nestedObj = { + outerProp: "outer", + innerObj: { + innerProp: "inner", + somethingElse: "whatever" + } +} +const {innerObj: {innerProp:first}, innerObj: {somethingElse: second}} = nestedObj +console.log(nestedObj) +console.log(first) +console.log(second) // 6. Usa propagación para combinar dos arrays en uno nuevo +console.log("Excercise 6: Usa propagación para combinar dos arrays en uno nuevo") +const arr1 = [1, 2] +const arr2 = ["1", "2"] +const arr3 = [...arr1, ...arr2] +console.log(arr1) +console.log(arr2) +console.log(arr3) // 7. Usa propagación para crear una copia de un array +console.log("Excercise 7: Usa propagación para crear una copia de un array") +const copyOfArr1 = [...arr1] +console.log(copyOfArr1) +console.log(arr1) // 8. Usa propagación para combinar dos objetos en uno nuevo +console.log("Excercise 8: Usa propagación para combinar dos objetos en uno nuevo") +const obj1 = {prop1: 1, prop2: "2"} +const obj2 = {prop2: 2, prop3: "3"} +const obj3 = {...obj1, ...obj2} +console.log(obj1) +console.log(obj2) +console.log(obj3) + +// Ojo: Si hay propiedades con el mismo nombre, se toma el valor del último objeto +// (se soluciona desestructurando primero la propiedad comun, propagando el resto y +// luego combinar las partes) +const { prop2: prop2Obj1, ...rest1 } = obj1 +const { prop2: prop2Obj2, ...rest2 } = obj2 + +const combined = { + ...rest1, + ...rest2, + prop2Obj1, + prop2Obj2 +} +console.log(combined) // 9. Usa propagación para crear una copia de un objeto +console.log("Excercise 9: Usa propagación para crear una copia de un objeto") +const copyOfObj1 = {...obj1} +console.log(obj1) +console.log(copyOfObj1) + +// 10. Combina desestructuración y propagación +console.log("Excercise 10: Combina desestructuración y propagación") +const person = { + id: 1, + name: "Ana", + password: "123456" +} -// 10. Combina desestructuración y propagación \ No newline at end of file +const { password, ...safePerson } = person +console.log(person) +console.log(safePerson) \ No newline at end of file diff --git a/Basic/22-classes.js b/Basic/22-classes.js index b95ddc26..71a7370c 100644 --- a/Basic/22-classes.js +++ b/Basic/22-classes.js @@ -6,13 +6,11 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=16864 // Clases class Person { - constructor(name, age, alias) { this.name = name this.age = age this.alias = alias } - } // Sintaxis @@ -122,7 +120,7 @@ class GetSetPerson { } -person6 = new GetSetPerson("Brais", 37, "MoureDev", "IBAN123456789") +const person6 = new GetSetPerson("Brais", 37, "MoureDev", "IBAN123456789") console.log(person6) console.log(person6.name) diff --git a/Basic/23-classes-exercises.js b/Basic/23-classes-exercises.js index e26e0232..1397cfa8 100644 --- a/Basic/23-classes-exercises.js +++ b/Basic/23-classes-exercises.js @@ -4,21 +4,83 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=18630 */ // 1. Crea una clase que reciba dos propiedades +class Pc { + #type + #os + + constructor(type, os) { + this.#type = type + this.#os = os + } + + get type(){ + return this.#type + } + + get os(){ + return this.#os + } -// 2. Añade un método a la clase que utilice las propiedades + set os(os){ + this.#os = os + } + + // 2. Añade un método a la clase que utilice las propiedades + getInfo(){ + return `Type: ${this.#type}, OS: ${this.#os}` + } + + // 4. Añade un método estático a la primera clase + static createGeneric(){ + return new Pc("generic", "generic") + } +} // 3. Muestra los valores de las propiedades e invoca a la función +const pc1 = new Pc("laptop", "Windows") +console.log(pc1) +console.log(pc1.type) +console.log(pc1.os) +console.log(pc1.getInfo()) -// 4. Añade un método estático a la primera clase // 5. Haz uso del método estático +const pc2 = Pc.createGeneric() +console.log(pc2) +console.log(pc2.getInfo()) // 6. Crea una clase que haga uso de herencia - // 7. Crea una clase que haga uso de getters y setters - // 8. Modifica la clase con getters y setters para que use propiedades privadas +class Smartphone extends Pc { + #brand + + constructor(type, os, brand) { + super(type, os) + this.#brand = brand + } + + get brand() { + return this.#brand + } + + set brand(brand) { + this.#brand = brand + } + + // 10. Sobrescribe un método de una clase que utilice herencia + getInfo(){ + return `Type: ${super.type}, OS: ${super.os}, Brand: ${this.#brand}` + } +} // 9. Utiliza los get y set y muestra sus valores +const phone1 = new Smartphone("smartphone", "Android", "Samsung") +console.log(phone1) +phone1.os = "iOS" +phone1.brand = "iPhone" + + +// 10 -> +console.log(phone1.getInfo()) -// 10. Sobrescribe un método de una clase que utilice herencia \ No newline at end of file diff --git a/Basic/25-error-handling-exercises.js b/Basic/25-error-handling-exercises.js index 5e227586..884a5e4d 100644 --- a/Basic/25-error-handling-exercises.js +++ b/Basic/25-error-handling-exercises.js @@ -3,22 +3,188 @@ Clase 41 - Ejercicios: Manejo de errores Vídeo: https://youtu.be/1glVfFxj8a4?t=20392 */ +const traverseArray = (array) => { + for (const item of array) { + console.log(item) + } +} + // 1. Captura una excepción utilizando try-catch +try { + traverseArray(undefined) +} catch (error) { + console.log("1 " + error) + console.log("2 " + error.message) +} +console.log("seguimos vivos!\n") // 2. Captura una excepción utilizando try-catch y finally +try { + let arrayOfNumbers = [] + const arr2 = [1, "2"] + for(const item of arr2){ + if(typeof item !== "number") throw new Error("Solo se permiten numeros") + arrayOfNumbers.push(item) + } + console.log(`Array of numbers: ${arrayOfNumbers}`) +} catch (error) { + console.error("error: " + error.message) +} finally { + console.log("Esto se ejecuta siempre, haya error o no\n") +} // 3. Lanza una excepción genérica +try{ + throw new Error("Error generico") +} catch(error){ + console.log(error.message + "\n") +} // 4. Crea una excepción personalizada +class DomainError extends Error { + constructor(message) { + super(message) + this.type = "DomainError" + } +} + +function superiorOrderFunc (func, param){ + if(!Array.isArray(param)) throw new DomainError("No es un array") + else func(param) +} // 5. Lanza una excepción personalizada +try { + superiorOrderFunc(traverseArray, undefined) +} catch (error) { + console.log(error.type + ": " + error.message) +} +console.log() + +class Persona{ + #name + #age + + constructor(name, age){ + this.#name = name + this.#age = age + } + + get name(){ + return this.#name + } + + get age(){ + return this.#age + } +} + +class InstanceError extends Error{ + constructor(message){ + super(message) + this.type = "InstanceError" + } +} // 6. Lanza varias excepciones según una lógica definida +function validateData(data){ + if(!(data instanceof Persona)){ + throw new InstanceError(`Se esperaba ${new Persona().constructor.name}, se recibió ${data.constructor.name}`) + } + if(typeof data.name !== "string"){ + throw new TypeError("El nombre debe ser de tipo string, se recibió " + typeof data.name) + } + if(typeof data.age !== "number"){ + throw new TypeError("La edad debe ser de tipo number, se recibió " + typeof data.age) + } +} -// 7. Captura varias excepciones en un mismo try-catch +try { + const personas = [ + new Persona("Carlos", 20), + //new Persona(22, "John"), + new Persona(), + //new String("hola") + ] + for (const persona of personas){ + validateData(persona) + console.log(`${persona.name} tiene ${persona.age} años`) + } +} catch (error){ + // 7. Captura varias excepciones en un mismo try-catch + if(error instanceof InstanceError){ + console.log(error.type + ": " + error.message) + } + else if(error instanceof TypeError){ + console.log(error.name + ": " + error.message) + } + else console.log("Error desconocido: " + error.message) +} // 8. Crea un bucle que intente transformar a float cada valor y capture y muestre los errores +console.log() +const values = ["1.5", "2.3", "tres", "4.0", "cinco"] + +for(const value of values){ + try{ + const number = parseFloat(value) + if(isNaN(number)) throw new Error("Valor no numérico") + console.log(`Valor convertido: ${number}`) + } catch(error){ + console.log(`Error al convertir "${value}": ${error.message}`) + } +} // 9. Crea una función que verifique si un objeto tiene una propiedad específica y lance una excepción personalizada +class MissingPropertyError extends Error { + constructor(message) { + super(message) + this.name = "MissingPropertyError" + } +} + +function hasProperty(obj, prop) { + if (!(prop in obj)) { + throw new MissingPropertyError(`La propiedad "${prop}" no existe en el objeto`) + } +} + +console.log() + +try{ + const obj = { name: "Alice", age: 30 } + hasProperty(obj, "email") + console.log("Objeto completo") +} catch(error){ + if(error instanceof MissingPropertyError){ + console.log(error.name + ": " + error.message) + } else { + console.log("Error desconocido: " + error.message) + } +} -// 10. Crea una función que realice reintentos en caso de error hasta un máximo de 10 \ No newline at end of file +// 10. Crea una función que realice reintentos en caso de error hasta un máximo de 10 +console.log() +const isNumber = (number) => { + console.log("Se recibió: " + number.constructor.name) + if(typeof number !== "number"){ + throw new TypeError("Se requiere un numero") + } + return true; +} +const arr =[1, "str", "str2", {}, {}, [], [], new Persona(), new Persona(), new Map()] +let attempt = 0 +let wasError = false +do{ + try{ + console.log(`Intento ${attempt + 1}`) + const num = arr[Math.floor(Math.random() * 10)] + if (isNumber(num)) console.log("Todo bien") + wasError = false + } catch (error){ + console.log(error.message) + wasError = true + } + attempt++ +}while(attempt < 10 && wasError); +if(attempt === 10) console.log("Se alcanzó el número máximo de intentos") diff --git a/Basic/27-console-methods-exercises.js b/Basic/27-console-methods-exercises.js index 9c38919b..1e576b44 100644 --- a/Basic/27-console-methods-exercises.js +++ b/Basic/27-console-methods-exercises.js @@ -4,21 +4,102 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=21421 */ // 1. Crea un función que utilice error correctamente +function findUser(name) { + const users = ["Cris", "Montes", "Dev"] + const user = users.find(u => u === name) + if (!user) { + console.error("Usuario no encontrado") + } + return user +} +console.log(`Buscando a Cristofer: ${findUser("Cristofer")}`) +console.log(`Buscando a Cris: ${findUser("Cris")}`) // 2. Crea una función que utilice warn correctamente +function validateAge(age) { + if (age < 0) { + console.warn("La edad no puede ser negativa") + } +} +console.log("Validando edad -5...") +validateAge(-5) +console.log("Validando edad 30...") +validateAge(30) // 3. Crea una función que utilice info correctamente +function logUserInfo(user) { + console.info("Información del usuario:") + console.info(user) +} +logUserInfo({ name: "Cris", age: 30, alias: "cmontesdev" }) + // 4. Utiliza table +function logUsersTable(users) { + console.table(users) +} +logUsersTable([ + { name: "Cris", age: 30, alias: "cmontesdev" }, + { name: "Brais", age: 37, alias: "MoureDev" } +]) // 5. Utiliza group +function logUserGroup(user) { + console.group("Información del usuario") + console.info(user) + console.groupEnd() +} +logUserGroup({ name: "Cris", age: 30, alias: "cmontesdev" }) +console.log("Otra información fuera del grupo") // 6. Utiliza time +function timeOperation(operation) { + console.time(operation) + // Simula una operación + for (let i = 0; i < 1000000; i++) { + Math.sqrt(i) + } + console.timeEnd(operation) +} +timeOperation("Operación de raíz cuadrada") // 7. Valida con assert si un número es positivo +function validatePositiveNumber(num) { + console.assert(num > 0, "El número debe ser positivo") +} +console.log("Validando número -5...") +validatePositiveNumber(-5) +console.log("Validando número 10...") +validatePositiveNumber(10) // 8. Utiliza count +function countOperations() { + console.count("Operación realizada") +} +function resetCount() { + console.countReset("Operación realizada") + console.log("Contador reiniciado") +} + +countOperations() +countOperations() +resetCount() +countOperations() // 9. Utiliza trace +function logTrace() { + console.trace() +} +function anotherFunction() { + logTrace() +} +anotherFunction() + +// 10. Utiliza clear +function clearConsole() { + console.log("Este mensaje se mostrará antes de limpiar la consola.") + console.clear() + console.log("La consola ha sido limpiada.") +} -// 10. Utiliza clear \ No newline at end of file +//clearConsole() diff --git a/Basic/30-import-external-modules.cjs b/Basic/30-import-external-modules.cjs index 5718b5d4..b1e0e664 100644 --- a/Basic/30-import-external-modules.cjs +++ b/Basic/30-import-external-modules.cjs @@ -5,7 +5,7 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=21480 // Módulos externos -const os = require("os") +const os = require("node:os") console.log(os.platform()) console.log(os.arch()) diff --git a/Basic/31-modules-exercises.js b/Basic/31-modules-exercises.js index a09c62b9..52e315f9 100644 --- a/Basic/31-modules-exercises.js +++ b/Basic/31-modules-exercises.js @@ -4,21 +4,72 @@ Vídeo: https://youtu.be/1glVfFxj8a4?t=22720 */ // 1. Exporta una función +console.log("\nInicio...\n\n") +export const validateAge = (age) => age >= 18 // 2. Exporta una constante +export const API_URL = "http://localhost:3000"; // 3. Exporta una clase +class User { + #name + + constructor(name) { + this.#name = name + } + + get name() { + return this.#name + } + + set name(name) { + this.#name = name + } +} + +export { User } // 4. Importa una función +import { echo } from "./my_modules/echo.js" +console.log(echo("Hello, world!")) // 5. Importa una constante +// this will run the code in 17-functions-exercises.js and export the PI constant +import { PI } from "./my_modules/constants.js"; +console.log(PI) // 6. Importa una clase +// !IMPORTANT: this will run the code in 22-classes.js and export the Dog class +import { Dog } from "./22-classes.js" +const dog1 = new Dog("scooby") +dog1.sound() // 7. Exporta una función, una constante y una clase por defecto (en caso de que lo permita) +// solo se puede exportar una función, una constante o una clase por defecto, +// no se pueden exportar varias por defecto en el mismo archivo // 8. Importa una función, una constante y una clase por defecto (en caso de que lo permita) +// solo se puede importar una función, una constante o una clase por defecto, +// no se pueden importar varias por defecto en el mismo archivo // 9. Exporta una función, una constante y una clase desde una carpeta +import { sub, MULTIPLICATIVE_IDENTITY, Circle } from "./my_modules/math-utils.js" +console.log(sub(10, 5)) +console.log(MULTIPLICATIVE_IDENTITY) + +// 10. Importa una función, una constante y una clase desde un directorio diferente al anterior +import { UserAge, users, findUser } from "../other-modules/others.mjs" +const userAge1 = new UserAge("Carlos", 30) +console.log(userAge1) + +const user1 = findUser("Carlos") +const user2 = findUser("Cristofer") +const users2 = [user1, user2] -// 10. Importa una función, una constante y una clase desde un directorio diferente al anterior \ No newline at end of file +users2.forEach(user => { + if (user === undefined) { + console.log("Usuario no encontrado") + } else { + console.log(`Usuario encontrado: ${user.name}, ${user.age} años`) + } +}) \ No newline at end of file diff --git a/Basic/my_modules/constants.js b/Basic/my_modules/constants.js new file mode 100644 index 00000000..3044bcac --- /dev/null +++ b/Basic/my_modules/constants.js @@ -0,0 +1,3 @@ +const PI = 3.1416 + +export { PI } \ No newline at end of file diff --git a/Basic/my_modules/echo.js b/Basic/my_modules/echo.js new file mode 100644 index 00000000..c636e4d3 --- /dev/null +++ b/Basic/my_modules/echo.js @@ -0,0 +1,5 @@ +function echo(message) { + return message +} + +export { echo } \ No newline at end of file diff --git a/Basic/my_modules/math-utils.js b/Basic/my_modules/math-utils.js new file mode 100644 index 00000000..01936222 --- /dev/null +++ b/Basic/my_modules/math-utils.js @@ -0,0 +1,24 @@ +class Circle { + constructor(radius) { + this.radius = radius + } + + area() { + return Math.PI * Math.pow(this.radius, 2) + } + + perimeter() { + return 2 * Math.PI * this.radius + } +} + +const sub = (a = 0, b = 0) => { + if (typeof a !== "number" || typeof b !== "number") { + throw new TypeError("Both arguments must be numbers") + } + return a - b +} + +const MULTIPLICATIVE_IDENTITY = 1 + +export { sub, MULTIPLICATIVE_IDENTITY, Circle } \ No newline at end of file diff --git a/Basic/package-lock.json b/Basic/package-lock.json new file mode 100644 index 00000000..a9975591 --- /dev/null +++ b/Basic/package-lock.json @@ -0,0 +1,18 @@ +{ + "name": "Basic", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "lodash": "^4.18.1" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + } + } +} diff --git a/Basic/package.json b/Basic/package.json index 96ae6e57..b2c11c22 100644 --- a/Basic/package.json +++ b/Basic/package.json @@ -1,3 +1,6 @@ { - "type": "module" -} \ No newline at end of file + "type": "module", + "dependencies": { + "lodash": "^4.18.1" + } +} diff --git a/Intermediate/01-advanced-functions-exercises.js b/Intermediate/01-advanced-functions-exercises.js index 2d182882..4032c1aa 100644 --- a/Intermediate/01-advanced-functions-exercises.js +++ b/Intermediate/01-advanced-functions-exercises.js @@ -4,21 +4,142 @@ Vídeo: https://youtu.be/iJvLAZ8MJ2E?t=4112 */ // 1. Crea una función que retorne a otra función +import createCounter from "./my_modules/counter.js" +import deleteVowels from "./my_modules/vowel-deleter.js" +import { insertUser } from "./my_modules/db.js" + +const counter = createCounter() +console.log(typeof counter) + +// aqui retorno la funcion +function registerUser(name) { + const key = `${counter.next().value}${deleteVowels(name)}` + return insertUser(key, name) +} + +const users = ["Cristofer", "John", "Wick"] +users.forEach(user => { + console.log(registerUser(user)) +}) // 2. Implementa una función currificada que multiplique 3 números +console.log("currying") +function multiply(x) { + return function (y) { + return function (z) { + return x * y * z + } + } +} +console.log(multiply(2)(3)(4)) // 24 // 3. Desarrolla una función recursiva que calcule la potencia de un número elevado a un exponente +function pow(number, exponent) { + if (exponent < 0) throw new Error("Esta función no soporta exponentes negativos") + if (exponent === 0) return 1 + return number * pow(number, exponent - 1) +} +try { + console.log(pow(2, -1)) +} catch (error) { + console.log(error.message) +} +console.log(pow(2, 0)) +console.log(pow(2, 1)) +console.log(pow(2, 2)) +console.log(pow(2, 3)) // 4. Crea una función createCounter() que reciba un valor inicial y retorne un objeto con métodos para increment(), decrement() y getValue(), utilizando un closure para mantener el estado +console.log("closures") +function createCounter2(start) { + let i = start; + + return { + increment: () => ++i, + decrement: function () { return --i }, + getValue: function () { + return i + } + } +} +const counter2 = createCounter2(5) +console.log(counter2.increment()) +console.log(counter2.decrement()) +console.log(counter2.getValue()) + // 5. Crea una función sumManyTimes(multiplier, ...numbers) que primero sume todos los números (usando parámetros Rest) y luego multiplique el resultado por multiplier +console.log("Rest params") +function sumManyTimes(multiplier, ...numbers){ + let sum = 0 + + // "numbers" es un array de los elementos restantes, por lo tanto ya es iterable + for (const number of numbers) { + sum += number + } + return multiplier * sum +} +console.log(sumManyTimes(4, 3, 2, 1)) // 6. Crea un Callback que se invoque con el resultado de la suma de todos los números que se le pasan a una función +function suma(callback, ...numbers){ + let sum = 0 + + numbers.forEach(element => { + sum = sum + element + }) + + callback(sum) +} + +suma((result) => console.log(`El resultado es: ${result}`), + 5, 10, 20) // 7. Desarrolla una función parcial +function getFullName(name){ + return function(lastname){ + return `${name} ${lastname}` + } +} + +console.log(`Hola ${getFullName("Cristofer")("Montes")}`) // 8. Implementa un ejemplo que haga uso de Spread +const personas = [ + {name: "Jorge"}, + {name: "Rodrigo"}, + {name: "Ana"} +] + +console.log(...personas) // esto es diferente de console.log(personas) // 9. Implementa un retorno implícito +const echo = (value) => value + +console.log(echo("echo")) + +// 10. Haz uso del this léxico +class Persona { + #magicNumber + printMagicNumber(){ + console.log("Obteniendo tu número mágico...") + this.#magicNumber = Math.floor(Math.random() * 100) + 1 + setTimeout(() => { + console.log(`Tu número mágico es: ${this.#magicNumber}`) + }, 5000) + } +} +const p = new Persona() +p.printMagicNumber() + + +const obj = { + name: "Objeto", + printNameWithDelay: function() { + setTimeout(() => { + console.log(`El nombre del objeto es: ${this.name}`) + }, 2000) + } +} -// 10. Haz uso del this léxico \ No newline at end of file +obj.printNameWithDelay() diff --git a/Intermediate/03-advanced-structures-exercises.js b/Intermediate/03-advanced-structures-exercises.js index c633ef28..9e42ac95 100644 --- a/Intermediate/03-advanced-structures-exercises.js +++ b/Intermediate/03-advanced-structures-exercises.js @@ -4,21 +4,221 @@ Vídeo: https://youtu.be/iJvLAZ8MJ2E?t=7514 */ // 1. Utiliza map, filter y reduce para crear un ejemplo diferente al de la lección +// agrego foreach para practicar aunque no se pidio +const prices = [100, 200, 300] + +prices.forEach((item, idx, fullArray) => { + fullArray[idx] = item * 0.9 +}) + +console.log(prices) + +//map +const discount = 0.25 +const sales = prices.map((i) => i * (1 - discount)) +console.log(sales) + +//filter +const salesUnderOneHundredBucks = sales.filter(i => i <= 100) +console.log(salesUnderOneHundredBucks) + +//reduce +const fruits = ["apple", "banana", "apple", "orange", "banana"] + +const count = fruits.reduce((acc, fruit) => { + acc[fruit] = (acc[fruit] ?? 0) + 1 // valor o 0 si no existe, luego sumo 1 + return acc +}, {}) + +console.log(count) // 2. Dado un array de números, crea uno nuevo con dichos números elevados al cubo y filtra sólo los números pares +const myNumbers = [1, 2, 3, 4, 5] +const myQubicNumbersEvens = myNumbers + .map(n => n ** 3) + .filter(n => n % 2 === 0) +console.log(myQubicNumbersEvens) // 3. Utiliza flat y flatMap para crear un ejemplo diferente al de la lección +//flat +const myNestedArray = [6, [4, [2, [1], 3], 5], 7] +const myFlatArray = myNestedArray.flat(Infinity) +console.log(myFlatArray) + +//flatmap +const mySencences = [ + "esta sentencia está en español", + "this sentence is written in English" +] + +const tokens = mySencences.flatMap(sentence => sentence.split(" ")) +console.log(tokens) + +const letters = mySencences.flatMap(sentence => sentence.split("")) +console.log(letters) // 4. Ordena un array de números de mayor a menor +myFlatArray.sort((a, b) => b - a) // si retorna negativo, a va antes, 0 iguales, positivo a es mayor +console.log(myFlatArray) // 5. Dados dos sets, encuentra la unión, intersección y diferencia de ellos +const myArrOfSets = [new Set([1, 2, 3]), new Set([2, 3, 4])] +console.log("sets: ", myArrOfSets) + +const union = new Set([...myArrOfSets[0], ...myArrOfSets[1]]) +console.log(`union:`, union) + +const [small, large] = myArrOfSets[0] <= myArrOfSets[1] + ? [myArrOfSets[0], myArrOfSets[1]] + : [myArrOfSets[1], myArrOfSets[0]] + +const interseccion = new Set() +for(const number of small){ + if(large.has(number)) + interseccion.add(number) +} +console.log("interseccion:", interseccion) + +const diferenciaSimetrica = new Set() +for(const number of small){ + if(!large.has(number)) + diferenciaSimetrica.add(number) +} +for(const number of large){ + if(!small.has(number)) + diferenciaSimetrica.add(number) +} + +console.log("diferencia simetrica:", diferenciaSimetrica) // 6. Itera los resultados del ejercicio anterior +;[union, interseccion, diferenciaSimetrica] + .forEach(set => { + set.forEach(setItem => process.stdout.write(`${setItem} `)) + console.log() + }) // 7. Crea un mapa que almacene información se usuarios (nombre, edad y email) e itera los datos +// ! -> A partir de aquí, lo hago de tres formas distintas para practicar +// 1 +const usuarios = [ + new Map([ + ["nombre", "Cristofer"], + ["edad", 24], + ["email", "c@c.com"] + ]), + new Map([ + ["nombre", "Ramiro"], + ["edad", 17], + ["email", "a@a.com"] + ]) +] +usuarios.forEach(mapa => + mapa.forEach((v, k) => { + console.log(`${k}: ${v}`) + }) +) + +//2 +function crearPersona(nombre, edad, email){ + return { nombre, edad, email } +} + +const usuariosV2 = new Map([ + [1, crearPersona("Carlos", 20, "c@a.com")], + [2, crearPersona("Fernando", 16, "f@a.com")] +]) + +usuariosV2.forEach((v, k) => { + console.log(`${k} =>`) + for(const prop in v){ + console.log(`${prop}: ${v[prop]}`) + } +}) + +// 3 +const usuariosV3 = new Map([ + [3, crearPersona("Domingo", 25, "d@a.com")], + [4, crearPersona("Laura", 15, "l@a.com")] +]) + +usuariosV3.forEach((v, k) => { + console.log(`${k} =>`) + for (const [clave, valor] of Object.entries(v)) { + console.log(`${clave}: ${valor}`) +} +}) // 8. Dado el mapa anterior, crea un array con los nombres +const nombres = [] +usuarios.forEach(mapa => { + nombres.push(mapa.get("nombre")) +}) + +console.log(nombres) + +const nombresV2 = [] +usuariosV2.forEach(value => { + nombresV2.push(value["nombre"]) // value.nombre es lo mismo en este caso +}) +console.log(nombresV2) + +const nombresV3 = [...usuariosV3.values()].map(persona => persona.nombre) + +console.log(nombresV3) // 9. Dado el mapa anterior, obtén un array con los email de los usuarios mayores de edad y transfórmalo a un set +const emails = [] +usuarios.forEach(mapa => { + if(mapa.get("edad") >= 18){ + emails.push(mapa.get("email")) + } +}) +const emailsSet = new Set(emails) +console.log(emailsSet) + +const emails2 = [] +usuariosV2.forEach(persona => { + if(persona.edad >= 18) + emails2.push(persona.email) +}) +const emails2Set = new Set(emails2) +console.log(emails2Set) + +const emails3 = new Set(Array.from(usuariosV3).flat().filter(e => e instanceof Object && e.edad >= 18).map(e => e.email)) +console.log(emails3) +const emailsUnidos = new Set([...emailsSet, ...emails2Set, ...emails3]) +console.log(emailsUnidos) + +// 10. Transforma el mapa en un objeto, a continuación, transforma el objeto en un mapa con clave el email de cada usuario y como valor todos los datos del usuario +// 1 +console.log(usuarios) +const usuariosObj = {} +usuarios.forEach((usuario, idx) => { + usuariosObj[`${idx}`] = Object.fromEntries(usuario) +}) + +console.log(usuariosObj) +const usuariosPorEmail = new Map() +for(const prop in usuariosObj){ + usuariosPorEmail.set(usuariosObj[prop]["email"], usuariosObj[prop]) +} +console.log(usuariosPorEmail) + +// 2 +const usuariosObjV2 = Object.fromEntries(usuariosV2) +const usuariosPorEmailV2 = new Map() + +Object.values(usuariosObjV2).forEach(usuario => { + usuariosPorEmailV2.set(usuario.email, usuario) +}) +console.log(usuariosPorEmailV2) + +// 3 +const usuariosObjV3 = Object.fromEntries(usuariosV3) +const usuariosPorEmailV3 = new Map() -// 10. Transforma el mapa en un objeto, a continuación, transforma el objeto en un mapa con clave el email de cada usuario y como valor todos los datos del usuario \ No newline at end of file +Object.entries(usuariosObjV3).forEach(([k, v]) => { // realmente no ocupo la clave pero para usar Object.entries() + usuariosPorEmailV3.set(v["email"], v) +}) +console.log(usuariosPorEmailV3) \ No newline at end of file diff --git a/Intermediate/my_modules/counter.js b/Intermediate/my_modules/counter.js new file mode 100644 index 00000000..19ab2592 --- /dev/null +++ b/Intermediate/my_modules/counter.js @@ -0,0 +1,7 @@ +export default function* createCounter() { + let i = 0 + + while (true) { + yield ++i + } +} \ No newline at end of file diff --git a/Intermediate/my_modules/db.js b/Intermediate/my_modules/db.js new file mode 100644 index 00000000..4150fde0 --- /dev/null +++ b/Intermediate/my_modules/db.js @@ -0,0 +1,12 @@ +const usersDb = new Map() + +const insertUser = (key, name) => { + usersDb.set(key, name) + return { key, name } +} + +const getUser = (key) => usersDb.get(key) + +const getAllUsers = () => [...usersDb.entries()] + +export { insertUser, getUser, getAllUsers } \ No newline at end of file diff --git a/Intermediate/my_modules/vowel-deleter.js b/Intermediate/my_modules/vowel-deleter.js new file mode 100644 index 00000000..c329bedb --- /dev/null +++ b/Intermediate/my_modules/vowel-deleter.js @@ -0,0 +1,12 @@ +export default function deleteVowels(word) { + const vowels = new Set(["a", "e", "i", "o", "u"]) + const consonants = [] + + for (const character of word) { + if (!vowels.has(character.toLowerCase())) { + consonants.push(character.toUpperCase()) + } + } + + return consonants.join("") +} \ No newline at end of file diff --git a/Intermediate/package.json b/Intermediate/package.json new file mode 100644 index 00000000..96ae6e57 --- /dev/null +++ b/Intermediate/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/other-modules/others.mjs b/other-modules/others.mjs new file mode 100644 index 00000000..8e48506b --- /dev/null +++ b/other-modules/others.mjs @@ -0,0 +1,25 @@ +// Este modulo se creo con extension .mjs para indicar que es un modulo de ES6, +// aunque no es necesario si se especifica "type": "module" en el package.json +// Sin embargo, preferi usar .mjs porque ya hay un package.json +// el cual no tiene "type": "module" y no quiero cambiarlo para evitar posibles +// problemas de incompatibilidad con modulos CommonJS que pueda tener el proyecto +// y que no he visto aun (me falta explorar toda la carpeta Intermediate) + +class UserAge { + constructor(name, age) { + this.name = name + this.age = age + } + +} + +const users = [ + new UserAge("Cristofer", 24), + new UserAge("Montes", 25) +] + +function findUser(name) { + return users.find(u => u.name === name) +} + +export { UserAge, users, findUser } \ No newline at end of file