From c59e57ea113412a5d2b5db0a29bb607e52cd955e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Sat, 8 Jun 2019 12:21:25 -0500 Subject: [PATCH 01/25] feat(es.json): Include dictionary for Spanish --- i18n/es.json | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 i18n/es.json diff --git a/i18n/es.json b/i18n/es.json new file mode 100644 index 0000000..d1e2aeb --- /dev/null +++ b/i18n/es.json @@ -0,0 +1,50 @@ +{ + "title": "JAVASCRIPT FUNCIONAL ES GENIAL", + "subtitle": "\u001b[23mElige un ejercicio y oprime \u001b[3mEnter\u001b[23m para comenzar", + "common": { + "exercise": { + "fail": { + "missing_deps": "Necesitas instalar todas las dependencias que estés usando en tu solución (e.j. lodash)", + "module_not_found": "No se pudo encontrar tu archivo. Asegurate de que la ruta es correcta.", + "must_export_function": "Siempre deberías retornar una función usando el objeto module.exports." + }, + "input": "input: %s", + "submission": "sumisión: %s", + "solution": "solución: %s" + } + }, + "exercises": { + "Basic: Map": { + "didnt_use_map": "No usaste Array#map", + "used_map": "¡Sí! Usaste Array#map" + }, + "Basic: Every Some": { + "found_good_lists": "!Encontré %d buenas listas!" + }, + "Basic: Call": { + "matched_objects": "Encontrados %d de %d objetos validos de %d." + }, + "Higher Order Functions": { + "call_log": "La función se llamo %d veces." + }, + "Function Spies": { + "call_times": "El método fue llamado %d veces.", + "incorrect_return": "¡Verifica el valor de retorno de tu función!", + "incorrect_this": "¡Verifica el valor de `this` en tu función! Pista: Function#apply", + "not_all_args": "¡Verifica que estés pasando TODOS los argumentos! Pista: Function#apply", + "incorrect_count": "!Verifica que tu `Spy` esté contando las invocaciones del método correctamente!" + }, + "Trampoline": { + "intro": "Se repitió %d veces", + "result": "Se ejecuto exitosamente %d veces." + }, + "Async Loops": { + "all_loaded": "¡Todos los %d usuarios fueron cargados!", + "bad_result": "esperado: \n%s\n pero se recibió:\n%s", + "took_too_long": "¡Tomó demasiado tiempo!" + }, + "Currying": { + "five_words": "Este,problema,ha,sido,resuelto" + } + } +} From 4a6b4074b884ff875f05c43a6b8bee38ed7fc543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Tue, 11 Jun 2019 10:09:31 -0500 Subject: [PATCH 02/25] feat(README.md): Change to convention and add spanish translation --- README.es.md | 113 +++++++++++++++++++++++++++++++++++++++ Readme.md => README.md | 0 functional-javascript.js | 2 +- i18n/es.json | 4 +- 4 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 README.es.md rename Readme.md => README.md (100%) diff --git a/README.es.md b/README.es.md new file mode 100644 index 0000000..bcfee8e --- /dev/null +++ b/README.es.md @@ -0,0 +1,113 @@ +# Taller de Javascript Funcional + +[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/nodeschool/discussions?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +Discusiones de NodeSchool + +### Enseñando las propiedades fundamentales de Javascript Funcional. + +#### No se requieren librerías (e.j. sin `underscore`), tan solo ES5. + +
+ +
+ +[![Gittip](http://img.shields.io/gittip/timoxley.png)](https://www.gittip.com/timoxley/) + +## Misión + +Muchos recursos de aprendizaje de programación funcional te enseñarán como escribir código al estilo funcional, pero usualmente es altamente indirecto, profundamente abstraído, requiere el entendimiento de complejas relaciones entre llamados de librerías personalizadas y no representa la realidad de como la gente escribe realmente JavaScript. + +La meta de este taller es de crear problemas realistas que pueden ser resueltos usando JavaScript nativo y conciso. + +**Por favor lee los ejercicios cuidadosamente y sigue todas las instrucciones, están para ayudarte a aprender** + +## Instalación y actualización + +``` +$ npm install -g functional-javascript-workshop@latest +``` + +Algunas instalaciones de npm requieren el uso de `sudo` en el comando de arriba. Es recomendado en vez [re-instalar node/npm para que no necesites usar sudo](https://gist.github.com/isaacs/579814). + +## Instrucciones de uso + +#### 1. Elige el problema en el que quieras trabajar + +Una vez el taller está instalado, corre `functional-javascript-workshop` para imprimir en consola un menú donde puedas seleccionar un problema para trabajar. + +``` +$ functional-javascript-workshop +``` + +Los problemas están listados en un vago orden de dificultad. Se recomienda completarlos en orden, debido a que ejercicios posteriores serán resueltos por habilidades desarrolladas al resolver problemas previos. + +#### 2. Escribiendo tu solución + +Una vez has elegido un problema, el taller recordará en cual problema estás trabajando. Usando tu editor preferido, simplemente crea un archivo en el cual escribir tu solución. La mayoría de problemas proveerán algún contenido previo con el cual comenzar. Cópialo de la descripción del problema a tu archivo de solución. + +#### 3. Probando tu solución + +Usa el comando del taller `run` para apuntar el taller a tu archivo de solución. Tu solución será cargada y pasada a el proceso del problema. Esto usualmente no correrá ningún tipo de validación, simplemente mostrará el resultado del programa. + +``` +$ functional-javascript-workshop run misolucion.js +``` + +#### 4. Verificando tu solución + +Tu solución será verificada contra el resultado de la solución 'oficial'. Si todos los resultados concuerdan, ¡has solucionado el problema correctamente!. + +``` +$ functional-javascript-workshop verify misolucion.js +``` + +## ¿Problemas? + +Retroalimentación y recomendaciones son recibidas, por favor informa de tus problemas en [issues](https://github.com/timoxley/functional-javascript-workshop/issues). + +Reseñas completas [como esta](https://github.com/timoxley/functional-javascript-workshop/issues/7) son increíblemente útiles. ¡Más reseñas así por favor!. + +Estamos a la búsqueda de más problemas prácticos, así que si tienes un problema en tu día a día el cual fue solucionado simple y elegantemente con alguna técnica de JavaScript funcional, dejanos saber para crear un ejercicio en base a esta. + +## Pantallazos + +![screen shot 2013-09-27 at 5 18 45 pm](https://f.cloud.github.com/assets/43438/1225514/08c87a70-276a-11e3-8db7-485e3c760373.png) +![screen shot 2013-09-23 at 9 13 02 pm](https://f.cloud.github.com/assets/43438/1191466/f289f38a-2451-11e3-9ba5-a3c224b5ca97.png) + +## Recursos + +[Una colección en crecimiento de recursos sobre JavaScript funcional puede ser encontrada en la wiki](https://github.com/timoxley/functional-javascript-workshop/wiki). + +## Gracias rvagg + +Este tutorial fue construido usando el [framework de talleres](https://github.com/rvagg/workshopper) de rvagg. + +## Resumen + +``` + proyecto : functional-javascript + edad del repositorio : 2 años + activo : 50 días + commits : 152 + archivos : 70 + autores : + 69 Tim 45.4% + 67 Tim Oxley 44.1% + 3 Sequoia McDowell 2.0% + 2 ZJ 1.3% + 1 Naor Biton 0.7% + 1 Pavel Kornilov 0.7% + 1 Steve Teo 0.7% + 1 Wei Lu 0.7% + 1 Yoshua Wuyts 0.7% + 1 flakyfilibuster 0.7% + 1 Arvid Andersson 0.7% + 1 tim walker 0.7% + 1 Brendon Murphy 0.7% + 1 Lorcan Coyle 0.7% + 1 Matthew Hokanson 0.7% +``` + +## Licencia + +MIT diff --git a/Readme.md b/README.md similarity index 100% rename from Readme.md rename to README.md diff --git a/functional-javascript.js b/functional-javascript.js index 2c6edfa..56e4a7c 100755 --- a/functional-javascript.js +++ b/functional-javascript.js @@ -8,5 +8,5 @@ var path = require('path') Workshopper({ name : 'functional-javascript' , appDir : __dirname - , languages : ['en', 'fr', 'ko'] + , languages : ['en', 'fr', 'ko', 'es'] }) diff --git a/i18n/es.json b/i18n/es.json index d1e2aeb..c16e6a3 100644 --- a/i18n/es.json +++ b/i18n/es.json @@ -5,7 +5,7 @@ "exercise": { "fail": { "missing_deps": "Necesitas instalar todas las dependencias que estés usando en tu solución (e.j. lodash)", - "module_not_found": "No se pudo encontrar tu archivo. Asegurate de que la ruta es correcta.", + "module_not_found": "No se pudo encontrar tu archivo. Asegúrate de que la ruta es correcta.", "must_export_function": "Siempre deberías retornar una función usando el objeto module.exports." }, "input": "input: %s", @@ -36,7 +36,7 @@ }, "Trampoline": { "intro": "Se repitió %d veces", - "result": "Se ejecuto exitosamente %d veces." + "result": "Se ejecutó exitosamente %d veces." }, "Async Loops": { "all_loaded": "¡Todos los %d usuarios fueron cargados!", From 76bf3ea2e2bca7b92b1e65ca424f4951b36c8559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Tue, 11 Jun 2019 11:13:07 -0500 Subject: [PATCH 03/25] feat(async_loops): Spanish translation BREAKING CHANGE: Changed "boilerplate" to be "plantilla" --- README.es.md | 2 +- exercises/async_loops/problem.es.md | 51 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 exercises/async_loops/problem.es.md diff --git a/README.es.md b/README.es.md index bcfee8e..7bb75e2 100644 --- a/README.es.md +++ b/README.es.md @@ -43,7 +43,7 @@ Los problemas están listados en un vago orden de dificultad. Se recomienda comp #### 2. Escribiendo tu solución -Una vez has elegido un problema, el taller recordará en cual problema estás trabajando. Usando tu editor preferido, simplemente crea un archivo en el cual escribir tu solución. La mayoría de problemas proveerán algún contenido previo con el cual comenzar. Cópialo de la descripción del problema a tu archivo de solución. +Una vez has elegido un problema, el taller recordará en cual problema estás trabajando. Usando tu editor preferido, simplemente crea un archivo en el cual escribir tu solución. La mayoría de problemas proveerán algúna plantilla con la cual comenzar. Cópialo de la descripción del problema a tu archivo de solución. #### 3. Probando tu solución diff --git a/exercises/async_loops/problem.es.md b/exercises/async_loops/problem.es.md new file mode 100644 index 0000000..21ecb00 --- /dev/null +++ b/exercises/async_loops/problem.es.md @@ -0,0 +1,51 @@ +¡El código está roto! + +¡Un desarrollador Java ha subido su terrible código a nuestro proyecto y no lo probó! + +```js +function loadUsers(userIds, load, done) { + var users = []; + for (var i = 0; i < userIds.length; i++) { + users.push(load(userIds[i])); + } + return users; +} + +module.exports = loadUsers; +``` + +# Tarea + +¡Arregla este código! El callback debería ser llamado con todos los usuarios cargados. El orden de los usuarios debería concordar el order de los IDs cargados. Debido a que esta función es asíncrona, no nos importa el valor de retorno. + +## Parámetros + +- `userIds`: Un Array de IDs de usuario numéricos. +- `load`: Una función usada para cargar un objeto de tipo usuario. Recibe un ID numérico y un callback. El callback será llamado con el resultado de cargar el usuario con el ID provisto (puede ser un objeto usuario o `null`). +- `done`: Una función que recibe un Array de objetos usuario (como los devueltos en `load`). + +## Condiciones + +- No uses ciclos `for/while` (Array#forEach está bien). +- El orden de los resultados en `done` debe ser el mismo en el fueron especificados en `userIds`. +- Los usuarios deberían ser cargado es paralelo, e.j. todo el proceso no debería tomar más de un segundo. +- No crees ninguna función innecesaria, e.j. funciones auxiliares. + +## Pista + +- No necesitas organizar para mantener el orden. +- Usar `console.log` afectará la verificación. Solo usa `console.log` cuando corras `functional-javascript run`. + +## Plantilla + +```js +function loadUsers(userIds, load, done) { + var users = []; + for (var i = 0; i < userIds.length; i++) { + users.push(load(userIds[i])); + } + return users; +} + +module.exports = loadUsers; +``` From 0d80c7b3457e78c7d4ec3dcd76b66b8b71c34dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Tue, 11 Jun 2019 12:24:21 -0500 Subject: [PATCH 04/25] feat(basic_call): Spanish Translation --- exercises/basic_call/problem.es.md | 105 +++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 exercises/basic_call/problem.es.md diff --git a/exercises/basic_call/problem.es.md b/exercises/basic_call/problem.es.md new file mode 100644 index 0000000..8845dc0 --- /dev/null +++ b/exercises/basic_call/problem.es.md @@ -0,0 +1,105 @@ +JavaScript permite "duck typing", el cual es una forma de tipeado dinámico en el cual las propiedades y métodos de un objeto determinan la validez semántica, en vez de su herencia de una clase en particular o implementación de un interfaz en particular. El nombre del concepto se refiere al "duck test" (prueba de pato), atribuida a James Whitcomb Riley, el cual puede ser formulado así: + +> Cuando veo un ave que camina como un pato, nada como un pato y grazna como un pato, digo que esa ave es un pato. + +En JavaScript, para escribir programas robustos necesitamos revisar que un objeto es del tipo que necesitamos. + +Podemos usar `Object#hasOwnProperty` para saber si un objeto "tiene" una propiedad definida en si mismo (e.j. no heredada desde su prototipo): + +```js +var duck = { + quack: function() { + console.log("quack"); + } +}; + +duck.hasOwnProperty("quack"); // => true +``` + +Nosotros no le dimos a `duck` el método #hasOwnProperty, ¿de donde vino?. + +`duck` fue creado con la sintaxis de `{}`, y esta hereda de `Object.prototype`: + +```js +var object = { quack: true }; + +Object.getPrototypeOf(object) === Object.prototype; // => true +object.hasOwnProperty("quack"); // => true +``` + +¿Pero qué pasa si un objeto no hereda de `Object.prototype`?. + +```js +// crea un objeto con el prototipo de `null` +var object = Object.create(null); +object.quack = function() { + console.log("quack"); +}; + +Object.getPrototypeOf(object) === Object.prototype; // => false +Object.getPrototypeOf(object) === null; // => true + +object.hasOwnProperty("quack"); +// => TypeError: Object object has no method 'hasOwnProperty' +``` + +Aún podemos usar `hasOwnProperty` de `Object.prototype`, si lo llamamos con el valor de `this` con "algo similar a un objeto". `Function#call` nos permite llamar cualquiera función con valor de `this` alterado. + +```js +// el primer argumento se convierte en el valor de `this` +// el resto de los argumentos son pasados a la función + +Object.prototype.hasOwnProperty.call(object, "quack"); // => true +``` + +# Tarea: + +Escribe una función `duckCount` que retorne el numero de argumentos provistos que contienen una propiedad "quack" definida en ellos. No cuentes valores heredados de los prototipos. + +Ejemplo: + +```js +var notDuck = Object.create({ quack: true }); +var duck = { quack: true }; +duckCount(duck, notDuck); // 1 +``` + +## Argumentos + +- Se te proveerán de 0 a 20 argumentos. Cada argumento podría ser de cualquier tipo con cualquier propiedad. Algunos de estos tendrán una propiedad "quack". + +## Condiciones + +- No uses ciclos `for/while` o `Array#forEach`. +- No crees ninguna variable como contador/acumulador. +- No crees ninguna función innecesaria, e.j. funciones auxiliares. + +## Pista + +- La variable `arguments`, disponible en todas las funciones, es un _Object_ similar a un _Array_ de esta manera: + +```js +{ + 0: 'argument0', + 1: 'argument1', // etc + length: 2 +} +``` + +## Recursos + +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice#Array-like +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments + +## Plantilla + +```js +function duckCount() { + // TU SOLUCIÓN +} + +module.exports = duckCount; +``` From 3af01b402a7a3effff479f58b11e8028905a1526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Tue, 11 Jun 2019 12:35:06 -0500 Subject: [PATCH 05/25] feat(basic_every_some): Spanish Translation --- exercises/basic_every_some/problem.es.md | 48 ++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 exercises/basic_every_some/problem.es.md diff --git a/exercises/basic_every_some/problem.es.md b/exercises/basic_every_some/problem.es.md new file mode 100644 index 0000000..48beb36 --- /dev/null +++ b/exercises/basic_every_some/problem.es.md @@ -0,0 +1,48 @@ +# Tarea + +Retorna una función que tome una lista de usuarios validos, y retorna una función que retorne verdadero si todos los usuarios existen en la lista original de usuarios. + +Solo necesitas revisar que los IDs concuerden. + +## Ejemplo + +```js +var goodUsers = [{ id: 1 }, { id: 2 }, { id: 3 }]; + +// `checkUsersValid` es la función que definirás +var testAllValid = checkUsersValid(goodUsers); + +testAllValid([{ id: 2 }, { id: 1 }]); +// => true + +testAllValid([{ id: 2 }, { id: 4 }, { id: 1 }]); +// => false +``` + +## Argumentos + +- `goodUsers`: Una lista de usuarios validos. + +Usa `array#some` y `Array#every` para verificar que cada usuario pasado a tu función retornada existe en en el array pasado a la función exportada. + +## Condiciones + +- No uses ciclos `for/while` o `Array#forEach`. +- No crees ninguna función innecesaria, e.j. funciones auxiliares. + +## Recursos + +- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/every +- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some + +## Plantilla + +```js +function checkUsersValid(goodUsers) { + return function allUsersValid(submittedUsers) { + // TU SOLUCIÓN + }; +} + +module.exports = checkUsersValid; +``` From 9eb986c24de3c5187b66e5743016cf2e0f4140b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Tue, 11 Jun 2019 12:47:07 -0500 Subject: [PATCH 06/25] feat(basic_filter): Spanish Translation --- exercises/basic_filter/problem.es.md | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 exercises/basic_filter/problem.es.md diff --git a/exercises/basic_filter/problem.es.md b/exercises/basic_filter/problem.es.md new file mode 100644 index 0000000..60ed218 --- /dev/null +++ b/exercises/basic_filter/problem.es.md @@ -0,0 +1,50 @@ +# Tarea + +Usa `Array#filter` para escribir una función llamada `getShortMessages`. + +`getShortMessages` recibe un `array` de objetos con la propiedad `message` y retorna un `array` de mensajes que _tienen menos de 50 caracteres_. + +La función debería retornar un `array` conteniendo los mensajes _sin su objeto contenedor_. + +## Argumentos + +- mensajes: un `Array` de 10 a 100 objetos aleatorios que se ven algo así: + +```js +{ + message: "Esse id amet quis eu esse aute officia ipsum."; // aleatorio +} +``` + +## Condiciones + +- No uses ciclos `for/while` o `Array#forEach`. +- No crees ninguna función innecesaria, e.j. funciones auxiliares. + +## Pista + +- ¡Trata de encadenar algunos métodos de `Array`! + +## Ejemplo + +``` +[ 'Tempor quis esse consequat sunt ea eiusmod.', + 'Id culpa ad proident ad nulla laborum incididunt.', + 'Ullamco in ea et ad anim anim ullamco est.', + 'Est ut irure irure nisi.' ] +``` + +## Recursos + +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map + +## Plantilla + +```js +function getShortMessages(messages) { + // TU SOLUCIÓN +} + +module.exports = getShortMessages; +``` From d6f65180923c5536ef2f7ab5631536fe71026cf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Tue, 11 Jun 2019 13:27:45 -0500 Subject: [PATCH 07/25] feat(Excercises): Add files to be translated --- .../problem.es.md | 74 +++++++ .../problem.es.md | 85 ++++++++ exercises/basic_map/problem.es.md | 39 ++++ exercises/basic_recursion/problem.es.md | 68 ++++++ .../basic_recursion/solution_es/solution.js | 8 + exercises/basic_reduce/problem.es.md | 42 ++++ .../basic_reduce/solucion_es/solution.js | 8 + exercises/blocking_event_loop/problem.es.md | 34 +++ .../solution_es/solution.js | 18 ++ exercises/blocking_event_loop/wrapper_es.js | 47 ++++ exercises/currying/problem.es.md | 74 +++++++ exercises/function_call/problem.es.md | 68 ++++++ .../function_call/solution_es/solution.js | 13 ++ exercises/function_spies/problem.es.md | 41 ++++ .../function_spies/solution_es/solution.js | 19 ++ exercises/hello_world/problem.es.md | 17 ++ .../higher_order_functions/problem.es.md | 46 ++++ .../implement_map_with_reduce/problem.es.md | 42 ++++ .../problem.es.md | 41 ++++ .../problem.es.md | 110 ++++++++++ .../problem.es.md | 202 ++++++++++++++++++ exercises/recursion/problem.es.md | 54 +++++ exercises/trampoline/problem.es.md | 60 ++++++ 23 files changed, 1210 insertions(+) create mode 100644 exercises/basic_inheritance_with_objectcreate/problem.es.md create mode 100644 exercises/basic_inheritance_without_objectcreate/problem.es.md create mode 100644 exercises/basic_map/problem.es.md create mode 100644 exercises/basic_recursion/problem.es.md create mode 100644 exercises/basic_recursion/solution_es/solution.js create mode 100644 exercises/basic_reduce/problem.es.md create mode 100644 exercises/basic_reduce/solucion_es/solution.js create mode 100644 exercises/blocking_event_loop/problem.es.md create mode 100644 exercises/blocking_event_loop/solution_es/solution.js create mode 100644 exercises/blocking_event_loop/wrapper_es.js create mode 100644 exercises/currying/problem.es.md create mode 100644 exercises/function_call/problem.es.md create mode 100644 exercises/function_call/solution_es/solution.js create mode 100644 exercises/function_spies/problem.es.md create mode 100644 exercises/function_spies/solution_es/solution.js create mode 100644 exercises/hello_world/problem.es.md create mode 100644 exercises/higher_order_functions/problem.es.md create mode 100644 exercises/implement_map_with_reduce/problem.es.md create mode 100644 exercises/partial_application_with_bind/problem.es.md create mode 100644 exercises/partial_application_without_bind/problem.es.md create mode 100644 exercises/prototypical_inheritance_by_hand/problem.es.md create mode 100644 exercises/recursion/problem.es.md create mode 100644 exercises/trampoline/problem.es.md diff --git a/exercises/basic_inheritance_with_objectcreate/problem.es.md b/exercises/basic_inheritance_with_objectcreate/problem.es.md new file mode 100644 index 0000000..7ace3f5 --- /dev/null +++ b/exercises/basic_inheritance_with_objectcreate/problem.es.md @@ -0,0 +1,74 @@ +# Tarea + +Create a new "BetterUser" type that extends "User" by overriding the User's `.toString` method. + +Your exported function will be passed the constructor function for a "User" type that looks like this: + +```js +/** + * User Constructor. + * + * @param title {String} Title for User, e.g. 'Mr.', 'Mrs.', 'Dr.', etc. + * @param name {String} Name of User e.g. 'John Smith' + */ + +function User(title, name) { + this.title = title; + this.name = name; + console.info("NEW USER: " + this); +} + +/** + * Creates full display name for a user. + * @return {String} Display name + */ + +User.prototype.displayName = function() { + return this.title + " " + this.name; +}; + +/** + * @return {String} Formatted name & title + */ + +User.prototype.toString = function() { + return "[User:" + this.displayName() + "]"; +}; +``` + +Note: you do not need to copy this into your solution. + +## Ejemplo + +From your exported function, return a `BetterUser` constructor function that extends `User` with a custom `toString` method that works like so: + +```js +var joe = new BetterUser("Mr.", "Joe Smith"); // pass in title and name +console.log("Hello " + joe); // 'Hello [BetterUser: Mr. Joe Smith]' +``` + +## Condiciones + +- Don't call the User constructor unnecessarily! +- Don't use `__proto__` +- No crees ninguna función innecesaria, e.j. funciones auxiliares. + +## Recursos + +- http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/ +- http://tobyho.com/2011/11/11/js-object-inheritance/ +- http://hughfdjackson.com/javascript/2012/01/05/prototypes:-the-short%28est-possible%29-story/ + +## Plantilla + +```js +// User is a constructor +function upgradeUser(User) { + // EDIT THESE AS NECESSARY + function BetterUser() {} + + return BetterUser; +} + +module.exports = upgradeUser; +``` diff --git a/exercises/basic_inheritance_without_objectcreate/problem.es.md b/exercises/basic_inheritance_without_objectcreate/problem.es.md new file mode 100644 index 0000000..d212cb6 --- /dev/null +++ b/exercises/basic_inheritance_without_objectcreate/problem.es.md @@ -0,0 +1,85 @@ +# Tarea + +Do the exact same task as "Basic Inhertance with Object.create", except don't use Object.create! + +Details copied below for your reference. + +## Condiciones + +- Don't call the User constructor unnecessarily! +- Don't use `Object.create`. +- Don't use `__proto__` + +## Pista + +- Prototypes are always Objects +- Your `BetterUser` instances need to 'inherit' from `User.prototype` +- No reason you can't create dummy objects in the inheritance tree +- Understand what `Object.create` does. + +## Recursos + +- http://www.bennadel.com/blog/2184-Object-create-Improves-Constructor-Based-Inheritance-In-Javascript-It-Doesn-t-Replace-It.htm + +## Definición de tarea previa + +Create a "BetterUser" that extends "User" by overriding the User's `.toString` method. + +Your exported function will be passed the constructor function for a "User" type that looks like this: + +```js +/** + * User Constructor. + * + * @param title {String} Title for User, e.g. 'Mr.', 'Mrs.', 'Dr.', etc. + * @param name {String} Name of User e.g. 'John Smith' + */ + +function User(title, name) { + this.title = title; + this.name = name; + console.info("NEW USER: " + this); +} + +/** + * Creates full display name for a user. + * @return {String} Display name + */ + +User.prototype.displayName = function() { + return this.title + " " + this.name; +}; + +/** + * @return {String} Formatted name & title + */ + +User.prototype.toString = function() { + return "[User: " + this.displayName() + "]"; +}; +``` + +Note: you do not need to copy this into your solution. + +## Ejemplo + +From your exported function, return a `BetterUser` constructor function that extends `User` with a custom `toString` method that works like so: + +```js +var joe = new BetterUser("Mr.", "Joe Smith"); // pass in title and name +console.log("Hello " + joe); // 'Hello [BetterUser: Mr. Joe Smith]' +``` + +## Plantilla + +```js +// User is a constructor +function upgradeUser(User) { + // EDIT THESE AS NECESSARY + function BetterUser() {} + + return BetterUser; +} + +module.exports = upgradeuser; +``` diff --git a/exercises/basic_map/problem.es.md b/exercises/basic_map/problem.es.md new file mode 100644 index 0000000..8ba9dca --- /dev/null +++ b/exercises/basic_map/problem.es.md @@ -0,0 +1,39 @@ +# Tarea + +Convert the following code from a for-loop to Array#map: + +```js +function doubleAll(numbers) { + var result = []; + for (var i = 0; i < numbers.length; i++) { + result.push(numbers[i] * 2); + } + return result; +} + +module.exports = doubleAll; +``` + +## Argumentos + +- numbers: An Array of 0 to 20 Integers between 0 and 9 + +## Condiciones + +- Your solution should use Array.prototype.map() +- No uses ciclos `for/while` o `Array#forEach`. +- No crees ninguna función innecesaria, e.j. funciones auxiliares. + +## Recursos + +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map + +## Plantilla + +```js +function doubleAll(numbers) { + // TU SOLUCIÓN +} + +module.exports = doubleAll; +``` diff --git a/exercises/basic_recursion/problem.es.md b/exercises/basic_recursion/problem.es.md new file mode 100644 index 0000000..8bc2bda --- /dev/null +++ b/exercises/basic_recursion/problem.es.md @@ -0,0 +1,68 @@ +Recursion is a fundamental programming concept which can lead to elegant and efficient solutions to algorithmic problems. In fact, recursion is so powerful, all iterating behaviour can be defined using recursive functions. You will find recursion indispensable when iterating over nested data structures. + +A recursive function is a function which calls itself. For example, this recursive function will take an array of words, and return an array of those words, uppercased. + +```js +function toUpperArray(items) { + if (!items.length) return []; // end condition + var head = items[0]; // item to operate on + head = head.toUpperCase(); // perform action + var tail = items.slice(1); // next + return [head].concat(toUpperArray(tail)); // recursive step +} + +toUpperArray(["hello", "world"]); // => ['HELLO', 'WORLD'] +``` + +The point of this exercise is to familiarise yourself with recursion by implementing a familiar interface using a recursive function. + +# Tarea + +Implement Array#reduce using recursion. + +To test your reduction works correctly we will use your reduce implementation to execute our solution to the previous basic_reduce problem. i.e. your reduce function will be passed an array of words, and a function, and an initial value which will return an object containing the counts for each word found in the array. You don't need to implement this functionality, it will be supplied to your reduce implementation. + +For simplicity, your implementation of reduce **need not replicate the behaviour of a reduce missing an initial value**. You may assume the initial value will always be supplied. + +## Argumentos + +- arr: An Array to reduce over +- fn: Function to use as the reduction step. Like regular Array#reduce, this function must be passed previousValue, currentValue, index and the array we're iterating over. +- init: Initial value of the reduction. Unlike Array#reduce, this value is required (and you may assume it will always be supplied). + +## Ejemplo + +```js +// Your reduce function should behave the same as a +// regular Array#reduce, but it will take the array +// to operate on as the first argument: + +reduce( + [1, 2, 3], + function(prev, curr, index, arr) { + return prev + curr; + }, + 0 +); +// => 6 +``` + +## Condiciones + +- No uses ciclos `for/while` o `Array#forEach`. +- No uses ningún método de `Array` como `Array#map` o `Array#reduce` + +## Recursos + +- https://en.wikipedia.org/wiki/Recursion +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce + +## Plantilla + +```js +function reduce(arr, fn, initial) { + // TU SOLUCIÓN +} + +module.exports = reduce; +``` diff --git a/exercises/basic_recursion/solution_es/solution.js b/exercises/basic_recursion/solution_es/solution.js new file mode 100644 index 0000000..485507f --- /dev/null +++ b/exercises/basic_recursion/solution_es/solution.js @@ -0,0 +1,8 @@ +function reduce(arr, fn, initial) { + return (function reduceOne(index, value) { + if (index > arr.length - 1) return value // end condition + return reduceOne(index + 1, fn(value, arr[index], index, arr)) // calculate & pass values to next step + })(0, initial) // IIFE. kick off recursion with initial values +} + +module.exports = reduce diff --git a/exercises/basic_reduce/problem.es.md b/exercises/basic_reduce/problem.es.md new file mode 100644 index 0000000..e368390 --- /dev/null +++ b/exercises/basic_reduce/problem.es.md @@ -0,0 +1,42 @@ +# Tarea + +Given an Array of strings, use `Array#reduce` to create an object that contains the number of times each string occured in the array. Return the object directly (no need to console.log). + +## Ejemplo + +```js +var inputWords = ["Apple", "Banana", "Apple", "Durian", "Durian", "Durian"]; + +console.log(countWords(inputWords)); + +// => +// { +// Apple: 2, +// Banana: 1, +// Durian: 3 +// } +``` + +## Argumentos + +- inputWords: An array of random Strings. + +## Condiciones + +- Do not use any for/while loops or Array#forEach. +- No crees ninguna función innecesaria, e.j. funciones auxiliares. + +## Recursos + +- https://en.wikipedia.org/wiki/Reduce_(higher-order_function) +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce + +## Plantilla + +```js +function countWords(inputWords) { + // TU SOLUCIÓN +} + +module.exports = countWords; +``` diff --git a/exercises/basic_reduce/solucion_es/solution.js b/exercises/basic_reduce/solucion_es/solution.js new file mode 100644 index 0000000..13ebddf --- /dev/null +++ b/exercises/basic_reduce/solucion_es/solution.js @@ -0,0 +1,8 @@ +function countWords(arr) { + return arr.reduce(function(countMap, word) { + countMap[word] = ++countMap[word] || 1 // increment or initialize to 1 + return countMap + }, {}) // second argument to reduce initialises countMap to {} +} + +module.exports = countWords diff --git a/exercises/blocking_event_loop/problem.es.md b/exercises/blocking_event_loop/problem.es.md new file mode 100644 index 0000000..6ed3813 --- /dev/null +++ b/exercises/blocking_event_loop/problem.es.md @@ -0,0 +1,34 @@ +# Tarea + +Modify the recursive `repeat` function provided in the boilerplate, such that it does not block the event loop (i.e. Timers and IO handlers can fire). This necessarily requires repeat to be asynchronous. + +A timeout is queued to fire after 100 milliseconds, which will print the results of the test and exit the process. `repeat` should release control of the event loop to allow the timeout to interrupt before all of the operations complete. + +Try to perform as many operations as you can before the timeout fires! + +## Condiciones + +- Do not use any for/while loops or Array#forEach. +- No crees ninguna función innecesaria, e.j. funciones auxiliares. + +## Pista + +- If your program takes a long time to run, something is probably wrong. + Use Control - C to kill the node process. + +## Recursos + +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Timers + +## Plantilla + +```js +function repeat(operation, num) { + // modify this so it can be interrupted + if (num <= 0) return; + operation(); + return repeat(operation, --num); +} + +module.exports = repeat; +``` diff --git a/exercises/blocking_event_loop/solution_es/solution.js b/exercises/blocking_event_loop/solution_es/solution.js new file mode 100644 index 0000000..546f61a --- /dev/null +++ b/exercises/blocking_event_loop/solution_es/solution.js @@ -0,0 +1,18 @@ +function repeat(operation, num) { + if (num <= 0) return + + operation() + + // release control every 10 or so + // iterations. + // 10 is arbitrary. + if (num % 10 === 0) { + setTimeout(function() { + repeat(operation, --num) + }) + } else { + repeat(operation, --num) + } +} + +module.exports = repeat diff --git a/exercises/blocking_event_loop/wrapper_es.js b/exercises/blocking_event_loop/wrapper_es.js new file mode 100644 index 0000000..28750f5 --- /dev/null +++ b/exercises/blocking_event_loop/wrapper_es.js @@ -0,0 +1,47 @@ +'use strict' + +var path = require('path') + +var repeat = require(path.resolve(process.cwd(), process.argv[2])) + +var count = 0 +var CYCLES = 10000 + +function operation() { + for (var i = 0; i < 1000000; i++) { + // burn some CPU cycles + } + // count how many times this function was called + count++ +} + + +console.error() +console.error(operation.toString()) +console.error() +console.error('Trying to execute the above operation %d times, this may crash…', CYCLES) +console.error() +console.error('Press Ctrl+C to kill.') +console.error() + +var start = Date.now() +repeat(operation, CYCLES) + +setTimeout(function() { + var end = Date.now() + console.error('Performed %d operations.', count) + + if (count < 10) { + console.log('Fail! You should have completed some operations!') + process.exit(1) + } + + if (count >= CYCLES) { + console.log('Fail! Should not have completed all operations!') + process.exit(1) + } + + console.log('Operations successfully interrupted!') + console.error('Interrupted after %d milliseconds.', end - start) + process.exit() +}, 100) diff --git a/exercises/currying/problem.es.md b/exercises/currying/problem.es.md new file mode 100644 index 0000000..a5398ef --- /dev/null +++ b/exercises/currying/problem.es.md @@ -0,0 +1,74 @@ +This is an example implementation of `curry3`, which curries up to 3 arguments: + +```js +function curry3(fun) { + return function(one) { + return function(two) { + return function(three) { + return fun(one, two, three); + }; + }; + }; +} +``` + +If we were to use this implementation with this sample function: + +```js +function abc(one, two, three) { + return one / two / three; +} +``` + +It would work like so: + +```js +var curryC = curry3(abc); +var curryB = curryC(6); +var curryA = curryB(3); + +console.log(curryA(2)); // => 1 +``` + +# Tarea + +In this challenge, we're going to implement a 'curry' function for an arbitrary number of arguments. + +`curryN` will take two parameters: + +- fn: The function we want to curry. +- n: Optional number of arguments to curry. If not supplied, `curryN` should use the fn's arity as the value for `n`. + +## Ejemplo + +```js +function add3(one, two, three) { + return one + two + three; +} + +var curryC = curryN(add3); +var curryB = curryC(1); +var curryA = curryB(2); +console.log(curryA(3)); // => 6 +console.log(curryA(10)); // => 13 + +console.log(curryN(add3)(1)(2)(3)); // => 6 +``` + +## Condiciones + +- Do not use any for/while loops or `Array.prototype.forEach`. + +## Pista + +- You can detect the number of expected arguments to a function (it's arity) by checking a function's .length property. + +## Plantilla + +```js +function curryN(fn, n) { + // TU SOLUCIÓN +} + +module.exports = curryN; +``` diff --git a/exercises/function_call/problem.es.md b/exercises/function_call/problem.es.md new file mode 100644 index 0000000..b8aad95 --- /dev/null +++ b/exercises/function_call/problem.es.md @@ -0,0 +1,68 @@ +# Tarea + +Write a function that allows you to use `Array.prototype.slice` without using `slice.call` or `slice.apply` to invoke it. + +Normally you have to use `slice` with `call` or `apply`: + +```js +var slice = Array.prototype.slice + +function() { + var args = slice.call(arguments) // this works +} +``` + +We want this to work: + +```js +var slice = yourFunction + +function() { + var args = slice(arguments) // this works +} +``` + +## Ejemplo + +A function, `slice` that exhibits the following behaviour: + +```js +var nums = [1, 2, 3, 4, 5]; + +// your slice function should match the regular +// behaviour of slice, except it takes the array +// as the first argument + +slice(nums, 0, 2); // [1, 2] +slice(nums, 1, 2); // [2] + +// regular slice usage for comparison +nums.slice(0, 2); // [1, 2] +nums.slice(1, 2); // [2] +``` + +## Condiciones + +- Do not use any for/while loops or Array#forEach. +- Do not use the `function` keyword :D + +## Pista + +- This is absolutely a one liner. +- Every JavaScript Function inherits methods such as call, apply and bind from the object `Function.prototype`. +- Function#call executes the value of `this` when it is invoked. Inside `someFunction.call()`, the value of `this` will be `someFunction`. +- Function.call itself is a function thus it inherits from `Function.prototype` + +```js +function myFunction() { + console.log("called my function"); +} + +Function.prototype.call.call(myFunction); // => "called my function" +``` + +## Plantilla + +```js +module.exports = // your solution here! +``` diff --git a/exercises/function_call/solution_es/solution.js b/exercises/function_call/solution_es/solution.js new file mode 100644 index 0000000..29fa8f6 --- /dev/null +++ b/exercises/function_call/solution_es/solution.js @@ -0,0 +1,13 @@ +// Explained: +// The value of `this` in Function.call is the function +// that will be executed. +// +// Bind returns a new function with the value of `this` fixed +// to whatever was passed as its first argument. +// +// Every function 'inherits' from Function.prototype, +// thus every function, including call, apply and bind +// have the methods call apply and bind. +// +// Function.prototype.call === Function.call +module.exports = Function.call.bind(Array.prototype.slice) diff --git a/exercises/function_spies/problem.es.md b/exercises/function_spies/problem.es.md new file mode 100644 index 0000000..1897b15 --- /dev/null +++ b/exercises/function_spies/problem.es.md @@ -0,0 +1,41 @@ +# Tarea + +Override a specified method of an object with new functionality while still maintaining all of the old behaviour. + +Create a spy that keeps track of how many times a function is called. + +## Ejemplo + +```js +var spy = Spy(console, "error"); + +console.error("calling console.error"); +console.error("calling console.error"); +console.error("calling console.error"); + +console.log(spy.count); // 3 +``` + +## Argumentos + +- target: an object containing the method `method` +- method: a string with the name of the method on `target` to spy on. + +## Condiciones + +- Do not use any for/while loops or Array#forEach. +- No crees ninguna función innecesaria, e.j. funciones auxiliares. + +## Pista + +- Functions have context, input and output. Make sure you consider the context, input to _and output from_ the function you are spying on. + +## Plantilla + +```js +function Spy(target, method) { + // TU SOLUCIÓN +} + +module.exports = Spy; +``` diff --git a/exercises/function_spies/solution_es/solution.js b/exercises/function_spies/solution_es/solution.js new file mode 100644 index 0000000..04af6ec --- /dev/null +++ b/exercises/function_spies/solution_es/solution.js @@ -0,0 +1,19 @@ +function Spy(target, method) { + var originalFunction = target[method] + + // use an object so we can pass by reference, not value + // i.e. we can return result, but update count from this scope + var result = { + count: 0 + } + + // replace method with spy method + target[method] = function() { + result.count++ // track function was called + return originalFunction.apply(this, arguments) // invoke original function + } + + return result +} + +module.exports = Spy diff --git a/exercises/hello_world/problem.es.md b/exercises/hello_world/problem.es.md new file mode 100644 index 0000000..2298712 --- /dev/null +++ b/exercises/hello_world/problem.es.md @@ -0,0 +1,17 @@ +# Tarea + +Write a function that takes an input string and returns it uppercased. + +## Argumentos + +- input: a String of random words (lorem ipsum). + +## Plantilla + +```js +function upperCaser(input) { + // TU SOLUCIÓN +} + +module.exports = upperCaser; +``` diff --git a/exercises/higher_order_functions/problem.es.md b/exercises/higher_order_functions/problem.es.md new file mode 100644 index 0000000..fbd3b6a --- /dev/null +++ b/exercises/higher_order_functions/problem.es.md @@ -0,0 +1,46 @@ +A higher-order function is a function that does at least one of the following: + +- Take one or more functions as an input +- Output a function + +All other functions are first order functions. [1] + +Unlike many other languages with imperative features, JavaScript allows you to utilize higher-order functions because it has "first-class functions". This means functions can be treated just like any other value in JavaScript: just like Strings or Numbers, Function values can be stored as variables, properties on objects or passed to other functions as arguments. Function values are actually Objects (inheriting from `Function.prototype`) so you can even add properties and store values on them, just like any regular Object. + +The key difference between Functions and other value types in JavaScript is the call syntax: if a reference to a function is followed by parenthesis and some optional comma-separated values: `someFunctionValue(arg1, arg2, etc)`, then the function body will be executed with the supplied arguments (if any). + +In this exercise we're going to demonstrate that functions can be passed as values by passing you a function as an argument. + +# Tarea + +Implement a function that takes a function as its first argument, a number `num` as its second argument, then executes the passed in function `num` times. + +Use the boilerplate code given to you below to get started. Most/all future exercises will provide boilerplate. + +## Argumentos + +- operation: A Function, takes no arguments, returns no useful value. +- num: the number of times to call `operation` + +## Recursos + +- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions_and_function_scope +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype + +## Pista + +- Don't overthink it, the code should be rather simple. +- It's ok to use a loop in your implementation, bonus points if you use recursion instead. +- You may notice some output. That is coming from the function we passed you. +- You do not need to console.log anything. + +## Plantilla + +```js +function repeat(operation, num) { + // TU SOLUCIÓN +} + +// Do not remove the line below +module.exports = repeat; +``` diff --git a/exercises/implement_map_with_reduce/problem.es.md b/exercises/implement_map_with_reduce/problem.es.md new file mode 100644 index 0000000..2b8695b --- /dev/null +++ b/exercises/implement_map_with_reduce/problem.es.md @@ -0,0 +1,42 @@ +# Tarea + +Use Array#reduce to implement a simple version of Array#map. + +## Resultado esperado + +A function `map` that applies a function to each item in an array and collects the results in a new Array. + +```js +var nums = [1, 2, 3, 4, 5]; + +// `map` is your exported function +var output = map(nums, function double(item) { + return item * 2; +}); + +console.log(output); // => [2,4,6,8,10] +``` + +## Argumentos + +- input: an arbitrary Array of any type. +- operation: an arbitrary Function which can be applied to items in `input`. + +## Pista + +- No need to implement the optional `thisArg` argument of `Array.prototype.map`, bonus points if you do! + +## Recursos + +- https://en.wikipedia.org/wiki/Reduce_(higher-order_function) +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce + +## Plantilla + +```js +function arrayMap(arr, fn) { + //SOLUTION GOES HERE +} + +module.exports = arrayMap; +``` diff --git a/exercises/partial_application_with_bind/problem.es.md b/exercises/partial_application_with_bind/problem.es.md new file mode 100644 index 0000000..7551071 --- /dev/null +++ b/exercises/partial_application_with_bind/problem.es.md @@ -0,0 +1,41 @@ +# Tarea + +**Use Function#bind** to implement a logging function that allows you to namespace messages. + +Your implementation should take a namespace string, and return a function that prints messages to the console with the namespace prepended. + +Make sure _all_ arguments passed to the returned logging function are printed. + +** Print the output to the console directly ** + +## Argumentos + +- namespace: a String to prepend to each message passed to the returned function. + +## Ejemplo + +```js +var info = logger("INFO:"); +info("this is an info message"); +// INFO: this is an info message + +var warn = logger("WARN:"); +warn("this is a warning message", "with more info"); +// WARN: this is a warning message with more info +``` + +## Condiciones + +- Use Function#bind + +## Plantilla + +```js +module.exports = function(namespace) { + // TU SOLUCIÓN +}; +``` + +## Recursos + +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind diff --git a/exercises/partial_application_without_bind/problem.es.md b/exercises/partial_application_without_bind/problem.es.md new file mode 100644 index 0000000..015cd98 --- /dev/null +++ b/exercises/partial_application_without_bind/problem.es.md @@ -0,0 +1,110 @@ +Partial application allows you to create new functions from existing functions, while fixing some number of arguments. After setting the arguments to be partially applied, you get a new function ready to take the rest of the arguments and perhaps execute the original function. + +More formally: Partial application refers to the process of fixing a number of arguments to a function, producing another function of smaller arity. + +As an example, say we have a function `add`, that takes 2 arguments and adds them together: + +```js +function add(x, y) { + return x + y; +} + +add(10, 20); // => 30 +``` + +Now, pretend we have a function `partiallyApply`. `partiallyApply` takes a function, and some arguments to 'partially apply'. + +Here we 'partially apply' the first parameter, `x`, of our `add` function: + +```js +var addTen = partiallyApply(add, 10); // fix `x` to 10 +``` + +`addTen` is a new function that takes the `y` parameter of `add`. `add` has not yet been called! + +Once we pass the argument for `y`, we can execute the original `add` function: + +```js +addTen(20); // => 30 +addTen(100); // => 110 +addTen(0); // => 10 + +// etc +``` + +All of the above examples are same as calling `add(10, y)`, where `y` was supplied in the call to the appropriately named `addTen`. + +# Tarea + +Use partial application to create a function that fixes the first argument to `console.log`. i.e. Implement a logging function that prepends a namespace string to its output. + +Your implementation should take a namespace String and return a function that prints messages to the console with the namespace prepended. + +You should use `Function#apply` to implement the partial application. + +Make sure _all_ arguments passed to the returned logging function are printed. + +** Print the output to the console directly ** + +## Argumentos + +- namespace: a String to prepend to each message passed to the returned function. + +## Ejemplo + +```js +var info = logger("INFO:"); +info("this is an info message"); +// INFO: this is an info message + +var warn = logger("WARN:"); +warn("this is a warning message", "with more info"); +// WARN: this is a warning message with more info +``` + +## Condiciones + +- Do not use Function#bind +- Use Function#apply + +## Plantilla + +```js +var slice = Array.prototype.slice; + +function logger(namespace) { + // TU SOLUCIÓN +} + +module.exports = logger; +``` + +## Recursos + +- https://en.wikipedia.org/wiki/Partial_application +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply + +## Pista + +Remember `console.log` takes any number of arguments and prints them, separated by spaces: + +```js +console.log("hello", "world"); // => 'hello world' +console.log(1, 2, 3); // => 1 2 3 +``` + +We simply want to 'partially apply' the first argument to `console.log`. + +`Function.prototype.apply` allows us to execute a function, supply a new 'value for this' (we can ignore in this case), and then _an array of arguments to apply to the function_: + +```js +add(10, 20); // => 30 +add.apply(null, [10, 20]); // => 30 +``` + +Also contrast `apply` with `Function.prototype.call`: + +```js +add.apply(null, [10, 20]); // => 30 +add.call(null, 10, 20); // => 30 +``` diff --git a/exercises/prototypical_inheritance_by_hand/problem.es.md b/exercises/prototypical_inheritance_by_hand/problem.es.md new file mode 100644 index 0000000..4376b0f --- /dev/null +++ b/exercises/prototypical_inheritance_by_hand/problem.es.md @@ -0,0 +1,202 @@ +We're going to implement a rough analog of JavaScript's prototypical inheritance by hand, to ensure we fully understand exactly how prototypical inheritance fits together. + +# Tarea + +Implement the functions `New`, `Create` and `Lookup` to simulate JavaScript's `new`, `Object.create` and property lookup mechanisms respectively. + +Throughout this exercise, you will avoid using any built-in JavaScript inheritance features. Instead, you will need to use your own New, Create and Lookup functions as well as `__PROTO__` to represent an instance's prototype, and `PROTOTYPE` to represent a constructor's prototype. + +i.e. + +- New(Apple, 1,2,3) == new Apple(1,2,3) +- `obj.__PROTO__` == obj.**proto** || Object.getPrototypeOf(obj) +- `Constructor.PROTOTYPE` == `Constructor.prototype` + +## Parte 1: Lookup + +`Lookup` will simulate the behaviour of JavaScript's property lookup mechanism, or "Getters". When you reference any object's property in JavaScript, it will 'walk up the prototype chain' to find the property, if found it will return its value, otherwise it will return `undefined`. + +Your `Lookup` function will be passed a context object, and the property String that we're looking for. If the property is found on the current context, return that property, otherwise check the context's prototype, `__PROTO__`. + +If a property cannot be found in the object's prototype chain, simply return `undefined`. + +```js +var cat = { + color: "black" +}; + +var kitten = { + size: "small" +}; + +var otherKitten = { + size: "small", + color: "grey" +}; + +kitten.__PROTO__ = cat; +otherKitten.__PROTO__ = cat; + +Lookup(kitten, "color"); // => 'black' +Lookup(otherKitten, "color"); // => 'grey' + +Lookup(kitten, "wings"); // => undefined + +// changing properties on the prototype should +// affect any instances that inherit from it. +cat.color = "blue"; + +Lookup(kitten, "color"); // => 'blue' + +// overridden properties should still work +Lookup(otherKitten, "color"); // => 'grey' +``` + +Side Note: in JavaScript, when you 'get' a property (i.e. lookup), the engine walks up the prototype chain to find the value, but if you 'set' a property it ignores the prototype chain and simply sets the value on the current object. We could have implemented a 'Setter' as an exercise, but since there's no magic, it's pretty trivial: + +```js +function Setter(context, property, value) { + return (context[property] = value); +} +``` + +## Parte 2: Create + +`Create` will simulate the behaviour of `Object.create`. + +`Create` will be passed an object, and you must return a new object with its prototype (`__PROTO__`) set to the supplied object. + +```js +fuction Cat() { + +} + +Cat.PROTOTYPE.speak = function() { + return 'Meow!' +} + +function Kitten() { + Cat.apply(this, arguments) +} + +Kitten.PROTOTYPE = Create(Cat.PROTOTYPE) + +var kitten = New(Kitten) +Lookup(kitten, 'speak')() // => 'Meow!' + +``` + +## Finale: New + +`New` will simulate the behaviour of JavaScript's `new` keyword. + +The first argument passed to `New` will be a constructor function (i.e. a type). Subsequent parameters must be passed to the constructor function when creating the the new object. + +`New` will return new objects using the supplied constructor function. + +```js +function Cat(color) { + this.color = color; +} + +var blackCat = New(Cat, "black"); +blackCat.color; // => black + +var brownCat = New(Cat, "brown"); +brownCat.color; // => brown +``` + +The constructor function passed to `New` may have a `.PROTOTYPE` property. All objects created with this constructor will have their `__PROTO__` set to the constructor's `.PROTOTYPE` property. + +```js +function Cat(color) { + this.color = color; +} + +Cat.PROTOTYPE.speak = function() { + return "Meow!"; +}; + +function Kitten() { + Cat.apply(this, arguments); +} + +Kitten.PROTOTYPE = Create(Cat); + +Kitten.PROTOTYPE.speak = function() { + return "Mew."; +}; + +var blackCat = New(Cat, "black"); +blackCat.color; // => black + +var brownCat = New(Cat, "brown"); +brownCat.color; // => brown +``` + +Prototype properties should be available in the constructor: + +```js +function Cow() { + // lookup this.moo: + console.log("moo", Lookup(this, "moo")); +} + +// this step is done for you automatically in 'real' javascript. +Cow.PROTOTYPE = {}; + +Cow.PROTOTYPE.moo = true; +var cow = New(Cow); // 'moo' true +``` + +We also need to simulate one other behaviour of the `new` keyword: If the constructor itself returns a value, `New` will return that value. + +```js +function Cat() { + return 3; +} +var cat = new Cat(); // 3 +var cat = New(Cat); // 3 +``` + +## Condiciones + +- Do not use any built-in javascript prototypical inheritance features. +- Do not call `new` +- Do not use `__proto__`, `Object.getPrototypeOf` or `Object.setPrototypeOf` + +## Pista + +- Use `hasOwnProperty` to discover if an object has a property. + +## Plantilla + +```js +/** + * @param context {Object} Initial object to start searching for `property` + * @param property {String} name of property we are trying to locate. + * @return {Mixed} The value of `property` in `context` or somewhere in its prototype chain. + */ + +function Lookup(context, property) {} + +/** + * @param proto {Object} The prototype to use for the created object. + * @return A new Object whose prototype is set to `proto` + */ + +function Create(proto) {} + +/** + * @param Constructor {Function} Constructor for a new type. + * @return new instance of the type defined by `Constructor`. + */ + +function New(Constructor) {} + +module.exports = { + Lookup: Lookup, + Create: Create, + New: New +}; +``` diff --git a/exercises/recursion/problem.es.md b/exercises/recursion/problem.es.md new file mode 100644 index 0000000..e21cc6d --- /dev/null +++ b/exercises/recursion/problem.es.md @@ -0,0 +1,54 @@ +# Tarea + +Implement a recursive function that returns all of the unique dependencies, and sub-dependencies of a module, sorted alphabetically. Dependencies should be printed as dependency@version e.g. 'inflection@1.2.6'. + +Multiple versions of the same module are allowed, but duplicates modules of the same version should be removed. + +## Argumentos: + +- tree: A dependency tree. See below for an example of the structure. + +## Ejemplo + +```js +var loremIpsum = { + name: "lorem-ipsum", + version: "0.1.1", + dependencies: { + optimist: { + version: "0.3.7", + dependencies: { + wordwrap: { + version: "0.0.2" + } + } + }, + inflection: { + version: "1.2.6" + } + } +}; + +getDependencies(loremIpsum); // => [ 'inflection@1.2.6', 'optimist@0.3.7', 'wordwrap@0.0.2' ] +``` + +## Condiciones: + +- No uses ciclos `for/while` o `Array#forEach`. + +## Plantilla + +```js +function getDependencies(tree) { + // TU SOLUCIÓN + // Note: Feel free to add additional arguments + // to this function for use with recursive calls. + // Or not! There are many ways to recurse. +} + +module.exports = getDependencies; +``` + +## Recursos + +- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys diff --git a/exercises/trampoline/problem.es.md b/exercises/trampoline/problem.es.md new file mode 100644 index 0000000..7396226 --- /dev/null +++ b/exercises/trampoline/problem.es.md @@ -0,0 +1,60 @@ +The boilerplate includes a definition of `repeat`. `repeat` will take a Function operation, and a Number num, and invoke operation num times: + +```js +var count = 0; +repeat(function() { + count++; +}, 100); + +console.log("executed %d times.", count); +// => executed 100 times. +``` + +BUT note that executing `repeat` with a large `num` causes a stack overflow: + +``` +var count = 0 +repeat(function() { + count++ +}, 100000) + +console.log('executed %d times', count) +// => RangeError: Maximum call stack size exceeded +``` + +# Tarea + +Modify the boilerplate below such that it uses a trampoline to continuously call itself synchronously. + +You can assume that the operation passed to repeat does not take arguments (or they are already bound to the function) and the return value is not important. + +## Condiciones + +- Do not change the implementation of repeat to include any loops + (you may change it in other ways though). + +## Pista + +- Modify `repeat` so it returns the 'next step', if there is one. +- A trampoline continues to synchronously execute steps, getting new steps, until there are no more steps. You can use a loop here! +- If your program takes a long time to run, something is probably wrong. Use Control - C to kill the node process. + +## Plantilla + +```js +function repeat(operation, num) { + // Modify this so it doesn't cause a stack overflow! + if (num <= 0) return; + operation(); + return repeat(operation, --num); +} + +function trampoline(fn) { + // You probably want to implement a trampoline! +} + +module.exports = function(operation, num) { + // You probably want to call your trampoline here! + return repeat(operation, num); +}; +``` From 497732e1a0f9e6429ee97d35748afe643263f69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Tue, 11 Jun 2019 14:04:20 -0500 Subject: [PATCH 08/25] feat(basic_inheritance_with_objectcreate): Spanish translation --- .../problem.es.md | 32 +++++++++---------- .../problem.es.md | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/exercises/basic_inheritance_with_objectcreate/problem.es.md b/exercises/basic_inheritance_with_objectcreate/problem.es.md index 7ace3f5..1d3fde9 100644 --- a/exercises/basic_inheritance_with_objectcreate/problem.es.md +++ b/exercises/basic_inheritance_with_objectcreate/problem.es.md @@ -1,15 +1,15 @@ # Tarea -Create a new "BetterUser" type that extends "User" by overriding the User's `.toString` method. +Crea un nuevo tipo "BetterUser" que extienda "User" y sobreescribe el método `.toString` de "User". -Your exported function will be passed the constructor function for a "User" type that looks like this: +La función que exportes será pasada a la función del constructor de "User" que se verá así: ```js /** - * User Constructor. + * Constructor de User. * - * @param title {String} Title for User, e.g. 'Mr.', 'Mrs.', 'Dr.', etc. - * @param name {String} Name of User e.g. 'John Smith' + * @param title {String} Prefijo para el Usuario. e.j: "Sr", "Sra", "Srta", etc. + * @param name {String} Nombre del Usuario. e.g: 'Pepito Peréz'. */ function User(title, name) { @@ -19,8 +19,8 @@ function User(title, name) { } /** - * Creates full display name for a user. - * @return {String} Display name + * Crea un nombre completo para un usuario. + * @return {String} Nombre a mostrar */ User.prototype.displayName = function() { @@ -28,7 +28,7 @@ User.prototype.displayName = function() { }; /** - * @return {String} Formatted name & title + * @return {String} Prefijo y nombre formateado. */ User.prototype.toString = function() { @@ -36,21 +36,21 @@ User.prototype.toString = function() { }; ``` -Note: you do not need to copy this into your solution. +Notas: No necesitas copiar esto en tu solución. ## Ejemplo -From your exported function, return a `BetterUser` constructor function that extends `User` with a custom `toString` method that works like so: +De tu función exportada, retorna un función constructora `BetterUser` que extienda `User` con un método personalizado `toString` que funcione de esta manera: ```js -var joe = new BetterUser("Mr.", "Joe Smith"); // pass in title and name -console.log("Hello " + joe); // 'Hello [BetterUser: Mr. Joe Smith]' +var joe = new BetterUser("Sr.", "Elver Mires"); // pasa prefijo y nombre +console.log("Hola " + joe); // 'Hola [BetterUser: Sr. Elver Mires]' ``` ## Condiciones -- Don't call the User constructor unnecessarily! -- Don't use `__proto__` +- ¡No llames el constructor de `User` innecesariamente! +- No uses `__proto__` - No crees ninguna función innecesaria, e.j. funciones auxiliares. ## Recursos @@ -62,9 +62,9 @@ console.log("Hello " + joe); // 'Hello [BetterUser: Mr. Joe Smith]' ## Plantilla ```js -// User is a constructor +// User es un constructor function upgradeUser(User) { - // EDIT THESE AS NECESSARY + // EDITA ESTO CUANTO NECESITES function BetterUser() {} return BetterUser; diff --git a/exercises/basic_inheritance_without_objectcreate/problem.es.md b/exercises/basic_inheritance_without_objectcreate/problem.es.md index d212cb6..e2694ff 100644 --- a/exercises/basic_inheritance_without_objectcreate/problem.es.md +++ b/exercises/basic_inheritance_without_objectcreate/problem.es.md @@ -75,7 +75,7 @@ console.log("Hello " + joe); // 'Hello [BetterUser: Mr. Joe Smith]' ```js // User is a constructor function upgradeUser(User) { - // EDIT THESE AS NECESSARY + // EDITA ESTO CUANTO NECESITES function BetterUser() {} return BetterUser; From 8ef7f8772f8386b55f10fda12a301623f957b541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Tue, 11 Jun 2019 14:17:51 -0500 Subject: [PATCH 09/25] feat(basic_inheritance_without_objectcreate): Spanish translation Fixed: Typo --- .../problem.es.md | 48 +++++++++---------- .../problem.md | 45 ++++++++--------- 2 files changed, 45 insertions(+), 48 deletions(-) diff --git a/exercises/basic_inheritance_without_objectcreate/problem.es.md b/exercises/basic_inheritance_without_objectcreate/problem.es.md index e2694ff..fcb721b 100644 --- a/exercises/basic_inheritance_without_objectcreate/problem.es.md +++ b/exercises/basic_inheritance_without_objectcreate/problem.es.md @@ -1,21 +1,21 @@ # Tarea -Do the exact same task as "Basic Inhertance with Object.create", except don't use Object.create! +Haz la misma tarea que en "Basic Inhertance with Object.create", pero no uses `Object.create`! -Details copied below for your reference. +Los detalles están abajo para tu referencia. ## Condiciones -- Don't call the User constructor unnecessarily! -- Don't use `Object.create`. -- Don't use `__proto__` +- ¡No llames el constructor de `User` innecesariamente!. +- No uses `Object.create`. +- No uses `__proto__`. ## Pista -- Prototypes are always Objects -- Your `BetterUser` instances need to 'inherit' from `User.prototype` -- No reason you can't create dummy objects in the inheritance tree -- Understand what `Object.create` does. +- Los prototipos siempre son objetos. +- Tus instancias de `BetterUser` necesitan "heredar" de `User.prototype` +- No hay razon por la que no puedas crear objetos de prueba en arbol de herencia. +- Entiende que es lo que `Object.create` hace. ## Recursos @@ -23,16 +23,16 @@ Details copied below for your reference. ## Definición de tarea previa -Create a "BetterUser" that extends "User" by overriding the User's `.toString` method. +Crea un nuevo tipo "BetterUser" que extienda "User" y sobreescribe el método `.toString` de "User". -Your exported function will be passed the constructor function for a "User" type that looks like this: +La función que exportes será pasada a la función del constructor de "User" que se verá así: ```js /** - * User Constructor. + * Constructor de User. * - * @param title {String} Title for User, e.g. 'Mr.', 'Mrs.', 'Dr.', etc. - * @param name {String} Name of User e.g. 'John Smith' + * @param title {String} Prefijo para el Usuario. e.j: "Sr", "Sra", "Srta", etc. + * @param name {String} Nombre del Usuario. e.g: 'Pepito Peréz'. */ function User(title, name) { @@ -42,8 +42,8 @@ function User(title, name) { } /** - * Creates full display name for a user. - * @return {String} Display name + * Crea un nombre completo para un usuario. + * @return {String} Nombre a mostrar */ User.prototype.displayName = function() { @@ -51,29 +51,29 @@ User.prototype.displayName = function() { }; /** - * @return {String} Formatted name & title + * @return {String} Prefijo y nombre formateado. */ User.prototype.toString = function() { - return "[User: " + this.displayName() + "]"; + return "[User:" + this.displayName() + "]"; }; ``` -Note: you do not need to copy this into your solution. +Notas: No necesitas copiar esto en tu solución. ## Ejemplo -From your exported function, return a `BetterUser` constructor function that extends `User` with a custom `toString` method that works like so: +De tu función exportada, retorna un función constructora `BetterUser` que extienda `User` con un método personalizado `toString` que funcione de esta manera: ```js -var joe = new BetterUser("Mr.", "Joe Smith"); // pass in title and name -console.log("Hello " + joe); // 'Hello [BetterUser: Mr. Joe Smith]' +var joe = new BetterUser("Sr.", "Elver Mires"); // pasa prefijo y nombre +console.log("Hola " + joe); // 'Hola [BetterUser: Sr. Elver Mires]' ``` ## Plantilla ```js -// User is a constructor +// User es un constructor function upgradeUser(User) { // EDITA ESTO CUANTO NECESITES function BetterUser() {} @@ -81,5 +81,5 @@ function upgradeUser(User) { return BetterUser; } -module.exports = upgradeuser; +module.exports = upgradeUser; ``` diff --git a/exercises/basic_inheritance_without_objectcreate/problem.md b/exercises/basic_inheritance_without_objectcreate/problem.md index 40c8ca0..1e31247 100644 --- a/exercises/basic_inheritance_without_objectcreate/problem.md +++ b/exercises/basic_inheritance_without_objectcreate/problem.md @@ -1,25 +1,25 @@ # Task -Do the exact same task as "Basic Inhertance with Object.create", except don't use Object.create! +Do the exact same task as "Basic Inheritance with Object.create", except don't use Object.create! Details copied below for your reference. ## Conditions -* Don't call the User constructor unnecessarily! -* Don't use `Object.create`. -* Don't use `__proto__` +- Don't call the User constructor unnecessarily! +- Don't use `Object.create`. +- Don't use `__proto__` ## Hints -* Prototypes are always Objects -* Your `BetterUser` instances need to 'inherit' from `User.prototype` -* No reason you can't create dummy objects in the inheritance tree -* Understand what `Object.create` does. +- Prototypes are always Objects +- Your `BetterUser` instances need to 'inherit' from `User.prototype` +- No reason you can't create dummy objects in the inheritance tree +- Understand what `Object.create` does. ## Resources -* http://www.bennadel.com/blog/2184-Object-create-Improves-Constructor-Based-Inheritance-In-Javascript-It-Doesn-t-Replace-It.htm +- http://www.bennadel.com/blog/2184-Object-create-Improves-Constructor-Based-Inheritance-In-Javascript-It-Doesn-t-Replace-It.htm ## Previous Task Definition @@ -36,9 +36,9 @@ Your exported function will be passed the constructor function for a "User" type */ function User(title, name) { - this.title = title - this.name = name - console.info('NEW USER: ' + this) + this.title = title; + this.name = name; + console.info("NEW USER: " + this); } /** @@ -47,16 +47,16 @@ function User(title, name) { */ User.prototype.displayName = function() { - return this.title + ' ' + this.name -} + return this.title + " " + this.name; +}; /** * @return {String} Formatted name & title */ User.prototype.toString = function() { - return '[User: '+this.displayName()+']' -} + return "[User: " + this.displayName() + "]"; +}; ``` Note: you do not need to copy this into your solution. @@ -66,8 +66,8 @@ Note: you do not need to copy this into your solution. From your exported function, return a `BetterUser` constructor function that extends `User` with a custom `toString` method that works like so: ```js -var joe = new BetterUser('Mr.', 'Joe Smith') // pass in title and name -console.log('Hello ' + joe) // 'Hello [BetterUser: Mr. Joe Smith]' +var joe = new BetterUser("Mr.", "Joe Smith"); // pass in title and name +console.log("Hello " + joe); // 'Hello [BetterUser: Mr. Joe Smith]' ``` ## Boilerplate @@ -75,14 +75,11 @@ console.log('Hello ' + joe) // 'Hello [BetterUser: Mr. Joe Smith]' ```js // User is a constructor function upgradeUser(User) { - // EDIT THESE AS NECESSARY - function BetterUser() { - - } + function BetterUser() {} - return BetterUser + return BetterUser; } -module.exports = upgradeuser +module.exports = upgradeuser; ``` From 43fd67b62a4bbad6b3bad698dade5563c3d92bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Tue, 11 Jun 2019 14:23:06 -0500 Subject: [PATCH 10/25] feat(basic_map): Spanish translation --- exercises/basic_map/problem.es.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/basic_map/problem.es.md b/exercises/basic_map/problem.es.md index 8ba9dca..b721230 100644 --- a/exercises/basic_map/problem.es.md +++ b/exercises/basic_map/problem.es.md @@ -1,6 +1,6 @@ # Tarea -Convert the following code from a for-loop to Array#map: +Convierte el siguiente código de un ciclo `for` a un `Array#map`: ```js function doubleAll(numbers) { @@ -16,11 +16,11 @@ module.exports = doubleAll; ## Argumentos -- numbers: An Array of 0 to 20 Integers between 0 and 9 +- `numbers`: Un `Array` de 0 a 20 enteros entre 0 y 9. ## Condiciones -- Your solution should use Array.prototype.map() +- Tu solución debería user `Array.prototype.map()` - No uses ciclos `for/while` o `Array#forEach`. - No crees ninguna función innecesaria, e.j. funciones auxiliares. From 8c37742f4c097247da1a8c00b6903dcad1b4d22a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Wed, 12 Jun 2019 10:15:07 -0500 Subject: [PATCH 11/25] feat(basic_recursion): Spanish Translation --- exercises/basic_recursion/problem.es.md | 34 +++++++++---------- .../basic_recursion/solution_es/solution.js | 6 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/exercises/basic_recursion/problem.es.md b/exercises/basic_recursion/problem.es.md index 8bc2bda..6a71bb6 100644 --- a/exercises/basic_recursion/problem.es.md +++ b/exercises/basic_recursion/problem.es.md @@ -1,41 +1,41 @@ -Recursion is a fundamental programming concept which can lead to elegant and efficient solutions to algorithmic problems. In fact, recursion is so powerful, all iterating behaviour can be defined using recursive functions. You will find recursion indispensable when iterating over nested data structures. +La recursión es un concepto de programación fundamental el cual puede llevar a soluciones elegantes y eficientes a problemas algorítmicos. De hecho, la recursion es tan poderosa, que todo el comportamiento de iteración puede ser definido usando funciones recursivas. Encontrarás que la recursión es indispensable cuando se itera sobre estructuras de datos anidados. -A recursive function is a function which calls itself. For example, this recursive function will take an array of words, and return an array of those words, uppercased. +Una función recursiva es una función la cual se llama a sí misma. Por ejemplo, esta función recursiva tomará un `array` de palabras, y retornara un `array` de esas palabras, en mayúscula. ```js function toUpperArray(items) { - if (!items.length) return []; // end condition - var head = items[0]; // item to operate on - head = head.toUpperCase(); // perform action - var tail = items.slice(1); // next - return [head].concat(toUpperArray(tail)); // recursive step + if (!items.length) return []; // condición final + var head = items[0]; // elemento con el que trabajar + head = head.toUpperCase(); // ejecuta acción + var tail = items.slice(1); // siguiente + return [head].concat(toUpperArray(tail)); // paso recursivo } toUpperArray(["hello", "world"]); // => ['HELLO', 'WORLD'] ``` -The point of this exercise is to familiarise yourself with recursion by implementing a familiar interface using a recursive function. +El punto de este ejercicio es familiarizarte con la recursion al implementar una interfaz familiar usando funciones recursivas. # Tarea -Implement Array#reduce using recursion. +Implementa `Array#reduce` usando recursión. -To test your reduction works correctly we will use your reduce implementation to execute our solution to the previous basic_reduce problem. i.e. your reduce function will be passed an array of words, and a function, and an initial value which will return an object containing the counts for each word found in the array. You don't need to implement this functionality, it will be supplied to your reduce implementation. +Para probar que tu recursión funciona correctamente, usaremos tu implementación de `reduce` para ejecutar nuestra solución al previo problema de `basic_reduce`. e.j: tu función de `reduce` se le pasará un `array` de palabras, y una función, y el valor inicial el cual retornará un objeto conteniendo el contado por cada palabra encontrada en el `array`. No necesitas implementar esta función, se te proveerá a tu implementación de `reduce`. -For simplicity, your implementation of reduce **need not replicate the behaviour of a reduce missing an initial value**. You may assume the initial value will always be supplied. +Para simplificar, tu implementación de `reduce` **debe replicar el comportamiento de un reductor sin un valor inicial**. Puedes asumir que el valor inicial siempré será provisto. ## Argumentos -- arr: An Array to reduce over -- fn: Function to use as the reduction step. Like regular Array#reduce, this function must be passed previousValue, currentValue, index and the array we're iterating over. -- init: Initial value of the reduction. Unlike Array#reduce, this value is required (and you may assume it will always be supplied). +- `arr`: Un `Array` el cual reducir. +- `fn`: Function para usar en el paso de reducción. Al igual que `Array#reduce`, esta función debe ser pasada `valorPrevio`, `valorActual`, `indice` y el `array` que estamos iterando. +- `init`: Valor inicial de la reducción. A diferencia de `Array#reduce`, este valor es requerido (puedes asumir que siempre te será provisto). ## Ejemplo ```js -// Your reduce function should behave the same as a -// regular Array#reduce, but it will take the array -// to operate on as the first argument: +// Tu función de reduce se debería comportar al +// igual que `Array#reduce`, pero tomará el `array` +// para operar como el primer argumento: reduce( [1, 2, 3], diff --git a/exercises/basic_recursion/solution_es/solution.js b/exercises/basic_recursion/solution_es/solution.js index 485507f..00d2466 100644 --- a/exercises/basic_recursion/solution_es/solution.js +++ b/exercises/basic_recursion/solution_es/solution.js @@ -1,8 +1,8 @@ function reduce(arr, fn, initial) { return (function reduceOne(index, value) { - if (index > arr.length - 1) return value // end condition - return reduceOne(index + 1, fn(value, arr[index], index, arr)) // calculate & pass values to next step - })(0, initial) // IIFE. kick off recursion with initial values + if (index > arr.length - 1) return value // condición final + return reduceOne(index + 1, fn(value, arr[index], index, arr)) // calcula y pasa los valores al siguiente paso + })(0, initial) // IIFE. dispara la recursión con los valores iniciales } module.exports = reduce From 0c01a0d984821d2b1a9458b97bee2aecfa2e779c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Wed, 12 Jun 2019 15:25:09 -0500 Subject: [PATCH 12/25] feat(Spanish Translation): Changed similar text in other translations --- exercises/basic_reduce/problem.es.md | 6 +++--- exercises/basic_reduce/solucion_es/solution.js | 8 ++++---- exercises/blocking_event_loop/problem.es.md | 2 +- exercises/function_call/problem.es.md | 2 +- exercises/function_spies/problem.es.md | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/exercises/basic_reduce/problem.es.md b/exercises/basic_reduce/problem.es.md index e368390..a132c70 100644 --- a/exercises/basic_reduce/problem.es.md +++ b/exercises/basic_reduce/problem.es.md @@ -1,6 +1,6 @@ # Tarea -Given an Array of strings, use `Array#reduce` to create an object that contains the number of times each string occured in the array. Return the object directly (no need to console.log). +Dado un `Array` de `strings`, usa `Array#reduce` para crear un objeto que contenga el numero de veces que cada `string` se encuentra en el `array`. Devuelve el objeto directamente (no hay necesidad de usar `console.log`). ## Ejemplo @@ -19,11 +19,11 @@ console.log(countWords(inputWords)); ## Argumentos -- inputWords: An array of random Strings. +- `inputWords`: Un `array` de `strings` aleatorios. ## Condiciones -- Do not use any for/while loops or Array#forEach. +- No uses ciclos `for/while` o `Array#forEach`. - No crees ninguna función innecesaria, e.j. funciones auxiliares. ## Recursos diff --git a/exercises/basic_reduce/solucion_es/solution.js b/exercises/basic_reduce/solucion_es/solution.js index 13ebddf..62015e4 100644 --- a/exercises/basic_reduce/solucion_es/solution.js +++ b/exercises/basic_reduce/solucion_es/solution.js @@ -1,8 +1,8 @@ function countWords(arr) { return arr.reduce(function(countMap, word) { - countMap[word] = ++countMap[word] || 1 // increment or initialize to 1 - return countMap - }, {}) // second argument to reduce initialises countMap to {} + countMap[word] = ++countMap[word] || 1; // incrementa o lo inicia en 1 + return countMap; + }, {}); // segundo argumento a reducir e inicia el countMap en `{}` } -module.exports = countWords +module.exports = countWords; diff --git a/exercises/blocking_event_loop/problem.es.md b/exercises/blocking_event_loop/problem.es.md index 6ed3813..28b812f 100644 --- a/exercises/blocking_event_loop/problem.es.md +++ b/exercises/blocking_event_loop/problem.es.md @@ -8,7 +8,7 @@ Try to perform as many operations as you can before the timeout fires! ## Condiciones -- Do not use any for/while loops or Array#forEach. +- No uses ciclos `for/while` o `Array#forEach`. - No crees ninguna función innecesaria, e.j. funciones auxiliares. ## Pista diff --git a/exercises/function_call/problem.es.md b/exercises/function_call/problem.es.md index b8aad95..8b34cef 100644 --- a/exercises/function_call/problem.es.md +++ b/exercises/function_call/problem.es.md @@ -43,7 +43,7 @@ nums.slice(1, 2); // [2] ## Condiciones -- Do not use any for/while loops or Array#forEach. +- No uses ciclos `for/while` o `Array#forEach`. - Do not use the `function` keyword :D ## Pista diff --git a/exercises/function_spies/problem.es.md b/exercises/function_spies/problem.es.md index 1897b15..83d0bfc 100644 --- a/exercises/function_spies/problem.es.md +++ b/exercises/function_spies/problem.es.md @@ -23,7 +23,7 @@ console.log(spy.count); // 3 ## Condiciones -- Do not use any for/while loops or Array#forEach. +- No uses ciclos `for/while` o `Array#forEach`. - No crees ninguna función innecesaria, e.j. funciones auxiliares. ## Pista From 00ca3746a70574cc707e5a19e28088a6e19caf9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Wed, 12 Jun 2019 15:48:06 -0500 Subject: [PATCH 13/25] feat(blocking_event_loop): Spanish translation --- exercises/blocking_event_loop/problem.es.md | 11 ++-- .../solution_es/solution.js | 18 +++--- exercises/blocking_event_loop/wrapper_es.js | 58 ++++++++++--------- 3 files changed, 44 insertions(+), 43 deletions(-) diff --git a/exercises/blocking_event_loop/problem.es.md b/exercises/blocking_event_loop/problem.es.md index 28b812f..129e67a 100644 --- a/exercises/blocking_event_loop/problem.es.md +++ b/exercises/blocking_event_loop/problem.es.md @@ -1,10 +1,10 @@ # Tarea -Modify the recursive `repeat` function provided in the boilerplate, such that it does not block the event loop (i.e. Timers and IO handlers can fire). This necessarily requires repeat to be asynchronous. +Modifica la función recursiva `repeat` provista en la plantilla, de forma que no bloquea el ciclo del evento (e.j. `Timers` y manejadores de `IO` que se puedan disparar). Esto necesariamente requiere que `repeat` sea asíncrono. -A timeout is queued to fire after 100 milliseconds, which will print the results of the test and exit the process. `repeat` should release control of the event loop to allow the timeout to interrupt before all of the operations complete. +Un `timeout` es puesto en cola luego de 100 milisegundo, el cual imprimirá los resultados de la prueba y saldrá del proceso. `repeat` debería liberar el control del ciclo del evento para permitir que el `timeout` interrupta antes de que todas las operaciones se completen. -Try to perform as many operations as you can before the timeout fires! +Trata de realizar tantas operaciones como puedas antes de que el `timeout` se dispare. ## Condiciones @@ -13,8 +13,7 @@ Try to perform as many operations as you can before the timeout fires! ## Pista -- If your program takes a long time to run, something is probably wrong. - Use Control - C to kill the node process. +- Si tu programa tarda en correr, algo está probablemente mal. Usa `Ctrl+C` para matar el proceso de `node`. ## Recursos @@ -24,7 +23,7 @@ Try to perform as many operations as you can before the timeout fires! ```js function repeat(operation, num) { - // modify this so it can be interrupted + // modifica esto para que pueda ser interrumpido if (num <= 0) return; operation(); return repeat(operation, --num); diff --git a/exercises/blocking_event_loop/solution_es/solution.js b/exercises/blocking_event_loop/solution_es/solution.js index 546f61a..5f4b19a 100644 --- a/exercises/blocking_event_loop/solution_es/solution.js +++ b/exercises/blocking_event_loop/solution_es/solution.js @@ -1,18 +1,18 @@ function repeat(operation, num) { - if (num <= 0) return + if (num <= 0) return; - operation() + operation(); - // release control every 10 or so - // iterations. - // 10 is arbitrary. + // libera el control cada 10 + // iteraciones o similar + // 10 es aleatorio. if (num % 10 === 0) { setTimeout(function() { - repeat(operation, --num) - }) + repeat(operation, --num); + }); } else { - repeat(operation, --num) + repeat(operation, --num); } } -module.exports = repeat +module.exports = repeat; diff --git a/exercises/blocking_event_loop/wrapper_es.js b/exercises/blocking_event_loop/wrapper_es.js index 28750f5..efeb869 100644 --- a/exercises/blocking_event_loop/wrapper_es.js +++ b/exercises/blocking_event_loop/wrapper_es.js @@ -1,47 +1,49 @@ -'use strict' +"use strict"; -var path = require('path') +var path = require("path"); -var repeat = require(path.resolve(process.cwd(), process.argv[2])) +var repeat = require(path.resolve(process.cwd(), process.argv[2])); -var count = 0 -var CYCLES = 10000 +var count = 0; +var CYCLES = 10000; function operation() { for (var i = 0; i < 1000000; i++) { - // burn some CPU cycles + // quema algunos ciclos de la CPU } - // count how many times this function was called - count++ + // cuenta cuantas veces ha sido llamada esta función + count++; } +console.error(); +console.error(operation.toString()); +console.error(); +console.error( + "Tratando de ejecutor las operaciones de arriba %d veces, puede que se congele...", + CYCLES +); +console.error(); +console.error("Presiona Ctrl+C para terminar el proceso."); +console.error(); -console.error() -console.error(operation.toString()) -console.error() -console.error('Trying to execute the above operation %d times, this may crash…', CYCLES) -console.error() -console.error('Press Ctrl+C to kill.') -console.error() - -var start = Date.now() -repeat(operation, CYCLES) +var start = Date.now(); +repeat(operation, CYCLES); setTimeout(function() { - var end = Date.now() - console.error('Performed %d operations.', count) + var end = Date.now(); + console.error("Se ejecutarón %d operaciones.", count); if (count < 10) { - console.log('Fail! You should have completed some operations!') - process.exit(1) + console.log("¡Error! Debiste haber completado algunas operaciones"); + process.exit(1); } if (count >= CYCLES) { - console.log('Fail! Should not have completed all operations!') - process.exit(1) + console.log("¡Error! No debiste haber completado todas las operaciones"); + process.exit(1); } - console.log('Operations successfully interrupted!') - console.error('Interrupted after %d milliseconds.', end - start) - process.exit() -}, 100) + console.log("¡Las operaciones se interrumpieron exitosamente!"); + console.error("Interrumpido luego de %d milisegundos.", end - start); + process.exit(); +}, 100); From 1249f664c994f206341d4ad7d4cf3d6f6c369349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Thu, 13 Jun 2019 14:48:03 -0500 Subject: [PATCH 14/25] feat(currying): Spanish translation BREAKING CHANGE: Removed unnecessary frech file --- exercises/currying/problem.es.md | 18 +++++++++--------- exercises/currying/solution_fr/solution.js | 9 --------- 2 files changed, 9 insertions(+), 18 deletions(-) delete mode 100644 exercises/currying/solution_fr/solution.js diff --git a/exercises/currying/problem.es.md b/exercises/currying/problem.es.md index a5398ef..1e466bf 100644 --- a/exercises/currying/problem.es.md +++ b/exercises/currying/problem.es.md @@ -1,4 +1,4 @@ -This is an example implementation of `curry3`, which curries up to 3 arguments: +Este es un ejemplo de la implementación de `curry3`, el cual hace "curry" de hasta 3 argumentos: ```js function curry3(fun) { @@ -12,7 +12,7 @@ function curry3(fun) { } ``` -If we were to use this implementation with this sample function: +Si fuésemos a utilizar está implementación con una función de prueba: ```js function abc(one, two, three) { @@ -20,7 +20,7 @@ function abc(one, two, three) { } ``` -It would work like so: +Funcionaría así: ```js var curryC = curry3(abc); @@ -32,12 +32,12 @@ console.log(curryA(2)); // => 1 # Tarea -In this challenge, we're going to implement a 'curry' function for an arbitrary number of arguments. +En este reto, vamos a implementar una función de "curry" para un numero arbitrario de argumentos. -`curryN` will take two parameters: +`curryN` tomará dos parámetros: -- fn: The function we want to curry. -- n: Optional number of arguments to curry. If not supplied, `curryN` should use the fn's arity as the value for `n`. +- `fn`: La función que queremos convertir en "curry". +- `n`: Un numero opcional de argumentos que se van a convertir en "curry". Si no se provee `curryN` debería usar el numero de argumento de `fn` como valor de `n`. ## Ejemplo @@ -57,11 +57,11 @@ console.log(curryN(add3)(1)(2)(3)); // => 6 ## Condiciones -- Do not use any for/while loops or `Array.prototype.forEach`. +- No uses ciclos `for/while` o `Array#forEach`. ## Pista -- You can detect the number of expected arguments to a function (it's arity) by checking a function's .length property. +- Puedes detectar el numero de argumentos provistos a una función (su aridad) al revisar la propiedad `.length` de la función. ## Plantilla diff --git a/exercises/currying/solution_fr/solution.js b/exercises/currying/solution_fr/solution.js deleted file mode 100644 index 98caefb..0000000 --- a/exercises/currying/solution_fr/solution.js +++ /dev/null @@ -1,9 +0,0 @@ -function curryN(fn, n) { - n = n || fn.length - return function curriedN(arg) { - if (n <= 1) return fn(arg) - return curryN(fn.bind(this, arg), n - 1) - } -} - -module.exports = curryN From 25797ea07d7da6913626985ac7ff607acf2fc6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Thu, 13 Jun 2019 15:09:30 -0500 Subject: [PATCH 15/25] feat(function_call): Spanish Translation --- exercises/function_call/problem.es.md | 37 +++++++++---------- .../function_call/solution_es/solution.js | 26 +++++++------ 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/exercises/function_call/problem.es.md b/exercises/function_call/problem.es.md index 8b34cef..737429b 100644 --- a/exercises/function_call/problem.es.md +++ b/exercises/function_call/problem.es.md @@ -1,42 +1,41 @@ # Tarea -Write a function that allows you to use `Array.prototype.slice` without using `slice.call` or `slice.apply` to invoke it. - -Normally you have to use `slice` with `call` or `apply`: +Escribe una función que te permita usar `Array.prototype.slice` sin usar `slice.call` o `slice.apply` para llamarla. +Normalmente tienes que usar `slice` con `call` o `apply`: ```js var slice = Array.prototype.slice function() { - var args = slice.call(arguments) // this works + var args = slice.call(arguments) // esto funciona } ``` -We want this to work: +Queremos que esto funcione: ```js var slice = yourFunction function() { - var args = slice(arguments) // this works + var args = slice(arguments) // esto funciona } ``` ## Ejemplo -A function, `slice` that exhibits the following behaviour: +Una función `slice` que se comporta de la siguiente manera: ```js var nums = [1, 2, 3, 4, 5]; -// your slice function should match the regular -// behaviour of slice, except it takes the array -// as the first argument +// tu función slice debería comportarse +// similar a `slice`, excepto que toma el +// array como el primer argumento. slice(nums, 0, 2); // [1, 2] slice(nums, 1, 2); // [2] -// regular slice usage for comparison +// el `slice` normal usado para comparar nums.slice(0, 2); // [1, 2] nums.slice(1, 2); // [2] ``` @@ -44,25 +43,25 @@ nums.slice(1, 2); // [2] ## Condiciones - No uses ciclos `for/while` o `Array#forEach`. -- Do not use the `function` keyword :D +- No uses la palabra reservada `function` :D ## Pista -- This is absolutely a one liner. -- Every JavaScript Function inherits methods such as call, apply and bind from the object `Function.prototype`. -- Function#call executes the value of `this` when it is invoked. Inside `someFunction.call()`, the value of `this` will be `someFunction`. -- Function.call itself is a function thus it inherits from `Function.prototype` +- Lo puedes resolver en una linea- +- Todas las funciones de heredan `call`, `apply` y `bind` del objeto `Function.prototype`. +- `Function#call` ejecuta el valor de this cuando es invocado, dentro de `algunaFuncion.call()`, el valor de `this` será `algunaFuncion`. +- `Function.call` por si misma es una función y hereda de `Function.prototype`. ```js function myFunction() { - console.log("called my function"); + console.log("se llamo mi función"); } -Function.prototype.call.call(myFunction); // => "called my function" +Function.prototype.call.call(myFunction); // => "se llamo mi función" ``` ## Plantilla ```js -module.exports = // your solution here! +module.exports = // tu solución aquí; ``` diff --git a/exercises/function_call/solution_es/solution.js b/exercises/function_call/solution_es/solution.js index 29fa8f6..09c921e 100644 --- a/exercises/function_call/solution_es/solution.js +++ b/exercises/function_call/solution_es/solution.js @@ -1,13 +1,15 @@ -// Explained: -// The value of `this` in Function.call is the function -// that will be executed. -// -// Bind returns a new function with the value of `this` fixed -// to whatever was passed as its first argument. -// -// Every function 'inherits' from Function.prototype, -// thus every function, including call, apply and bind -// have the methods call apply and bind. -// +// Explicado: El valor de `this` +// en `Function.call` es la +// función que será ejecutada. + +// `Bind` se refiere a la +// nueva función que sera ejecutada +// con el valor de `this` cambiada a +// lo que sea que se paso como primer argumento` + +// Toda función "hereda" de `Function.prototype`, +// por ende toda función, incluyendo `call`, `apply` +// y `bind` tienen los métodos `call`, `apply` y `bind. + // Function.prototype.call === Function.call -module.exports = Function.call.bind(Array.prototype.slice) +module.exports = Function.call.bind(Array.prototype.slice); From 3ba2d8714957c71149533f2f74dc2ac1d9e7e7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Thu, 13 Jun 2019 15:53:43 -0500 Subject: [PATCH 16/25] feat(function_spies): Spanish translation --- exercises/function_spies/problem.es.md | 11 +++++----- .../function_spies/solution_es/solution.js | 22 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/exercises/function_spies/problem.es.md b/exercises/function_spies/problem.es.md index 83d0bfc..74e82a0 100644 --- a/exercises/function_spies/problem.es.md +++ b/exercises/function_spies/problem.es.md @@ -1,8 +1,7 @@ # Tarea -Override a specified method of an object with new functionality while still maintaining all of the old behaviour. - -Create a spy that keeps track of how many times a function is called. +Sobrescribe la función especifica de un objeto con una nueva funcionalidad mientras mantienes el comportamiento anterior. +Crea un espía que mantiene cuenta de cuantas veces una función fue llamada; ## Ejemplo @@ -18,8 +17,8 @@ console.log(spy.count); // 3 ## Argumentos -- target: an object containing the method `method` -- method: a string with the name of the method on `target` to spy on. +- `target`: Un objeto conteniendo el método `method`. +- `method`: Un `string` con el nombre del método en `target` que debería espiar. ## Condiciones @@ -28,7 +27,7 @@ console.log(spy.count); // 3 ## Pista -- Functions have context, input and output. Make sure you consider the context, input to _and output from_ the function you are spying on. +- Las funciones tienen contexto, entrada y retorno. Asegurate de considerar el contexto, entrada y _el retorno de_ la función que estás espiando. ## Plantilla diff --git a/exercises/function_spies/solution_es/solution.js b/exercises/function_spies/solution_es/solution.js index 04af6ec..3954a36 100644 --- a/exercises/function_spies/solution_es/solution.js +++ b/exercises/function_spies/solution_es/solution.js @@ -1,19 +1,19 @@ function Spy(target, method) { - var originalFunction = target[method] - - // use an object so we can pass by reference, not value - // i.e. we can return result, but update count from this scope + var originalFunction = target[method]; + // usa un objeto de manera que podamos pasar + //por referencia, no por valor, e.j: podemos + // devolver el resultado, pero actualizar el contador de este `scope var result = { count: 0 - } + }; - // replace method with spy method + // reemplaza el método con la función espiá. target[method] = function() { - result.count++ // track function was called - return originalFunction.apply(this, arguments) // invoke original function - } + result.count++; // revisa que la función fue llamada + return originalFunction.apply(this, arguments); // invoca la función original + }; - return result + return result; } -module.exports = Spy +module.exports = Spy; From a0a83717e9ebf7471fd6ef35112d1f6356b292ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Thu, 13 Jun 2019 16:05:04 -0500 Subject: [PATCH 17/25] feat(hello_world): Spanish translation --- exercises/hello_world/problem.es.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/hello_world/problem.es.md b/exercises/hello_world/problem.es.md index 2298712..d483ebd 100644 --- a/exercises/hello_world/problem.es.md +++ b/exercises/hello_world/problem.es.md @@ -1,10 +1,10 @@ # Tarea -Write a function that takes an input string and returns it uppercased. +Escribe una función que tome como argumento un `string` y lo retorne en mayúsculas. ## Argumentos -- input: a String of random words (lorem ipsum). +- `input`: Un `string` de palabras aleatorias (lorem ipsum). ## Plantilla From 5318e73524583e5b4503bf40e3a498a1d74d78b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Thu, 13 Jun 2019 17:04:24 -0500 Subject: [PATCH 18/25] feat(higher_order_functions): Spanish Translation --- .../higher_order_functions/problem.es.md | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/exercises/higher_order_functions/problem.es.md b/exercises/higher_order_functions/problem.es.md index fbd3b6a..737b708 100644 --- a/exercises/higher_order_functions/problem.es.md +++ b/exercises/higher_order_functions/problem.es.md @@ -1,26 +1,26 @@ -A higher-order function is a function that does at least one of the following: +Una función `higher-order` (de alto orden) es una función que hace al menos una de las siguientes cosas: -- Take one or more functions as an input -- Output a function +- Toma una o más funciones como argumentos. +- Retorna una función. -All other functions are first order functions. [1] +Todas las demás funciones son de primer orden. [1] -Unlike many other languages with imperative features, JavaScript allows you to utilize higher-order functions because it has "first-class functions". This means functions can be treated just like any other value in JavaScript: just like Strings or Numbers, Function values can be stored as variables, properties on objects or passed to other functions as arguments. Function values are actually Objects (inheriting from `Function.prototype`) so you can even add properties and store values on them, just like any regular Object. +A diferencia de muchos otros lenguajes con capacidades imperativas, JavaScript te permite utilizar funciones `higher-order` porque tiene funciones de "primera clase". Esto significa que las funciones pueden ser tratadas como cualquier otro valor en JavaScript: justo como con números o `strings`, el valor de una función puede ser almacenada como variable, propiedades en objetos o pasadas a otras funciones como argumentos. El valor de una función es de hecho un objeto (que hereda de `Function.prototype`) así que inclusive puedes agregar propiedades y guardar valores en ellas, como con cualquier objeto. -The key difference between Functions and other value types in JavaScript is the call syntax: if a reference to a function is followed by parenthesis and some optional comma-separated values: `someFunctionValue(arg1, arg2, etc)`, then the function body will be executed with the supplied arguments (if any). +La diferencia clave entre las funciones y cualquier otro tipo de valor en JavaScript es la sintaxis de llamado: Si una referencia a una función le sigue unos paréntesis y valores opciones separado por coma: `algunaFuncion(a, b, ...etc)`, entonces el cuerpo de la función sera ejecutado con los argumentos provistos (si hay). -In this exercise we're going to demonstrate that functions can be passed as values by passing you a function as an argument. +En este ejercicio vamos a demostrar que las funciones pueden ser pasadas como valores al pasar una función como argumento. # Tarea -Implement a function that takes a function as its first argument, a number `num` as its second argument, then executes the passed in function `num` times. +Implementa una función que toma una función como su primer argumento, un numero `num` como su segundo argumento, entonces ejecuta la función pasada `num` veces. -Use the boilerplate code given to you below to get started. Most/all future exercises will provide boilerplate. +Usa la plantilla de código dada a ti en la parte inferior, La mayoría o todos los ejercicios proveerán una plantilla. ## Argumentos -- operation: A Function, takes no arguments, returns no useful value. -- num: the number of times to call `operation` +- `operation`: Una function, no toma argumentos y no retorna ningún valor de uso. +- `num`: El numero de veces que se debe llamar la función `operation`. ## Recursos @@ -29,10 +29,10 @@ Use the boilerplate code given to you below to get started. Most/all future exer ## Pista -- Don't overthink it, the code should be rather simple. -- It's ok to use a loop in your implementation, bonus points if you use recursion instead. -- You may notice some output. That is coming from the function we passed you. -- You do not need to console.log anything. +- No lo pienses de mas, el código debería ser simple. +- Está bien usar un ciclo en tu implementación, puntos extra si usas recursion en vez. +- Quizás notes algún valor de retorno. Viene de la función que te otorgamos. +- No necesitas usar `console.log` para nada. ## Plantilla @@ -41,6 +41,6 @@ function repeat(operation, num) { // TU SOLUCIÓN } -// Do not remove the line below +// No remuevas o edites esta linea module.exports = repeat; ``` From 2edd5103902568724a1fdf603a408f241ffbe4d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Thu, 13 Jun 2019 17:17:47 -0500 Subject: [PATCH 19/25] feat(implement_map_with_reduce): Spanish Translation --- exercises/implement_map_with_reduce/problem.es.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/exercises/implement_map_with_reduce/problem.es.md b/exercises/implement_map_with_reduce/problem.es.md index 2b8695b..8cf7554 100644 --- a/exercises/implement_map_with_reduce/problem.es.md +++ b/exercises/implement_map_with_reduce/problem.es.md @@ -1,15 +1,15 @@ # Tarea -Use Array#reduce to implement a simple version of Array#map. +Usa `Array#reduce` para implementar una versión simple de `Array#map`. ## Resultado esperado -A function `map` that applies a function to each item in an array and collects the results in a new Array. +Una función `map` que aplique una función a cada elemento en el `array` y recolecte el resultado en un nuevo `Array`. ```js var nums = [1, 2, 3, 4, 5]; -// `map` is your exported function +// `map` es la función que exportas var output = map(nums, function double(item) { return item * 2; }); @@ -19,12 +19,12 @@ console.log(output); // => [2,4,6,8,10] ## Argumentos -- input: an arbitrary Array of any type. -- operation: an arbitrary Function which can be applied to items in `input`. +- `input`: Un `Array` aleatorio de cualquier tipo. +- `operation`: Una función arbitraria la cual puede ser aplicada a los elementos en `input`. ## Pista -- No need to implement the optional `thisArg` argument of `Array.prototype.map`, bonus points if you do! +- No hay necesidad de implementar el argumento opcional `thisArg` de `Array.prototype.map`, ¡puntos adicionales si lo haces! ## Recursos @@ -35,7 +35,7 @@ console.log(output); // => [2,4,6,8,10] ```js function arrayMap(arr, fn) { - //SOLUTION GOES HERE + // TU SOLUCIÓN } module.exports = arrayMap; From b7923ddba13238e3df616c83c4f8a79985c666ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Fri, 14 Jun 2019 12:34:37 -0500 Subject: [PATCH 20/25] feat(partial_application_with_bind): Spanish Translation --- .../problem.es.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/exercises/partial_application_with_bind/problem.es.md b/exercises/partial_application_with_bind/problem.es.md index 7551071..f1d2f22 100644 --- a/exercises/partial_application_with_bind/problem.es.md +++ b/exercises/partial_application_with_bind/problem.es.md @@ -1,32 +1,32 @@ # Tarea -**Use Function#bind** to implement a logging function that allows you to namespace messages. +**Usa `Function#bind`** para implementar una función que imprima y te permita crear un `namespace` para los mensajes. -Your implementation should take a namespace string, and return a function that prints messages to the console with the namespace prepended. +Tu implementación debería tomar un `string` como `namespace`, y devolver una función que imprima el mensaje a la consola con el `namespace` como prefijo. -Make sure _all_ arguments passed to the returned logging function are printed. +Asegurate que _todos_ los argumentos pasados a la función que retornes sean impresos. -** Print the output to the console directly ** +**Imprime los argumentos directamente en la consola** ## Argumentos -- namespace: a String to prepend to each message passed to the returned function. +- `namespace`: Un `string` que será el sufijo a cada mensaje enviado a la función retornada. ## Ejemplo ```js var info = logger("INFO:"); -info("this is an info message"); -// INFO: this is an info message +info("este es un mensaje informativo"); +// INFO: este es un mensaje informativo -var warn = logger("WARN:"); -warn("this is a warning message", "with more info"); -// WARN: this is a warning message with more info +var warn = logger("AVISO:"); +warn("este es un aviso", "con mas información"); +// AVISO: este es un aviso con mas información ``` ## Condiciones -- Use Function#bind +- Usa `Function#bind`. ## Plantilla From 55eec8a0d6d15e364e475e0789b0c3d1442a2204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Fri, 14 Jun 2019 13:06:39 -0500 Subject: [PATCH 21/25] feat(partial_application_without_bind): Spanish Translation --- .../problem.es.md | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/exercises/partial_application_without_bind/problem.es.md b/exercises/partial_application_without_bind/problem.es.md index 015cd98..15fdd52 100644 --- a/exercises/partial_application_without_bind/problem.es.md +++ b/exercises/partial_application_without_bind/problem.es.md @@ -1,8 +1,8 @@ -Partial application allows you to create new functions from existing functions, while fixing some number of arguments. After setting the arguments to be partially applied, you get a new function ready to take the rest of the arguments and perhaps execute the original function. +La aplicación parcial te permite crear nuevas funciónes de funciónes existentes, mientras permite ajustar algún numero de argumentos. Luego de ajustar algunos argumentos para ser aplicados parcialmente, obtienes una nueva función para obtener el resto de los argumentos y quizás ejecutar la función original. -More formally: Partial application refers to the process of fixing a number of arguments to a function, producing another function of smaller arity. +Formalmente: La aplicación parcial se refiere al proceso de ajustar un numero de argumentos para una función, produciendo una función con una aridad (cantidad de argumentos) menor. -As an example, say we have a function `add`, that takes 2 arguments and adds them together: +Como ejemplo, digamos que tenemos una función `add`, que toma dos argumentos y los suma: ```js function add(x, y) { @@ -12,17 +12,17 @@ function add(x, y) { add(10, 20); // => 30 ``` -Now, pretend we have a function `partiallyApply`. `partiallyApply` takes a function, and some arguments to 'partially apply'. +Ahora, pretendamos que tenemos una función `partiallyApply` que toma una función y algunos argumentos para "aplicar parcialmente". -Here we 'partially apply' the first parameter, `x`, of our `add` function: +Aquí "aplicamos parcialmente" el primer parámetro, `x`, a nuestra función `add`: ```js -var addTen = partiallyApply(add, 10); // fix `x` to 10 +var addTen = partiallyApply(add, 10); // ajusta `x` a ser 10 ``` -`addTen` is a new function that takes the `y` parameter of `add`. `add` has not yet been called! +`addTen` es una función nueva que toma como parámetro `y` de `add`. ¡`add` no ha sido llamada aún! -Once we pass the argument for `y`, we can execute the original `add` function: +Una vez pasamos el argumento para `y`, podemos ejecutar la función original de`add`: ```js addTen(20); // => 30 @@ -32,46 +32,44 @@ addTen(0); // => 10 // etc ``` -All of the above examples are same as calling `add(10, y)`, where `y` was supplied in the call to the appropriately named `addTen`. +Todos los ejemplos de arriba son el mismo llamando `add(10, y)`, donde `y` fue provisto en la llamada a la función `addTen`. # Tarea -Use partial application to create a function that fixes the first argument to `console.log`. i.e. Implement a logging function that prepends a namespace string to its output. +Usa aplicación parcial para crear una función que ajuste el primer argumento de `console.log`. e.j. Implementa una función de impresión que agregue un `namespace` como sufijo al `string` que vaya a imprimir. -Your implementation should take a namespace String and return a function that prints messages to the console with the namespace prepended. +Tu implementación debería tomar un `string` como `namespace` y retornar una función que imprima el mensaje en consola con el `namespace` com prefijo. -You should use `Function#apply` to implement the partial application. +Deberías utilizar `Function#apply` para implementar la aplicación parcial. -Make sure _all_ arguments passed to the returned logging function are printed. +Asegurate que _todos_ los argumentos pasados a la función que retornes sean impresos. -** Print the output to the console directly ** +**Imprime los argumentos directamente en la consola** ## Argumentos -- namespace: a String to prepend to each message passed to the returned function. +- `namespace`: Un `string` que será el sufijo a cada mensaje enviado a la función retornada. ## Ejemplo ```js var info = logger("INFO:"); -info("this is an info message"); -// INFO: this is an info message +info("este es un mensaje informativo"); +// INFO: este es un mensaje informativo -var warn = logger("WARN:"); -warn("this is a warning message", "with more info"); -// WARN: this is a warning message with more info +var warn = logger("AVISO:"); +warn("este es un aviso", "con mas información"); +// AVISO: este es un aviso con mas información ``` ## Condiciones -- Do not use Function#bind -- Use Function#apply +- No uses `Function#bind`. +- Usa `Function#apply`. ## Plantilla ```js -var slice = Array.prototype.slice; - function logger(namespace) { // TU SOLUCIÓN } @@ -86,23 +84,23 @@ module.exports = logger; ## Pista -Remember `console.log` takes any number of arguments and prints them, separated by spaces: +Recuerda que `console.log` toma cualquier numero de argumentos y los imprime, separados por espacios: ```js console.log("hello", "world"); // => 'hello world' console.log(1, 2, 3); // => 1 2 3 ``` -We simply want to 'partially apply' the first argument to `console.log`. +Queremos simplemente "aplicar parcialmente" el primer argumento de `console.log`. -`Function.prototype.apply` allows us to execute a function, supply a new 'value for this' (we can ignore in this case), and then _an array of arguments to apply to the function_: +`Function.prototype.apply` nos permite ejecutar una función, proveer un nuevo valor para `this` (que podemos ignorar en este caso), y entonces proveer _un array de argumentos para pasar a la función_: ```js add(10, 20); // => 30 add.apply(null, [10, 20]); // => 30 ``` -Also contrast `apply` with `Function.prototype.call`: +También ten en cuenta `apply` con `Function.prototype.call`: ```js add.apply(null, [10, 20]); // => 30 From 7149114d9bc0985deb835bd976feab9463020277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Fri, 14 Jun 2019 17:14:58 -0500 Subject: [PATCH 22/25] feat(prototypical_inheritance_by_hand): Spanish Translation --- .../problem.es.md | 95 ++++++++++--------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/exercises/prototypical_inheritance_by_hand/problem.es.md b/exercises/prototypical_inheritance_by_hand/problem.es.md index 4376b0f..82e151c 100644 --- a/exercises/prototypical_inheritance_by_hand/problem.es.md +++ b/exercises/prototypical_inheritance_by_hand/problem.es.md @@ -1,24 +1,28 @@ -We're going to implement a rough analog of JavaScript's prototypical inheritance by hand, to ensure we fully understand exactly how prototypical inheritance fits together. +Vamos a crear una vaga implementación de la herencia de prototipos en JavaScript a mano, para asegurar que entendemos completamente como la herencia de prototipos funcióna. # Tarea -Implement the functions `New`, `Create` and `Lookup` to simulate JavaScript's `new`, `Object.create` and property lookup mechanisms respectively. +Implementa las funciónes `New`, `Create` y `Lookup` para simular `new`, `Object.create` y búsqueda de propiedades en JavaScript respectivamente. -Throughout this exercise, you will avoid using any built-in JavaScript inheritance features. Instead, you will need to use your own New, Create and Lookup functions as well as `__PROTO__` to represent an instance's prototype, and `PROTOTYPE` to represent a constructor's prototype. +Por medio de esta experiencia, evitaras usar cualquier capacidad de herencia de JavaScript. En vez, necesitaras usar tus propias funciónes de `New`, `Create` y `Lookup` al igual que `__PROTO__` para representar la instancia de un prototipo, y `PROTOTYPE` para representar el constructor de un prototipo. -i.e. +## Ejemplo -- New(Apple, 1,2,3) == new Apple(1,2,3) -- `obj.__PROTO__` == obj.**proto** || Object.getPrototypeOf(obj) -- `Constructor.PROTOTYPE` == `Constructor.prototype` +```js +New(Apple, 1, 2, 3) == new Apple(1, 2, 3); // true + +obj.__PROTO__ == obj.__proto__ || Object.getPrototypeOf(obj); // true + +Constructor.PROTOTYPE == Constructor.prototype; // true +``` ## Parte 1: Lookup -`Lookup` will simulate the behaviour of JavaScript's property lookup mechanism, or "Getters". When you reference any object's property in JavaScript, it will 'walk up the prototype chain' to find the property, if found it will return its value, otherwise it will return `undefined`. +`Lookup` simulará el mecanismo de la búsqueda de propiedades en JavaScript, o `Getters`. Cuando tu referencias cualquier propiedad de un objeto en JavaScript, esta "recorrerá la cadena de prototipos" para encontrar una propiedad, si lo encuentra devolverá su valor, de otro modo retornara `undefined`. -Your `Lookup` function will be passed a context object, and the property String that we're looking for. If the property is found on the current context, return that property, otherwise check the context's prototype, `__PROTO__`. +Tu función de `Lookup` le sera provista un objeto de contexto, y la propiedad en `string` que estamos buscando. Si la propiedad se encuentra en el contexto actual, retorna esa propiedad, de otro modo busca en el contexto del prototipo, `__PROTO__`. -If a property cannot be found in the object's prototype chain, simply return `undefined`. +Si una propiedad no puede ser encontrada en la cadena de prototipos del objeto, simplemente retorna `undefined`. ```js var cat = { @@ -42,17 +46,19 @@ Lookup(otherKitten, "color"); // => 'grey' Lookup(kitten, "wings"); // => undefined -// changing properties on the prototype should -// affect any instances that inherit from it. +// cambiar propiedades en el prototipo debería +// afectar todas las instancias que hereden de el. cat.color = "blue"; Lookup(kitten, "color"); // => 'blue' -// overridden properties should still work +// propiedades sobrescritas deberían funciónar Lookup(otherKitten, "color"); // => 'grey' ``` -Side Note: in JavaScript, when you 'get' a property (i.e. lookup), the engine walks up the prototype chain to find the value, but if you 'set' a property it ignores the prototype chain and simply sets the value on the current object. We could have implemented a 'Setter' as an exercise, but since there's no magic, it's pretty trivial: +### Notas + +En JavaScript, cuando tu "obtienes" (`get`) un propiedad (e.j. `lookup`), el motor recorre la cadena de prototipos para encontrar el valor, pero si tu "das" (`set`) un valor, ignora la cadena de prototipo y simplemente da el valor al objeto actual, Nosotros pudimos haber implementado un `Setter` como ejercicio, pero no hay magia detrás de esto, es bastante trivial: ```js function Setter(context, property, value) { @@ -62,37 +68,34 @@ function Setter(context, property, value) { ## Parte 2: Create -`Create` will simulate the behaviour of `Object.create`. +`Create` simulara el comportamiento de `Object.create`. -`Create` will be passed an object, and you must return a new object with its prototype (`__PROTO__`) set to the supplied object. +`Create` se le pasara un objeto, y debes retornar un nuevo objeto con su prototipo(`__PROTO__`) que sea el valor del objeto provisto. ```js -fuction Cat() { - -} +function Cat() {} Cat.PROTOTYPE.speak = function() { - return 'Meow!' -} + return "Meow!"; +}; function Kitten() { - Cat.apply(this, arguments) + Cat.apply(this, arguments); } -Kitten.PROTOTYPE = Create(Cat.PROTOTYPE) - -var kitten = New(Kitten) -Lookup(kitten, 'speak')() // => 'Meow!' +Kitten.PROTOTYPE = Create(Cat.PROTOTYPE); +var kitten = New(Kitten); +Lookup(kitten, "speak")(); // => 'Meow!' ``` -## Finale: New +## Parte 3: New -`New` will simulate the behaviour of JavaScript's `new` keyword. +`New` simulara el comportamiento de la palabra clave de JavaScript `new`. -The first argument passed to `New` will be a constructor function (i.e. a type). Subsequent parameters must be passed to the constructor function when creating the the new object. +El primer argumento pasado a `New` sera una función constructora (e.j. un tipo). Los parámetros subsecuentes deberán ser pasados al constructor de la función cuando se cree un nuevo objeto. -`New` will return new objects using the supplied constructor function. +`New` retornara nuevos objetos usando la función constructora provista. ```js function Cat(color) { @@ -106,7 +109,7 @@ var brownCat = New(Cat, "brown"); brownCat.color; // => brown ``` -The constructor function passed to `New` may have a `.PROTOTYPE` property. All objects created with this constructor will have their `__PROTO__` set to the constructor's `.PROTOTYPE` property. +La función constructora pasada a `New` puede que tenga una propiedad `.PROTOTYPE` . Todos los objetos con este constructor tendrán su `__PROTO__` a que sea el valor de la propiedad `.PROTOTYPE` del constructor. ```js function Cat(color) { @@ -134,22 +137,22 @@ var brownCat = New(Cat, "brown"); brownCat.color; // => brown ``` -Prototype properties should be available in the constructor: +Las propiedades del prototipo deberían estar disponibles en el constructor: ```js function Cow() { - // lookup this.moo: + // busca this.moo: console.log("moo", Lookup(this, "moo")); } -// this step is done for you automatically in 'real' javascript. +// este paso es hecho automaticamente en JavaScript "normal". Cow.PROTOTYPE = {}; Cow.PROTOTYPE.moo = true; var cow = New(Cow); // 'moo' true ``` -We also need to simulate one other behaviour of the `new` keyword: If the constructor itself returns a value, `New` will return that value. +También necesitamos simular uno comportamiento adicional de la palabra clave `new`: Si el constructor de por si retorna un valor, `New` retornara ese valor. ```js function Cat() { @@ -161,35 +164,35 @@ var cat = New(Cat); // 3 ## Condiciones -- Do not use any built-in javascript prototypical inheritance features. -- Do not call `new` -- Do not use `__proto__`, `Object.getPrototypeOf` or `Object.setPrototypeOf` +- No uses ninguna capacidad de Javascript de herencia de prototipos. +- No uses `new`. +- No uses `__proto__`, `Object.getPrototypeOf` ni `Object.setPrototypeOf`. ## Pista -- Use `hasOwnProperty` to discover if an object has a property. +- Usa `hasOwnProperty` para descubrir si un objeto tiene una propiedad. ## Plantilla ```js /** - * @param context {Object} Initial object to start searching for `property` - * @param property {String} name of property we are trying to locate. - * @return {Mixed} The value of `property` in `context` or somewhere in its prototype chain. + * @param context {Object} Objeto inicial para comenzar la búsqueda por "propiedad". + * @param property {String} nombre de la propiedad que estamos tratando de encontrar. + * @return {Mixed} El valor de `property` en `context` o en algún lugar de su cadena de prototipos. */ function Lookup(context, property) {} /** - * @param proto {Object} The prototype to use for the created object. - * @return A new Object whose prototype is set to `proto` + * @param proto {Object} El prototipo a usar para el objeto creado. + * @return Un nuevo objeto cuyo prototipo es puesto en`proto`. */ function Create(proto) {} /** - * @param Constructor {Function} Constructor for a new type. - * @return new instance of the type defined by `Constructor`. + * @param Constructor {Function} Constructor para un nuevo tipo. + * @return nueva instancia de un tipo definida por `Constructor`. */ function New(Constructor) {} From 7f199618b546c452f641032afeca451c829cf44c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Fri, 21 Jun 2019 20:10:20 -0500 Subject: [PATCH 23/25] feat(recursion): Add Spanish Translation --- exercises/recursion/problem.es.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/exercises/recursion/problem.es.md b/exercises/recursion/problem.es.md index e21cc6d..8f2af97 100644 --- a/exercises/recursion/problem.es.md +++ b/exercises/recursion/problem.es.md @@ -1,12 +1,12 @@ # Tarea -Implement a recursive function that returns all of the unique dependencies, and sub-dependencies of a module, sorted alphabetically. Dependencies should be printed as dependency@version e.g. 'inflection@1.2.6'. +Implementa una función recursiva que retorne todas las dependencias únicas, y sub-dependencias de un modulo, organizado alfabéticamente. Las dependencias deberían ser impresas en forma `dependencia@version`, por ejemplo `inflection@1.3.6`. -Multiple versions of the same module are allowed, but duplicates modules of the same version should be removed. +Se permite tener múltiples versiones de un mismo modulo, pero los módulos duplicados de la misma version deben ser removidos. ## Argumentos: -- tree: A dependency tree. See below for an example of the structure. +- `tree`: Una árbol de dependencias. Abajo encontrarás un ejemplo de la estructura. ## Ejemplo @@ -41,9 +41,10 @@ getDependencies(loremIpsum); // => [ 'inflection@1.2.6', 'optimist@0.3.7', 'word ```js function getDependencies(tree) { // TU SOLUCIÓN - // Note: Feel free to add additional arguments - // to this function for use with recursive calls. - // Or not! There are many ways to recurse. + // Nota: Sientete libre de agregar + // argumentos adicionales a esta funcion + // para usar con un llamado recursivo, + // ¡o no lo hagas!, hay varias maneras de hacer recursión. } module.exports = getDependencies; From 2b5679365774aa48c468b7ddf3aec0958ebd3ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Fri, 21 Jun 2019 21:58:55 -0500 Subject: [PATCH 24/25] feat(es.json/trampoline): Add Spanish Translation Additionally add punctuation. --- exercises/basic_call/problem.es.md | 2 +- exercises/basic_reduce/problem.es.md | 2 +- exercises/currying/problem.es.md | 6 ++-- .../higher_order_functions/problem.es.md | 4 +-- .../problem.es.md | 6 ++-- exercises/trampoline/problem.es.md | 31 +++++++++---------- i18n/es.json | 22 ++++++++++++- 7 files changed, 46 insertions(+), 27 deletions(-) diff --git a/exercises/basic_call/problem.es.md b/exercises/basic_call/problem.es.md index 8845dc0..c9558e4 100644 --- a/exercises/basic_call/problem.es.md +++ b/exercises/basic_call/problem.es.md @@ -54,7 +54,7 @@ Object.prototype.hasOwnProperty.call(object, "quack"); // => true # Tarea: -Escribe una función `duckCount` que retorne el numero de argumentos provistos que contienen una propiedad "quack" definida en ellos. No cuentes valores heredados de los prototipos. +Escribe una función `duckCount` que retorne el número de argumentos provistos que contienen una propiedad "quack" definida en ellos. No cuentes valores heredados de los prototipos. Ejemplo: diff --git a/exercises/basic_reduce/problem.es.md b/exercises/basic_reduce/problem.es.md index a132c70..aa41e35 100644 --- a/exercises/basic_reduce/problem.es.md +++ b/exercises/basic_reduce/problem.es.md @@ -1,6 +1,6 @@ # Tarea -Dado un `Array` de `strings`, usa `Array#reduce` para crear un objeto que contenga el numero de veces que cada `string` se encuentra en el `array`. Devuelve el objeto directamente (no hay necesidad de usar `console.log`). +Dado un `Array` de `strings`, usa `Array#reduce` para crear un objeto que contenga el número de veces que cada `string` se encuentra en el `array`. Devuelve el objeto directamente (no hay necesidad de usar `console.log`). ## Ejemplo diff --git a/exercises/currying/problem.es.md b/exercises/currying/problem.es.md index 1e466bf..07c94a8 100644 --- a/exercises/currying/problem.es.md +++ b/exercises/currying/problem.es.md @@ -32,12 +32,12 @@ console.log(curryA(2)); // => 1 # Tarea -En este reto, vamos a implementar una función de "curry" para un numero arbitrario de argumentos. +En este reto, vamos a implementar una función de "curry" para un número arbitrario de argumentos. `curryN` tomará dos parámetros: - `fn`: La función que queremos convertir en "curry". -- `n`: Un numero opcional de argumentos que se van a convertir en "curry". Si no se provee `curryN` debería usar el numero de argumento de `fn` como valor de `n`. +- `n`: Un número opcional de argumentos que se van a convertir en "curry". Si no se provee `curryN` debería usar el número de argumento de `fn` como valor de `n`. ## Ejemplo @@ -61,7 +61,7 @@ console.log(curryN(add3)(1)(2)(3)); // => 6 ## Pista -- Puedes detectar el numero de argumentos provistos a una función (su aridad) al revisar la propiedad `.length` de la función. +- Puedes detectar el número de argumentos provistos a una función (su aridad) al revisar la propiedad `.length` de la función. ## Plantilla diff --git a/exercises/higher_order_functions/problem.es.md b/exercises/higher_order_functions/problem.es.md index 737b708..e9ad1a5 100644 --- a/exercises/higher_order_functions/problem.es.md +++ b/exercises/higher_order_functions/problem.es.md @@ -13,14 +13,14 @@ En este ejercicio vamos a demostrar que las funciones pueden ser pasadas como va # Tarea -Implementa una función que toma una función como su primer argumento, un numero `num` como su segundo argumento, entonces ejecuta la función pasada `num` veces. +Implementa una función que toma una función como su primer argumento, un número `num` como su segundo argumento, entonces ejecuta la función pasada `num` veces. Usa la plantilla de código dada a ti en la parte inferior, La mayoría o todos los ejercicios proveerán una plantilla. ## Argumentos - `operation`: Una function, no toma argumentos y no retorna ningún valor de uso. -- `num`: El numero de veces que se debe llamar la función `operation`. +- `num`: El número de veces que se debe llamar la función `operation`. ## Recursos diff --git a/exercises/partial_application_without_bind/problem.es.md b/exercises/partial_application_without_bind/problem.es.md index 15fdd52..44325da 100644 --- a/exercises/partial_application_without_bind/problem.es.md +++ b/exercises/partial_application_without_bind/problem.es.md @@ -1,6 +1,6 @@ -La aplicación parcial te permite crear nuevas funciónes de funciónes existentes, mientras permite ajustar algún numero de argumentos. Luego de ajustar algunos argumentos para ser aplicados parcialmente, obtienes una nueva función para obtener el resto de los argumentos y quizás ejecutar la función original. +La aplicación parcial te permite crear nuevas funciónes de funciónes existentes, mientras permite ajustar algún número de argumentos. Luego de ajustar algunos argumentos para ser aplicados parcialmente, obtienes una nueva función para obtener el resto de los argumentos y quizás ejecutar la función original. -Formalmente: La aplicación parcial se refiere al proceso de ajustar un numero de argumentos para una función, produciendo una función con una aridad (cantidad de argumentos) menor. +Formalmente: La aplicación parcial se refiere al proceso de ajustar un número de argumentos para una función, produciendo una función con una aridad (cantidad de argumentos) menor. Como ejemplo, digamos que tenemos una función `add`, que toma dos argumentos y los suma: @@ -84,7 +84,7 @@ module.exports = logger; ## Pista -Recuerda que `console.log` toma cualquier numero de argumentos y los imprime, separados por espacios: +Recuerda que `console.log` toma cualquier número de argumentos y los imprime, separados por espacios: ```js console.log("hello", "world"); // => 'hello world' diff --git a/exercises/trampoline/problem.es.md b/exercises/trampoline/problem.es.md index 7396226..427abb3 100644 --- a/exercises/trampoline/problem.es.md +++ b/exercises/trampoline/problem.es.md @@ -1,4 +1,4 @@ -The boilerplate includes a definition of `repeat`. `repeat` will take a Function operation, and a Number num, and invoke operation num times: +La plantilla incluye una definición de `repeat`. `repeat` tomará como argumentos una función y un número `num`, e invocará la función `num` veces: ```js var count = 0; @@ -6,11 +6,11 @@ repeat(function() { count++; }, 100); -console.log("executed %d times.", count); -// => executed 100 times. +console.log("se ejecutó %d veces.", count); +// => se ejecuto 100 veces. ``` -BUT note that executing `repeat` with a large `num` causes a stack overflow: +PERO nota que ejecutar `repeat` con un número grande en `num` genera un `stack overflow`: ``` var count = 0 @@ -18,43 +18,42 @@ repeat(function() { count++ }, 100000) -console.log('executed %d times', count) +console.log('se ejecutó %d veces', count) // => RangeError: Maximum call stack size exceeded ``` # Tarea -Modify the boilerplate below such that it uses a trampoline to continuously call itself synchronously. +Modifica la plantilla abajo de forma que use un trampolín para llamarse continuamente a si mismo de forma sincronizada. -You can assume that the operation passed to repeat does not take arguments (or they are already bound to the function) and the return value is not important. +Puedes asumir que la operación pasada a `repeat` no recibe argumentos (o que han sido conectados previamente a la función) y el valor de retorno de la función no es importante. ## Condiciones -- Do not change the implementation of repeat to include any loops - (you may change it in other ways though). +- No cambies la implementación de `repeat` para que incluya ciclos (aunque la puedes cambiar de otras maneras). ## Pista -- Modify `repeat` so it returns the 'next step', if there is one. -- A trampoline continues to synchronously execute steps, getting new steps, until there are no more steps. You can use a loop here! -- If your program takes a long time to run, something is probably wrong. Use Control - C to kill the node process. +- Modifica `repeat` para que retorne el "siguiente paso, si lo hay. +- Un trampolín continua ejecutando los pasos de forma sincronizada, obteniendo nuevos pasos hasta que no haya mas pasos. !Puedes usar un ciclo aquí!. +- Si tu programa toma mucho tiempo en correr, probablemente algo se encuentre mal. Usa `Ctrl+C` para matar el proceso de `Node`. ## Plantilla ```js function repeat(operation, num) { - // Modify this so it doesn't cause a stack overflow! + // Modifica esto de manera que no cause un `stack overflow`! if (num <= 0) return; operation(); return repeat(operation, --num); } -function trampoline(fn) { - // You probably want to implement a trampoline! +function trampolíne(fn) { + // ¡Probablemente quieras implementar un trampolín! } module.exports = function(operation, num) { - // You probably want to call your trampoline here! + // ¡Probablemente quieras llamar tu trampolín aquí! return repeat(operation, num); }; ``` diff --git a/i18n/es.json b/i18n/es.json index c16e6a3..7892e05 100644 --- a/i18n/es.json +++ b/i18n/es.json @@ -8,11 +8,31 @@ "module_not_found": "No se pudo encontrar tu archivo. Asegúrate de que la ruta es correcta.", "must_export_function": "Siempre deberías retornar una función usando el objeto module.exports." }, - "input": "input: %s", + "input": "input: %s", "submission": "sumisión: %s", "solution": "solución: %s" } }, + "exercise": { + "Hello World": "Hola Mundo", + "Higher Order Functions": "Funciones `higher-order` (de alto orden)", + "Basic: Map": "Fundamentos: `Map`", + "Basic: Filter": "Fundamentos: `Filter`", + "Basic: Every Some": "Fundamentos: `Every`, `Some`", + "Basic: Reduce": "Fundamentos: `Reduce`", + "Basic: Recursion": "Fundamentos: Recursividad", + "Basic: Call": "Fundamentos: `Call`", + "Partial Application without Bind": "Aplicación parcial sin Bind", + "Partial Application with Bind": "Aplicación parcial con Bind", + "Implement Map with Reduce": "Implementar `Map` con la ayuda de `Reduce`", + "Function Spies": "Espiás en las funciones", + "Blocking Event Loop": "Bloqueando ciclos de eventos", + "Trampoline": "Trampolines", + "Async Loops": "Ciclos asíncronos", + "Recursion": "Recursividad", + "Currying": "`Currying`", + "Function Call": "Llamada de funciones" + }, "exercises": { "Basic: Map": { "didnt_use_map": "No usaste Array#map", From f1d1111ffbc6afa707f05301135081d317b187d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=2E=20Pardo?= Date: Fri, 21 Jun 2019 22:03:46 -0500 Subject: [PATCH 25/25] fix(Spanish Translation): Fix typos --- exercises/async_loops/problem.es.md | 2 +- exercises/function_spies/problem.es.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/async_loops/problem.es.md b/exercises/async_loops/problem.es.md index 21ecb00..5ca375f 100644 --- a/exercises/async_loops/problem.es.md +++ b/exercises/async_loops/problem.es.md @@ -20,7 +20,7 @@ module.exports = loadUsers; ## Parámetros -- `userIds`: Un Array de IDs de usuario numéricos. +- `userIds`: Un `Array` de IDs de usuario numéricos. - `load`: Una función usada para cargar un objeto de tipo usuario. Recibe un ID numérico y un callback. El callback será llamado con el resultado de cargar el usuario con el ID provisto (puede ser un objeto usuario o `null`). - `done`: Una función que recibe un Array de objetos usuario (como los devueltos en `load`). diff --git a/exercises/function_spies/problem.es.md b/exercises/function_spies/problem.es.md index 74e82a0..491716f 100644 --- a/exercises/function_spies/problem.es.md +++ b/exercises/function_spies/problem.es.md @@ -8,9 +8,9 @@ Crea un espía que mantiene cuenta de cuantas veces una función fue llamada; ```js var spy = Spy(console, "error"); -console.error("calling console.error"); -console.error("calling console.error"); -console.error("calling console.error"); +console.error("llamando `console.error`"); +console.error("llamando `console.error`"); +console.error("llamando `console.error`"); console.log(spy.count); // 3 ```