diff --git a/modules/10-basics/10-hello-world/description.es.yml b/modules/10-basics/10-hello-world/description.es.yml index b7723334..3c8b2d2f 100644 --- a/modules/10-basics/10-hello-world/description.es.yml +++ b/modules/10-basics/10-hello-world/description.es.yml @@ -2,16 +2,62 @@ name: ¡Hola, Mundo! theory: | - Por lo general, el aprendizaje de un nuevo lenguaje de programación comienza con 'Hello, World!'. Es un programa simple que muestra un saludo en la pantalla y al mismo tiempo familiariza con el nuevo lenguaje, así como con su sintaxis y la estructura del programa.. Esta tradición tiene más de cuarenta años, por lo que no la romperemos: en la primera lección escribiremos el programa `Hello, World!`. - - Este programa mostrará el siguiente texto en la pantalla: + El aprendizaje de un nuevo lenguaje de programación comienza tradicionalmente con un programa 'Hello, World!'. Es un programa simple que muestra un saludo en la pantalla y familiariza con la sintaxis y la estructura del nuevo lenguaje. ```text - Hello, World! + Hello, World! + ``` + + Esta tradición tiene ya más de cuarenta años, y nosotros también comenzaremos con ella. En la primera lección escribiremos un programa `Hello, World!`. En JavaScript, este programa se ve así: + + ```javascript + console.log('Hello, World!'); ``` - Para mostrar algo en la pantalla, es necesario darle al ordenador un comando especial. En el lenguaje JavaScript, ese comando es `console.log()`. + El comando `console.log()` muestra en la pantalla el texto indicado entre paréntesis. En lugar del ejemplo puedes escribir cualquier otro texto. + ```javascript + console.log('Hexlet - escuela de programación'); + ``` + + El comando sigue siendo el mismo, solo cambia el contenido entre paréntesis. Para que el programa entienda que se trata precisamente de texto, este se encierra entre comillas. Puedes usar comillas simples `'...'` o dobles `"..."`, pero las comillas de apertura y de cierre deben coincidir. + + ```javascript + console.log("Hexlet - escuela de programación"); + ``` + + Según el estilo aceptado en la comunidad de JavaScript, se recomienda usar comillas simples para las cadenas. Si dentro de la cadena hay un apóstrofo, las comillas simples romperán la sintaxis, por lo que en esos casos se usan comillas dobles. + + ```javascript + console.log("it's JavaScript"); // apóstrofo dentro, por eso comillas dobles + ``` + + ## El significado de los símbolos + + El código está formado por comandos, y cada uno de ellos debe escribirse de una forma determinada. Además de las letras, en el código son importantes las comillas `'` y `"`, los paréntesis `()` y los signos de puntuación. Un signo omitido o confundido hará que el programa no se ejecute. ¿Puedes intentar determinar qué error se cometió en cada una de las líneas? + + ```javascript + console.log("it's JavaScript" + console.log(it's JavaScript") + consol.log("it's JavaScript") + console.log('it's JavaScript") + consolelog("it's JavaScript") + ``` + + Incluso una pequeña diferencia, por ejemplo una letra de más o un signo distinto, puede hacer que el programa no funcione. Esto también se aplica a las mayúsculas y minúsculas, es decir, a la diferencia entre letras grandes y pequeñas. Mientras que en el texto ordinario `Hola` y `hola` se ven iguales, para JavaScript son palabras diferentes. JavaScript considera `console.log`, `Console.Log` y `CONSOLE.LOG` como comandos diferentes, y solo funcionará la primera variante. + + ## Dónde practicar + + La teoría se asimila mejor cuando ejecutas el código en paralelo y ves el resultado. Para esto sirve la consola del navegador (DevTools), donde los comandos se ejecutan línea por línea. Todo lo que aparece en la lección vale la pena probarlo [en la consola del navegador](https://developer.chrome.com/docs/devtools/console/). + + ¿Cómo funciona esto técnicamente? Cualquier código que se escribe se pasa al motor de JavaScript, que ejecuta ese código y muestra en la pantalla el resultado de su trabajo. + + ```text + Código Motor JS Pantalla + ┌──────────────────┐ ┌───────────┐ ┌──────────────┐ + │ console.log(…) │──→│JavaScript │──→│ Hello, World!│ + └──────────────────┘ └───────────┘ └──────────────┘ + ``` instructions: | Escribe en el editor el código del ejercicio, carácter por carácter, y luego haz clic en "Comprobar". @@ -19,8 +65,7 @@ instructions: | console.log('Hello, World!'); ``` - Atención: si escribes `heLLo, woRld!` en lugar de `Hello, World!`, se considerará un texto diferente, ya que las mayúsculas y minúsculas son caracteres distintos. El *tamaño de las letras* es importante y es por eso que dicen que: ¡*las mayúsculas importan*!. Esto se aplica a casi todo el código, así que acostúmbrate a prestar siempre atención a las mayúsculas. - + Atención: si escribes `heLLo, woRld!` en lugar de `Hello, World!`, se considerará un texto diferente, porque las mayúsculas y minúsculas son caracteres distintos. El tamaño de una letra se llama *caja* (mayúscula o minúscula), y se dice: ¡*la caja importa*! Esto se aplica a casi todo en el código, así que acostúmbrate a prestar siempre atención a las mayúsculas y minúsculas. tips: - | [Un poco sobre 'Hello, World!'](https://codica.la/blog/mi-gente-me-entiende-la-historia-de-la-frase-hello-world-y-sus-analogos) diff --git a/modules/10-basics/10-hello-world/en/EXERCISE.md b/modules/10-basics/10-hello-world/en/EXERCISE.md index 2ab96e5a..3d6b85aa 100644 --- a/modules/10-basics/10-hello-world/en/EXERCISE.md +++ b/modules/10-basics/10-hello-world/en/EXERCISE.md @@ -1,6 +1,7 @@ -Copy the exact code from the instructions into the editor and run it by clicking “Run”. +Type the code from the task into the editor character by character and click "Check". ```javascript console.log('Hello, World!'); ``` -Note that if you type `hello, woRld!` instead of `Hello, World!`, it will count as different text, because upper and lowercase letters are different symbols in JavaScript. Letter size is called *case*, and any programmer will tell you that *case is important*. This rule affects almost everything in coding, so make sure you get used to paying close attention to the case at all times. + +Note: if you write `heLLo, woRld!` instead of `Hello, World!`, it will be considered different text, because uppercase and lowercase letters are different characters. The size of a letter is called *case*, and people say: *case matters!* This applies to almost everything in code, so get used to always paying attention to case. diff --git a/modules/10-basics/10-hello-world/en/README.md b/modules/10-basics/10-hello-world/en/README.md index dde799d8..29d27fcd 100644 --- a/modules/10-basics/10-hello-world/en/README.md +++ b/modules/10-basics/10-hello-world/en/README.md @@ -1,7 +1,56 @@ -As is tradition, we'll start by writing a 'Hello, World!' program. The program will print the following text: +Learning a new programming language traditionally begins with a 'Hello, World!' program. This is a simple program that prints a greeting to the screen and introduces the syntax and structure of the new language. ```text - Hello, World! +Hello, World! ``` -To print something, you need to give computer a special command. In JavaScript, we use `console.log()`. +This tradition is already more than forty years old, and we will start with it too. In the first lesson, we will write a `Hello, World!` program. In JavaScript, this program looks like this: + +```javascript +console.log('Hello, World!'); +``` + +The `console.log()` command prints to the screen the text specified in parentheses. Instead of the example, you can write any other text. + +```javascript +console.log('Hexlet - programming school'); +``` + +The command stays the same, only the contents of the parentheses change. So that the program understands that this is exactly text, it is enclosed in quotes. You can use single `'...'` or double `"..."` quotes, but the opening and closing quotes must match. + +```javascript +console.log("Hexlet - programming school"); +``` + +According to the style accepted in the JavaScript community, single quotes are recommended for strings. If there is an apostrophe inside the string, single quotes will break the syntax, so in such cases double quotes are used. + +```javascript +console.log("it's JavaScript"); // apostrophe inside, so double quotes +``` + +## The meaning of symbols + +Code consists of commands, and each of them must be written in a specific form. Besides letters, quotes `'` and `"`, parentheses `()`, and punctuation marks are important in code. A missing or mixed-up sign will cause the program not to run. Try to determine what error was made in each of the lines? + +```javascript +console.log("it's JavaScript" +console.log(it's JavaScript") +consol.log("it's JavaScript") +console.log('it's JavaScript") +consolelog("it's JavaScript") +``` + +Even a small difference, for example one extra letter or a different sign, can cause the program not to work. This also applies to case, that is, to the difference between uppercase and lowercase letters. While in ordinary text `Hello` and `hello` look the same, for JavaScript these are different words. JavaScript considers `console.log`, `Console.Log`, and `CONSOLE.LOG` to be different commands, and only the first variant will work. + +## Where to practice + +Theory is absorbed better when you run code in parallel and see the result. The browser console (DevTools) is suitable for this, where commands are executed line by line. Everything that appears in the lesson is worth trying [in the browser console](https://developer.chrome.com/docs/devtools/console/). + +How does this work technically? Any code that is written is passed to the JavaScript engine, which executes this code and prints the result of its work to the screen. + +```text +Code JS Engine Screen +┌──────────────────┐ ┌───────────┐ ┌──────────────┐ +│ console.log(…) │──→│JavaScript │──→│ Hello, World!│ +└──────────────────┘ └───────────┘ └──────────────┘ +``` diff --git a/modules/10-basics/10-hello-world/en/data.yml b/modules/10-basics/10-hello-world/en/data.yml index dee7d3fe..20cc1c72 100644 --- a/modules/10-basics/10-hello-world/en/data.yml +++ b/modules/10-basics/10-hello-world/en/data.yml @@ -2,5 +2,5 @@ name: Hello, World! tips: - > - [Read more about 'Hello, + [A bit about 'Hello, World!'](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program) diff --git a/modules/10-basics/10-hello-world/es/EXERCISE.md b/modules/10-basics/10-hello-world/es/EXERCISE.md index f378f902..56f065f3 100644 --- a/modules/10-basics/10-hello-world/es/EXERCISE.md +++ b/modules/10-basics/10-hello-world/es/EXERCISE.md @@ -4,4 +4,4 @@ Escribe en el editor el código del ejercicio, carácter por carácter, y luego console.log('Hello, World!'); ``` -Atención: si escribes `heLLo, woRld!` en lugar de `Hello, World!`, se considerará un texto diferente, ya que las mayúsculas y minúsculas son caracteres distintos. El *tamaño de las letras* es importante y es por eso que dicen que: ¡*las mayúsculas importan*!. Esto se aplica a casi todo el código, así que acostúmbrate a prestar siempre atención a las mayúsculas. +Atención: si escribes `heLLo, woRld!` en lugar de `Hello, World!`, se considerará un texto diferente, porque las mayúsculas y minúsculas son caracteres distintos. El tamaño de una letra se llama *caja* (mayúscula o minúscula), y se dice: ¡*la caja importa*! Esto se aplica a casi todo en el código, así que acostúmbrate a prestar siempre atención a las mayúsculas y minúsculas. diff --git a/modules/10-basics/10-hello-world/es/README.md b/modules/10-basics/10-hello-world/es/README.md index fe2c2e64..7cc5cd18 100644 --- a/modules/10-basics/10-hello-world/es/README.md +++ b/modules/10-basics/10-hello-world/es/README.md @@ -1,9 +1,56 @@ -Por lo general, el aprendizaje de un nuevo lenguaje de programación comienza con 'Hello, World!'. Es un programa simple que muestra un saludo en la pantalla y al mismo tiempo familiariza con el nuevo lenguaje, así como con su sintaxis y la estructura del programa.. Esta tradición tiene más de cuarenta años, por lo que no la romperemos: en la primera lección escribiremos el programa `Hello, World!`. - -Este programa mostrará el siguiente texto en la pantalla: +El aprendizaje de un nuevo lenguaje de programación comienza tradicionalmente con un programa 'Hello, World!'. Es un programa simple que muestra un saludo en la pantalla y familiariza con la sintaxis y la estructura del nuevo lenguaje. ```text - Hello, World! +Hello, World! +``` + +Esta tradición tiene ya más de cuarenta años, y nosotros también comenzaremos con ella. En la primera lección escribiremos un programa `Hello, World!`. En JavaScript, este programa se ve así: + +```javascript +console.log('Hello, World!'); +``` + +El comando `console.log()` muestra en la pantalla el texto indicado entre paréntesis. En lugar del ejemplo puedes escribir cualquier otro texto. + +```javascript +console.log('Hexlet - escuela de programación'); +``` + +El comando sigue siendo el mismo, solo cambia el contenido entre paréntesis. Para que el programa entienda que se trata precisamente de texto, este se encierra entre comillas. Puedes usar comillas simples `'...'` o dobles `"..."`, pero las comillas de apertura y de cierre deben coincidir. + +```javascript +console.log("Hexlet - escuela de programación"); ``` -Para mostrar algo en la pantalla, es necesario darle al ordenador un comando especial. En el lenguaje JavaScript, ese comando es `console.log()`. +Según el estilo aceptado en la comunidad de JavaScript, se recomienda usar comillas simples para las cadenas. Si dentro de la cadena hay un apóstrofo, las comillas simples romperán la sintaxis, por lo que en esos casos se usan comillas dobles. + +```javascript +console.log("it's JavaScript"); // apóstrofo dentro, por eso comillas dobles +``` + +## El significado de los símbolos + +El código está formado por comandos, y cada uno de ellos debe escribirse de una forma determinada. Además de las letras, en el código son importantes las comillas `'` y `"`, los paréntesis `()` y los signos de puntuación. Un signo omitido o confundido hará que el programa no se ejecute. ¿Puedes intentar determinar qué error se cometió en cada una de las líneas? + +```javascript +console.log("it's JavaScript" +console.log(it's JavaScript") +consol.log("it's JavaScript") +console.log('it's JavaScript") +consolelog("it's JavaScript") +``` + +Incluso una pequeña diferencia, por ejemplo una letra de más o un signo distinto, puede hacer que el programa no funcione. Esto también se aplica a las mayúsculas y minúsculas, es decir, a la diferencia entre letras grandes y pequeñas. Mientras que en el texto ordinario `Hola` y `hola` se ven iguales, para JavaScript son palabras diferentes. JavaScript considera `console.log`, `Console.Log` y `CONSOLE.LOG` como comandos diferentes, y solo funcionará la primera variante. + +## Dónde practicar + +La teoría se asimila mejor cuando ejecutas el código en paralelo y ves el resultado. Para esto sirve la consola del navegador (DevTools), donde los comandos se ejecutan línea por línea. Todo lo que aparece en la lección vale la pena probarlo [en la consola del navegador](https://developer.chrome.com/docs/devtools/console/). + +¿Cómo funciona esto técnicamente? Cualquier código que se escribe se pasa al motor de JavaScript, que ejecuta ese código y muestra en la pantalla el resultado de su trabajo. + +```text +Código Motor JS Pantalla +┌──────────────────┐ ┌───────────┐ ┌──────────────┐ +│ console.log(…) │──→│JavaScript │──→│ Hello, World!│ +└──────────────────┘ └───────────┘ └──────────────┘ +``` diff --git a/modules/10-basics/20-comments/description.es.yml b/modules/10-basics/20-comments/description.es.yml index a4946543..a5a10f6a 100644 --- a/modules/10-basics/20-comments/description.es.yml +++ b/modules/10-basics/20-comments/description.es.yml @@ -2,8 +2,7 @@ name: Comentarios theory: | - - Además del código en sí, los archivos de código fuente pueden contener comentarios. Estos son textos que no forman parte del programa y son útiles para los programadores como notas. Con ellos se pueden agregar explicaciones sobre cómo funciona el código, qué errores corregir o qué agregar más adelante. + Además del código, los archivos de código fuente pueden contener comentarios. Estos son textos que no forman parte del programa y son útiles para los programadores como notas. Con ellos se pueden agregar explicaciones sobre cómo funciona el código, qué errores hay que corregir aquí o recordatorios de agregar algo más adelante. ```javascript // Eliminar la línea de abajo después de implementar la tarea de registro @@ -26,7 +25,7 @@ theory: | Un comentario puede estar en una línea después de algún código: ```javascript - console.log('Soy el Rey'); // For Lannisters! + console.log('I am the King'); // For Lannisters! ``` ## Comentarios de varias líneas @@ -41,26 +40,40 @@ theory: | console.log('I am the King'); ``` - Estos comentarios generalmente se utilizan para la documentación del código, por ejemplo, en el caso de las funciones. + ## Comentarios de servicio + + Durante el trabajo, te encontrarás con un código así en nuestro editor: + + ```javascript + // BEGIN + + // END + ``` + + *BEGIN* y *END* aquí son comentarios comunes que no afectan en absoluto el funcionamiento del programa. Indican dónde escribir el código de la tarea. + + ```javascript + // BEGIN + + // END + ``` + + Cuando veas *BEGIN* y *END*, escribe tu código entre ellos y deja el resto sin cambios. instructions: | - Crea un comentario de una línea con el texto: ``You know nothing, Jon Snow!`. + Estás escribiendo un programa y te das cuenta de que una parte debe terminarse más tarde. Para no olvidarlo, los programadores dejan notas para sí mismos directamente en el código: los comentarios TODO. + + Agrega al archivo este comentario: + ```javascript + // TODO: add a greeting function + ``` + + Cuando vuelvas a este lugar más tarde, el comentario te recordará que aquí todavía hay trabajo sin terminar. tips: - | [Más información sobre comentarios](https://www.w3schools.com/js/js_comments.asp) - definitions: - - name: Comentario - description: | - texto en el código de un programa que no afecta la funcionalidad y es agregado por los programadores para ellos mismos y sus colegas. - - `// comentario de una línea` - - ``` - /* - comentario de varias líneas - comentario de varias líneas - */ - ``` + - name: "Comentario" + description: "texto en el código de un programa que no afecta la funcionalidad y es agregado por los programadores para ellos mismos y sus colegas." diff --git a/modules/10-basics/20-comments/en/EXERCISE.md b/modules/10-basics/20-comments/en/EXERCISE.md index ab77882f..592e4d0b 100644 --- a/modules/10-basics/20-comments/en/EXERCISE.md +++ b/modules/10-basics/20-comments/en/EXERCISE.md @@ -1 +1,9 @@ -Create a single line comment with the following text: `You know nothing, Jon Snow!`. +You are writing a program and realize that one part needs to be finished later. To avoid forgetting, programmers leave notes for themselves right in the code — TODO comments. + +Add such a comment to the file: + +```javascript +// TODO: add a greeting function +``` + +When you come back to this place later, the comment will remind you that there is still unfinished work here. diff --git a/modules/10-basics/20-comments/en/README.md b/modules/10-basics/20-comments/en/README.md index 990b9ae1..dc1fd7a3 100644 --- a/modules/10-basics/20-comments/en/README.md +++ b/modules/10-basics/20-comments/en/README.md @@ -1,27 +1,60 @@ -Almost every programming language allows you to add comments to your code. An interpreter doesn't evaluate comments, their only purpose is to allow programmers to leave notes for themselves and others. There are two ways to write comments in JavaScript: -**Single line comments** start with `//`. Any text or symbols that follow, won't be evaluated or executed. +In addition to code, source files can contain comments. This is text that is not part of the program and is used by programmers for notes. They are used to add explanations of how the code works, what bugs need to be fixed here, or as reminders to add something later. -A comment can take up the whole line: +```javascript +// Remove the line below after implementing the registration task +console.log(10); +``` + +There are two types of comments in JavaScript: + +## Single-line comments + +*Single-line comments* start with `//`. After these two characters, any text can follow; the entire line will not be analyzed or executed. - ```javascript +A comment can take up the whole line. If one line is not enough, several comments are created: + +```javascript // For Winterfell! +// For Lanisters! ``` -or can follow some code on the same line: +A comment can be placed on a line after some code: ```javascript console.log('I am the King'); // For Lannisters! ``` -**Multiline comments** start with `/*` and end with `*/`. +## Multi-line comments + +*Multi-line comments* start with `/*` and end with `*/`. ```javascript /* The night is dark and full of terrors. - */ +*/ console.log('I am the King'); ``` -Such comments usually clarify the purpose of pieces of code. +Such comments are usually used for documenting code, for example, functions. + +## Service comments + +While working, you will encounter such code in our editor: + +```javascript +// BEGIN + +// END +``` + +*BEGIN* and *END* here are ordinary comments that do not affect the program in any way. They show where to write the code for the task. + +```javascript +// BEGIN + +// END +``` + +When you see *BEGIN* and *END*, write your code between them and leave the rest unchanged. diff --git a/modules/10-basics/20-comments/en/data.yml b/modules/10-basics/20-comments/en/data.yml index 46ce09ea..08af9d80 100644 --- a/modules/10-basics/20-comments/en/data.yml +++ b/modules/10-basics/20-comments/en/data.yml @@ -1,22 +1,23 @@ --- name: Comments -tips: [] +tips: + - | + [More about comments](https://www.w3schools.com/js/js_comments.asp) definitions: - name: Comment - description: > - is a piece of text that does not affect the execution of the program. - Programmers use comments to add notes for themselves or for their - colleagues. + description: >- + text in a program's code that does not affect functionality and is + added by programmers for themselves and their colleagues. - `// single line comment` + `// single-line comment` ``` /* - multiline comment - multiline comment + multi-line comment + multi-line comment */ ``` diff --git a/modules/10-basics/20-comments/es/EXERCISE.md b/modules/10-basics/20-comments/es/EXERCISE.md index 25fd47da..aa2e16b8 100644 --- a/modules/10-basics/20-comments/es/EXERCISE.md +++ b/modules/10-basics/20-comments/es/EXERCISE.md @@ -1 +1,9 @@ -Crea un comentario de una línea con el texto: ``You know nothing, Jon Snow!`. +Estás escribiendo un programa y te das cuenta de que una parte debe terminarse más tarde. Para no olvidarlo, los programadores dejan notas para sí mismos directamente en el código: los comentarios TODO. + +Agrega al archivo este comentario: + +```javascript +// TODO: add a greeting function +``` + +Cuando vuelvas a este lugar más tarde, el comentario te recordará que aquí todavía hay trabajo sin terminar. diff --git a/modules/10-basics/20-comments/es/README.md b/modules/10-basics/20-comments/es/README.md index f429a8b7..08f84148 100644 --- a/modules/10-basics/20-comments/es/README.md +++ b/modules/10-basics/20-comments/es/README.md @@ -1,5 +1,5 @@ -Además del código en sí, los archivos de código fuente pueden contener comentarios. Estos son textos que no forman parte del programa y son útiles para los programadores como notas. Con ellos se pueden agregar explicaciones sobre cómo funciona el código, qué errores corregir o qué agregar más adelante. +Además del código, los archivos de código fuente pueden contener comentarios. Estos son textos que no forman parte del programa y son útiles para los programadores como notas. Con ellos se pueden agregar explicaciones sobre cómo funciona el código, qué errores hay que corregir aquí o recordatorios de agregar algo más adelante. ```javascript // Eliminar la línea de abajo después de implementar la tarea de registro @@ -22,7 +22,7 @@ Un comentario puede ocupar toda una línea. Si una línea no es suficiente, se p Un comentario puede estar en una línea después de algún código: ```javascript -console.log('Soy el Rey'); // For Lannisters! +console.log('I am the King'); // For Lannisters! ``` ## Comentarios de varias líneas @@ -38,3 +38,23 @@ console.log('I am the King'); ``` Estos comentarios generalmente se utilizan para la documentación del código, por ejemplo, en el caso de las funciones. + +## Comentarios de servicio + +Durante el trabajo, te encontrarás con un código así en nuestro editor: + +```javascript +// BEGIN + +// END +``` + +*BEGIN* y *END* aquí son comentarios comunes que no afectan en absoluto el funcionamiento del programa. Indican dónde escribir el código de la tarea. + +```javascript +// BEGIN + +// END +``` + +Cuando veas *BEGIN* y *END*, escribe tu código entre ellos y deja el resto sin cambios. diff --git a/modules/10-basics/20-comments/es/data.yml b/modules/10-basics/20-comments/es/data.yml index b77d169c..df56b7ab 100644 --- a/modules/10-basics/20-comments/es/data.yml +++ b/modules/10-basics/20-comments/es/data.yml @@ -1,12 +1,11 @@ --- name: Comentarios tips: - - > - [Más información sobre - comentarios](https://www.w3schools.com/js/js_comments.asp) + - | + [Más información sobre comentarios](https://www.w3schools.com/js/js_comments.asp) definitions: - name: Comentario - description: > + description: >- texto en el código de un programa que no afecta la funcionalidad y es agregado por los programadores para ellos mismos y sus colegas. diff --git a/modules/10-basics/20-comments/index.js b/modules/10-basics/20-comments/index.js index 83926864..96cba987 100644 --- a/modules/10-basics/20-comments/index.js +++ b/modules/10-basics/20-comments/index.js @@ -1 +1 @@ -// TODO: добавить функцию приветствия +// TODO: add a greeting function diff --git a/modules/10-basics/20-comments/ru/EXERCISE.md b/modules/10-basics/20-comments/ru/EXERCISE.md index 32618f9f..b4a6db1a 100644 --- a/modules/10-basics/20-comments/ru/EXERCISE.md +++ b/modules/10-basics/20-comments/ru/EXERCISE.md @@ -3,7 +3,7 @@ Добавьте в файл такой комментарий: ```javascript -// TODO: добавить функцию приветствия +// TODO: add a greeting function ``` Когда вернётесь к этому месту позже, комментарий напомнит, что здесь ещё есть незавершённая работа. diff --git a/modules/10-basics/20-comments/test.js b/modules/10-basics/20-comments/test.js index 99730f06..41a7da8d 100644 --- a/modules/10-basics/20-comments/test.js +++ b/modules/10-basics/20-comments/test.js @@ -1,12 +1,15 @@ -// @ts-check +// @ts-nocheck -- tsconfig has no Node.js types (types: []), and the test reads the source via node:fs import { readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { expect, test } from 'vitest'; test('comments', () => { - const code = readFileSync(fileURLToPath(new URL('./index.js', import.meta.url)), 'utf-8'); + const code = readFileSync( + fileURLToPath(new URL('./index.js', import.meta.url)), + 'utf-8', + ); - // В коде должен быть хотя бы один строчный TODO-комментарий + // The code must contain at least one single-line TODO comment expect(code).toMatch(/\/\/\s*TODO/i); }); diff --git a/modules/10-basics/40-instructions/description.es.yml b/modules/10-basics/40-instructions/description.es.yml index cb039e39..f834333f 100644 --- a/modules/10-basics/40-instructions/description.es.yml +++ b/modules/10-basics/40-instructions/description.es.yml @@ -2,54 +2,93 @@ name: Instrucciones theory: | - Una instrucción es una orden para que la computadora realice algo. El código en JavaScript es un conjunto de instrucciones que generalmente se separan entre sí con el símbolo `;`. + Podemos llamar instrucción a `console.log('Hexlet')`; le indica al intérprete de JavaScript qué hacer. Puede haber tantas instrucciones como quieras. Cada una se ejecuta después de que la anterior haya terminado, y así, a partir de elementos simples, obtenemos un programa tan grande y complejo como queramos. - Aquí tienes un ejemplo de código con dos instrucciones. + ```text + Instrucción 1: console.log('Hello') → ejecutada + ↓ + Instrucción 2: console.log('World') → ejecutada + ↓ + Instrucción 3: console.log('!') → ejecutada + ``` + + Aquí tienes un ejemplo de código con dos instrucciones. Estas líneas le indican a la computadora que muestre las frases en pantalla. ```javascript - console.log('Mother of Dragons.'); - console.log('Dracarys!'); + console.log('Mother of Dragons.'); // Primera instrucción + console.log('Dracarys!'); // Segunda instrucción ``` - - Al ejecutar este código, se mostrarán en pantalla las dos frases de forma secuencial: + El resultado de la ejecución: ```text Mother of Dragons. Dracarys! ``` - Teóricamente, las instrucciones se pueden escribir una tras otra sin saltar de línea: + ## El orden importa + + El intérprete de JavaScript ejecuta el código estrictamente en el orden en el que lo escribiste. Si intercambias las líneas: ```javascript - console.log('Mother of Dragons.'); console.log('Drakarys!'); + console.log('Dracarys!'); + console.log('Mother of Dragons.'); ``` - El resultado en pantalla será el mismo, pero este tipo de código es incómodo de leer, por lo que las instrucciones se colocan una debajo de la otra. + en la pantalla también aparecerán intercambiadas: - ¿Por qué es importante saber esto? Una instrucción es una unidad de ejecución. El intérprete, el programa que ejecuta el código en JavaScript, ejecuta estrictamente las instrucciones en orden. Como desarrolladores, debemos entender este orden y ser capaces de dividir mentalmente el programa en partes independientes que sean fáciles de analizar. + ```text + Dracarys! + Mother of Dragons. + ``` -instructions: | - Muestra en pantalla, uno tras otro, estos tres nombres: *Robert*, *Stannis*, *Renly*. El resultado en pantalla debe ser: + ## Una forma alternativa de escribirlo - ```text - Robert - Stannis - Renly + Normalmente las instrucciones se escriben en líneas separadas, pero también pueden escribirse en una sola línea separadas por `;`: + + ```javascript + console.log('Mother of Dragons.'); console.log('Dracarys!'); ``` - Utiliza una llamada `console.log()` para cada nombre. + Ambas versiones funcionan igual, pero la segunda es más difícil de leer. Por eso, las instrucciones casi siempre se escriben una por línea. + + ## Por qué es necesario + + Por ahora escribimos programas muy simples, pero con el tiempo empezarán a complicarse, y una de las habilidades más importantes que te ayudará a entenderlos es la capacidad de dividir (mentalmente) el programa en instrucciones independientes. Solo así se puede comprender lo que ocurre en el código. A continuación hay un ejemplo para llamar tu atención; no hace falta que lo entiendas todavía: + + ```javascript + const isPrime = (number) => { + if (number < 2) { + return false; + } + + let divider = 2; + while (divider <= number / 2) { + if (number % divider === 0) { + return false; + } + divider += 1; + } + + return true; + }; + ``` +instructions: | + Muestra en pantalla el estado de entrega del paquete — tres líneas, cada una con una llamada `console.log()` separada: + + ```text + Order #1337 + Status: in delivery + Estimated time: 2 days + ``` tips: - | [Un poco sobre los intérpretes](https://es.wikipedia.org/wiki/Int%C3%A9rprete) - | [Instrucciones y declaraciones por categorías](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements) - definitions: - - name: Intérprete - description: | - Un programa que ejecuta código en JavaScript. - - name: Instrucción - description: | - Una orden para la computadora escrita en un lenguaje de programación. El código en JavaScript es un conjunto de instrucciones separadas (generalmente) por el símbolo `;`. + - name: "Intérprete" + description: "un programa que ejecuta código en JavaScript." + - name: "Instrucción" + description: "una orden para la computadora escrita en un lenguaje de programación. El código en JavaScript es un conjunto de instrucciones separadas (generalmente) por el símbolo `;`." diff --git a/modules/10-basics/40-instructions/en/EXERCISE.md b/modules/10-basics/40-instructions/en/EXERCISE.md index ae7ee406..5578558f 100644 --- a/modules/10-basics/40-instructions/en/EXERCISE.md +++ b/modules/10-basics/40-instructions/en/EXERCISE.md @@ -1,9 +1,7 @@ -Print these three names, one after the other: "Robert", "Stannis", "Renly". As a result, the editor should print: +Print the parcel delivery status to the screen — three lines, each with a separate `console.log()` call: ```text -Robert -Stannis -Renly +Order #1337 +Status: in delivery +Estimated time: 2 days ``` - -Call `console.log()` for each name. diff --git a/modules/10-basics/40-instructions/en/README.md b/modules/10-basics/40-instructions/en/README.md index f659b181..230ec08c 100644 --- a/modules/10-basics/40-instructions/en/README.md +++ b/modules/10-basics/40-instructions/en/README.md @@ -1,25 +1,72 @@ -A statement is a command given to a computer to do something. The JavaScript code is a set of statements which are usually separated by a `;` symbol. +We can call `console.log('Hexlet')` a statement; it tells the JavaScript interpreter what to do. There can be as many such statements as you like. Each one runs after the previous one has finished, and that is how we build an arbitrarily large and complex program out of simple elements. -Here is an example of some code with two statements. +```text +Statement 1: console.log('Hello') → executed + ↓ +Statement 2: console.log('World') → executed + ↓ +Statement 3: console.log('!') → executed +``` + +Here is an example of code with two statements. These lines tell the computer to print phrases on the screen. ```javascript -console.log('Mother of Dragons.'); -console.log('Dracarys!'); +console.log('Mother of Dragons.'); // First statement +console.log('Dracarys!'); // Second statement ``` -When you run this code you will see two sentences on the screen, one after the other. +The result: ```text Mother of Dragons. Dracarys! ``` -Theoretically, it's possible to put multiple statements on the same string: +## Order matters + +The JavaScript interpreter runs code strictly in the order in which you wrote it. If you swap the lines: + +```javascript +console.log('Dracarys!'); +console.log('Mother of Dragons.'); +``` + +they will be swapped on the screen as well: + +```text +Dracarys! +Mother of Dragons. +``` + +## An alternative way to write it + +Usually statements are written on separate lines, but they can also be written on a single line separated by `;`: ```javascript -console.log('Mother of Dragons.'); console.log('Drakarys!'); +console.log('Mother of Dragons.'); console.log('Dracarys!'); ``` -but it's considered bad practice as it's difficult to read. +Both versions work the same way, but the second one is harder to read. That is why statements are almost always written one per line. + +## Why this matters -Why is it important to know? A statement is a unit of execution. An interpreter, which is the program which executes code in JavaScript, needs statements to be split in this way. This interpreter in JavaScript world is any browser (as it's able to JavaScript code) or Node.js (for the same reason). An interpreter's principle of operation is (approximately) as follows. It reads the file with the code, splits the code into statements, and then executes them. +Right now we are writing very simple programs, but over time they will start to grow more complex, and one of the most important skills that will help you understand them is the ability to break a program (in your head) into independent statements. That is the only way to figure out what is going on in the code. Below is an example to grab your attention; you don't need to understand it yet: + +```javascript +const isPrime = (number) => { + if (number < 2) { + return false; + } + + let divider = 2; + + while (divider <= number / 2) { + if (number % divider === 0) { + return false; + } + divider += 1; + } + + return true; +}; +``` diff --git a/modules/10-basics/40-instructions/en/data.yml b/modules/10-basics/40-instructions/en/data.yml index a22fb48e..f8df9c2d 100644 --- a/modules/10-basics/40-instructions/en/data.yml +++ b/modules/10-basics/40-instructions/en/data.yml @@ -1,17 +1,16 @@ --- name: Statements tips: - - > - [More about - interpreters](https://en.wikipedia.org/wiki/Interpreter_(computing)) + - | + [A bit about interpreters](https://en.wikipedia.org/wiki/Interpreter_(computing)) - > [Statements and declarations by - category](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements) + category](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements) definitions: - name: Interpreter - description: | - is a program that executes the code in JavaScript. + description: >- + a program that executes JavaScript code. - name: Statement - description: > - is a command given to a computer. The JavaScript code is a set of - statements separated (most frequently) by `;`. + description: >- + a command for the computer, written in a programming language. JavaScript + code is a set of statements separated (most often) by the `;` character. diff --git a/modules/10-basics/40-instructions/es/EXERCISE.md b/modules/10-basics/40-instructions/es/EXERCISE.md index c288bb3c..b364b7e5 100644 --- a/modules/10-basics/40-instructions/es/EXERCISE.md +++ b/modules/10-basics/40-instructions/es/EXERCISE.md @@ -1,9 +1,7 @@ -Muestra en pantalla, uno tras otro, estos tres nombres: *Robert*, *Stannis*, *Renly*. El resultado en pantalla debe ser: +Muestra en pantalla el estado de entrega del paquete — tres líneas, cada una con una llamada `console.log()` separada: ```text -Robert -Stannis -Renly +Order #1337 +Status: in delivery +Estimated time: 2 days ``` - -Utiliza una llamada `console.log()` para cada nombre. diff --git a/modules/10-basics/40-instructions/es/README.md b/modules/10-basics/40-instructions/es/README.md index 815ca0cc..9c1756d8 100644 --- a/modules/10-basics/40-instructions/es/README.md +++ b/modules/10-basics/40-instructions/es/README.md @@ -1,25 +1,72 @@ -Una instrucción es una orden para que la computadora realice algo. El código en JavaScript es un conjunto de instrucciones que generalmente se separan entre sí con el símbolo `;`. +Podemos llamar instrucción a `console.log('Hexlet')`; le indica al intérprete de JavaScript qué hacer. Puede haber tantas instrucciones como quieras. Cada una se ejecuta después de que la anterior haya terminado, y así, a partir de elementos simples, obtenemos un programa tan grande y complejo como queramos. -Aquí tienes un ejemplo de código con dos instrucciones. +```text +Instrucción 1: console.log('Hello') → ejecutada + ↓ +Instrucción 2: console.log('World') → ejecutada + ↓ +Instrucción 3: console.log('!') → ejecutada +``` + +Aquí tienes un ejemplo de código con dos instrucciones. Estas líneas le indican a la computadora que muestre las frases en pantalla. ```javascript -console.log('Mother of Dragons.'); -console.log('Dracarys!'); +console.log('Mother of Dragons.'); // Primera instrucción +console.log('Dracarys!'); // Segunda instrucción ``` -Al ejecutar este código, se mostrarán en pantalla las dos frases de forma secuencial: +El resultado de la ejecución: ```text Mother of Dragons. Dracarys! ``` -Teóricamente, las instrucciones se pueden escribir una tras otra sin saltar de línea: +## El orden importa + +El intérprete de JavaScript ejecuta el código estrictamente en el orden en el que lo escribiste. Si intercambias las líneas: + +```javascript +console.log('Dracarys!'); +console.log('Mother of Dragons.'); +``` + +en la pantalla también aparecerán intercambiadas: + +```text +Dracarys! +Mother of Dragons. +``` + +## Una forma alternativa de escribirlo + +Normalmente las instrucciones se escriben en líneas separadas, pero también pueden escribirse en una sola línea separadas por `;`: ```javascript -console.log('Mother of Dragons.'); console.log('Drakarys!'); +console.log('Mother of Dragons.'); console.log('Dracarys!'); ``` -El resultado en pantalla será el mismo, pero este tipo de código es incómodo de leer, por lo que las instrucciones se colocan una debajo de la otra. +Ambas versiones funcionan igual, pero la segunda es más difícil de leer. Por eso, las instrucciones casi siempre se escriben una por línea. + +## Por qué es necesario -¿Por qué es importante saber esto? Una instrucción es una unidad de ejecución. El intérprete, el programa que ejecuta el código en JavaScript, ejecuta estrictamente las instrucciones en orden. Como desarrolladores, debemos entender este orden y ser capaces de dividir mentalmente el programa en partes independientes que sean fáciles de analizar. +Por ahora escribimos programas muy simples, pero con el tiempo empezarán a complicarse, y una de las habilidades más importantes que te ayudará a entenderlos es la capacidad de dividir (mentalmente) el programa en instrucciones independientes. Solo así se puede comprender lo que ocurre en el código. A continuación hay un ejemplo para llamar tu atención; no hace falta que lo entiendas todavía: + +```javascript +const isPrime = (number) => { + if (number < 2) { + return false; + } + + let divider = 2; + + while (divider <= number / 2) { + if (number % divider === 0) { + return false; + } + divider += 1; + } + + return true; +}; +``` diff --git a/modules/10-basics/40-instructions/es/data.yml b/modules/10-basics/40-instructions/es/data.yml index 3c643bc1..3d8fc855 100644 --- a/modules/10-basics/40-instructions/es/data.yml +++ b/modules/10-basics/40-instructions/es/data.yml @@ -1,18 +1,17 @@ --- name: Instrucciones tips: - - > - [Un poco sobre los - intérpretes](https://es.wikipedia.org/wiki/Int%C3%A9rprete) + - | + [Un poco sobre los intérpretes](https://es.wikipedia.org/wiki/Int%C3%A9rprete) - > [Instrucciones y declaraciones por categorías](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements) definitions: - name: Intérprete - description: | - Un programa que ejecuta código en JavaScript. + description: >- + un programa que ejecuta código en JavaScript. - name: Instrucción - description: > - Una orden para la computadora escrita en un lenguaje de programación. El + description: >- + una orden para la computadora escrita en un lenguaje de programación. El código en JavaScript es un conjunto de instrucciones separadas (generalmente) por el símbolo `;`. diff --git a/modules/10-basics/40-instructions/index.js b/modules/10-basics/40-instructions/index.js index 057cf58b..06a953f1 100644 --- a/modules/10-basics/40-instructions/index.js +++ b/modules/10-basics/40-instructions/index.js @@ -1,3 +1,3 @@ -console.log('Заказ №1337'); -console.log('Статус: доставляется'); -console.log('Примерный срок: 2 дня'); +console.log('Order #1337'); +console.log('Status: in delivery'); +console.log('Estimated time: 2 days'); diff --git a/modules/10-basics/40-instructions/ru/EXERCISE.md b/modules/10-basics/40-instructions/ru/EXERCISE.md index 0c0750fc..9d3c5539 100644 --- a/modules/10-basics/40-instructions/ru/EXERCISE.md +++ b/modules/10-basics/40-instructions/ru/EXERCISE.md @@ -1,7 +1,7 @@ Выведите на экран статус доставки посылки — три строки, каждая отдельным вызовом `console.log()`: ```text -Заказ №1337 -Статус: доставляется -Примерный срок: 2 дня +Order #1337 +Status: in delivery +Estimated time: 2 days ``` diff --git a/modules/10-basics/40-instructions/test.js b/modules/10-basics/40-instructions/test.js index d63757f8..5d4beef8 100644 --- a/modules/10-basics/40-instructions/test.js +++ b/modules/10-basics/40-instructions/test.js @@ -9,6 +9,6 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); expect(firstArg).toBe( - 'Заказ №1337\nСтатус: доставляется\nПримерный срок: 2 дня', + 'Order #1337\nStatus: in delivery\nEstimated time: 2 days', ); }); diff --git a/modules/10-basics/45-testing/description.es.yml b/modules/10-basics/45-testing/description.es.yml index a8204391..11499d48 100644 --- a/modules/10-basics/45-testing/description.es.yml +++ b/modules/10-basics/45-testing/description.es.yml @@ -2,20 +2,15 @@ name: Cómo verificamos tus soluciones theory: | + Nuestro sitio web verifica automáticamente tus soluciones. ¿Cómo funciona? - El sitio web verifica automáticamente tus soluciones. ¿Cómo funciona? + En el caso más simple, la verificación ejecuta tu código y compara la salida en pantalla con el resultado esperado. Por ejemplo, si la tarea dice: "Muestra el número 10 en pantalla", entonces tu código en JavaScript podría verse así: - En el caso más simple, el sistema simplemente ejecuta tu código y verifica lo que se muestra en la pantalla. Luego lo compara con lo que "esperábamos" según la tarea. - - En lecciones más avanzadas, escribirás funciones, que son pequeños programas que toman información del mundo exterior y realizan operaciones. La verificación de tus soluciones en estos casos es un poco más complicada: el sistema ejecuta tu solución y le pasa cierta información. El sistema también sabe qué respuesta debería dar la función correcta con esos datos de entrada. - - Por ejemplo, si tu tarea es escribir una función que sume dos números, el sistema de verificación le pasará diferentes combinaciones de números y comparará la respuesta de tu función con las sumas reales. Si las respuestas coinciden en todos los casos, se considera que la solución es correcta. - - Este enfoque se llama pruebas y se utiliza en el desarrollo diario real. Por lo general, el programador primero escribe una prueba, que es un programa de verificación, y luego escribe el programa que quería escribir. Durante el proceso, ejecuta las pruebas constantemente y verifica si se acerca a la solución. - - Es por eso que nuestro sitio dice "Pruebas aprobadas" cuando resuelves correctamente un problema. + ```javascript + console.log(10); + ``` - Aquí tienes un ejemplo sencillo: en una de las futuras lecciones, tendrás que escribir una función que realice cálculos y devuelva una respuesta. Supongamos que cometiste un pequeño error y la función devuelve un número incorrecto. El sistema responderá algo como esto: + La verificación ejecutará este código y se asegurará de que `10` realmente aparezca en pantalla. Si la salida coincide con la esperada, la solución se acepta. De lo contrario, verás un error: ```text ● test @@ -23,37 +18,41 @@ theory: | expect(received).toBe(expected) // Object.is equality Expected value to be: - "Hello, World!" + "10" Received: - "ello, World!" + "9" ``` - Expected es el valor esperado y Received es el valor que devolvió tu código. + `Expected` es el resultado esperado y `Received` es el que devolvió tu código. - Además de nuestras pruebas, es muy útil experimentar con el código en la consola del [navegador](https://developer.mozilla.org/es/docs/Tools/Consola_de_navegador). En cualquier situación en la que no entiendas algo o quieras probar diferentes formas de uso, no dudes en abrir la consola e ingresar el código allí. Sería ideal si ejecutas todo el código presente en las lecciones por tu cuenta. + En las siguientes lecciones, más complejas, escribirás funciones. Estas toman datos y devuelven un resultado. En este tipo de tareas, la verificación funciona de manera un poco diferente: llama a tu función con diferentes argumentos y sabe de antemano qué respuesta debería obtenerse en cada caso. - --- + Por ejemplo, si necesitas escribir una función que sume dos números, la verificación le pasará diferentes pares de números y comparará el resultado con la suma correcta. Si las respuestas coinciden en todos los casos, la solución se considera correcta. - A veces, durante la resolución de un problema, puede parecer que has hecho todo correctamente, pero el sistema "se pone caprichoso" y no acepta la solución. Este comportamiento es prácticamente inexistente. Las pruebas que no funcionan simplemente no pueden llegar al sitio, se ejecutan automáticamente después de cada cambio. En la gran mayoría de estos casos (y todos nuestros proyectos en conjunto han realizado millones de verificaciones durante muchos años), el error se encuentra en el código de la solución. Puede ser muy sutil, como haber ingresado accidentalmente una letra rusa en lugar de una letra en inglés, haber utilizado minúsculas en lugar de mayúsculas o haber olvidado poner una coma. Otros casos son más complicados. Es posible que tu solución funcione para un conjunto de datos de entrada, pero no funcione para otro. Por lo tanto, siempre lee atentamente la descripción del problema y los resultados de las pruebas. Casi seguro que habrá alguna indicación sobre el error. + Este enfoque se llama pruebas y se utiliza en el desarrollo real. Las pruebas ayudan a verificar si un programa funciona correctamente y a detectar rápidamente un error después de los cambios. - Sin embargo, si estás seguro de que hay un error o has encontrado alguna imprecisión, siempre puedes señalarlo. Al final de cada teoría hay un enlace al contenido de la lección en GitHub (¡este proyecto está completamente abierto!). Al ir allí, puedes escribir un issue, ver el contenido de las pruebas (donde se muestra cómo se llama tu código) e incluso enviar un pull request. Si esto aún te resulta confuso, únete a nuestra comunidad en [Telegram](https://t.me/hexletcommunity), allí en el canal *Feedback* siempre estaremos dispuestos a ayudarte. + Es precisamente por eso que nuestro sitio dice "Pruebas aprobadas" cuando resuelves correctamente la tarea. -instructions: | - Solamente es un ejercicio de práctica. Muestra en pantalla el número 9780262531962. + ## ¿Es mi error o no? - ```text - 9780262531962 - ``` + A veces, durante el proceso de resolución, parecerá que has hecho todo correctamente, pero la verificación no acepta la solución. Esto ocurre muy raramente. Las pruebas se ejecutan automáticamente después de cada cambio, por lo que una verificación rota normalmente no llega al sitio. - Experimenta con la salida. Pasa otro número o una cadena de texto. Observa la respuesta del sistema, intenta traducirla y entenderla. + En la gran mayoría de estos casos, el error está en el código de la solución. Puede ser muy sutil: en lugar de una letra en inglés ingresaste accidentalmente una rusa, en lugar de mayúsculas usaste minúsculas o te olvidaste de poner una coma. También hay situaciones más complejas. Por ejemplo, la solución funciona para un conjunto de datos de entrada, pero no funciona para otro. -definitions: - - name: Pruebas - description: | - código especial que verifica la corrección de los programas, comparando el resultado correcto con el resultado real. + Por lo tanto, siempre lee atentamente el enunciado de la tarea y la salida de las pruebas. Allí casi seguro hay una indicación sobre el error. + + Si estás seguro de que el problema está en la tarea o has encontrado una imprecisión, escribe a nuestra [comunidad](https://t.me/hexletcommunity), en el canal _'Feedback'_. + Además de los ejercicios del sitio, será sumamente útil experimentar con el código en la [consola del navegador](https://developer.mozilla.org/es/docs/Tools/Browser_Console). En cualquier situación en la que no entiendas algo o quieras probar diferentes opciones, no dudes en abrir la consola e ingresar el código allí. +instructions: | + En la tienda quedan 10 manzanas en el estante. Escribe un programa que muestre este número en pantalla. + + Luego intenta mostrar otro número y observa lo que muestra el sistema de verificación. Esto te ayudará a aprender a leer los mensajes de error de las pruebas. tips: - | [TDD](https://es.wikipedia.org/wiki/Desarrollo_guiado_por_pruebas) - | [Comunidad de Hexlet en Telegram](https://t.me/hexletcommunity) +definitions: + - name: "Pruebas" + description: "código especial que verifica la corrección de los programas, comparando el resultado correcto con el resultado real." diff --git a/modules/10-basics/45-testing/en/EXERCISE.md b/modules/10-basics/45-testing/en/EXERCISE.md index ea69f264..334e9b80 100644 --- a/modules/10-basics/45-testing/en/EXERCISE.md +++ b/modules/10-basics/45-testing/en/EXERCISE.md @@ -1,2 +1,3 @@ -Print the following number: `9780262531962`. -Experiment with the output. Try another number or string there. Look at the system's output. +There are 10 apples left on the shelf in the store. Write a program that prints this number to the screen. + +Then try printing a different number and see what the checking system shows. This will help you learn to read test error messages. diff --git a/modules/10-basics/45-testing/en/README.md b/modules/10-basics/45-testing/en/README.md index 56822cfd..eaef35c5 100644 --- a/modules/10-basics/45-testing/en/README.md +++ b/modules/10-basics/45-testing/en/README.md @@ -1,17 +1,12 @@ +Our website automatically checks your solutions. How does it work? -Our website verifies your solutions automatically. You may be wondering how it works. +In the simplest case, the check runs your code and compares the screen output with the expected result. For example, if the task says: "Print the number 10 to the screen," then your JavaScript code might look like this: -In the most basic case, the system just runs your code and examines the output. Then it compares the actual output against the expected one. - -The following lessons deal with more complex matters. You will be writing functions. They're like mini-programs that take data from outside and perform operations on it. Verifying solutions gets a little more complicated in this case. The system runs your code and passes data to it. The system knows what result a correctly written function would give with the data the system provides it with, and this result is what the system is "expecting". - -Let's assume your task is to program a function that adds two numbers. The verification system will give it several combinations of numbers and compare your function's answers with the correctly calculated ones. If all actual values match the expected ones, your solution would be considered valid. - -This is testing. It's used extensively in the real, day-to-day development process. Developers usually write the tests _first_, that will proceed to write the program itself. During that process, they run tests multiple times to check how close they are to the desired solution. - -That is why our website says “Tests passed” once you solve the task correctly. +```javascript +console.log(10); +``` -One of your tasks in the following lessons will be to write a function that performs certain calculations and returns the result. As an example, let's assume you made a small mistake and the function returns the wrong value. In that case, the system will give you the following message: +The check will run this code and make sure that `10` actually appears on the screen. If the output matches the expected one, the solution is accepted. Otherwise, you will see an error: ```text ● test @@ -19,13 +14,29 @@ One of your tasks in the following lessons will be to write a function that perf expect(received).toBe(expected) // Object.is equality Expected value to be: - "Hello, World!" + "10" Received: - "ello, World!" + "9" ``` -In addition to our tests, it's very useful to experiment with code in the [browser console](https://developer.mozilla.org/en-US/docs/Tools/Browser_Console). When something isn't clear to you, or you want to experiment with code, feel free to do all of this in the console. +`Expected` is the expected result, and `Received` is the one your code returned. + +In the following, more complex lessons, you will write functions. They take data and return a result. In such tasks, the check works a little differently: it calls your function with different arguments and knows in advance which answer should be obtained in each case. + +For example, if you need to write a function that adds two numbers, the check will pass it different pairs of numbers and compare the result with the correct sum. If the answers match in all cases, the solution is considered correct. + +This approach is called testing, and it is used in real-world development. Tests help verify whether a program works correctly and quickly catch an error after changes. + +That is exactly why our website says "Tests passed" when you have solved the task correctly. + +## My mistake or not? + +Sometimes during the solution process it will seem that you did everything correctly, but the check does not accept the solution. This happens extremely rarely. Tests run automatically after every change, so a broken check usually does not make it to the website. + +In the vast majority of such cases, the error is contained in the solution code. It can be very subtle: instead of an English letter you accidentally typed a Russian one, instead of uppercase you used lowercase, or you forgot to print a comma. There are also more complex situations. For example, the solution works for one set of input data, but does not work for another. + +So always carefully read the task statement and the test output. There is almost certainly an indication of the error there. -Sometimes when creating a solution, it may seem that you have done everything correctly, but the system has got into a huff and won't accept your solution. Such cases are borderline impossible. Failed tests simply won't get as far as the site, they are automatically run after each change. In the vast majority of cases (all our projects have been run millions of times in total over many years) the error is in the solution code. It can be very imperceptible, maybe you used the wrong punctuation, or you used upper case instead of lower case, or you missed a comma. Other cases are more complicated. Maybe your solution works for one set of inputs, but not for another. So always read the instructions and test your output carefully. There will almost certainly be some sign of an error. +If you are sure that the problem is in the task or you have found an inaccuracy, write to our [community](https://t.me/hexletcommunity), in the _'Feedback'_ channel. -However, if you are sure about a mistake or have found an inaccuracy, you can always point it out. At the end of each theory section, there is a link to the contents of the lesson on GitHub (this project is completely open-source!). You can write about an issue, look through the tests (you can see how your code is called there), and even send a pull request. If it's all gone over your head, then join the #hexlet-feedback channel in [Slack community](https://slack.hexlet.io/), where we'll always be ready to help you. +In addition to the exercises on the website, it will be extremely useful to experiment with code in the [browser console](https://developer.mozilla.org/en-US/docs/Tools/Browser_Console). In any situation when you do not fully understand something or want to try different options, feel free to open the console and type code there. diff --git a/modules/10-basics/45-testing/en/data.yml b/modules/10-basics/45-testing/en/data.yml index d26dda1f..cb655758 100644 --- a/modules/10-basics/45-testing/en/data.yml +++ b/modules/10-basics/45-testing/en/data.yml @@ -1,10 +1,12 @@ --- -name: How do we verify your solutions? -definitions: - - name: Tests - description: > - are special bits of code that validate programs by checking the correct - result against the actual one. +name: How we check your solutions tips: - | [TDD](https://en.wikipedia.org/wiki/Test-driven_development) + - | + [Hexlet community on Telegram](https://t.me/hexletcommunity) +definitions: + - name: Tests + description: >- + special code that checks programs for correctness by comparing the correct + result with the actual one. diff --git a/modules/10-basics/45-testing/es/EXERCISE.md b/modules/10-basics/45-testing/es/EXERCISE.md index 8ecf46a0..051b4f64 100644 --- a/modules/10-basics/45-testing/es/EXERCISE.md +++ b/modules/10-basics/45-testing/es/EXERCISE.md @@ -1,7 +1,3 @@ -Solamente es un ejercicio de práctica. Muestra en pantalla el número 9780262531962. +En la tienda quedan 10 manzanas en el estante. Escribe un programa que muestre este número en pantalla. -```text -9780262531962 -``` - -Experimenta con la salida. Pasa otro número o una cadena de texto. Observa la respuesta del sistema, intenta traducirla y entenderla. +Luego intenta mostrar otro número y observa lo que muestra el sistema de verificación. Esto te ayudará a aprender a leer los mensajes de error de las pruebas. diff --git a/modules/10-basics/45-testing/es/README.md b/modules/10-basics/45-testing/es/README.md index ecb051d2..c4d84924 100644 --- a/modules/10-basics/45-testing/es/README.md +++ b/modules/10-basics/45-testing/es/README.md @@ -1,17 +1,12 @@ +Nuestro sitio web verifica automáticamente tus soluciones. ¿Cómo funciona? -El sitio web verifica automáticamente tus soluciones. ¿Cómo funciona? +En el caso más simple, la verificación ejecuta tu código y compara la salida en pantalla con el resultado esperado. Por ejemplo, si la tarea dice: "Muestra el número 10 en pantalla", entonces tu código en JavaScript podría verse así: -En el caso más simple, el sistema simplemente ejecuta tu código y verifica lo que se muestra en la pantalla. Luego lo compara con lo que "esperábamos" según la tarea. - -En lecciones más avanzadas, escribirás funciones, que son pequeños programas que toman información del mundo exterior y realizan operaciones. La verificación de tus soluciones en estos casos es un poco más complicada: el sistema ejecuta tu solución y le pasa cierta información. El sistema también sabe qué respuesta debería dar la función correcta con esos datos de entrada. - -Por ejemplo, si tu tarea es escribir una función que sume dos números, el sistema de verificación le pasará diferentes combinaciones de números y comparará la respuesta de tu función con las sumas reales. Si las respuestas coinciden en todos los casos, se considera que la solución es correcta. - -Este enfoque se llama pruebas y se utiliza en el desarrollo diario real. Por lo general, el programador primero escribe una prueba, que es un programa de verificación, y luego escribe el programa que quería escribir. Durante el proceso, ejecuta las pruebas constantemente y verifica si se acerca a la solución. - -Es por eso que nuestro sitio dice "Pruebas aprobadas" cuando resuelves correctamente un problema. +```javascript +console.log(10); +``` -Aquí tienes un ejemplo sencillo: en una de las futuras lecciones, tendrás que escribir una función que realice cálculos y devuelva una respuesta. Supongamos que cometiste un pequeño error y la función devuelve un número incorrecto. El sistema responderá algo como esto: +La verificación ejecutará este código y se asegurará de que `10` realmente aparezca en pantalla. Si la salida coincide con la esperada, la solución se acepta. De lo contrario, verás un error: ```text ● test @@ -19,17 +14,29 @@ Aquí tienes un ejemplo sencillo: en una de las futuras lecciones, tendrás que expect(received).toBe(expected) // Object.is equality Expected value to be: - "Hello, World!" + "10" Received: - "ello, World!" + "9" ``` -Expected es el valor esperado y Received es el valor que devolvió tu código. +`Expected` es el resultado esperado y `Received` es el que devolvió tu código. + +En las siguientes lecciones, más complejas, escribirás funciones. Estas toman datos y devuelven un resultado. En este tipo de tareas, la verificación funciona de manera un poco diferente: llama a tu función con diferentes argumentos y sabe de antemano qué respuesta debería obtenerse en cada caso. + +Por ejemplo, si necesitas escribir una función que sume dos números, la verificación le pasará diferentes pares de números y comparará el resultado con la suma correcta. Si las respuestas coinciden en todos los casos, la solución se considera correcta. + +Este enfoque se llama pruebas y se utiliza en el desarrollo real. Las pruebas ayudan a verificar si un programa funciona correctamente y a detectar rápidamente un error después de los cambios. + +Es precisamente por eso que nuestro sitio dice "Pruebas aprobadas" cuando resuelves correctamente la tarea. + +## ¿Es mi error o no? + +A veces, durante el proceso de resolución, parecerá que has hecho todo correctamente, pero la verificación no acepta la solución. Esto ocurre muy raramente. Las pruebas se ejecutan automáticamente después de cada cambio, por lo que una verificación rota normalmente no llega al sitio. -Además de nuestras pruebas, es muy útil experimentar con el código en la consola del [navegador](https://developer.mozilla.org/es/docs/Tools/Consola_de_navegador). En cualquier situación en la que no entiendas algo o quieras probar diferentes formas de uso, no dudes en abrir la consola e ingresar el código allí. +En la gran mayoría de estos casos, el error está en el código de la solución. Puede ser muy sutil: en lugar de una letra en inglés ingresaste accidentalmente una rusa, en lugar de mayúsculas usaste minúsculas o te olvidaste de poner una coma. También hay situaciones más complejas. Por ejemplo, la solución funciona para un conjunto de datos de entrada, pero no funciona para otro. ---- +Por lo tanto, siempre lee atentamente el enunciado de la tarea y la salida de las pruebas. Allí casi seguro hay una indicación sobre el error. -A veces, durante la resolución de un problema, puede parecer que has hecho todo correctamente, pero el sistema "se pone caprichoso" y no acepta la solución. Este comportamiento es prácticamente inexistente. Las pruebas que no funcionan simplemente no pueden llegar al sitio, se ejecutan automáticamente después de cada cambio. En la gran mayoría de estos casos (y todos nuestros proyectos en conjunto han realizado millones de verificaciones durante muchos años), el error se encuentra en el código de la solución. Puede ser muy sutil, como haber ingresado accidentalmente una letra rusa en lugar de una letra en inglés, haber utilizado minúsculas en lugar de mayúsculas o haber olvidado poner una coma. Otros casos son más complicados. Es posible que tu solución funcione para un conjunto de datos de entrada, pero no funcione para otro. Por lo tanto, siempre lee atentamente la descripción del problema y los resultados de las pruebas. Casi seguro que habrá alguna indicación sobre el error. +Si estás seguro de que el problema está en la tarea o has encontrado una imprecisión, escribe a nuestra [comunidad](https://t.me/hexletcommunity), en el canal _'Feedback'_. -Sin embargo, si estás seguro de que hay un error o has encontrado alguna imprecisión, siempre puedes señalarlo. Al final de cada teoría hay un enlace al contenido de la lección en GitHub (¡este proyecto está completamente abierto!). Al ir allí, puedes escribir un issue, ver el contenido de las pruebas (donde se muestra cómo se llama tu código) e incluso enviar un pull request. Si esto aún te resulta confuso, únete a nuestra comunidad en [Telegram](https://t.me/hexletcommunity), allí en el canal *Feedback* siempre estaremos dispuestos a ayudarte. +Además de los ejercicios del sitio, será sumamente útil experimentar con el código en la [consola del navegador](https://developer.mozilla.org/es/docs/Tools/Browser_Console). En cualquier situación en la que no entiendas algo o quieras probar diferentes opciones, no dudes en abrir la consola e ingresar el código allí. diff --git a/modules/10-basics/45-testing/es/data.yml b/modules/10-basics/45-testing/es/data.yml index 2396d2c8..8bc1a498 100644 --- a/modules/10-basics/45-testing/es/data.yml +++ b/modules/10-basics/45-testing/es/data.yml @@ -1,12 +1,12 @@ --- name: Cómo verificamos tus soluciones -definitions: - - name: Pruebas - description: > - código especial que verifica la corrección de los programas, comparando el - resultado correcto con el resultado real. tips: - | [TDD](https://es.wikipedia.org/wiki/Desarrollo_guiado_por_pruebas) - | [Comunidad de Hexlet en Telegram](https://t.me/hexletcommunity) +definitions: + - name: Pruebas + description: >- + código especial que verifica la corrección de los programas, comparando el + resultado correcto con el resultado real. diff --git a/modules/10-basics/50-syntax-errors/description.es.yml b/modules/10-basics/50-syntax-errors/description.es.yml index 3e9e96c5..a717decb 100644 --- a/modules/10-basics/50-syntax-errors/description.es.yml +++ b/modules/10-basics/50-syntax-errors/description.es.yml @@ -2,31 +2,76 @@ name: Errores de sintaxis theory: | + Si un programa en JavaScript está escrito en violación de las reglas, el intérprete detendrá la ejecución y mostrará un mensaje de error. Este mensaje indica: - Si un programa escrito en JavaScript tiene errores de sintaxis, el intérprete mostrará un mensaje correspondiente, así como una indicación del archivo y la línea en la que, según su opinión, se produjo el error. Un *error de sintaxis* ocurre cuando el código se ha escrito con violación de las reglas gramaticales. En los lenguajes humanos, la gramática es importante, pero generalmente se puede entender y leer el texto con errores. En la programación, todo es estricto. Cualquier error gramatical, por más mínimo que sea, y el programa ni siquiera se ejecutará. Un ejemplo puede ser un punto y coma olvidado, así como paréntesis mal colocados y otros detalles. + - el tipo de error, + - la línea en la que ocurrió, + - y (a menudo) el punto donde el intérprete "tropezó". - Aquí hay un ejemplo de código con un error de sintaxis: + ## ¿Qué es un error de sintaxis? + + Un error de sintaxis (SyntaxError) es una violación de las reglas de escritura de código (reglas gramaticales) en un lenguaje de programación concreto. Estos errores ocurren cuando el código se escribe con una desviación del formato esperado: una cadena sin cerrar, un paréntesis que falta, un orden incorrecto de símbolos, etc. + + A diferencia de los lenguajes naturales, donde un texto con errores se puede entender por el contexto, en la programación incluso la más mínima desviación hace que el código sea inutilizable. + + ```text + Código con un error Intérprete Resultado + ┌────────────────────┐ ┌───────────┐ ┌──────────────────────┐ + │ console.log('Hi' │──→│JavaScript │──→│ SyntaxError: │ + └────────────────────┘ └───────────┘ │ missing ) after args │ + └──────────────────────┘ + ``` + + Veamos un ejemplo sencillo con un error de sintaxis: ```javascript + // La versión correcta es: console.log('Hodor') + console.log('Hodor' + ``` + + En este código el paréntesis no está cerrado, lo que hace que el programa sea incorrecto desde el punto de vista de la sintaxis. Intentemos ejecutar el programa, y el intérprete producirá un error: + + ```bash + node index.js + index.js:2 console.log('Hodor' + ^ + + SyntaxError: missing ) after argument list ``` - Si ejecutamos el código anterior, veremos el siguiente mensaje: `SyntaxError: missing ) after argument list`, así como una indicación de la línea y el archivo donde se produjo este error. Estos errores de sintaxis en JavaScript se clasifican como SyntaxError. + El texto puede resultar poco claro al principio, pero eso es normal: cuanto más te enfrentes a este tipo de errores, más rápido aprenderás a entender qué sucedió. + + ## ¿Por qué estos errores se consideran simples? + + Los errores de sintaxis: - Por un lado, los errores de SyntaxError son los más simples porque están relacionados exclusivamente con las reglas gramaticales de escritura de código, no con el significado del código en sí. Son fáciles de corregir: solamente necesitas encontrar la violación de las reglas gramaticales. + - son fáciles de detectar: el código a menudo se resalta en el editor; + - son fáciles de corregir: basta con restaurar el símbolo que falta o corregir la estructura. - Por otro lado, el intérprete no siempre puede señalar claramente estas infracciones. Por lo tanto, a veces sucede que hay que colocar el paréntesis olvidado no donde indica precisamente el mensaje de error. + Pero hay una pega. El intérprete no siempre señala exactamente el lugar donde se cometió el error. A veces el problema está varias líneas más arriba. Por ejemplo, un paréntesis abierto pero no cerrado en una línea puede "romper" todo el código siguiente. + ## ¿Qué hacer ante un error de sintaxis? + + - Lee el mensaje de error. Casi siempre contiene información útil. + - Comprueba la línea indicada en el mensaje, y la línea anterior: a veces el error está "escondido" un poco antes. + - Usa un [editor con resaltado de sintaxis](https://code.visualstudio.com/): te ayudará a notar los problemas de inmediato (por ejemplo, comillas o paréntesis sin cerrar). instructions: | + El programa se inicia e informa del resultado. Escribe un programa que muestre: + + ```text + Program started successfully + ``` - Esta tarea no está directamente relacionada con la lección. Pero será útil practicar la salida en la pantalla. + Después de que el programa funcione, rómpelo a propósito: comete uno de los errores de sintaxis: - Muestra en la pantalla *What Is Dead May Never Die*. + - quita la comilla de cierre; + - quita el paréntesis de cierre. + Ejecuta el código y lee el mensaje de JavaScript. Verás estos mensajes con frecuencia, así que es importante aprender a leerlos. Luego restaura la versión que funciona para que el ejercicio pase la verificación. tips: - | [Errores en JavaScript](https://habr.com/ru/post/249525/) - definitions: - name: "Error de sintaxis" description: "violación de las reglas gramaticales del lenguaje de programación." diff --git a/modules/10-basics/50-syntax-errors/en/EXERCISE.md b/modules/10-basics/50-syntax-errors/en/EXERCISE.md index f91cf3b6..f249a8be 100644 --- a/modules/10-basics/50-syntax-errors/en/EXERCISE.md +++ b/modules/10-basics/50-syntax-errors/en/EXERCISE.md @@ -1,4 +1,12 @@ +The program starts and reports the result. Write a program that prints: -This task isn't directly related to the lesson, but it would be useful to practice printing anyway. +```text +Program started successfully +``` -Print the following text `What Is Dead May Never Die`. +After the program works, deliberately break it — make one of the syntax errors: + +- remove the closing quote; +- remove the closing bracket. + +Run the code and read the JavaScript message. You will see such messages often — it's important to learn to read them. Then restore the working version so the exercise passes the check. diff --git a/modules/10-basics/50-syntax-errors/en/README.md b/modules/10-basics/50-syntax-errors/en/README.md index 89d1d1fb..3e877d32 100644 --- a/modules/10-basics/50-syntax-errors/en/README.md +++ b/modules/10-basics/50-syntax-errors/en/README.md @@ -1,13 +1,54 @@ -If a JavaScript program is syntactically incorrect, the interpreter will show a relevant message and a message showing the file and line where the error might have occurred. **Syntax errors** occur when the code has grammatical mistakes. Grammar is essential to human language, but a text with grammar mistakes can still be read and understood. However, when it comes to programming, things are much stricter. Even a tiny mistake can mean your program won't run. Maybe you've mixed up your brackets, or there's a `;` that you forgot to add — these are just some examples of such mistakes. +If a JavaScript program is written in violation of the rules, the interpreter will stop execution and print an error message. This message indicates: -Here is an example of some code with a syntax error: +- the type of error, +- the line where it occurred, +- and (often) the point where the interpreter "stumbled." + +## What is a syntax error? + +A syntax error (SyntaxError) is a violation of the rules for writing code (grammar rules) in a particular programming language. Such errors occur when code is written with a deviation from the expected format: an unclosed string, a missing bracket, a wrong order of symbols, and so on. + +Unlike natural languages, where text with mistakes can be understood from context, in programming even the slightest deviation makes the code unusable. + +```text +Code with an error Interpreter Result +┌────────────────────┐ ┌───────────┐ ┌──────────────────────┐ +│ console.log('Hi' │──→│JavaScript │──→│ SyntaxError: │ +└────────────────────┘ └───────────┘ │ missing ) after args │ + └──────────────────────┘ +``` + +Let's look at a simple example with a syntax error: ```javascript +// The correct version is: console.log('Hodor') console.log('Hodor' ``` -If we run this code we will see the following message: `SyntaxError: missing ) after the argument list`. In JavaScript, these errors are labelled as "SyntaxError". +In this code the bracket is not closed, which makes the program incorrect from the syntax point of view. Let's try to run the program, and the interpreter will produce an error: + +```bash +node index.js +index.js:2 +console.log('Hodor' + ^ + +SyntaxError: missing ) after argument list +``` + +The text may be unclear at first, but that's normal — the more often you encounter such errors, the faster you'll learn to understand what happened. + +## Why are such errors considered simple? + +Syntax errors: + +- are easy to notice: the code is often highlighted in the editor; +- are easy to fix: it's enough to restore the missing symbol or correct the structure. + +But there's a fly in the ointment. The interpreter doesn't always point exactly to the place where the error was made. Sometimes the problem is several lines above. For example, an opened but unclosed bracket on one line can "break" all the following code. -On the one hand, syntax errors are the most obvious because they deal with code grammar rules and have nothing to do with its logic. You can easily fix it once you find it. +## What to do with a syntax error? -On the other hand, an interpreter will not always tell you the correct position of an error. Sometimes you need to add a forgotten bracket to different place than what the error message says. +- Read the error message. It almost always contains useful information. +- Check the line indicated in the message, and the line before it: sometimes the error is "hidden" a bit earlier. +- Use an [editor with syntax highlighting](https://code.visualstudio.com/): it will help you notice problems right away (for example, unclosed quotes or brackets). diff --git a/modules/10-basics/50-syntax-errors/en/data.yml b/modules/10-basics/50-syntax-errors/en/data.yml index e6b11825..db5916c1 100644 --- a/modules/10-basics/50-syntax-errors/en/data.yml +++ b/modules/10-basics/50-syntax-errors/en/data.yml @@ -2,11 +2,12 @@ name: Syntax errors tips: - | - [JavaScript errors](https://davidwalsh.name/fix-javascript-errors) + [Errors in JavaScript](https://habr.com/ru/post/249525/) definitions: - - name: Syntax errors - description: are grammar mistakes in a programming language. - - name: SyntaxError (Parse error) + - name: Syntax error description: >- - is a type of error in JavaScript which occurs when there are syntax errors - in the code. + a violation of the grammar rules of a programming language. + - name: SyntaxError (parsing error) + description: >- + a type of error in JavaScript that occurs when there are syntax errors in + the code. diff --git a/modules/10-basics/50-syntax-errors/es/EXERCISE.md b/modules/10-basics/50-syntax-errors/es/EXERCISE.md index c1ab47e4..ca4e3f07 100644 --- a/modules/10-basics/50-syntax-errors/es/EXERCISE.md +++ b/modules/10-basics/50-syntax-errors/es/EXERCISE.md @@ -1,4 +1,12 @@ +El programa se inicia e informa del resultado. Escribe un programa que muestre: -Esta tarea no está directamente relacionada con la lección. Pero será útil practicar la salida en la pantalla. +```text +Program started successfully +``` -Muestra en la pantalla *What Is Dead May Never Die*. +Después de que el programa funcione, rómpelo a propósito: comete uno de los errores de sintaxis: + +- quita la comilla de cierre; +- quita el paréntesis de cierre. + +Ejecuta el código y lee el mensaje de JavaScript. Verás estos mensajes con frecuencia, así que es importante aprender a leerlos. Luego restaura la versión que funciona para que el ejercicio pase la verificación. diff --git a/modules/10-basics/50-syntax-errors/es/README.md b/modules/10-basics/50-syntax-errors/es/README.md index 0b6f6fc0..837c390b 100644 --- a/modules/10-basics/50-syntax-errors/es/README.md +++ b/modules/10-basics/50-syntax-errors/es/README.md @@ -1,14 +1,54 @@ +Si un programa en JavaScript está escrito en violación de las reglas, el intérprete detendrá la ejecución y mostrará un mensaje de error. Este mensaje indica: -Si un programa escrito en JavaScript tiene errores de sintaxis, el intérprete mostrará un mensaje correspondiente, así como una indicación del archivo y la línea en la que, según su opinión, se produjo el error. Un *error de sintaxis* ocurre cuando el código se ha escrito con violación de las reglas gramaticales. En los lenguajes humanos, la gramática es importante, pero generalmente se puede entender y leer el texto con errores. En la programación, todo es estricto. Cualquier error gramatical, por más mínimo que sea, y el programa ni siquiera se ejecutará. Un ejemplo puede ser un punto y coma olvidado, así como paréntesis mal colocados y otros detalles. +- el tipo de error, +- la línea en la que ocurrió, +- y (a menudo) el punto donde el intérprete "tropezó". -Aquí hay un ejemplo de código con un error de sintaxis: +## ¿Qué es un error de sintaxis? + +Un error de sintaxis (SyntaxError) es una violación de las reglas de escritura de código (reglas gramaticales) en un lenguaje de programación concreto. Estos errores ocurren cuando el código se escribe con una desviación del formato esperado: una cadena sin cerrar, un paréntesis que falta, un orden incorrecto de símbolos, etc. + +A diferencia de los lenguajes naturales, donde un texto con errores se puede entender por el contexto, en la programación incluso la más mínima desviación hace que el código sea inutilizable. + +```text +Código con un error Intérprete Resultado +┌────────────────────┐ ┌───────────┐ ┌──────────────────────┐ +│ console.log('Hi' │──→│JavaScript │──→│ SyntaxError: │ +└────────────────────┘ └───────────┘ │ missing ) after args │ + └──────────────────────┘ +``` + +Veamos un ejemplo sencillo con un error de sintaxis: ```javascript +// La versión correcta es: console.log('Hodor') +console.log('Hodor' +``` + +En este código el paréntesis no está cerrado, lo que hace que el programa sea incorrecto desde el punto de vista de la sintaxis. Intentemos ejecutar el programa, y el intérprete producirá un error: + +```bash +node index.js +index.js:2 console.log('Hodor' + ^ + +SyntaxError: missing ) after argument list ``` -Si ejecutamos el código anterior, veremos el siguiente mensaje: `SyntaxError: missing ) after argument list`, así como una indicación de la línea y el archivo donde se produjo este error. Estos errores de sintaxis en JavaScript se clasifican como SyntaxError. +El texto puede resultar poco claro al principio, pero eso es normal: cuanto más te enfrentes a este tipo de errores, más rápido aprenderás a entender qué sucedió. + +## ¿Por qué estos errores se consideran simples? + +Los errores de sintaxis: + +- son fáciles de detectar: el código a menudo se resalta en el editor; +- son fáciles de corregir: basta con restaurar el símbolo que falta o corregir la estructura. + +Pero hay una pega. El intérprete no siempre señala exactamente el lugar donde se cometió el error. A veces el problema está varias líneas más arriba. Por ejemplo, un paréntesis abierto pero no cerrado en una línea puede "romper" todo el código siguiente. -Por un lado, los errores de SyntaxError son los más simples porque están relacionados exclusivamente con las reglas gramaticales de escritura de código, no con el significado del código en sí. Son fáciles de corregir: solamente necesitas encontrar la violación de las reglas gramaticales. +## ¿Qué hacer ante un error de sintaxis? -Por otro lado, el intérprete no siempre puede señalar claramente estas infracciones. Por lo tanto, a veces sucede que hay que colocar el paréntesis olvidado no donde indica precisamente el mensaje de error. +- Lee el mensaje de error. Casi siempre contiene información útil. +- Comprueba la línea indicada en el mensaje, y la línea anterior: a veces el error está "escondido" un poco antes. +- Usa un [editor con resaltado de sintaxis](https://code.visualstudio.com/): te ayudará a notar los problemas de inmediato (por ejemplo, comillas o paréntesis sin cerrar). diff --git a/modules/10-basics/50-syntax-errors/es/data.yml b/modules/10-basics/50-syntax-errors/es/data.yml index 7017b32c..5b02d56c 100644 --- a/modules/10-basics/50-syntax-errors/es/data.yml +++ b/modules/10-basics/50-syntax-errors/es/data.yml @@ -5,7 +5,8 @@ tips: [Errores en JavaScript](https://habr.com/ru/post/249525/) definitions: - name: Error de sintaxis - description: violación de las reglas gramaticales del lenguaje de programación. + description: >- + violación de las reglas gramaticales del lenguaje de programación. - name: SyntaxError (error de análisis) description: >- tipo de errores en JavaScript que ocurren cuando hay errores de sintaxis diff --git a/modules/10-basics/50-syntax-errors/index.js b/modules/10-basics/50-syntax-errors/index.js index f7830cd6..72fc421f 100644 --- a/modules/10-basics/50-syntax-errors/index.js +++ b/modules/10-basics/50-syntax-errors/index.js @@ -1 +1 @@ -console.log('Программа успешно запущена'); +console.log('Program started successfully'); diff --git a/modules/10-basics/50-syntax-errors/ru/EXERCISE.md b/modules/10-basics/50-syntax-errors/ru/EXERCISE.md index 65effb6c..221d332a 100644 --- a/modules/10-basics/50-syntax-errors/ru/EXERCISE.md +++ b/modules/10-basics/50-syntax-errors/ru/EXERCISE.md @@ -1,7 +1,7 @@ Программа запускается и сообщает о результате. Напишите программу, которая выводит: ```text -Программа успешно запущена +Program started successfully ``` После того как программа заработает, намеренно сломайте её — допустите одну из синтаксических ошибок: diff --git a/modules/10-basics/50-syntax-errors/test.js b/modules/10-basics/50-syntax-errors/test.js index 24c26d68..e2c9e32d 100644 --- a/modules/10-basics/50-syntax-errors/test.js +++ b/modules/10-basics/50-syntax-errors/test.js @@ -8,5 +8,5 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); - expect(firstArg).toBe('Программа успешно запущена'); + expect(firstArg).toBe('Program started successfully'); }); diff --git a/modules/20-arithmetics/20-basic/description.es.yml b/modules/20-arithmetics/20-basic/description.es.yml index 1523cd45..8fa83490 100644 --- a/modules/20-arithmetics/20-basic/description.es.yml +++ b/modules/20-arithmetics/20-basic/description.es.yml @@ -2,17 +2,26 @@ name: Operaciones aritméticas theory: | - A nivel básico, las computadoras operan solamente con números. Incluso en aplicaciones de alto nivel, hay muchos números y operaciones dentro de ellas. Afortunadamente, para comenzar, es suficiente conocer la aritmética básica, así que empecemos por ahí. - En matemáticas, para sumar dos números, escribimos, por ejemplo, `3 + 4`. En programación, es lo mismo. Aquí hay un programa que suma dos números: + A nivel básico, las computadoras solo trabajan con números. Incluso si escribes una aplicación compleja en un lenguaje de programación moderno, dentro de ella siempre ocurren numerosos cálculos: suma, resta, división, etc. + + Afortunadamente, para empezar a programar, basta con conocer la aritmética escolar habitual. Por ahí empezaremos. + + ## La suma en JavaScript + + En matemáticas, para sumar escribimos 3 + 4. En JavaScript es exactamente igual: ```javascript - // No olvides el punto y coma al final, - // ya que cada línea de código es una instrucción 3 + 4; ``` - La instrucción `3 + 4;` hará que la computadora sume los números y obtenga el resultado. Si ejecutas este programa, no sucederá nada. O más precisamente, la computadora calculará la suma, pero eso es todo. El resultado de la suma no se utiliza de ninguna manera, por lo que este programa no es interesante. Necesitamos pedirle a la computadora que sume `3 + 4` **y** que haga algo con el resultado. Por ejemplo, mostrarlo en la pantalla: + Este código realmente se puede ejecutar: el intérprete realizará el cálculo. Pero... no hará nada con el resultado. Es decir, se obtendrá 7, pero no lo verás. + + ## Para ver el resultado, hay que imprimirlo + + En un programa real, simplemente calcular un valor no es suficiente. Hay que hacer algo con el resultado, por ejemplo, mostrarlo al usuario. + + Para ello usamos el ya familiar comando `console.log()`: ```javascript // Primero se calcula la suma, @@ -20,45 +29,92 @@ theory: | console.log(3 + 4); ``` - Después de ejecutarlo, aparecerá el resultado en la pantalla: + ```text + console.log(3 + 4) + └─┬─┘ + 7 + + console.log(7) → 7 + ``` + + Resultado de la ejecución: ```text 7 ``` - Además de la suma, están disponibles las siguientes operaciones: + Si escribimos la misma expresión como una cadena, obtenemos un resultado completamente diferente: se imprimirá la cadena "tal cual": + + ```javascript + console.log('3 + 4'); // imprime: 3 + 4 + console.log(3 + 4); // imprime: 7 + ``` + + ## Otras operaciones aritméticas + + JavaScript admite todas las operaciones habituales más algunas específicas relacionadas con la forma en que se almacenan y procesan los números en una computadora: - * `*` — multiplicación - * `/` — división - * `-` — resta - * `%` — [resto de la división](https://es.wikipedia.org/wiki/División_euclídea) - * `**` — potenciación + | Operación | Símbolo | Ejemplo | Resultado | + |------------------|---------|-----------|-----------| + | Suma | `+` | `2 + 3` | `5` | + | Resta | `-` | `7 - 2` | `5` | + | Multiplicación | `*` | `4 * 3` | `12` | + | División | `/` | `8 / 2` | `4` | + | Potenciación | `**` | `3 ** 2` | `9` | + | Resto | `%` | `7 % 3` | `1` | - Ahora, vamos a mostrar en la pantalla el resultado de la división y luego el resultado de la potenciación: + Así es como puedes imprimir el resultado de la división y de la potenciación: ```javascript console.log(8 / 2); // => 4 console.log(3 ** 2); // => 9 ``` + ## Qué es el resto de la división (`%`) - A veces, para mayor comodidad, mostraremos el resultado de la ejecución de las líneas de código en los comentarios, de esta manera: `=> RESULTADO`. Por ejemplo, `// => 4`. + Esta operación se llama **obtención del resto de la división**. Muestra **lo que "queda"** cuando un número se divide por otro *de forma no exacta*. Ejemplo: - La primera instrucción mostrará `4` en la pantalla (porque 8 / 2 es igual a 4), y la segunda instrucción mostrará 9 en la pantalla (porque 32 es igual a 9). + ```javascript + console.log(7 % 3); // => 1 + ``` + + ¿Por qué el resultado es igual a 1? + + - 7 se divide entre 3 dos veces: 3 * 2 = 6 + - Hasta 7 queda 1, y ese es el resto. + + Otros ejemplos: + + ```javascript + console.log(10 % 4); // => 2 (10 se divide entre 4 dos veces: 4 * 2 = 8, resto 2) + console.log(15 % 5); // => 0 (se divide sin resto) + ``` + + La operación `%` se usa con frecuencia en programación, por ejemplo, para comprobar si un número se divide de forma exacta (si el resto es 0). + + ## Formato de las expresiones aritméticas + + Desde el punto de vista de JavaScript, no hay diferencia entre `3+4` y `3 + 4`. El intérprete entenderá ambas opciones de la misma manera. La única diferencia está en el formato del código. En programación es costumbre poner espacios alrededor de los operadores aritméticos, porque así las expresiones son más fáciles de leer: + + ```javascript + console.log(3 + 4); + console.log(8 / 2); + console.log(7 % 3); + ``` instructions: | - Muestra en la pantalla el resultado de dividir el número `81` entre `9`. + Entraste a una tienda mayorista y viste un paquete de 9 pilas por 81 rublos. En una tienda normal, una pila cuesta 12 rublos. Calcula e imprime el precio de una sola pila en el paquete mayorista para averiguar dónde conviene comprar. tips: - | - Siempre deja espacios entre los operadores aritméticos y los números (operandos) - esta es una buena práctica de programación. Por lo tanto, en nuestros ejemplos, es `console.log(3 + 4)`, no `console.log(3+4)`. + Siempre separa los operadores aritméticos de los propios números (operandos) con espacios: es un buen estilo de programación. Por eso en nuestros ejemplos es `console.log(3 + 4)`, y no `console.log(3+4)`. - | - La división por cero es igual a `Infinity` (infinito). Explicaremos qué significa esto en futuras lecciones. + La división por cero es `Infinity` (infinito). Explicaremos qué significa esto en futuras lecciones. - | [Operaciones aritméticas](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators#arithmetic_operators) - | - [Resto de la división](https://es.wikipedia.org/wiki/División_euclídea) + [División con resto](https://es.wikipedia.org/wiki/División_euclídea) definitions: - name: Instrucción diff --git a/modules/20-arithmetics/20-basic/en/EXERCISE.md b/modules/20-arithmetics/20-basic/en/EXERCISE.md index a75e3dd9..dfe596eb 100644 --- a/modules/20-arithmetics/20-basic/en/EXERCISE.md +++ b/modules/20-arithmetics/20-basic/en/EXERCISE.md @@ -1,2 +1 @@ - -Print the result of dividing `81` by `9`. +You walked into a wholesale store and saw a pack of 9 batteries for 81 rubles. In a regular store, one battery costs 12 rubles. Calculate and print the price of a single battery in the wholesale pack to figure out where it is cheaper to buy. diff --git a/modules/20-arithmetics/20-basic/en/README.md b/modules/20-arithmetics/20-basic/en/README.md index de77aaf5..1930edc7 100644 --- a/modules/20-arithmetics/20-basic/en/README.md +++ b/modules/20-arithmetics/20-basic/en/README.md @@ -1,41 +1,98 @@ -At the most basic level, computers only use numbers. Even in high-level language applications, there are many numbers and operations with them. To get started with programming all you need to know is basic arithmetic – let’s start with that. +At a basic level, computers only work with numbers. Even if you write a complex application in a modern programming language, numerous calculations are always happening inside it: addition, subtraction, division, and so on. -When adding two numbers in math, we write, for example, `3 + 4`. The same goes for programming. Here is a program that adds two numbers: +Fortunately, to start programming, it is enough to know ordinary school arithmetic. That is where we will begin. -```javascript -// Don't forget the semicolon at the end, -// since each line of code is a statement +## Addition in JavaScript + +In math, we write 3 + 4 to add. In JavaScript, it is exactly the same: +```javascript 3 + 4; ``` -The statement `3 + 4` makes the computer add up the numbers and find the result. If you run this program, nothing will happen. Well, the computer will calculate the sum, of course, but that'll be it. The result of the sum isn't used, and as such, this program has no real value. We need to ask the computer to add `3 + 4`, and then give it a command to do something with the result. For example, print it: +This code can actually be run: the interpreter will perform the calculation. But... it will do nothing with the result. That is, 7 will be produced, but you will not see it. -```javascript -// The sum is calculated first, -// it is then passed to the print function +## To see the result, you need to print it + +In a real program, simply computing a value is not enough. You need to do something with the result, for example, show it to the user. +To do this, we use the now familiar `console.log()` command: + +```javascript +// First the sum is computed, +// then it is passed to the print function console.log(3 + 4); ``` -After launching, the result will appear on the screen: +```text +console.log(3 + 4) + └─┬─┘ + 7 + +console.log(7) → 7 ``` + +Execution result: + +```text 7 ``` -The following operations are available besides addition: -`*` — multiplication -`/` — division -`-` — subtraction -`%` — [modulo](https://en.wikipedia.org/wiki/Modulo_operation) (remainder after division) -`**` — power +If we write the same expression as a string, we get a completely different result — the string will be printed "as is": + +```javascript +console.log('3 + 4'); // prints: 3 + 4 +console.log(3 + 4); // prints: 7 +``` + +## Other arithmetic operations + +JavaScript supports all the usual operations plus a few specific ones related to how numbers are stored and processed on a computer: -Now let's print the result of division, and then the result of exponentiation: +| Operation | Symbol | Example | Result | +|------------------|--------|-----------|--------| +| Addition | `+` | `2 + 3` | `5` | +| Subtraction | `-` | `7 - 2` | `5` | +| Multiplication | `*` | `4 * 3` | `12` | +| Division | `/` | `8 / 2` | `4` | +| Exponentiation | `**` | `3 ** 2` | `9` | +| Remainder | `%` | `7 % 3` | `1` | + +Here is how you can print the result of division and exponentiation: ```javascript console.log(8 / 2); // => 4 console.log(3 ** 2); // => 9 ``` -Sometimes we will show the result of the executed code in the comments like this: `=> RESULT`. For example, `// => 4`. -The first statement will print `4` (since `8 / 2` is `4`), and the second statement will print 9 (since 32 is 9). +## What is the remainder of a division (`%`) + +This operation is called **taking the remainder of a division**. It shows **what is "left over"** when one number is divided by another *not evenly*. Example: + +```javascript +console.log(7 % 3); // => 1 +``` + +Why is the result equal to 1? + +- 7 is divided by 3 twice: 3 * 2 = 6 +- Up to 7 there is 1 left, and that is the remainder. + +Other examples: + +```javascript +console.log(10 % 4); // => 2 (10 is divided by 4 twice: 4 * 2 = 8, remainder 2) +console.log(15 % 5); // => 0 (divides evenly) +``` + +The `%` operation is often used in programming, for example, to check whether a number divides evenly (if the remainder is 0). + +## Formatting arithmetic expressions + +From JavaScript's point of view, there is no difference between `3+4` and `3 + 4`. The interpreter will understand both options the same way. The only difference is in code formatting. In programming, it is conventional to put spaces around arithmetic operators, because that makes expressions easier to read: + +```javascript +console.log(3 + 4); +console.log(8 / 2); +console.log(7 % 3); +``` diff --git a/modules/20-arithmetics/20-basic/en/data.yml b/modules/20-arithmetics/20-basic/en/data.yml index 18b5d764..38c0f427 100644 --- a/modules/20-arithmetics/20-basic/en/data.yml +++ b/modules/20-arithmetics/20-basic/en/data.yml @@ -1,13 +1,18 @@ --- + name: Arithmetic operations + tips: - - > - Always indent arithmetic operators with spaces between the numbers - (operands) - it is good form when programming. This is why we write - `console.log(3 + 4)`, and not `console.log(3+4)` in our examples. - - > - The result of dividing by zero is Infinity. We will figure out what this - means in later lessons. - - > - [Arithmetic - operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators) + - | + Always separate arithmetic operators from the numbers (operands) with spaces – this is good programming style. That is why in our examples it is `console.log(3 + 4)`, not `console.log(3+4)`. + - | + Division by zero is `Infinity`. We will figure out what that means in future lessons. + - | + [Arithmetic operations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#arithmetic_operators) + - | + [Division with remainder](https://en.wikipedia.org/wiki/Remainder) + +definitions: + - name: Statement + description: | + the smallest standalone part of a programming language; a command or a set of commands. A program is usually a sequence of statements. diff --git a/modules/20-arithmetics/20-basic/es/EXERCISE.md b/modules/20-arithmetics/20-basic/es/EXERCISE.md index feca11ba..cadc833c 100644 --- a/modules/20-arithmetics/20-basic/es/EXERCISE.md +++ b/modules/20-arithmetics/20-basic/es/EXERCISE.md @@ -1,2 +1 @@ - -Muestra en la pantalla el resultado de dividir el número `81` entre `9`. +Entraste a una tienda mayorista y viste un paquete de 9 pilas por 81 rublos. En una tienda normal, una pila cuesta 12 rublos. Calcula e imprime el precio de una sola pila en el paquete mayorista para averiguar dónde conviene comprar. diff --git a/modules/20-arithmetics/20-basic/es/README.md b/modules/20-arithmetics/20-basic/es/README.md index d86935e6..1a8cc34b 100644 --- a/modules/20-arithmetics/20-basic/es/README.md +++ b/modules/20-arithmetics/20-basic/es/README.md @@ -1,14 +1,22 @@ -A nivel básico, las computadoras operan solamente con números. Incluso en aplicaciones de alto nivel, hay muchos números y operaciones dentro de ellas. Afortunadamente, para comenzar, es suficiente conocer la aritmética básica, así que empecemos por ahí. +A nivel básico, las computadoras solo trabajan con números. Incluso si escribes una aplicación compleja en un lenguaje de programación moderno, dentro de ella siempre ocurren numerosos cálculos: suma, resta, división, etc. -En matemáticas, para sumar dos números, escribimos, por ejemplo, `3 + 4`. En programación, es lo mismo. Aquí hay un programa que suma dos números: +Afortunadamente, para empezar a programar, basta con conocer la aritmética escolar habitual. Por ahí empezaremos. + +## La suma en JavaScript + +En matemáticas, para sumar escribimos 3 + 4. En JavaScript es exactamente igual: ```javascript -// No olvides el punto y coma al final, -// ya que cada línea de código es una instrucción 3 + 4; ``` -La instrucción `3 + 4;` hará que la computadora sume los números y obtenga el resultado. Si ejecutas este programa, no sucederá nada. O más precisamente, la computadora calculará la suma, pero eso es todo. El resultado de la suma no se utiliza de ninguna manera, por lo que este programa no es interesante. Necesitamos pedirle a la computadora que sume `3 + 4` **y** que haga algo con el resultado. Por ejemplo, mostrarlo en la pantalla: +Este código realmente se puede ejecutar: el intérprete realizará el cálculo. Pero... no hará nada con el resultado. Es decir, se obtendrá 7, pero no lo verás. + +## Para ver el resultado, hay que imprimirlo + +En un programa real, simplemente calcular un valor no es suficiente. Hay que hacer algo con el resultado, por ejemplo, mostrarlo al usuario. + +Para ello usamos el ya familiar comando `console.log()`: ```javascript // Primero se calcula la suma, @@ -16,27 +24,75 @@ La instrucción `3 + 4;` hará que la computadora sume los números y obtenga el console.log(3 + 4); ``` -Después de ejecutarlo, aparecerá el resultado en la pantalla: +```text +console.log(3 + 4) + └─┬─┘ + 7 + +console.log(7) → 7 +``` + +Resultado de la ejecución: ```text 7 ``` -Además de la suma, están disponibles las siguientes operaciones: +Si escribimos la misma expresión como una cadena, obtenemos un resultado completamente diferente: se imprimirá la cadena "tal cual": + +```javascript +console.log('3 + 4'); // imprime: 3 + 4 +console.log(3 + 4); // imprime: 7 +``` -* `*` — multiplicación -* `/` — división -* `-` — resta -* `%` — [resto de la división](https://es.wikipedia.org/wiki/División_euclídea) -* `**` — potenciación +## Otras operaciones aritméticas -Ahora, vamos a mostrar en la pantalla el resultado de la división y luego el resultado de la potenciación: +JavaScript admite todas las operaciones habituales más algunas específicas relacionadas con la forma en que se almacenan y procesan los números en una computadora: + +| Operación | Símbolo | Ejemplo | Resultado | +|------------------|---------|-----------|-----------| +| Suma | `+` | `2 + 3` | `5` | +| Resta | `-` | `7 - 2` | `5` | +| Multiplicación | `*` | `4 * 3` | `12` | +| División | `/` | `8 / 2` | `4` | +| Potenciación | `**` | `3 ** 2` | `9` | +| Resto | `%` | `7 % 3` | `1` | + +Así es como puedes imprimir el resultado de la división y de la potenciación: ```javascript console.log(8 / 2); // => 4 console.log(3 ** 2); // => 9 ``` -A veces, para mayor comodidad, mostraremos el resultado de la ejecución de las líneas de código en los comentarios, de esta manera: `=> RESULTADO`. Por ejemplo, `// => 4`. +## Qué es el resto de la división (`%`) + +Esta operación se llama **obtención del resto de la división**. Muestra **lo que "queda"** cuando un número se divide por otro *de forma no exacta*. Ejemplo: + +```javascript +console.log(7 % 3); // => 1 +``` + +¿Por qué el resultado es igual a 1? -La primera instrucción mostrará `4` en la pantalla (porque 8 / 2 es igual a 4), y la segunda instrucción mostrará 9 en la pantalla (porque 32 es igual a 9). +- 7 se divide entre 3 dos veces: 3 * 2 = 6 +- Hasta 7 queda 1, y ese es el resto. + +Otros ejemplos: + +```javascript +console.log(10 % 4); // => 2 (10 se divide entre 4 dos veces: 4 * 2 = 8, resto 2) +console.log(15 % 5); // => 0 (se divide sin resto) +``` + +La operación `%` se usa con frecuencia en programación, por ejemplo, para comprobar si un número se divide de forma exacta (si el resto es 0). + +## Formato de las expresiones aritméticas + +Desde el punto de vista de JavaScript, no hay diferencia entre `3+4` y `3 + 4`. El intérprete entenderá ambas opciones de la misma manera. La única diferencia está en el formato del código. En programación es costumbre poner espacios alrededor de los operadores aritméticos, porque así las expresiones son más fáciles de leer: + +```javascript +console.log(3 + 4); +console.log(8 / 2); +console.log(7 % 3); +``` diff --git a/modules/20-arithmetics/20-basic/es/data.yml b/modules/20-arithmetics/20-basic/es/data.yml index 787dfebf..02b1d686 100644 --- a/modules/20-arithmetics/20-basic/es/data.yml +++ b/modules/20-arithmetics/20-basic/es/data.yml @@ -1,21 +1,18 @@ --- + name: Operaciones aritméticas + tips: - - > - Siempre deja espacios entre los operadores aritméticos y los números - (operandos) - esta es una buena práctica de programación. Por lo tanto, en - nuestros ejemplos, es `console.log(3 + 4)`, no `console.log(3+4)`. - - > - La división por cero es igual a `Infinity` (infinito). Explicaremos qué - significa esto en futuras lecciones. - - > - [Operaciones - aritméticas](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators#arithmetic_operators) - | - [Resto de la división](https://es.wikipedia.org/wiki/División_euclídea) + Siempre separa los operadores aritméticos de los propios números (operandos) con espacios: es un buen estilo de programación. Por eso en nuestros ejemplos es `console.log(3 + 4)`, y no `console.log(3+4)`. + - | + La división por cero es `Infinity` (infinito). Explicaremos qué significa esto en futuras lecciones. + - | + [Operaciones aritméticas](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators#arithmetic_operators) + - | + [División con resto](https://es.wikipedia.org/wiki/División_euclídea) + definitions: - name: Instrucción - description: > - la unidad más pequeña e independiente de un lenguaje de programación; una - orden o conjunto de órdenes. Un programa generalmente consiste en una - secuencia de instrucciones. + description: | + la unidad más pequeña e independiente de un lenguaje de programación; una orden o conjunto de órdenes. Un programa generalmente consiste en una secuencia de instrucciones. diff --git a/modules/20-arithmetics/25-operator/description.es.yml b/modules/20-arithmetics/25-operator/description.es.yml index 5ad90ad8..54ddb3a6 100644 --- a/modules/20-arithmetics/25-operator/description.es.yml +++ b/modules/20-arithmetics/25-operator/description.es.yml @@ -3,36 +3,92 @@ name: Operadores theory: | - Antes de continuar, vamos a repasar la terminología básica. Un símbolo de operación, como `+`, se llama **operador**. Los operadores realizan operaciones en valores específicos, que se llaman **operandos**. Los operadores en sí suelen estar representados por uno o varios caracteres, aunque a veces también pueden ser palabras. La gran mayoría de los operadores corresponden a operaciones matemáticas. + En matemáticas y programación, a menudo usamos signos de operación como `+`, `-`, `*` y otros. En programación, estos signos se llaman operadores. + + - Un operador es un símbolo o palabra que denota una acción. + - Los operandos son los valores a los que se aplica el operador. + + Ejemplo: ```javascript console.log(8 + 2); ``` - En este ejemplo, `+` es el **operador**, y los números `8` y `2` son los **operandos**. + Aquí: + + - `+` es un operador + - `8` y `2` son operandos + - el resultado será `10` + + ```text + operando operador operando resultado + 8 + 2 → 10 + 5 - 3 → 2 + 4 * 3 → 12 + ``` + + ## Operadores unarios + + También existen operaciones unarias, que trabajan con un solo operando. Ejemplo: - En el caso de la suma, tenemos dos operandos: uno a la izquierda y otro a la derecha del símbolo `+`. Las operaciones que requieren dos operandos se llaman **binarias**. Si falta al menos uno de los operandos, por ejemplo, `3 + ;`, el programa mostrará un error de sintaxis. + ```javascript + console.log(-3); // => -3 + ``` - Las operaciones (no los operadores) pueden ser no sólo binarias, sino también unarias (con un solo operando) e incluso ternarias (con tres operandos). Además, los operadores pueden tener la misma apariencia pero representar operaciones diferentes. + En este caso, `-` es un operador unario, y `3` es el operando. El intérprete recibe la orden: "toma el número 3 y cambia su signo". - ```javascript - console.log(-3); // => -3 - ``` + El operador `-` puede usarse de diferentes maneras. Cuando se encuentra **entre dos números**, es una operación de resta: - En el ejemplo anterior, se aplica una operación unaria al número `3`. El operador de menos antes del tres le indica al intérprete que tome el número `3` y encuentre su opuesto, es decir, `-3`. + ```javascript + console.log(5 - 2); // => 3 + console.log(10 - 7); // => 3 + ``` - Esto puede ser un poco confuso, ya que `-3` es tanto un número en sí mismo como un operador con un operando, pero es una estructura común en los lenguajes de programación. + Esta diferencia es especialmente notable al trabajar con números negativos: + + ```javascript + // menos por menos da más + console.log(5 - -2); // => 7 + ``` + + Primero vemos la operación de resta: `5 - (...)`. Pero a la derecha hay un menos unario `-2`, que convierte el `2` en un número negativo. Como resultado, obtenemos: `5 - (-2) = 7`. + + Así, el significado de `-` depende del contexto: si hay otro número a su lado, es una resta; de lo contrario, es un cambio de signo del número. + + ## Errores en los cálculos + + Si consideras `-3` como un único número, puedes no darte cuenta de que `-` es un operador independiente con su propia prioridad. Por ejemplo: + + ```javascript + console.log(-3 ** 2); // => -9, ¡no 9! + ``` + + A primera vista, puede parecer que `-3` se eleva al cuadrado, y el resultado debería ser `9`. Pero el resultado será `-9`. + + La razón está en el orden de los cálculos: primero se realiza la potenciación (`**`), y sólo después se aplica el menos unario. Es decir: `-(3 ** 2) = -9`. Hablaremos sobre la prioridad de las operaciones con más detalle en las siguientes lecciones. instructions: | - Escribe un programa que calcule la diferencia entre los números `6` y `-81` y muestre la respuesta en pantalla. + + Un submarino se encuentra a una profundidad de -81 m. La cubierta del barco de rescate está situada a una altura de +6 m sobre el nivel del agua. + + Calcula y muestra en pantalla: + + 1. La distancia total de ascenso en metros. + 2. El tiempo de ascenso en minutos — el submarino asciende a una velocidad de 3 m/min. tips: + - | + Separa siempre los operadores aritméticos de sus operandos con espacios — es un buen estilo de programación. - | [Operadores en JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Expressions_and_Operators) definitions: - name: Operación aritmética description: suma, resta, multiplicación y división. + - name: Operador + description: símbolo especial que crea una operación. Por ejemplo, `+` crea la operación de suma. + - name: Operando + description: 'objeto que participa en una operación. `3 * 6`: aquí 3 y 6 son operandos.' - name: Operación unaria description: operación con un solo operando. Por ejemplo, `-3` es una operación unaria para obtener el número opuesto al número tres. - name: Operación binaria diff --git a/modules/20-arithmetics/25-operator/en/EXERCISE.md b/modules/20-arithmetics/25-operator/en/EXERCISE.md index 9fcd61e6..c016d56e 100644 --- a/modules/20-arithmetics/25-operator/en/EXERCISE.md +++ b/modules/20-arithmetics/25-operator/en/EXERCISE.md @@ -1 +1,6 @@ -Write a program that calculates and prints the difference between `6` and `-81`. +A submarine is at a depth of -81 m. The deck of the rescue ship is located at a height of +6 m above the water level. + +Calculate and print to the screen: + +1. The total ascent distance in meters. +2. The ascent time in minutes — the submarine rises at a speed of 3 m/min. diff --git a/modules/20-arithmetics/25-operator/en/README.md b/modules/20-arithmetics/25-operator/en/README.md index e1a65009..bc35f19a 100644 --- a/modules/20-arithmetics/25-operator/en/README.md +++ b/modules/20-arithmetics/25-operator/en/README.md @@ -1,17 +1,63 @@ -Before we move on, let's take a look at the basic terminology. Operation signs such as `+` are called **operators**. They perform operations on certain values (**operands**). Operators are usually represented by one or more symbols, but occasionally, they can be represented by a word. Most of the operators are identical to those you'll have seen in math class. +In mathematics and programming, we often use operation signs such as `+`, `-`, `*`, and others. In programming, such signs are called operators. + +- An operator is a symbol or word that denotes an action. +- Operands are the values to which the operator is applied. + +Example: ```javascript console.log(8 + 2); ``` -Here the `+` is an addition **operator**, `8` and `2` are **operands**. -The addition operation has two operands, positioned to the left and right of the operator `+`. Operations with two operands are called **binary** operations. If at least one operand is missing, for example, `3 + ;` then the program will throw out a syntax error. +Here: + +- `+` is an operator +- `8` and `2` are operands +- the result will be `10` + +```text +operand operator operand result + 8 + 2 → 10 + 5 - 3 → 2 + 4 * 3 → 12 +``` + +## Unary operators + +There are also unary operations that work with a single operand. Example: -Besides binary operations (not operators) there are unary operations (with one operand) and even ternary (with three operands)! Moreover, operators may look the same but denote different operations. +```javascript +console.log(-3); // => -3 +``` + +In this case, `-` is a unary operator, and `3` is the operand. The interpreter receives the command: "take the number 3 and change its sign". + +The `-` operator can be used in different ways. When it stands **between two numbers**, it is a subtraction operation: + +```javascript +console.log(5 - 2); // => 3 +console.log(10 - 7); // => 3 +``` + +This difference is especially noticeable when working with negative numbers: + +```javascript +// minus times minus gives plus +console.log(5 - -2); // => 7 +``` + +First we see the subtraction operation: `5 - (...)`. But on the right there is a unary minus `-2`, which turns `2` into a negative number. As a result, we get: `5 - (-2) = 7`. + +Thus, the meaning of `-` depends on the context: if there is another number next to it, it is subtraction; otherwise, it is a change of the number's sign. + +## Errors in calculations + +If you treat `-3` as a single number, you might not notice that `-` is a separate operator with its own priority. For example: + +```javascript +console.log(-3 ** 2); // => -9, not 9! +``` - ```javascript - console.log(-3); // => -3 - ``` -In the example above, the unary operation applies to `3`. An interpreter will read it as follows: the minus operator tells it to take the number `3` and find the opposite, which is `-3`. +At first glance, it might seem that `-3` is being squared, and the result should be `9`. But the result will be `-9`. -You might be a bit confused since `-3` is both a number and an operator with an operand, but that's simply how programming languages work. +The reason lies in the order of calculations: first the exponentiation (`**`) is performed, and only then the unary minus is applied. That is: `-(3 ** 2) = -9`. We will talk about operator priority in more detail in the following lessons. diff --git a/modules/20-arithmetics/25-operator/en/data.yml b/modules/20-arithmetics/25-operator/en/data.yml index 19e4a18c..a9d240d6 100644 --- a/modules/20-arithmetics/25-operator/en/data.yml +++ b/modules/20-arithmetics/25-operator/en/data.yml @@ -1,15 +1,24 @@ --- name: Operators tips: + - >- + Always separate arithmetic operators from their operands with spaces — this + is good programming style. - > - [JavaScript - operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators) + [Operators in + JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators) definitions: - - name: Arithmetic operations - description: are addition, subtraction, multiplication and division. + - name: Arithmetic operation + description: addition, subtraction, multiplication, and division. + - name: Operator + description: >- + a special symbol that creates an operation. For example, `+` creates the + addition operation. + - name: Operand + description: 'an object that participates in an operation. `3 * 6`: here 3 and 6 are operands.' - name: Unary operation description: >- - is an operation with only one operand. For example, `-3` is an unary - operation to get the number which is opposite to 3. + an operation with a single operand. For example, `-3` is a unary + operation for getting the number opposite to three. - name: Binary operation - description: is an operation involving two operands. For example, `3 + 9`. + description: an operation with two operands. For example, `3 + 9`. diff --git a/modules/20-arithmetics/25-operator/es/EXERCISE.md b/modules/20-arithmetics/25-operator/es/EXERCISE.md index 6e382d0d..00d09163 100644 --- a/modules/20-arithmetics/25-operator/es/EXERCISE.md +++ b/modules/20-arithmetics/25-operator/es/EXERCISE.md @@ -1 +1,6 @@ -Escribe un programa que calcule la diferencia entre los números `6` y `-81` y muestre la respuesta en pantalla. +Un submarino se encuentra a una profundidad de -81 m. La cubierta del barco de rescate está situada a una altura de +6 m sobre el nivel del agua. + +Calcula y muestra en pantalla: + +1. La distancia total de ascenso en metros. +2. El tiempo de ascenso en minutos — el submarino asciende a una velocidad de 3 m/min. diff --git a/modules/20-arithmetics/25-operator/es/README.md b/modules/20-arithmetics/25-operator/es/README.md index 31858377..da377c90 100644 --- a/modules/20-arithmetics/25-operator/es/README.md +++ b/modules/20-arithmetics/25-operator/es/README.md @@ -1,20 +1,63 @@ +En matemáticas y programación, a menudo usamos signos de operación como `+`, `-`, `*` y otros. En programación, estos signos se llaman operadores. -Antes de continuar, vamos a repasar la terminología básica. Un símbolo de operación, como `+`, se llama **operador**. Los operadores realizan operaciones en valores específicos, que se llaman **operandos**. Los operadores en sí suelen estar representados por uno o varios caracteres, aunque a veces también pueden ser palabras. La gran mayoría de los operadores corresponden a operaciones matemáticas. +- Un operador es un símbolo o palabra que denota una acción. +- Los operandos son los valores a los que se aplica el operador. + +Ejemplo: ```javascript console.log(8 + 2); ``` -En este ejemplo, `+` es el **operador**, y los números `8` y `2` son los **operandos**. +Aquí: + +- `+` es un operador +- `8` y `2` son operandos +- el resultado será `10` + +```text +operando operador operando resultado + 8 + 2 → 10 + 5 - 3 → 2 + 4 * 3 → 12 +``` + +## Operadores unarios + +También existen operaciones unarias, que trabajan con un solo operando. Ejemplo: + +```javascript +console.log(-3); // => -3 +``` + +En este caso, `-` es un operador unario, y `3` es el operando. El intérprete recibe la orden: "toma el número 3 y cambia su signo". + +El operador `-` puede usarse de diferentes maneras. Cuando se encuentra **entre dos números**, es una operación de resta: + +```javascript +console.log(5 - 2); // => 3 +console.log(10 - 7); // => 3 +``` + +Esta diferencia es especialmente notable al trabajar con números negativos: -En el caso de la suma, tenemos dos operandos: uno a la izquierda y otro a la derecha del símbolo `+`. Las operaciones que requieren dos operandos se llaman **binarias**. Si falta al menos uno de los operandos, por ejemplo, `3 + ;`, el programa mostrará un error de sintaxis. +```javascript +// menos por menos da más +console.log(5 - -2); // => 7 +``` -Las operaciones (no los operadores) pueden ser no sólo binarias, sino también unarias (con un solo operando) e incluso ternarias (con tres operandos). Además, los operadores pueden tener la misma apariencia pero representar operaciones diferentes. +Primero vemos la operación de resta: `5 - (...)`. Pero a la derecha hay un menos unario `-2`, que convierte el `2` en un número negativo. Como resultado, obtenemos: `5 - (-2) = 7`. - ```javascript - console.log(-3); // => -3 - ``` +Así, el significado de `-` depende del contexto: si hay otro número a su lado, es una resta; de lo contrario, es un cambio de signo del número. + +## Errores en los cálculos + +Si consideras `-3` como un único número, puedes no darte cuenta de que `-` es un operador independiente con su propia prioridad. Por ejemplo: + +```javascript +console.log(-3 ** 2); // => -9, ¡no 9! +``` -En el ejemplo anterior, se aplica una operación unaria al número `3`. El operador de menos antes del tres le indica al intérprete que tome el número `3` y encuentre su opuesto, es decir, `-3`. +A primera vista, puede parecer que `-3` se eleva al cuadrado, y el resultado debería ser `9`. Pero el resultado será `-9`. -Esto puede ser un poco confuso, ya que `-3` es tanto un número en sí mismo como un operador con un operando, pero es una estructura común en los lenguajes de programación. +La razón está en el orden de los cálculos: primero se realiza la potenciación (`**`), y sólo después se aplica el menos unario. Es decir: `-(3 ** 2) = -9`. Hablaremos sobre la prioridad de las operaciones con más detalle en las siguientes lecciones. diff --git a/modules/20-arithmetics/25-operator/es/data.yml b/modules/20-arithmetics/25-operator/es/data.yml index ade32f95..4e11c06a 100644 --- a/modules/20-arithmetics/25-operator/es/data.yml +++ b/modules/20-arithmetics/25-operator/es/data.yml @@ -1,12 +1,21 @@ --- name: Operadores tips: + - >- + Separa siempre los operadores aritméticos de sus operandos con espacios — + es un buen estilo de programación. - > [Operadores en JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Expressions_and_Operators) definitions: - name: Operación aritmética description: suma, resta, multiplicación y división. + - name: Operador + description: >- + símbolo especial que crea una operación. Por ejemplo, `+` crea la + operación de suma. + - name: Operando + description: 'objeto que participa en una operación. `3 * 6`: aquí 3 y 6 son operandos.' - name: Operación unaria description: >- operación con un solo operando. Por ejemplo, `-3` es una operación unaria diff --git a/modules/20-arithmetics/27-commutativity/description.es.yml b/modules/20-arithmetics/27-commutativity/description.es.yml index 5bf8fc20..39d1dfd8 100644 --- a/modules/20-arithmetics/27-commutativity/description.es.yml +++ b/modules/20-arithmetics/27-commutativity/description.es.yml @@ -2,17 +2,71 @@ name: Operación conmutativa theory: | - Todos recordamos de la escuela: "el resultado no cambia al modificar el orden de los sumandos". Este es uno de los principios básicos e intuitivos de la aritmética, se llama **ley conmutativa**. - Una operación binaria se considera conmutativa si al intercambiar los operandos se obtiene el mismo resultado. Es obvio que la suma es una operación conmutativa: *3 + 2 = 2 + 3*. + La frase "el resultado no cambia al modificar el orden de los sumandos" es familiar para todos desde la escuela. Este principio se llama ley conmutativa y es una de las leyes fundamentales de la aritmética. - Pero, ¿es la resta una operación conmutativa? Por supuesto que no: *2 - 3 ≠ 3 - 2*. En programación, esta ley funciona de la misma manera que en aritmética. + ## Qué es la conmutatividad - Además, la mayoría de las operaciones con las que nos encontramos en la vida real no son conmutativas. Por lo tanto, siempre preste atención al orden en el que trabaja. + Una operación se llama conmutativa si el orden de los operandos no afecta el resultado: si intercambias los valores, obtienes la misma respuesta. Un ejemplo de operación conmutativa es la suma. + + ```javascript + console.log(3 + 2); // => 5 + console.log(2 + 3); // => 5 + ``` + + El resultado idéntico confirma que la operación es conmutativa. + + ```text + 2 + 3 = 5 3 + 2 = 5 + └──────────┬─────────┘ + mismo resultado + + 2 - 3 = -1 3 - 2 = 1 + └──────────┬─────────┘ + resultado diferente + ``` + + ## Operaciones no conmutativas + + Pero no todas las operaciones tienen esta propiedad. Por ejemplo, la resta es una operación no conmutativa: + + ```javascript + console.log(2 - 3); // => -1 + console.log(3 - 2); // => 1 + ``` + + Intercambiar los operandos da un resultado diferente. + + ## En programación es exactamente igual + + La conmutatividad en programación funciona exactamente igual que en aritmética. JavaScript sigue estrictamente las reglas matemáticas. + + Otras operaciones no conmutativas: + + - División: _8 / 2 ≠ 2 / 8_ + - Exponenciación: _2 \*\*3 ≠ 3\*\* 2_ + + Ejemplos en código: + + ```javascript + // División + console.log(8 / 2); // 8 dividido por 2 = 4 + + // Exponenciación + console.log(3 ** 2); // 3 al cuadrado = 9 + ``` + + Por lo tanto: + + - Verifica siempre con cuidado el orden de los operandos, especialmente al trabajar con operaciones desconocidas; + - comprueba la conmutatividad de forma experimental en lugar de suponerla de antemano. instructions: | - Escriba un programa que calcule y muestre en pantalla los valores de las siguientes expresiones matemáticas: "3 elevado a la 5" y "-8 dividido por -4". + Escribe un programa que resuelva dos tareas y muestre las respuestas en pantalla, cada una en su propia línea. + + 1. Un pintor quiere pintar 8 secciones de una valla, cada una de uno de 2 colores. ¿Cuántas combinaciones de colores únicas existen? Usa el operador de exponenciación `**`. + 2. Tú y dos amigos (3 personas en total) compraron 9 pasteles y quieren repartirlos por igual. ¿Cuántos le tocan a cada uno? Usa el operador de división `/`. tips: - | @@ -20,5 +74,7 @@ tips: definitions: - name: Conmutatividad - description: | - propiedad de una operación en la que el cambio de orden de los operandos no afecta el resultado. Por ejemplo, la suma es una operación conmutativa: el resultado no cambia al modificar el orden de los sumandos. + description: > + propiedad de una operación en la que el cambio de orden de los operandos + no afecta el resultado. Por ejemplo, la suma es una operación conmutativa: + el resultado no cambia al modificar el orden de los sumandos. diff --git a/modules/20-arithmetics/27-commutativity/en/EXERCISE.md b/modules/20-arithmetics/27-commutativity/en/EXERCISE.md index b7b88624..49a2364c 100644 --- a/modules/20-arithmetics/27-commutativity/en/EXERCISE.md +++ b/modules/20-arithmetics/27-commutativity/en/EXERCISE.md @@ -1,2 +1,4 @@ +Write a program that solves two tasks and prints the answers to the screen — each on its own line. -Write a program that adds and prints the values of "3 to the power of 5" and "-8 divided by -4". +1. A painter wants to paint 8 sections of a fence, each in one of 2 colors. How many unique color combinations are there? Use the exponentiation operator `**`. +2. You and two friends (3 people in total) bought 9 pastries and want to share them equally. How many does each person get? Use the division operator `/`. diff --git a/modules/20-arithmetics/27-commutativity/en/README.md b/modules/20-arithmetics/27-commutativity/en/README.md index 721b4475..e17bd3f5 100644 --- a/modules/20-arithmetics/27-commutativity/en/README.md +++ b/modules/20-arithmetics/27-commutativity/en/README.md @@ -1,7 +1,57 @@ -Do you remember the basic rule of arithmetic that "changing the order of the numbers we are adding doesn't change the sum"? It's called the **commutative law**. +The phrase "changing the order of the addends does not change the sum" is familiar to everyone from school. This principle is called the commutative law and is one of the fundamental laws of arithmetic. -A binary operation is commutative since swapping operands gets you the same result. Obviously, addition is a commutative operation: _3 + 2 = 2 + 3_. +## What is commutativity -But is subtraction a commutative operation? Of course not: _2 - 3 ≠ 3 - 2_. In programming, this law applies just like it does in arithmetic. +An operation is called commutative if the order of the operands does not affect the result: if you swap the values, you get the same answer. An example of a commutative operation is addition. -Moreover, most of the operations we face in real life are not commutative. Here is the conclusion: always pay attention to the order of things you work with. +```javascript +console.log(3 + 2); // => 5 +console.log(2 + 3); // => 5 +``` + +The identical result confirms that the operation is commutative. + +```text +2 + 3 = 5 3 + 2 = 5 +└──────────┬─────────┘ + same result + +2 - 3 = -1 3 - 2 = 1 +└──────────┬─────────┘ + different result +``` + +## Non-commutative operations + +But not all operations have this property. For example, subtraction is a non-commutative operation: + +```javascript +console.log(2 - 3); // => -1 +console.log(3 - 2); // => 1 +``` + +Swapping the operands gives a different result. + +## In programming, it works the same way + +Commutativity in programming works exactly as it does in arithmetic. JavaScript strictly follows mathematical rules. + +Other non-commutative operations: + +- Division: _8 / 2 ≠ 2 / 8_ +- Exponentiation: _2 \*\*3 ≠ 3\*\* 2_ + +Examples in code: + +```javascript +// Division +console.log(8 / 2); // 8 divided by 2 = 4 + +// Exponentiation +console.log(3 ** 2); // 3 squared = 9 +``` + +Therefore: + +- Always carefully check the order of the operands, especially when working with unfamiliar operations; +- check commutativity experimentally rather than assuming it in advance. diff --git a/modules/20-arithmetics/27-commutativity/en/data.yml b/modules/20-arithmetics/27-commutativity/en/data.yml index 12af9fd3..c34cbc6d 100644 --- a/modules/20-arithmetics/27-commutativity/en/data.yml +++ b/modules/20-arithmetics/27-commutativity/en/data.yml @@ -1,10 +1,12 @@ --- -name: Commutative operations -tips: [] +name: Commutative operation +tips: + - > + [More about + commutativity](https://en.wikipedia.org/wiki/Commutative_property) definitions: - name: Commutativity description: > - is a property of an operation wherein changing the order of the operands - does not change the result. For example, addition is a commutative - operation: changing the order of the numbers we are adding does not change - the sum. + a property of an operation where changing the order of the operands does + not affect the result. For example, addition is a commutative operation: + changing the order of the addends does not change the sum. diff --git a/modules/20-arithmetics/27-commutativity/es/EXERCISE.md b/modules/20-arithmetics/27-commutativity/es/EXERCISE.md index 3191ace4..4b180216 100644 --- a/modules/20-arithmetics/27-commutativity/es/EXERCISE.md +++ b/modules/20-arithmetics/27-commutativity/es/EXERCISE.md @@ -1,2 +1,4 @@ +Escribe un programa que resuelva dos tareas y muestre las respuestas en pantalla, cada una en su propia línea. -Escriba un programa que calcule y muestre en pantalla los valores de las siguientes expresiones matemáticas: "3 elevado a la 5" y "-8 dividido por -4". +1. Un pintor quiere pintar 8 secciones de una valla, cada una de uno de 2 colores. ¿Cuántas combinaciones de colores únicas existen? Usa el operador de exponenciación `**`. +2. Tú y dos amigos (3 personas en total) compraron 9 pasteles y quieren repartirlos por igual. ¿Cuántos le tocan a cada uno? Usa el operador de división `/`. diff --git a/modules/20-arithmetics/27-commutativity/es/README.md b/modules/20-arithmetics/27-commutativity/es/README.md index 2a0ec04a..17c055eb 100644 --- a/modules/20-arithmetics/27-commutativity/es/README.md +++ b/modules/20-arithmetics/27-commutativity/es/README.md @@ -1,7 +1,57 @@ -Todos recordamos de la escuela: "el resultado no cambia al modificar el orden de los sumandos". Este es uno de los principios básicos e intuitivos de la aritmética, se llama **ley conmutativa**. +La frase "el resultado no cambia al modificar el orden de los sumandos" es familiar para todos desde la escuela. Este principio se llama ley conmutativa y es una de las leyes fundamentales de la aritmética. -Una operación binaria se considera conmutativa si al intercambiar los operandos se obtiene el mismo resultado. Es obvio que la suma es una operación conmutativa: *3 + 2 = 2 + 3*. +## Qué es la conmutatividad -Pero, ¿es la resta una operación conmutativa? Por supuesto que no: *2 - 3 ≠ 3 - 2*. En programación, esta ley funciona de la misma manera que en aritmética. +Una operación se llama conmutativa si el orden de los operandos no afecta el resultado: si intercambias los valores, obtienes la misma respuesta. Un ejemplo de operación conmutativa es la suma. -Además, la mayoría de las operaciones con las que nos encontramos en la vida real no son conmutativas. Por lo tanto, siempre preste atención al orden en el que trabaja. +```javascript +console.log(3 + 2); // => 5 +console.log(2 + 3); // => 5 +``` + +El resultado idéntico confirma que la operación es conmutativa. + +```text +2 + 3 = 5 3 + 2 = 5 +└──────────┬─────────┘ + mismo resultado + +2 - 3 = -1 3 - 2 = 1 +└──────────┬─────────┘ + resultado diferente +``` + +## Operaciones no conmutativas + +Pero no todas las operaciones tienen esta propiedad. Por ejemplo, la resta es una operación no conmutativa: + +```javascript +console.log(2 - 3); // => -1 +console.log(3 - 2); // => 1 +``` + +Intercambiar los operandos da un resultado diferente. + +## En programación es exactamente igual + +La conmutatividad en programación funciona exactamente igual que en aritmética. JavaScript sigue estrictamente las reglas matemáticas. + +Otras operaciones no conmutativas: + +- División: _8 / 2 ≠ 2 / 8_ +- Exponenciación: _2 \*\*3 ≠ 3\*\* 2_ + +Ejemplos en código: + +```javascript +// División +console.log(8 / 2); // 8 dividido por 2 = 4 + +// Exponenciación +console.log(3 ** 2); // 3 al cuadrado = 9 +``` + +Por lo tanto: + +- Verifica siempre con cuidado el orden de los operandos, especialmente al trabajar con operaciones desconocidas; +- comprueba la conmutatividad de forma experimental en lugar de suponerla de antemano. diff --git a/modules/20-arithmetics/30-composition/description.es.yml b/modules/20-arithmetics/30-composition/description.es.yml index 767cbd2c..2b418e97 100644 --- a/modules/20-arithmetics/30-composition/description.es.yml +++ b/modules/20-arithmetics/30-composition/description.es.yml @@ -2,42 +2,95 @@ name: Composición de operaciones theory: | - ¿Qué pasa si necesitamos calcular la siguiente expresión: `3 * 5 - 2`? Así es como lo escribiremos: + + En JavaScript, al igual que en las matemáticas, puedes combinar varias operaciones en una sola línea. El intérprete procesa estas expresiones paso a paso según ciertas reglas. + + Veamos un ejemplo: ```javascript - console.log(3 * 5 - 2); // => 13 + console.log(2 * 4 * 5 * 10); ``` - Observa que el intérprete realiza las operaciones aritméticas en el orden correcto: primero la multiplicación y la división, luego la suma y la resta. A veces, es necesario cambiar este orden, lo cual veremos en la siguiente lección. + Este código consta de varias operaciones de multiplicación combinadas en una sola expresión. Para entender cómo el intérprete evalúa la expresión, analicémosla paso a paso: + + - Primero se calcula `2 * 4`: `8 * 5 * 10` + - Luego `8 * 5`: `40 * 10` + - Y finalmente `40 * 10`: `400` - Otra ejemplo: + El resultado final es `400`. + + ## ¿Y si las operaciones son diferentes? + + Todo es sencillo mientras se utilicen los mismos operadores. Pero ¿qué sucede si combinamos, por ejemplo, la multiplicación y la suma? ```javascript - console.log(2 * 4 * 5 * 10); + console.log(2 + 3 * 4); ``` + ```text + 2 + 3 * 4 + └─┬─┘ + 2 + 12 + └──┬───┘ + 14 + ``` - Como puedes ver, las operaciones se pueden combinar entre sí, lo que nos permite calcular expresiones compuestas más complejas. Para entender cómo se realizan los cálculos dentro del intérprete, analicemos el ejemplo: `2 * 4 * 5 * 10`. + ¿El resultado será `20` o `14`? La respuesta es `14`. - 1. Primero se calcula `2 * 4` y se obtiene la expresión `8 * 5 * 10`. - 2. Luego se calcula `8 * 5`. Al final, tenemos `40 * 10`. - 3. Finalmente, se realiza la última multiplicación y se obtiene el resultado `400`. + Esto se debe a que en JavaScript, al igual que en las matemáticas, las operaciones tienen prioridad. La multiplicación se realiza antes que la suma, a menos que se utilicen paréntesis. Lo veremos con más detalle en la lección sobre las prioridades. - De esta manera, el intérprete combina expresiones compuestas complejas, realizando las operaciones aritméticas en el orden correcto de forma predeterminada: primero la multiplicación y la división, luego la suma y la resta. + ## Ejemplos con resta y números negativos -instructions: | + La misma regla funciona para la resta: + + ```javascript + console.log(10 - 2 * 3); // => 4 + ``` + + Primero se realiza la multiplicación: `10 - 6 = 4`. + + Si la expresión contiene números negativos, el menos unario se aplica después de la potenciación: - Implementa un programa que calcule y muestre en pantalla el valor de la siguiente expresión: + ```javascript + console.log(-2 ** 2); // => -4, dos elevado a la potencia de dos, luego se aplica el menos + console.log(-2 * 5); // => -10, menos dos multiplicado por cinco + console.log(4 + -2); // => 2 + console.log(6 - -2); // => 8 + ``` + + En todos los ejemplos, excepto el primero, primero se calcula el menos unario (`-2`) y luego se realizan las operaciones restantes. + + Veamos con más detalle el último ejemplo: + ```javascript + console.log(6 - -2); // => 8 ``` - 8 / 2 + 5 - -3 / 2 + + Primero se calcula el menos unario (`-2`), y luego la operación se convierte en `6 - (-2)`, lo que da `8`. Esto es lo mismo que: + + ```javascript + console.log(6 + 2); // => 8 ``` - No realices ningún cálculo por tu cuenta; tu programa debe realizar todos los cálculos por sí mismo. + ## Qué hay que recordar + + - Las expresiones pueden constar de varias operaciones. + - JavaScript las evalúa paso a paso: de izquierda a derecha, respetando la prioridad de las operaciones. + - Los paréntesis se pueden utilizar para indicar explícitamente el orden de evaluación. + +instructions: | + + Vas a la tienda a comprar regalos: 3 libros a 200 rublos cada uno y 2 bolígrafos a 30 rublos cada uno. Calcula y muestra el costo total de la compra. + + ```text + 3 * 200 + 2 * 30 + ↓ ↓ + 600 + 60 = 660 + ``` tips: [] definitions: - name: Composición description: | - Método de combinar varias operaciones simples en una sola operación compleja. + método de combinar varias operaciones simples en una sola operación compleja. diff --git a/modules/20-arithmetics/30-composition/en/EXERCISE.md b/modules/20-arithmetics/30-composition/en/EXERCISE.md index be1ff967..cad5e962 100644 --- a/modules/20-arithmetics/30-composition/en/EXERCISE.md +++ b/modules/20-arithmetics/30-composition/en/EXERCISE.md @@ -1,8 +1,7 @@ +You are going to the store to buy gifts: 3 books at 200 rubles each and 2 pens at 30 rubles each. Calculate and print the total cost of the purchase. -Write a program that calculates and prints the value of this expression: - -``` -8 / 2 + 5 - -3 / 2 +```text +3 * 200 + 2 * 30 + ↓ ↓ + 600 + 60 = 660 ``` - -Don't calculate anything manually, your program should do all the calculations on its own. diff --git a/modules/20-arithmetics/30-composition/en/README.md b/modules/20-arithmetics/30-composition/en/README.md index f914e84f..c8b730ed 100644 --- a/modules/20-arithmetics/30-composition/en/README.md +++ b/modules/20-arithmetics/30-composition/en/README.md @@ -1,18 +1,74 @@ -Suppose we want to calculate an expression such as `3 * 5 - 2`. That is exactly how we would write it down: +In JavaScript, just like in mathematics, you can combine several operations into a single line. The interpreter processes such expressions step by step according to certain rules. + +Let's look at an example: ```javascript -console.log(3 * 5 - 2); // => 13 +console.log(2 * 4 * 5 * 10); ``` -Note that the interpreter performs arithmetic operations in the right order: first division and multiplication, then addition and subtraction. Sometimes we want to change the order of calculations. We'll dig into this topic in the next lesson. Or another example: +This code consists of several multiplication operations combined into one expression. To understand how the interpreter evaluates the expression, let's break it down step by step: + +- First, `2 * 4` is computed: `8 * 5 * 10` +- Then `8 * 5`: `40 * 10` +- And finally `40 * 10`: `400` + +The final result is `400`. + +## What about different operations? + +Everything is simple as long as the same operators are used. But what happens if you combine, for example, multiplication and addition? ```javascript -console.log(2 * 4 * 5 * 10); +console.log(2 + 3 * 4); +``` + +```text +2 + 3 * 4 + └─┬─┘ +2 + 12 +└──┬───┘ + 14 +``` + +Will the result be `20` or `14`? The answer is `14`. + +This is because in JavaScript, just like in mathematics, operations have precedence. Multiplication is performed before addition unless parentheses are used. We will look at this in more detail in the lesson on precedence. + +## Examples with subtraction and negative numbers + +The same rule works for subtraction: + +```javascript +console.log(10 - 2 * 3); // => 4 +``` + +First, multiplication is performed: `10 - 6 = 4`. + +If the expression contains negative numbers, the unary minus is applied after exponentiation: + +```javascript +console.log(-2 ** 2); // => -4, two to the power of two, then the minus is applied +console.log(-2 * 5); // => -10, minus two multiplied by five +console.log(4 + -2); // => 2 +console.log(6 - -2); // => 8 +``` + +In all examples except the first one, the unary minus (`-2`) is computed first, and then the remaining operations are performed. + +Let's take a closer look at the last example: + +```javascript +console.log(6 - -2); // => 8 +``` + +First, the unary minus (`-2`) is computed, and then the operation becomes `6 - (-2)`, which gives `8`. This is the same as: + +```javascript +console.log(6 + 2); // => 8 ``` - As you can see, we can combine operations, which allows us to compute even more complex compound expressions. To visualize how calculations are done inside the interpreter, let's look at an example: `2 * 4 * 5 * 10`. -1. First we calculate `2 * 4` and get `8 * 5 * 10` -2. Then we calculate `8 * 5`, which gives us `40 * 10` -3. Finally, do the last multiplication. The result will be `400` +## What to remember -We can combine operations, making it possible to compute increasingly complex compound expressions. +- Expressions can consist of several operations. +- JavaScript evaluates them step by step: from left to right, respecting operation precedence. +- Parentheses can be used to explicitly indicate the order of evaluation. diff --git a/modules/20-arithmetics/30-composition/en/data.yml b/modules/20-arithmetics/30-composition/en/data.yml index 7666a24f..3718495a 100644 --- a/modules/20-arithmetics/30-composition/en/data.yml +++ b/modules/20-arithmetics/30-composition/en/data.yml @@ -1,3 +1,7 @@ --- name: Composition of operations tips: [] +definitions: + - name: Composition + description: | + a method of combining several simple operations into one complex operation. diff --git a/modules/20-arithmetics/30-composition/es/EXERCISE.md b/modules/20-arithmetics/30-composition/es/EXERCISE.md index 0c98dee7..8a7235f5 100644 --- a/modules/20-arithmetics/30-composition/es/EXERCISE.md +++ b/modules/20-arithmetics/30-composition/es/EXERCISE.md @@ -1,8 +1,7 @@ +Vas a la tienda a comprar regalos: 3 libros a 200 rublos cada uno y 2 bolígrafos a 30 rublos cada uno. Calcula y muestra el costo total de la compra. -Implementa un programa que calcule y muestre en pantalla el valor de la siguiente expresión: - -``` -8 / 2 + 5 - -3 / 2 +```text +3 * 200 + 2 * 30 + ↓ ↓ + 600 + 60 = 660 ``` - -No realices ningún cálculo por tu cuenta; tu programa debe realizar todos los cálculos por sí mismo. diff --git a/modules/20-arithmetics/30-composition/es/README.md b/modules/20-arithmetics/30-composition/es/README.md index 7ae5ea87..b440d760 100644 --- a/modules/20-arithmetics/30-composition/es/README.md +++ b/modules/20-arithmetics/30-composition/es/README.md @@ -1,21 +1,74 @@ -¿Qué pasa si necesitamos calcular la siguiente expresión: `3 * 5 - 2`? Así es como lo escribiremos: +En JavaScript, al igual que en las matemáticas, puedes combinar varias operaciones en una sola línea. El intérprete procesa estas expresiones paso a paso según ciertas reglas. + +Veamos un ejemplo: ```javascript -console.log(3 * 5 - 2); // => 13 +console.log(2 * 4 * 5 * 10); ``` -Observa que el intérprete realiza las operaciones aritméticas en el orden correcto: primero la multiplicación y la división, luego la suma y la resta. A veces, es necesario cambiar este orden, lo cual veremos en la siguiente lección. +Este código consta de varias operaciones de multiplicación combinadas en una sola expresión. Para entender cómo el intérprete evalúa la expresión, analicémosla paso a paso: + +- Primero se calcula `2 * 4`: `8 * 5 * 10` +- Luego `8 * 5`: `40 * 10` +- Y finalmente `40 * 10`: `400` + +El resultado final es `400`. -Otra ejemplo: +## ¿Y si las operaciones son diferentes? + +Todo es sencillo mientras se utilicen los mismos operadores. Pero ¿qué sucede si combinamos, por ejemplo, la multiplicación y la suma? ```javascript -console.log(2 * 4 * 5 * 10); +console.log(2 + 3 * 4); +``` + +```text +2 + 3 * 4 + └─┬─┘ +2 + 12 +└──┬───┘ + 14 +``` + +¿El resultado será `20` o `14`? La respuesta es `14`. + +Esto se debe a que en JavaScript, al igual que en las matemáticas, las operaciones tienen prioridad. La multiplicación se realiza antes que la suma, a menos que se utilicen paréntesis. Lo veremos con más detalle en la lección sobre las prioridades. + +## Ejemplos con resta y números negativos + +La misma regla funciona para la resta: + +```javascript +console.log(10 - 2 * 3); // => 4 +``` + +Primero se realiza la multiplicación: `10 - 6 = 4`. + +Si la expresión contiene números negativos, el menos unario se aplica después de la potenciación: + +```javascript +console.log(-2 ** 2); // => -4, dos elevado a la potencia de dos, luego se aplica el menos +console.log(-2 * 5); // => -10, menos dos multiplicado por cinco +console.log(4 + -2); // => 2 +console.log(6 - -2); // => 8 +``` + +En todos los ejemplos, excepto el primero, primero se calcula el menos unario (`-2`) y luego se realizan las operaciones restantes. + +Veamos con más detalle el último ejemplo: + +```javascript +console.log(6 - -2); // => 8 ``` -Como puedes ver, las operaciones se pueden combinar entre sí, lo que nos permite calcular expresiones compuestas más complejas. Para entender cómo se realizan los cálculos dentro del intérprete, analicemos el ejemplo: `2 * 4 * 5 * 10`. +Primero se calcula el menos unario (`-2`), y luego la operación se convierte en `6 - (-2)`, lo que da `8`. Esto es lo mismo que: + +```javascript +console.log(6 + 2); // => 8 +``` -1. Primero se calcula `2 * 4` y se obtiene la expresión `8 * 5 * 10`. -2. Luego se calcula `8 * 5`. Al final, tenemos `40 * 10`. -3. Finalmente, se realiza la última multiplicación y se obtiene el resultado `400`. +## Qué hay que recordar -De esta manera, el intérprete combina expresiones compuestas complejas, realizando las operaciones aritméticas en el orden correcto de forma predeterminada: primero la multiplicación y la división, luego la suma y la resta. +- Las expresiones pueden constar de varias operaciones. +- JavaScript las evalúa paso a paso: de izquierda a derecha, respetando la prioridad de las operaciones. +- Los paréntesis se pueden utilizar para indicar explícitamente el orden de evaluación. diff --git a/modules/20-arithmetics/30-composition/es/data.yml b/modules/20-arithmetics/30-composition/es/data.yml index 9ab9ca37..3ce94b51 100644 --- a/modules/20-arithmetics/30-composition/es/data.yml +++ b/modules/20-arithmetics/30-composition/es/data.yml @@ -3,6 +3,5 @@ name: Composición de operaciones tips: [] definitions: - name: Composición - description: > - Método de combinar varias operaciones simples en una sola operación - compleja. + description: | + método de combinar varias operaciones simples en una sola operación compleja. diff --git a/modules/20-arithmetics/40-priority/description.es.yml b/modules/20-arithmetics/40-priority/description.es.yml index e56699fc..7fd20345 100644 --- a/modules/20-arithmetics/40-priority/description.es.yml +++ b/modules/20-arithmetics/40-priority/description.es.yml @@ -2,43 +2,81 @@ name: Prioridad de las operaciones theory: | - Observa detenidamente la expresión `2 + 2 * 2` y calcula mentalmente el resultado. + Consideremos una expresión sencilla: - Respuesta correcta: `6`. + ```javascript + console.log(2 + 2 * 2); // => 6 + ``` + + El resultado es 6, no 8. Esto se explica por el concepto de prioridad de las operaciones en matemáticas y programación. Determina el orden en que se ejecutan las operaciones: - Si obtuviste `8`, entonces esta lección es para ti. En matemáticas escolares, aprendimos el concepto de "prioridad de la operación". La prioridad determina en qué secuencia deben realizarse las operaciones. Por ejemplo, la multiplicación y la división tienen mayor prioridad que la suma y la resta, y la potenciación tiene la prioridad más alta de todas las operaciones aritméticas: `2 ** 3 * 2` se calculará como `16`. + - La multiplicación y la división se ejecutan antes que la suma y la resta. + - La potenciación (`**`) tiene una prioridad aún más alta. - Sin embargo, a menudo los cálculos deben realizarse en un orden diferente al de la prioridad estándar. En situaciones complicadas, se puede (y se debe) especificar la prioridad mediante paréntesis, al igual que en la escuela, por ejemplo: `(2 + 2) * 2`. + ```text + Prioridad de las operaciones (de mayor a menor): + + ** potenciación + ↓ + * / % multiplicación, división, resto + ↓ + + - suma, resta + ``` + + Por ejemplo: + + ```javascript + console.log(2 * 2 ** 3); // => 16, porque primero 2 ** 3 = 8, luego 8 * 2 = 16 + ``` - Los paréntesis se pueden colocar alrededor de cualquier operación. Pueden anidarse tantas veces como sea necesario. Aquí tienes algunos ejemplos: + Si hay operaciones con la misma prioridad una al lado de la otra, se ejecutan de izquierda a derecha: ```javascript - console.log(3 ** (4 - 2)); // => 9 - console.log(7 * 3 + (4 / 2) - (8 + (2 - 1))); // => 14 + console.log(8 / 2 * 3); // => 12, porque primero 8 / 2 = 4, luego 4 * 3 = 12 ``` - A veces, la expresión puede ser difícil de comprender visualmente. En ese caso, se pueden colocar paréntesis para hacerla más clara, sin afectar la prioridad. Por ejemplo, la tarea del ejercicio anterior se puede hacer un poco más comprensible si se colocan paréntesis. + ## Controlar el orden de las operaciones - Antes: + A veces es necesario cambiar el orden de los cálculos. Para ello se utilizan los paréntesis. Permiten indicar qué operaciones deben ejecutarse primero: ```javascript - console.log(8 / 2 + 5 - -3 / 2); // => 10.5 + console.log((2 + 2) * 2); // => 8 ``` - Después: + Los paréntesis se pueden colocar alrededor de cualquier parte de una expresión y anidarse unos dentro de otros: ```javascript - console.log(((8 / 2) + 5) - (-3 / 2)); // => 10.5 + console.log(3 ** (4 - 2)); // => 9 + console.log(7 * 3 + (4 / 2) - (8 + (2 - 1))); // => 14 ``` + La regla principal: cierra siempre los paréntesis. Los paréntesis sin pareja provocan errores: tanto los principiantes como los programadores experimentados a veces olvidan el paréntesis de cierre. - Recuerda: el código se escribe para las personas, porque son personas las que leerán el código y las máquinas solamente lo ejecutarán. Para las máquinas, el código es correcto o incorrecto, no hay código "más" o "menos" comprensible para ellas. + > Escribe los paréntesis en pareja de inmediato. Por ejemplo, escribe `()` y luego rellena la parte interna. La mayoría de los editores de código (incluido el nuestro) añaden automáticamente el paréntesis de cierre en cuanto escribes el de apertura. + + ## Mejorar la legibilidad + + A veces una expresión funciona correctamente, pero se ve confusa. En esos casos, se pueden añadir paréntesis solo por claridad: no cambian el resultado, pero mejoran la legibilidad. + + ```javascript + // Antes + console.log(8 / 2 + 5 - -3 / 2); // => 10.5 + + // Después + console.log(((8 / 2) + 5) - (-3 / 2)); // => 10.5 + ``` + + Los programas los escriben personas, y también los leen personas. A la computadora no le importa lo comprensible que sea el código: solo necesita que sea sintácticamente correcto. Para una persona, un código claro y ordenado es la clave de la comodidad, especialmente cuando se trabaja en equipo o se depuran errores. instructions: | + Tú y 4 amigos (5 personas en total) pidieron 2 pizzas a 300 rublos cada una y 4 bebidas a 50 rublos cada una. Hay que dividir la cuenta en partes iguales. - Dada la expresión `70 * 3 + 4 / 8 + 2`. + Escribe un programa de una sola línea con `console.log()`, colocando los paréntesis de manera que primero se calcule el importe total y luego se divida entre todos: - Coloca paréntesis de manera que ambas sumas (`3 + 4`) y (`8 + 2`) se calculen primero. Muestra el resultado en la pantalla. + ```text + sin paréntesis: 2 * 300 + 4 * 50 / 5 = 640 ← incorrecto + con paréntesis: (2 * 300 + 4 * 50) / 5 = 160 ← correcto + ``` tips: - | diff --git a/modules/20-arithmetics/40-priority/en/EXERCISE.md b/modules/20-arithmetics/40-priority/en/EXERCISE.md index 0a06e454..965d5564 100644 --- a/modules/20-arithmetics/40-priority/en/EXERCISE.md +++ b/modules/20-arithmetics/40-priority/en/EXERCISE.md @@ -1,4 +1,8 @@ +You and 4 friends (5 people in total) ordered 2 pizzas at 300 rubles each and 4 drinks at 50 rubles each. You need to split the bill equally. -Given the expression `70 * 3 + 4 / 8 + 2`. +Write a one-line program with `console.log()`, placing parentheses so that the total amount is calculated first and then divided among everyone: -Place parentheses so that both additions (`3 + 4`) and (`8 + 2`) will be calculated first. Print the result. +```text +without parentheses: 2 * 300 + 4 * 50 / 5 = 640 ← incorrect +with parentheses: (2 * 300 + 4 * 50) / 5 = 160 ← correct +``` diff --git a/modules/20-arithmetics/40-priority/en/README.md b/modules/20-arithmetics/40-priority/en/README.md index 6cbd2537..dd9ecc23 100644 --- a/modules/20-arithmetics/40-priority/en/README.md +++ b/modules/20-arithmetics/40-priority/en/README.md @@ -1,30 +1,65 @@ -Look closely at the expression `2 + 2 * 2` and try to work out the answer. +Consider a simple expression: -The correct answer is `6`. +```javascript +console.log(2 + 2 * 2); // => 6 +``` + +The result is 6, not 8. This is explained by the concept of operator precedence in mathematics and programming. It determines the order in which operations are performed: -If you guessed `8`, then you'll find this lesson useful. You'll have studied the order of operations in high school math. This concept defines the order in which operations are to be performed. For example, multiplication and division have a higher precedence than addition and subtraction, and exponentiation comes before all other arithmetic operations, e.g., `2 ** 3 * 2` gives us `16`. +- Multiplication and division are performed before addition and subtraction. +- Exponentiation (`**`) has an even higher precedence. -But sometimes we have to perform calculations in a non-standard order. In tricky cases, precedence can (and must) be set with parentheses, just like we did in high school, e.g., `(2 + 2) * 2`. +```text +Operator precedence (from high to low): + + ** exponentiation + ↓ + * / % multiplication, division, remainder + ↓ + + - addition, subtraction +``` + +For example: + +```javascript +console.log(2 * 2 ** 3); // => 16, because first 2 ** 3 = 8, then 8 * 2 = 16 +``` -Parentheses fit with any operation. They can be nested into each other as many times as you need. Here are a couple of examples: +If operations with the same precedence are next to each other, they are performed from left to right: ```javascript -console.log(3 ** (4 - 2)); // => 9 -console.log(7 * 3 + (4 / 2) - (8 + (2 - 1))); // => 14 +console.log(8 / 2 * 3); // => 12, because first 8 / 2 = 4, then 4 * 3 = 12 ``` -Sometimes an expression may be visually cumbersome. In such cases, parentheses can come in handy without affecting the order of operations. For example, the task from the previous lesson becomes clearer with parentheses. +## Controlling the order of operations -Before: +Sometimes you need to change the order of calculations. Parentheses are used for this. They let you specify which operations should be performed first: ```javascript -console.log(8 / 2 + 5 - -3 / 2); // => 10.5 +console.log((2 + 2) * 2); // => 8 ``` -After: +Parentheses can be placed around any part of an expression and nested within each other: ```javascript -console.log(((8 / 2) + 5) - (-3 / 2)); // => 10.5 +console.log(3 ** (4 - 2)); // => 9 +console.log(7 * 3 + (4 / 2) - (8 + (2 - 1))); // => 14 +``` + +The main rule: always close your parentheses. Unmatched parentheses cause errors: both beginners and experienced programmers sometimes forget about the closing parenthesis. + +> Write parentheses as a pair right away. For example, type `()` and then fill in the inner part. Most code editors (including ours) automatically add the closing parenthesis as soon as you write the opening one. + +## Improving readability + +Sometimes an expression works correctly but looks confusing. In such cases, parentheses can be added just for clarity: they won't change the result, but they will improve readability. + +```javascript +// Before +console.log(8 / 2 + 5 - -3 / 2); // => 10.5 + +// After +console.log(((8 / 2) + 5) - (-3 / 2)); // => 10.5 ``` -Note: code is written for humans, since they'll be the ones to read it, the machine just executes it. For the machine, code is either valid or invalid, it doesn't recognize "more" or "less" valid code. +Programs are written by people, and they are read by people too. The computer doesn't care how understandable the code is: it just needs to be syntactically correct. For a human, clear and tidy code is the key to convenience, especially when working in a team or debugging errors. diff --git a/modules/20-arithmetics/40-priority/en/data.yml b/modules/20-arithmetics/40-priority/en/data.yml index 467c947f..3f533bfa 100644 --- a/modules/20-arithmetics/40-priority/en/data.yml +++ b/modules/20-arithmetics/40-priority/en/data.yml @@ -1,6 +1,11 @@ --- name: Operator precedence tips: - - > + - | [Operator precedence](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) +definitions: + - name: Expression + description: > + a sequence of operations on data that produces some result that can be + used. diff --git a/modules/20-arithmetics/40-priority/es/EXERCISE.md b/modules/20-arithmetics/40-priority/es/EXERCISE.md index 218a6ac9..8b90fa45 100644 --- a/modules/20-arithmetics/40-priority/es/EXERCISE.md +++ b/modules/20-arithmetics/40-priority/es/EXERCISE.md @@ -1,4 +1,8 @@ +Tú y 4 amigos (5 personas en total) pidieron 2 pizzas a 300 rublos cada una y 4 bebidas a 50 rublos cada una. Hay que dividir la cuenta en partes iguales. -Dada la expresión `70 * 3 + 4 / 8 + 2`. +Escribe un programa de una sola línea con `console.log()`, colocando los paréntesis de manera que primero se calcule el importe total y luego se divida entre todos: -Coloca paréntesis de manera que ambas sumas (`3 + 4`) y (`8 + 2`) se calculen primero. Muestra el resultado en la pantalla. +```text +sin paréntesis: 2 * 300 + 4 * 50 / 5 = 640 ← incorrecto +con paréntesis: (2 * 300 + 4 * 50) / 5 = 160 ← correcto +``` diff --git a/modules/20-arithmetics/40-priority/es/README.md b/modules/20-arithmetics/40-priority/es/README.md index f784cfa8..78e1da97 100644 --- a/modules/20-arithmetics/40-priority/es/README.md +++ b/modules/20-arithmetics/40-priority/es/README.md @@ -1,30 +1,65 @@ -Observa detenidamente la expresión `2 + 2 * 2` y calcula mentalmente el resultado. +Consideremos una expresión sencilla: -Respuesta correcta: `6`. +```javascript +console.log(2 + 2 * 2); // => 6 +``` + +El resultado es 6, no 8. Esto se explica por el concepto de prioridad de las operaciones en matemáticas y programación. Determina el orden en que se ejecutan las operaciones: -Si obtuviste `8`, entonces esta lección es para ti. En matemáticas escolares, aprendimos el concepto de "prioridad de la operación". La prioridad determina en qué secuencia deben realizarse las operaciones. Por ejemplo, la multiplicación y la división tienen mayor prioridad que la suma y la resta, y la potenciación tiene la prioridad más alta de todas las operaciones aritméticas: `2 ** 3 * 2` se calculará como `16`. +- La multiplicación y la división se ejecutan antes que la suma y la resta. +- La potenciación (`**`) tiene una prioridad aún más alta. -Sin embargo, a menudo los cálculos deben realizarse en un orden diferente al de la prioridad estándar. En situaciones complicadas, se puede (y se debe) especificar la prioridad mediante paréntesis, al igual que en la escuela, por ejemplo: `(2 + 2) * 2`. +```text +Prioridad de las operaciones (de mayor a menor): + + ** potenciación + ↓ + * / % multiplicación, división, resto + ↓ + + - suma, resta +``` + +Por ejemplo: + +```javascript +console.log(2 * 2 ** 3); // => 16, porque primero 2 ** 3 = 8, luego 8 * 2 = 16 +``` -Los paréntesis se pueden colocar alrededor de cualquier operación. Pueden anidarse tantas veces como sea necesario. Aquí tienes algunos ejemplos: +Si hay operaciones con la misma prioridad una al lado de la otra, se ejecutan de izquierda a derecha: ```javascript -console.log(3 ** (4 - 2)); // => 9 -console.log(7 * 3 + (4 / 2) - (8 + (2 - 1))); // => 14 +console.log(8 / 2 * 3); // => 12, porque primero 8 / 2 = 4, luego 4 * 3 = 12 ``` -A veces, la expresión puede ser difícil de comprender visualmente. En ese caso, se pueden colocar paréntesis para hacerla más clara, sin afectar la prioridad. Por ejemplo, la tarea del ejercicio anterior se puede hacer un poco más comprensible si se colocan paréntesis. +## Controlar el orden de las operaciones -Antes: +A veces es necesario cambiar el orden de los cálculos. Para ello se utilizan los paréntesis. Permiten indicar qué operaciones deben ejecutarse primero: ```javascript -console.log(8 / 2 + 5 - -3 / 2); // => 10.5 +console.log((2 + 2) * 2); // => 8 ``` -Después: +Los paréntesis se pueden colocar alrededor de cualquier parte de una expresión y anidarse unos dentro de otros: ```javascript -console.log(((8 / 2) + 5) - (-3 / 2)); // => 10.5 +console.log(3 ** (4 - 2)); // => 9 +console.log(7 * 3 + (4 / 2) - (8 + (2 - 1))); // => 14 +``` + +La regla principal: cierra siempre los paréntesis. Los paréntesis sin pareja provocan errores: tanto los principiantes como los programadores experimentados a veces olvidan el paréntesis de cierre. + +> Escribe los paréntesis en pareja de inmediato. Por ejemplo, escribe `()` y luego rellena la parte interna. La mayoría de los editores de código (incluido el nuestro) añaden automáticamente el paréntesis de cierre en cuanto escribes el de apertura. + +## Mejorar la legibilidad + +A veces una expresión funciona correctamente, pero se ve confusa. En esos casos, se pueden añadir paréntesis solo por claridad: no cambian el resultado, pero mejoran la legibilidad. + +```javascript +// Antes +console.log(8 / 2 + 5 - -3 / 2); // => 10.5 + +// Después +console.log(((8 / 2) + 5) - (-3 / 2)); // => 10.5 ``` -Recuerda: el código se escribe para las personas, porque son personas las que leerán el código y las máquinas solamente lo ejecutarán. Para las máquinas, el código es correcto o incorrecto, no hay código "más" o "menos" comprensible para ellas. +Los programas los escriben personas, y también los leen personas. A la computadora no le importa lo comprensible que sea el código: solo necesita que sea sintácticamente correcto. Para una persona, un código claro y ordenado es la clave de la comodidad, especialmente cuando se trabaja en equipo o se depuran errores. diff --git a/modules/20-arithmetics/40-priority/es/data.yml b/modules/20-arithmetics/40-priority/es/data.yml index 7069362e..af1b2b5b 100644 --- a/modules/20-arithmetics/40-priority/es/data.yml +++ b/modules/20-arithmetics/40-priority/es/data.yml @@ -1,7 +1,7 @@ --- name: Prioridad de las operaciones tips: - - > + - | [Prioridad de los operadores](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) definitions: diff --git a/modules/20-arithmetics/50-float/description.es.yml b/modules/20-arithmetics/50-float/description.es.yml index 597f8816..fc76e808 100644 --- a/modules/20-arithmetics/50-float/description.es.yml +++ b/modules/20-arithmetics/50-float/description.es.yml @@ -1,41 +1,68 @@ --- name: Números de punto flotante - theory: | - JavaScript no hace distinción entre números racionales (0.5) y números naturales (10); para él ambos son números (en otros lenguajes esto no es así). Gracias a esto, se pueden utilizar juntos en cualquier operación: + En matemáticas existen distintos tipos de números. Por ejemplo: + + - Naturales: números enteros positivos: 1, 2, 3, etc. + - Racionales: números fraccionarios que se pueden representar como una división, por ejemplo: 0.5, 1.75, 3.14. + + Desde el punto de vista de las matemáticas todo es sencillo. Pero desde el punto de vista de la computadora, entre estos tipos de números hay un verdadero abismo. Intenta resolver mentalmente: ¿cuánto es `0.2` + `0.1`? Obviamente, `0.3`. Pero esto es lo que dirá JavaScript: ```javascript - 3 * 0.5; // 1.5 + console.log(0.2 + 0.1); // => 0.30000000000000004 ``` - Pero por más que nos lo oculten, los números racionales, debido a sus características, están estructurados de manera diferente. A nosotros, como programadores aplicados, esto no sería especialmente importante si no fuera por un detalle. Mira este ejemplo: + En lugar del habitual 0.3 obtenemos 0.30000000000000004. - ```javascript - // Prueba este código en la consola del navegador - 0.2 * 0.2 // 0.04000000000000001 + ```text + Expectativa: 0.1 + 0.2 → 0.3 + Realidad: 0.1 + 0.2 → 0.30000000000000004 + └── error de almacenamiento ``` - La operación de multiplicación de dos números racionales resultó en un cálculo inexacto del resultado. Otros lenguajes de programación también darán el mismo resultado. Este comportamiento se debe a las limitaciones de la capacidad de cálculo. El tamaño de la memoria, a diferencia de los números, es finito (una cantidad infinita de números requiere una cantidad infinita de memoria para su almacenamiento). Y si con los números naturales este problema se resuelve con un límite superior simple (hay un número máximo que se puede ingresar), con los números racionales no se puede hacer ese truco. + ## ¿Por qué ocurre esto? + + Este comportamiento es propio de JavaScript, Python, C++ y la mayoría de los demás lenguajes de programación. + + La razón está en cómo está construida la computadora. La computadora trabaja con una memoria limitada, mientras que los números racionales son infinitamente precisos. Entre 0.1 y 0.2 se pueden colocar infinitos números más. Pero la computadora no puede almacenar el infinito. Aproxima el número, intentando ajustarlo a la cantidad de bits disponibles. + + Estos valores aproximados se llaman números de punto flotante (floating point numbers). Su almacenamiento y los cálculos con ellos siguen reglas estrictas descritas en un estándar especial, IEEE 754, en el que se basan la mayoría de los lenguajes de programación. + + ## Cuándo aparecen estos números + + Los números de punto flotante aparecen en los programas con más frecuencia de lo que podría parecer. Estos son los casos principales: + + - Cuando escribes explícitamente un número fraccionario, por ejemplo 0.1, 2.5, 3.14. + - Cuando realizas una división, incluso si divides dos números enteros: ```javascript - // El número entero máximo posible - console.log(Number.MAX_SAFE_INTEGER); - 9007199254740991 + console.log(1 / 2); // => 0.5 + console.log(2 / 3); // => 0.6666666666666666 ``` - Los números racionales no están dispuestos en una cadena continua, entre _0.1_ y _0.2_ hay un conjunto infinito de números. Por lo tanto, surge un problema serio, ¿cómo almacenar números racionales? Esta es una pregunta interesante en sí misma. En Internet hay muchos artículos dedicados a la organización de la memoria en estos casos. Además, existe un estándar que describe cómo hacerlo correctamente, y la gran mayoría de los lenguajes se basan en él. + Aunque el resultado parezca «bonito», internamente sigue estando representado como un valor aproximado. Algunas fracciones, como 1 / 3, no se pueden representar de forma exacta en el sistema binario, por lo que su precisión siempre es limitada. + + ## Dónde esto es crítico y cómo se trabaja con ello + + Por lo general, un pequeño error no molesta. Pero en los cálculos financieros, en las tareas científicas y de ingeniería, así como al comparar resultados con precisión, puede convertirse en un problema. Por ejemplo, un error de una fracción de centavo puede dar una suma final incorrecta, y una larga cadena de cálculos puede acumular inexactitud poco a poco. - Para nosotros, como desarrolladores, es importante entender que las operaciones con números de punto flotante no son precisas (se puede ajustar esta precisión), por lo que al resolver problemas relacionados con este tipo de números, es necesario recurrir a trucos especiales que permitan lograr la precisión necesaria. + En los programas reales esto se trata de distintas maneras. El dinero suele almacenarse en las unidades mínimas, por ejemplo en centavos, es decir, se usan números enteros en lugar de fraccionarios. En otros casos el resultado se redondea a la cantidad de dígitos necesaria, se comparan los números con un error admisible o se utilizan bibliotecas especiales para cálculos precisos. + + ## Qué hay que recordar + + Las operaciones con números de punto flotante no siempre son precisas, y esto es normal. Este comportamiento es propio de la mayoría de los lenguajes de programación y se explica por cómo está construida la memoria de la computadora. La precisión se puede controlar, por ejemplo mediante el redondeo o comparando los números con un error dado. Y al trabajar con dinero, mediciones precisas o cálculos científicos, es mejor usar tipos de datos especiales que aseguren el control sobre la precisión. instructions: | - Calcula y muestra en pantalla el producto de dos números: *0.39* y *0.22* + Estás pagando dos productos en una tienda en línea: el primero cuesta 0.1 dólares, el segundo cuesta 0.2 dólares. Calcula y muestra el monto total. + + Esperas ver 0.3, pero JavaScript mostrará algo interesante. tips: - | - [Lo que necesitas saber sobre aritmética de punto flotante](https://habr.com/post/112953/) + [Lo que necesitas saber sobre la aritmética de punto flotante](https://habr.com/post/112953/) definitions: - name: Número racional diff --git a/modules/20-arithmetics/50-float/en/EXERCISE.md b/modules/20-arithmetics/50-float/en/EXERCISE.md index 66d82bca..92a4eca4 100644 --- a/modules/20-arithmetics/50-float/en/EXERCISE.md +++ b/modules/20-arithmetics/50-float/en/EXERCISE.md @@ -1,2 +1,3 @@ +You are paying for two items in an online store: the first costs 0.1 dollars, the second costs 0.2 dollars. Calculate and print the total amount. -Compute and print the product of *0.39* and *0.22*. +You expect to see 0.3 — but JavaScript will produce something interesting. diff --git a/modules/20-arithmetics/50-float/en/README.md b/modules/20-arithmetics/50-float/en/README.md index 17e43844..599ceb12 100644 --- a/modules/20-arithmetics/50-float/en/README.md +++ b/modules/20-arithmetics/50-float/en/README.md @@ -1,25 +1,50 @@ +In mathematics, there are different types of numbers. For example: -JavaScript doesn't distinguish between rational numbers (0.5) and natural numbers (10), both are numbers in JS (though other languages treat them differently). This means they can be used together in any operation: +- Natural: positive whole numbers: 1, 2, 3, and so on. +- Rational: fractional numbers that can be represented as a division, for example: 0.5, 1.75, 3.14. + +From a mathematical point of view, everything is simple. But from a computer's point of view, there is a real gulf between these types of numbers. Try to work out in your head: what is `0.2` + `0.1`? Obviously, `0.3`. But here is what JavaScript will say: ```javascript -3 * 0.5; // 1.5 +console.log(0.2 + 0.1); // => 0.30000000000000004 ``` -However, due to their features, rational numbers are very different. As applied programmers, it wouldn't matter so much if it were not for one detail. Look at this example: +Instead of the familiar 0.3, we get 0.30000000000000004. -```javascript -// Check this code in the [browser console](https://firefox-source-docs.mozilla.org/devtools-user/browser_console/index.html) -0.2 * 0.2 // 0.04000000000000001 +```text +Expectation: 0.1 + 0.2 → 0.3 +Reality: 0.1 + 0.2 → 0.30000000000000004 + └── storage error ``` -Multiplying two rational numbers has suddenly led to an imprecise result. Other programming languages deliver the same result. This happens due to the limits of computing power. The amount of memory, unlike the amount of numbers, is finite (an infinite amount of numbers requires an infinite amount of memory to store). In the case of natural numbers, this issue is solved by a simple upper bound (you can set the maximum number allowed). However, this is not impossible with rational numbers. +## Why does this happen? + +This behavior is typical for JavaScript, Python, C++, and most other programming languages. + +The reason lies in how a computer is built. A computer works with limited memory, whereas rational numbers are infinitely precise. Between 0.1 and 0.2 you can fit infinitely many other numbers. But a computer cannot store infinity. It approximates the number, trying to fit it into the available number of bits. + +Such approximate values are called floating point numbers. Their storage and the calculations with them follow strict rules described in a special standard, IEEE 754, which most programming languages rely on. + +## When such numbers appear + +Floating point numbers appear in programs more often than it might seem. Here are the main cases: + +- When you explicitly write a fractional number, for example 0.1, 2.5, 3.14. +- When you perform division, even if you divide two whole numbers: ```javascript -// Maximum possible integer -console.log(Number.MAX_SAFE_INTEGER); -9007199254740991 +console.log(1 / 2); // => 0.5 +console.log(2 / 3); // => 0.6666666666666666 ``` -Rational numbers are not lined up in a continuous chain like integers, there's an infinite amount of numbers between _0.1_ and _0.2_. So now we have a big problem: how can we store rational numbers? Excellent question. There is a myriad of articles on the internet about memory organization in these cases. Moreover, there is even a standard describing how to do it correctly, and an overwhelming number of languages are based on this set of recommendations. +Even if the result seems "nice," internally it is still represented as an approximate value. Some fractions, such as 1 / 3, cannot be represented exactly in the binary system at all, so their precision is always limited. + +## Where this is critical and how it is handled + +Usually a small error does not get in the way. But in financial calculations, scientific and engineering tasks, as well as when comparing results precisely, it can become a problem. For example, an error of a fraction of a cent can produce an incorrect final amount, and a long chain of calculations can gradually accumulate inaccuracy. + +In real programs this is handled in different ways. Money is often stored in the smallest units, for example in cents, that is, whole numbers are used instead of fractional ones. In other cases the result is rounded to the required number of digits, numbers are compared with an acceptable error, or special libraries for precise calculations are used. + +## What you need to remember -As developers, it's important to understand that operations with floating numbers are not precise (though precision can be adjusted using special tricks). +Operations with floating point numbers are not always precise, and that is normal. This behavior is typical for most programming languages and is explained by the way computer memory is built. Precision can be controlled, for example by rounding or by comparing numbers with a given error. And when working with money, precise measurements, or scientific calculations, it is better to use special data types that provide control over precision. diff --git a/modules/20-arithmetics/50-float/en/data.yml b/modules/20-arithmetics/50-float/en/data.yml index c335a718..ccfc7eba 100644 --- a/modules/20-arithmetics/50-float/en/data.yml +++ b/modules/20-arithmetics/50-float/en/data.yml @@ -1,2 +1,9 @@ --- -name: Floating-point numbers +name: Floating point numbers +tips: + - | + [What you need to know about floating point arithmetic](https://habr.com/post/112953/) +definitions: + - name: Rational number + description: | + a number that can be represented as a common fraction. diff --git a/modules/20-arithmetics/50-float/es/EXERCISE.md b/modules/20-arithmetics/50-float/es/EXERCISE.md index 19d36083..7305bf11 100644 --- a/modules/20-arithmetics/50-float/es/EXERCISE.md +++ b/modules/20-arithmetics/50-float/es/EXERCISE.md @@ -1,2 +1,3 @@ +Estás pagando dos productos en una tienda en línea: el primero cuesta 0.1 dólares, el segundo cuesta 0.2 dólares. Calcula y muestra el monto total. -Calcula y muestra en pantalla el producto de dos números: *0.39* y *0.22* +Esperas ver 0.3, pero JavaScript mostrará algo interesante. diff --git a/modules/20-arithmetics/50-float/es/README.md b/modules/20-arithmetics/50-float/es/README.md index 877bae27..e183396c 100644 --- a/modules/20-arithmetics/50-float/es/README.md +++ b/modules/20-arithmetics/50-float/es/README.md @@ -1,25 +1,50 @@ +En matemáticas existen distintos tipos de números. Por ejemplo: -JavaScript no hace distinción entre números racionales (0.5) y números naturales (10); para él ambos son números (en otros lenguajes esto no es así). Gracias a esto, se pueden utilizar juntos en cualquier operación: +- Naturales: números enteros positivos: 1, 2, 3, etc. +- Racionales: números fraccionarios que se pueden representar como una división, por ejemplo: 0.5, 1.75, 3.14. + +Desde el punto de vista de las matemáticas todo es sencillo. Pero desde el punto de vista de la computadora, entre estos tipos de números hay un verdadero abismo. Intenta resolver mentalmente: ¿cuánto es `0.2` + `0.1`? Obviamente, `0.3`. Pero esto es lo que dirá JavaScript: ```javascript -3 * 0.5; // 1.5 +console.log(0.2 + 0.1); // => 0.30000000000000004 ``` -Pero por más que nos lo oculten, los números racionales, debido a sus características, están estructurados de manera diferente. A nosotros, como programadores aplicados, esto no sería especialmente importante si no fuera por un detalle. Mira este ejemplo: +En lugar del habitual 0.3 obtenemos 0.30000000000000004. -```javascript -// Prueba este código en la consola del navegador -0.2 * 0.2 // 0.04000000000000001 +```text +Expectativa: 0.1 + 0.2 → 0.3 +Realidad: 0.1 + 0.2 → 0.30000000000000004 + └── error de almacenamiento ``` -La operación de multiplicación de dos números racionales resultó en un cálculo inexacto del resultado. Otros lenguajes de programación también darán el mismo resultado. Este comportamiento se debe a las limitaciones de la capacidad de cálculo. El tamaño de la memoria, a diferencia de los números, es finito (una cantidad infinita de números requiere una cantidad infinita de memoria para su almacenamiento). Y si con los números naturales este problema se resuelve con un límite superior simple (hay un número máximo que se puede ingresar), con los números racionales no se puede hacer ese truco. +## ¿Por qué ocurre esto? + +Este comportamiento es propio de JavaScript, Python, C++ y la mayoría de los demás lenguajes de programación. + +La razón está en cómo está construida la computadora. La computadora trabaja con una memoria limitada, mientras que los números racionales son infinitamente precisos. Entre 0.1 y 0.2 se pueden colocar infinitos números más. Pero la computadora no puede almacenar el infinito. Aproxima el número, intentando ajustarlo a la cantidad de bits disponibles. + +Estos valores aproximados se llaman números de punto flotante (floating point numbers). Su almacenamiento y los cálculos con ellos siguen reglas estrictas descritas en un estándar especial, IEEE 754, en el que se basan la mayoría de los lenguajes de programación. + +## Cuándo aparecen estos números + +Los números de punto flotante aparecen en los programas con más frecuencia de lo que podría parecer. Estos son los casos principales: + +- Cuando escribes explícitamente un número fraccionario, por ejemplo 0.1, 2.5, 3.14. +- Cuando realizas una división, incluso si divides dos números enteros: ```javascript -// El número entero máximo posible -console.log(Number.MAX_SAFE_INTEGER); -9007199254740991 +console.log(1 / 2); // => 0.5 +console.log(2 / 3); // => 0.6666666666666666 ``` -Los números racionales no están dispuestos en una cadena continua, entre _0.1_ y _0.2_ hay un conjunto infinito de números. Por lo tanto, surge un problema serio, ¿cómo almacenar números racionales? Esta es una pregunta interesante en sí misma. En Internet hay muchos artículos dedicados a la organización de la memoria en estos casos. Además, existe un estándar que describe cómo hacerlo correctamente, y la gran mayoría de los lenguajes se basan en él. +Aunque el resultado parezca «bonito», internamente sigue estando representado como un valor aproximado. Algunas fracciones, como 1 / 3, no se pueden representar de forma exacta en el sistema binario, por lo que su precisión siempre es limitada. + +## Dónde esto es crítico y cómo se trabaja con ello + +Por lo general, un pequeño error no molesta. Pero en los cálculos financieros, en las tareas científicas y de ingeniería, así como al comparar resultados con precisión, puede convertirse en un problema. Por ejemplo, un error de una fracción de centavo puede dar una suma final incorrecta, y una larga cadena de cálculos puede acumular inexactitud poco a poco. + +En los programas reales esto se trata de distintas maneras. El dinero suele almacenarse en las unidades mínimas, por ejemplo en centavos, es decir, se usan números enteros en lugar de fraccionarios. En otros casos el resultado se redondea a la cantidad de dígitos necesaria, se comparan los números con un error admisible o se utilizan bibliotecas especiales para cálculos precisos. + +## Qué hay que recordar -Para nosotros, como desarrolladores, es importante entender que las operaciones con números de punto flotante no son precisas (se puede ajustar esta precisión), por lo que al resolver problemas relacionados con este tipo de números, es necesario recurrir a trucos especiales que permitan lograr la precisión necesaria. +Las operaciones con números de punto flotante no siempre son precisas, y esto es normal. Este comportamiento es propio de la mayoría de los lenguajes de programación y se explica por cómo está construida la memoria de la computadora. La precisión se puede controlar, por ejemplo mediante el redondeo o comparando los números con un error dado. Y al trabajar con dinero, mediciones precisas o cálculos científicos, es mejor usar tipos de datos especiales que aseguren el control sobre la precisión. diff --git a/modules/20-arithmetics/50-float/es/data.yml b/modules/20-arithmetics/50-float/es/data.yml index cd93e37e..084d38b1 100644 --- a/modules/20-arithmetics/50-float/es/data.yml +++ b/modules/20-arithmetics/50-float/es/data.yml @@ -1,9 +1,8 @@ --- name: Números de punto flotante tips: - - > - [Lo que necesitas saber sobre aritmética de punto - flotante](https://habr.com/post/112953/) + - | + [Lo que necesitas saber sobre la aritmética de punto flotante](https://habr.com/post/112953/) definitions: - name: Número racional description: | diff --git a/modules/20-arithmetics/80-linting/description.es.yml b/modules/20-arithmetics/80-linting/description.es.yml index e703de9f..bbfc0e77 100644 --- a/modules/20-arithmetics/80-linting/description.es.yml +++ b/modules/20-arithmetics/80-linting/description.es.yml @@ -2,49 +2,79 @@ name: Linter theory: | - Ahora que ya hemos aprendido a escribir programas simples, podemos hablar un poco sobre cómo hacer esta tarea. - El código del programa debe ser formateado de una manera específica para que sea lo suficientemente comprensible y fácil de mantener. Los conjuntos de reglas especiales, llamados estándares, describen varios aspectos de la escritura de código. En JavaScript, el estándar más común es el estándar de [AirBnb](https://github.com/airbnb/javascript). + Cuando distintos desarrolladores escriben código en estilos diferentes, el código se vuelve difícil de leer: aquí sobra un espacio, allí la indentación es distinta. Para evitar estos desacuerdos, los programadores acordaron seguir un único estilo de codificación. Este conjunto de reglas describe cómo debe verse el código: la colocación de espacios, el formato de las funciones y los nombres de las variables. - En cualquier lenguaje de programación, existen utilidades llamadas **linters**. Estas verifican el código para asegurarse de que cumpla con los estándares. En JavaScript, esto se hace con [eslint](https://eslint.org/). + Un estilo único significa un código igualmente comprensible para todos los miembros del equipo, sin importar quién lo haya escrito. Esto ahorra tiempo, reduce la cantidad de errores y facilita el trabajo en conjunto. - Echa un vistazo al ejemplo del tema anterior: + ## Estándares de codificación - ```javascript - console.log(8/2+5 - -3 / 2); // => 10.5 - ``` + En el ecosistema de JavaScript no existe un único estándar oficial, pero sí hay guías ampliamente aceptadas, por ejemplo la de [AirBnb](https://github.com/airbnb/javascript). Describen en detalle cómo formatear el código: qué indentación usar, cómo colocar los espacios, qué longitud deben tener las líneas, cómo nombrar las variables y mucho más. + + Estas reglas son conocidas y utilizadas por los desarrolladores de JavaScript. A los principiantes les resulta útil consultarlas de vez en cuando y desarrollar buenos hábitos desde el principio. Sin embargo, no es necesario memorizarlo todo de golpe. + + ## Linters: verificación automática del código - El linter mostrará errores relacionados con la violación de varias reglas: + No es necesario memorizar todas las reglas a mano. Existen programas especiales que lo hacen por ti. Se llaman linters. - * [space-infix-ops](https://eslint.org/docs/rules/space-infix-ops) – Falta de espacios entre el operador y los operandos. - * [no-mixed-operators](https://eslint.org/docs/rules/no-mixed-operators) – Según el estándar, no se puede escribir código en el que diferentes operaciones se utilicen en una misma expresión sin separación explícita mediante paréntesis. + Un linter es una herramienta que analiza tu código e informa sobre las violaciones de los estándares. Te ayuda a: - En la lección anterior, reconocimos que esta abundancia de números y símbolos puede ser confusa, por lo que decidimos agregar paréntesis solamente para facilitar la lectura: + - Eliminar los espacios sobrantes + - Mantener una indentación consistente + - Escribir expresiones legibles y limpias + + ## Un linter moderno: Biome + + Hoy en día, uno de los linters más rápidos y populares para JavaScript es [Biome](https://biomejs.dev/). Combina un linter y un formateador en una sola herramienta, funciona rápido y se desarrolla activamente. + + Veamos un ejemplo: ```javascript - console.log(((8 / 2) + 5) - (-3 / 2)); // => 10.5 + const result = 1+ 3; ``` - Esta versión no viola las reglas y el linter no mostrará errores. + Este código se ve descuidado, y el linter señalará con razón el error. Así se ve el proceso de verificación: - En el ejercicio de la lección anterior, probablemente obtuviste algo como esto: + ```text + Código Linter Resultado + ┌──────────────┐ ┌──────────┐ ┌─────────────────────────┐ + │ const result │ → │ Biome │ → │ lint/style/noShoutyConst│ + │ = 1+ 3 │ │ │ │ missing whitespace │ + └──────────────┘ └──────────┘ └─────────────────────────┘ + ``` + + Esto significa que faltan espacios antes y después de `+`. Según el estándar, debería verse así: ```javascript - console.log(70 * (3 + 4) / (8 + 2)); + const result = 1 + 3; ``` - ¿Hay alguna violación del estándar aquí? + ## Las reglas y su significado + + Cada mensaje del linter está vinculado a una regla concreta. Por ejemplo, algunas reglas se refieren a los espacios alrededor de los operadores, otras a las líneas en blanco entre bloques de código y otras a la longitud de las líneas. Cuando recién empiezas, estos detalles pueden parecer poco importantes. Pero con el tiempo queda claro que son justamente ellos los que forman un estilo único y legible. - Desafortunadamente, sí. En este caso, las operaciones `*` y `/` están en la misma expresión sin separación mediante paréntesis. Puedes resolver este problema agregando paréntesis adicionales. Sin embargo, en algún momento, la cantidad de paréntesis puede ser tan grande que el código se vuelva incómodo e incomprensible nuevamente. En ese momento, será más razonable dividir la expresión en partes separadas. Aprenderemos a hacer esto en las próximas lecciones. + Puedes consultar la lista completa de reglas de Biome en la [documentación oficial](https://biomejs.dev/linter/rules/). - [no-mixed-operators](https://eslint.org/docs/rules/no-mixed-operators) es solamente una de muchas reglas. Otras reglas describen la indentación, los nombres de las entidades creadas, los paréntesis, las operaciones matemáticas, la longitud de las cadenas y muchos otros aspectos. Cada regla individual puede parecer pequeña e insignificante, pero juntas forman la base de un buen código. + ## Uso del linter en tus propios proyectos - Actualmente, el sitio no verificará tu código con el linter, pero en tus futuras prácticas en [Hexlet](https://ru.hexlet.io) y en el desarrollo real, el linter funcionará y te informará sobre las violaciones. + Cuando empieces a escribir tus propios proyectos fuera de la plataforma de aprendizaje, el linter será un ayudante indispensable. Se puede configurar en cualquier editor de código, ejecutar en la terminal o integrar en la compilación del proyecto. El linter muestra los errores y sabe corregirlos automáticamente. instructions: | - Muestra en pantalla el resultado de la siguiente operación: "la diferencia entre el cuadrado de cinco y el producto de tres y siete". Coloca los paréntesis de manera que no se viole la regla `no-mixed-operators`. + Recibiste código de un colega: funciona correctamente, pero viola el estándar de formato. Corrige los espacios alrededor de los operadores sin cambiar la lógica: + + ```javascript + console.log( (5 **2)-(3* 7)); + ``` + + El resultado debe seguir siendo `4`. tips: - | - [eslint](https://eslint.org/) + [Biome — un linter y formateador para JavaScript](https://biomejs.dev/) + +definitions: + - name: Linter + description: >- + una herramienta que analiza el código e informa sobre las violaciones + de los estándares de formato. diff --git a/modules/20-arithmetics/80-linting/en/EXERCISE.md b/modules/20-arithmetics/80-linting/en/EXERCISE.md index 1e180211..bbf79c61 100644 --- a/modules/20-arithmetics/80-linting/en/EXERCISE.md +++ b/modules/20-arithmetics/80-linting/en/EXERCISE.md @@ -1,2 +1,7 @@ +You received some code from a colleague — it works correctly, but it violates the formatting standard. Fix the spaces around the operators without changing the logic: -Print the result of "the difference between five squared and the product of three and seven". Place the parentheses to follow the `no-mixed-operators` rule. +```javascript +console.log( (5 **2)-(3* 7)); +``` + +The result must stay `4`. diff --git a/modules/20-arithmetics/80-linting/en/README.md b/modules/20-arithmetics/80-linting/en/README.md index 3c727923..f7f6ef95 100644 --- a/modules/20-arithmetics/80-linting/en/README.md +++ b/modules/20-arithmetics/80-linting/en/README.md @@ -1,38 +1,55 @@ -Since we've learned to write simple programs, let's talk about the very process of writing. +When different developers write code in different styles, the code becomes hard to read: an extra space here, different indentation there. To avoid such disagreements, programmers agreed to follow a single coding style. This set of rules describes how code should look: spacing, how functions are formatted, and variable naming. -The program code should be organized in a certain way so that it is sufficiently clear and easy to maintain. Special sets of rules - standards - describe different aspects of code writing. The most common standard in JavaScript is [Airbnb](https://github.com/airbnb/javascript). +A single style means code that is equally clear to all team members, regardless of who wrote it. This saves time, reduces the number of errors, and makes collaboration easier. -In any programming language, there are utilities known as **linters**. They ensure the code meets the standards. For example, [ESLint](https://eslint.org/) analyzes JavaScript code. +## Coding standards -Take a look at the example from the previous lesson: +The JavaScript ecosystem has no single official standard, but there are widely adopted guides, for example the one from [AirBnb](https://github.com/airbnb/javascript). They describe in detail how to format code: which indentation to use, how to place spaces, how long lines should be, how to name variables, and much more. -```javascript -console.log(8/2+5 - -3 / 2); // => 10.5 -``` +These rules are known and used by JavaScript developers. It is useful for beginners to look into them from time to time and develop good habits from the very start. However, there is no need to memorize everything at once. + +## Linters: automatic code checking + +There is no need to memorize all the rules by hand. There are special programs that do this for you. They are called linters. + +A linter is a tool that analyzes your code and reports violations of standards. It helps you: -Linter won't be happy about it, because several rules have been violated: +- Get rid of extra spaces +- Keep consistent indentation +- Write readable and clean expressions - * [space-infix-ops](https://eslint.org/docs/rules/space-infix-ops) – No space between operator and operands - * [no-mixed-operators](https://eslint.org/docs/rules/no-mixed-operators) – You can't write code that contains multiple operations in a single expression with no explicit parentheses separation +## A modern linter: Biome -In the last lesson we recognized that such an abundance of numbers and symbols may be confusing, and we decided to add parentheses purely for the sake of readability: +Today, one of the fastest and most popular linters for JavaScript is [Biome](https://biomejs.dev/). It combines a linter and a formatter in a single tool, works fast, and is actively developed. + +Let's look at an example: ```javascript -console.log(((8 / 2) + 5) - (-3 / 2)); // => 10.5 +const result = 1+ 3; ``` -This code does not violate the rules, and the linter will "say nothing" as it were. +This code looks messy, and the linter will rightly point out the error. Here is what the checking process looks like: + +```text +Code Linter Result +┌──────────────┐ ┌──────────┐ ┌─────────────────────────┐ +│ const result │ → │ Biome │ → │ lint/style/noShoutyConst│ +│ = 1+ 3 │ │ │ │ missing whitespace │ +└──────────────┘ └──────────┘ └─────────────────────────┘ +``` -In previous exercise you probably did this: +This means there are missing spaces before and after `+`. According to the standard, it should look like this: ```javascript -console.log(70 * (3 + 4) / (8 + 2)); +const result = 1 + 3; ``` -Is there any violation of the standard here? +## Rules and their meaning + +Each linter message is tied to a specific rule. For example, some rules deal with spaces around operators, others with blank lines between code blocks, and still others with line length. When you are just starting out, such small things may seem unimportant. But over time it becomes clear that they are exactly what forms a single readable style. -Unfortunately, yes. This time, the `*` and `/` are in the same expression and there are no parentheses. You can solve this problem by adding additional parentheses. But at some point, too many parentheses can make the code incomprehensible again. At this point, you can divide the expression into separate parts. We will learn how to do this in the following lessons. +You can find the full list of Biome rules in the [official documentation](https://biomejs.dev/linter/rules/). -[no-mixed-operators](https://eslint.org/docs/rules/no-mixed-operators) is just one of many rules. Other ones describe indentations, entity names, parentheses, mathematical operations, line length, and many other aspects. Each rule may seem small and insignificant, but together they form the basis of good code. +## Using a linter in your own projects -Code-Basics won't test your code with a linter now, but in your future Hexlet practice segments and in actual development, the linter will work and flag the bugs. +Once you start writing your own projects beyond the learning platform, a linter will be an indispensable helper. It can be set up in any code editor, run in the terminal, or integrated into the project build. The linter shows errors and can fix them automatically. diff --git a/modules/20-arithmetics/80-linting/en/data.yml b/modules/20-arithmetics/80-linting/en/data.yml index aabf032d..c921d2cc 100644 --- a/modules/20-arithmetics/80-linting/en/data.yml +++ b/modules/20-arithmetics/80-linting/en/data.yml @@ -1,3 +1,10 @@ --- name: Linter -tips: [] +tips: + - | + [Biome — a linter and formatter for JavaScript](https://biomejs.dev/) +definitions: + - name: Linter + description: >- + a tool that analyzes code and reports violations of formatting + standards. diff --git a/modules/20-arithmetics/80-linting/es/EXERCISE.md b/modules/20-arithmetics/80-linting/es/EXERCISE.md index 25f19cc8..0212494d 100644 --- a/modules/20-arithmetics/80-linting/es/EXERCISE.md +++ b/modules/20-arithmetics/80-linting/es/EXERCISE.md @@ -1,2 +1,7 @@ +Recibiste código de un colega: funciona correctamente, pero viola el estándar de formato. Corrige los espacios alrededor de los operadores sin cambiar la lógica: -Muestra en pantalla el resultado de la siguiente operación: "la diferencia entre el cuadrado de cinco y el producto de tres y siete". Coloca los paréntesis de manera que no se viole la regla `no-mixed-operators`. +```javascript +console.log( (5 **2)-(3* 7)); +``` + +El resultado debe seguir siendo `4`. diff --git a/modules/20-arithmetics/80-linting/es/README.md b/modules/20-arithmetics/80-linting/es/README.md index 31764e7e..7925b385 100644 --- a/modules/20-arithmetics/80-linting/es/README.md +++ b/modules/20-arithmetics/80-linting/es/README.md @@ -1,38 +1,55 @@ -Ahora que ya hemos aprendido a escribir programas simples, podemos hablar un poco sobre cómo hacer esta tarea. +Cuando distintos desarrolladores escriben código en estilos diferentes, el código se vuelve difícil de leer: aquí sobra un espacio, allí la indentación es distinta. Para evitar estos desacuerdos, los programadores acordaron seguir un único estilo de codificación. Este conjunto de reglas describe cómo debe verse el código: la colocación de espacios, el formato de las funciones y los nombres de las variables. -El código del programa debe ser formateado de una manera específica para que sea lo suficientemente comprensible y fácil de mantener. Los conjuntos de reglas especiales, llamados estándares, describen varios aspectos de la escritura de código. En JavaScript, el estándar más común es el estándar de [AirBnb](https://github.com/airbnb/javascript). +Un estilo único significa un código igualmente comprensible para todos los miembros del equipo, sin importar quién lo haya escrito. Esto ahorra tiempo, reduce la cantidad de errores y facilita el trabajo en conjunto. -En cualquier lenguaje de programación, existen utilidades llamadas **linters**. Estas verifican el código para asegurarse de que cumpla con los estándares. En JavaScript, esto se hace con [eslint](https://eslint.org/). +## Estándares de codificación -Echa un vistazo al ejemplo del tema anterior: +En el ecosistema de JavaScript no existe un único estándar oficial, pero sí hay guías ampliamente aceptadas, por ejemplo la de [AirBnb](https://github.com/airbnb/javascript). Describen en detalle cómo formatear el código: qué indentación usar, cómo colocar los espacios, qué longitud deben tener las líneas, cómo nombrar las variables y mucho más. -```javascript -console.log(8/2+5 - -3 / 2); // => 10.5 -``` +Estas reglas son conocidas y utilizadas por los desarrolladores de JavaScript. A los principiantes les resulta útil consultarlas de vez en cuando y desarrollar buenos hábitos desde el principio. Sin embargo, no es necesario memorizarlo todo de golpe. + +## Linters: verificación automática del código + +No es necesario memorizar todas las reglas a mano. Existen programas especiales que lo hacen por ti. Se llaman linters. + +Un linter es una herramienta que analiza tu código e informa sobre las violaciones de los estándares. Te ayuda a: -El linter mostrará errores relacionados con la violación de varias reglas: +- Eliminar los espacios sobrantes +- Mantener una indentación consistente +- Escribir expresiones legibles y limpias - * [space-infix-ops](https://eslint.org/docs/rules/space-infix-ops) – Falta de espacios entre el operador y los operandos. - * [no-mixed-operators](https://eslint.org/docs/rules/no-mixed-operators) – Según el estándar, no se puede escribir código en el que diferentes operaciones se utilicen en una misma expresión sin separación explícita mediante paréntesis. +## Un linter moderno: Biome -En la lección anterior, reconocimos que esta abundancia de números y símbolos puede ser confusa, por lo que decidimos agregar paréntesis solamente para facilitar la lectura: +Hoy en día, uno de los linters más rápidos y populares para JavaScript es [Biome](https://biomejs.dev/). Combina un linter y un formateador en una sola herramienta, funciona rápido y se desarrolla activamente. + +Veamos un ejemplo: ```javascript -console.log(((8 / 2) + 5) - (-3 / 2)); // => 10.5 +const result = 1+ 3; ``` -Esta versión no viola las reglas y el linter no mostrará errores. +Este código se ve descuidado, y el linter señalará con razón el error. Así se ve el proceso de verificación: + +```text +Código Linter Resultado +┌──────────────┐ ┌──────────┐ ┌─────────────────────────┐ +│ const result │ → │ Biome │ → │ lint/style/noShoutyConst│ +│ = 1+ 3 │ │ │ │ missing whitespace │ +└──────────────┘ └──────────┘ └─────────────────────────┘ +``` -En el ejercicio de la lección anterior, probablemente obtuviste algo como esto: +Esto significa que faltan espacios antes y después de `+`. Según el estándar, debería verse así: ```javascript -console.log(70 * (3 + 4) / (8 + 2)); +const result = 1 + 3; ``` -¿Hay alguna violación del estándar aquí? +## Las reglas y su significado + +Cada mensaje del linter está vinculado a una regla concreta. Por ejemplo, algunas reglas se refieren a los espacios alrededor de los operadores, otras a las líneas en blanco entre bloques de código y otras a la longitud de las líneas. Cuando recién empiezas, estos detalles pueden parecer poco importantes. Pero con el tiempo queda claro que son justamente ellos los que forman un estilo único y legible. -Desafortunadamente, sí. En este caso, las operaciones `*` y `/` están en la misma expresión sin separación mediante paréntesis. Puedes resolver este problema agregando paréntesis adicionales. Sin embargo, en algún momento, la cantidad de paréntesis puede ser tan grande que el código se vuelva incómodo e incomprensible nuevamente. En ese momento, será más razonable dividir la expresión en partes separadas. Aprenderemos a hacer esto en las próximas lecciones. +Puedes consultar la lista completa de reglas de Biome en la [documentación oficial](https://biomejs.dev/linter/rules/). -[no-mixed-operators](https://eslint.org/docs/rules/no-mixed-operators) es solamente una de muchas reglas. Otras reglas describen la indentación, los nombres de las entidades creadas, los paréntesis, las operaciones matemáticas, la longitud de las cadenas y muchos otros aspectos. Cada regla individual puede parecer pequeña e insignificante, pero juntas forman la base de un buen código. +## Uso del linter en tus propios proyectos -Actualmente, el sitio no verificará tu código con el linter, pero en tus futuras prácticas en [Hexlet](https://ru.hexlet.io) y en el desarrollo real, el linter funcionará y te informará sobre las violaciones. +Cuando empieces a escribir tus propios proyectos fuera de la plataforma de aprendizaje, el linter será un ayudante indispensable. Se puede configurar en cualquier editor de código, ejecutar en la terminal o integrar en la compilación del proyecto. El linter muestra los errores y sabe corregirlos automáticamente. diff --git a/modules/20-arithmetics/80-linting/es/data.yml b/modules/20-arithmetics/80-linting/es/data.yml index 266a47c2..d0cf6075 100644 --- a/modules/20-arithmetics/80-linting/es/data.yml +++ b/modules/20-arithmetics/80-linting/es/data.yml @@ -2,4 +2,9 @@ name: Linter tips: - | - [eslint](https://eslint.org/) + [Biome — un linter y formateador para JavaScript](https://biomejs.dev/) +definitions: + - name: Linter + description: >- + una herramienta que analiza el código e informa sobre las violaciones + de los estándares de formato. diff --git a/modules/25-strings/10-quotes/description.es.yml b/modules/25-strings/10-quotes/description.es.yml index d8011daa..16e94c74 100644 --- a/modules/25-strings/10-quotes/description.es.yml +++ b/modules/25-strings/10-quotes/description.es.yml @@ -3,107 +3,130 @@ name: Comillas theory: | + En la programación en JavaScript, las cadenas de texto se utilizan con mucha frecuencia y en las situaciones más diversas. Con su ayuda trabajamos con texto, mostramos mensajes en la pantalla, procesamos la entrada del usuario e interactuamos con sistemas externos. + + Desde el punto de vista de JavaScript, una cadena de texto es simplemente un conjunto de caracteres encerrado entre comillas. Veamos algunos ejemplos. + ```javascript - 'Hola' - 'Adiós' + 'Hello' + 'Goodbye' 'G' ' ' '' ``` - ¿Cuáles de estas cinco opciones son cadenas de texto? + Todas estas opciones son cadenas de texto. + + - `'Hello'`, `'Goodbye'` y `'G'` son cadenas de varios caracteres o de un solo carácter. + - `' '` es una cadena que consta de un solo espacio. + - `''` es una cadena vacía; no contiene ningún carácter. Cumple el mismo papel que el 0 en matemáticas. - Con las primeras dos opciones está claro, son definitivamente cadenas de texto, ya hemos trabajado con construcciones similares y hemos dicho que las cadenas de texto son conjuntos de caracteres. + Es decir, todo lo que está dentro de las comillas se considera una cadena de texto, incluso si solo hay un espacio o no hay nada. - Cualquier carácter individual entre comillas es una cadena de texto. Una cadena de texto vacía `''` también es una cadena de texto. Es decir, consideramos como cadena de texto todo lo que está dentro de comillas, incluso si es un espacio, un solo carácter o incluso la ausencia de caracteres. + Si mostramos las cadenas en la pantalla, `'Hello'` y `'Goodbye'` se verán claramente. Pero `' '` y `''` pueden resultar confusas, porque la salida de una cadena vacía parece una ausencia total, mientras que una cadena con un espacio muestra un "espacio vacío" que visualmente es difícil de distinguir. Aun así, JavaScript las distingue claramente. Una cadena vacía significa la ausencia de caracteres, mientras que una cadena con un espacio contiene un carácter de espacio concreto. - Anteriormente, en las lecciones escribimos cadenas de texto entre comillas simples, pero esa no es la única forma. También se pueden usar comillas dobles: + Pregunta de control. ¿Son estas las mismas cadenas o no? ```javascript - // El estándar de codificación de airbnb recomienda - // usar comillas simples siempre que sea posible - console.log("¡Dracarys!"); + 'hexlet' + ' hexlet' ``` - Imagina que quieres imprimir la frase _Dragon's Mother_. El apóstrofe antes de la letra **s** es el mismo carácter que una comilla simple. Intentemos: + ## Terminología. ¿Cadena o línea? - ```javascript - console.log('Dragon's Mother'); - // Uncaught SyntaxError: missing ) after argument list - ``` + En la programación existe una trampa terminológica. - Este programa no funcionará. Desde el punto de vista de JavaScript, la cadena de texto comenzó con una comilla simple y luego terminó después de la letra **n**. Luego hubo caracteres `s mother` sin comillas, lo que significa que no es una cadena de texto. Y luego hubo una comilla de apertura de cadena que nunca se cerró: `');`. Este código es sintácticamente incorrecto (se puede ver incluso por cómo se resalta el código). + - Una cadena (string) es un tipo de datos (el que analizamos arriba), por ejemplo `'hello'`. + - Una línea (line) es una línea de texto en un archivo o en el código. - Aquí es donde las comillas dobles nos ayudan. Esta versión del programa funcionará correctamente: + Por ejemplo, en el código de abajo hay una línea, pero no una cadena. ```javascript - console.log("Dragon's Mother"); + console.log(5); ``` - Ahora el intérprete sabe que la cadena de texto comenzó con una comilla doble, por lo que también debe terminar con una comilla doble. Y la comilla simple dentro se convirtió en parte de la cadena de texto. + Para evitar confusiones, en este curso usaremos las siguientes formulaciones. - Lo contrario también es cierto. Si queremos usar comillas dobles dentro de una cadena de texto, debemos hacer la cadena de texto con comillas simples. Y la cantidad de comillas dentro de la cadena de texto no importa. + - Cadena, cuando hablamos del tipo de datos. + - Línea, cuando se trata de líneas de código. - ¿Y si queremos crear una cadena de texto como esta? + ## Comillas simples y dobles + En JavaScript, las cadenas de texto se pueden escribir tanto entre comillas simples como entre comillas dobles. + + ```javascript + console.log('Hello'); + console.log("Hello"); ``` - Dragon's mother said "No" - ``` - En ella hay tanto comillas simples como comillas dobles. ¿Qué hacer en esta situación? De alguna manera tenemos que decirle al intérprete que cada comilla es parte de la cadena de texto y no el comienzo o el final de la cadena de texto. + Por defecto, se acostumbra usar comillas simples `'` si no se requieren comillas dobles dentro de la cadena. Este estilo lo sigue el popular estándar de formato de código de [AirBnb](https://github.com/airbnb/javascript). + + ## El problema con las comillas dentro de una cadena - Para esto se **escapan** los caracteres especiales. En nuestro caso, el carácter que indica el final y el comienzo de la cadena de texto es una comilla simple o una comilla doble, dependiendo de la situación. Para escapar se utiliza una barra invertida `\`. + Imagina que quieres imprimir la cadena *Dragon's mother*. Contiene un apóstrofe (*'s*) que coincide con el carácter de comilla simple. Intentemos así. ```javascript - // Solo se escapa ", ya que en esta situación - // las comillas dobles tienen un significado especial - console.log("Dragon's mother said \"No\""); - // => Dragon's mother said "No" + console.log('Dragon's mother'); + // Uncaught SyntaxError: missing ) after argument list ``` - Mira atentamente: tuvimos que agregar `\` para las comillas dobles, pero no para la comilla simple (apóstrofe), porque la cadena de texto en sí se creó con comillas dobles. Si la cadena de texto se hubiera creado con comillas simples, entonces se habría necesitado un carácter de escape antes del apóstrofe, pero no antes de las comillas dobles. + JavaScript decidirá que la cadena termina después de la palabra `Dragon`, y no reconocerá el resto como código válido, lo que provocará un error de sintaxis. Para evitar esto, encerremos la cadena entre comillas dobles. ```javascript - // \ no se muestra si después de él hay un carácter normal, - // no un carácter especial - console.log("Death is \so terribly final"); - // => Death is so terribly final + console.log("Dragon's mother"); ``` - ¿Y si queremos imprimir la barra invertida en sí? De la misma manera que cualquier otro carácter especial, debemos escaparlo con el mismo carácter. + Ahora JavaScript entiende que la comilla simple dentro de la cadena es un carácter común, y que la cadena en sí empieza y termina con comillas dobles. + + Si necesitas comillas dobles dentro de la cadena y comillas simples fuera, tampoco habrá ningún problema. ```javascript - console.log("\\"); - // => \ + console.log('He said "No"'); ``` - Pregunta de autoevaluación, ¿qué imprimirá este código? + A veces aparecen ambos tipos de comillas en una cadena. - ```javascript - console.log("\\ \\ \\\\ \\\ \'\""); + ``` + Dragon's mother said "No" ``` -
- Respuesta + En este caso, para que JavaScript no confunda las comillas dentro de la cadena con las exteriores, se utiliza el carácter de escape: la barra invertida `\`. Le indica al intérprete que el carácter que la sigue es parte de la cadena y no un carácter de control. - Este código imprimirá la siguiente cadena de texto: `\ \ \\ \ '"`. + ```javascript + console.log("Dragon's mother said \"No\""); + // => Dragon's mother said "No" + ``` -
+ Aquí escapamos las comillas dobles dentro de una cadena encerrada entre comillas dobles. -instructions: | + Ten en cuenta que JavaScript interpreta `\"` como un único carácter de comilla, no como dos caracteres. Lo mismo ocurre con `\'`, `\\`, `\n` y otras secuencias de escape. Se ven como dos caracteres en el código, pero en la cadena cuentan como uno. - Escribe un programa que imprima en la pantalla: + Lo mismo funciona en el caso inverso. + ```javascript + console.log('Dragon\'s mother said "No"'); + // => Dragon's mother said "No" ``` - "La palabra favorita de Khal Drogo es "athjahakar"" + + ## Cómo imprimir una barra invertida + + Para imprimir la barra invertida en sí, también hay que escaparla. + + ```javascript + console.log("\\"); + // => \ ``` - El programa debe imprimir exactamente esa frase. Presta atención a las comillas al principio y al final de la frase: +instructions: | + + El programa no encontró el archivo requerido e imprimió un mensaje con su nombre. Escribe un programa que imprima el mismo mensaje: ```text - "Khal Drogo's favorite word is "athjahakar"" + The file "user's_config.json" was not found. ``` + La cadena contiene tanto un apóstrofe como comillas dobles: elige una forma adecuada de escribirlos. + tips: - | - [Cadenas de plantilla](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/template_strings) + [Cadenas en JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/String) diff --git a/modules/25-strings/10-quotes/en/EXERCISE.md b/modules/25-strings/10-quotes/en/EXERCISE.md index ffbdcd67..5f8e369c 100644 --- a/modules/25-strings/10-quotes/en/EXERCISE.md +++ b/modules/25-strings/10-quotes/en/EXERCISE.md @@ -1,12 +1,7 @@ - -Write a program that prints: - -``` -"Khal Drogo's favorite word is "athjahakar"" -``` - -The program should print the exact phrase. Note the quotes at the beginning and the end of the phrase: +The program could not find the required file and printed a message with its name. Write a program that prints the same message: ```text -"Khal Drogo's favorite word is "athjahakar"" +The file "user's_config.json" was not found. ``` + +The string contains both an apostrophe and double quotes — choose a suitable way to write them. diff --git a/modules/25-strings/10-quotes/en/README.md b/modules/25-strings/10-quotes/en/README.md index c185d1be..d9480d55 100644 --- a/modules/25-strings/10-quotes/en/README.md +++ b/modules/25-strings/10-quotes/en/README.md @@ -1,3 +1,6 @@ +Strings in JavaScript programming are used very often and in a wide variety of situations. With their help, we work with text, display messages on the screen, process user input, and interact with external systems. + +From JavaScript's point of view, a string is simply a set of characters enclosed in quotes. Let's look at some examples. ```javascript 'Hello' @@ -7,77 +10,104 @@ '' ``` -Which of these five items are strings? +All of these options are strings. + +- `'Hello'`, `'Goodbye'`, and `'G'` are strings of several or a single character. +- `' '` is a string consisting of a single space. +- `''` is an empty string; it contains no characters at all. It plays the same role as 0 in mathematics. + +In other words, everything inside the quotes is considered a string, even if there is only a space or nothing at all. + +If you display strings on the screen, `'Hello'` and `'Goodbye'` will be clearly visible. But `' '` and `''` can be confusing, because the output of an empty string looks like complete absence, while a string with a space shows "empty space", which is visually hard to distinguish. At the same time, JavaScript clearly distinguishes between them. An empty string means the absence of characters, whereas a string with a space contains a specific space character. + +A check question. Are these the same strings or not? + +```javascript +'hexlet' +' hexlet' +``` + +## Terminology. String or line? -The first two are clearly strings, we've already worked with similar constructions and mentioned that strings are sets of characters. +There is a terminological trap in programming. -Any single character between parentheses is a string. The empty string `''` is also a string. So everything inside the quotation marks can be considered a string, even if it is a space, one character, or no characters at all. +- A string is a data type (the one discussed above), for example `'hello'`. +- A line is a line of text in a file or in code. -In previous lessons, we enclosed strings in single quotes, but you can also use double quotes: +For example, in the code below there is a line, but not a string. ```javascript -// Coding airbnb standard recommends -// using single quotes where possible +console.log(5); +``` + +To avoid confusion, in this course we will use the following wording. + +- String, when we talk about the data type. +- Line, when we are talking about lines of code. -console.log("Dracarys!"); +## Single and double quotes + +In JavaScript, strings can be written in both single and double quotes. + +```javascript +console.log('Hello'); +console.log("Hello"); ``` -Imagine you want to print a string: _Dragon's mother_. The apostrophe before the letter **s** and a single quote are the same symbols. Let's print it: +By default, it is customary to use single quotes `'` if double quotes are not required inside the string. This style is followed by the popular code style standard from [AirBnb](https://github.com/airbnb/javascript). + +## The problem with quotes inside a string + +Imagine you want to print the string *Dragon's mother*. It contains an apostrophe (*'s*), which matches the single quote character. Let's try this. ```javascript console.log('Dragon's mother'); // Uncaught SyntaxError: missing ) after argument list ``` -This program won't work. For JavaScript, the string begins with a single quote and ends after the letter **n**. Then comes some characters: `s mother` without quotes, which are not a string. And then there is one quote opening a string which is never closed: `');`. This code is syntactically incorrect (you can see it by the way the code is highlighted). - -It's a good idea here is to use double quotes. This version of the program will work correctly: +JavaScript will decide that the string ends after the word `Dragon`, and it will not recognize the rest as valid code, which will cause a syntax error. To avoid this, let's wrap the string in double quotes. ```javascript console.log("Dragon's mother"); ``` -Now the interpreter knows that the string begins with a double quote, so it should end with a double quote too. And the single quote inside has become the part of the string. +Now JavaScript understands that the single quote inside the string is an ordinary character, and the string itself begins and ends with double quotes. -It works the other way too. If you want to use double quotes inside a string, you should enclose the string in single quotes. And the number of quotes in a string doesn't matter. +If you need double quotes inside the string and single quotes outside, there will be no problem either. + +```javascript +console.log('He said "No"'); +``` -Now, what if we want to create a string like this? +Sometimes both types of quotes appear in a string. ``` Dragon's mother said "No" ``` -There are single and double quotes here. What can we do in this case? You need to somehow tell the interpreter to consider each quote as a part of the string, and not as its beginning or an end. - -To do this, you have to use **an escape character**. In our case, the character that starts and ends a string is either a single or a double quote, depending on the part of the code. Use a backslash `\` before the character you want to escape. +In this case, to keep JavaScript from confusing the quotes inside the string with the outer ones, an escape character is used — the backslash `\`. It tells the interpreter that the character following it is part of the string, not a control character. ```javascript -// Only " is escaped, because in this code -// double quotes have a special meaning - console.log("Dragon's mother said \"No\""); // => Dragon's mother said "No" ``` -Look closely: we had to use `\` for double quotes to escape them, and not for the single quote (apostrophe) because the string is written in double quotes. If the string were written in single quotes, the escape character would be used before the apostrophe, not before double quotes. - -```javascript -// \ won't be printed if it is followed by a normal character, -// not a special one +Here we escape the double quotes inside a string enclosed in double quotes. -console.log("Death is \so terribly final"); -// => Death is so terribly final -``` +Note that JavaScript treats `\"` as a single quote character, not two characters. The same applies to `\'`, `\\`, `\n`, and other escape sequences. They look like two characters in the code, but in the string they count as one. -But what if you want to print the backslash? Just like any other special symbol, it escapes using a backslash too. +The same works in the opposite case. ```javascript -console.log("\\"); -// => \ +console.log('Dragon\'s mother said "No"'); +// => Dragon's mother said "No" ``` -Self-test: what will be printed? +## How to print a backslash + +To print the backslash itself, it also needs to be escaped. ```javascript -console.log("\\ \\ \\\\ \\\ \'\""); +console.log("\\"); +// => \ ``` diff --git a/modules/25-strings/10-quotes/en/data.yml b/modules/25-strings/10-quotes/en/data.yml index 66fc5e03..27e1643f 100644 --- a/modules/25-strings/10-quotes/en/data.yml +++ b/modules/25-strings/10-quotes/en/data.yml @@ -1,6 +1,5 @@ --- -name: Quotation marks +name: Quotes tips: - - > - [Template - strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) + - | + [Strings in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) diff --git a/modules/25-strings/10-quotes/es/EXERCISE.md b/modules/25-strings/10-quotes/es/EXERCISE.md index 52fc382c..0c1b195e 100644 --- a/modules/25-strings/10-quotes/es/EXERCISE.md +++ b/modules/25-strings/10-quotes/es/EXERCISE.md @@ -1,12 +1,7 @@ - -Escribe un programa que imprima en la pantalla: - -``` -"La palabra favorita de Khal Drogo es "athjahakar"" -``` - -El programa debe imprimir exactamente esa frase. Presta atención a las comillas al principio y al final de la frase: +El programa no encontró el archivo requerido e imprimió un mensaje con su nombre. Escribe un programa que imprima el mismo mensaje: ```text -"Khal Drogo's favorite word is "athjahakar"" +The file "user's_config.json" was not found. ``` + +La cadena contiene tanto un apóstrofe como comillas dobles: elige una forma adecuada de escribirlos. diff --git a/modules/25-strings/10-quotes/es/README.md b/modules/25-strings/10-quotes/es/README.md index ebc981eb..c59e760b 100644 --- a/modules/25-strings/10-quotes/es/README.md +++ b/modules/25-strings/10-quotes/es/README.md @@ -1,87 +1,113 @@ +En la programación en JavaScript, las cadenas de texto se utilizan con mucha frecuencia y en las situaciones más diversas. Con su ayuda trabajamos con texto, mostramos mensajes en la pantalla, procesamos la entrada del usuario e interactuamos con sistemas externos. + +Desde el punto de vista de JavaScript, una cadena de texto es simplemente un conjunto de caracteres encerrado entre comillas. Veamos algunos ejemplos. ```javascript -'Hola' -'Adiós' +'Hello' +'Goodbye' 'G' ' ' '' ``` -¿Cuáles de estas cinco opciones son cadenas de texto? +Todas estas opciones son cadenas de texto. + +- `'Hello'`, `'Goodbye'` y `'G'` son cadenas de varios caracteres o de un solo carácter. +- `' '` es una cadena que consta de un solo espacio. +- `''` es una cadena vacía; no contiene ningún carácter. Cumple el mismo papel que el 0 en matemáticas. -Con las primeras dos opciones está claro, son definitivamente cadenas de texto, ya hemos trabajado con construcciones similares y hemos dicho que las cadenas de texto son conjuntos de caracteres. +Es decir, todo lo que está dentro de las comillas se considera una cadena de texto, incluso si solo hay un espacio o no hay nada. -Cualquier carácter individual entre comillas es una cadena de texto. Una cadena de texto vacía `''` también es una cadena de texto. Es decir, consideramos como cadena de texto todo lo que está dentro de comillas, incluso si es un espacio, un solo carácter o incluso la ausencia de caracteres. +Si mostramos las cadenas en la pantalla, `'Hello'` y `'Goodbye'` se verán claramente. Pero `' '` y `''` pueden resultar confusas, porque la salida de una cadena vacía parece una ausencia total, mientras que una cadena con un espacio muestra un "espacio vacío" que visualmente es difícil de distinguir. Aun así, JavaScript las distingue claramente. Una cadena vacía significa la ausencia de caracteres, mientras que una cadena con un espacio contiene un carácter de espacio concreto. -Anteriormente, en las lecciones escribimos cadenas de texto entre comillas simples, pero esa no es la única forma. También se pueden usar comillas dobles: +Pregunta de control. ¿Son estas las mismas cadenas o no? ```javascript -// El estándar de codificación de airbnb recomienda -// usar comillas simples siempre que sea posible -console.log("¡Dracarys!"); +'hexlet' +' hexlet' ``` -Imagina que quieres imprimir la frase _Dragon's Mother_. El apóstrofe antes de la letra **s** es el mismo carácter que una comilla simple. Intentemos: +## Terminología. ¿Cadena o línea? + +En la programación existe una trampa terminológica. + +- Una cadena (string) es un tipo de datos (el que analizamos arriba), por ejemplo `'hello'`. +- Una línea (line) es una línea de texto en un archivo o en el código. + +Por ejemplo, en el código de abajo hay una línea, pero no una cadena. ```javascript -console.log('Dragon's Mother'); -// Uncaught SyntaxError: missing ) after argument list +console.log(5); ``` -Este programa no funcionará. Desde el punto de vista de JavaScript, la cadena de texto comenzó con una comilla simple y luego terminó después de la letra **n**. Luego hubo caracteres `s mother` sin comillas, lo que significa que no es una cadena de texto. Y luego hubo una comilla de apertura de cadena que nunca se cerró: `');`. Este código es sintácticamente incorrecto (se puede ver incluso por cómo se resalta el código). +Para evitar confusiones, en este curso usaremos las siguientes formulaciones. + +- Cadena, cuando hablamos del tipo de datos. +- Línea, cuando se trata de líneas de código. + +## Comillas simples y dobles -Aquí es donde las comillas dobles nos ayudan. Esta versión del programa funcionará correctamente: +En JavaScript, las cadenas de texto se pueden escribir tanto entre comillas simples como entre comillas dobles. ```javascript -console.log("Dragon's Mother"); +console.log('Hello'); +console.log("Hello"); ``` -Ahora el intérprete sabe que la cadena de texto comenzó con una comilla doble, por lo que también debe terminar con una comilla doble. Y la comilla simple dentro se convirtió en parte de la cadena de texto. +Por defecto, se acostumbra usar comillas simples `'` si no se requieren comillas dobles dentro de la cadena. Este estilo lo sigue el popular estándar de formato de código de [AirBnb](https://github.com/airbnb/javascript). -Lo contrario también es cierto. Si queremos usar comillas dobles dentro de una cadena de texto, debemos hacer la cadena de texto con comillas simples. Y la cantidad de comillas dentro de la cadena de texto no importa. +## El problema con las comillas dentro de una cadena -¿Y si queremos crear una cadena de texto como esta? +Imagina que quieres imprimir la cadena *Dragon's mother*. Contiene un apóstrofe (*'s*) que coincide con el carácter de comilla simple. Intentemos así. +```javascript +console.log('Dragon's mother'); +// Uncaught SyntaxError: missing ) after argument list ``` -Dragon's mother said "No" + +JavaScript decidirá que la cadena termina después de la palabra `Dragon`, y no reconocerá el resto como código válido, lo que provocará un error de sintaxis. Para evitar esto, encerremos la cadena entre comillas dobles. + +```javascript +console.log("Dragon's mother"); ``` -En ella hay tanto comillas simples como comillas dobles. ¿Qué hacer en esta situación? De alguna manera tenemos que decirle al intérprete que cada comilla es parte de la cadena de texto y no el comienzo o el final de la cadena de texto. +Ahora JavaScript entiende que la comilla simple dentro de la cadena es un carácter común, y que la cadena en sí empieza y termina con comillas dobles. -Para esto se **escapan** los caracteres especiales. En nuestro caso, el carácter que indica el final y el comienzo de la cadena de texto es una comilla simple o una comilla doble, dependiendo de la situación. Para escapar se utiliza una barra invertida `\`. +Si necesitas comillas dobles dentro de la cadena y comillas simples fuera, tampoco habrá ningún problema. ```javascript -// Solo se escapa ", ya que en esta situación -// las comillas dobles tienen un significado especial -console.log("Dragon's mother said \"No\""); -// => Dragon's mother said "No" +console.log('He said "No"'); ``` -Mira atentamente: tuvimos que agregar `\` para las comillas dobles, pero no para la comilla simple (apóstrofe), porque la cadena de texto en sí se creó con comillas dobles. Si la cadena de texto se hubiera creado con comillas simples, entonces se habría necesitado un carácter de escape antes del apóstrofe, pero no antes de las comillas dobles. +A veces aparecen ambos tipos de comillas en una cadena. -```javascript -// \ no se muestra si después de él hay un carácter normal, -// no un carácter especial -console.log("Death is \so terribly final"); -// => Death is so terribly final +``` +Dragon's mother said "No" ``` -¿Y si queremos imprimir la barra invertida en sí? De la misma manera que cualquier otro carácter especial, debemos escaparlo con el mismo carácter. +En este caso, para que JavaScript no confunda las comillas dentro de la cadena con las exteriores, se utiliza el carácter de escape: la barra invertida `\`. Le indica al intérprete que el carácter que la sigue es parte de la cadena y no un carácter de control. ```javascript -console.log("\\"); -// => \ +console.log("Dragon's mother said \"No\""); +// => Dragon's mother said "No" ``` -Pregunta de autoevaluación, ¿qué imprimirá este código? +Aquí escapamos las comillas dobles dentro de una cadena encerrada entre comillas dobles. + +Ten en cuenta que JavaScript interpreta `\"` como un único carácter de comilla, no como dos caracteres. Lo mismo ocurre con `\'`, `\\`, `\n` y otras secuencias de escape. Se ven como dos caracteres en el código, pero en la cadena cuentan como uno. + +Lo mismo funciona en el caso inverso. ```javascript -console.log("\\ \\ \\\\ \\\ \'\""); +console.log('Dragon\'s mother said "No"'); +// => Dragon's mother said "No" ``` -
-Respuesta +## Cómo imprimir una barra invertida -Este código imprimirá la siguiente cadena de texto: `\ \ \\ \ '"`. +Para imprimir la barra invertida en sí, también hay que escaparla. -
+```javascript +console.log("\\"); +// => \ +``` diff --git a/modules/25-strings/10-quotes/es/data.yml b/modules/25-strings/10-quotes/es/data.yml index fd8161fc..c9e918ca 100644 --- a/modules/25-strings/10-quotes/es/data.yml +++ b/modules/25-strings/10-quotes/es/data.yml @@ -1,6 +1,5 @@ --- name: Comillas tips: - - > - [Cadenas de - plantilla](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/template_strings) + - | + [Cadenas en JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/String) diff --git a/modules/25-strings/15-escape-characters/description.es.yml b/modules/25-strings/15-escape-characters/description.es.yml index 4f6da407..cd1c8791 100644 --- a/modules/25-strings/15-escape-characters/description.es.yml +++ b/modules/25-strings/15-escape-characters/description.es.yml @@ -3,51 +3,38 @@ name: Secuencias de escape theory: | - Queremos mostrar un diálogo entre Daenerys Targaryen y su hijo: + Supongamos que queremos mostrar el texto de abajo en dos líneas. - ``` + ```text - Are you hungry? - Aaaarrrgh! ``` - Si imprimimos en la pantalla una cadena de texto con este contenido: - - ```javascript - console.log('- Are you hungry?- ¡Aaaarrrgh!'); - ``` - - obtendremos esto: + Si simplemente pasamos este texto a `console.log()`, JavaScript imprimirá todo en una sola línea. Técnicamente, podríamos escribir dos llamadas consecutivas a `console.log()`, pero imaginemos que queremos hacerlo con una sola. ```javascript console.log('- Are you hungry?- Aaaarrrgh!'); + // => - Are you hungry?- Aaaarrrgh! ``` - No es lo que queríamos. Las líneas están una al lado de la otra en lugar de estar una debajo de la otra. Necesitamos decirle al intérprete "presiona Enter" - haz un salto de línea después del signo de interrogación. Esto se puede hacer utilizando el carácter de salto de línea: `\n`. + Para que cada una de ellas empiece en una nueva línea, necesitamos agregar un salto de línea, es decir, "presionar Enter". En programación, esto se hace agregando caracteres especiales, en este caso `\n`. Sí, no es un error de escritura. A pesar de que aquí vemos dos caracteres, desde el punto de vista de JavaScript es un solo carácter. ```javascript console.log('- Are you hungry?\n- Aaaarrrgh!'); ``` - resultado: + El resultado será el siguiente. - ``` + ```text - Are you hungry? - Aaaarrrgh! ``` - `\n` es un carácter especial. En literatura a menudo se le llama *LF* (Line Feed). Es posible que ahora estés pensando que es un error de escritura, ya que aquí vemos dos caracteres `\` y `n`, pero no es así. Desde el punto de vista de la computadora, es un solo carácter de salto de línea invisible. Prueba de ello: - - ```javascript - // No hemos estudiado esto, pero debes saber la verdad - // A continuación hay un código que devuelve la longitud de una cadena - 'a'.length; // 1 - '\n'.length; // 1 !!! - '\n\n'.length; // 2 !!! - ``` + ## ¿Qué es `\n`? - ¿Por qué se hizo así? `\n` es simplemente una forma de escribir el carácter de salto de línea, pero el salto de línea en sí es un solo carácter, aunque invisible. Es por eso que surgió esta tarea. Necesitábamos encontrar una forma de representarlo en el teclado. Y dado que la cantidad de caracteres en el teclado es limitada y se reserva para los más importantes, todos los caracteres especiales se implementan como tales representaciones. + `\n` es una secuencia de escape (en inglés, escape sequence; a veces se le llama "secuencia escapada"). Denota un salto de línea, pero no se muestra directamente. No verás `\n` en la salida del programa, ya que solo afecta a la disposición del texto. - El carácter de salto de línea no es algo específico de la programación. Todos los que han escrito en una computadora han utilizado el salto de línea al presionar Enter. En muchos editores hay una opción que permite mostrar los caracteres invisibles, lo que permite ver dónde se encuentran (aunque esto es solamente una representación esquemática, estos caracteres no tienen una representación gráfica; son invisibles): + En los editores de texto, al presionar Enter se agrega un carácter invisible LF (Line Feed). Eso es precisamente lo que significa `\n`. A veces estos caracteres se pueden ver si activas la visualización de los caracteres especiales. ```text - ¡Hola!¶ @@ -55,97 +42,101 @@ theory: | - ¿Cómo estás? ``` - El dispositivo que muestra el texto correspondiente tiene en cuenta este carácter. Por ejemplo, una impresora, al encontrar un LF, avanza el papel hacia arriba una línea, y un editor de texto mueve todo el texto siguiente hacia abajo, también una línea. - - `\n` es un ejemplo de una **secuencia de escape** (escape sequence). También se les llama construcciones de control. Aunque hay más de una docena de estos caracteres, en programación a menudo solamente se encuentran unos pocos. Además del salto de línea, estos caracteres incluyen la tabulación (espacio que se obtiene al presionar la tecla Tab) y el retorno de carro (solo en Windows). A menudo, los programadores necesitamos usar el salto de línea `\n` para formatear correctamente el texto. + Las impresoras, los editores y los intérpretes de JavaScript entienden `\n` como una orden de empezar el texto en una nueva línea. - ```javascript - console.log('Gregor Clegane\nDunsen\nPolliver\nChiswyck'); - ``` + ## Ejemplos de uso de `\n` - Se mostrará en la pantalla: + Así es como JavaScript procesa la secuencia de escape `\n`. - ``` - Gregor Clegane - Dunsen - Polliver - Chiswyck + ```text + En el código 'Hello\nWorld' + ↓ + En pantalla Hello + World ``` - Ten en cuenta los siguientes puntos: + La posición de `\n` cambia la salida final. - 1. No importa lo que haya antes o después de `\n`: un carácter o una cadena vacía. El salto de línea se detectará y se realizará de todos modos. - - 2. Recuerda que una cadena puede contener un solo carácter o incluso cero caracteres. Y también una cadena puede contener solo `\n`. Analiza el siguiente ejemplo: + ```javascript + console.log('Hello\nWorld'); + // Hello + // World - ```javascript - console.log('\n'); - console.log('Dunsen'); - ``` + console.log('Hello \nWorld'); + // Hello + // World (al final de la primera línea hay un espacio) - Aquí primero imprimimos una cadena "salto de línea" y luego imprimimos una cadena normal. El programa mostrará en la pantalla: + console.log('Hello\n World'); + // Hello + // World (al principio de la segunda línea hay un espacio) - ```text + console.log('Hello\n\nWorld'); + // Hello + // + // World (una línea vacía entre ellas) + ``` + Los espacios antes o después de `\n` también se tienen en cuenta. JavaScript los interpreta como caracteres ordinarios y los muestra en la salida. - Dunsen - ``` + También puedes insertar `\n` en cualquier parte de la cadena, antes, después, o incluso usarlo por sí solo. - ¿Por qué antes de la cadena *Dunsen* hay dos líneas vacías en lugar de una? El caso es que `console.log()` agrega automáticamente un carácter de salto de línea al final al imprimir un valor. Por lo tanto, especificamos un salto de línea explícitamente pasando este carácter como argumento a la función, y el segundo salto de línea se agrega automáticamente por la función. + ```javascript + console.log('First line'); + console.log('\n'); // simplemente una línea vacía + console.log('Second line'); + ``` - Otro ejemplo de código: + El resultado será el siguiente. - ```javascript - console.log('Polliver'); - console.log('Gregor Clegane'); - console.log(); - console.log('Chiswyck'); - console.log('\n'); - console.log('Dunsen'); - ``` + ```text + First line - La salida será la siguiente: + Second line + ``` - ```text - Polliver - Gregor Clegane + ## Cómo mostrar el propio carácter `\n` - Chiswyck + `\n` en JavaScript es una secuencia de escape. Controla la disposición del texto y no se muestra en pantalla como los caracteres ordinarios. Si necesitas mostrar precisamente los caracteres `\` y `n`, en lugar de un salto de línea, hay que escaparlos. Para ello, se agrega otra barra antes de la barra invertida. + ```javascript + console.log('Hello\\nWorld'); + // Hello\nWorld - Dunsen - ``` + // Si te olvidas de indicar la segunda barra + console.log('Hello\nWorld'); + // Hello + // World + ``` - Ahora tienes suficiente conocimiento para entender por qué se formó la salida de esta manera. + En este caso, JavaScript entiende `\\` como una barra invertida ordinaria y muestra la cadena sin salto de línea. - 3. Si necesitamos imprimir `\n` como texto (dos caracteres de impresión separados), podemos usar el método de escape que ya conocemos, agregando otro `\` al principio. Es decir, la secuencia `\\n` se mostrará como los caracteres `\` y `n` uno tras otro. + ## Otras secuencias de escape - ```javascript - console.log('Joffrey loves using \\n'); - ``` + Además de `\n`, en JavaScript existen otras secuencias de escape. - se mostrará en la pantalla: + - `\t` denota una tabulación (el equivalente de la tecla Tab). + - `\r` denota un retorno de carro (se usa en Windows, pero rara vez se aplica en el código moderno). + - En programación, lo que más se usa es precisamente `\n`; es suficiente para la mayoría de las tareas. - ```text - Joffrey loves using \n - ``` + ## Detalles importantes - Una pequeña pero importante nota sobre Windows. En Windows, por defecto se utiliza `\r\n` para el salto de línea. Esta combinación funciona bien solamente en Windows, pero crea problemas al transferir a otros sistemas (por ejemplo, cuando en un equipo de desarrollo hay usuarios tanto de Windows como de Linux). El caso es que la secuencia `\r\n` tiene diferentes interpretaciones dependiendo de la codificación seleccionada (esto se discutirá más adelante). Por esta razón, en el ámbito de desarrollo se acostumbra a usar siempre `\n` sin `\r`, ya que LF siempre se interpreta de la misma manera y funciona perfectamente en cualquier sistema. No olvides configurar tu editor para usar `\n`. + - `\n` es un solo carácter, a pesar de que en el código se escribe como dos (`\` y `n`). + - En Windows, por defecto se utiliza la combinación `\r\n`, pero en JavaScript (y en el desarrollo multiplataforma en general) se acostumbra a usar solo `\n` para evitar problemas al transferir el código entre sistemas. instructions: | - Escribe un programa que muestre en la pantalla: + Estás escribiendo un programa que muestra al usuario una pista sobre cómo dividir el texto en líneas. Muestra la pista con una sola llamada a `console.log()`: - ``` - - Did Joffrey agree? - - He did. He also said "I love using \n". + ```text + Use "\n" to separate lines + Example: console.log("line1\nline2") ``` - El programa debe usar solo un `console.log()`, pero el resultado en la pantalla debe verse exactamente como se muestra arriba. + Ten en cuenta: `\n` en la primera línea es texto literal, no un salto de línea. + +tips: [] definitions: - name: Secuencia de escape description: | una combinación especial de caracteres en un texto. Por ejemplo, `\n` es un salto de línea. - -tips: [] diff --git a/modules/25-strings/15-escape-characters/en/EXERCISE.md b/modules/25-strings/15-escape-characters/en/EXERCISE.md index d96616de..6b610951 100644 --- a/modules/25-strings/15-escape-characters/en/EXERCISE.md +++ b/modules/25-strings/15-escape-characters/en/EXERCISE.md @@ -1,9 +1,8 @@ - -Write a program that prints: +You are writing a program that shows the user a hint about how to split text into lines. Print the hint with a single call to `console.log()`: ```text -- Did Joffrey agree? -- He did. He also said "I love using \n". +Use "\n" to separate lines +Example: console.log("line1\nline2") ``` -The program calls only one `console.log()`, but the result on the screen should look exactly like the one above. +Note: `\n` in the first line is literal text, not a line break. diff --git a/modules/25-strings/15-escape-characters/en/README.md b/modules/25-strings/15-escape-characters/en/README.md index 41d09f16..e7ed3543 100644 --- a/modules/25-strings/15-escape-characters/en/README.md +++ b/modules/25-strings/15-escape-characters/en/README.md @@ -1,130 +1,119 @@ +Suppose we want to print the text below across two lines. -Imagine you want to print a dialogue between the Mother of Dragons and her child: - -``` +```text - Are you hungry? - Aaaarrrgh! ``` -If you print a string with this text: +If we simply pass this text to `console.log()`, JavaScript will print everything on a single line. Technically, we could write two consecutive `console.log()` calls, but let's imagine we want to do it with a single one. ```javascript console.log('- Are you hungry?- Aaaarrrgh!'); +// => - Are you hungry?- Aaaarrrgh! ``` -then you'll see: - -``` -- Are you hungry?- Aaaarrrgh! -``` - -Not quite what we were looking for. The strings are written one after the other, it doesn't start a new line. We need to tell the interpreter to "press enter" as it were. In other words, it needs to put a line break after the question mark. You can do this with the new line symbol '\n'. +For each of them to start on a new line, we need to add a line break, that is, to "press Enter". In programming, this is done by adding special characters, in this case `\n`. Yes, this is not a typo. Even though we see two characters here, from JavaScript's point of view this is a single character. ```javascript console.log('- Are you hungry?\n- Aaaarrrgh!'); ``` -The result: +The result will be as follows. -``` +```text - Are you hungry? - Aaaarrrgh! ``` -`\n` is a special symbol. It's often referred to as *LF* (Line Feed, sometimes as line break or newline) in documentation. You may have initially thought it was a misprint, since there are two symbols - `\` and `n`, but this isn't the case. To the computer, this is no more than an invisible symbol to tell it to go to the next line. Proof: +## What is `\n`? -```javascript -// We haven't studied it yet, but you should know the truth -// Below is code that returns the length of a string - -'a'.length; // 1 -'\n'.length; // 1 !!! -'\n\n'.length; // 2 !!! -``` - -Why is it done in this way? `\n` is just a way to write a line break symbol. That's why line feed is just one character, just invisible. And it's also why this problem has arisen. There had to be a way of representing it using a keyboard. And since the number of keyboard characters is limited, and they're all dedicated to very important things, special characters are entered using these escape sequences. +`\n` is an escape sequence (sometimes also called an "escaped sequence"). It denotes a line break but is not displayed directly. You won't see `\n` in the program's output, as it only affects the placement of the text. -The Line Feed symbol is not something specific to programming. Anyone who has ever typed on a computer has used the line feed by clicking Enter. Many editors can display these invisible characters, you can use this feature to see where they are (though it's only for display, these characters are invisible, they have no graphical representation): +In text editors, pressing Enter adds an invisible LF (Line Feed) character. That is exactly what `\n` stands for. Sometimes such characters can be seen if you enable the display of special characters. ```text -- Hi!¶ -- Oh, hey!¶ -- What's up? +- Hello!¶ +- Oh, hi!¶ +- How are you? ``` -The device that outputs the corresponding text takes this character into account. For example, when the printer reaches the line feed, it pulls the paper up one line, and the text editor brings all subsequent text down one line as well. +Printers, editors, and JavaScript interpreters understand `\n` as a command to start the text on a new line. -`\n` is an example of an ** escape sequence**. Although there are dozens of these characters, only a few of them are common in programming. Besides line feed, there is also indents (which you get from pressing Tab) and carriage return (Windows only). Programmers often need to use `\n` line break to format text properly. +## Examples of using `\n` -```javascript -console.log('Gregor Clegane\nDunsen\nPolliver\nChiswyck'); -``` +Here is how JavaScript handles the escape sequence `\n`. -The result: - -``` -Gregor Clegane -Dunsen -Polliver -Chiswyck +```text +In code 'Hello\nWorld' + ↓ +On screen Hello + World ``` -Note: - -1. It does not matter what comes before or after `\n`, whether it's a character or an empty string. The line feed will be detected and executed either way - -2. Remember that a string can contain a single character or none at all. Additionally, a string can only contain `\n`. Analyze the following example: - - ```javascript - console.log('\n'); - console.log('Dunsen'); - ``` - - First the interpreter outputs the string "line feed", and then the normal string. The program will print it like this: +The position of `\n` changes the resulting output. - ```text +```javascript +console.log('Hello\nWorld'); +// Hello +// World + +console.log('Hello \nWorld'); +// Hello +// World (there is a space at the end of the first line) + +console.log('Hello\n World'); +// Hello +// World (there is a space at the beginning of the second line) + +console.log('Hello\n\nWorld'); +// Hello +// +// World (an empty line between them) +``` +Spaces before or after `\n` are also taken into account. JavaScript treats them as ordinary characters and displays them in the output. - Dunsen - ``` +You can also insert `\n` into any part of the string, before, after, or even use it on its own. - Why are there two empty lines before the *Dunsen* line instead of one? The point is that `console.log()` automatically adds a line feed to the end when it outputs a value. So, we explicitly typed one line feed, passing this escape character as an argument in the function, and the second line feed is added automatically by the function itself. +```javascript +console.log('First line'); +console.log('\n'); // just an empty line +console.log('Second line'); +``` - One more example: +The result will be as follows. - ```javascript - console.log('Polliver'); - console.log('Gregor Clegane'); - console.log(); - console.log('Chiswyck'); - console.log('\n'); - console.log('Dunsen'); - ``` +```text +First line - The result: +Second line +``` - ```text - Polliver - Gregor Clegane +## How to print the `\n` character itself - Chiswyck +`\n` in JavaScript is an escape sequence. It controls the placement of the text and is not displayed on screen like ordinary characters. If you need to print exactly the characters `\` and `n`, rather than a line break, you need to escape them. To do this, you add another slash before the backslash. +```javascript +console.log('Hello\\nWorld'); +// Hello\nWorld - Dunsen - ``` +// If you forget to add the second slash +console.log('Hello\nWorld'); +// Hello +// World +``` - Now you understand enough to figure out why the result was formed in this way. +In this case, JavaScript understands `\\` as an ordinary backslash and shows the string without a line break. -3. If we need to print `\n` as a text (two separate characters), we can use the escape character, adding another `\` at the beginning. I.e., the sequence of `\n` will be printed as characters `\` and `n` following each other +## Other escape sequences -```javascript -console.log('Joffrey loves using \\n'); -``` +In addition to `\n`, JavaScript has other escape sequences as well. -The result: +- `\t` denotes a tab (the equivalent of the Tab key). +- `\r` denotes a carriage return (used on Windows, but rarely applied in modern code). +- In programming, `\n` is used most often; it is enough for the majority of tasks. -```text -Joffrey loves using \n -``` +## Important details -A small but important note about Windows. Windows uses `\r\n` by default to enter a line break. This combination works well on Windows but creates problems when copied to other systems (for example, when the development team includes both Windows and Linux users). The point is that the sequence `\r\n` has a different interpretation depending on the encoding chosen (we discuss it later). For this reason, it's common among developers to always use `\n` without `\r`, since it means that LF is always interpreted the same way and works fine on any system. Remember to configure your editor to use `\n`. +- `\n` is a single character, even though in the code it is written as two (`\` and `n`). +- On Windows, the combination `\r\n` is used by default, but in JavaScript (and in cross-platform development in general) it is customary to use only `\n` to avoid problems when moving code between systems. diff --git a/modules/25-strings/15-escape-characters/en/data.yml b/modules/25-strings/15-escape-characters/en/data.yml index 84169d63..7cede4c8 100644 --- a/modules/25-strings/15-escape-characters/en/data.yml +++ b/modules/25-strings/15-escape-characters/en/data.yml @@ -3,9 +3,9 @@ name: Escape sequences definitions: - name: Escape sequence description: > - is a special combination of characters in the text. For example, `\n` is a - line feed. + a special combination of characters in text. For example, `\n` is a line + break. tips: - > - [The History of - Newline](https://en.wikipedia.org/wiki/Newline#:~:text=External%20links-,History,-%5Bedit%5D) + [The history of the line + break](https://en.wikipedia.org/wiki/Newline#History) diff --git a/modules/25-strings/15-escape-characters/es/EXERCISE.md b/modules/25-strings/15-escape-characters/es/EXERCISE.md index a851fa81..24ca159d 100644 --- a/modules/25-strings/15-escape-characters/es/EXERCISE.md +++ b/modules/25-strings/15-escape-characters/es/EXERCISE.md @@ -1,9 +1,8 @@ - -Escribe un programa que muestre en la pantalla: +Estás escribiendo un programa que muestra al usuario una pista sobre cómo dividir el texto en líneas. Muestra la pista con una sola llamada a `console.log()`: ```text -- Did Joffrey agree? -- He did. He also said "I love using \n". +Use "\n" to separate lines +Example: console.log("line1\nline2") ``` -El programa debe usar solo un `console.log()`, pero el resultado en la pantalla debe verse exactamente como se muestra arriba. +Ten en cuenta: `\n` en la primera línea es texto literal, no un salto de línea. diff --git a/modules/25-strings/15-escape-characters/es/README.md b/modules/25-strings/15-escape-characters/es/README.md index 9c585fcf..e32654e0 100644 --- a/modules/25-strings/15-escape-characters/es/README.md +++ b/modules/25-strings/15-escape-characters/es/README.md @@ -1,49 +1,35 @@ +Supongamos que queremos mostrar el texto de abajo en dos líneas. -Queremos mostrar un diálogo entre Daenerys Targaryen y su hijo: - -``` +```text - Are you hungry? - Aaaarrrgh! ``` -Si imprimimos en la pantalla una cadena de texto con este contenido: - -```javascript -console.log('- Are you hungry?- ¡Aaaarrrgh!'); -``` - -obtendremos esto: +Si simplemente pasamos este texto a `console.log()`, JavaScript imprimirá todo en una sola línea. Técnicamente, podríamos escribir dos llamadas consecutivas a `console.log()`, pero imaginemos que queremos hacerlo con una sola. ```javascript console.log('- Are you hungry?- Aaaarrrgh!'); +// => - Are you hungry?- Aaaarrrgh! ``` -No es lo que queríamos. Las líneas están una al lado de la otra en lugar de estar una debajo de la otra. Necesitamos decirle al intérprete "presiona Enter" - haz un salto de línea después del signo de interrogación. Esto se puede hacer utilizando el carácter de salto de línea: `\n`. +Para que cada una de ellas empiece en una nueva línea, necesitamos agregar un salto de línea, es decir, "presionar Enter". En programación, esto se hace agregando caracteres especiales, en este caso `\n`. Sí, no es un error de escritura. A pesar de que aquí vemos dos caracteres, desde el punto de vista de JavaScript es un solo carácter. ```javascript console.log('- Are you hungry?\n- Aaaarrrgh!'); ``` -resultado: +El resultado será el siguiente. -``` +```text - Are you hungry? - Aaaarrrgh! ``` -`\n` es un carácter especial. En literatura a menudo se le llama *LF* (Line Feed). Es posible que ahora estés pensando que es un error de escritura, ya que aquí vemos dos caracteres `\` y `n`, pero no es así. Desde el punto de vista de la computadora, es un solo carácter de salto de línea invisible. Prueba de ello: +## ¿Qué es `\n`? -```javascript -// No hemos estudiado esto, pero debes saber la verdad -// A continuación hay un código que devuelve la longitud de una cadena -'a'.length; // 1 -'\n'.length; // 1 !!! -'\n\n'.length; // 2 !!! -``` +`\n` es una secuencia de escape (en inglés, escape sequence; a veces se le llama "secuencia escapada"). Denota un salto de línea, pero no se muestra directamente. No verás `\n` en la salida del programa, ya que solo afecta a la disposición del texto. -¿Por qué se hizo así? `\n` es simplemente una forma de escribir el carácter de salto de línea, pero el salto de línea en sí es un solo carácter, aunque invisible. Es por eso que surgió esta tarea. Necesitábamos encontrar una forma de representarlo en el teclado. Y dado que la cantidad de caracteres en el teclado es limitada y se reserva para los más importantes, todos los caracteres especiales se implementan como tales representaciones. - -El carácter de salto de línea no es algo específico de la programación. Todos los que han escrito en una computadora han utilizado el salto de línea al presionar Enter. En muchos editores hay una opción que permite mostrar los caracteres invisibles, lo que permite ver dónde se encuentran (aunque esto es solamente una representación esquemática, estos caracteres no tienen una representación gráfica; son invisibles): +En los editores de texto, al presionar Enter se agrega un carácter invisible LF (Line Feed). Eso es precisamente lo que significa `\n`. A veces estos caracteres se pueden ver si activas la visualización de los caracteres especiales. ```text - ¡Hola!¶ @@ -51,79 +37,83 @@ El carácter de salto de línea no es algo específico de la programación. Todo - ¿Cómo estás? ``` -El dispositivo que muestra el texto correspondiente tiene en cuenta este carácter. Por ejemplo, una impresora, al encontrar un LF, avanza el papel hacia arriba una línea, y un editor de texto mueve todo el texto siguiente hacia abajo, también una línea. - -`\n` es un ejemplo de una **secuencia de escape** (escape sequence). También se les llama construcciones de control. Aunque hay más de una docena de estos caracteres, en programación a menudo solamente se encuentran unos pocos. Además del salto de línea, estos caracteres incluyen la tabulación (espacio que se obtiene al presionar la tecla Tab) y el retorno de carro (solo en Windows). A menudo, los programadores necesitamos usar el salto de línea `\n` para formatear correctamente el texto. +Las impresoras, los editores y los intérpretes de JavaScript entienden `\n` como una orden de empezar el texto en una nueva línea. -```javascript -console.log('Gregor Clegane\nDunsen\nPolliver\nChiswyck'); -``` +## Ejemplos de uso de `\n` -Se mostrará en la pantalla: +Así es como JavaScript procesa la secuencia de escape `\n`. -``` -Gregor Clegane -Dunsen -Polliver -Chiswyck +```text +En el código 'Hello\nWorld' + ↓ +En pantalla Hello + World ``` -Ten en cuenta los siguientes puntos: +La posición de `\n` cambia la salida final. -1. No importa lo que haya antes o después de `\n`: un carácter o una cadena vacía. El salto de línea se detectará y se realizará de todos modos. - -2. Recuerda que una cadena puede contener un solo carácter o incluso cero caracteres. Y también una cadena puede contener solo `\n`. Analiza el siguiente ejemplo: - - ```javascript - console.log('\n'); - console.log('Dunsen'); - ``` - - Aquí primero imprimimos una cadena "salto de línea" y luego imprimimos una cadena normal. El programa mostrará en la pantalla: - - ```text +```javascript +console.log('Hello\nWorld'); +// Hello +// World + +console.log('Hello \nWorld'); +// Hello +// World (al final de la primera línea hay un espacio) + +console.log('Hello\n World'); +// Hello +// World (al principio de la segunda línea hay un espacio) + +console.log('Hello\n\nWorld'); +// Hello +// +// World (una línea vacía entre ellas) +``` +Los espacios antes o después de `\n` también se tienen en cuenta. JavaScript los interpreta como caracteres ordinarios y los muestra en la salida. - Dunsen - ``` +También puedes insertar `\n` en cualquier parte de la cadena, antes, después, o incluso usarlo por sí solo. - ¿Por qué antes de la cadena *Dunsen* hay dos líneas vacías en lugar de una? El caso es que `console.log()` agrega automáticamente un carácter de salto de línea al final al imprimir un valor. Por lo tanto, especificamos un salto de línea explícitamente pasando este carácter como argumento a la función, y el segundo salto de línea se agrega automáticamente por la función. +```javascript +console.log('First line'); +console.log('\n'); // simplemente una línea vacía +console.log('Second line'); +``` - Otro ejemplo de código: +El resultado será el siguiente. - ```javascript - console.log('Polliver'); - console.log('Gregor Clegane'); - console.log(); - console.log('Chiswyck'); - console.log('\n'); - console.log('Dunsen'); - ``` +```text +First line - La salida será la siguiente: +Second line +``` - ```text - Polliver - Gregor Clegane +## Cómo mostrar el propio carácter `\n` - Chiswyck +`\n` en JavaScript es una secuencia de escape. Controla la disposición del texto y no se muestra en pantalla como los caracteres ordinarios. Si necesitas mostrar precisamente los caracteres `\` y `n`, en lugar de un salto de línea, hay que escaparlos. Para ello, se agrega otra barra antes de la barra invertida. +```javascript +console.log('Hello\\nWorld'); +// Hello\nWorld - Dunsen - ``` +// Si te olvidas de indicar la segunda barra +console.log('Hello\nWorld'); +// Hello +// World +``` - Ahora tienes suficiente conocimiento para entender por qué se formó la salida de esta manera. +En este caso, JavaScript entiende `\\` como una barra invertida ordinaria y muestra la cadena sin salto de línea. -3. Si necesitamos imprimir `\n` como texto (dos caracteres de impresión separados), podemos usar el método de escape que ya conocemos, agregando otro `\` al principio. Es decir, la secuencia `\\n` se mostrará como los caracteres `\` y `n` uno tras otro. +## Otras secuencias de escape -```javascript -console.log('Joffrey loves using \\n'); -``` +Además de `\n`, en JavaScript existen otras secuencias de escape. -se mostrará en la pantalla: +- `\t` denota una tabulación (el equivalente de la tecla Tab). +- `\r` denota un retorno de carro (se usa en Windows, pero rara vez se aplica en el código moderno). +- En programación, lo que más se usa es precisamente `\n`; es suficiente para la mayoría de las tareas. -```text -Joffrey loves using \n -``` +## Detalles importantes -Una pequeña pero importante nota sobre Windows. En Windows, por defecto se utiliza `\r\n` para el salto de línea. Esta combinación funciona bien solamente en Windows, pero crea problemas al transferir a otros sistemas (por ejemplo, cuando en un equipo de desarrollo hay usuarios tanto de Windows como de Linux). El caso es que la secuencia `\r\n` tiene diferentes interpretaciones dependiendo de la codificación seleccionada (esto se discutirá más adelante). Por esta razón, en el ámbito de desarrollo se acostumbra a usar siempre `\n` sin `\r`, ya que LF siempre se interpreta de la misma manera y funciona perfectamente en cualquier sistema. No olvides configurar tu editor para usar `\n`. +- `\n` es un solo carácter, a pesar de que en el código se escribe como dos (`\` y `n`). +- En Windows, por defecto se utiliza la combinación `\r\n`, pero en JavaScript (y en el desarrollo multiplataforma en general) se acostumbra a usar solo `\n` para evitar problemas al transferir el código entre sistemas. diff --git a/modules/25-strings/15-escape-characters/es/data.yml b/modules/25-strings/15-escape-characters/es/data.yml index ff48e086..d7f21e5d 100644 --- a/modules/25-strings/15-escape-characters/es/data.yml +++ b/modules/25-strings/15-escape-characters/es/data.yml @@ -5,4 +5,7 @@ definitions: description: > una combinación especial de caracteres en un texto. Por ejemplo, `\n` es un salto de línea. -tips: [] +tips: + - > + [La historia del salto de + línea](https://es.wikipedia.org/wiki/Nueva_l%C3%ADnea) diff --git a/modules/25-strings/15-escape-characters/index.js b/modules/25-strings/15-escape-characters/index.js index 0789496d..1453dae5 100644 --- a/modules/25-strings/15-escape-characters/index.js +++ b/modules/25-strings/15-escape-characters/index.js @@ -1,3 +1,3 @@ console.log( - 'Для разделения строк используйте "\\n"\nПример: console.log("строка1\\nстрока2")', + 'Use "\\n" to separate lines\nExample: console.log("line1\\nline2")', ); diff --git a/modules/25-strings/15-escape-characters/ru/EXERCISE.md b/modules/25-strings/15-escape-characters/ru/EXERCISE.md index 9ffec32b..d4e15e00 100644 --- a/modules/25-strings/15-escape-characters/ru/EXERCISE.md +++ b/modules/25-strings/15-escape-characters/ru/EXERCISE.md @@ -1,8 +1,8 @@ Вы пишете программу, которая показывает пользователю подсказку о том, как разбить текст на строки. Выведите подсказку одним вызовом `console.log()`: ```text -Для разделения строк используйте "\n" -Пример: console.log("строка1\nстрока2") +Use "\n" to separate lines +Example: console.log("line1\nline2") ``` Обратите внимание: `\n` в первой строке — это буквальный текст, а не перевод строки. diff --git a/modules/25-strings/15-escape-characters/test.js b/modules/25-strings/15-escape-characters/test.js index a0f2859d..8503b970 100644 --- a/modules/25-strings/15-escape-characters/test.js +++ b/modules/25-strings/15-escape-characters/test.js @@ -9,6 +9,6 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); expect(firstArg).toBe( - 'Для разделения строк используйте "\\n"\nПример: console.log("строка1\\nстрока2")', + 'Use "\\n" to separate lines\nExample: console.log("line1\\nline2")', ); }); diff --git a/modules/25-strings/20-string-concatenation/description.es.yml b/modules/25-strings/20-string-concatenation/description.es.yml index bddd1a50..c8bebe1d 100644 --- a/modules/25-strings/20-string-concatenation/description.es.yml +++ b/modules/25-strings/20-string-concatenation/description.es.yml @@ -3,68 +3,94 @@ name: Concatenación theory: | - En el desarrollo web, los programas operan constantemente con cadenas de texto. Todo lo que vemos en los sitios web está representado de alguna manera como texto. Este texto suele ser dinámico, es decir, se obtiene a partir de diferentes partes que se unen. La operación de unir cadenas en programación se llama **concatenación**. + A menudo, las cadenas deben ensamblarse a partir de varias partes, por ejemplo, combinar un nombre y un apellido, agregar una unidad de medida o componer un texto a partir de una plantilla. Para ello se utiliza la operación de concatenación, es decir, el pegado de cadenas. + + ## Cómo combinar cadenas + + En JavaScript, las cadenas se combinan con el operador `+`. Aunque este operador también se usa para sumar números, en el caso de las cadenas significa combinar, es decir, pegar el contenido. ```javascript - // El operador es el mismo que para sumar números - // pero aquí tiene un significado diferente (semántica) console.log('Dragon' + 'stone'); // => Dragonstone ``` - La concatenación de cadenas siempre ocurre en el mismo orden en el que se escriben los operandos. El operando izquierdo se convierte en la parte izquierda de la cadena, y el operando derecho en la parte derecha. + El orden importa. Primero va la parte izquierda (`'Dragon'`), luego la parte derecha (`'stone'`). El resultado se obtiene en el orden en que se especifican los operandos. - Aquí hay algunos ejemplos adicionales: + Así funciona la combinación de varias cadenas: - ```javascript - console.log('Kings' + 'wood'); // => Kingswood + ```text + 'Hello' + ', ' + 'World!' + └──┬──┘ └┬┘ └──┬───┘ + └────┬───┘ │ + 'Hello, ' + 'World!' + └──────┬───────┘ + 'Hello, World!' + ``` - // Orden inverso de las palabras - console.log('road' + 'Kings'); // => roadKings + Ejemplos. - // Se pueden concatenar cadenas de cualquier tipo - console.log("King's" + 'Landing'); // => King'sLanding + ```javascript + console.log('Kings' + 'wood'); // => Kingswood + console.log('Kings' + 'road'); // => Kingsroad + // Aquí usamos comillas dobles por fuera porque hay una comilla simple adentro + console.log("King's" + 'Landing'); // => King'sLanding ``` - Como puedes ver, puedes concatenar cadenas incluso si están escritas con diferentes tipos de comillas. + JavaScript permite combinar cadenas incluso si están escritas con comillas diferentes. Lo principal es que ambas partes sean cadenas. - En el último ejemplo, el nombre de la ciudad se escribió incorrectamente: *King's Landing* debe escribirse con un espacio. Pero en nuestras cadenas iniciales no había espacios, y los espacios en el código a la izquierda y a la derecha del símbolo `+` no importan, ya que no forman parte de las cadenas. + ## Un espacio también es un carácter - Hay dos formas de solucionar esta situación: + Al combinar, JavaScript no inserta espacios automáticamente. Si debe haber un espacio entre las partes, hay que indicarlo manualmente. ```javascript - // Ambas formas son equivalentes + // Espacio al final de la primera cadena + console.log("King's " + 'Landing'); // => King's Landing - // Agregar un espacio en la parte izquierda - console.log("King's " + 'Landing'); // => King's Landing - // Agregar un espacio en la parte derecha - console.log("King's" + ' Landing'); // => King's Landing + // Espacio al principio de la segunda cadena + console.log("King's" + ' Landing'); // => King's Landing ``` - Un espacio es simplemente un símbolo más, al igual que los demás. Cuantos más espacios haya, más anchos serán los espacios: + El resultado será el mismo. Pero si no se agrega un espacio, las palabras se pegarán. + + ## Secuencias de escape + + En las cadenas se pueden usar secuencias de escape, por ejemplo `\n` para un salto de línea o `\t` para una tabulación. Durante la concatenación, funcionan igual que cualquier otro carácter. ```javascript - console.log("King's " + ' Landing'); // => King's Landing + console.log('Hello,' + '\n' + 'World!'); + // Hello, + // World! + ``` + + De la misma manera, se puede usar la tabulación `\t` para alinear la salida. - console.log("King's " + ' Landing'); // => King's Landing + ```javascript + console.log('A' + '\t' + 'B'); // => A B ``` + ## Conclusión + + La concatenación es la combinación de cadenas mediante `+`, y las cadenas se pueden combinar independientemente del tipo de comillas. + + - El pegado ocurre estrictamente en orden de izquierda a derecha. + - Los espacios no se agregan automáticamente; hay que incluirlos en las cadenas manualmente. instructions: | - Muestra en la pantalla + El sitio genera automáticamente enlaces a las páginas de los repositorios, ensamblándolos a partir de partes separadas. Ensambla el enlace usando concatenación e imprímelo en la pantalla: - ``` - Winter came for the House of Frey. + ```text + https://github.com/hexlet/exercises-javascript ``` - utilizando la concatenación de palabras. + Cada componente de la URL es una cadena separada: el protocolo, el dominio, el nombre del propietario y el nombre del repositorio. tips: - | - Si hay una línea `// BEGIN` y `// END` en el editor, el código debe escribirse entre estas líneas. + Si el editor contiene `// BEGIN` y `// END`, entonces el código debe escribirse entre estas líneas. definitions: - name: Concatenación - description: | - la operación de unir dos cadenas. Por ejemplo, `console.log("King's " + ' Landing');` + description: > + la operación de unir dos cadenas. Por ejemplo, `console.log("King's " + ' + Landing');` diff --git a/modules/25-strings/20-string-concatenation/en/EXERCISE.md b/modules/25-strings/20-string-concatenation/en/EXERCISE.md index faf23758..21882251 100644 --- a/modules/25-strings/20-string-concatenation/en/EXERCISE.md +++ b/modules/25-strings/20-string-concatenation/en/EXERCISE.md @@ -1,8 +1,7 @@ +The site automatically generates links to repository pages by assembling them from separate parts. Assemble the link using concatenation and print it to the screen: -Print the following code - -``` -Winter came for the House of Frey. +```text +https://github.com/hexlet/exercises-javascript ``` -using concatenation. +Each URL component is a separate string: the protocol, the domain, the owner name, and the repository name. diff --git a/modules/25-strings/20-string-concatenation/en/README.md b/modules/25-strings/20-string-concatenation/en/README.md index a0e0682a..7e345bbd 100644 --- a/modules/25-strings/20-string-concatenation/en/README.md +++ b/modules/25-strings/20-string-concatenation/en/README.md @@ -1,47 +1,71 @@ +Often, strings need to be assembled from several parts, for example, to combine a first and last name, add a unit of measurement, or compose text from a template. The concatenation operation, that is, gluing strings together, is used for this. -In web development, programs use strings constantly. Everything we see on websites is represented as text in one way or another. This text is most often dynamic, it's made up of different connected pieces. In programming, the operation of joining one string to another is called **concatenation**. +## How to combine strings -```javascript -// The operator is the same as for adding -// but it has different semantics (meaning) +In JavaScript, strings are combined using the `+` operator. Even though this operator is also used to add numbers, in the case of strings it means combining, that is, gluing the contents together. +```javascript console.log('Dragon' + 'stone'); -// => 'Dragonstone' +// => Dragonstone ``` -Strings always concatenate in the same order in which the operands are written. The left operand becomes the left part of the string, and the right one becomes the right part. +Order matters. First comes the left part (`'Dragon'`), then the right part (`'stone'`). The result comes out in the order in which the operands are specified. -Here are a few more examples: +Here is how combining several strings works: -```javascript -console.log('Kings' + 'wood'); // => Kingswood +```text +'Hello' + ', ' + 'World!' +└──┬──┘ └┬┘ └──┬───┘ + └────┬───┘ │ + 'Hello, ' + 'World!' + └──────┬───────┘ + 'Hello, World!' +``` -// Reverse word order -console.log('road' + 'Kings'); // => roadKings +Examples. -// Any string can be concatenated -console.log("King's" + 'Landing'); // => King'sLanding +```javascript +console.log('Kings' + 'wood'); // => Kingswood +console.log('Kings' + 'road'); // => Kingsroad +// Here we use double quotes on the outside because there is a single quote inside +console.log("King's" + 'Landing'); // => King'sLanding ``` -As you can see, strings can concatenate even if they are written in different quotes. +JavaScript lets you combine strings even if they are written with different quotes. The main thing is that both parts are strings. -In the last example, the name of the city has a misprint: *King's Landing* should be written with a space. But there were no spaces at the beginning of our strings, and the spaces left and right of the `+` don't matter because they are not part of the strings. +## A space is also a character -There are two ways to fix this: +When combining, JavaScript does not insert spaces automatically. If there should be a space between the parts, it must be specified manually. ```javascript -// Both ways are functionally the same +// Space at the end of the first string +console.log("King's " + 'Landing'); // => King's Landing -// Put space in the end of the left part -console.log("King's " + 'Landing'); // => King's Landing -// Put space in the beginning of the right part -console.log("King's" + ' Landing'); // => King's Landing +// Space at the beginning of the second string +console.log("King's" + ' Landing'); // => King's Landing ``` -A space is also a symbol. The more spaces you put, the wider the indentation will be: +The result will be the same. But if you do not add a space, the words will glue together. + +## Escape sequences + +In strings, you can use escape sequences, for example `\n` for a line break or `\t` for a tab. During concatenation, they work the same as any other characters. ```javascript -console.log("King's " + ' Landing'); // => King's Landing +console.log('Hello,' + '\n' + 'World!'); +// Hello, +// World! +``` + +In the same way, you can use the tab `\t` to align output. -console.log("King's " + ' Landing'); // => King's Landing +```javascript +console.log('A' + '\t' + 'B'); // => A B ``` + +## Conclusion + +Concatenation is the combining of strings via `+`, and strings can be combined regardless of the type of quotes. + +- Gluing happens strictly in order from left to right. +- Spaces are not added automatically; they must be included in the strings manually. diff --git a/modules/25-strings/20-string-concatenation/en/data.yml b/modules/25-strings/20-string-concatenation/en/data.yml index e9b58281..268ddaa4 100644 --- a/modules/25-strings/20-string-concatenation/en/data.yml +++ b/modules/25-strings/20-string-concatenation/en/data.yml @@ -1,10 +1,11 @@ --- name: Concatenation tips: - - | - Type your code between the `// BEGIN` and `// END` lines in the editor. + - > + If the editor contains `// BEGIN` and `// END`, then the code must be + written between these lines. definitions: - name: Concatenation description: > - is the operation of joining two strings. For example, `console.log("King's - " + ' Landing');`. + the operation of joining two strings. For example, `console.log("King's " + + ' Landing');` diff --git a/modules/25-strings/20-string-concatenation/es/EXERCISE.md b/modules/25-strings/20-string-concatenation/es/EXERCISE.md index a70d636e..ed65e52a 100644 --- a/modules/25-strings/20-string-concatenation/es/EXERCISE.md +++ b/modules/25-strings/20-string-concatenation/es/EXERCISE.md @@ -1,8 +1,7 @@ +El sitio genera automáticamente enlaces a las páginas de los repositorios, ensamblándolos a partir de partes separadas. Ensambla el enlace usando concatenación e imprímelo en la pantalla: -Muestra en la pantalla - -``` -Winter came for the House of Frey. +```text +https://github.com/hexlet/exercises-javascript ``` -utilizando la concatenación de palabras. +Cada componente de la URL es una cadena separada: el protocolo, el dominio, el nombre del propietario y el nombre del repositorio. diff --git a/modules/25-strings/20-string-concatenation/es/README.md b/modules/25-strings/20-string-concatenation/es/README.md index 314c78ed..11dd7670 100644 --- a/modules/25-strings/20-string-concatenation/es/README.md +++ b/modules/25-strings/20-string-concatenation/es/README.md @@ -1,46 +1,71 @@ +A menudo, las cadenas deben ensamblarse a partir de varias partes, por ejemplo, combinar un nombre y un apellido, agregar una unidad de medida o componer un texto a partir de una plantilla. Para ello se utiliza la operación de concatenación, es decir, el pegado de cadenas. -En el desarrollo web, los programas operan constantemente con cadenas de texto. Todo lo que vemos en los sitios web está representado de alguna manera como texto. Este texto suele ser dinámico, es decir, se obtiene a partir de diferentes partes que se unen. La operación de unir cadenas en programación se llama **concatenación**. +## Cómo combinar cadenas + +En JavaScript, las cadenas se combinan con el operador `+`. Aunque este operador también se usa para sumar números, en el caso de las cadenas significa combinar, es decir, pegar el contenido. ```javascript -// El operador es el mismo que para sumar números -// pero aquí tiene un significado diferente (semántica) console.log('Dragon' + 'stone'); // => Dragonstone ``` -La concatenación de cadenas siempre ocurre en el mismo orden en el que se escriben los operandos. El operando izquierdo se convierte en la parte izquierda de la cadena, y el operando derecho en la parte derecha. +El orden importa. Primero va la parte izquierda (`'Dragon'`), luego la parte derecha (`'stone'`). El resultado se obtiene en el orden en que se especifican los operandos. -Aquí hay algunos ejemplos adicionales: +Así funciona la combinación de varias cadenas: -```javascript -console.log('Kings' + 'wood'); // => Kingswood +```text +'Hello' + ', ' + 'World!' +└──┬──┘ └┬┘ └──┬───┘ + └────┬───┘ │ + 'Hello, ' + 'World!' + └──────┬───────┘ + 'Hello, World!' +``` -// Orden inverso de las palabras -console.log('road' + 'Kings'); // => roadKings +Ejemplos. -// Se pueden concatenar cadenas de cualquier tipo -console.log("King's" + 'Landing'); // => King'sLanding +```javascript +console.log('Kings' + 'wood'); // => Kingswood +console.log('Kings' + 'road'); // => Kingsroad +// Aquí usamos comillas dobles por fuera porque hay una comilla simple adentro +console.log("King's" + 'Landing'); // => King'sLanding ``` -Como puedes ver, puedes concatenar cadenas incluso si están escritas con diferentes tipos de comillas. +JavaScript permite combinar cadenas incluso si están escritas con comillas diferentes. Lo principal es que ambas partes sean cadenas. -En el último ejemplo, el nombre de la ciudad se escribió incorrectamente: *King's Landing* debe escribirse con un espacio. Pero en nuestras cadenas iniciales no había espacios, y los espacios en el código a la izquierda y a la derecha del símbolo `+` no importan, ya que no forman parte de las cadenas. +## Un espacio también es un carácter -Hay dos formas de solucionar esta situación: +Al combinar, JavaScript no inserta espacios automáticamente. Si debe haber un espacio entre las partes, hay que indicarlo manualmente. ```javascript -// Ambas formas son equivalentes +// Espacio al final de la primera cadena +console.log("King's " + 'Landing'); // => King's Landing -// Agregar un espacio en la parte izquierda -console.log("King's " + 'Landing'); // => King's Landing -// Agregar un espacio en la parte derecha -console.log("King's" + ' Landing'); // => King's Landing +// Espacio al principio de la segunda cadena +console.log("King's" + ' Landing'); // => King's Landing ``` -Un espacio es simplemente un símbolo más, al igual que los demás. Cuantos más espacios haya, más anchos serán los espacios: +El resultado será el mismo. Pero si no se agrega un espacio, las palabras se pegarán. + +## Secuencias de escape + +En las cadenas se pueden usar secuencias de escape, por ejemplo `\n` para un salto de línea o `\t` para una tabulación. Durante la concatenación, funcionan igual que cualquier otro carácter. ```javascript -console.log("King's " + ' Landing'); // => King's Landing +console.log('Hello,' + '\n' + 'World!'); +// Hello, +// World! +``` + +De la misma manera, se puede usar la tabulación `\t` para alinear la salida. -console.log("King's " + ' Landing'); // => King's Landing +```javascript +console.log('A' + '\t' + 'B'); // => A B ``` + +## Conclusión + +La concatenación es la combinación de cadenas mediante `+`, y las cadenas se pueden combinar independientemente del tipo de comillas. + +- El pegado ocurre estrictamente en orden de izquierda a derecha. +- Los espacios no se agregan automáticamente; hay que incluirlos en las cadenas manualmente. diff --git a/modules/25-strings/20-string-concatenation/es/data.yml b/modules/25-strings/20-string-concatenation/es/data.yml index 75103b54..903e4a1b 100644 --- a/modules/25-strings/20-string-concatenation/es/data.yml +++ b/modules/25-strings/20-string-concatenation/es/data.yml @@ -2,7 +2,7 @@ name: Concatenación tips: - > - Si hay una línea `// BEGIN` y `// END` en el editor, el código debe + Si el editor contiene `// BEGIN` y `// END`, entonces el código debe escribirse entre estas líneas. definitions: - name: Concatenación diff --git a/modules/25-strings/30-encoding/description.es.yml b/modules/25-strings/30-encoding/description.es.yml index c9ab6a92..8689967a 100644 --- a/modules/25-strings/30-encoding/description.es.yml +++ b/modules/25-strings/30-encoding/description.es.yml @@ -3,65 +3,106 @@ name: Codificación theory: | - En el nivel más profundo, una computadora opera exclusivamente con los dígitos `0` y `1`. Esto se conoce como [código binario](https://es.wikipedia.org/wiki/C%C3%B3digo_binario), y los unos y ceros se llaman bits, que es una abreviatura de "binary digit" (dígito binario). + En el nivel más básico, una computadora trabaja únicamente con ceros y unos, lo que constituye el llamado código binario. Cada uno o cero se denomina bit (de binary digit, "dígito binario"). - Los números que estamos acostumbrados a utilizar en el sistema decimal se codifican utilizando números binarios: + Cualquier dato en una computadora se representa simplemente como una secuencia de bits, por ejemplo imágenes, música y texto. Los números habituales del sistema decimal también pueden representarse en forma binaria. - - 0 ← 0 - - 1 ← 1 - - 2 ← 10 - - 3 ← 11 - - 4 ← 100 - - 5 ← 101 + - 0 → `0` + - 1 → `1` + - 2 → `10` - Pero, ¿qué pasa con el texto? En realidad, la computadora no sabe nada acerca de letras, signos de puntuación y otros caracteres de texto. Todos estos caracteres también se codifican con números. + ## ¿Cómo codificar texto? - Podemos tomar el alfabeto inglés y asignar un número a cada letra, comenzando desde uno en orden: + Una computadora no "entiende" el texto. Para trabajar con letras y otros caracteres, también hay que convertirlos en números. Esto se hace mediante codificaciones, es decir, tablas en las que a cada carácter le corresponde un número determinado. - - a ← 1 - - b ← 2 - - c ← 3 - - d ← 4 - - ... - - z ← 26 + La forma más sencilla consiste en numerar las letras, empezando por 1. - Luego, podemos enseñarle a la computadora a entender esta tabla y convertir texto en números y viceversa: + - `a` → `1` + - `b` → `2` + - ...y así hasta `z` → `26` - - `hello` → `8` `5` `12` `12` `15` - - `7` `15` `15` `4` → `good` + Ahora podemos representar la palabra `hello` como un conjunto de números. - Estas tablas que relacionan letras y números se llaman codificaciones. Además de las letras del alfabeto, las tablas de codificación incluyen signos de puntuación y otros caracteres útiles. Seguramente has encontrado codificaciones como [ASCII](https://es.wikipedia.org/wiki/ASCII) o [UTF-8](https://es.wikipedia.org/wiki/UTF-8). + ```text + h e l l o + ↓ ↓ ↓ ↓ ↓ + 8 5 12 12 15 + ``` - Las diferentes codificaciones contienen diferentes conjuntos de caracteres. Inicialmente, tablas pequeñas como ASCII eran suficientes para la mayoría de las tareas. Sin embargo, esta solamente contiene letras latinas, algunos caracteres simples como `%` y `?`, y caracteres de control especiales como el salto de línea. + Y `good` se convierte en la siguiente secuencia. - Con la proliferación de las computadoras, diferentes países necesitaron sus propias tablas más amplias. Esto incluye letras cirílicas, caracteres chinos, árabe, matemáticos y tipográficos adicionales, e incluso emojis. + ```text + g o o d + ↓ ↓ ↓ ↓ + 7 15 15 4 + ``` - Hoy en día, en la mayoría de los casos se utiliza una de las variantes de [Unicode](https://es.wikipedia.org/wiki/Unicode) - *utf-8*. Esta incluye caracteres de casi todos los idiomas escritos del mundo. Gracias a esto, un correo electrónico escrito en chino en China se puede abrir y ver sin problemas en una computadora en Finlandia (si lo entiende o no, es otra cuestión). + El programa no sabe que esto es una palabra. Simplemente ve la instrucción "hay que mostrar el carácter con el código 8, luego el de código 5, etc.". - Los programadores se encuentran regularmente con la codificación de texto y las codificaciones en su vida. El soporte de Unicode en diferentes lenguajes de programación se implementa a diferentes niveles. Además, las codificaciones deben especificarse explícitamente al trabajar con bases de datos y archivos. + ## ASCII. La primera codificación masiva -instructions: | + Las primeras computadoras trabajaban principalmente con el idioma inglés. Para él, en la década de 1960 se inventó la tabla ASCII, que incluía 128 caracteres, entre ellos el alfabeto latino, los dígitos, los signos de puntuación, los caracteres especiales (`@`, `#`, `!`, `\n`) y los códigos de control. - En JavaScript, puedes "solicitar" y mostrar en pantalla cualquier carácter de la codificación ASCII. Por ejemplo: + Esto bastaba para los primeros programas, pero no para todo el mundo. - ```javascript - console.log(String.fromCharCode(63)); + Cuando las computadoras empezaron a usarse en otros países, surgió un problema. En ASCII no hay cirílico, ideogramas, escritura árabe, acentos, símbolos de moneda, etc. + + Cada país o empresa empezó a crear su propia codificación basada en ASCII. + + - Windows ideó Windows-1251 para el ruso + - Apple creó Mac Roman + - Los países de Europa del Este, Asia y Oriente Medio desarrollaron sus propias variantes + + Todas estas codificaciones eran incompatibles entre sí. El código 226 en una codificación podía ser la letra é, en otra una letra distinta, y en una tercera incluso un carácter técnico. Esto provocaba un verdadero caos. + + ## Cómo se veían los problemas con las codificaciones + + Si ves esto en un texto. + + ```text + ÐÑивеÑ! ``` - Esto mostrará en pantalla el carácter con el número 63, que es el signo de interrogación `?`. De esta manera, puedes mostrar cualquier carácter. + Significa que el programa determinó incorrectamente la codificación del texto. Recibió una secuencia de bytes, pero los leyó con la tabla equivocada. + + Esto era lo habitual en las décadas de 1990 y 2000. Un programa escribía el texto en Windows-1251, otro lo leía como ISO-8859-1 y, como resultado, salía basura. + + ## Unicode y UTF-8. El fin del desorden + Para arreglarlo todo, en la década de 1990 se empezó a crear la tabla universal Unicode, que contiene los caracteres de todos los sistemas de escritura del mundo, entre ellos el alfabeto latino y el cirílico, la escritura china y árabe, los signos matemáticos, la escritura del antiguo Egipto e incluso los emojis. - Encuentra una tabla de códigos ASCII en Internet. Puedes usar búsquedas como "tabla de códigos ASCII" o "ascii codes table". Por lo general, en estas tablas los códigos se muestran en varios sistemas de numeración: decimal, binario, octal y hexadecimal. Nos interesa el código decimal (*dec* o *decimal*). + Dentro de Unicode hay varios formatos de almacenamiento. El más extendido de ellos es UTF-8. Codifica de forma compacta los caracteres ingleses, pero puede ampliarse para cualquier otro. - Utilizando el ejemplo anterior y la tabla que encontraste, muestra en pantalla los caracteres `~`, `^` y `%` (cada uno en su propia línea). + Hoy en día, UTF-8 es el estándar por defecto en internet, JavaScript, Linux, las bases de datos y los editores de código. - (Por supuesto, puedes "engañar" las pruebas y simplemente hacer algo como `console.log('~')`, pero eso no sería interesante :) + ## ¿Por qué debe saber esto un programador? + + - Vas a trabajar con texto, y los errores de codificación siguen ocurriendo, especialmente al leer archivos, procesar datos, interactuar con APIs y bases de datos. + - JavaScript usa Unicode para las cadenas por defecto. + - Hay que saber diagnosticar los problemas. Por ejemplo, si ves "caracteres ilegibles", casi con seguridad es un error de codificación. + +instructions: | + + El programa recibe los códigos numéricos de los caracteres y los muestra en pantalla: esto es útil cuando un carácter es difícil de escribir con el teclado. Encuentra los caracteres con los códigos 126, 94 y 37 en la tabla ASCII y muestra cada uno en una línea distinta con la función `String.fromCharCode()`. + + ```javascript + console.log(String.fromCharCode(...)); + console.log(String.fromCharCode(...)); + console.log(String.fromCharCode(...)); + ``` + + Por ejemplo, el carácter `?` tiene el código 63: + + ```javascript + console.log(String.fromCharCode(63)); // salida: ? + ``` tips: - | - [¿Qué son las codificaciones?](https://codica.la/guides/encoding) - + [¿Qué son las codificaciones?](https://guides.hexlet.io/es/encoding/) definitions: - name: Codificación - description: "conjunto de caracteres codificados con números para representar texto en formato electrónico." + description: >- + conjunto de caracteres codificados con números para representar texto en + formato electrónico. diff --git a/modules/25-strings/30-encoding/en/EXERCISE.md b/modules/25-strings/30-encoding/en/EXERCISE.md index c27df311..3b7880ea 100644 --- a/modules/25-strings/30-encoding/en/EXERCISE.md +++ b/modules/25-strings/30-encoding/en/EXERCISE.md @@ -1,14 +1,13 @@ - -In JavaScript you can "query" and print any ASCII character. For example: +The program receives the numeric codes of characters and prints them to the screen — this is convenient when a character is hard to type on the keyboard. Find the characters with codes 126, 94, and 37 in the ASCII table and print each on a separate line using the `String.fromCharCode()` function. ```javascript -console.log(String.fromCharCode(63)); +console.log(String.fromCharCode(...)); +console.log(String.fromCharCode(...)); +console.log(String.fromCharCode(...)); ``` -Character 63 will be printed - a question mark. You can print any character this way. - -Find an ASCII table on the internet. You can use queries like "ASCII codes table" or "ASCII codes". Generally, these tables give codes in several number systems: decimal, binary, octal and hexadecimal. We are interested in the decimal code (*dec* or *decimal*). - -Using the example above and the table you found, print the characters `~`, `^` and `%` (each on their own line). +For example, the `?` character has code 63: -(Of course, you could cheat and just do something like `console.log('~')`, but that would be no fun at all :) +```javascript +console.log(String.fromCharCode(63)); // output: ? +``` diff --git a/modules/25-strings/30-encoding/en/README.md b/modules/25-strings/30-encoding/en/README.md index 1567833c..cd436522 100644 --- a/modules/25-strings/30-encoding/en/README.md +++ b/modules/25-strings/30-encoding/en/README.md @@ -1,37 +1,77 @@ +At the most basic level, a computer works only with zeros and ones, which make up what is called binary code. Each one or zero is called a bit (from binary digit). -At machine level, the computer operates only with the numbers `0` and `1`. This is called [binary code](https://en.wikipedia.org/wiki/Binary_code), the ones and zeros are called bits, which is derived from the term "binary digit". +Any data in a computer is represented simply as a sequence of bits, for example images, music, and text. The familiar numbers from the decimal system can also be represented in binary form. -The numbers that we usually use in the decimal system are encoded using binary numbers: +- 0 → `0` +- 1 → `1` +- 2 → `10` -- 0 ← 0 -- 1 ← 1 -- 2 ← 10 -- 3 ← 11 -- 4 ← 100 -- 5 ← 101 +## How to encode text? -But does it deal with text? The computer isn't aware of letters, punctuation, and other text characters. All these characters are encoded by numbers too. +A computer does not "understand" text. To work with letters and other characters, they also need to be turned into numbers. This is done using encodings, that is, tables in which each character corresponds to a specific number. -We can take the English alphabet and give each letter a number, starting with one: +The simplest way is to number the letters, starting from 1. -- a ← 1 -- b ← 2 -- c ← 3 -- d ← 4 -- ... -- z ← 26 +- `a` → `1` +- `b` → `2` +- ...and so on up to `z` → `26` -Then you can teach the computer to understand this table and translate text into numbers and vice versa: +Now we can represent the word `hello` as a set of numbers. -- `hello` → `8` `5` `12` `12` `15` -- `7` `15` `15` `4` → `good` +```text +h e l l o +↓ ↓ ↓ ↓ ↓ +8 5 12 12 15 +``` -These tables that match letters and numbers are called encodings. Besides letters of the alphabet, encoding tables include punctuation marks and other useful characters. You've probably come across such encodings as [ASCII](https://en.wikipedia.org/wiki/ASCII) or [UTF-8](https://en.wikipedia.org/wiki/UTF-8). +And `good` turns into the following sequence. -Different encodings have different numbers of characters. At first, small tables like ASCII were enough for programmers. But they usually contain only Latin letters, a few simple characters like `%` and `?`, and special control characters like newline (/n). +```text +g o o d +↓ ↓ ↓ ↓ +7 15 15 4 +``` -With the development of computers, different countries needed their own comprehensive tables. Including Cyrillic letters, hieroglyphs, Arabic script, additional mathematical and typographic characters, and even emojis as time went on. +The program does not know that this is a word. It simply sees the instruction "display the character with code 8, then the one with code 5, and so on". -One [Unicode standards](https://en.wikipedia.org/wiki/Unicode) standard in particular, *utf-8*, is the one used in most cases today. It includes characters from almost all the written languages found in the world. Therefore, a letter written by someone from China in Chinese can easily be opened and read natively on a computer in Finland (whether the reader would understand it or not is another question). +## ASCII. The first mass encoding -Programmers have to deal with encodings regularly. Unicode support in different programming languages is carried out on a different level. Moreover, encodings must be declared when working with databases and files. +The first computers worked mostly with the English language. For it, in the 1960s the ASCII table was invented, including 128 characters, among them the Latin alphabet, digits, punctuation marks, special characters (`@`, `#`, `!`, `\n`), and control codes. + +This was enough for the first programs, but not for the whole world. + +When computers began to be used in other countries, a problem arose. ASCII has no Cyrillic, hieroglyphs, Arabic script, accents, currency symbols, and so on. + +Each country or company started making its own encoding based on ASCII. + +- Windows came up with Windows-1251 for Russian +- Apple created Mac Roman +- Countries in Eastern Europe, Asia, and the Middle East developed their own variants + +All these encodings were incompatible with each other. Code 226 in one encoding could be the letter é, in another a different letter, and in a third some technical character altogether. This led to real chaos. + +## What encoding problems looked like + +If you see this in a text. + +```text +ÐÑивеÑ! +``` + +It means that the program incorrectly determined the encoding of the text. It received a sequence of bytes but read them with the wrong table. + +This was the norm in the 1990s and 2000s. One program wrote text in Windows-1251, another read it as ISO-8859-1, and the result was garbage. + +## Unicode and UTF-8. The end of the mess + +To fix everything, in the 1990s work began on creating the universal Unicode table, which contains the characters of all the writing systems of the world, among them the Latin alphabet and Cyrillic, Chinese and Arabic script, mathematical signs, ancient Egyptian writing, and even emoji. + +Inside Unicode there are several storage formats. The most widespread of them is UTF-8. It compactly encodes English characters but can expand to fit any others. + +Today UTF-8 is the default standard on the internet, in JavaScript, Linux, databases, and code editors. + +## Why should a programmer know this? + +- You will work with text, and encoding errors still happen, especially when reading files, processing data, interacting with APIs and databases. +- JavaScript uses Unicode for strings by default. +- You need to be able to diagnose problems. For example, if you see "gibberish", it is almost certainly an encoding error. diff --git a/modules/25-strings/30-encoding/en/data.yml b/modules/25-strings/30-encoding/en/data.yml index b4104721..895accc0 100644 --- a/modules/25-strings/30-encoding/en/data.yml +++ b/modules/25-strings/30-encoding/en/data.yml @@ -1,5 +1,10 @@ --- name: Encoding +tips: + - | + [What are encodings?](https://guides.hexlet.io/en/encoding/) definitions: - name: Encoding - description: is a set of characters encoded using numbers to represent text digitally. + description: >- + a set of characters encoded using numbers to represent text in electronic + form. diff --git a/modules/25-strings/30-encoding/es/EXERCISE.md b/modules/25-strings/30-encoding/es/EXERCISE.md index 63926f17..ec02c199 100644 --- a/modules/25-strings/30-encoding/es/EXERCISE.md +++ b/modules/25-strings/30-encoding/es/EXERCISE.md @@ -1,14 +1,13 @@ - -En JavaScript, puedes "solicitar" y mostrar en pantalla cualquier carácter de la codificación ASCII. Por ejemplo: +El programa recibe los códigos numéricos de los caracteres y los muestra en pantalla: esto es útil cuando un carácter es difícil de escribir con el teclado. Encuentra los caracteres con los códigos 126, 94 y 37 en la tabla ASCII y muestra cada uno en una línea distinta con la función `String.fromCharCode()`. ```javascript -console.log(String.fromCharCode(63)); +console.log(String.fromCharCode(...)); +console.log(String.fromCharCode(...)); +console.log(String.fromCharCode(...)); ``` -Esto mostrará en pantalla el carácter con el número 63, que es el signo de interrogación `?`. De esta manera, puedes mostrar cualquier carácter. - -Encuentra una tabla de códigos ASCII en Internet. Puedes usar búsquedas como "tabla de códigos ASCII" o "ascii codes table". Por lo general, en estas tablas los códigos se muestran en varios sistemas de numeración: decimal, binario, octal y hexadecimal. Nos interesa el código decimal (*dec* o *decimal*). - -Utilizando el ejemplo anterior y la tabla que encontraste, muestra en pantalla los caracteres `~`, `^` y `%` (cada uno en su propia línea). +Por ejemplo, el carácter `?` tiene el código 63: -(Por supuesto, puedes "engañar" las pruebas y simplemente hacer algo como `console.log('~')`, pero eso no sería interesante :) +```javascript +console.log(String.fromCharCode(63)); // salida: ? +``` diff --git a/modules/25-strings/30-encoding/es/README.md b/modules/25-strings/30-encoding/es/README.md index 3e368921..b85f21fa 100644 --- a/modules/25-strings/30-encoding/es/README.md +++ b/modules/25-strings/30-encoding/es/README.md @@ -1,37 +1,77 @@ +En el nivel más básico, una computadora trabaja únicamente con ceros y unos, lo que constituye el llamado código binario. Cada uno o cero se denomina bit (de binary digit, "dígito binario"). -En el nivel más profundo, una computadora opera exclusivamente con los dígitos `0` y `1`. Esto se conoce como [código binario](https://es.wikipedia.org/wiki/C%C3%B3digo_binario), y los unos y ceros se llaman bits, que es una abreviatura de "binary digit" (dígito binario). +Cualquier dato en una computadora se representa simplemente como una secuencia de bits, por ejemplo imágenes, música y texto. Los números habituales del sistema decimal también pueden representarse en forma binaria. -Los números que estamos acostumbrados a utilizar en el sistema decimal se codifican utilizando números binarios: +- 0 → `0` +- 1 → `1` +- 2 → `10` -- 0 ← 0 -- 1 ← 1 -- 2 ← 10 -- 3 ← 11 -- 4 ← 100 -- 5 ← 101 +## ¿Cómo codificar texto? -Pero, ¿qué pasa con el texto? En realidad, la computadora no sabe nada acerca de letras, signos de puntuación y otros caracteres de texto. Todos estos caracteres también se codifican con números. +Una computadora no "entiende" el texto. Para trabajar con letras y otros caracteres, también hay que convertirlos en números. Esto se hace mediante codificaciones, es decir, tablas en las que a cada carácter le corresponde un número determinado. -Podemos tomar el alfabeto inglés y asignar un número a cada letra, comenzando desde uno en orden: +La forma más sencilla consiste en numerar las letras, empezando por 1. -- a ← 1 -- b ← 2 -- c ← 3 -- d ← 4 -- ... -- z ← 26 +- `a` → `1` +- `b` → `2` +- ...y así hasta `z` → `26` -Luego, podemos enseñarle a la computadora a entender esta tabla y convertir texto en números y viceversa: +Ahora podemos representar la palabra `hello` como un conjunto de números. -- `hello` → `8` `5` `12` `12` `15` -- `7` `15` `15` `4` → `good` +```text +h e l l o +↓ ↓ ↓ ↓ ↓ +8 5 12 12 15 +``` -Estas tablas que relacionan letras y números se llaman codificaciones. Además de las letras del alfabeto, las tablas de codificación incluyen signos de puntuación y otros caracteres útiles. Seguramente has encontrado codificaciones como [ASCII](https://es.wikipedia.org/wiki/ASCII) o [UTF-8](https://es.wikipedia.org/wiki/UTF-8). +Y `good` se convierte en la siguiente secuencia. -Las diferentes codificaciones contienen diferentes conjuntos de caracteres. Inicialmente, tablas pequeñas como ASCII eran suficientes para la mayoría de las tareas. Sin embargo, esta solamente contiene letras latinas, algunos caracteres simples como `%` y `?`, y caracteres de control especiales como el salto de línea. +```text +g o o d +↓ ↓ ↓ ↓ +7 15 15 4 +``` -Con la proliferación de las computadoras, diferentes países necesitaron sus propias tablas más amplias. Esto incluye letras cirílicas, caracteres chinos, árabe, matemáticos y tipográficos adicionales, e incluso emojis. +El programa no sabe que esto es una palabra. Simplemente ve la instrucción "hay que mostrar el carácter con el código 8, luego el de código 5, etc.". -Hoy en día, en la mayoría de los casos se utiliza una de las variantes de [Unicode](https://es.wikipedia.org/wiki/Unicode) - *utf-8*. Esta incluye caracteres de casi todos los idiomas escritos del mundo. Gracias a esto, un correo electrónico escrito en chino en China se puede abrir y ver sin problemas en una computadora en Finlandia (si lo entiende o no, es otra cuestión). +## ASCII. La primera codificación masiva -Los programadores se encuentran regularmente con la codificación de texto y las codificaciones en su vida. El soporte de Unicode en diferentes lenguajes de programación se implementa a diferentes niveles. Además, las codificaciones deben especificarse explícitamente al trabajar con bases de datos y archivos. +Las primeras computadoras trabajaban principalmente con el idioma inglés. Para él, en la década de 1960 se inventó la tabla ASCII, que incluía 128 caracteres, entre ellos el alfabeto latino, los dígitos, los signos de puntuación, los caracteres especiales (`@`, `#`, `!`, `\n`) y los códigos de control. + +Esto bastaba para los primeros programas, pero no para todo el mundo. + +Cuando las computadoras empezaron a usarse en otros países, surgió un problema. En ASCII no hay cirílico, ideogramas, escritura árabe, acentos, símbolos de moneda, etc. + +Cada país o empresa empezó a crear su propia codificación basada en ASCII. + +- Windows ideó Windows-1251 para el ruso +- Apple creó Mac Roman +- Los países de Europa del Este, Asia y Oriente Medio desarrollaron sus propias variantes + +Todas estas codificaciones eran incompatibles entre sí. El código 226 en una codificación podía ser la letra é, en otra una letra distinta, y en una tercera incluso un carácter técnico. Esto provocaba un verdadero caos. + +## Cómo se veían los problemas con las codificaciones + +Si ves esto en un texto. + +```text +ÐÑивеÑ! +``` + +Significa que el programa determinó incorrectamente la codificación del texto. Recibió una secuencia de bytes, pero los leyó con la tabla equivocada. + +Esto era lo habitual en las décadas de 1990 y 2000. Un programa escribía el texto en Windows-1251, otro lo leía como ISO-8859-1 y, como resultado, salía basura. + +## Unicode y UTF-8. El fin del desorden + +Para arreglarlo todo, en la década de 1990 se empezó a crear la tabla universal Unicode, que contiene los caracteres de todos los sistemas de escritura del mundo, entre ellos el alfabeto latino y el cirílico, la escritura china y árabe, los signos matemáticos, la escritura del antiguo Egipto e incluso los emojis. + +Dentro de Unicode hay varios formatos de almacenamiento. El más extendido de ellos es UTF-8. Codifica de forma compacta los caracteres ingleses, pero puede ampliarse para cualquier otro. + +Hoy en día, UTF-8 es el estándar por defecto en internet, JavaScript, Linux, las bases de datos y los editores de código. + +## ¿Por qué debe saber esto un programador? + +- Vas a trabajar con texto, y los errores de codificación siguen ocurriendo, especialmente al leer archivos, procesar datos, interactuar con APIs y bases de datos. +- JavaScript usa Unicode para las cadenas por defecto. +- Hay que saber diagnosticar los problemas. Por ejemplo, si ves "caracteres ilegibles", casi con seguridad es un error de codificación. diff --git a/modules/25-strings/30-encoding/es/data.yml b/modules/25-strings/30-encoding/es/data.yml index 33f588c3..6d20ad42 100644 --- a/modules/25-strings/30-encoding/es/data.yml +++ b/modules/25-strings/30-encoding/es/data.yml @@ -2,7 +2,7 @@ name: Codificación tips: - | - [¿Qué son las codificaciones?](https://codica.la/guides/encoding) + [¿Qué son las codificaciones?](https://guides.hexlet.io/es/encoding/) definitions: - name: Codificación description: >- diff --git a/modules/30-variables/10-definition/description.es.yml b/modules/30-variables/10-definition/description.es.yml index 4f695ab3..1e34f6a4 100644 --- a/modules/30-variables/10-definition/description.es.yml +++ b/modules/30-variables/10-definition/description.es.yml @@ -3,57 +3,158 @@ name: ¿Qué es una variable? theory: | - Imagina que tienes la tarea de imprimir en la pantalla la frase *¡Father!* dos veces, o incluso cinco veces. Puedes resolver este problema de manera directa: + Imagina que necesitas imprimir la frase `Father!` dos veces: ```javascript console.log('Father!'); console.log('Father!'); ``` - En el caso más simple, esto funciona bien. Sin embargo, si la frase *¡Father!* se utiliza con más frecuencia, y en diferentes partes del programa, tendrás que repetirla en todas partes. Los problemas con este enfoque comienzan cuando necesitas cambiar la frase, lo cual ocurre con bastante frecuencia. Tendrás que encontrar todos los lugares donde se utiliza la frase *¡Father!* y realizar el cambio necesario. Pero hay otra forma de hacerlo. En lugar de copiar nuestra expresión, simplemente podemos crear una variable con esta frase. + Este enfoque funciona bien si la frase aparece solo un par de veces. Pero ¿qué pasa si se utiliza con frecuencia, en diferentes partes del programa? Entonces tendrías que copiar la misma expresión una y otra vez. + + ¿Y qué ocurre si necesitas cambiar la frase, por ejemplo reemplazar _Father!_ por _Mother!_? Tendrías que buscar y corregir todas las apariciones a mano. Esto es incómodo y conduce a errores. + + ## Variables + + Para no duplicar la misma cadena, puedes guardarla en una variable e imprimir su contenido: ```javascript - // greeting - se traduce como saludo - let greeting = '¡Father!'; - console.log(greeting); // => Father! - console.log(greeting); // => Father! + const greeting = 'Father!'; + + console.log(greeting); + console.log(greeting); + ``` + + Resultado: + + ```text + Father! + Father! + ``` + + Una **variable** es un nombre detrás del cual se almacena un valor. En nuestro ejemplo creamos una variable llamada `greeting` y escribimos en ella la cadena `'Father!'`. + + ```text + const greeting = 'Father!'; + + Variable Valor + ┌──────────┐ ┌──────────┐ + │ greeting │ ──→ │ 'Father!'│ + └──────────┘ └──────────┘ + ``` + + La línea `const greeting = 'Father!'` se lee así: «toma el valor `'Father!'` y asígnalo a la variable llamada `greeting`». El signo `=` aquí es el operador de asignación, no una notación de igualdad como en matemáticas. Coloca el valor en la variable. + + Cuando escribimos `console.log(greeting)`, el motor sustituye el nombre `greeting` por el valor almacenado en ella. Como resultado, la cadena `'Father!'` se imprime en la pantalla. + + ```text + console.log(greeting) + | + v + console.log('Father!') ``` - Una variable apunta a los datos que se le han asignado. Gracias a esto, los datos se pueden utilizar múltiples veces sin necesidad de duplicarlos constantemente. La variable en sí se crea y se llena con datos (se inicializa) utilizando la instrucción `let greeting = 'Father!'`. + ## let y const - Para el nombre de la variable, se puede utilizar cualquier conjunto de caracteres permitidos, que incluyen letras del alfabeto inglés, números, así como los símbolos *_* y *$*. Sin embargo, no se puede colocar un número al principio. Los nombres de las variables distinguen entre mayúsculas y minúsculas, es decir, `hello` y `heLLo` son dos nombres diferentes, y por lo tanto, dos variables diferentes. En JavaScript, el registro es importante, nunca lo olvides. + En JavaScript, una variable debe declararse antes de usarse con una de las palabras clave — `const` o `let`: - No es necesario inicializar una variable con datos al momento de declararla. A veces, es necesario crearla y luego llenarla más adelante: + - `const` — para valores que no van a cambiar; + - `let` — para valores que pueden cambiar durante la ejecución del programa. ```javascript - let greeting; + const greeting = 'Father!'; // no cambiará + let score = 0; // cambiará a medida que se ejecuta el programa + ``` + + Si no sabes si el valor cambiará, usa `const`. Esta es una buena práctica: el código es más fácil de leer y más difícil de dañar accidentalmente. Volveremos a `let` y a las constantes en lecciones separadas. + + ## Nombres de variables - // Uso - console.log(greeting); // undefined + El programador es quien inventa los nombres de las variables. En JavaScript puedes usar: - // Cambiar la variable en la siguiente lección + - letras latinas (a-z, A-Z), + - dígitos (pero no al principio), + - los símbolos `_` y `$`. + + Ejemplos de nombres válidos: `greeting`, `name1`, `helloWorld`. JavaScript distingue entre letras minúsculas y mayúsculas. Las variables `greeting`, `Greeting` y `GREETING` son tres variables diferentes. + + ## Variables y literales + + En el código es importante distinguir dónde usamos una variable y dónde escribimos un valor directamente. Esto es especialmente notable en el ejemplo con `console.log()`: + + ```javascript + const greeting = 'Mother!'; + console.log(greeting); // => Mother! + console.log('greeting'); // => greeting ``` - Una variable declarada pero no inicializada contiene el valor `undefined`. Este es un valor especial que se utiliza cuando nada está definido. + En el primer caso se usa la **variable** `greeting`, y el programa sustituye su valor. En el segundo caso `'greeting'` está entre comillas, por lo que es un **literal de cadena**, es decir, un valor ya hecho escrito directamente en el código. Aunque vemos la palabra `greeting` en ambos casos, desde el punto de vista del motor son cosas completamente diferentes. + + Los literales son datos escritos explícitamente (por ejemplo, `'Hello'`, `42`, `3.14`). Los identificadores son los nombres de variables y funciones (por ejemplo, `greeting`, `console`) que apuntan a valores o comandos ya existentes. - No hay límite en la cantidad de variables que se pueden crear, los programas grandes contienen decenas o incluso cientos de miles de nombres de variables: + ## Orden de uso + + Una variable primero debe crearse (declararse y asignarle un valor), y solo después usarse. Si intentas acceder a una variable antes de crearla, el programa lanzará un error: + + ```javascript + console.log(name); // Error: la variable aún no está definida + // ReferenceError: Cannot access 'name' before initialization + const name = 'Alice'; + ``` + + Pero en el orden correcto todo funciona: + + ```javascript + const name = 'Alice'; + console.log(name); // => Alice + ``` + + ## Varias variables en un programa + + En un solo programa puedes crear tantas variables como quieras. Cada una almacena sus propios datos y no interfiere con las demás: ```javascript - let greeting1 = 'Father!'; + const greeting1 = 'Father!'; console.log(greeting1); console.log(greeting1); - let greeting2 = 'Mother!'; + const greeting2 = 'Mother!'; console.log(greeting2); console.log(greeting2); ``` + ¿Cómo saber cuándo se necesitan varias variables? La cantidad de variables depende de la lógica del programa. Este tema se trata en detalle más adelante, cuando nos encontremos con las funciones y las construcciones condicionales. + + ## Dónde crear variables + + Los programadores intentan crear variables cerca del lugar donde se usan. Esto hace que el código sea más legible. Esto es especialmente importante en programas grandes, donde puede haber decenas y cientos de miles de variables. + + ## Errores al trabajar con variables + + El orden de las instrucciones en el código con variables es de enorme importancia. Una variable debe definirse antes de usarse. A continuación se muestra un ejemplo de un error que los principiantes cometen muy a menudo: + + ```javascript + // Uncaught ReferenceError: greeting is not defined + console.log(greeting); + let greeting = 'Father!'; + ``` + + La ejecución de un programa con el código del ejemplo anterior termina con el error `ReferenceError: greeting is not defined`. `ReferenceError` es un error de referencia. Significa que el código usa un nombre (identificador) que no está definido. El mensaje lo dice directamente: `greeting is not defined`. + + Además del orden incorrecto de definición, en JavaScript también se dan erratas banales — tanto al usar una variable como al declararla. La cantidad de errores de este tipo se reduce con un editor configurado correctamente: resalta los nombres que se usan sin declaración y advierte sobre posibles problemas. + + Otro error común es intentar declarar una variable ya declarada con `let`: + + ```javascript + let greeting = 'Father!'; + let greeting = 'Father!'; // SyntaxError: Identifier 'greeting' has already been declared + ``` - Para facilitar el análisis del programa, se recomienda crear variables lo más cerca posible del lugar donde se utilizan. + No se puede declarar una variable dos veces. Si necesitas un valor diferente — crea una nueva variable con un nombre diferente, o simplemente reasigna el valor de una variable `let` existente sin la palabra clave. instructions: | - Crea una variable llamada `motto` con el contenido `What Is Dead May Never Die!`. Imprime el contenido de la variable. + Crea una variable llamada `url` con el valor `https://hexlet.io`. Imprime el valor de esta variable en la pantalla dos veces. tips: - | diff --git a/modules/30-variables/10-definition/en/EXERCISE.md b/modules/30-variables/10-definition/en/EXERCISE.md index 928a5ab8..be0db1eb 100644 --- a/modules/30-variables/10-definition/en/EXERCISE.md +++ b/modules/30-variables/10-definition/en/EXERCISE.md @@ -1,2 +1 @@ - -Create a variable with the name `motto` containing `What Is Dead May Never Die!`. Print its contents. +Create a variable named `url` with the value `https://hexlet.io`. Print the value of this variable to the screen twice. diff --git a/modules/30-variables/10-definition/en/README.md b/modules/30-variables/10-definition/en/README.md index 502ffe2f..343d0b8f 100644 --- a/modules/30-variables/10-definition/en/README.md +++ b/modules/30-variables/10-definition/en/README.md @@ -1,46 +1,148 @@ - -Consider this task: we need to print the phrase _Father!_ two times or even five times. You can solve it via brute force: +Imagine you need to print the phrase `Father!` twice: ```javascript console.log('Father!'); console.log('Father!'); ``` -This will do for the most basic case, but if you use the phrase _Father!_ more often and in different parts of your code, you have to repeat it everywhere. Then you will face even more issues when it turns out that you need to change the phrase. This is a common scenario in development. We have to find all the occurrences of the phrase _Father!_ and make all the required changes. There is one other way to do it. Instead of copying our expression, just create a variable containing this phrase. +This approach works fine if the phrase appears just a couple of times. But what if it is used often, in different parts of the program? Then you would have to copy the same expression over and over. + +And what happens if the phrase needs to change, for example replacing _Father!_ with _Mother!_? You would have to find and fix every occurrence by hand. This is inconvenient and leads to errors. + +## Variables + +To avoid duplicating the same string, you can store it in a variable and print its contents: ```javascript -let greeting = 'Father!'; -console.log(greeting); // => Father! -console.log(greeting); // => Father! +const greeting = 'Father!'; + +console.log(greeting); +console.log(greeting); +``` + +Result: + +```text +Father! +Father! +``` + +A **variable** is a name behind which a value is stored. In our example we created a variable named `greeting` and wrote the string `'Father!'` into it. + +```text +const greeting = 'Father!'; + +Variable Value +┌──────────┐ ┌──────────┐ +│ greeting │ ──→ │ 'Father!'│ +└──────────┘ └──────────┘ +``` + +The line `const greeting = 'Father!'` reads as follows: "take the value `'Father!'` and assign it to the variable named `greeting`". The `=` sign here is the assignment operator, not a notation for equality as in mathematics. It puts the value into the variable. + +When we write `console.log(greeting)`, the engine substitutes the name `greeting` with the value stored in it. As a result, the string `'Father!'` is printed to the screen. + +```text +console.log(greeting) + | + v +console.log('Father!') +``` + +## let and const + +In JavaScript, a variable must be declared before use with one of the keywords — `const` or `let`: + +- `const` — for values that will not change; +- `let` — for values that may change during the program's execution. + +```javascript +const greeting = 'Father!'; // will not change +let score = 0; // will change as the program runs +``` + +If you do not know whether the value will change, use `const`. This is good practice: the code is easier to read and harder to accidentally corrupt. We will return to `let` and constants in separate lessons. + +## Variable names + +The programmer comes up with the variable names. In JavaScript you can use: + +- Latin letters (a-z, A-Z), +- digits (but not at the beginning), +- the `_` and `$` symbols. + +Examples of valid names: `greeting`, `name1`, `helloWorld`. JavaScript distinguishes between lowercase and uppercase letters. The variables `greeting`, `Greeting`, and `GREETING` are three different variables. + +## Variables and literals + +In code it is important to distinguish where we use a variable and where we write a value directly. This is especially noticeable in the example with `console.log()`: + +```javascript +const greeting = 'Mother!'; +console.log(greeting); // => Mother! +console.log('greeting'); // => greeting ``` -A variable points to data that it stores. It allows you to use the data multiple times without duplicating it. The variable is created and filled with data (initialized) using the statement `let greeting = 'Father!'`. +In the first case the **variable** `greeting` is used, and the program substitutes its value. In the second case `'greeting'` is enclosed in quotes, so it is a **string literal**, that is, a ready-made value written directly in the code. Even though we see the word `greeting` in both cases, from the engine's point of view these are completely different things. -The variable name can consist of characters from any valid character set including English letters and numbers as well as *_* and *$* signs. Note that you can't place a digit at the beginning of a name. Variable names are case-sensitive, which means that `hello` and `heLLo` are two different names and thus two distinct variables. Case is really important in JavaScript, so never forget it. +Literals are data written explicitly (for example, `'Hello'`, `42`, `3.14`). Identifiers are the names of variables and functions (for example, `greeting`, `console`) that point to already existing values or commands. -You don't have to initialize the variable with data when declaring it. Sometimes you may want to create a variable and fill it later: +## Order of use + +A variable must first be created (declared and assigned a value), and only then used. If you try to access a variable before it is created, the program will throw an error: ```javascript -let greeting; +console.log(name); // Error: the variable is not yet defined +// ReferenceError: Cannot access 'name' before initialization +const name = 'Alice'; +``` -// Usage -console.log(greeting); // undefined +But in the correct order everything works: -// We'll learn about changing a variable in the next lesson +```javascript +const name = 'Alice'; +console.log(name); // => Alice ``` -A declared but uninitialized variable contains an `undefined` value. This is a special value used when nothing is defined. +## Multiple variables in a program -You can create any number of variables. Large programs contain dozens or hundreds of thousands of variable names: +In a single program you can create as many variables as you like. Each one stores its own data and does not interfere with the others: ```javascript -let greeting1 = 'Father!'; +const greeting1 = 'Father!'; console.log(greeting1); console.log(greeting1); -let greeting2 = 'Mother!'; +const greeting2 = 'Mother!'; console.log(greeting2); console.log(greeting2); ``` -For the sake of the code analysis, it's common to create variables near the place they are used. +How do you know when you need several variables? The number of variables depends on the program's logic. This topic is covered in detail later, when we encounter functions and conditional constructs. + +## Where to create variables + +Programmers try to create variables close to where they are used. This makes the code more readable. This is especially important in large programs, where there can be tens and hundreds of thousands of variables. + +## Errors when working with variables + +The order of statements in code with variables is hugely important. A variable must be defined before it is used. Below is an example of an error that beginners very often make: + +```javascript +// Uncaught ReferenceError: greeting is not defined +console.log(greeting); +let greeting = 'Father!'; +``` + +Running a program with the code from the example above ends with the error `ReferenceError: greeting is not defined`. `ReferenceError` is a reference error. It means that the code uses a name (identifier) that is not defined. The message says so directly: `greeting is not defined`. + +In addition to the wrong order of definition, JavaScript also has plain typos — both when using a variable and when declaring it. The number of such errors is reduced by a properly configured editor: it highlights names that are used without declaration and warns about possible problems. + +Another common error is trying to declare an already declared variable with `let`: + +```javascript +let greeting = 'Father!'; +let greeting = 'Father!'; // SyntaxError: Identifier 'greeting' has already been declared +``` + +You cannot declare a variable twice. If you need a different value — create a new variable with a different name, or simply reassign the value of an existing `let` variable without the keyword. diff --git a/modules/30-variables/10-definition/en/data.yml b/modules/30-variables/10-definition/en/data.yml index 7f2f3547..ac7086e2 100644 --- a/modules/30-variables/10-definition/en/data.yml +++ b/modules/30-variables/10-definition/en/data.yml @@ -1,8 +1,9 @@ --- name: What is a variable tips: - - > + - | [let](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) definitions: - name: Variable - description: is a way to save data under a name for later use in code. + description: | + a way to store information and give it a name for later use in code. diff --git a/modules/30-variables/10-definition/es/EXERCISE.md b/modules/30-variables/10-definition/es/EXERCISE.md index 44e85681..77a2a701 100644 --- a/modules/30-variables/10-definition/es/EXERCISE.md +++ b/modules/30-variables/10-definition/es/EXERCISE.md @@ -1,2 +1 @@ - -Crea una variable llamada `motto` con el contenido `What Is Dead May Never Die!`. Imprime el contenido de la variable. +Crea una variable llamada `url` con el valor `https://hexlet.io`. Imprime el valor de esta variable en la pantalla dos veces. diff --git a/modules/30-variables/10-definition/es/README.md b/modules/30-variables/10-definition/es/README.md index abe2134d..4aae2c56 100644 --- a/modules/30-variables/10-definition/es/README.md +++ b/modules/30-variables/10-definition/es/README.md @@ -1,47 +1,148 @@ - -Imagina que tienes la tarea de imprimir en la pantalla la frase *¡Father!* dos veces, o incluso cinco veces. Puedes resolver este problema de manera directa: +Imagina que necesitas imprimir la frase `Father!` dos veces: ```javascript console.log('Father!'); console.log('Father!'); ``` -En el caso más simple, esto funciona bien. Sin embargo, si la frase *¡Father!* se utiliza con más frecuencia, y en diferentes partes del programa, tendrás que repetirla en todas partes. Los problemas con este enfoque comienzan cuando necesitas cambiar la frase, lo cual ocurre con bastante frecuencia. Tendrás que encontrar todos los lugares donde se utiliza la frase *¡Father!* y realizar el cambio necesario. Pero hay otra forma de hacerlo. En lugar de copiar nuestra expresión, simplemente podemos crear una variable con esta frase. +Este enfoque funciona bien si la frase aparece solo un par de veces. Pero ¿qué pasa si se utiliza con frecuencia, en diferentes partes del programa? Entonces tendrías que copiar la misma expresión una y otra vez. + +¿Y qué ocurre si necesitas cambiar la frase, por ejemplo reemplazar _Father!_ por _Mother!_? Tendrías que buscar y corregir todas las apariciones a mano. Esto es incómodo y conduce a errores. + +## Variables + +Para no duplicar la misma cadena, puedes guardarla en una variable e imprimir su contenido: ```javascript -// greeting - se traduce como saludo -let greeting = '¡Father!'; -console.log(greeting); // => Father! -console.log(greeting); // => Father! +const greeting = 'Father!'; + +console.log(greeting); +console.log(greeting); ``` -Una variable apunta a los datos que se le han asignado. Gracias a esto, los datos se pueden utilizar múltiples veces sin necesidad de duplicarlos constantemente. La variable en sí se crea y se llena con datos (se inicializa) utilizando la instrucción `let greeting = 'Father!'`. +Resultado: + +```text +Father! +Father! +``` -Para el nombre de la variable, se puede utilizar cualquier conjunto de caracteres permitidos, que incluyen letras del alfabeto inglés, números, así como los símbolos *_* y *$*. Sin embargo, no se puede colocar un número al principio. Los nombres de las variables distinguen entre mayúsculas y minúsculas, es decir, `hello` y `heLLo` son dos nombres diferentes, y por lo tanto, dos variables diferentes. En JavaScript, el registro es importante, nunca lo olvides. +Una **variable** es un nombre detrás del cual se almacena un valor. En nuestro ejemplo creamos una variable llamada `greeting` y escribimos en ella la cadena `'Father!'`. -No es necesario inicializar una variable con datos al momento de declararla. A veces, es necesario crearla y luego llenarla más adelante: +```text +const greeting = 'Father!'; + +Variable Valor +┌──────────┐ ┌──────────┐ +│ greeting │ ──→ │ 'Father!'│ +└──────────┘ └──────────┘ +``` + +La línea `const greeting = 'Father!'` se lee así: «toma el valor `'Father!'` y asígnalo a la variable llamada `greeting`». El signo `=` aquí es el operador de asignación, no una notación de igualdad como en matemáticas. Coloca el valor en la variable. + +Cuando escribimos `console.log(greeting)`, el motor sustituye el nombre `greeting` por el valor almacenado en ella. Como resultado, la cadena `'Father!'` se imprime en la pantalla. + +```text +console.log(greeting) + | + v +console.log('Father!') +``` + +## let y const + +En JavaScript, una variable debe declararse antes de usarse con una de las palabras clave — `const` o `let`: + +- `const` — para valores que no van a cambiar; +- `let` — para valores que pueden cambiar durante la ejecución del programa. ```javascript -let greeting; +const greeting = 'Father!'; // no cambiará +let score = 0; // cambiará a medida que se ejecuta el programa +``` + +Si no sabes si el valor cambiará, usa `const`. Esta es una buena práctica: el código es más fácil de leer y más difícil de dañar accidentalmente. Volveremos a `let` y a las constantes en lecciones separadas. + +## Nombres de variables -// Uso -console.log(greeting); // undefined +El programador es quien inventa los nombres de las variables. En JavaScript puedes usar: -// Cambiar la variable en la siguiente lección +- letras latinas (a-z, A-Z), +- dígitos (pero no al principio), +- los símbolos `_` y `$`. + +Ejemplos de nombres válidos: `greeting`, `name1`, `helloWorld`. JavaScript distingue entre letras minúsculas y mayúsculas. Las variables `greeting`, `Greeting` y `GREETING` son tres variables diferentes. + +## Variables y literales + +En el código es importante distinguir dónde usamos una variable y dónde escribimos un valor directamente. Esto es especialmente notable en el ejemplo con `console.log()`: + +```javascript +const greeting = 'Mother!'; +console.log(greeting); // => Mother! +console.log('greeting'); // => greeting ``` -Una variable declarada pero no inicializada contiene el valor `undefined`. Este es un valor especial que se utiliza cuando nada está definido. +En el primer caso se usa la **variable** `greeting`, y el programa sustituye su valor. En el segundo caso `'greeting'` está entre comillas, por lo que es un **literal de cadena**, es decir, un valor ya hecho escrito directamente en el código. Aunque vemos la palabra `greeting` en ambos casos, desde el punto de vista del motor son cosas completamente diferentes. + +Los literales son datos escritos explícitamente (por ejemplo, `'Hello'`, `42`, `3.14`). Los identificadores son los nombres de variables y funciones (por ejemplo, `greeting`, `console`) que apuntan a valores o comandos ya existentes. -No hay límite en la cantidad de variables que se pueden crear, los programas grandes contienen decenas o incluso cientos de miles de nombres de variables: +## Orden de uso + +Una variable primero debe crearse (declararse y asignarle un valor), y solo después usarse. Si intentas acceder a una variable antes de crearla, el programa lanzará un error: + +```javascript +console.log(name); // Error: la variable aún no está definida +// ReferenceError: Cannot access 'name' before initialization +const name = 'Alice'; +``` + +Pero en el orden correcto todo funciona: + +```javascript +const name = 'Alice'; +console.log(name); // => Alice +``` + +## Varias variables en un programa + +En un solo programa puedes crear tantas variables como quieras. Cada una almacena sus propios datos y no interfiere con las demás: ```javascript -let greeting1 = 'Father!'; +const greeting1 = 'Father!'; console.log(greeting1); console.log(greeting1); -let greeting2 = 'Mother!'; +const greeting2 = 'Mother!'; console.log(greeting2); console.log(greeting2); ``` -Para facilitar el análisis del programa, se recomienda crear variables lo más cerca posible del lugar donde se utilizan. +¿Cómo saber cuándo se necesitan varias variables? La cantidad de variables depende de la lógica del programa. Este tema se trata en detalle más adelante, cuando nos encontremos con las funciones y las construcciones condicionales. + +## Dónde crear variables + +Los programadores intentan crear variables cerca del lugar donde se usan. Esto hace que el código sea más legible. Esto es especialmente importante en programas grandes, donde puede haber decenas y cientos de miles de variables. + +## Errores al trabajar con variables + +El orden de las instrucciones en el código con variables es de enorme importancia. Una variable debe definirse antes de usarse. A continuación se muestra un ejemplo de un error que los principiantes cometen muy a menudo: + +```javascript +// Uncaught ReferenceError: greeting is not defined +console.log(greeting); +let greeting = 'Father!'; +``` + +La ejecución de un programa con el código del ejemplo anterior termina con el error `ReferenceError: greeting is not defined`. `ReferenceError` es un error de referencia. Significa que el código usa un nombre (identificador) que no está definido. El mensaje lo dice directamente: `greeting is not defined`. + +Además del orden incorrecto de definición, en JavaScript también se dan erratas banales — tanto al usar una variable como al declararla. La cantidad de errores de este tipo se reduce con un editor configurado correctamente: resalta los nombres que se usan sin declaración y advierte sobre posibles problemas. + +Otro error común es intentar declarar una variable ya declarada con `let`: + +```javascript +let greeting = 'Father!'; +let greeting = 'Father!'; // SyntaxError: Identifier 'greeting' has already been declared +``` + +No se puede declarar una variable dos veces. Si necesitas un valor diferente — crea una nueva variable con un nombre diferente, o simplemente reasigna el valor de una variable `let` existente sin la palabra clave. diff --git a/modules/30-variables/10-definition/es/data.yml b/modules/30-variables/10-definition/es/data.yml index 6788ff4d..b9b649e5 100644 --- a/modules/30-variables/10-definition/es/data.yml +++ b/modules/30-variables/10-definition/es/data.yml @@ -1,10 +1,9 @@ --- name: ¿Qué es una variable? tips: - - > + - | [let](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/let) definitions: - name: Variable - description: >- - una forma de almacenar información y darle un nombre para su uso posterior - en el código. + description: | + una forma de almacenar información y darle un nombre para su uso posterior en el código. diff --git a/modules/30-variables/11-change/description.es.yml b/modules/30-variables/11-change/description.es.yml index bd990b4d..54d9ef99 100644 --- a/modules/30-variables/11-change/description.es.yml +++ b/modules/30-variables/11-change/description.es.yml @@ -3,24 +3,69 @@ name: Cambio de variable theory: | - La palabra "variable" en sí misma indica que se puede cambiar. Y de hecho, con el tiempo, los valores de las variables pueden cambiar dentro de un programa. + La palabra misma "variable" sugiere que su valor puede cambiar. Esta es una de las principales razones por las que existen las variables. + + Aquí tienes un ejemplo sencillo: ```javascript + // greeting significa un saludo let greeting = 'Father!'; - console.log(greeting); - console.log(greeting); + console.log(greeting); // => Father! greeting = 'Mother!'; - console.log(greeting); - console.log(greeting); + console.log(greeting); // => Mother! + ``` + + Aquí primero guardamos una cadena (_Father!_) en la variable, y luego otra (_Mother!_). El nombre de la variable no cambió, pero el valor dentro de ella se volvió diferente. + + ```text + Antes: greeting ──→ 'Father!' + ╳ + Después: greeting ──→ 'Mother!' ``` + Ten en cuenta: la palabra clave `let` se escribe solo en la **primera** declaración de una variable. Al reasignarla, `let` ya no es necesaria — la variable ya existe, y solo estamos cambiando su valor. + + ## ¿Por qué cambiar un valor? + + En los programas reales, las variables cambian todo el tiempo. Aquí tienes algunas razones: - El nombre sigue siendo el mismo, pero los datos internos son diferentes. Presta atención a la diferencia clave entre la declaración de una variable y su cambio. La palabra clave `let` solo se utiliza al crear una variable, pero no se utiliza al cambiarla. + - El programa reacciona a las acciones del usuario. Por ejemplo, mientras introduces datos en un formulario de un sitio web, las variables que contienen estos datos se actualizan constantemente en ese momento. + - Resultados intermedios. A menudo los datos pasan por una serie de transformaciones, y en cada etapa una variable se actualiza con un nuevo valor. Existe incluso un mecanismo similar en las calculadoras, cuando los valores intermedios se guardan con las teclas `m+` o `m-`. + - Almacenamiento del estado. Si estás escribiendo un juego, entonces la posición del personaje, su salud, la puntuación y el nivel actual son variables que cambian constantemente. + + ## const no cambia + + No toda variable se puede reasignar. Si una variable se declara con `const`, su valor no se puede cambiar: + + ```javascript + const greeting = 'Father!'; + greeting = 'Mother!'; // TypeError: Assignment to constant variable. + ``` + + Por eso, para los valores que van a cambiar se usa `let`, y para los constantes, `const`. Así funciona la mayoría de los lenguajes de programación modernos: un valor que no debe cambiar se marca por separado. + + ## Por qué esto es importante + + Las variables son una forma flexible de almacenar datos que pueden cambiar durante la ejecución del programa. Gracias a esto, puedes escribir programas que se comportan de manera diferente según las condiciones, las acciones del usuario o los resultados de los cálculos. + + Pero la flexibilidad tiene su lado negativo. A veces es difícil saber de inmediato qué se almacena exactamente en una variable en un momento u otro. El desarrollador tiene que rastrear dónde y cómo cambió, especialmente si el código es largo. + + Esto es exactamente lo que se hace durante la depuración: intentar averiguar por qué el programa funciona de manera diferente a la prevista. Se comprueban los valores de las variables, se rastrea el orden de ejecución del código y se busca dónde algo salió mal. instructions: | - En el ejercicio se define una variable que contiene una cadena de texto. Reasigna el valor de esta variable y asígnale la misma cadena de texto, pero en orden inverso, es decir, coloca los caracteres de la cadena original en orden inverso. + El estado del pedido se actualiza a medida que este avanza. Al principio, el pedido se encuentra en el estado `'in transit'`, luego pasa al estado `'delivered'`. + + En el ejercicio ya está definida la variable `deliveryStatus` con el valor `'in transit'`. Reasigna su valor a `'delivered'` e imprímelo en pantalla. + + Ejemplo de reasignación de una variable: + + ```javascript + let someVar = 'valor antiguo'; + someVar = 'valor nuevo'; + console.log(someVar); // => valor nuevo + ``` definitions: - name: Variable diff --git a/modules/30-variables/11-change/en/EXERCISE.md b/modules/30-variables/11-change/en/EXERCISE.md index 6c1f3d05..daf14d0c 100644 --- a/modules/30-variables/11-change/en/EXERCISE.md +++ b/modules/30-variables/11-change/en/EXERCISE.md @@ -1,2 +1,11 @@ +The order status is updated as the order moves along. At the beginning, the order is in the `'in transit'` status, then it changes to the `'delivered'` status. -In the exercise, the variable comes with an initial string value. Override the variable and assign it the same string, but reversed, i.e., place the characters of the initial string in reverse order. +The exercise already defines a variable `deliveryStatus` with the value `'in transit'`. Reassign its value to `'delivered'` and print it to the screen. + +An example of reassigning a variable: + +```javascript +let someVar = 'old value'; +someVar = 'new value'; +console.log(someVar); // => new value +``` diff --git a/modules/30-variables/11-change/en/README.md b/modules/30-variables/11-change/en/README.md index 38bd314e..7ddbd243 100644 --- a/modules/30-variables/11-change/en/README.md +++ b/modules/30-variables/11-change/en/README.md @@ -1,14 +1,49 @@ +The very word "variable" suggests that its value can change. This is one of the main reasons variables exist at all. -The word "variable" itself suggests that it can vary. Indeed, the value of a variable can change throughout your code. +Here is a simple example: ```javascript +// greeting means a salutation let greeting = 'Father!'; -console.log(greeting); -console.log(greeting); +console.log(greeting); // => Father! greeting = 'Mother!'; -console.log(greeting); -console.log(greeting); +console.log(greeting); // => Mother! ``` -The name remains unchanged, although it stores new data. Note the key difference between declaring a variable and changing it. The `let` keyword appears only when you create a variable, but when you modify it, you don't use a keyword. +Here we first stored one string (_Father!_) in the variable, then another (_Mother!_). The variable name did not change, but the value inside became different. + +```text +Before: greeting ──→ 'Father!' + ╳ +After: greeting ──→ 'Mother!' +``` + +Note: the keyword `let` is written only at the **first** declaration of a variable. On reassignment, `let` is no longer needed — the variable already exists, and we are only changing its value. + +## Why change a value at all? + +In real programs, variables change all the time. Here are a few reasons: + +- The program reacts to user actions. For example, while you are entering data into a form on a website, the variables that hold this data are being updated constantly at that moment. +- Intermediate results. Often data passes through a series of transformations, and at each stage a variable is updated with a new value. There is even a similar mechanism in calculators, when intermediate values are saved using the `m+` or `m-` keys. +- Storing state. If you are writing a game, then the character's position, health, score, and current level are variables that change constantly. + +## const does not change + +Not every variable can be reassigned. If a variable is declared with `const`, its value cannot be changed: + +```javascript +const greeting = 'Father!'; +greeting = 'Mother!'; // TypeError: Assignment to constant variable. +``` + +That is why `let` is used for values that will change, and `const` for constant ones. This is how most modern programming languages work: a value that should not change is marked separately. + +## Why this matters + +Variables are a flexible way to store data that can change during program execution. Thanks to this, you can write programs that behave differently depending on conditions, user actions, or the results of computations. + +But flexibility has a downside. Sometimes it is hard to immediately tell what exactly is stored in a variable at one moment or another. The developer has to track where and how it changed, especially if the code is long. + +This is exactly what is done during debugging: trying to figure out why the program works differently than intended. They check the values of variables, trace the order of code execution, and look for where something went wrong. diff --git a/modules/30-variables/11-change/en/data.yml b/modules/30-variables/11-change/en/data.yml index 6b93c72a..9459a752 100644 --- a/modules/30-variables/11-change/en/data.yml +++ b/modules/30-variables/11-change/en/data.yml @@ -1,5 +1,6 @@ --- -name: Variable change +name: Changing a variable definitions: - name: Variable - description: is a way to save data under a name for later use in code. + description: >- + a way to store information and give it a name for later use in code. diff --git a/modules/30-variables/11-change/es/EXERCISE.md b/modules/30-variables/11-change/es/EXERCISE.md index bc0f3da8..b7e17d2a 100644 --- a/modules/30-variables/11-change/es/EXERCISE.md +++ b/modules/30-variables/11-change/es/EXERCISE.md @@ -1,2 +1,11 @@ +El estado del pedido se actualiza a medida que este avanza. Al principio, el pedido se encuentra en el estado `'in transit'`, luego pasa al estado `'delivered'`. -En el ejercicio se define una variable que contiene una cadena de texto. Reasigna el valor de esta variable y asígnale la misma cadena de texto, pero en orden inverso, es decir, coloca los caracteres de la cadena original en orden inverso. +En el ejercicio ya está definida la variable `deliveryStatus` con el valor `'in transit'`. Reasigna su valor a `'delivered'` e imprímelo en pantalla. + +Ejemplo de reasignación de una variable: + +```javascript +let someVar = 'valor antiguo'; +someVar = 'valor nuevo'; +console.log(someVar); // => valor nuevo +``` diff --git a/modules/30-variables/11-change/es/README.md b/modules/30-variables/11-change/es/README.md index d6b64e92..dd0b9dca 100644 --- a/modules/30-variables/11-change/es/README.md +++ b/modules/30-variables/11-change/es/README.md @@ -1,14 +1,49 @@ +La palabra misma "variable" sugiere que su valor puede cambiar. Esta es una de las principales razones por las que existen las variables. -La palabra "variable" en sí misma indica que se puede cambiar. Y de hecho, con el tiempo, los valores de las variables pueden cambiar dentro de un programa. +Aquí tienes un ejemplo sencillo: ```javascript +// greeting significa un saludo let greeting = 'Father!'; -console.log(greeting); -console.log(greeting); +console.log(greeting); // => Father! greeting = 'Mother!'; -console.log(greeting); -console.log(greeting); +console.log(greeting); // => Mother! ``` -El nombre sigue siendo el mismo, pero los datos internos son diferentes. Presta atención a la diferencia clave entre la declaración de una variable y su cambio. La palabra clave `let` solo se utiliza al crear una variable, pero no se utiliza al cambiarla. +Aquí primero guardamos una cadena (_Father!_) en la variable, y luego otra (_Mother!_). El nombre de la variable no cambió, pero el valor dentro de ella se volvió diferente. + +```text +Antes: greeting ──→ 'Father!' + ╳ +Después: greeting ──→ 'Mother!' +``` + +Ten en cuenta: la palabra clave `let` se escribe solo en la **primera** declaración de una variable. Al reasignarla, `let` ya no es necesaria — la variable ya existe, y solo estamos cambiando su valor. + +## ¿Por qué cambiar un valor? + +En los programas reales, las variables cambian todo el tiempo. Aquí tienes algunas razones: + +- El programa reacciona a las acciones del usuario. Por ejemplo, mientras introduces datos en un formulario de un sitio web, las variables que contienen estos datos se actualizan constantemente en ese momento. +- Resultados intermedios. A menudo los datos pasan por una serie de transformaciones, y en cada etapa una variable se actualiza con un nuevo valor. Existe incluso un mecanismo similar en las calculadoras, cuando los valores intermedios se guardan con las teclas `m+` o `m-`. +- Almacenamiento del estado. Si estás escribiendo un juego, entonces la posición del personaje, su salud, la puntuación y el nivel actual son variables que cambian constantemente. + +## const no cambia + +No toda variable se puede reasignar. Si una variable se declara con `const`, su valor no se puede cambiar: + +```javascript +const greeting = 'Father!'; +greeting = 'Mother!'; // TypeError: Assignment to constant variable. +``` + +Por eso, para los valores que van a cambiar se usa `let`, y para los constantes, `const`. Así funciona la mayoría de los lenguajes de programación modernos: un valor que no debe cambiar se marca por separado. + +## Por qué esto es importante + +Las variables son una forma flexible de almacenar datos que pueden cambiar durante la ejecución del programa. Gracias a esto, puedes escribir programas que se comportan de manera diferente según las condiciones, las acciones del usuario o los resultados de los cálculos. + +Pero la flexibilidad tiene su lado negativo. A veces es difícil saber de inmediato qué se almacena exactamente en una variable en un momento u otro. El desarrollador tiene que rastrear dónde y cómo cambió, especialmente si el código es largo. + +Esto es exactamente lo que se hace durante la depuración: intentar averiguar por qué el programa funciona de manera diferente a la prevista. Se comprueban los valores de las variables, se rastrea el orden de ejecución del código y se busca dónde algo salió mal. diff --git a/modules/30-variables/11-change/index.js b/modules/30-variables/11-change/index.js index 3d211f87..aae09b69 100644 --- a/modules/30-variables/11-change/index.js +++ b/modules/30-variables/11-change/index.js @@ -1,7 +1,7 @@ -let deliveryStatus = 'в пути'; +let deliveryStatus = 'in transit'; // BEGIN -deliveryStatus = 'доставлен'; +deliveryStatus = 'delivered'; // END console.log(deliveryStatus); diff --git a/modules/30-variables/11-change/ru/EXERCISE.md b/modules/30-variables/11-change/ru/EXERCISE.md index 5925d185..90b6a2e8 100644 --- a/modules/30-variables/11-change/ru/EXERCISE.md +++ b/modules/30-variables/11-change/ru/EXERCISE.md @@ -1,6 +1,6 @@ -Статус заказа обновляется по мере его продвижения. В начале заказ находится «в пути», затем переходит в статус «доставлен». +Статус заказа обновляется по мере его продвижения. В начале заказ находится в статусе `'in transit'`, затем переходит в статус `'delivered'`. -В упражнении уже определена переменная `deliveryStatus` со значением `'в пути'`. Переопределите её значение на `'доставлен'` и выведите на экран. +В упражнении уже определена переменная `deliveryStatus` со значением `'in transit'`. Переопределите её значение на `'delivered'` и выведите на экран. Пример переопределения переменной: diff --git a/modules/30-variables/11-change/test.js b/modules/30-variables/11-change/test.js index e58e1c45..7d69186d 100644 --- a/modules/30-variables/11-change/test.js +++ b/modules/30-variables/11-change/test.js @@ -8,5 +8,5 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); - expect(firstArg).toBe('доставлен'); + expect(firstArg).toBe('delivered'); }); diff --git a/modules/30-variables/13-variables-naming/description.es.yml b/modules/30-variables/13-variables-naming/description.es.yml index 2713d339..256d150c 100644 --- a/modules/30-variables/13-variables-naming/description.es.yml +++ b/modules/30-variables/13-variables-naming/description.es.yml @@ -1,54 +1,54 @@ --- -name: Elección del nombre de la variable +name: Elección del nombre de una variable theory: | - - Imaginemos que el programa del último ejercicio se ve así: + Imagina que tenemos un programa como este: ```javascript - let x = 'Father!'; - console.log(x); + const x = 'Father!'; console.log(x); ``` - Todavía funciona, pero el nombre de la variable ha cambiado a `x`. A la computadora no le importa cómo llamamos a las variables, es una máquina sin emociones, pero a los programadores sí nos importa. Leemos el código mucho más a menudo de lo que lo escribimos. Y no solamente nuestro propio código, sino también el código escrito por otras personas. La mitad del éxito en el análisis de código depende de la calidad y claridad de los nombres de las variables. - - Es mejor tomarse el tiempo para pensar en un nombre que describa la esencia y el significado de la variable, en lugar de nombrarla al azar y tener que cambiarla en el futuro. Intente darles nombres que sean comprensibles sin contexto, sin tener que estudiar el código circundante. + Desde el punto de vista técnico, todo funciona. Ya hemos visto ejemplos similares, pero aquí se usa una variable con el nombre `x`. Los nombres malos dificultan leer y entender el código. Aquí tienes algunos ejemplos de variables poco afortunadas: - Existe una regla generalmente aceptada: no utilice transliteraciones para los nombres; solamente use el idioma inglés. Si tiene dificultades con el inglés, utilice un traductor. Con el tiempo, al trabajar con código ajeno, formará conceptos adecuados para la nomenclatura. - - Entre los desarrolladores hay un chiste: "lo más difícil de la programación son los nombres de las variables y la invalidación de la caché". De hecho, es difícil inventar nombres. ¿Cómo llamaría a una variable que almacena "la cantidad de pedidos impagos de clientes que tienen deudas en el trimestre anterior"? - -
- Respuesta + ```javascript + const a = 'John'; + const n = 42; + const ddr = 'New York'; + ``` - No hay una respuesta correcta y unívoca a esta pregunta. Por ejemplo, se puede utilizar el nombre `unpaidOrdersFromDebtorsInPreviousQuarterCount`. + ¿Qué son estas variables? ¿Qué almacenan? Para entenderlo, hay que leer todo el resto del código y adivinar por el contexto. - Este nombre describe bien el contenido de la variable y permite identificar fácilmente su significado en el código. Sin embargo, es demasiado largo y complicado, por lo que es mejor utilizar un nombre más corto, como `unpaidOrdersFromDebtorsCount` o `debtorsUnpaidOrdersCount`. En general, la elección del nombre de la variable depende del contexto de uso. -
+ A la computadora le da igual cómo se llame la variable. Para ella, `x`, `abc`, `message` o `elephantInTheRoom` son simplemente etiquetas para almacenar datos. A las personas les importa otra cosa. Los programadores leen el código mucho más a menudo de lo que lo escriben. Por eso los nombres de las variables son una parte importante de la comunicación a través del código. - En JavaScript, en los nombres de las constantes y variables, cada palabra se escribe con mayúscula inicial, excepto la primera. Por ejemplo: + ## Buenos ejemplos ```javascript - const firstName = 'John'; - console.log(firstName); // => John - - const playerNumber = 24; - console.log(playerNumber); // => 24 + const userName = 'Arya Stark'; + const unpaidOrdersCount = 3; + const maxAttempts = 5; ``` - Autoevaluación. Piense en un nombre para una variable que almacene "la cantidad de hermanos y hermanas del rey". Escríbalo en un bloc de notas o envíelo por correo electrónico. No incluya nada más que el nombre de la variable. Volveremos a este tema en unas lecciones ;-) + Un buen nombre de variable ayuda a entender qué hace el programa sin tener que leer cada línea. Es especialmente importante dar nombres cuyo significado sea claro sin contexto, sin necesidad de leer todo el código alrededor. -instructions: | + Aquí tienes algunos consejos: - Crea una variable que describa literalmente "la cantidad de mis hermanos" y asígnale el valor *2*. Imprime el contenido de la variable. Después de una verificación exitosa, compara tu nombre con el nombre utilizado en la solución del profesor. + - Usa el inglés. Es el estándar internacional. Es mejor escribir `ordersCount` en lugar de `kolvoZakazov`. Si el inglés todavía te resulta difícil, usa un traductor, es normal. Con el tiempo se hará más fácil. + - Intenta que el nombre refleje el significado de la variable. Que sea un poco más largo, pero comprensible. + - No tengas miedo de dedicar tiempo a elegir un buen nombre. Es una inversión en la legibilidad y el mantenimiento del código. + Entre los programadores incluso hay una broma: «Algunos de los problemas más difíciles en programación son el almacenamiento en caché y poner nombres a las variables». A veces inventar un nombre adecuado es realmente difícil. Aquí tienes un ejemplo: ¿cómo llamarías a una variable que almacena la cantidad de pedidos no pagados de clientes con deuda del trimestre anterior? + + Y ahora un pequeño ejercicio: inventa un nombre para una variable que almacenará «la cantidad de hermanos y hermanas del rey». Anótalo en una libreta o envíatelo por correo. Solo el nombre, sin explicaciones. Volveremos a esta tarea dentro de unas lecciones. +instructions: | + Crea una variable que describa literalmente "la cantidad de mis hermanos", y asígnale el valor *2*. Imprime el contenido de la variable. Después de una comprobación exitosa, compara tu nombre con el nombre que se usa en la solución del profesor. tips: - | [Nomenclatura en programación](https://codica.la/blog/naming-in-programming) - | [Errores en la nomenclatura de variables](https://codica.la/blog/naming-errors-1) - definitions: - name: Variable - description: una forma de almacenar información y darle un nombre para su uso posterior en el código. + description: >- + una forma de almacenar información y darle un nombre para su uso posterior + en el código. diff --git a/modules/30-variables/13-variables-naming/en/EXERCISE.md b/modules/30-variables/13-variables-naming/en/EXERCISE.md index f03e8bdc..fe1daff0 100644 --- a/modules/30-variables/13-variables-naming/en/EXERCISE.md +++ b/modules/30-variables/13-variables-naming/en/EXERCISE.md @@ -1,2 +1,2 @@ -Create a variable storing the number of my brothers and assign it a value of *2*. Print it. After completing the tests, compare your name with the teacher's variable name in the solution. +Create a variable that literally describes "the number of my brothers", and assign it the value *2*. Print the contents of the variable. After a successful check, compare your name with the name used in the teacher's solution. diff --git a/modules/30-variables/13-variables-naming/en/README.md b/modules/30-variables/13-variables-naming/en/README.md index bba6447f..464f67d7 100644 --- a/modules/30-variables/13-variables-naming/en/README.md +++ b/modules/30-variables/13-variables-naming/en/README.md @@ -1,24 +1,38 @@ - -Imagine the code from the previous lesson looks like this: +Imagine we have a program like this: ```javascript -let x = 'Father!'; -console.log(x); +const x = 'Father!'; console.log(x); ``` -Although it works, the variable name is now `x`. A computer doesn't care about naming since it's a mindless machine, but developers do care. We are mostly read someone else's code, then write or read our own. Quality and clarity of variable names is half the battle when it comes to code analysis. +Technically, everything works. We've already seen similar examples, but here we use a variable named `x`. Bad names make code hard to read and understand. Here are a few examples of poor variables: + +```javascript +const a = 'John'; +const n = 42; +const ddr = 'New York'; +``` -It's best take a moment and come up with a name reflecting the essence and meaning of the variable than give it a random name and rename it later. Try to name variables to make them as comprehensive as possible without context, or without examining the surrounding code. +What are these variables? What do they store? To figure this out, you have to read all the surrounding code and guess from the context. -A common joke among developers is that "the hardest part of programming is cache invalidation and naming things". Coming up with names is tough indeed. How would you name a variable that stores _the number of unpaid orders from customers in debt from the previous quarter?_ +The computer doesn't care what a variable is called. To it, `x`, `abc`, `message`, or `elephantInTheRoom` are just labels for storing data. People care about other things. Programmers read code far more often than they write it. That's why variable names are an important part of communicating through code. -```javascript -const firstName = 'John'; -console.log(firstName); // => John +## Good examples -const playerNumber = 24; -console.log(playerNumber); // => 24 +```javascript +const userName = 'Arya Stark'; +const unpaidOrdersCount = 3; +const maxAttempts = 5; ``` -Self-сheck. Think of a name for the variable that would store _"the number of siblings the king has"_. Write it down in a notebook or send it to yourself. Don't put anything in there except the name of the variable. And we'll come back to this topic in a few lessons ;-) +A good variable name helps you understand what the program does without reading every line. It's especially important to choose names whose meaning is clear without context, without having to read all the code around them. + +Here are a few tips: + +- Use English. It's the international standard. It's better to write `ordersCount` instead of `kolvoZakazov`. If English is still difficult for you, use a translator, that's fine. Over time it will get easier. +- Try to make the name reflect the meaning of the variable. Let it be a bit longer, but understandable. +- Don't be afraid to spend time choosing a good name. It's an investment in the readability and maintainability of the code. + +Programmers even have a joke: "Some of the hardest problems in programming are caching and naming variables." Sometimes coming up with a fitting name really is hard. Here's an example: how would you name a variable that stores the number of unpaid orders from customers with outstanding debt from the previous quarter? + +And now a small exercise: come up with a name for a variable that will store "the number of the king's brothers and sisters". Write it down in a notepad or send it to yourself by email. Just the name, without explanations. We'll come back to this task in a few lessons. diff --git a/modules/30-variables/13-variables-naming/en/data.yml b/modules/30-variables/13-variables-naming/en/data.yml index bc0fef8f..69a078cd 100644 --- a/modules/30-variables/13-variables-naming/en/data.yml +++ b/modules/30-variables/13-variables-naming/en/data.yml @@ -1,10 +1,13 @@ --- -name: Naming a variable +name: Choosing a variable name tips: - > [Naming in - programing](https://en.hexlet.io/blog/posts/code-complete-naming-in-programming) + programming](https://en.hexlet.io/blog/posts/code-complete-naming-in-programming) - > [Variable naming mistakes](https://en.hexlet.io/blog/posts/perfect-code-naming-mistakes-to-avoid-in-programming-i) -definitions: [] +definitions: + - name: Variable + description: >- + a way to store information and give it a name for later use in the code. diff --git a/modules/30-variables/13-variables-naming/es/EXERCISE.md b/modules/30-variables/13-variables-naming/es/EXERCISE.md index e3bc81ae..cbb6a62d 100644 --- a/modules/30-variables/13-variables-naming/es/EXERCISE.md +++ b/modules/30-variables/13-variables-naming/es/EXERCISE.md @@ -1,2 +1,2 @@ -Crea una variable que describa literalmente "la cantidad de mis hermanos" y asígnale el valor *2*. Imprime el contenido de la variable. Después de una verificación exitosa, compara tu nombre con el nombre utilizado en la solución del profesor. +Crea una variable que describa literalmente "la cantidad de mis hermanos", y asígnale el valor *2*. Imprime el contenido de la variable. Después de una comprobación exitosa, compara tu nombre con el nombre que se usa en la solución del profesor. diff --git a/modules/30-variables/13-variables-naming/es/README.md b/modules/30-variables/13-variables-naming/es/README.md index db1a4281..2a9a0922 100644 --- a/modules/30-variables/13-variables-naming/es/README.md +++ b/modules/30-variables/13-variables-naming/es/README.md @@ -1,36 +1,38 @@ - -Imaginemos que el programa del último ejercicio se ve así: +Imagina que tenemos un programa como este: ```javascript -let x = 'Father!'; -console.log(x); +const x = 'Father!'; console.log(x); ``` -Todavía funciona, pero el nombre de la variable ha cambiado a `x`. A la computadora no le importa cómo llamamos a las variables, es una máquina sin emociones, pero a los programadores sí nos importa. Leemos el código mucho más a menudo de lo que lo escribimos. Y no solamente nuestro propio código, sino también el código escrito por otras personas. La mitad del éxito en el análisis de código depende de la calidad y claridad de los nombres de las variables. +Desde el punto de vista técnico, todo funciona. Ya hemos visto ejemplos similares, pero aquí se usa una variable con el nombre `x`. Los nombres malos dificultan leer y entender el código. Aquí tienes algunos ejemplos de variables poco afortunadas: -Es mejor tomarse el tiempo para pensar en un nombre que describa la esencia y el significado de la variable, en lugar de nombrarla al azar y tener que cambiarla en el futuro. Intente darles nombres que sean comprensibles sin contexto, sin tener que estudiar el código circundante. +```javascript +const a = 'John'; +const n = 42; +const ddr = 'New York'; +``` -Existe una regla generalmente aceptada: no utilice transliteraciones para los nombres; solamente use el idioma inglés. Si tiene dificultades con el inglés, utilice un traductor. Con el tiempo, al trabajar con código ajeno, formará conceptos adecuados para la nomenclatura. +¿Qué son estas variables? ¿Qué almacenan? Para entenderlo, hay que leer todo el resto del código y adivinar por el contexto. -Entre los desarrolladores hay un chiste: "lo más difícil de la programación son los nombres de las variables y la invalidación de la caché". De hecho, es difícil inventar nombres. ¿Cómo llamaría a una variable que almacena "la cantidad de pedidos impagos de clientes que tienen deudas en el trimestre anterior"? +A la computadora le da igual cómo se llame la variable. Para ella, `x`, `abc`, `message` o `elephantInTheRoom` son simplemente etiquetas para almacenar datos. A las personas les importa otra cosa. Los programadores leen el código mucho más a menudo de lo que lo escriben. Por eso los nombres de las variables son una parte importante de la comunicación a través del código. -
-Respuesta +## Buenos ejemplos -No hay una respuesta correcta y unívoca a esta pregunta. Por ejemplo, se puede utilizar el nombre `unpaidOrdersFromDebtorsInPreviousQuarterCount`. +```javascript +const userName = 'Arya Stark'; +const unpaidOrdersCount = 3; +const maxAttempts = 5; +``` -Este nombre describe bien el contenido de la variable y permite identificar fácilmente su significado en el código. Sin embargo, es demasiado largo y complicado, por lo que es mejor utilizar un nombre más corto, como `unpaidOrdersFromDebtorsCount` o `debtorsUnpaidOrdersCount`. En general, la elección del nombre de la variable depende del contexto de uso. -
+Un buen nombre de variable ayuda a entender qué hace el programa sin tener que leer cada línea. Es especialmente importante dar nombres cuyo significado sea claro sin contexto, sin necesidad de leer todo el código alrededor. -En JavaScript, en los nombres de las constantes y variables, cada palabra se escribe con mayúscula inicial, excepto la primera. Por ejemplo: +Aquí tienes algunos consejos: -```javascript -const firstName = 'John'; -console.log(firstName); // => John +- Usa el inglés. Es el estándar internacional. Es mejor escribir `ordersCount` en lugar de `kolvoZakazov`. Si el inglés todavía te resulta difícil, usa un traductor, es normal. Con el tiempo se hará más fácil. +- Intenta que el nombre refleje el significado de la variable. Que sea un poco más largo, pero comprensible. +- No tengas miedo de dedicar tiempo a elegir un buen nombre. Es una inversión en la legibilidad y el mantenimiento del código. -const playerNumber = 24; -console.log(playerNumber); // => 24 -``` +Entre los programadores incluso hay una broma: «Algunos de los problemas más difíciles en programación son el almacenamiento en caché y poner nombres a las variables». A veces inventar un nombre adecuado es realmente difícil. Aquí tienes un ejemplo: ¿cómo llamarías a una variable que almacena la cantidad de pedidos no pagados de clientes con deuda del trimestre anterior? -Autoevaluación. Piense en un nombre para una variable que almacene "la cantidad de hermanos y hermanas del rey". Escríbalo en un bloc de notas o envíelo por correo electrónico. No incluya nada más que el nombre de la variable. Volveremos a este tema en unas lecciones ;-) +Y ahora un pequeño ejercicio: inventa un nombre para una variable que almacenará «la cantidad de hermanos y hermanas del rey». Anótalo en una libreta o envíatelo por correo. Solo el nombre, sin explicaciones. Volveremos a esta tarea dentro de unas lecciones. diff --git a/modules/30-variables/13-variables-naming/es/data.yml b/modules/30-variables/13-variables-naming/es/data.yml index ac6a8781..feadc5dc 100644 --- a/modules/30-variables/13-variables-naming/es/data.yml +++ b/modules/30-variables/13-variables-naming/es/data.yml @@ -1,5 +1,5 @@ --- -name: Elección del nombre de la variable +name: Elección del nombre de una variable tips: - | [Nomenclatura en programación](https://codica.la/blog/naming-in-programming) diff --git a/modules/30-variables/15-variables-expressions/description.es.yml b/modules/30-variables/15-variables-expressions/description.es.yml index d2b998a7..85a4056f 100644 --- a/modules/30-variables/15-variables-expressions/description.es.yml +++ b/modules/30-variables/15-variables-expressions/description.es.yml @@ -3,84 +3,101 @@ name: Expresiones en definiciones theory: | - Las variables son útiles no solamente para almacenar y reutilizar información, sino también para simplificar cálculos complejos. Veamos un ejemplo: necesitamos convertir euros a yuanes a través de dólares. Los bancos a menudo realizan conversiones similares a través de una moneda intermedia al realizar compras en el extranjero. + Ya sabemos que las expresiones pueden estar compuestas por varias operaciones. Pero si escribimos todo el cálculo en una sola línea larga, el código rápidamente se vuelve difícil de leer. - Primero, convirtamos 50 euros a dólares. Supongamos que un euro equivale a 1.25 dólares: + Por ejemplo, esta forma funciona: ```javascript - let dollarsCount = 50 * 1.25; - console.log(dollarsCount); // => 62.5 + const yuansCount = 50 * 1.25 * 6.91; + console.log(yuansCount); // => 431.875 ``` - En la lección anterior, asignamos un valor específico a una variable. Pero aquí, `let dollarsCount = 50 * 1.25;`, a la derecha del signo igual, hay una **expresión**. El intérprete calculará el resultado, que es `62.5`, y lo asignará a la variable. Desde el punto de vista del intérprete, no importa si hay `62.5` o `50 * 1.25`, ambos son expresiones que deben evaluarse. Y se evalúan en el mismo valor, `62.5`. + JavaScript evaluará fácilmente esta expresión. Pero para una persona ya no resulta tan cómodo leer este código. Surgen preguntas de inmediato: - Cualquier cadena de texto es una expresión. La concatenación de cadenas también es una expresión. Cuando el intérprete encuentra una expresión, la procesa y genera un resultado, que es el **valor de la expresión**. Aquí hay algunos ejemplos de expresiones y sus valores resultantes: + - ¿Qué significa `1.25`? + - ¿Qué significa `6.91`? + - ¿Dónde termina un paso del cálculo y empieza el siguiente? - ```javascript - 62.5 // 62.5 - 50 * 1.25 // 62.5 - 120 / 10 * 2 // 24 + Para que estos cálculos sean más claros, las variables pueden usarse dentro de otras expresiones. Primero el programa guarda un resultado intermedio en una variable, y luego sustituye el valor de esa variable en el siguiente cálculo. + + ## Expresiones - 'hello' // hello - 'Good' + 'will' // Goodwill + Cualquier valor que se pueda calcular es una expresión. A una variable se le puede asignar una expresión, no solo un valor ya preparado. + + ```javascript + const sum = 3 + 4; // => 7 + const text = 'Hello' + '!'; // => 'Hello!' + const doubled = sum * 2; // => 14 ``` - Las reglas de construcción del código (gramática del lenguaje) permiten que en los lugares donde se espera una expresión, se pueda colocar cualquier cálculo (no solo matemático, sino también, por ejemplo, de concatenación de cadenas) y el programa seguirá funcionando. Por esta razón, no es posible describir y mostrar todos los casos de uso de todas las operaciones. + JavaScript primero evalúa la expresión a la derecha de `=`, y luego guarda el resultado en la variable a la izquierda. - Los programas están compuestos por muchas combinaciones de expresiones, y comprender este concepto es uno de los pasos clave en tu camino. + ## Conversión de moneda a través de una moneda intermedia - Basándonos en lo dicho anteriormente, ¿crees que este código funcionará? + Imaginemos que necesitamos convertir euros a yuanes, pero el tipo de cambio directo no está disponible para nosotros. Entonces lo haremos en dos pasos: **euros → dólares → yuanes**. Así suelen funcionar los bancos al pagar compras en el extranjero. + + ### Paso 1. Euros → Dólares + + Supongamos que el tipo de cambio es: 1 euro = 1.25 dólares. Queremos convertir 50 euros: ```javascript - let who = "dragon's" + 'mother'; - console.log(who); + const dollarsPerEuro = 1.25; + const dollarsCount = 50 * dollarsPerEuro; + console.log(dollarsCount); // => 62.5 ``` -
- Respuesta + En esta línea, `50 * dollarsPerEuro` es una expresión, y `dollarsCount` es la variable en la que se escribe el resultado. JavaScript primero evalúa la expresión, y solo después guarda el resultado en la variable. - Sí, funcionará. Se imprimirá la cadena `dragon'smother`. + Al motor le da igual cómo esté escrita la expresión: -
+ ```javascript + const dollarsCount = 62.5; + ``` - Volvamos a nuestro programa de conversión de moneda. Guardemos el valor del dólar en yuanes como una variable separada. Calculemos el precio de 50 euros en dólares multiplicándolos por `1.25`. Supongamos que 1 dólar equivale a 6.91 yuanes: + o ```javascript - let yuansPerDollar = 6.91; - let dollarsCount = 50 * 1.25; // 62.5 - let yuansCount = dollarsCount * yuansPerDollar; // 431.875 - - console.log(yuansCount); + const dollarsCount = 50 * dollarsPerEuro; ``` - Ahora agreguemos texto a la salida utilizando concatenación: + El resultado será el mismo. Pero para una persona la segunda opción es más útil: por el nombre `dollarsCount` se ve de inmediato que en este paso obtuvimos la cantidad en dólares. + + ### Paso 2. Dólares → Yuanes + + Ahora convirtamos 50 euros a yuanes, usando el dólar como moneda intermedia. Supongamos que los tipos de cambio son: 1 dólar = 6.91 yuanes, 1 euro = 1.25 dólares. ```javascript - let yuansPerDollar = 6.91; - let dollarsCount = 50 * 1.25; // 62.5 - let yuansCount = dollarsCount * yuansPerDollar; // 431.875 + const dollarsPerEuro = 1.25; + const yuansPerDollar = 6.91; - console.log('The price is ' + yuansCount + ' yuans'); - ``` + const dollarsCount = 50 * dollarsPerEuro; + const yuansCount = dollarsCount * yuansPerDollar; - ```text - The price is 431.875 yuans + console.log(yuansCount); ``` - Cualquier variable puede ser parte de cualquier expresión. En el momento de la evaluación, el valor de la variable se sustituye en lugar de su nombre. + Este código es más largo que la única línea `50 * 1.25 * 6.91`, pero es más fácil de leer: + + - se ve que `1.25` es el tipo de cambio del euro al dólar; + - se ve que `6.91` es el tipo de cambio del dólar al yuan; + - se ve que `dollarsCount` es un resultado intermedio. + + Esto se nota especialmente si no vuelves al código durante al menos una semana. Y ahora imagina que un proyecto tiene cientos de miles de líneas de código. Si en tales proyectos no hubiera variables y cálculos intermedios, sería imposible entenderlos. - El intérprete calcula el valor de `dollarsCount` antes de que esta variable se utilice en otras expresiones. Cuando llega el momento de usar la variable, JavaScript "conoce" su valor porque ya lo ha calculado. + ## Qué hay que recordar + + - Si una expresión resulta demasiado larga, es mejor dividirla en varios pasos. + - Las variables ayudan a guardar resultados intermedios y hacen los cálculos más claros. + - Cuando una variable se usa en una expresión, JavaScript sustituye su valor y continúa el cálculo. instructions: | - Escribe un programa que tome una cantidad inicial de euros, almacenada en la variable `eurosCount`, convierta los euros a dólares y los imprima en la pantalla. Luego, convierte el valor obtenido a yuanes e imprímelos en una nueva línea. + Dada la cantidad de euros: `eurosCount = 100`. Escribe un programa que: - Ejemplo de salida para 100 euros: + 1. Convierta euros a dólares al tipo de cambio `1.25` e imprima el resultado. + 2. Convierta dólares a yuanes al tipo de cambio `6.91` e imprima el resultado. - ```text - 125 - 863.75 - ``` + Usa variables para almacenar los valores intermedios. tips: - | diff --git a/modules/30-variables/15-variables-expressions/en/EXERCISE.md b/modules/30-variables/15-variables-expressions/en/EXERCISE.md index fa5d8696..a0979c2a 100644 --- a/modules/30-variables/15-variables-expressions/en/EXERCISE.md +++ b/modules/30-variables/15-variables-expressions/en/EXERCISE.md @@ -1,13 +1,6 @@ +Given the number of euros: `eurosCount = 100`. Write a program that: -Write a program that takes the initial amount of euros stored in the variable `eurosCount`, converts euros to dollars, and prints it. Then, it should convert the result to yuan and print it on a new line. +1. Converts euros to dollars at the rate of `1.25` and prints the result. +2. Converts dollars to yuan at the rate of `6.91` and prints the result. -Sample output for 100 euros: - -```text -125 -863.75 -``` - -Suppose that: -- 1 euro = 1.25 dollars -- 1 dollar = 6.91 yuan +Use variables to store the intermediate values. diff --git a/modules/30-variables/15-variables-expressions/en/README.md b/modules/30-variables/15-variables-expressions/en/README.md index 56c6b4ad..fcbb283c 100644 --- a/modules/30-variables/15-variables-expressions/en/README.md +++ b/modules/30-variables/15-variables-expressions/en/README.md @@ -1,61 +1,86 @@ +We already know that expressions can be made up of several operations. But if you write an entire calculation in one long line, the code quickly becomes hard to read. -Variables are helpful not only for storing and reusing data but also for simplifying complex calculations. Consider an example: you need to convert euros into yuan through dollars. Banks often do this kind of conversion via an intermediate currency when shopping abroad. - -First, convert 50 euros into dollars. Suppose that one euro is $1.25: +For example, this works: ```javascript -let dollarsCount = 50 * 1.25; -console.log(dollarsCount); // => 62.5 +const yuansCount = 50 * 1.25 * 6.91; +console.log(yuansCount); // => 431.875 ``` -Last lesson, we assigned a specific value to a variable. Here, when we declare our variable, `let dollarsCount = 50 * 1.25;` we have an **expression** to the right of the equals sign. The interpreter computes the result - `62.5`, and records it in a variable. An interpreter doesn't care about what is in front of it: `62.5` or `50 * 1.25`, both are expressions to compute. And they result in the same value, `62.5`. +JavaScript will easily evaluate this expression. But it is no longer convenient for a human to read such code. Questions immediately arise: -Any string is an expression. The concatenation of strings is also an expression. The interpreter processes an encountered expression and produces, as a result, the **value of the expression**. Here are some sample expressions with comments on the right containing the resulting value. +- What does `1.25` mean? +- What does `6.91` mean? +- Where does one calculation step end and the next begin? -```javascript -62.5 // 62.5 -50 * 1.25 // 62.5 -120 / 10 * 2 // 24 +To make such calculations clearer, variables can be used inside other expressions. First the program saves an intermediate result in a variable, and then it substitutes the value of that variable into the next calculation. + +## Expressions + +Any computable value is an expression. You can assign an expression to a variable, not just a ready-made value. -'hello' // "hello" -'Good' + 'will' // "Goodwill" +```javascript +const sum = 3 + 4; // => 7 +const text = 'Hello' + '!'; // => 'Hello!' +const doubled = sum * 2; // => 14 ``` -The code structure rules (language grammar) ensure that any calculation (not just math, but also things like string concatenation) can take place when an expression is expected, and the program will continue. For this reason, it's impossible to describe and show all use cases of all operations. +JavaScript first evaluates the expression to the right of `=`, and then saves the result in the variable on the left. + +## Currency conversion through an intermediate currency + +Imagine we need to convert euros to yuan, but the direct rate is not available to us. Then we will do it in two steps: **euros → dollars → yuan**. This is often how banks work when paying for purchases abroad. -Programs consist of numerous combinations of expressions and understanding this concept is a major step on your journey. +### Step 1. Euros → Dollars -Based on the above, consider whether this code will work? +Suppose the rate is: 1 euro = 1.25 dollars. We want to convert 50 euros: ```javascript -let who = "dragon's" + 'mother'; -console.log(who); +const dollarsPerEuro = 1.25; +const dollarsCount = 50 * dollarsPerEuro; +console.log(dollarsCount); // => 62.5 ``` -Now, back to our currency program. We'll record the dollar value in yuan as a separate variable. Calculate the value of 50 euros in dollars by multiplying them by `1.25`. Suppose that 1 dollar is 6.91 yuan: +In this line, `50 * dollarsPerEuro` is an expression, and `dollarsCount` is the variable into which the result is written. JavaScript first evaluates the expression, and only then saves the result in the variable. + +The engine does not care how the expression is written: ```javascript -let yuanPerDollar = 6.91; -let dollarsCount = 50 * 1.25; // 62.5 -let yuanCount = dollarsCount * yuanPerDollar; // 431.875 +const dollarsCount = 62.5; +``` + +or -console.log(yuanCount); +```javascript +const dollarsCount = 50 * dollarsPerEuro; ``` -Now, let's merge our output with some text via concatenation: +The result will be the same. But for a human the second option is more useful: from the name `dollarsCount` it is immediately clear that at this step we got the amount in dollars. + +### Step 2. Dollars → Yuan + +Now let's convert 50 euros to yuan, using the dollar as an intermediate currency. Suppose the exchange rates are: 1 dollar = 6.91 yuan, 1 euro = 1.25 dollars. ```javascript -let yuanPerDollar = 6.91; -let dollarsCount = 50 * 1.25; // 62.5 -let yuanCount = dollarsCount * yuanPerDollar; // 431.875 +const dollarsPerEuro = 1.25; +const yuansPerDollar = 6.91; -console.log('The price is ' + yuanCount + ' yuan'); -``` +const dollarsCount = 50 * dollarsPerEuro; +const yuansCount = dollarsCount * yuansPerDollar; -```text -The price is 431.875 yuan +console.log(yuansCount); ``` -Any variable can be part of any expression. During the computation, the variable's name is replaced with its value. +This code is longer than the single line `50 * 1.25 * 6.91`, but it is easier to read: + +- you can see that `1.25` is the euro-to-dollar rate; +- you can see that `6.91` is the dollar-to-yuan rate; +- you can see that `dollarsCount` is an intermediate result. + +This becomes especially noticeable if you don't come back to the code for at least a week. And now imagine that a project has hundreds of thousands of lines of code. If such projects had no intermediate variables and calculations, it would be impossible to make sense of them. + +## What to remember -The interpreter calculates the value of `dollarsCount` before using it in other expressions. When it comes to using the variable, Javascript "knows" the value it has already computed. +- If an expression turns out to be too long, it is better to break it into several steps. +- Variables help save intermediate results and make calculations clearer. +- When a variable is used in an expression, JavaScript substitutes its value and continues the calculation. diff --git a/modules/30-variables/15-variables-expressions/en/data.yml b/modules/30-variables/15-variables-expressions/en/data.yml index 1bda0949..8a279f33 100644 --- a/modules/30-variables/15-variables-expressions/en/data.yml +++ b/modules/30-variables/15-variables-expressions/en/data.yml @@ -1,2 +1,9 @@ --- -name: Defining with expressions +name: Expressions in definitions +tips: + - | + [Expression](https://en.wikipedia.org/wiki/Expression_(computer_science)) +definitions: + - name: Variable + description: >- + a way to store information and give it a name for later use in the code. diff --git a/modules/30-variables/15-variables-expressions/es/EXERCISE.md b/modules/30-variables/15-variables-expressions/es/EXERCISE.md index 27225799..e1ac4b81 100644 --- a/modules/30-variables/15-variables-expressions/es/EXERCISE.md +++ b/modules/30-variables/15-variables-expressions/es/EXERCISE.md @@ -1,9 +1,6 @@ +Dada la cantidad de euros: `eurosCount = 100`. Escribe un programa que: -Escribe un programa que tome una cantidad inicial de euros, almacenada en la variable `eurosCount`, convierta los euros a dólares y los imprima en la pantalla. Luego, convierte el valor obtenido a yuanes e imprímelos en una nueva línea. +1. Convierta euros a dólares al tipo de cambio `1.25` e imprima el resultado. +2. Convierta dólares a yuanes al tipo de cambio `6.91` e imprima el resultado. -Ejemplo de salida para 100 euros: - -```text -125 -863.75 -``` +Usa variables para almacenar los valores intermedios. diff --git a/modules/30-variables/15-variables-expressions/es/README.md b/modules/30-variables/15-variables-expressions/es/README.md index 8d766b0c..28d10c8e 100644 --- a/modules/30-variables/15-variables-expressions/es/README.md +++ b/modules/30-variables/15-variables-expressions/es/README.md @@ -1,68 +1,86 @@ +Ya sabemos que las expresiones pueden estar compuestas por varias operaciones. Pero si escribimos todo el cálculo en una sola línea larga, el código rápidamente se vuelve difícil de leer. -Las variables son útiles no solamente para almacenar y reutilizar información, sino también para simplificar cálculos complejos. Veamos un ejemplo: necesitamos convertir euros a yuanes a través de dólares. Los bancos a menudo realizan conversiones similares a través de una moneda intermedia al realizar compras en el extranjero. - -Primero, convirtamos 50 euros a dólares. Supongamos que un euro equivale a 1.25 dólares: +Por ejemplo, esta forma funciona: ```javascript -let dollarsCount = 50 * 1.25; -console.log(dollarsCount); // => 62.5 +const yuansCount = 50 * 1.25 * 6.91; +console.log(yuansCount); // => 431.875 ``` -En la lección anterior, asignamos un valor específico a una variable. Pero aquí, `let dollarsCount = 50 * 1.25;`, a la derecha del signo igual, hay una **expresión**. El intérprete calculará el resultado, que es `62.5`, y lo asignará a la variable. Desde el punto de vista del intérprete, no importa si hay `62.5` o `50 * 1.25`, ambos son expresiones que deben evaluarse. Y se evalúan en el mismo valor, `62.5`. +JavaScript evaluará fácilmente esta expresión. Pero para una persona ya no resulta tan cómodo leer este código. Surgen preguntas de inmediato: -Cualquier cadena de texto es una expresión. La concatenación de cadenas también es una expresión. Cuando el intérprete encuentra una expresión, la procesa y genera un resultado, que es el **valor de la expresión**. Aquí hay algunos ejemplos de expresiones y sus valores resultantes: +- ¿Qué significa `1.25`? +- ¿Qué significa `6.91`? +- ¿Dónde termina un paso del cálculo y empieza el siguiente? -```javascript -62.5 // 62.5 -50 * 1.25 // 62.5 -120 / 10 * 2 // 24 +Para que estos cálculos sean más claros, las variables pueden usarse dentro de otras expresiones. Primero el programa guarda un resultado intermedio en una variable, y luego sustituye el valor de esa variable en el siguiente cálculo. + +## Expresiones + +Cualquier valor que se pueda calcular es una expresión. A una variable se le puede asignar una expresión, no solo un valor ya preparado. -'hello' // hello -'Good' + 'will' // Goodwill +```javascript +const sum = 3 + 4; // => 7 +const text = 'Hello' + '!'; // => 'Hello!' +const doubled = sum * 2; // => 14 ``` -Las reglas de construcción del código (gramática del lenguaje) permiten que en los lugares donde se espera una expresión, se pueda colocar cualquier cálculo (no solo matemático, sino también, por ejemplo, de concatenación de cadenas) y el programa seguirá funcionando. Por esta razón, no es posible describir y mostrar todos los casos de uso de todas las operaciones. +JavaScript primero evalúa la expresión a la derecha de `=`, y luego guarda el resultado en la variable a la izquierda. + +## Conversión de moneda a través de una moneda intermedia + +Imaginemos que necesitamos convertir euros a yuanes, pero el tipo de cambio directo no está disponible para nosotros. Entonces lo haremos en dos pasos: **euros → dólares → yuanes**. Así suelen funcionar los bancos al pagar compras en el extranjero. -Los programas están compuestos por muchas combinaciones de expresiones, y comprender este concepto es uno de los pasos clave en tu camino. +### Paso 1. Euros → Dólares -Basándonos en lo dicho anteriormente, ¿crees que este código funcionará? +Supongamos que el tipo de cambio es: 1 euro = 1.25 dólares. Queremos convertir 50 euros: ```javascript -let who = "dragon's" + 'mother'; -console.log(who); +const dollarsPerEuro = 1.25; +const dollarsCount = 50 * dollarsPerEuro; +console.log(dollarsCount); // => 62.5 ``` -
-Respuesta +En esta línea, `50 * dollarsPerEuro` es una expresión, y `dollarsCount` es la variable en la que se escribe el resultado. JavaScript primero evalúa la expresión, y solo después guarda el resultado en la variable. -Sí, funcionará. Se imprimirá la cadena `dragon'smother`. +Al motor le da igual cómo esté escrita la expresión: -
+```javascript +const dollarsCount = 62.5; +``` -Volvamos a nuestro programa de conversión de moneda. Guardemos el valor del dólar en yuanes como una variable separada. Calculemos el precio de 50 euros en dólares multiplicándolos por `1.25`. Supongamos que 1 dólar equivale a 6.91 yuanes: +o ```javascript -let yuansPerDollar = 6.91; -let dollarsCount = 50 * 1.25; // 62.5 -let yuansCount = dollarsCount * yuansPerDollar; // 431.875 - -console.log(yuansCount); +const dollarsCount = 50 * dollarsPerEuro; ``` -Ahora agreguemos texto a la salida utilizando concatenación: +El resultado será el mismo. Pero para una persona la segunda opción es más útil: por el nombre `dollarsCount` se ve de inmediato que en este paso obtuvimos la cantidad en dólares. + +### Paso 2. Dólares → Yuanes + +Ahora convirtamos 50 euros a yuanes, usando el dólar como moneda intermedia. Supongamos que los tipos de cambio son: 1 dólar = 6.91 yuanes, 1 euro = 1.25 dólares. ```javascript -let yuansPerDollar = 6.91; -let dollarsCount = 50 * 1.25; // 62.5 -let yuansCount = dollarsCount * yuansPerDollar; // 431.875 +const dollarsPerEuro = 1.25; +const yuansPerDollar = 6.91; -console.log('The price is ' + yuansCount + ' yuans'); -``` +const dollarsCount = 50 * dollarsPerEuro; +const yuansCount = dollarsCount * yuansPerDollar; -```text -The price is 431.875 yuans +console.log(yuansCount); ``` -Cualquier variable puede ser parte de cualquier expresión. En el momento de la evaluación, el valor de la variable se sustituye en lugar de su nombre. +Este código es más largo que la única línea `50 * 1.25 * 6.91`, pero es más fácil de leer: + +- se ve que `1.25` es el tipo de cambio del euro al dólar; +- se ve que `6.91` es el tipo de cambio del dólar al yuan; +- se ve que `dollarsCount` es un resultado intermedio. + +Esto se nota especialmente si no vuelves al código durante al menos una semana. Y ahora imagina que un proyecto tiene cientos de miles de líneas de código. Si en tales proyectos no hubiera variables y cálculos intermedios, sería imposible entenderlos. + +## Qué hay que recordar -El intérprete calcula el valor de `dollarsCount` antes de que esta variable se utilice en otras expresiones. Cuando llega el momento de usar la variable, JavaScript "conoce" su valor porque ya lo ha calculado. +- Si una expresión resulta demasiado larga, es mejor dividirla en varios pasos. +- Las variables ayudan a guardar resultados intermedios y hacen los cálculos más claros. +- Cuando una variable se usa en una expresión, JavaScript sustituye su valor y continúa el cálculo. diff --git a/modules/30-variables/18-variable-concatenation/description.es.yml b/modules/30-variables/18-variable-concatenation/description.es.yml index 6ccc646e..6436bf02 100644 --- a/modules/30-variables/18-variable-concatenation/description.es.yml +++ b/modules/30-variables/18-variable-concatenation/description.es.yml @@ -1,62 +1,104 @@ --- -name: Variables y Concatenación +name: Variables y concatenación theory: | - Para reforzar el tema anterior, intentaremos utilizar variables con concatenación. Sintácticamente no cambia nada: sabemos cómo concatenar (unir) dos cadenas: + Anteriormente ya unimos cadenas directamente usando concatenación. Ahora haremos lo mismo, pero con variables. La buena noticia: la sintaxis sigue siendo la misma. Simplemente se sustituyen los valores de las variables. + + ## Unir dos cadenas directamente ```javascript - let what = 'Kings' + 'road'; + const what = 'Kings' + 'road'; console.log(what); // => Kingsroad ``` - ... lo que significa que también podemos concatenar una cadena y una variable en la que se almacena una cadena: + Aquí todo es sencillo: dos cadenas se unen en una. Así funciona la concatenación: el operador `+` suma las cadenas, creando una nueva cadena. + + ## Unir una cadena y una variable + + Si la variable `first` contiene la cadena `'Kings'`, podemos unirla tranquilamente con otra cadena: ```javascript - let primero = 'Kings'; - let que = primero + 'road'; + const first = 'Kings'; + const what = first + 'road'; + console.log(what); // => Kingsroad + ``` + + JavaScript sustituye el valor de la variable, ejecuta la operación y crea la cadena resultante. - console.log(que); // => Kingsroad + ## Unir dos variables + + De la misma manera, puedes combinar los valores de dos variables, si ambas contienen cadenas: + + ```javascript + const first = 'Kings'; + const last = 'road'; + const what = first + last; + console.log(what); // => Kingsroad ``` - ... e incluso concatenar dos variables en las que se almacenan cadenas: + También puedes agregar espacios: ```javascript - let primero = 'Kings'; - let ultimo = 'road'; + const full = first + ' ' + last; + console.log(full); // => Kings road + ``` - let que = primero + ultimo; - console.log(que); // => Kingsroad + ```text + first = 'Kings' + last = 'road' + + first + ' ' + last + └─┬──┘ └─┬┘ + 'Kings' + ' ' + 'road' + └────────┬─────────┘ + 'Kings road' ``` + ## ¿Y qué pasa si la variable contiene un número? -instructions: | + En JavaScript, el operador `+` se comporta de forma especial cuando de un lado hay una cadena y del otro un número. En ese caso, el número se convierte automáticamente en una cadena, y ocurre la concatenación: - Los sitios web envían constantemente correos electrónicos a sus usuarios. Una tarea típica es enviar automáticamente un correo electrónico personalizado, donde el título contendrá el nombre del usuario. Si en algún lugar de la base de datos del sitio se almacena el nombre de la persona como una cadena, la tarea de generar el título se reduce a la concatenación: por ejemplo, es necesario unir la cadena `Hola` con la cadena que contiene el nombre. + ```javascript + const age = 42; + console.log('Age: ' + age); // => Age: 42 + ``` - Escribe un programa que genere el título y el cuerpo del correo electrónico utilizando variables ya definidas, y muestra las cadenas resultantes en la pantalla. + Lo mismo ocurre con las variables que contienen resultados de cálculos: - Para el título, utiliza las variables `firstname` y `greeting`, seguidas de una coma y un signo de exclamación. Muestra esto en la pantalla en el orden correcto. + ```javascript + const price = 50 * 1.25 * 6.91; // => 431.875 + console.log('Price in yuans: ' + price); // => Price in yuans: 431.875 + ``` - Para el cuerpo del correo, utiliza las variables `info` e `intro`, asegurándote de que la segunda oración esté en una nueva línea. + También existe una conversión explícita de un número a una cadena mediante `String()`: la analizaremos en la lección sobre conversión de tipos. - El resultado en la pantalla se verá así: +instructions: | + + Escribe un programa que genere y muestre una carta de bienvenida. Usa **solamente dos** llamadas a `console.log()`. + + Define las variables: + + - `firstName` = `'Anna'` + - `greeting` = `'Hello'` + - `intro` = `'Thank you for your order.'` + - `info` = `'Expected delivery date — 3 business days.'` + + Salida esperada: ```text - Hello, Joffrey! - Here is important information about your account security. - We couldn't verify your mother's maiden name. + Hello, Anna! + Thank you for your order. + Expected delivery date — 3 business days. ``` - Realiza la tarea usando solamente dos `console.log()`. - tips: - | - Piensa en qué cadena y en qué orden debes concatenar las variables para obtener esa salida de dos líneas para el cuerpo del correo. + Piensa en qué cadena y en qué orden debes unir las variables para obtener esa salida de dos líneas del cuerpo de la carta. - | - Recuerda que puedes crear una cadena que contenga solo una secuencia de control `\n`. + Recuerda que puedes crear una cadena que contenga solo la secuencia de control `\n`. definitions: - name: Concatenación description: | - La operación de unir dos cadenas. Por ejemplo, `console.log("King's " + ' Landing');` + la operación de unir dos cadenas. Por ejemplo, `console.log("King's " + ' Landing');` diff --git a/modules/30-variables/18-variable-concatenation/en/EXERCISE.md b/modules/30-variables/18-variable-concatenation/en/EXERCISE.md index 3ce30df0..ae89fc78 100644 --- a/modules/30-variables/18-variable-concatenation/en/EXERCISE.md +++ b/modules/30-variables/18-variable-concatenation/en/EXERCISE.md @@ -1,18 +1,16 @@ +Write a program that builds and prints a greeting letter. Use **only two** `console.log()` calls. -Websites are constantly sending emails to their users. A common task is to automatically send a personalized email with the user's name in the header. If you store a person's name as a string somewhere in a website database, the task of generating the header boils down to concatenation. For instance, you have to concatenate the string `Hello` with a string containing their name. +Define the variables: -Write a program that will create a header and a body of the email using ready-made variables and print the resulting strings. +- `firstName` = `'Anna'` +- `greeting` = `'Hello'` +- `intro` = `'Thank you for your order.'` +- `info` = `'Expected delivery date — 3 business days.'` -For the header use the variables `firstName` and `greeting`, a comma, and an exclamation mark. Print it in the correct order. - -For the email body, use the variables `info` and `intro`, with the second sentence on a new line. - -The result should look like this: +Expected output: ```text -Hello, Joffrey! -Here is important information about your account security. -We couldn't verify your mother's maiden name. +Hello, Anna! +Thank you for your order. +Expected delivery date — 3 business days. ``` - -Complete the task using `console.log()` no more than twice. diff --git a/modules/30-variables/18-variable-concatenation/en/README.md b/modules/30-variables/18-variable-concatenation/en/README.md index 359cf4ca..f9ce97de 100644 --- a/modules/30-variables/18-variable-concatenation/en/README.md +++ b/modules/30-variables/18-variable-concatenation/en/README.md @@ -1,26 +1,69 @@ +Earlier, we already joined strings directly using concatenation. Now we'll do the same thing, but with variables. The good news: the syntax stays the same. The values of the variables are simply substituted in. -To consolidate the previous topic, let's try using variables with concatenation. The syntax remains the same, we know how to concatenate (combine) two strings: +## Joining two strings directly ```javascript -let what = 'Kings' + 'road'; -console.log(what); // => 'Kingsroad' +const what = 'Kings' + 'road'; +console.log(what); // => Kingsroad ``` -… which means we can concatenate the string with a variable containing the string: +Everything is simple here: two strings are joined into one. This is how concatenation works: the `+` operator adds strings together, creating a new string. + +## Joining a string and a variable + +If the variable `first` holds the string `'Kings'`, we can safely join it with another string: ```javascript -let first = 'Kings'; -let what = first + 'road'; +const first = 'Kings'; +const what = first + 'road'; +console.log(what); // => Kingsroad +``` + +JavaScript substitutes the value of the variable, performs the operation, and creates the resulting string. + +## Joining two variables -console.log(what); // => 'Kingsroad' +In the same way, you can combine the values of two variables, if both contain strings: + +```javascript +const first = 'Kings'; +const last = 'road'; +const what = first + last; +console.log(what); // => Kingsroad ``` -… and even concatenate two variables containing strings: +You can also add spaces: ```javascript -let first = 'Kings'; -let last = 'road'; +const full = first + ' ' + last; +console.log(full); // => Kings road +``` -let what = first + last; -console.log(what); // => 'Kingsroad' +```text +first = 'Kings' +last = 'road' + +first + ' ' + last +└─┬──┘ └─┬┘ +'Kings' + ' ' + 'road' +└────────┬─────────┘ + 'Kings road' ``` + +## What if the variable contains a number? + +In JavaScript, the `+` operator behaves in a special way when there's a string on one side and a number on the other. In this case, the number is automatically converted to a string, and concatenation happens: + +```javascript +const age = 42; +console.log('Age: ' + age); // => Age: 42 +``` + +The same applies to variables holding the results of computations: + +```javascript +const price = 50 * 1.25 * 6.91; // => 431.875 +console.log('Price in yuans: ' + price); // => Price in yuans: 431.875 +``` + +There's also an explicit way to convert a number to a string using `String()` — we'll cover it in the lesson about type coercion. diff --git a/modules/30-variables/18-variable-concatenation/en/data.yml b/modules/30-variables/18-variable-concatenation/en/data.yml index a5b81f90..374c5ca0 100644 --- a/modules/30-variables/18-variable-concatenation/en/data.yml +++ b/modules/30-variables/18-variable-concatenation/en/data.yml @@ -1,9 +1,14 @@ --- name: Variables and concatenation tips: - - > - Consider how you should concatenate the variables (Which string? What - order?) to get the two-line output of the email body. - - > - Remember that you can create a string containing only the escape sequence - `\n`. + - | + Think about which string and in what order you need to join the variables + with to get this two-line body of the letter. + - | + Remember that you can create a string that contains only the escape + sequence `\n`. +definitions: + - name: Concatenation + description: > + the operation of joining two strings. For example, `console.log("King's " + + ' Landing');` diff --git a/modules/30-variables/18-variable-concatenation/es/EXERCISE.md b/modules/30-variables/18-variable-concatenation/es/EXERCISE.md index ce1b8c30..bdb4abf2 100644 --- a/modules/30-variables/18-variable-concatenation/es/EXERCISE.md +++ b/modules/30-variables/18-variable-concatenation/es/EXERCISE.md @@ -1,18 +1,16 @@ +Escribe un programa que genere y muestre una carta de bienvenida. Usa **solamente dos** llamadas a `console.log()`. -Los sitios web envían constantemente correos electrónicos a sus usuarios. Una tarea típica es enviar automáticamente un correo electrónico personalizado, donde el título contendrá el nombre del usuario. Si en algún lugar de la base de datos del sitio se almacena el nombre de la persona como una cadena, la tarea de generar el título se reduce a la concatenación: por ejemplo, es necesario unir la cadena `Hola` con la cadena que contiene el nombre. +Define las variables: -Escribe un programa que genere el título y el cuerpo del correo electrónico utilizando variables ya definidas, y muestra las cadenas resultantes en la pantalla. +- `firstName` = `'Anna'` +- `greeting` = `'Hello'` +- `intro` = `'Thank you for your order.'` +- `info` = `'Expected delivery date — 3 business days.'` -Para el título, utiliza las variables `firstname` y `greeting`, seguidas de una coma y un signo de exclamación. Muestra esto en la pantalla en el orden correcto. - -Para el cuerpo del correo, utiliza las variables `info` e `intro`, asegurándote de que la segunda oración esté en una nueva línea. - -El resultado en la pantalla se verá así: +Salida esperada: ```text -Hello, Joffrey! -Here is important information about your account security. -We couldn't verify your mother's maiden name. +Hello, Anna! +Thank you for your order. +Expected delivery date — 3 business days. ``` - -Realiza la tarea usando solamente dos `console.log()`. diff --git a/modules/30-variables/18-variable-concatenation/es/README.md b/modules/30-variables/18-variable-concatenation/es/README.md index 697f6bde..6a2cca40 100644 --- a/modules/30-variables/18-variable-concatenation/es/README.md +++ b/modules/30-variables/18-variable-concatenation/es/README.md @@ -1,26 +1,69 @@ +Anteriormente ya unimos cadenas directamente usando concatenación. Ahora haremos lo mismo, pero con variables. La buena noticia: la sintaxis sigue siendo la misma. Simplemente se sustituyen los valores de las variables. -Para reforzar el tema anterior, intentaremos utilizar variables con concatenación. Sintácticamente no cambia nada: sabemos cómo concatenar (unir) dos cadenas: +## Unir dos cadenas directamente ```javascript -let what = 'Kings' + 'road'; +const what = 'Kings' + 'road'; console.log(what); // => Kingsroad ``` -... lo que significa que también podemos concatenar una cadena y una variable en la que se almacena una cadena: +Aquí todo es sencillo: dos cadenas se unen en una. Así funciona la concatenación: el operador `+` suma las cadenas, creando una nueva cadena. + +## Unir una cadena y una variable + +Si la variable `first` contiene la cadena `'Kings'`, podemos unirla tranquilamente con otra cadena: ```javascript -let primero = 'Kings'; -let que = primero + 'road'; +const first = 'Kings'; +const what = first + 'road'; +console.log(what); // => Kingsroad +``` + +JavaScript sustituye el valor de la variable, ejecuta la operación y crea la cadena resultante. + +## Unir dos variables -console.log(que); // => Kingsroad +De la misma manera, puedes combinar los valores de dos variables, si ambas contienen cadenas: + +```javascript +const first = 'Kings'; +const last = 'road'; +const what = first + last; +console.log(what); // => Kingsroad ``` -... e incluso concatenar dos variables en las que se almacenan cadenas: +También puedes agregar espacios: ```javascript -let primero = 'Kings'; -let ultimo = 'road'; +const full = first + ' ' + last; +console.log(full); // => Kings road +``` + +```text +first = 'Kings' +last = 'road' -let que = primero + ultimo; -console.log(que); // => Kingsroad +first + ' ' + last +└─┬──┘ └─┬┘ +'Kings' + ' ' + 'road' +└────────┬─────────┘ + 'Kings road' ``` + +## ¿Y qué pasa si la variable contiene un número? + +En JavaScript, el operador `+` se comporta de forma especial cuando de un lado hay una cadena y del otro un número. En ese caso, el número se convierte automáticamente en una cadena, y ocurre la concatenación: + +```javascript +const age = 42; +console.log('Age: ' + age); // => Age: 42 +``` + +Lo mismo ocurre con las variables que contienen resultados de cálculos: + +```javascript +const price = 50 * 1.25 * 6.91; // => 431.875 +console.log('Price in yuans: ' + price); // => Price in yuans: 431.875 +``` + +También existe una conversión explícita de un número a una cadena mediante `String()`: la analizaremos en la lección sobre conversión de tipos. diff --git a/modules/30-variables/18-variable-concatenation/es/data.yml b/modules/30-variables/18-variable-concatenation/es/data.yml index 8a1836d4..fa94fa45 100644 --- a/modules/30-variables/18-variable-concatenation/es/data.yml +++ b/modules/30-variables/18-variable-concatenation/es/data.yml @@ -1,14 +1,14 @@ --- -name: Variables y Concatenación +name: Variables y concatenación tips: - - > - Piensa en qué cadena y en qué orden debes concatenar las variables para - obtener esa salida de dos líneas para el cuerpo del correo. - - > - Recuerda que puedes crear una cadena que contenga solo una secuencia de + - | + Piensa en qué cadena y en qué orden debes unir las variables para obtener + esa salida de dos líneas del cuerpo de la carta. + - | + Recuerda que puedes crear una cadena que contenga solo la secuencia de control `\n`. definitions: - name: Concatenación description: > - La operación de unir dos cadenas. Por ejemplo, `console.log("King's " + ' + la operación de unir dos cadenas. Por ejemplo, `console.log("King's " + ' Landing');` diff --git a/modules/30-variables/18-variable-concatenation/index.js b/modules/30-variables/18-variable-concatenation/index.js index cbf1e002..ddfc253d 100644 --- a/modules/30-variables/18-variable-concatenation/index.js +++ b/modules/30-variables/18-variable-concatenation/index.js @@ -1,8 +1,8 @@ // BEGIN -const firstName = 'Анна'; -const greeting = 'Здравствуйте'; -const intro = 'Спасибо за ваш заказ.'; -const info = 'Ожидаемая дата доставки — 3 рабочих дня.'; +const firstName = 'Anna'; +const greeting = 'Hello'; +const intro = 'Thank you for your order.'; +const info = 'Expected delivery date — 3 business days.'; console.log(greeting + ', ' + firstName + '!'); console.log(intro + '\n' + info); diff --git a/modules/30-variables/18-variable-concatenation/ru/EXERCISE.md b/modules/30-variables/18-variable-concatenation/ru/EXERCISE.md index d0e393b6..8462cff0 100644 --- a/modules/30-variables/18-variable-concatenation/ru/EXERCISE.md +++ b/modules/30-variables/18-variable-concatenation/ru/EXERCISE.md @@ -2,15 +2,15 @@ Определите переменные: -- `firstName` = `'Анна'` -- `greeting` = `'Здравствуйте'` -- `intro` = `'Спасибо за ваш заказ.'` -- `info` = `'Ожидаемая дата доставки — 3 рабочих дня.'` +- `firstName` = `'Anna'` +- `greeting` = `'Hello'` +- `intro` = `'Thank you for your order.'` +- `info` = `'Expected delivery date — 3 business days.'` Ожидаемый вывод: ```text -Здравствуйте, Анна! -Спасибо за ваш заказ. -Ожидаемая дата доставки — 3 рабочих дня. +Hello, Anna! +Thank you for your order. +Expected delivery date — 3 business days. ``` diff --git a/modules/30-variables/18-variable-concatenation/test.js b/modules/30-variables/18-variable-concatenation/test.js index 06519be1..60501131 100644 --- a/modules/30-variables/18-variable-concatenation/test.js +++ b/modules/30-variables/18-variable-concatenation/test.js @@ -9,6 +9,6 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); expect(firstArg).toBe( - 'Здравствуйте, Анна!\nСпасибо за ваш заказ.\nОжидаемая дата доставки — 3 рабочих дня.', + 'Hello, Anna!\nThank you for your order.\nExpected delivery date — 3 business days.', ); }); diff --git a/modules/30-variables/19-naming-style/description.es.yml b/modules/30-variables/19-naming-style/description.es.yml index 4df9efa1..a81a5a9b 100644 --- a/modules/30-variables/19-naming-style/description.es.yml +++ b/modules/30-variables/19-naming-style/description.es.yml @@ -1,24 +1,57 @@ --- -name: Estilos de nomenclatura +name: Estilos de nombrado theory: | - `greeting` — un ejemplo de un nombre simple, pero no todos los nombres son tan simples. A menudo son compuestos, es decir, incluyen varias palabras. Por ejemplo, "nombre de usuario". En diferentes idiomas se utilizan diferentes estilos de codificación y el nombre de la variable será diferente. + `greeting` es un ejemplo de un nombre de variable simple y claro. Pero a menudo nombres como `name`, `email` o `price` no son suficientes. Por ejemplo, puede que necesites describir el nombre de un usuario, la cantidad total de pedidos o la longitud máxima de un mensaje. Tales nombres ya constan de varias palabras. ¿Cómo se verá el nombre de la variable en este caso? - En la nomenclatura de variables se pueden identificar cuatro enfoques principales, que a veces se combinan entre sí. Todos estos enfoques se aplican cuando el nombre de la variable consta de varias palabras: + En los distintos lenguajes de programación se usan diferentes estilos de nombrado. De esto depende cómo se verá el nombre de una variable compuesta por varias palabras. Por ejemplo, así se puede escribir una variable que almacena la longitud máxima de un mensaje: - * kebab-case — las partes compuestas de la variable se separan con guiones. Por ejemplo: `mi-super-var`. - * snake_case — se utiliza un guion bajo para separar las palabras. Por ejemplo: `mi_super_var`. - * CamelCase — cada palabra en la variable se escribe con mayúscula. Por ejemplo: `MiSuperVar`. - * lowerCamelCase — cada palabra en la variable se escribe con mayúscula, excepto la primera. Por ejemplo: `miSuperVar`. + 1. `maxmessagelength` + 1. `maxMessageLength` + 1. `max-message-length` + 1. `max_message_length` - En JavaScript se utiliza CamelCase y su variante lowerCamelCase, donde la primera letra de la primera palabra es minúscula. Es precisamente lowerCamelCase el que se utiliza para las variables. Esto significa que los nombres se unen entre sí, y todas las palabras excepto la primera se convierten en mayúsculas: `userName`. Con tres palabras se vería así: `miSuperVariable`. + ## Estilos principales + + Estos son algunos enfoques populares para escribir nombres compuestos: + + - **kebab-case**: las palabras se separan con un guion — `max-message-length`. + + No funciona en JavaScript, ya que el guion (`-`) se interpreta como el operador de resta. + + - **snake_case**: las palabras se separan con un guion bajo — `max_message_length`. Este es el estándar en algunos otros lenguajes, por ejemplo en Python. + + - **CamelCase** (o UpperCamelCase): cada palabra comienza con mayúscula, sin separadores — `MaxMessageLength`. En JavaScript, así se suele nombrar a las clases. + + - **lowerCamelCase**: lo mismo, pero la primera palabra comienza con minúscula — `maxMessageLength`. + + ## Cómo hacerlo correctamente en JavaScript + + El estándar para las variables en JavaScript es **lowerCamelCase**: la primera palabra en minúsculas y cada palabra siguiente con mayúscula inicial. + + ```javascript + const userName = 'Daenerys'; + const maxLength = 280; + const totalOrdersCount = 17; + ``` + + ## Cómo no hacerlo + + No conviene incluir el tipo de dato en el nombre de una variable. Tales nombres se leen peor y quedan obsoletos rápidamente. Por ejemplo, `userNameString` o `messagesNumber` describen no el significado de la variable, sino su implementación técnica. + + El nombre debe responder a la pregunta "¿qué se almacena?", y no "¿de qué tipo es?". Por eso es mejor escribir `userName` en lugar de `userNameString`, y `messagesCount` en lugar de `messagesNumber`. instructions: | - Crea dos variables con los nombres "primer número" y "segundo número" en inglés, utilizando lowerCamelCase. Asigna el número `11` a la primera variable y `-100` a la segunda. Imprime en pantalla el producto de los números almacenados en las variables resultantes. + Escribe un programa que calcule e imprima en pantalla el costo de una compra. + + Crea dos variables en estilo lowerCamelCase: + + - cantidad de productos: `20` + - precio de un producto: `100` - El código funcionará con cualquier nombre, y nuestro sistema siempre verifica solamente el resultado en pantalla, por lo que la ejecución de esta tarea es responsabilidad tuya. + Imprime su producto. tips: - | diff --git a/modules/30-variables/19-naming-style/en/EXERCISE.md b/modules/30-variables/19-naming-style/en/EXERCISE.md index 99c1ab57..6e67557b 100644 --- a/modules/30-variables/19-naming-style/en/EXERCISE.md +++ b/modules/30-variables/19-naming-style/en/EXERCISE.md @@ -1,4 +1,8 @@ +Write a program that calculates and prints the cost of a purchase to the screen. -Create two variables named "first number" and "second number" using lowerCamelCase. Assign `11` to the first variable and `-100` to the second. Print their product. +Create two variables in lowerCamelCase style: -The code will work with any name, and we only check the printed result, so the task is up to you. +- number of items: `20` +- price of one item: `100` + +Print their product. diff --git a/modules/30-variables/19-naming-style/en/README.md b/modules/30-variables/19-naming-style/en/README.md index 8ff6b074..fe7d12ed 100644 --- a/modules/30-variables/19-naming-style/en/README.md +++ b/modules/30-variables/19-naming-style/en/README.md @@ -1,11 +1,38 @@ +`greeting` is an example of a simple and clear variable name. But often names like `name`, `email` or `price` are not enough. For example, you may need to describe a user's name, the total number of orders, or the maximum length of a message. Such names already consist of several words. What will a variable name look like in this case? -`greeting` is an example of a simple name, although not all of them are that simple. Often, they are a combination of several words. For example, "user password". Different languages have different naming styles for variables. +Different programming languages use different naming styles. This determines how a variable name made of several words will look. For example, here is how you can write a variable that stores the maximum length of a message: -Four main variable naming conventions are sometimes combined. These conventions apply to variable names consisting of several words: +1. `maxmessagelength` +1. `maxMessageLength` +1. `max-message-length` +1. `max_message_length` -* kebab-case – a hyphen separates the parts of the name. For example, `my-super-var` -* snake_case - an underscore is used as a separator. For example, `my_super_var` -* CamelCase - each word in the name is capitalized. For example, `MySuperVar` -* lowerCamelCase - each word is capitalized except the first. For example, `mySuperVar` +## Main styles -Javascript uses CamelCase and its variation lowerCamelCase, with the first letter of the first word in lowercase. We use lowerCamelCase for variables. It means we concatenate the words, and all the words apart from the first are capitalized: `userName`. With three words it looks like this: `mySuperVariable`. +Here are a few popular approaches to writing compound names: + +- **kebab-case**: words are separated by a hyphen — `max-message-length`. + + It doesn't work in JavaScript, because the hyphen (`-`) is interpreted as the subtraction operator. + +- **snake_case**: words are separated by an underscore — `max_message_length`. This is the standard in some other languages, for example in Python. + +- **CamelCase** (or UpperCamelCase): each word starts with a capital letter, with no separators — `MaxMessageLength`. In JavaScript, this is how classes are usually named. + +- **lowerCamelCase**: the same thing, but the first word starts with a lowercase letter — `maxMessageLength`. + +## How to do it right in JavaScript + +The standard for variables in JavaScript is **lowerCamelCase**: the first word is in lowercase letters, and each subsequent one starts with a capital letter. + +```javascript +const userName = 'Daenerys'; +const maxLength = 280; +const totalOrdersCount = 17; +``` + +## How not to do it + +You shouldn't include the data type in a variable name. Such names are harder to read and quickly become outdated. For example, `userNameString` or `messagesNumber` describe not the meaning of the variable but its technical implementation. + +A name should answer the question "what is stored?", not "what type is it?". That's why it's better to write `userName` instead of `userNameString`, and `messagesCount` instead of `messagesNumber`. diff --git a/modules/30-variables/19-naming-style/en/data.yml b/modules/30-variables/19-naming-style/en/data.yml index ef4cc20c..bfd565d3 100644 --- a/modules/30-variables/19-naming-style/en/data.yml +++ b/modules/30-variables/19-naming-style/en/data.yml @@ -1,6 +1,8 @@ --- name: Naming styles -tips: [] +tips: + - | + [CamelCase](https://en.wikipedia.org/wiki/CamelCase) definitions: - - name: Coding standards - description: are a list of syntax and style conventions for code writing. + - name: Coding standard + description: A set of syntactic and stylistic rules for writing code. diff --git a/modules/30-variables/19-naming-style/es/EXERCISE.md b/modules/30-variables/19-naming-style/es/EXERCISE.md index 986bdffe..2a2a2ac1 100644 --- a/modules/30-variables/19-naming-style/es/EXERCISE.md +++ b/modules/30-variables/19-naming-style/es/EXERCISE.md @@ -1,4 +1,8 @@ +Escribe un programa que calcule e imprima en pantalla el costo de una compra. -Crea dos variables con los nombres "primer número" y "segundo número" en inglés, utilizando lowerCamelCase. Asigna el número `11` a la primera variable y `-100` a la segunda. Imprime en pantalla el producto de los números almacenados en las variables resultantes. +Crea dos variables en estilo lowerCamelCase: -El código funcionará con cualquier nombre, y nuestro sistema siempre verifica solamente el resultado en pantalla, por lo que la ejecución de esta tarea es responsabilidad tuya. +- cantidad de productos: `20` +- precio de un producto: `100` + +Imprime su producto. diff --git a/modules/30-variables/19-naming-style/es/README.md b/modules/30-variables/19-naming-style/es/README.md index e31fedd1..4c204ea0 100644 --- a/modules/30-variables/19-naming-style/es/README.md +++ b/modules/30-variables/19-naming-style/es/README.md @@ -1,11 +1,38 @@ +`greeting` es un ejemplo de un nombre de variable simple y claro. Pero a menudo nombres como `name`, `email` o `price` no son suficientes. Por ejemplo, puede que necesites describir el nombre de un usuario, la cantidad total de pedidos o la longitud máxima de un mensaje. Tales nombres ya constan de varias palabras. ¿Cómo se verá el nombre de la variable en este caso? -`greeting` — un ejemplo de un nombre simple, pero no todos los nombres son tan simples. A menudo son compuestos, es decir, incluyen varias palabras. Por ejemplo, "nombre de usuario". En diferentes idiomas se utilizan diferentes estilos de codificación y el nombre de la variable será diferente. +En los distintos lenguajes de programación se usan diferentes estilos de nombrado. De esto depende cómo se verá el nombre de una variable compuesta por varias palabras. Por ejemplo, así se puede escribir una variable que almacena la longitud máxima de un mensaje: -En la nomenclatura de variables se pueden identificar cuatro enfoques principales, que a veces se combinan entre sí. Todos estos enfoques se aplican cuando el nombre de la variable consta de varias palabras: +1. `maxmessagelength` +1. `maxMessageLength` +1. `max-message-length` +1. `max_message_length` -* kebab-case — las partes compuestas de la variable se separan con guiones. Por ejemplo: `mi-super-var`. -* snake_case — se utiliza un guion bajo para separar las palabras. Por ejemplo: `mi_super_var`. -* CamelCase — cada palabra en la variable se escribe con mayúscula. Por ejemplo: `MiSuperVar`. -* lowerCamelCase — cada palabra en la variable se escribe con mayúscula, excepto la primera. Por ejemplo: `miSuperVar`. +## Estilos principales -En JavaScript se utiliza CamelCase y su variante lowerCamelCase, donde la primera letra de la primera palabra es minúscula. Es precisamente lowerCamelCase el que se utiliza para las variables. Esto significa que los nombres se unen entre sí, y todas las palabras excepto la primera se convierten en mayúsculas: `userName`. Con tres palabras se vería así: `miSuperVariable`. +Estos son algunos enfoques populares para escribir nombres compuestos: + +- **kebab-case**: las palabras se separan con un guion — `max-message-length`. + + No funciona en JavaScript, ya que el guion (`-`) se interpreta como el operador de resta. + +- **snake_case**: las palabras se separan con un guion bajo — `max_message_length`. Este es el estándar en algunos otros lenguajes, por ejemplo en Python. + +- **CamelCase** (o UpperCamelCase): cada palabra comienza con mayúscula, sin separadores — `MaxMessageLength`. En JavaScript, así se suele nombrar a las clases. + +- **lowerCamelCase**: lo mismo, pero la primera palabra comienza con minúscula — `maxMessageLength`. + +## Cómo hacerlo correctamente en JavaScript + +El estándar para las variables en JavaScript es **lowerCamelCase**: la primera palabra en minúsculas y cada palabra siguiente con mayúscula inicial. + +```javascript +const userName = 'Daenerys'; +const maxLength = 280; +const totalOrdersCount = 17; +``` + +## Cómo no hacerlo + +No conviene incluir el tipo de dato en el nombre de una variable. Tales nombres se leen peor y quedan obsoletos rápidamente. Por ejemplo, `userNameString` o `messagesNumber` describen no el significado de la variable, sino su implementación técnica. + +El nombre debe responder a la pregunta "¿qué se almacena?", y no "¿de qué tipo es?". Por eso es mejor escribir `userName` en lugar de `userNameString`, y `messagesCount` en lugar de `messagesNumber`. diff --git a/modules/30-variables/19-naming-style/es/data.yml b/modules/30-variables/19-naming-style/es/data.yml index f0a2c41c..10dd4a54 100644 --- a/modules/30-variables/19-naming-style/es/data.yml +++ b/modules/30-variables/19-naming-style/es/data.yml @@ -1,5 +1,5 @@ --- -name: Estilos de nomenclatura +name: Estilos de nombrado tips: - | [CamelCase](https://es.wikipedia.org/wiki/CamelCase) diff --git a/modules/30-variables/20-magic-numbers/description.es.yml b/modules/30-variables/20-magic-numbers/description.es.yml index 6abcb3ff..84ea6f7a 100644 --- a/modules/30-variables/20-magic-numbers/description.es.yml +++ b/modules/30-variables/20-magic-numbers/description.es.yml @@ -3,62 +3,61 @@ name: Números mágicos theory: | - Recordemos una de las lecciones anteriores: + Veamos un ejemplo de un programa que realiza la conversión de divisas: ```javascript - let dollarsCount = 50 * 1.25; // 62.5 - let rublesCount = dollarsCount * 60; // 3750 + const eurosCount = 1000; + const dollarsCount = eurosCount * 1.25; // => 1250 + const rublesCount = dollarsCount * 60; // => 75000 console.log(rublesCount); ``` - Desde el punto de vista del desarrollo profesional, este código "huele mal". Así es como se describe el código que es difícil de entender. Y la razón es la siguiente: en este momento, al ver los números `60` y `1.25`, es probable que te preguntes: "¿qué significan estos números?". ¡Imagínate cómo será dentro de un mes! Y cómo lo entenderá un nuevo programador que no haya visto el código antes. En nuestro ejemplo, el contexto se recupera gracias a una buena nomenclatura, pero en la vida real, el código es mucho más complicado, y a menudo, es imposible adivinar el significado de los números. + Técnicamente, el código funciona. Pero desde el punto de vista del desarrollo profesional, este tipo de código se considera una mala práctica. - Estos números que no se pueden entender sin un profundo conocimiento de lo que está sucediendo dentro de una parte específica del código se llaman Números mágicos. + ## ¿Cuál es el problema? - La solución es simple: solamente necesitas crear variables con nombres adecuados y todo encajará en su lugar. + En las expresiones se usan números poco claros: `1.25` y `60`. ¿Qué son estos valores? ¿Un tipo de cambio? ¿De dónde salieron? Dentro de un mes o un año, lo más probable es que no recuerdes qué significan estos números. Y si otro desarrollador abre el código, simplemente no entenderá de dónde sale todo. Estos números se llaman mágicos. + + Los números mágicos son valores numéricos cuyo significado no queda claro a partir del código. Por lo general, se usan directamente en expresiones matemáticas, sin variables con nombres comprensibles. Para entender su propósito, hay que profundizar en el contexto o leer documentación adicional. Los números mágicos dificultan la lectura, la comprensión y el mantenimiento del código. + + ## Cómo evitar la magia + + La forma más sencilla consiste en extraer dichos valores a variables con nombres comprensibles. Entonces el significado se vuelve evidente: ```javascript - let dollarsPerEuro = 1.25; - let rublesPerDollar = 60; + const dollarsPerEuro = 1.25; + const rublesPerDollar = 60; - let dollarsCount = 50 * dollarsPerEuro; // 62.5 - let rublesCount = dollarsCount * rublesPerDollar; // 3750 + const eurosCount = 1000; + const dollarsCount = eurosCount * dollarsPerEuro; // => 1250 + const rublesCount = dollarsCount * rublesPerDollar; // => 75000 console.log(rublesCount); ``` - Presta atención a los siguientes detalles: + Los números en sí no han desaparecido, pero ahora están almacenados en variables cuyos nombres indican sin ambigüedad qué son. - * Nomenclatura en lowerCamelCase. - * Las dos nuevas variables están separadas de los cálculos posteriores por una línea en blanco. Estas variables tienen sentido incluso sin los cálculos, por lo que esta separación es apropiada y mejora la legibilidad. - * El código resultante es más largo que la versión anterior, pero eso es normal. El código debe ser legible. + ## Conclusión + + Los números mágicos hacen que el código sea poco claro y difícil de mantener. Para evitar este problema, hay que reemplazar dichos números por variables con nombres significativos. Esto hace que el código sea más legible, especialmente a largo plazo. El código claro siempre es más importante que la compacidad, incluso si el programa se vuelve un poco más largo. instructions: | - Te has encontrado con el siguiente código que muestra la cantidad total de habitaciones en posesión del actual rey: + En un almacén hay palés con cajas. Extrae los números "mágicos" `6` y `17` a variables con nombre e imprime el resultado. ```javascript - let king = 'King Balon the 6th'; - console.log(king + ' has ' + (6 * 17) + ' rooms.'); + console.log('Boxes in stock:'); + console.log(6 * 17); ``` - Como puedes ver, estos son números mágicos: no está claro qué significa el 6 y qué significa el 17. Puedes adivinarlo si conoces la historia de la familia real: cada nuevo rey hereda todos los castillos de sus antepasados y construye un nuevo castillo, una copia exacta del castillo de sus padres. - - Esta extraña dinastía simplemente está multiplicando castillos idénticos... - - Elimina los números mágicos creando nuevas variables y muestra el texto en la pantalla. - - Debería verse así: + Salida esperada: ```text - King Balon the 6th has 102 rooms. + Boxes in stock: + 102 ``` - Los nombres de las variables deben transmitir el significado de los números, pero al mismo tiempo deben ser lo suficientemente cortos y concisos para una lectura cómoda. - - Recuerda: el código funcionará con cualquier nombre, y nuestro sistema siempre verifica solamente el resultado en la pantalla, por lo que completar esta tarea es tu responsabilidad. - tips: - | - [Números mágicos](https://es.wikipedia.org/wiki/N%C3%BAmero_m%C3%A1gico_(programaci%C3%B3n)) + [Número mágico](https://es.wikipedia.org/wiki/N%C3%BAmero_m%C3%A1gico_(inform%C3%A1tica)) diff --git a/modules/30-variables/20-magic-numbers/en/EXERCISE.md b/modules/30-variables/20-magic-numbers/en/EXERCISE.md index 3bbbbe59..fd9957d4 100644 --- a/modules/30-variables/20-magic-numbers/en/EXERCISE.md +++ b/modules/30-variables/20-magic-numbers/en/EXERCISE.md @@ -1,23 +1,13 @@ - -You've come across some code printing the total number of rooms owned by the present king: +There are pallets with boxes in a warehouse. Extract the "magic" numbers `6` and `17` into named variables and print the result. ```javascript -let king = 'King Balon the 6th'; -console.log(king + ' has ' + (6 * 17) + ' rooms.'); +console.log('Boxes in stock:'); +console.log(6 * 17); ``` -As you can see, these numbers are magical: it is not clear what 6 and 17 are. If you know the history of the royal family, you can guess: each new king inherits all his ancestors' castles and builds a new one, an exact copy of his parents'. - -This strange dynasty simply breeds identical castles... - -Get rid of the magic numbers by creating new variables and print them. - -You'll get this: +Expected output: ```text -King Balon the 6th has 102 rooms. +Boxes in stock: +102 ``` - -The variable names should give the meaning of the numbers, but should also be short and succinct enough to be readable. - -Note: The code will work with any name, and we only check the printed result, so the task is up to you. diff --git a/modules/30-variables/20-magic-numbers/en/README.md b/modules/30-variables/20-magic-numbers/en/README.md index 06be31f1..500a5970 100644 --- a/modules/30-variables/20-magic-numbers/en/README.md +++ b/modules/30-variables/20-magic-numbers/en/README.md @@ -1,31 +1,38 @@ - -Let's remember one of the previous lessons: +Let's look at an example of a program that performs currency conversion: ```javascript -let dollarsCount = 50 * 1.25; // 62.5 -let rublesCount = dollarsCount * 60; // 3750 +const eurosCount = 1000; +const dollarsCount = eurosCount * 1.25; // => 1250 +const rublesCount = dollarsCount * 60; // => 75000 console.log(rublesCount); ``` -From the developer's point of view, such code "smells". It means that the code is hard to comprehend. Even now, when you look at the numbers `60` and `1.25`now, you might find yourself asking, "What are those numbers?" Imagine reading it in a month from now! How could a new programmer who hasn't seen the code before understand it? In our example, you can reconstruct the context through proper naming, but in real life, the code is much more complicated, and it is often impossible to guess the meaning of numbers. +Technically, the code works. But from a professional development standpoint, such code is considered bad practice. + +## What's the problem? + +The expressions use unclear numbers: `1.25` and `60`. What are these values? An exchange rate? Where did they come from? In a month or a year, you most likely won't remember what these numbers mean. And if another developer opens the code, they simply won't understand where everything comes from. Such numbers are called magic. -This "smell" is known as Magic Numbers. The numbers with an inexplicable origin, which you can only understand by digging deeper into the code. +Magic numbers are numeric values whose meaning is not clear from the code. They are usually used directly in mathematical expressions, without variables that have meaningful names. To understand their purpose, you have to dig into the context or read additional documentation. Magic numbers make code harder to read, understand, and maintain. -The solution is simple: create variables with the right names, and everything will fall into place. +## How to avoid the magic + +The simplest way is to extract such values into variables with clear names. Then the meaning becomes obvious: ```javascript -let dollarsPerEuro = 1.25; -let rublesPerDollar = 60; +const dollarsPerEuro = 1.25; +const rublesPerDollar = 60; -let dollarsCount = 50 * dollarsPerEuro; // 62.5 -let rublesCount = dollarsCount * rublesPerDollar; // 3750 +const eurosCount = 1000; +const dollarsCount = eurosCount * dollarsPerEuro; // => 1250 +const rublesCount = dollarsCount * rublesPerDollar; // => 75000 console.log(rublesCount); ``` -Note the following details: +The numbers themselves haven't gone anywhere, but now they are stored in variables whose names unambiguously tell you what they are. + +## Conclusion -* lowerCamelCase naming -* The two new variables are separated from the following computations by an empty line. These variables are meaningful even without a computation involved, which is why this separation is suitable here: it improves readability -* The code is well named and structured, but it is longer than the previous version. It happens every so often and that's okay. The code must be readable +Magic numbers make code unclear and hard to maintain. To avoid this problem, you should replace such numbers with variables that have meaningful names. This makes the code more readable, especially in the long run. Clear code is always more important than compactness, even if the program becomes a bit longer. diff --git a/modules/30-variables/20-magic-numbers/en/data.yml b/modules/30-variables/20-magic-numbers/en/data.yml index 9b0d5d95..3099c096 100644 --- a/modules/30-variables/20-magic-numbers/en/data.yml +++ b/modules/30-variables/20-magic-numbers/en/data.yml @@ -1,3 +1,5 @@ --- name: Magic numbers -tips: [] +tips: + - | + [Magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)) diff --git a/modules/30-variables/20-magic-numbers/es/EXERCISE.md b/modules/30-variables/20-magic-numbers/es/EXERCISE.md index 6c9e2544..54d12a75 100644 --- a/modules/30-variables/20-magic-numbers/es/EXERCISE.md +++ b/modules/30-variables/20-magic-numbers/es/EXERCISE.md @@ -1,23 +1,13 @@ - -Te has encontrado con el siguiente código que muestra la cantidad total de habitaciones en posesión del actual rey: +En un almacén hay palés con cajas. Extrae los números "mágicos" `6` y `17` a variables con nombre e imprime el resultado. ```javascript -let king = 'King Balon the 6th'; -console.log(king + ' has ' + (6 * 17) + ' rooms.'); +console.log('Boxes in stock:'); +console.log(6 * 17); ``` -Como puedes ver, estos son números mágicos: no está claro qué significa el 6 y qué significa el 17. Puedes adivinarlo si conoces la historia de la familia real: cada nuevo rey hereda todos los castillos de sus antepasados y construye un nuevo castillo, una copia exacta del castillo de sus padres. - -Esta extraña dinastía simplemente está multiplicando castillos idénticos... - -Elimina los números mágicos creando nuevas variables y muestra el texto en la pantalla. - -Debería verse así: +Salida esperada: ```text -King Balon the 6th has 102 rooms. +Boxes in stock: +102 ``` - -Los nombres de las variables deben transmitir el significado de los números, pero al mismo tiempo deben ser lo suficientemente cortos y concisos para una lectura cómoda. - -Recuerda: el código funcionará con cualquier nombre, y nuestro sistema siempre verifica solamente el resultado en la pantalla, por lo que completar esta tarea es tu responsabilidad. diff --git a/modules/30-variables/20-magic-numbers/es/README.md b/modules/30-variables/20-magic-numbers/es/README.md index 0dab960d..46daf912 100644 --- a/modules/30-variables/20-magic-numbers/es/README.md +++ b/modules/30-variables/20-magic-numbers/es/README.md @@ -1,31 +1,38 @@ - -Recordemos una de las lecciones anteriores: +Veamos un ejemplo de un programa que realiza la conversión de divisas: ```javascript -let dollarsCount = 50 * 1.25; // 62.5 -let rublesCount = dollarsCount * 60; // 3750 +const eurosCount = 1000; +const dollarsCount = eurosCount * 1.25; // => 1250 +const rublesCount = dollarsCount * 60; // => 75000 console.log(rublesCount); ``` -Desde el punto de vista del desarrollo profesional, este código "huele mal". Así es como se describe el código que es difícil de entender. Y la razón es la siguiente: en este momento, al ver los números `60` y `1.25`, es probable que te preguntes: "¿qué significan estos números?". ¡Imagínate cómo será dentro de un mes! Y cómo lo entenderá un nuevo programador que no haya visto el código antes. En nuestro ejemplo, el contexto se recupera gracias a una buena nomenclatura, pero en la vida real, el código es mucho más complicado, y a menudo, es imposible adivinar el significado de los números. +Técnicamente, el código funciona. Pero desde el punto de vista del desarrollo profesional, este tipo de código se considera una mala práctica. + +## ¿Cuál es el problema? + +En las expresiones se usan números poco claros: `1.25` y `60`. ¿Qué son estos valores? ¿Un tipo de cambio? ¿De dónde salieron? Dentro de un mes o un año, lo más probable es que no recuerdes qué significan estos números. Y si otro desarrollador abre el código, simplemente no entenderá de dónde sale todo. Estos números se llaman mágicos. -Estos números que no se pueden entender sin un profundo conocimiento de lo que está sucediendo dentro de una parte específica del código se llaman Números mágicos. +Los números mágicos son valores numéricos cuyo significado no queda claro a partir del código. Por lo general, se usan directamente en expresiones matemáticas, sin variables con nombres comprensibles. Para entender su propósito, hay que profundizar en el contexto o leer documentación adicional. Los números mágicos dificultan la lectura, la comprensión y el mantenimiento del código. -La solución es simple: solamente necesitas crear variables con nombres adecuados y todo encajará en su lugar. +## Cómo evitar la magia + +La forma más sencilla consiste en extraer dichos valores a variables con nombres comprensibles. Entonces el significado se vuelve evidente: ```javascript -let dollarsPerEuro = 1.25; -let rublesPerDollar = 60; +const dollarsPerEuro = 1.25; +const rublesPerDollar = 60; -let dollarsCount = 50 * dollarsPerEuro; // 62.5 -let rublesCount = dollarsCount * rublesPerDollar; // 3750 +const eurosCount = 1000; +const dollarsCount = eurosCount * dollarsPerEuro; // => 1250 +const rublesCount = dollarsCount * rublesPerDollar; // => 75000 console.log(rublesCount); ``` -Presta atención a los siguientes detalles: +Los números en sí no han desaparecido, pero ahora están almacenados en variables cuyos nombres indican sin ambigüedad qué son. + +## Conclusión -* Nomenclatura en lowerCamelCase. -* Las dos nuevas variables están separadas de los cálculos posteriores por una línea en blanco. Estas variables tienen sentido incluso sin los cálculos, por lo que esta separación es apropiada y mejora la legibilidad. -* El código resultante es más largo que la versión anterior, pero eso es normal. El código debe ser legible. +Los números mágicos hacen que el código sea poco claro y difícil de mantener. Para evitar este problema, hay que reemplazar dichos números por variables con nombres significativos. Esto hace que el código sea más legible, especialmente a largo plazo. El código claro siempre es más importante que la compacidad, incluso si el programa se vuelve un poco más largo. diff --git a/modules/30-variables/20-magic-numbers/es/data.yml b/modules/30-variables/20-magic-numbers/es/data.yml index 785008af..bd1a5d68 100644 --- a/modules/30-variables/20-magic-numbers/es/data.yml +++ b/modules/30-variables/20-magic-numbers/es/data.yml @@ -1,6 +1,5 @@ --- name: Números mágicos tips: - - > - [Números - mágicos](https://es.wikipedia.org/wiki/N%C3%BAmero_m%C3%A1gico_(programaci%C3%B3n)) + - | + [Número mágico](https://es.wikipedia.org/wiki/N%C3%BAmero_m%C3%A1gico_(inform%C3%A1tica)) diff --git a/modules/30-variables/20-magic-numbers/index.js b/modules/30-variables/20-magic-numbers/index.js index 4d6366b4..8f013d80 100644 --- a/modules/30-variables/20-magic-numbers/index.js +++ b/modules/30-variables/20-magic-numbers/index.js @@ -1,5 +1,5 @@ // BEGIN -const label = 'Ящиков на складе:'; +const label = 'Boxes in stock:'; const palletsCount = 6; const boxesPerPallet = 17; diff --git a/modules/30-variables/20-magic-numbers/ru/EXERCISE.md b/modules/30-variables/20-magic-numbers/ru/EXERCISE.md index 02632a40..4e1f5c1c 100644 --- a/modules/30-variables/20-magic-numbers/ru/EXERCISE.md +++ b/modules/30-variables/20-magic-numbers/ru/EXERCISE.md @@ -1,13 +1,13 @@ На складе стоят поддоны с ящиками. Вынесите «магические» числа `6` и `17` в именованные переменные и выведите результат. ```javascript -console.log('Ящиков на складе:'); +console.log('Boxes in stock:'); console.log(6 * 17); ``` Ожидаемый вывод: ```text -Ящиков на складе: +Boxes in stock: 102 ``` diff --git a/modules/30-variables/20-magic-numbers/test.js b/modules/30-variables/20-magic-numbers/test.js index 2055919d..d6107692 100644 --- a/modules/30-variables/20-magic-numbers/test.js +++ b/modules/30-variables/20-magic-numbers/test.js @@ -8,5 +8,5 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); - expect(firstArg).toBe('Ящиков на складе:\n102'); + expect(firstArg).toBe('Boxes in stock:\n102'); }); diff --git a/modules/30-variables/23-constants/description.es.yml b/modules/30-variables/23-constants/description.es.yml index 332f7f4d..c60c2c4e 100644 --- a/modules/30-variables/23-constants/description.es.yml +++ b/modules/30-variables/23-constants/description.es.yml @@ -3,54 +3,66 @@ name: Constantes theory: | - En todo el módulo, la gran mayoría de los ejemplos de código utilizaban variables como nombres (alias) de valores específicos, en lugar de usarlos como variables que cambian su valor con el tiempo. + A veces, un programa contiene valores que nunca deben cambiar. Por ejemplo: - ```javascript - let dollarsInEuro = 1.25; - let rublesInDollar = 60; + - la constante matemática π (pi); + - el tipo de cambio del dólar en una fecha determinada; + - una comisión fija del servicio. + + Estos valores se denominan constantes, y es habitual distinguirlos de las variables normales para que no surja la tentación de cambiarlos. - let dollarsCount = 50 * dollarsInEuro; // 62.5 - let rublesCount = dollarsCount * rublesInDollar; // 3750 + ## Ejemplo: el número π - console.log(rublesCount); + ```javascript + const PI = 3.14; + console.log(PI); // => 3.14 ``` - En programación, se acostumbra llamar a estos nombres constantes, y muchos lenguajes admiten las constantes como una construcción. JavaScript, en particular, pertenece a esos lenguajes, y sus estándares de codificación [lo dicen claramente](https://eslint.org/docs/rules/prefer-const) - si el valor no cambia, entonces estamos tratando con una constante. Reescribamos el ejemplo anterior utilizando constantes: + Aquí `PI` es una constante que almacena el valor del número π. El sentido de una constante es que su valor no debe cambiar durante la ejecución del programa. + + ## const en JavaScript + + En muchos lenguajes, una constante es una entidad del lenguaje independiente cuyo valor no se puede cambiar. En JavaScript existe la palabra clave `const` para esto. A diferencia de una variable normal, una constante declarada con `const` no se puede reasignar: ```javascript - const dollarsInEuro = 1.25; - const rublesInDollar = 60; + const maxLoginAttempts = 3; + maxLoginAttempts = 5; // TypeError: Assignment to constant variable. + ``` - const euros = 1000; - const dollars = euros * dollarsInEuro; // 1250 - const rubles = dollars * rublesInDollar; // 75000 + ## const vs let - console.log(rubles); + ```javascript + let score = 0; // cambiará + const lives = 3; // no cambia ``` + Usa `const` de forma predeterminada. Cambia a `let` solo cuando sepas con certeza que el valor se reasignará. Las constantes son más fáciles de analizar: al ver `const`, el lector sabe de inmediato que el valor no cambiará en ningún lugar del código. Con `let` no existe esa certeza, y hay que rastrear todos los lugares donde la variable podría haberse modificado. + + ## Convención de nomenclatura + + Técnicamente, cualquier variable declarada con `const` ya es una constante. Pero para las constantes globales — aquellas que definen los parámetros fundamentales de todo el programa — es habitual usar adicionalmente el estilo `UPPER_SNAKE_CASE` (también llamado SCREAMING_SNAKE_CASE): - El único cambio es que la palabra clave `let` se ha reemplazado por `const`, pero esto es solo sintaxis. Ahora, si intentamos cambiar cualquier constante, obtendremos un mensaje de error. De lo contrario, se utilizan de la misma manera que las variables. + - todas las letras en mayúsculas; + - las palabras se separan con el carácter de subrayado `_`. ```javascript - const pi = 3.14; - pi = 5; // TypeError: Assignment to constant variable. + const MAX_USERS = 100; + const DEFAULT_TIMEOUT = 30; + const DEFAULT_LANGUAGE = 'ru'; ``` - ¿Por qué tanta complicación? ¿Por qué no dejar solamente las variables? Incluso si dejáramos solamente las variables, eso no cambiaría el hecho de que, a menudo, se usarían como constantes. Además, el código en JavaScript se puede escribir de manera idiomática sin usar variables en absoluto. Eche un vistazo a un ejemplo de [código real de Hexlet](https://github.com/Hexlet/hexlet-exercise-kit/blob/main/import-documentation/index.js). En esta etapa, es posible que no lo entienda, pero intente contar la cantidad de constantes y variables dentro de él, verá que solo hay una variable y un montón de constantes. + Esto no es un requisito del lenguaje, sino una señal para el lector: ese valor no debe cambiar bajo ninguna circunstancia. - Las constantes son mucho más fáciles de analizar. Cuando vemos una constante en el código, inmediatamente entendemos que su valor siempre permanece igual. Al usar constantes, no hay concepto de tiempo. Con las variables, no es así, no podemos estar seguros de su valor, tenemos que analizar todo el código para comprender cómo podrían haber cambiado. + ## ¿Para qué sirven las constantes? - Las variables son absolutamente necesarias solamente en un caso (en todos los demás casos, se pueden evitar) - al trabajar con bucles, a los que aún no hemos llegado. - - En el futuro, preferiremos las constantes y solamente usaremos variables cuando sea necesario. + Las constantes hacen que el código sea más claro y seguro. Ayudan a ver de inmediato qué valores del programa se consideran fijos. Esto es especialmente importante al trabajar con datos como constantes matemáticas y físicas, configuraciones predeterminadas o límites fijos. El uso de constantes reduce el riesgo de errores: por la declaración `const` se entiende de inmediato que estamos ante un valor que no debe cambiarse. Además, si el valor sí necesita cambiarse (por ejemplo, en la configuración), basta con cambiarlo en un solo lugar, y el cambio se aplica automáticamente en todo el programa. instructions: | - Crea una constante llamada `army`, asígnale el valor `the white walkers` e imprime su valor en la pantalla. + Crea una constante `MAX_LOGIN_ATTEMPTS` con el valor `3` e imprímela en pantalla. tips: - | [const](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/const) - - | [TypeError](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/TypeError) diff --git a/modules/30-variables/23-constants/en/EXERCISE.md b/modules/30-variables/23-constants/en/EXERCISE.md index 8d8755d4..3f0b3fb5 100644 --- a/modules/30-variables/23-constants/en/EXERCISE.md +++ b/modules/30-variables/23-constants/en/EXERCISE.md @@ -1,2 +1 @@ - -Create a constant called `army`, assign it `the white walkers` value, and print it. +Create a constant `MAX_LOGIN_ATTEMPTS` with the value `3` and print it to the screen. diff --git a/modules/30-variables/23-constants/en/README.md b/modules/30-variables/23-constants/en/README.md index a219d205..ce8dc81e 100644 --- a/modules/30-variables/23-constants/en/README.md +++ b/modules/30-variables/23-constants/en/README.md @@ -1,40 +1,53 @@ +Sometimes a program contains values that should never change. For example: -Throughout the module, our sample code has mostly used variables as names (aliases) for particular values, rather than as variables that change their value over time. +- the mathematical constant π (pi); +- the dollar exchange rate on a specific date; +- a fixed service fee. -```javascript -let dollarsInEuro = 1.25; -let rublesInDollar = 60; +Such values are called constants, and it is customary to distinguish them from regular variables so that there is no temptation to change them. -let dollarsCount = 50 * dollarsInEuro; // 62.5 -let rublesCount = dollarsCount * rublesInDollar; // 3750 +## Example: the number π -console.log(rublesCount); +```javascript +const PI = 3.14; +console.log(PI); // => 3.14 ``` -Such names are often called constants in programming, and many languages support constants as a construct. JavaScript is one of those languages, and its coding standards [say explicitly](https://eslint.org/docs/rules/prefer-const) that if the value doesn't change, then we are dealing with a constant. Rewrite the example above to make use of constants: +Here `PI` is a constant that stores the value of the number π. The point of a constant is that its value should not change during the program's execution. -```javascript -const dollarsInEuro = 1.25; -const rublesInDollar = 60; +## const in JavaScript -const euros = 1000; -const dollars = euros * dollarsInEuro; // 1250 -const rubles = dollars * rublesInDollar; // 75000 +In many languages, a constant is a separate language entity whose value cannot be changed. In JavaScript, the keyword `const` is used for this. Unlike a regular variable, a constant declared with `const` cannot be reassigned: -console.log(rubles); +```javascript +const maxLoginAttempts = 3; +maxLoginAttempts = 5; // TypeError: Assignment to constant variable. ``` -The only change here is syntactical: the keyword `let` has been replaced by `const`. Now if we try to change any constant, we get an error message. Otherwise, it behaves the same way as a variable. +## const vs let ```javascript -const pi = 3.14; -pi = 5; // TypeError: Assignment to constant variable. +let score = 0; // will change +const lives = 3; // does not change ``` -You may be wondering why we need it. Can't we just use variables? Even if we limit ourselves to variables, it won't change the fact that they will often play the role of constants. Moreover, it is possible to write JavaScript code idiomatically without using variables at all. Take a look at the example from [the actual Hexlet code](https://github.com/Hexlet/hexlet-exercise-kit/blob/main/import-documentation/index.js). You're unlikely to understand it at this stage, but try counting the number of constants and variables there are, you'll see that there's exactly one variable and a bunch of constants. +Use `const` by default. Switch to `let` only when you know for certain that the value will be reassigned. Constants are easier to reason about: when you see `const`, the reader immediately knows that the value will not change anywhere in the code. With `let`, there is no such certainty, and you have to track all the places where the variable could have been modified. + +## Naming convention + +Technically, any variable declared with `const` is already a constant. But for global constants — those that define the fundamental parameters of the entire program — it is additionally customary to use the `UPPER_SNAKE_CASE` style (also called SCREAMING_SNAKE_CASE): + +- all letters are uppercase; +- words are separated by the underscore character `_`. + +```javascript +const MAX_USERS = 100; +const DEFAULT_TIMEOUT = 30; +const DEFAULT_LANGUAGE = 'ru'; +``` -Constants make it a lot easier to analyze; when we encounter a constant, it's obvious right away that its value always stays the same. With constants, we don't need to worry about when they were written. With variables, however, we can't be certain of their value and have to analyze all the code to figure out how they may have changed. +This is not a language requirement but a signal to the reader: such a value should not change under any circumstances. -Variables are essential only in one case (in all others, we can do without them for sure) and that's when we're dealing with loops. We'll get to that point later. +## Why do we need constants? -From now on, we will stick to constants and use variables only when it's inevitable. +Constants make code clearer and safer. They help you see right away which values in the program are considered fixed. This is especially important when working with data such as mathematical and physical constants, default settings, or fixed limits. Using constants reduces the risk of errors: from the `const` declaration, it is immediately clear that we are dealing with a value that should not be changed. In addition, if the value does need to be changed (for example, in settings), it is enough to change it in one place, and the change is automatically picked up throughout the entire program. diff --git a/modules/30-variables/23-constants/en/data.yml b/modules/30-variables/23-constants/en/data.yml index 03573d09..f17a701c 100644 --- a/modules/30-variables/23-constants/en/data.yml +++ b/modules/30-variables/23-constants/en/data.yml @@ -1,3 +1,7 @@ --- name: Constants -tips: [] +tips: + - | + [const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) + - | + [TypeError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError) diff --git a/modules/30-variables/23-constants/es/EXERCISE.md b/modules/30-variables/23-constants/es/EXERCISE.md index 80aee7e7..99ed395a 100644 --- a/modules/30-variables/23-constants/es/EXERCISE.md +++ b/modules/30-variables/23-constants/es/EXERCISE.md @@ -1,2 +1 @@ - -Crea una constante llamada `army`, asígnale el valor `the white walkers` e imprime su valor en la pantalla. +Crea una constante `MAX_LOGIN_ATTEMPTS` con el valor `3` e imprímela en pantalla. diff --git a/modules/30-variables/23-constants/es/README.md b/modules/30-variables/23-constants/es/README.md index baa9cbcb..43dc1e56 100644 --- a/modules/30-variables/23-constants/es/README.md +++ b/modules/30-variables/23-constants/es/README.md @@ -1,40 +1,53 @@ +A veces, un programa contiene valores que nunca deben cambiar. Por ejemplo: -En todo el módulo, la gran mayoría de los ejemplos de código utilizaban variables como nombres (alias) de valores específicos, en lugar de usarlos como variables que cambian su valor con el tiempo. +- la constante matemática π (pi); +- el tipo de cambio del dólar en una fecha determinada; +- una comisión fija del servicio. -```javascript -let dollarsInEuro = 1.25; -let rublesInDollar = 60; +Estos valores se denominan constantes, y es habitual distinguirlos de las variables normales para que no surja la tentación de cambiarlos. -let dollarsCount = 50 * dollarsInEuro; // 62.5 -let rublesCount = dollarsCount * rublesInDollar; // 3750 +## Ejemplo: el número π -console.log(rublesCount); +```javascript +const PI = 3.14; +console.log(PI); // => 3.14 ``` -En programación, se acostumbra llamar a estos nombres constantes, y muchos lenguajes admiten las constantes como una construcción. JavaScript, en particular, pertenece a esos lenguajes, y sus estándares de codificación [lo dicen claramente](https://eslint.org/docs/rules/prefer-const) - si el valor no cambia, entonces estamos tratando con una constante. Reescribamos el ejemplo anterior utilizando constantes: +Aquí `PI` es una constante que almacena el valor del número π. El sentido de una constante es que su valor no debe cambiar durante la ejecución del programa. -```javascript -const dollarsInEuro = 1.25; -const rublesInDollar = 60; +## const en JavaScript -const euros = 1000; -const dollars = euros * dollarsInEuro; // 1250 -const rubles = dollars * rublesInDollar; // 75000 +En muchos lenguajes, una constante es una entidad del lenguaje independiente cuyo valor no se puede cambiar. En JavaScript existe la palabra clave `const` para esto. A diferencia de una variable normal, una constante declarada con `const` no se puede reasignar: -console.log(rubles); +```javascript +const maxLoginAttempts = 3; +maxLoginAttempts = 5; // TypeError: Assignment to constant variable. ``` -El único cambio es que la palabra clave `let` se ha reemplazado por `const`, pero esto es solo sintaxis. Ahora, si intentamos cambiar cualquier constante, obtendremos un mensaje de error. De lo contrario, se utilizan de la misma manera que las variables. +## const vs let ```javascript -const pi = 3.14; -pi = 5; // TypeError: Assignment to constant variable. +let score = 0; // cambiará +const lives = 3; // no cambia ``` -¿Por qué tanta complicación? ¿Por qué no dejar solamente las variables? Incluso si dejáramos solamente las variables, eso no cambiaría el hecho de que, a menudo, se usarían como constantes. Además, el código en JavaScript se puede escribir de manera idiomática sin usar variables en absoluto. Eche un vistazo a un ejemplo de [código real de Hexlet](https://github.com/Hexlet/hexlet-exercise-kit/blob/main/import-documentation/index.js). En esta etapa, es posible que no lo entienda, pero intente contar la cantidad de constantes y variables dentro de él, verá que solo hay una variable y un montón de constantes. +Usa `const` de forma predeterminada. Cambia a `let` solo cuando sepas con certeza que el valor se reasignará. Las constantes son más fáciles de analizar: al ver `const`, el lector sabe de inmediato que el valor no cambiará en ningún lugar del código. Con `let` no existe esa certeza, y hay que rastrear todos los lugares donde la variable podría haberse modificado. + +## Convención de nomenclatura + +Técnicamente, cualquier variable declarada con `const` ya es una constante. Pero para las constantes globales — aquellas que definen los parámetros fundamentales de todo el programa — es habitual usar adicionalmente el estilo `UPPER_SNAKE_CASE` (también llamado SCREAMING_SNAKE_CASE): + +- todas las letras en mayúsculas; +- las palabras se separan con el carácter de subrayado `_`. + +```javascript +const MAX_USERS = 100; +const DEFAULT_TIMEOUT = 30; +const DEFAULT_LANGUAGE = 'ru'; +``` -Las constantes son mucho más fáciles de analizar. Cuando vemos una constante en el código, inmediatamente entendemos que su valor siempre permanece igual. Al usar constantes, no hay concepto de tiempo. Con las variables, no es así, no podemos estar seguros de su valor, tenemos que analizar todo el código para comprender cómo podrían haber cambiado. +Esto no es un requisito del lenguaje, sino una señal para el lector: ese valor no debe cambiar bajo ninguna circunstancia. -Las variables son absolutamente necesarias solamente en un caso (en todos los demás casos, se pueden evitar) - al trabajar con bucles, a los que aún no hemos llegado. +## ¿Para qué sirven las constantes? -En el futuro, preferiremos las constantes y solamente usaremos variables cuando sea necesario. +Las constantes hacen que el código sea más claro y seguro. Ayudan a ver de inmediato qué valores del programa se consideran fijos. Esto es especialmente importante al trabajar con datos como constantes matemáticas y físicas, configuraciones predeterminadas o límites fijos. El uso de constantes reduce el riesgo de errores: por la declaración `const` se entiende de inmediato que estamos ante un valor que no debe cambiarse. Además, si el valor sí necesita cambiarse (por ejemplo, en la configuración), basta con cambiarlo en un solo lugar, y el cambio se aplica automáticamente en todo el programa. diff --git a/modules/30-variables/23-constants/es/data.yml b/modules/30-variables/23-constants/es/data.yml index f81e1c95..51813ed5 100644 --- a/modules/30-variables/23-constants/es/data.yml +++ b/modules/30-variables/23-constants/es/data.yml @@ -1,7 +1,7 @@ --- name: Constantes tips: - - > + - | [const](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/const) - - > + - | [TypeError](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/TypeError) diff --git a/modules/31-advanced-strings/25-interpolation/es/EXERCISE.md b/modules/31-advanced-strings/25-interpolation/es/EXERCISE.md index 5450a8e7..cce26e52 100644 --- a/modules/31-advanced-strings/25-interpolation/es/EXERCISE.md +++ b/modules/31-advanced-strings/25-interpolation/es/EXERCISE.md @@ -1,5 +1,5 @@ -Dadas `username = 'Ana'` y `orderNumber = 1337`, usa interpolación para imprimir: +Dadas `username = 'Anna'` y `orderNumber = 1337`, usa interpolación para imprimir: ```text -Hola, Ana! Tu pedido #1337 ha sido aceptado. +Hello, Anna! Your order #1337 has been accepted. ``` diff --git a/modules/31-advanced-strings/25-interpolation/index.js b/modules/31-advanced-strings/25-interpolation/index.js index 950e5a2d..6a3f62dc 100644 --- a/modules/31-advanced-strings/25-interpolation/index.js +++ b/modules/31-advanced-strings/25-interpolation/index.js @@ -1,5 +1,7 @@ -const username = 'Анна'; +const username = 'Anna'; const orderNumber = 1337; // BEGIN -console.log(`Здравствуйте, ${username}! Ваш заказ #${orderNumber} принят.`); +console.log( + `Hello, ${username}! Your order #${orderNumber} has been accepted.`, +); // END diff --git a/modules/31-advanced-strings/25-interpolation/ru/EXERCISE.md b/modules/31-advanced-strings/25-interpolation/ru/EXERCISE.md index 3d8a75b2..f0f37747 100644 --- a/modules/31-advanced-strings/25-interpolation/ru/EXERCISE.md +++ b/modules/31-advanced-strings/25-interpolation/ru/EXERCISE.md @@ -1,5 +1,5 @@ -Дано две константы: `username = 'Анна'` и `orderNumber = 1337`. С помощью интерполяции выведите на экран: +Дано две константы: `username = 'Anna'` и `orderNumber = 1337`. С помощью интерполяции выведите на экран: ```text -Здравствуйте, Анна! Ваш заказ #1337 принят. +Hello, Anna! Your order #1337 has been accepted. ``` diff --git a/modules/31-advanced-strings/25-interpolation/test.js b/modules/31-advanced-strings/25-interpolation/test.js index 1469e5ab..15c7e9dc 100644 --- a/modules/31-advanced-strings/25-interpolation/test.js +++ b/modules/31-advanced-strings/25-interpolation/test.js @@ -8,5 +8,5 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); - expect(firstArg).toBe('Здравствуйте, Анна! Ваш заказ #1337 принят.'); + expect(firstArg).toBe('Hello, Anna! Your order #1337 has been accepted.'); }); diff --git a/modules/31-advanced-strings/90-multiline-strings/es/EXERCISE.md b/modules/31-advanced-strings/90-multiline-strings/es/EXERCISE.md index 9822685d..69868613 100644 --- a/modules/31-advanced-strings/90-multiline-strings/es/EXERCISE.md +++ b/modules/31-advanced-strings/90-multiline-strings/es/EXERCISE.md @@ -1 +1,8 @@ -Crea una variable `email` con texto multilínea e imprímelo. +Crea una variable `email` con texto multilínea e imprímelo: + +```text +Dear customer! + +Your order has been accepted. +Expected delivery: 3 business days. +``` diff --git a/modules/31-advanced-strings/90-multiline-strings/index.js b/modules/31-advanced-strings/90-multiline-strings/index.js index a449140c..d63d1ca1 100644 --- a/modules/31-advanced-strings/90-multiline-strings/index.js +++ b/modules/31-advanced-strings/90-multiline-strings/index.js @@ -1,8 +1,8 @@ // BEGIN -const email = `Уважаемый клиент! +const email = `Dear customer! -Ваш заказ принят в обработку. -Ожидаемая дата доставки — 3 рабочих дня.`; +Your order has been accepted. +Expected delivery: 3 business days.`; console.log(email); // END diff --git a/modules/31-advanced-strings/90-multiline-strings/ru/EXERCISE.md b/modules/31-advanced-strings/90-multiline-strings/ru/EXERCISE.md index 66128743..7c179433 100644 --- a/modules/31-advanced-strings/90-multiline-strings/ru/EXERCISE.md +++ b/modules/31-advanced-strings/90-multiline-strings/ru/EXERCISE.md @@ -1,10 +1,10 @@ Создайте переменную `email` с многострочным текстом и выведите её на экран: ```text -Уважаемый клиент! +Dear customer! -Ваш заказ принят в обработку. -Ожидаемая дата доставки — 3 рабочих дня. +Your order has been accepted. +Expected delivery: 3 business days. ``` Используйте шаблонную строку (обратные кавычки). diff --git a/modules/31-advanced-strings/90-multiline-strings/test.js b/modules/31-advanced-strings/90-multiline-strings/test.js index 92f4e580..629dab97 100644 --- a/modules/31-advanced-strings/90-multiline-strings/test.js +++ b/modules/31-advanced-strings/90-multiline-strings/test.js @@ -9,6 +9,6 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); expect(firstArg).toBe( - 'Уважаемый клиент!\n\nВаш заказ принят в обработку.\nОжидаемая дата доставки — 3 рабочих дня.', + 'Dear customer!\n\nYour order has been accepted.\nExpected delivery: 3 business days.', ); }); diff --git a/modules/33-data-types/10-primitive-data-types/description.es.yml b/modules/33-data-types/10-primitive-data-types/description.es.yml index 905eb636..40f3e49b 100644 --- a/modules/33-data-types/10-primitive-data-types/description.es.yml +++ b/modules/33-data-types/10-primitive-data-types/description.es.yml @@ -3,52 +3,126 @@ name: Tipos de datos theory: | - ¿Qué sucede si intentamos multiplicar un número por una cadena de texto? JavaScript devuelve `NaN` (no es un número) - ese es el valor. Ocurre cuando se utilizan valores incompatibles juntos. En este caso, un número y una cadena de texto: + Los programas trabajan con información diversa: texto, números, fechas, valores lógicos. Cada valor en un programa tiene un tipo. + + Por ejemplo: + + - `'Hello, World!'` es una cadena de texto (`string`); + - `7`, `-198`, `0`, `3.14` son números (`number`); + - `true` y `false` son valores lógicos (`boolean`). + + ## ¿Qué es un tipo de datos? + + Un tipo de datos define: + + - qué valores le pertenecen; + - qué operaciones se pueden realizar con él. + + Por ejemplo, los números se pueden sumar, dividir y multiplicar. Las cadenas de texto se combinan de otra manera — mediante la concatenación. Multiplicar una cadena de texto por otra cadena de texto no tiene sentido: ```javascript - 3 * 'Dracarys'; // NaN + // Sin sentido: 'mamá' * 'cuaderno' ``` - En los lenguajes de programación de alto nivel, los datos se dividen en tipos. Cualquier cadena de texto pertenece al tipo String, y los números pertenecen al tipo Number y BigInt (números muy grandes). ¿Para qué sirven los tipos? Para proteger el programa de errores difíciles de detectar. Los tipos determinan dos cosas: + ## Los números y las cadenas de texto pertenecen a tipos distintos - * Los valores posibles (permitidos). Por ejemplo, en JavaScript, los números se dividen en dos tipos: Number y BigInt. Los primeros son todos los números por debajo de un cierto umbral (que se puede ver); los segundos son los números más grandes. Esta división está relacionada con las características técnicas del hardware. - * El conjunto de operaciones que se pueden realizar con este tipo. Por ejemplo, la operación de multiplicación tiene sentido para el tipo "números enteros". Pero no tiene sentido para el tipo "cadenas de texto": multiplicar la palabra "mamá" por la palabra "cuaderno" es absurdo. + Un ejemplo de cómo mostrar un número: - JavaScript se comporta de dos maneras cuando se encuentra con violaciones. En algunas situaciones, se queja de la invalidez de la operación y se detiene con un error. En otros casos, el programa sigue funcionando. En este caso, la operación no válida devuelve algo similar a `NaN`, como en el ejemplo anterior. + ```javascript + console.log(5); // => 5 + console.log(-5); // => -5 + ``` - ¿Cómo sabe JavaScript qué tipo de datos tiene delante? Es bastante simple. Cualquier valor se inicializa en algún lugar y, dependiendo de cómo se inicialice, se entiende qué es. Por ejemplo, los números son simplemente números sin caracteres adicionales, excepto el punto para los números racionales. Pero las cadenas de texto siempre están delimitadas por caracteres especiales (en JavaScript hay tres variantes diferentes). Por ejemplo, el valor `'234'` es una cadena de texto, a pesar de que contiene números. + Un ejemplo de cómo mostrar una cadena de texto: - JavaScript permite conocer el tipo de datos con el operador `typeof`: + ```javascript + console.log('5'); // => 5 + console.log('-5'); // => -5 + ``` + + En la pantalla el resultado se ve igual, pero dentro del programa son cosas completamente diferentes: + + | Valor | Tipo de datos | + |----------|-----------------------------| + | `5` | `number` (número) | + | `'5'` | `string` (cadena de texto) | + + ## Los números en JavaScript + + En muchos lenguajes, los números enteros y los fraccionarios son tipos distintos (por ejemplo, en Python son `int` y `float`). En JavaScript no existe tal división: tanto los números enteros como los fraccionarios pertenecen a un solo tipo — `number`. ```javascript - typeof 3; // number - typeof 'Juego'; // string + console.log(10.234); // => 10.234 + console.log(-0.4); // => -0.4 + + console.log(3.5 + 1.2); // => 4.7 + console.log(5 / 2); // => 2.5 + console.log(2.75 - 0.5); // => 2.25 ``` + ## Tipos primitivos - Los tipos de datos Number, BigInt y String son tipos *primitivos*. Pero hay otros. En JavaScript, hay un tipo compuesto llamado Object (y con base en él, arrays, fechas y otros). Con él, se pueden combinar datos de diferentes tipos en un solo valor, por ejemplo, podemos crear un usuario agregando un nombre y una edad. + Los tipos como `string`, `number`, `boolean` se llaman primitivos — están integrados directamente en el lenguaje. + + ```text + Tipos primitivos de JavaScript + ├── number : números (enteros y fraccionarios) (7, -3, 3.14) + ├── string : cadenas de texto ('hello') + ├── boolean : tipo lógico (true, false) + ├── null : ausencia intencional de un valor + └── undefined : el valor no está definido + ``` + + Además de las cadenas de texto y los números, JavaScript tiene el tipo lógico `boolean` con los valores `true` y `false`, así como los valores especiales `null` y `undefined`. Los veremos con más detalle en el futuro. + + ## Cómo averiguar el tipo de un valor + + El operador `typeof` devuelve el tipo en forma de cadena de texto: ```javascript - // Esta sintaxis se aprende en Hexlet - const user = { name: 'Toto', age: 33 }; + console.log(typeof 42); // => 'number' + console.log(typeof 'hello'); // => 'string' + console.log(typeof true); // => 'boolean' + console.log(typeof undefined); // => 'undefined' + console.log(typeof null); // => 'object' (un error histórico de JS) ``` - En inglés, las cadenas de texto en programación se llaman "strings", y las líneas de los archivos de texto se llaman "lines". Por ejemplo, en el código anterior hay dos líneas (lines), pero solamente una cadena de texto (strings). En español, a veces puede haber confusión, por lo tanto, en todas las lecciones usaremos **cadena de texto** para referirnos al tipo de datos "cadena de texto", y **línea** para referirnos a las líneas (lines) en los archivos. + También existen tipos compuestos — arrays, objetos y otros. Nos familiarizaremos con ellos más adelante. Es más, en JavaScript se pueden crear tus propios tipos (por ejemplo, clases), pero para empezar es importante comprender bien los primitivos. instructions: | - Muestra en pantalla el número `-0.304`. + + En el programa ya está definido el año actual: + + ```javascript + const currentYear = 2026; + ``` + + Escribe un programa que muestre los datos del perfil en el siguiente formato: + + ```text + Name: Anna + Birth year: 1994 + Age: 32 + Rating: 4.7 + ``` + + Para ello: + + - crea una variable con el año de nacimiento; + - calcula la edad a partir del año actual; + - muestra los datos en pantalla con las etiquetas a la izquierda. tips: - | - [Literal](https://en.wikipedia.org/wiki/Literal_(computer_programming)) + [Literal](https://es.wikipedia.org/wiki/Literal_(inform%C3%A1tica)) - | - [Artículo sobre números decimales](https://es.wikipedia.org/wiki/N%C3%BAmero_decimal) + [Artículo sobre números fraccionarios](https://es.wikipedia.org/wiki/N%C3%BAmero_decimal) definitions: - name: "Tipo de datos" - description: "conjunto de datos en el código (tipo de información). El tipo determina qué se puede hacer con los elementos de un conjunto específico. Por ejemplo, números enteros, números racionales, cadenas de texto son diferentes tipos de datos." + description: "conjunto de datos en el código (tipo de información). El tipo determina qué se puede hacer con los elementos de un conjunto específico. Por ejemplo, los números enteros, los números racionales y las cadenas de texto son tipos de datos diferentes." - name: "Tipos de datos primitivos" - description: "tipos simples, incorporados en el propio lenguaje de programación." + description: "tipos simples, integrados en el propio lenguaje de programación." - name: "Cadena de texto (string)" description: | tipo de datos que describe un conjunto de caracteres (es decir, texto); por ejemplo, `'texto'` o `"texto"`. diff --git a/modules/33-data-types/10-primitive-data-types/en/EXERCISE.md b/modules/33-data-types/10-primitive-data-types/en/EXERCISE.md index 2762f5e6..96534108 100644 --- a/modules/33-data-types/10-primitive-data-types/en/EXERCISE.md +++ b/modules/33-data-types/10-primitive-data-types/en/EXERCISE.md @@ -1 +1,20 @@ -Print the number `-0.304`. +The current year is already defined in the program: + +```javascript +const currentYear = 2026; +``` + +Write a program that prints profile data in the following format: + +```text +Name: Anna +Birth year: 1994 +Age: 32 +Rating: 4.7 +``` + +To do this: + +- create a variable with the birth year; +- calculate the age based on the current year; +- print the data on the screen with labels on the left. diff --git a/modules/33-data-types/10-primitive-data-types/en/README.md b/modules/33-data-types/10-primitive-data-types/en/README.md index 2fa04f02..fad75461 100644 --- a/modules/33-data-types/10-primitive-data-types/en/README.md +++ b/modules/33-data-types/10-primitive-data-types/en/README.md @@ -1,29 +1,85 @@ +Programs work with different kinds of information: text, numbers, dates, boolean values. Every value in a program has a type. -What happens if we try to multiply a number by a string? JavaScript will return the `NaN` (not a number) value we've seen before. This happens whenever incompatible values are used together. In this case, a number and a string: +For example: + +- `'Hello, World!'` is a string (`string`); +- `7`, `-198`, `0`, `3.14` are numbers (`number`); +- `true` and `false` are boolean values (`boolean`). + +## What is a data type? + +A data type defines: + +- which values belong to it; +- which operations can be performed with it. + +For example, numbers can be added, divided, and multiplied. Strings are combined differently — using concatenation. Multiplying a string by a string makes no sense: ```javascript -3 * 'Dracarys'; // NaN +// Nonsense: 'mom' * 'notebook' ``` -In high-level programming languages, data are categorized by type. A string refers to the String type, while numbers refer to Number and BigInt (very large numbers). What are these data types for? They help to protect your program from hard-to-find errors. Types determine two things: +## Numbers and strings belong to different types -* Possible values. For example, numbers in JavaScript are divided into two types: Number and BigInt. All numbers below a certain threshold (you can check it) belong to the Numbers data type, and all numbers above it belong to the Biglnt type. They're divided this way due to the hardware's technical features -* A set of operations applied to this data type. For example, you can multiply integers, but not strings. Multiplying the word "mother" by the word "notepad" makes no sense +An example of printing a number: -Javascript may act in one of two possible ways when it sees a violation. In some situations, it'll terminate the program with an error. In others, the program will continue to work, though an invalid operation will return something like `NaN` as in the example above. +```javascript +console.log(5); // => 5 +console.log(-5); // => -5 +``` + +An example of printing a string: + +```javascript +console.log('5'); // => 5 +console.log('-5'); // => -5 +``` -How does JavaScript detect the data type? It's quite simple. Any value is initialized somewhere and, based on an initialization method, it understands what type of data it is. Numbers, for instance, are just numbers without any extra characters, apart from the point (.) for rational numbers. Strings, on the other hand, always require enclosing with special characters (there are three ways to write strings in JavaScript). For example, `'234'` is a string, even though there are numbers in quotes. +On the screen the result looks the same, but inside the program these are completely different things: -You can find out a data type using `typeof` operator: +| Value | Data type | +|----------|-----------------------| +| `5` | `number` (number) | +| `'5'` | `string` (string) | + +## Numbers in JavaScript + +In many languages, integers and fractional numbers are different types (for example, in Python they are `int` and `float`). JavaScript has no such division: both integers and fractional numbers belong to a single type — `number`. ```javascript -typeof 3; // 'number' -typeof 'Game'; // 'string' +console.log(10.234); // => 10.234 +console.log(-0.4); // => -0.4 + +console.log(3.5 + 1.2); // => 4.7 +console.log(5 / 2); // => 2.5 +console.log(2.75 - 0.5); // => 2.25 +``` + +## Primitive types + +Types like `string`, `number`, `boolean` are called primitive — they are built directly into the language. + +```text +JavaScript primitive types +├── number : numbers (integer and fractional) (7, -3, 3.14) +├── string : strings ('hello') +├── boolean : boolean type (true, false) +├── null : intentional absence of a value +└── undefined : value is not set ``` -The Number, BigInt, and String data types are *primitive* types. But there is more. JavaScript has a built-in composite type Object (as well as arrays, dates and others based on it). It serves to combine data of different types into a single value, e.g. we can create a user combining his name and age. +In addition to strings and numbers, JavaScript has the boolean type `boolean` with the values `true` and `false`, as well as the special values `null` and `undefined`. We will encounter them in more detail in the future. + +## How to find out the type of a value + +The `typeof` operator returns the type as a string: ```javascript -// You can learn this notation on Hexlet -const user = { name: 'Toto', age: 33 }; +console.log(typeof 42); // => 'number' +console.log(typeof 'hello'); // => 'string' +console.log(typeof true); // => 'boolean' +console.log(typeof undefined); // => 'undefined' +console.log(typeof null); // => 'object' (a historical JS bug) ``` + +There are also composite types — arrays, objects, and others. We will get acquainted with them later. Moreover, in JavaScript you can create your own types (for example, classes), but to start with it is important to understand primitives well. diff --git a/modules/33-data-types/10-primitive-data-types/en/data.yml b/modules/33-data-types/10-primitive-data-types/en/data.yml index 0eabf370..2db77818 100644 --- a/modules/33-data-types/10-primitive-data-types/en/data.yml +++ b/modules/33-data-types/10-primitive-data-types/en/data.yml @@ -3,15 +3,17 @@ name: Data types tips: - | [Literal](https://en.wikipedia.org/wiki/Literal_(computer_programming)) + - | + [Article about fractional numbers](https://en.wikipedia.org/wiki/Floating-point_arithmetic) definitions: - name: Data type description: >- - is a set of data in code. For example, integers, rational numbers, and - strings are different data types. The data type determines what can be - done with the elements of a particular data. + a set of data in code (a kind of information). A type defines what can be + done with the elements of a particular set. For example, integers, + rational numbers, and strings are different data types. - name: Primitive data types - description: are simple types built into the programming language. - - name: A string + description: simple types built into the programming language itself. + - name: String (string) description: > - is a data type defining a set of characters (text). For example, `'text'` - or `"text"`. + a data type that describes a set of characters (in other words — text); + for example, `'text'` or `"text"`. diff --git a/modules/33-data-types/10-primitive-data-types/es/EXERCISE.md b/modules/33-data-types/10-primitive-data-types/es/EXERCISE.md index a4346162..a20a37db 100644 --- a/modules/33-data-types/10-primitive-data-types/es/EXERCISE.md +++ b/modules/33-data-types/10-primitive-data-types/es/EXERCISE.md @@ -1 +1,20 @@ -Muestra en pantalla el número `-0.304`. +En el programa ya está definido el año actual: + +```javascript +const currentYear = 2026; +``` + +Escribe un programa que muestre los datos del perfil en el siguiente formato: + +```text +Name: Anna +Birth year: 1994 +Age: 32 +Rating: 4.7 +``` + +Para ello: + +- crea una variable con el año de nacimiento; +- calcula la edad a partir del año actual; +- muestra los datos en pantalla con las etiquetas a la izquierda. diff --git a/modules/33-data-types/10-primitive-data-types/es/README.md b/modules/33-data-types/10-primitive-data-types/es/README.md index 1e7b92db..80e4842e 100644 --- a/modules/33-data-types/10-primitive-data-types/es/README.md +++ b/modules/33-data-types/10-primitive-data-types/es/README.md @@ -1,31 +1,85 @@ +Los programas trabajan con información diversa: texto, números, fechas, valores lógicos. Cada valor en un programa tiene un tipo. -¿Qué sucede si intentamos multiplicar un número por una cadena de texto? JavaScript devuelve `NaN` (no es un número) - ese es el valor. Ocurre cuando se utilizan valores incompatibles juntos. En este caso, un número y una cadena de texto: +Por ejemplo: + +- `'Hello, World!'` es una cadena de texto (`string`); +- `7`, `-198`, `0`, `3.14` son números (`number`); +- `true` y `false` son valores lógicos (`boolean`). + +## ¿Qué es un tipo de datos? + +Un tipo de datos define: + +- qué valores le pertenecen; +- qué operaciones se pueden realizar con él. + +Por ejemplo, los números se pueden sumar, dividir y multiplicar. Las cadenas de texto se combinan de otra manera — mediante la concatenación. Multiplicar una cadena de texto por otra cadena de texto no tiene sentido: + +```javascript +// Sin sentido: 'mamá' * 'cuaderno' +``` + +## Los números y las cadenas de texto pertenecen a tipos distintos + +Un ejemplo de cómo mostrar un número: ```javascript -3 * 'Dracarys'; // NaN +console.log(5); // => 5 +console.log(-5); // => -5 ``` -En los lenguajes de programación de alto nivel, los datos se dividen en tipos. Cualquier cadena de texto pertenece al tipo String, y los números pertenecen al tipo Number y BigInt (números muy grandes). ¿Para qué sirven los tipos? Para proteger el programa de errores difíciles de detectar. Los tipos determinan dos cosas: +Un ejemplo de cómo mostrar una cadena de texto: -* Los valores posibles (permitidos). Por ejemplo, en JavaScript, los números se dividen en dos tipos: Number y BigInt. Los primeros son todos los números por debajo de un cierto umbral (que se puede ver); los segundos son los números más grandes. Esta división está relacionada con las características técnicas del hardware. -* El conjunto de operaciones que se pueden realizar con este tipo. Por ejemplo, la operación de multiplicación tiene sentido para el tipo "números enteros". Pero no tiene sentido para el tipo "cadenas de texto": multiplicar la palabra "mamá" por la palabra "cuaderno" es absurdo. +```javascript +console.log('5'); // => 5 +console.log('-5'); // => -5 +``` + +En la pantalla el resultado se ve igual, pero dentro del programa son cosas completamente diferentes: -JavaScript se comporta de dos maneras cuando se encuentra con violaciones. En algunas situaciones, se queja de la invalidez de la operación y se detiene con un error. En otros casos, el programa sigue funcionando. En este caso, la operación no válida devuelve algo similar a `NaN`, como en el ejemplo anterior. +| Valor | Tipo de datos | +|----------|-----------------------------| +| `5` | `number` (número) | +| `'5'` | `string` (cadena de texto) | -¿Cómo sabe JavaScript qué tipo de datos tiene delante? Es bastante simple. Cualquier valor se inicializa en algún lugar y, dependiendo de cómo se inicialice, se entiende qué es. Por ejemplo, los números son simplemente números sin caracteres adicionales, excepto el punto para los números racionales. Pero las cadenas de texto siempre están delimitadas por caracteres especiales (en JavaScript hay tres variantes diferentes). Por ejemplo, el valor `'234'` es una cadena de texto, a pesar de que contiene números. +## Los números en JavaScript -JavaScript permite conocer el tipo de datos con el operador `typeof`: +En muchos lenguajes, los números enteros y los fraccionarios son tipos distintos (por ejemplo, en Python son `int` y `float`). En JavaScript no existe tal división: tanto los números enteros como los fraccionarios pertenecen a un solo tipo — `number`. ```javascript -typeof 3; // number -typeof 'Juego'; // string +console.log(10.234); // => 10.234 +console.log(-0.4); // => -0.4 + +console.log(3.5 + 1.2); // => 4.7 +console.log(5 / 2); // => 2.5 +console.log(2.75 - 0.5); // => 2.25 +``` + +## Tipos primitivos + +Los tipos como `string`, `number`, `boolean` se llaman primitivos — están integrados directamente en el lenguaje. + +```text +Tipos primitivos de JavaScript +├── number : números (enteros y fraccionarios) (7, -3, 3.14) +├── string : cadenas de texto ('hello') +├── boolean : tipo lógico (true, false) +├── null : ausencia intencional de un valor +└── undefined : el valor no está definido ``` -Los tipos de datos Number, BigInt y String son tipos *primitivos*. Pero hay otros. En JavaScript, hay un tipo compuesto llamado Object (y con base en él, arrays, fechas y otros). Con él, se pueden combinar datos de diferentes tipos en un solo valor, por ejemplo, podemos crear un usuario agregando un nombre y una edad. +Además de las cadenas de texto y los números, JavaScript tiene el tipo lógico `boolean` con los valores `true` y `false`, así como los valores especiales `null` y `undefined`. Los veremos con más detalle en el futuro. + +## Cómo averiguar el tipo de un valor + +El operador `typeof` devuelve el tipo en forma de cadena de texto: ```javascript -// Esta sintaxis se aprende en Hexlet -const user = { name: 'Toto', age: 33 }; +console.log(typeof 42); // => 'number' +console.log(typeof 'hello'); // => 'string' +console.log(typeof true); // => 'boolean' +console.log(typeof undefined); // => 'undefined' +console.log(typeof null); // => 'object' (un error histórico de JS) ``` -En inglés, las cadenas de texto en programación se llaman "strings", y las líneas de los archivos de texto se llaman "lines". Por ejemplo, en el código anterior hay dos líneas (lines), pero solamente una cadena de texto (strings). En español, a veces puede haber confusión, por lo tanto, en todas las lecciones usaremos **cadena de texto** para referirnos al tipo de datos "cadena de texto", y **línea** para referirnos a las líneas (lines) en los archivos. +También existen tipos compuestos — arrays, objetos y otros. Nos familiarizaremos con ellos más adelante. Es más, en JavaScript se pueden crear tus propios tipos (por ejemplo, clases), pero para empezar es importante comprender bien los primitivos. diff --git a/modules/33-data-types/10-primitive-data-types/es/data.yml b/modules/33-data-types/10-primitive-data-types/es/data.yml index 614258de..9f1468a4 100644 --- a/modules/33-data-types/10-primitive-data-types/es/data.yml +++ b/modules/33-data-types/10-primitive-data-types/es/data.yml @@ -2,19 +2,18 @@ name: Tipos de datos tips: - | - [Literal](https://en.wikipedia.org/wiki/Literal_(computer_programming)) - - > - [Artículo sobre números - decimales](https://es.wikipedia.org/wiki/N%C3%BAmero_decimal) + [Literal](https://es.wikipedia.org/wiki/Literal_(inform%C3%A1tica)) + - | + [Artículo sobre números fraccionarios](https://es.wikipedia.org/wiki/N%C3%BAmero_decimal) definitions: - name: Tipo de datos description: >- conjunto de datos en el código (tipo de información). El tipo determina qué se puede hacer con los elementos de un conjunto específico. Por - ejemplo, números enteros, números racionales, cadenas de texto son - diferentes tipos de datos. + ejemplo, los números enteros, los números racionales y las cadenas de + texto son tipos de datos diferentes. - name: Tipos de datos primitivos - description: tipos simples, incorporados en el propio lenguaje de programación. + description: tipos simples, integrados en el propio lenguaje de programación. - name: Cadena de texto (string) description: > tipo de datos que describe un conjunto de caracteres (es decir, texto); diff --git a/modules/33-data-types/45-undefined/test.js b/modules/33-data-types/45-undefined/test.js index 9e8ef83d..3c0389a9 100644 --- a/modules/33-data-types/45-undefined/test.js +++ b/modules/33-data-types/45-undefined/test.js @@ -6,9 +6,9 @@ test('undefined', async () => { const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); await import('./index.js'); - // console.log должен быть вызван, и ему должен быть передан аргумент undefined + // console.log must be called and must be passed an undefined argument expect(consoleLogSpy).toHaveBeenCalled(); const [firstCall] = consoleLogSpy.mock.calls; - expect(firstCall.length).toBeGreaterThan(0); - expect(firstCall[0]).toBe(undefined); + expect(firstCall?.length).toBeGreaterThan(0); + expect(firstCall?.[0]).toBe(undefined); }); diff --git a/modules/33-data-types/50-data-types-weak-typing/description.es.yml b/modules/33-data-types/50-data-types-weak-typing/description.es.yml index b180b0da..03cb1e9e 100644 --- a/modules/33-data-types/50-data-types-weak-typing/description.es.yml +++ b/modules/33-data-types/50-data-types-weak-typing/description.es.yml @@ -3,33 +3,56 @@ name: Tipado débil theory: | - Sabemos que hay dos tipos de datos diferentes: números y cadenas de texto. Por ejemplo, podemos sumar números porque la operación de suma es una operación para el tipo "número". + Conocemos dos tipos de datos diferentes: números y cadenas de texto. Por ejemplo, podemos sumar números, porque la operación de suma es una operación para el tipo "números". - ¿Pero qué sucede si aplicamos esta operación a un número y una cadena de texto? + ¿Pero qué sucede si aplicamos esta operación no a dos números, sino a un número y una cadena de texto? ```javascript console.log(1 + '7'); // => 17 ``` - A pesar de que `'7'` es una cadena de texto y no un número, el intérprete de JavaScript devuelve el resultado `17`, como si estuviéramos concatenando dos cadenas de texto. Cuando JavaScript encuentra una incompatibilidad de tipos, intenta convertir la información por sí mismo. En este caso, convirtió el número `1` en la cadena de texto `'1'` y luego realizó la concatenación de `'1'` y `'7'`. + A pesar de que `'7'` es una cadena de texto y no un número, el intérprete de JavaScript devolvió la respuesta `'17'`, como si estuviéramos sumando dos cadenas de texto. Cuando JavaScript encuentra una incompatibilidad de tipos, intenta convertir la información por sí mismo. En este caso, convirtió el número `1` en la cadena de texto `'1'` y luego realizó tranquilamente la concatenación de `'1'` y `'7'`. - No todos los lenguajes hacen esto. JavaScript es un lenguaje con **tipado débil**. Conoce la existencia de diferentes tipos (números, cadenas de texto, etc.), pero no es muy estricto en su uso, intentando convertir la información cuando parece razonable. A veces, JavaScript incluso llega a extremos. La mayoría de las expresiones que no funcionan en otros lenguajes funcionan perfectamente en JavaScript. Prueba a realizar cualquier operación aritmética (excepto la suma) con cadenas de texto u otros tipos de datos (excepto cuando ambos operandos son números o cadenas de texto que contienen solo números) y verás que siempre funcionarán y devolverán `NaN`, lo cual es bastante lógico. + ## Tipado débil + + No todos los lenguajes hacen esto. JavaScript es un lenguaje con **tipado débil**. Conoce la existencia de diferentes tipos (números, cadenas de texto y otros), pero trata su uso de forma poco estricta e intenta convertir los datos cuando le parece razonable. + + A veces, JavaScript llega a extremos. La mayoría de las expresiones que no funcionan en otros lenguajes sí funcionan en JavaScript. Prueba a realizar cualquier operación aritmética, excepto la suma, sustituyendo allí cadenas de texto: verás que el código se ejecuta y devuelve `NaN` (Not a Number): ```javascript - const result = 'one' * 'two'; - console.log(result); // => NaN + console.log('one' * 'two'); // => NaN ``` + ```text + 1 + '7' → '17' (el número se convirtió en una cadena de texto, concatenación) + '7' - 1 → 6 (la cadena de texto se convirtió en un número, resta) + 'one' * 2 → NaN (la cadena de texto no se puede convertir en un número) + ``` + + ## ¿Y cómo es en los lenguajes estrictos? + + En los lenguajes con **tipado estricto (fuerte)**, no se puede sumar un número con una cadena de texto: el programa se detendrá con un error. Por ejemplo, en Python o Ruby la expresión `1 + '7'` provocará un error de tipos: el lenguaje exige que indiques explícitamente cómo convertir los datos. + + Al mismo tiempo, los lenguajes no se dividen exactamente en dos bandos: "estrictos" y "débiles". Es más correcto decir que los distintos lenguajes tienen un **grado de estrictez diferente**: en algunos casi no hay conversiones implícitas, mientras que en otros hay muchas. JavaScript se encuentra en el extremo "débil" de esta escala. + + ## Tipado estático y dinámico + + Existe otro concepto distinto: el tipado estático y dinámico. Describe **cuándo** se verifican los tipos. JavaScript pertenece a los lenguajes de tipado dinámico: los tipos se verifican durante la ejecución del programa. En los lenguajes de tipado estático, la verificación generalmente ocurre antes, incluso antes de ejecutar el código. + + Es importante no confundir dos cosas: + + - el tipado estático/dinámico responde a la pregunta "**cuándo** se verifican los tipos"; + - el tipado fuerte/débil responde a la pregunta "**qué sucederá** si mezclas tipos diferentes sin una conversión explícita". - En los lenguajes con **tipado fuerte**, no se puede sumar un número y una cadena de texto. + Estas son propiedades independientes. JavaScript es un lenguaje dinámico y de tipado débil. - JavaScript fue creado para Internet, y en Internet toda la información es una cadena de texto. Incluso cuando ingresas un número de teléfono o una fecha de nacimiento en un sitio web, esa información llega al servidor como una cadena de texto y no como un número. Por eso, los creadores del lenguaje decidieron que convertir automáticamente los tipos era correcto y conveniente. + ## Por qué JavaScript es así - Esta conversión automática e implícita de tipos es, por un lado, realmente conveniente. Pero en la práctica, esta característica del lenguaje crea muchos errores y problemas difíciles de encontrar. El código puede funcionar a veces y no funcionar en otras ocasiones, dependiendo de si la conversión automática tuvo "suerte" en un caso particular. El programador no se dará cuenta de esto de inmediato. + JavaScript fue creado para Internet, y en Internet toda la información son cadenas de texto. Incluso cuando ingresas en un sitio web un número de teléfono o un año de nacimiento, esos datos llegan al servidor no como números, sino como cadenas de texto. Por eso, los autores del lenguaje decidieron que convertir los tipos automáticamente es conveniente. - En los próximos ejercicios, te encontrarás con este comportamiento en varias ocasiones. A menudo te preguntarás "¿por qué mi código no funciona como espero?". + Hay conveniencia, pero tiene un precio alto. En la práctica, las conversiones implícitas crean multitud de errores que son difíciles de encontrar: el código puede funcionar a veces y otras no, dependiendo de si en un caso concreto "hubo suerte" con la conversión automática. El programador no lo nota de inmediato. - El tipado débil es un tema recurrente en el desarrollo en JavaScript. + En los próximos ejercicios te encontrarás con este comportamiento en más de una ocasión. A menudo surgirá la pregunta: "¿por qué mi código no funciona como espero?". El tipado débil es un hilo conductor a lo largo de todo el desarrollo en JavaScript. instructions: | @@ -37,9 +60,11 @@ instructions: | tips: - | - [Tipado](https://en.wikipedia.org/wiki/Strong_and_weak_typing) + [Tipado](https://es.wikipedia.org/wiki/Sistema_de_tipos) definitions: - name: Tipado débil - description: | - es un tipo de tipado en el que el lenguaje de programación realiza muchas conversiones de tipos implícitas automáticamente, incluso si puede haber pérdida de precisión o ambigüedad en la conversión. + description: > + es un tipo de tipado en el que el lenguaje de programación realiza muchas + conversiones de tipos implícitas automáticamente, incluso si puede haber + pérdida de precisión o la conversión es ambigua. diff --git a/modules/33-data-types/50-data-types-weak-typing/en/EXERCISE.md b/modules/33-data-types/50-data-types-weak-typing/en/EXERCISE.md index 46a6618a..fe4efa7f 100644 --- a/modules/33-data-types/50-data-types-weak-typing/en/EXERCISE.md +++ b/modules/33-data-types/50-data-types-weak-typing/en/EXERCISE.md @@ -1,2 +1,2 @@ -Print the result of `7 - (-8 - -2)`. Convert `7` to a string. Experiment with other numbers too. +Print the result of the expression: `7 - (-8 - -2)` to the screen. Try making the number 7 not a number, but a string. Experiment with other numbers too. diff --git a/modules/33-data-types/50-data-types-weak-typing/en/README.md b/modules/33-data-types/50-data-types-weak-typing/en/README.md index b5738ded..82c2d6a4 100644 --- a/modules/33-data-types/50-data-types-weak-typing/en/README.md +++ b/modules/33-data-types/50-data-types-weak-typing/en/README.md @@ -1,27 +1,50 @@ +We know about two different data types: numbers and strings. We can, for example, add numbers, because addition is an operation for the "numbers" type. -We know two different data types: numbers and strings. For example, we can add numbers, because addition is an operation for the "numbers" type. - -But what if you add a number to a string? +But what if we apply this operation not to two numbers, but to a number and a string? ```javascript -console.log(1 + '7'); // => '17' +console.log(1 + '7'); // => 17 ``` -Even though `'7'` is a string, the JavaScript interpreter returned `17` as if we were adding two strings. When JavaScript notices a type mismatch, it tries to convert the data. In our case, it converts the number `1` to a string `'1'` and then just concatenates `'1'` and `'7'`. +Even though `'7'` is a string and not a number, the JavaScript interpreter returned the answer `'17'`, as if we were adding two strings. When JavaScript sees a type mismatch, it tries to convert the information on its own. In this case, it converted the number `1` into the string `'1'`, and then calmly concatenated `'1'` and `'7'`. + +## Weak typing + +Not all languages do this. JavaScript is a language with **weak typing**. It knows about the existence of different types (numbers, strings, and others), but treats their use rather loosely and tries to convert data whenever this seems reasonable to it. -Not all languages can do this. JavaScript is a weakly typed language. It recognizes different data types (numbers, strings, etc.), but doesn't use them too strictly, trying to convert data when it seems reasonable. JavaScript sometimes even rushes into extremes. Most expressions that don't work in other languages work perfectly well in JavaScript. Try to perform any arithmetic operation (except addition) with strings or another data type (except when both operands are numbers or strings consisting only of numbers). You will see that they always work and return `NaN`, which makes sense. +Sometimes JavaScript goes to extremes. Most expressions that don't work in other languages do work in JavaScript. Try performing any arithmetic operation other than addition, substituting strings into it — you'll see that the code runs and returns `NaN` (Not a Number): ```javascript -const result = 'one' * 'two'; -console.log(result); // => NaN +console.log('one' * 'two'); // => NaN ``` -In **strongly typed** languages, adding a number to a string won't work. +```text +1 + '7' → '17' (the number turned into a string, concatenation) +'7' - 1 → 6 (the string turned into a number, subtraction) +'one' * 2 → NaN (the string cannot be turned into a number) +``` + +## What about strict languages? + +In languages with **strict (strong) typing**, you can't add a number to a string — the program will stop with an error. For example, in Python or Ruby the expression `1 + '7'` will lead to a type error: the language requires you to explicitly specify how to convert the data. + +At the same time, languages aren't divided neatly into two camps — "strict" and "weak". It's more accurate to say that different languages have a **different degree of strictness**: in some there are almost no implicit conversions, while in others there are many. JavaScript is at the "weak" end of this scale. + +## Static and dynamic typing + +There is another, separate concept — static and dynamic typing. It describes **when** types are checked. JavaScript belongs to the dynamically typed languages: types are checked while the program is running. In statically typed languages, the check usually happens earlier, before the code is run. + +It's important not to confuse two things: + +- static/dynamic typing answers the question "**when** are types checked"; +- strong/weak typing answers the question "**what will happen** if you mix different types without an explicit conversion". + +These are independent properties. JavaScript is a dynamic and weakly typed language. -JavaScript was created for the Internet, where all information is stored in strings. Even when you type a phone number or a birth year on a website, that information goes to the server as a string, not as a number. So the designers of the language decided that automatic type conversion is suitable and convenient. +## Why JavaScript is like this -This tacit automatic type conversion is indeed convenient. But in practice, this feature causes a lot of errors, which are difficult to find. The code may work or fail, depending on whether you are lucky enough for the automatic conversion to have been done correctly. A programmer may not notice this immediately. +JavaScript was created for the internet, and on the internet all information is strings. Even when you enter a phone number or a year of birth on a website, this data arrives at the server not as numbers, but as strings. That's why the authors of the language decided that automatically converting types is convenient. -You will encounter these cases more than once in further tasks. You'll often ask "Why doesn't my code work the way I expect?" +There is convenience, but it comes at a high price. In practice, implicit conversions create a multitude of errors that are hard to find: the code may sometimes work and sometimes not — depending on whether you got "lucky" with the automatic conversion in a particular case. The programmer doesn't notice this right away. -Weak typing runs like a thread through the whole Javascript development process. +In further tasks you will encounter such behavior more than once. The question will often arise: "why does my code not work the way I expect?". Weak typing runs as a common thread through all of JavaScript development. diff --git a/modules/33-data-types/50-data-types-weak-typing/en/data.yml b/modules/33-data-types/50-data-types-weak-typing/en/data.yml index edc2704f..d03762bc 100644 --- a/modules/33-data-types/50-data-types-weak-typing/en/data.yml +++ b/modules/33-data-types/50-data-types-weak-typing/en/data.yml @@ -1,3 +1,11 @@ --- name: Weak typing -tips: [] +tips: + - | + [Typing](https://en.wikipedia.org/wiki/Strong_and_weak_typing) +definitions: + - name: Weak typing + description: > + this is typing in which the programming language performs many + implicit type conversions automatically, even if a loss of precision + may occur or the conversion is ambiguous. diff --git a/modules/33-data-types/50-data-types-weak-typing/es/README.md b/modules/33-data-types/50-data-types-weak-typing/es/README.md index 405c916e..4b90d23a 100644 --- a/modules/33-data-types/50-data-types-weak-typing/es/README.md +++ b/modules/33-data-types/50-data-types-weak-typing/es/README.md @@ -1,27 +1,50 @@ +Conocemos dos tipos de datos diferentes: números y cadenas de texto. Por ejemplo, podemos sumar números, porque la operación de suma es una operación para el tipo "números". -Sabemos que hay dos tipos de datos diferentes: números y cadenas de texto. Por ejemplo, podemos sumar números porque la operación de suma es una operación para el tipo "número". - -¿Pero qué sucede si aplicamos esta operación a un número y una cadena de texto? +¿Pero qué sucede si aplicamos esta operación no a dos números, sino a un número y una cadena de texto? ```javascript console.log(1 + '7'); // => 17 ``` -A pesar de que `'7'` es una cadena de texto y no un número, el intérprete de JavaScript devuelve el resultado `17`, como si estuviéramos concatenando dos cadenas de texto. Cuando JavaScript encuentra una incompatibilidad de tipos, intenta convertir la información por sí mismo. En este caso, convirtió el número `1` en la cadena de texto `'1'` y luego realizó la concatenación de `'1'` y `'7'`. +A pesar de que `'7'` es una cadena de texto y no un número, el intérprete de JavaScript devolvió la respuesta `'17'`, como si estuviéramos sumando dos cadenas de texto. Cuando JavaScript encuentra una incompatibilidad de tipos, intenta convertir la información por sí mismo. En este caso, convirtió el número `1` en la cadena de texto `'1'` y luego realizó tranquilamente la concatenación de `'1'` y `'7'`. + +## Tipado débil + +No todos los lenguajes hacen esto. JavaScript es un lenguaje con **tipado débil**. Conoce la existencia de diferentes tipos (números, cadenas de texto y otros), pero trata su uso de forma poco estricta e intenta convertir los datos cuando le parece razonable. -No todos los lenguajes hacen esto. JavaScript es un lenguaje con **tipado débil**. Conoce la existencia de diferentes tipos (números, cadenas de texto, etc.), pero no es muy estricto en su uso, intentando convertir la información cuando parece razonable. A veces, JavaScript incluso llega a extremos. La mayoría de las expresiones que no funcionan en otros lenguajes funcionan perfectamente en JavaScript. Prueba a realizar cualquier operación aritmética (excepto la suma) con cadenas de texto u otros tipos de datos (excepto cuando ambos operandos son números o cadenas de texto que contienen solo números) y verás que siempre funcionarán y devolverán `NaN`, lo cual es bastante lógico. +A veces, JavaScript llega a extremos. La mayoría de las expresiones que no funcionan en otros lenguajes sí funcionan en JavaScript. Prueba a realizar cualquier operación aritmética, excepto la suma, sustituyendo allí cadenas de texto: verás que el código se ejecuta y devuelve `NaN` (Not a Number): ```javascript -const result = 'one' * 'two'; -console.log(result); // => NaN +console.log('one' * 'two'); // => NaN ``` -En los lenguajes con **tipado fuerte**, no se puede sumar un número y una cadena de texto. +```text +1 + '7' → '17' (el número se convirtió en una cadena de texto, concatenación) +'7' - 1 → 6 (la cadena de texto se convirtió en un número, resta) +'one' * 2 → NaN (la cadena de texto no se puede convertir en un número) +``` + +## ¿Y cómo es en los lenguajes estrictos? + +En los lenguajes con **tipado estricto (fuerte)**, no se puede sumar un número con una cadena de texto: el programa se detendrá con un error. Por ejemplo, en Python o Ruby la expresión `1 + '7'` provocará un error de tipos: el lenguaje exige que indiques explícitamente cómo convertir los datos. + +Al mismo tiempo, los lenguajes no se dividen exactamente en dos bandos: "estrictos" y "débiles". Es más correcto decir que los distintos lenguajes tienen un **grado de estrictez diferente**: en algunos casi no hay conversiones implícitas, mientras que en otros hay muchas. JavaScript se encuentra en el extremo "débil" de esta escala. + +## Tipado estático y dinámico + +Existe otro concepto distinto: el tipado estático y dinámico. Describe **cuándo** se verifican los tipos. JavaScript pertenece a los lenguajes de tipado dinámico: los tipos se verifican durante la ejecución del programa. En los lenguajes de tipado estático, la verificación generalmente ocurre antes, incluso antes de ejecutar el código. + +Es importante no confundir dos cosas: + +- el tipado estático/dinámico responde a la pregunta "**cuándo** se verifican los tipos"; +- el tipado fuerte/débil responde a la pregunta "**qué sucederá** si mezclas tipos diferentes sin una conversión explícita". + +Estas son propiedades independientes. JavaScript es un lenguaje dinámico y de tipado débil. -JavaScript fue creado para Internet, y en Internet toda la información es una cadena de texto. Incluso cuando ingresas un número de teléfono o una fecha de nacimiento en un sitio web, esa información llega al servidor como una cadena de texto y no como un número. Por eso, los creadores del lenguaje decidieron que convertir automáticamente los tipos era correcto y conveniente. +## Por qué JavaScript es así -Esta conversión automática e implícita de tipos es, por un lado, realmente conveniente. Pero en la práctica, esta característica del lenguaje crea muchos errores y problemas difíciles de encontrar. El código puede funcionar a veces y no funcionar en otras ocasiones, dependiendo de si la conversión automática tuvo "suerte" en un caso particular. El programador no se dará cuenta de esto de inmediato. +JavaScript fue creado para Internet, y en Internet toda la información son cadenas de texto. Incluso cuando ingresas en un sitio web un número de teléfono o un año de nacimiento, esos datos llegan al servidor no como números, sino como cadenas de texto. Por eso, los autores del lenguaje decidieron que convertir los tipos automáticamente es conveniente. -En los próximos ejercicios, te encontrarás con este comportamiento en varias ocasiones. A menudo te preguntarás "¿por qué mi código no funciona como espero?". +Hay conveniencia, pero tiene un precio alto. En la práctica, las conversiones implícitas crean multitud de errores que son difíciles de encontrar: el código puede funcionar a veces y otras no, dependiendo de si en un caso concreto "hubo suerte" con la conversión automática. El programador no lo nota de inmediato. -El tipado débil es un tema recurrente en el desarrollo en JavaScript. +En los próximos ejercicios te encontrarás con este comportamiento en más de una ocasión. A menudo surgirá la pregunta: "¿por qué mi código no funciona como espero?". El tipado débil es un hilo conductor a lo largo de todo el desarrollo en JavaScript. diff --git a/modules/33-data-types/50-data-types-weak-typing/es/data.yml b/modules/33-data-types/50-data-types-weak-typing/es/data.yml index 30ad66bf..6c35879a 100644 --- a/modules/33-data-types/50-data-types-weak-typing/es/data.yml +++ b/modules/33-data-types/50-data-types-weak-typing/es/data.yml @@ -2,10 +2,10 @@ name: Tipado débil tips: - | - [Tipado](https://en.wikipedia.org/wiki/Strong_and_weak_typing) + [Tipado](https://es.wikipedia.org/wiki/Sistema_de_tipos) definitions: - name: Tipado débil description: > es un tipo de tipado en el que el lenguaje de programación realiza muchas conversiones de tipos implícitas automáticamente, incluso si puede haber - pérdida de precisión o ambigüedad en la conversión. + pérdida de precisión o la conversión es ambigua. diff --git a/modules/35-calling-functions/100-call/description.es.yml b/modules/35-calling-functions/100-call/description.es.yml index 0052c810..73c60111 100644 --- a/modules/35-calling-functions/100-call/description.es.yml +++ b/modules/35-calling-functions/100-call/description.es.yml @@ -1,82 +1,166 @@ --- -name: Funciones y su llamado +name: Funciones y su llamada theory: | - La suma, la concatenación, el cálculo del resto de la división y otras operaciones que hemos visto son capacidades bastante básicas de los lenguajes de programación. Las matemáticas no se limitan a la aritmética; también hay muchos otros campos con sus propias operaciones, como la geometría. Lo mismo ocurre con las cadenas de texto: se pueden invertir, cambiar el caso de las letras, eliminar caracteres innecesarios, y eso es solamente lo más básico. Y, finalmente, a un nivel más alto, existe la lógica aplicada a una aplicación específica. Los programas retiran dinero, calculan impuestos, generan informes. La cantidad de operaciones similares es infinita y es única para cada programa. Y todas ellas deben ser expresadas de alguna manera en el código. + La programación existe para realizar las operaciones más diversas. A veces son acciones sencillas, como sumar números o concatenar cadenas. Pero más a menudo se trata de procesos complejos, como transferir dinero entre cuentas, hacer un pedido en una tienda en línea, calcular impuestos o preparar un informe. - Para expresar cualquier operación arbitraria en programación, existe el concepto de *función*. Las funciones pueden ser tanto incorporadas como añadidas por el programador. Ya estamos familiarizados con una función incorporada, que es `console.log()`. + Tales operaciones no se pueden expresar con un solo comando. Detrás de una acción como "transferir dinero" pueden esconderse decenas, cientos e incluso miles de líneas de código: comprobar el saldo, descontar la cantidad, tener en cuenta la comisión, actualizar la base de datos, enviar una notificación. - Las funciones son una de las construcciones clave en la programación, sin ellas no se puede hacer prácticamente nada. Comenzamos a familiarizarnos con ellas lo antes posible, ya que el resto del material se basa en las funciones al máximo. Primero aprenderemos a utilizar las funciones ya creadas y luego aprenderemos a crear nuestras propias funciones. + Para gestionar este código y no perderse en los detalles, se utilizan las funciones. Una función agrupa un bloque de código en un todo único, oculta la implementación y permite concentrarse en el significado. Al programador le basta con llamar a la función y confiarle todo el trabajo interno. - Comenzaremos con funciones sencillas para trabajar con cadenas de texto. A continuación se muestra un ejemplo de llamada a la función `length()`, que cuenta la cantidad de caracteres en una cadena: + Imaginemos una función que transfiere dinero de una cuenta a otra. En su interior puede haber cientos de líneas de código, pero nosotros no las vemos. Desde fuera, todo parece un único comando sencillo: + + ```javascript + transferMoney('Alice', 'Bob', 100); + ``` + + Esta línea llama a la función `transferMoney()`. Se le pasan el remitente `Alice`, el destinatario `Bob` y la cantidad `100`. + + Aquí tienes algunos ejemplos más de llamadas a funciones. Cada una tiene su propio nombre y su propio conjunto de datos con los que trabajar: + + ```javascript + // Sí, sí, console.log también es una función + console.log('Hexlet!'); + + // Envío de un correo a un usuario + sendEmail('bob@example.com', 'Welcome!'); + + // Cálculo del impuesto sobre la cantidad indicada + calculateTax(5000, 'Florida'); + + // Comprobación de si un usuario está en el sistema + isRegistered('Alice'); + + // Obtención de un número aleatorio del 1 al 10 + randomNumber(1, 10); + + // Creación de una copia de seguridad de la base de datos + backupDatabase(); + ``` + + En una llamada a una función primero se escribe su **nombre** y luego los **paréntesis**. Los paréntesis indican que se trata precisamente de una llamada: así entendemos que tenemos delante una función y no una variable. + + Dentro de los paréntesis se indican los **argumentos**, es decir, los datos que la función recibe para trabajar. Puede haber varios, uno o ninguno. + + ## ¿De dónde salen las funciones? + + Algunas funciones están incorporadas en el lenguaje (built-in), otras las crean los propios programadores. + + Las **funciones incorporadas** vienen junto con JavaScript y se pueden usar de inmediato. Un ejemplo es `console.log()`. Como suele decirse, está disponible de forma global. + + Las **funciones definidas por los programadores** se crean cuando hace falta encapsular la propia lógica en un bloque separado. A esa función se le puede dar cualquier nombre y usarla como una incorporada. Aprenderemos a hacerlo más adelante. + + Además, existen funciones de bibliotecas separadas. Para usarlas, se conectan mediante el mecanismo de importación. Por ahora no analizaremos la importación en detalle: basta con saber que permite conectar un conjunto externo de funciones. + + ## Una función con un parámetro + + Tomemos la función `length()`, que devuelve la cantidad de caracteres de una cadena. Se conecta desde el conjunto estándar de funciones del curso mediante la importación: ```javascript - // length es una función import { length } from 'hexlet-basics/string'; - // Llamada a la función length con el parámetro 'Hello!' - const result = length('Hello!'); - console.log(result); // => 6 + const message = 'Hello!'; + const count = length(message); + console.log(count); // => 6 ``` - Un paréntesis. La primera línea de este código es la importación de una función desde otro módulo. Las importaciones y los módulos se estudian en Hexlet, aquí estarán presentes en la tarea "tal cual", ya que no se pueden utilizar las funciones definidas en otros archivos sin ellos. No te preocupes si no entiendes el significado de esta acción, puedes obtener más información al respecto en el curso [Introducción a la programación](https://codica.la/courses/introduction-to-programming). + La cadena `'Hello!'` tiene seis caracteres, por lo que la llamada `length(message)` devolverá el número `6`. - Los parámetros (o argumentos) son la información que una función recibe al ser llamada. Es con base en esta información que la función, por lo general, realiza algún cálculo y devuelve un resultado. + ```text + Argumento Función Resultado + ┌──────────┐ ┌──────────┐ ┌──────────┐ + │ 'Hello!' │ ──→ │ length() │ ──→ │ 6 │ + └──────────┘ └──────────┘ └──────────┘ + ``` + + ## Devolución de un valor - Hemos creado la constante `result` y le hemos indicado al intérprete que guarde en ella el resultado **devuelto** por la función `length()` al ser llamada. En este sentido, las funciones son similares a las operaciones, siempre devuelven un resultado de su trabajo. + La devolución de un valor es uno de los principios clave del funcionamiento de las funciones. Si una función devuelve un valor, este se puede guardar en una variable, pasar a otra función o usar en cálculos: ```javascript - // La llamada a length devuelve el resultado (la longitud de la cadena) - // que se guarda en la constante llamada resultado - const result = length('Hello!'); + import { length } from 'hexlet-basics/string'; + + const length1 = length('Hello!'); // guardamos el resultado + const length2 = length('World!'); + + const combinedLength = length1 + length2; // usamos el resultado en una expresión + console.log(combinedLength); // => 12 ``` - La expresión `length('Hello!')` significa que se está llamando a la función llamada *length*, a la cual se le ha pasado el parámetro `'Hello!'`. La función `length()` cuenta la longitud exacta de la cadena que se le ha pasado. + Si la función imprimiera el resultado en pantalla de inmediato (como `console.log()`), veríamos el número, pero no podríamos usarlo después: sumarlo, guardarlo o compararlo. Precisamente por eso la devolución de un valor es tan importante: permite conectar las funciones entre sí. Así, a partir de pequeños pasos se construyen grandes programas. + + ## Una función con varios parámetros - La llamada a una función siempre se indica con paréntesis `()`, que van justo después del nombre de la función. Entre los paréntesis puede haber cualquier cantidad de parámetros, o incluso ninguno. La cantidad depende de la función utilizada. Tomemos como ejemplo la función `pow()`, que eleva un número especificado a una potencia determinada. Esta función recibe dos parámetros y eleva el número pasado como primer parámetro a la potencia pasada como segundo parámetro. + Algunas funciones aceptan varios valores a la vez. Por ejemplo, `Math.pow()` eleva un número a una potencia: el primer argumento es la base, el segundo es el exponente. ```javascript - import { pow } from 'hexlet-basics/math'; + // 2 a la 3ª potencia: 2 * 2 * 2 + console.log(Math.pow(2, 3)); // => 8 - // La llamada a pow(2, 3) devuelve el valor de 2 elevado a la 3ª potencia - const result = pow(2, 3); // 2 * 2 * 2 - console.log(result); // => 8 + // 5 a la 2ª potencia: 5 * 5 + console.log(Math.pow(5, 2)); // => 25 ``` - En resumen, los operadores y las funciones son lo mismo. La diferencia clave radica en cómo se escriben. Si imaginamos (hipotéticamente) la suma como una función, se vería así: + En cuanto a la estructura, una llamada con varios argumentos no se diferencia de una llamada con uno: el mismo nombre de función, los paréntesis y los argumentos separados por comas. + + `Math` es un conjunto de funciones incorporado en JavaScript para trabajar con números. Está disponible desde cualquier lugar del programa. Por ahora, la expresión `Math.pow(...)` se puede leer como un "nombre largo de función": el prefijo `Math.` indica que la función pertenece a ese conjunto. Lo que significa realmente el punto lo veremos en las lecciones sobre objetos. Esto no afecta en absoluto al comportamiento de la función. + + La lista completa de funciones matemáticas está disponible en la [documentación de MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math). + + ## Parámetros y argumentos + + En las conversaciones sobre funciones aparecen las palabras **parámetros** y **argumentos**. Están relacionadas, pero no son lo mismo. + + Se habla de **parámetros** al crear una función: son las variables dentro de la función en las que entran los valores pasados. Se habla de **argumentos** al llamarla: es lo que pasamos a la función. Un argumento puede ser un número, una variable o cualquier expresión: ```javascript - // Suma normal - 3 + 5; // 8 - // Suma representada como función - // Parece extraño, pero transmite el significado de las funciones - +(3, 5); + console.log(Math.pow(2, 3)); // => 8, los argumentos son números + + const x = 2; + // un argumento puede ser una expresión, se evaluará antes de pasarse + console.log(Math.pow(x + 1, 3)); // => 27 ``` - ## Resumen + No es obligatorio memorizar esto, pero será útil al leer literatura en inglés. + + ## Cómo conocer nuevas funciones + + Cada función tiene una **firma**: su "descripción", es decir, el nombre, la lista de parámetros y el tipo de valor devuelto. Es la firma la que permite entender cómo usar una función sin leer su código. Por ejemplo, la documentación de MDN describe `Math.pow()` así: - Las funciones se llaman y devuelven un resultado, que luego se puede utilizar en cálculos posteriores o, por ejemplo, mostrar en pantalla. + ``` + Math.pow(base, exponent) + + Parámetros + base — la base de la potencia + exponent — el exponente de la potencia + ``` - Pregunta de autoevaluación. ¿Cómo se puede saber qué devuelve la llamada a la función `console.log()`? Compruébalo. + A partir de la firma se ve de inmediato: la función acepta dos argumentos y devuelve un número. Una vez que aprendas a leer firmas, podrás trabajar con cualquier función desconocida. -
- Respuesta + Es imposible aprenderlo todo, y no hace falta. Lo importante es saber dónde buscar. Para JavaScript hay dos fuentes principales: - La llamada a la función `console.log()` devuelve `undefined`. + - **MDN** ([developer.mozilla.org](https://developer.mozilla.org/es/)) - documentación sobre las capacidades incorporadas del lenguaje y las API del navegador. + - **Documentación de Node.js** ([nodejs.org/api](https://nodejs.org/api/)) - la parte del servidor, funciones para trabajar con el sistema de archivos, la red, etc. -
+ Otra forma es leer el código de otras personas: cualquier paquete de npm es abierto, y en él a menudo se pueden encontrar técnicas de las que no se habla en los libros de texto. instructions: | - En el código del programa se han definido dos constantes que contienen nombres de empresas. Calcula la longitud total de los nombres en caracteres y muéstrala en pantalla. + Un sitio web comprueba si los anuncios de dos empresas asociadas caben en una sola línea. Sus nombres están definidos en el código: cuenta la cantidad total de caracteres de ambos nombres con la función `length()` y muéstrala en pantalla. + + La función ya está conectada en la plantilla: + + ```javascript + import { length } from 'hexlet-basics/string'; + ``` tips: - | - [Llamada a una función](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Funciones#llamando_funciones) + [Llamada a una función](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Functions#calling_functions) definitions: - name: Función description: "operación que puede recibir datos y devolver un resultado; una función se llama así: `foo()`." - name: Argumento - description: "información que una función recibe al ser llamada. Por ejemplo, `foo(42)` es pasar el argumento `42` a la función `foo()`." + description: "la información que una función recibe al ser llamada. Por ejemplo, `foo(42)` — pasar el argumento `42` a la función `foo()`." diff --git a/modules/35-calling-functions/100-call/en/EXERCISE.md b/modules/35-calling-functions/100-call/en/EXERCISE.md index cfa95846..5ea9b49a 100644 --- a/modules/35-calling-functions/100-call/en/EXERCISE.md +++ b/modules/35-calling-functions/100-call/en/EXERCISE.md @@ -1,2 +1,7 @@ +A website checks whether the ads of two partner companies will fit on one line. Their names are defined in the code - count the total number of characters in both names using the `length()` function and print it to the screen. -The program code features two constants containing company names. Calculate their total character length and print it. +The function is already connected in the template: + +```javascript +import { length } from 'hexlet-basics/string'; +``` diff --git a/modules/35-calling-functions/100-call/en/README.md b/modules/35-calling-functions/100-call/en/README.md index 2b36a500..4af35a97 100644 --- a/modules/35-calling-functions/100-call/en/README.md +++ b/modules/35-calling-functions/100-call/en/README.md @@ -1,57 +1,141 @@ +Programming exists to perform all kinds of operations. Sometimes these are simple actions, like adding numbers or joining strings. But more often they are complex processes such as transferring money between accounts, placing an order in an online store, calculating taxes, or preparing a report. -Addition, concatenation, finding the remainder, and the other operations discussed are all basic programming language features. Math is not limited to arithmetic, there are many other domains with their own operations, e.g., geometry. The same goes for strings: you can flip them, change a letter's case, delete extra characters – and that's just the tip of the iceberg. And finally, at a higher level, there is the applied logic of a particular program. Programs withdraw money, calculate taxes, and generate reports. The number of these jobs is endless and different for each program. And they all have to be somehow expressed in code. +Such operations can't be expressed with a single command. An action like "transfer money" may hide dozens, hundreds, or even thousands of lines of code: checking the balance, deducting the amount, accounting for the fee, updating the database, sending a notification. -The notion of a *function* expresses any arbitrary operation in programming. Functions can be both built-in and manually written by a programmer. We are already familiar with one built-in function, `log()`, when we call `console.log()`. +To manage this code and not get lost in the details, we use functions. A function combines a block of code into a single whole, hides the implementation, and lets us focus on the meaning. The programmer only needs to call the function and trust it to do all the internal work. -Functions are fundamental building blocks in programming, and it is impossible to accomplish anything without them. We need to get acquainted with them as soon as possible because future courses will deal almost exclusively with functions. First, we'll learn how to use the functions we have already defined, and we'll also learn to define our own functions. +Imagine a function that transfers money from one account to another. It may contain hundreds of lines of code inside, but we don't see them. From the outside, everything looks like one simple command: -We will start with basic functions that handle strings. Below is an example of the `length()` function being called. This counts the number of characters in a string: +```javascript +transferMoney('Alice', 'Bob', 100); +``` + +This line calls the `transferMoney()` function. It is passed the sender `Alice`, the recipient `Bob`, and the amount `100`. + +Here are a few more examples of function calls. Each one has its own name and its own set of data to work with: + +```javascript +// Yes, console.log is a function too +console.log('Hexlet!'); + +// Sending an email to a user +sendEmail('bob@example.com', 'Welcome!'); + +// Calculating tax on the given amount +calculateTax(5000, 'Florida'); + +// Checking whether a user is in the system +isRegistered('Alice'); + +// Getting a random number from 1 to 10 +randomNumber(1, 10); + +// Creating a database backup +backupDatabase(); +``` + +In a function call, you first write its **name**, then the **parentheses**. The parentheses show that this is exactly a call - that's how we know we're dealing with a function and not a variable. + +Inside the parentheses you specify **arguments**, that is, the data the function receives to work with. There can be several of them, just one, or none at all. + +## Where do functions come from? + +Some functions are built into the language (built-in), others are created by programmers themselves. + +**Built-in functions** come together with JavaScript and can be used right away. An example is `console.log()`. As they say, it is available globally. + +**Functions defined by programmers** are created when you need to wrap your own logic into a separate block. Such a function can be given any name and used like a built-in one. We'll learn how to do this later. + +In addition, there are functions from separate libraries. To use them, you connect them with the import mechanism. We won't go into import in detail yet - it's enough to know that it lets you connect an external set of functions. + +## A function with one parameter + +Let's take the `length()` function, which returns the number of characters in a string. It is connected from the course's standard set of functions using import: ```javascript -// length is a function import { length } from 'hexlet-basics/string'; -// length function call with 'Hello!' argument -const result = length('Hello!'); -console.log(result); // => 6 +const message = 'Hello!'; +const count = length(message); +console.log(count); // => 6 ``` -A lyrical digression. The first line in this code is an imported function from another module. You will learn about importing and modules on Hexlet, and here they will be "as is" because we need to import to use functions defined in other files. Don't bother if you don't understand the meaning of this step, you can learn more about it in our course [Programming fundamentals](https://en.hexlet.io/courses/intro_to_programming). +The string `'Hello!'` has six characters, so the call `length(message)` will return the number `6`. -Parameters (or arguments) represent the data the function receives when you call it. This data is what the function uses to compute something and return a result. +```text +Argument Function Result +┌──────────┐ ┌──────────┐ ┌──────────┐ +│ 'Hello!' │ ──→ │ length() │ ──→ │ 6 │ +└──────────┘ └──────────┘ └──────────┘ +``` + +## Returning a value -We have defined a `result` constant and told the interpreter to assign it a result returned by the `length()` function call. In this sense, functions are like operations – they always return the result of their job. +Returning a value is one of the key principles of how functions work. If a function returns a value, it can be stored in a variable, passed to another function, or used in calculations: ```javascript -// Calling length() returns the result (the string length) -// which is written in a constant named result -const result = length('Hello!'); +import { length } from 'hexlet-basics/string'; + +const length1 = length('Hello!'); // store the result +const length2 = length('World!'); + +const combinedLength = length1 + length2; // use the result in an expression +console.log(combinedLength); // => 12 ``` -Writing `length('Hello!')` means that we call the function named *length* and it will take the parameter `'Hello!'`. The function `length()` counts the length of the string passed to it. +If the function immediately printed the result to the screen (like `console.log()`), we would see the number but wouldn't be able to use it further - to add, store, or compare it. That's exactly why returning a value is so important: it lets you connect functions to each other. This is how big programs are built from small steps. -The function being called is always indicated by parentheses `()` following the function name. There can be any number of parameters in parentheses, even nothing can be a parameter. The number of parameters depends on the function used. Consider the function `pow()` as an example. This raises a given number to a given power. It takes two parameters as input and raises the number passed in the first parameter to the power passed in the second parameter. +## A function with several parameters + +Some functions take several values at once. For example, `Math.pow()` raises a number to a power: the first argument is the base, the second is the exponent. ```javascript -import { pow } from 'hexlet-basics/math'; +// 2 to the 3rd power: 2 * 2 * 2 +console.log(Math.pow(2, 3)); // => 8 -// Calling pow(2, 3) returns the value of 2 to the power of 3 -const result = pow(2, 3); // 2 * 2 * 2 -console.log(result); // => 8 +// 5 to the 2nd power: 5 * 5 +console.log(Math.pow(5, 2)); // => 25 ``` -Broadly speaking, operators and functions are the same things. The only key difference is how they are written. If you think of addition as a function, it might look like this: +In terms of structure, a call with several arguments is no different from a call with one: the same function name, parentheses, and arguments separated by commas. + +`Math` is a set of functions built into JavaScript for working with numbers. It is available from any place in the program. For now, you can read `Math.pow(...)` as a "long function name": the `Math.` prefix says that the function belongs to this set. What the dot actually means we'll cover in the lessons about objects. It doesn't affect the function's behavior in any way. + +A full list of math functions is available in the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math). + +## Parameters and arguments + +In conversations about functions you'll come across the words **parameters** and **arguments**. They are related, but they are not the same thing. + +We talk about **parameters** when creating a function - these are variables inside the function into which the passed values go. We talk about **arguments** when calling - these are what we pass into the function. An argument can be a number, a variable, or any expression: ```javascript -// Regular addition -3 + 5; // 8 -// Addition represented as a function -// It looks a bit strange, but it conveys the meaning of functions -+(3, 5); +console.log(Math.pow(2, 3)); // => 8, the arguments are numbers + +const x = 2; +// an argument can be an expression, it is evaluated before being passed +console.log(Math.pow(x + 1, 3)); // => 27 +``` + +You don't have to memorize this, but it will come in handy when reading English-language literature. + +## How to learn about new functions + +Every function has a **signature** - its "description": the name, the list of parameters, and the type of the returned value. It is the signature that lets you understand how to use a function without reading its code. For example, the MDN documentation describes `Math.pow()` like this: + ``` +Math.pow(base, exponent) + +Parameters + base — the base of the power + exponent — the exponent of the power +``` + +From the signature it's immediately clear: the function takes two arguments and returns a number. Once you've learned to read signatures, you can work with any unfamiliar function. -## Summary +It's impossible to learn everything - and there's no need to. What matters is knowing where to look. For JavaScript there are two main sources: -Functions are called. They also return a result that may be used in further calculations or, for example, can be printed. +- **MDN** ([developer.mozilla.org](https://developer.mozilla.org/en-US/)) - documentation on the built-in features of the language and browser APIs. +- **Node.js documentation** ([nodejs.org/api](https://nodejs.org/api/)) - the server side, functions for working with the file system, the network, and so on. -Self-check. How can you find out what calling `console.log()` will return? Test it. +Another way is to read other people's code: any package on npm is open, and in it you can often find techniques that aren't written about in textbooks. diff --git a/modules/35-calling-functions/100-call/en/data.yml b/modules/35-calling-functions/100-call/en/data.yml index e5e2ce00..24d0ef74 100644 --- a/modules/35-calling-functions/100-call/en/data.yml +++ b/modules/35-calling-functions/100-call/en/data.yml @@ -1,3 +1,14 @@ --- -name: Calling functions -tips: [] +name: Functions and calling them +tips: + - | + [Calling functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#calling_functions) +definitions: + - name: Function + description: >- + an operation able to receive data and return a result; a function is + called like this: `foo()`. + - name: Argument + description: >- + the information a function receives when called. For example, `foo(42)` — + passing the argument `42` to the function `foo()` diff --git a/modules/35-calling-functions/100-call/es/EXERCISE.md b/modules/35-calling-functions/100-call/es/EXERCISE.md index 28fb27ee..faa8c1ae 100644 --- a/modules/35-calling-functions/100-call/es/EXERCISE.md +++ b/modules/35-calling-functions/100-call/es/EXERCISE.md @@ -1,2 +1,7 @@ +Un sitio web comprueba si los anuncios de dos empresas asociadas caben en una sola línea. Sus nombres están definidos en el código: cuenta la cantidad total de caracteres de ambos nombres con la función `length()` y muéstrala en pantalla. -En el código del programa se han definido dos constantes que contienen nombres de empresas. Calcula la longitud total de los nombres en caracteres y muéstrala en pantalla. +La función ya está conectada en la plantilla: + +```javascript +import { length } from 'hexlet-basics/string'; +``` diff --git a/modules/35-calling-functions/100-call/es/README.md b/modules/35-calling-functions/100-call/es/README.md index 001fd96b..1ed8a6c0 100644 --- a/modules/35-calling-functions/100-call/es/README.md +++ b/modules/35-calling-functions/100-call/es/README.md @@ -1,64 +1,141 @@ +La programación existe para realizar las operaciones más diversas. A veces son acciones sencillas, como sumar números o concatenar cadenas. Pero más a menudo se trata de procesos complejos, como transferir dinero entre cuentas, hacer un pedido en una tienda en línea, calcular impuestos o preparar un informe. -La suma, la concatenación, el cálculo del resto de la división y otras operaciones que hemos visto son capacidades bastante básicas de los lenguajes de programación. Las matemáticas no se limitan a la aritmética; también hay muchos otros campos con sus propias operaciones, como la geometría. Lo mismo ocurre con las cadenas de texto: se pueden invertir, cambiar el caso de las letras, eliminar caracteres innecesarios, y eso es solamente lo más básico. Y, finalmente, a un nivel más alto, existe la lógica aplicada a una aplicación específica. Los programas retiran dinero, calculan impuestos, generan informes. La cantidad de operaciones similares es infinita y es única para cada programa. Y todas ellas deben ser expresadas de alguna manera en el código. +Tales operaciones no se pueden expresar con un solo comando. Detrás de una acción como "transferir dinero" pueden esconderse decenas, cientos e incluso miles de líneas de código: comprobar el saldo, descontar la cantidad, tener en cuenta la comisión, actualizar la base de datos, enviar una notificación. -Para expresar cualquier operación arbitraria en programación, existe el concepto de *función*. Las funciones pueden ser tanto incorporadas como añadidas por el programador. Ya estamos familiarizados con una función incorporada, que es `console.log()`. +Para gestionar este código y no perderse en los detalles, se utilizan las funciones. Una función agrupa un bloque de código en un todo único, oculta la implementación y permite concentrarse en el significado. Al programador le basta con llamar a la función y confiarle todo el trabajo interno. -Las funciones son una de las construcciones clave en la programación, sin ellas no se puede hacer prácticamente nada. Comenzamos a familiarizarnos con ellas lo antes posible, ya que el resto del material se basa en las funciones al máximo. Primero aprenderemos a utilizar las funciones ya creadas y luego aprenderemos a crear nuestras propias funciones. +Imaginemos una función que transfiere dinero de una cuenta a otra. En su interior puede haber cientos de líneas de código, pero nosotros no las vemos. Desde fuera, todo parece un único comando sencillo: -Comenzaremos con funciones sencillas para trabajar con cadenas de texto. A continuación se muestra un ejemplo de llamada a la función `length()`, que cuenta la cantidad de caracteres en una cadena: +```javascript +transferMoney('Alice', 'Bob', 100); +``` + +Esta línea llama a la función `transferMoney()`. Se le pasan el remitente `Alice`, el destinatario `Bob` y la cantidad `100`. + +Aquí tienes algunos ejemplos más de llamadas a funciones. Cada una tiene su propio nombre y su propio conjunto de datos con los que trabajar: + +```javascript +// Sí, sí, console.log también es una función +console.log('Hexlet!'); + +// Envío de un correo a un usuario +sendEmail('bob@example.com', 'Welcome!'); + +// Cálculo del impuesto sobre la cantidad indicada +calculateTax(5000, 'Florida'); + +// Comprobación de si un usuario está en el sistema +isRegistered('Alice'); + +// Obtención de un número aleatorio del 1 al 10 +randomNumber(1, 10); + +// Creación de una copia de seguridad de la base de datos +backupDatabase(); +``` + +En una llamada a una función primero se escribe su **nombre** y luego los **paréntesis**. Los paréntesis indican que se trata precisamente de una llamada: así entendemos que tenemos delante una función y no una variable. + +Dentro de los paréntesis se indican los **argumentos**, es decir, los datos que la función recibe para trabajar. Puede haber varios, uno o ninguno. + +## ¿De dónde salen las funciones? + +Algunas funciones están incorporadas en el lenguaje (built-in), otras las crean los propios programadores. + +Las **funciones incorporadas** vienen junto con JavaScript y se pueden usar de inmediato. Un ejemplo es `console.log()`. Como suele decirse, está disponible de forma global. + +Las **funciones definidas por los programadores** se crean cuando hace falta encapsular la propia lógica en un bloque separado. A esa función se le puede dar cualquier nombre y usarla como una incorporada. Aprenderemos a hacerlo más adelante. + +Además, existen funciones de bibliotecas separadas. Para usarlas, se conectan mediante el mecanismo de importación. Por ahora no analizaremos la importación en detalle: basta con saber que permite conectar un conjunto externo de funciones. + +## Una función con un parámetro + +Tomemos la función `length()`, que devuelve la cantidad de caracteres de una cadena. Se conecta desde el conjunto estándar de funciones del curso mediante la importación: ```javascript -// length es una función import { length } from 'hexlet-basics/string'; -// Llamada a la función length con el parámetro 'Hello!' -const result = length('Hello!'); -console.log(result); // => 6 +const message = 'Hello!'; +const count = length(message); +console.log(count); // => 6 ``` -Un paréntesis. La primera línea de este código es la importación de una función desde otro módulo. Las importaciones y los módulos se estudian en Hexlet, aquí estarán presentes en la tarea "tal cual", ya que no se pueden utilizar las funciones definidas en otros archivos sin ellos. No te preocupes si no entiendes el significado de esta acción, puedes obtener más información al respecto en el curso [Introducción a la programación](https://codica.la/courses/introduction-to-programming). +La cadena `'Hello!'` tiene seis caracteres, por lo que la llamada `length(message)` devolverá el número `6`. -Los parámetros (o argumentos) son la información que una función recibe al ser llamada. Es con base en esta información que la función, por lo general, realiza algún cálculo y devuelve un resultado. +```text +Argumento Función Resultado +┌──────────┐ ┌──────────┐ ┌──────────┐ +│ 'Hello!' │ ──→ │ length() │ ──→ │ 6 │ +└──────────┘ └──────────┘ └──────────┘ +``` -Hemos creado la constante `result` y le hemos indicado al intérprete que guarde en ella el resultado **devuelto** por la función `length()` al ser llamada. En este sentido, las funciones son similares a las operaciones, siempre devuelven un resultado de su trabajo. +## Devolución de un valor + +La devolución de un valor es uno de los principios clave del funcionamiento de las funciones. Si una función devuelve un valor, este se puede guardar en una variable, pasar a otra función o usar en cálculos: ```javascript -// La llamada a length devuelve el resultado (la longitud de la cadena) -// que se guarda en la constante llamada resultado -const result = length('Hello!'); +import { length } from 'hexlet-basics/string'; + +const length1 = length('Hello!'); // guardamos el resultado +const length2 = length('World!'); + +const combinedLength = length1 + length2; // usamos el resultado en una expresión +console.log(combinedLength); // => 12 ``` -La expresión `length('Hello!')` significa que se está llamando a la función llamada *length*, a la cual se le ha pasado el parámetro `'Hello!'`. La función `length()` cuenta la longitud exacta de la cadena que se le ha pasado. +Si la función imprimiera el resultado en pantalla de inmediato (como `console.log()`), veríamos el número, pero no podríamos usarlo después: sumarlo, guardarlo o compararlo. Precisamente por eso la devolución de un valor es tan importante: permite conectar las funciones entre sí. Así, a partir de pequeños pasos se construyen grandes programas. + +## Una función con varios parámetros -La llamada a una función siempre se indica con paréntesis `()`, que van justo después del nombre de la función. Entre los paréntesis puede haber cualquier cantidad de parámetros, o incluso ninguno. La cantidad depende de la función utilizada. Tomemos como ejemplo la función `pow()`, que eleva un número especificado a una potencia determinada. Esta función recibe dos parámetros y eleva el número pasado como primer parámetro a la potencia pasada como segundo parámetro. +Algunas funciones aceptan varios valores a la vez. Por ejemplo, `Math.pow()` eleva un número a una potencia: el primer argumento es la base, el segundo es el exponente. ```javascript -import { pow } from 'hexlet-basics/math'; +// 2 a la 3ª potencia: 2 * 2 * 2 +console.log(Math.pow(2, 3)); // => 8 -// La llamada a pow(2, 3) devuelve el valor de 2 elevado a la 3ª potencia -const result = pow(2, 3); // 2 * 2 * 2 -console.log(result); // => 8 +// 5 a la 2ª potencia: 5 * 5 +console.log(Math.pow(5, 2)); // => 25 ``` -En resumen, los operadores y las funciones son lo mismo. La diferencia clave radica en cómo se escriben. Si imaginamos (hipotéticamente) la suma como una función, se vería así: +En cuanto a la estructura, una llamada con varios argumentos no se diferencia de una llamada con uno: el mismo nombre de función, los paréntesis y los argumentos separados por comas. + +`Math` es un conjunto de funciones incorporado en JavaScript para trabajar con números. Está disponible desde cualquier lugar del programa. Por ahora, la expresión `Math.pow(...)` se puede leer como un "nombre largo de función": el prefijo `Math.` indica que la función pertenece a ese conjunto. Lo que significa realmente el punto lo veremos en las lecciones sobre objetos. Esto no afecta en absoluto al comportamiento de la función. + +La lista completa de funciones matemáticas está disponible en la [documentación de MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math). + +## Parámetros y argumentos + +En las conversaciones sobre funciones aparecen las palabras **parámetros** y **argumentos**. Están relacionadas, pero no son lo mismo. + +Se habla de **parámetros** al crear una función: son las variables dentro de la función en las que entran los valores pasados. Se habla de **argumentos** al llamarla: es lo que pasamos a la función. Un argumento puede ser un número, una variable o cualquier expresión: ```javascript -// Suma normal -3 + 5; // 8 -// Suma representada como función -// Parece extraño, pero transmite el significado de las funciones -+(3, 5); +console.log(Math.pow(2, 3)); // => 8, los argumentos son números + +const x = 2; +// un argumento puede ser una expresión, se evaluará antes de pasarse +console.log(Math.pow(x + 1, 3)); // => 27 ``` -## Resumen +No es obligatorio memorizar esto, pero será útil al leer literatura en inglés. + +## Cómo conocer nuevas funciones -Las funciones se llaman y devuelven un resultado, que luego se puede utilizar en cálculos posteriores o, por ejemplo, mostrar en pantalla. +Cada función tiene una **firma**: su "descripción", es decir, el nombre, la lista de parámetros y el tipo de valor devuelto. Es la firma la que permite entender cómo usar una función sin leer su código. Por ejemplo, la documentación de MDN describe `Math.pow()` así: + +``` +Math.pow(base, exponent) + +Parámetros + base — la base de la potencia + exponent — el exponente de la potencia +``` -Pregunta de autoevaluación. ¿Cómo se puede saber qué devuelve la llamada a la función `console.log()`? Compruébalo. +A partir de la firma se ve de inmediato: la función acepta dos argumentos y devuelve un número. Una vez que aprendas a leer firmas, podrás trabajar con cualquier función desconocida. -
-Respuesta +Es imposible aprenderlo todo, y no hace falta. Lo importante es saber dónde buscar. Para JavaScript hay dos fuentes principales: -La llamada a la función `console.log()` devuelve `undefined`. +- **MDN** ([developer.mozilla.org](https://developer.mozilla.org/es/)) - documentación sobre las capacidades incorporadas del lenguaje y las API del navegador. +- **Documentación de Node.js** ([nodejs.org/api](https://nodejs.org/api/)) - la parte del servidor, funciones para trabajar con el sistema de archivos, la red, etc. -
+Otra forma es leer el código de otras personas: cualquier paquete de npm es abierto, y en él a menudo se pueden encontrar técnicas de las que no se habla en los libros de texto. diff --git a/modules/35-calling-functions/100-call/es/data.yml b/modules/35-calling-functions/100-call/es/data.yml index 2246a485..6554ba63 100644 --- a/modules/35-calling-functions/100-call/es/data.yml +++ b/modules/35-calling-functions/100-call/es/data.yml @@ -1,9 +1,8 @@ --- -name: Funciones y su llamado +name: Funciones y su llamada tips: - - > - [Llamada a una - función](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Funciones#llamando_funciones) + - | + [Llamada a una función](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Functions#calling_functions) definitions: - name: Función description: >- @@ -11,5 +10,5 @@ definitions: llama así: `foo()`. - name: Argumento description: >- - información que una función recibe al ser llamada. Por ejemplo, `foo(42)` - es pasar el argumento `42` a la función `foo()`. + la información que una función recibe al ser llamada. Por ejemplo, + `foo(42)` — pasar el argumento `42` a la función `foo()` diff --git a/modules/35-calling-functions/135-calling-functions-default-params/index.js b/modules/35-calling-functions/135-calling-functions-default-params/index.js index 84c09481..7eb4b252 100644 --- a/modules/35-calling-functions/135-calling-functions-default-params/index.js +++ b/modules/35-calling-functions/135-calling-functions-default-params/index.js @@ -1,7 +1,7 @@ -const distance = 450; // расстояние, км -const fuelConsumption = 8.4; // расход топлива, л/100 км -const fuelPrice = 64.2; // цена топлива, руб./литр -const passengers = 4; // количество пассажиров +const distance = 450; // distance, km +const fuelConsumption = 8.4; // fuel consumption, l/100 km +const fuelPrice = 64.2; // fuel price, per liter +const passengers = 4; // number of passengers // BEGIN const fuel = (distance / 100) * fuelConsumption; diff --git a/modules/35-calling-functions/150-calling-functions-expression/description.es.yml b/modules/35-calling-functions/150-calling-functions-expression/description.es.yml index a7331b86..f4c1f032 100644 --- a/modules/35-calling-functions/150-calling-functions-expression/description.es.yml +++ b/modules/35-calling-functions/150-calling-functions-expression/description.es.yml @@ -1,77 +1,101 @@ --- -name: Llamada a una función - expresión +name: Llamada a una función es una expresión theory: | - En programación, una expresión es algo que devuelve un resultado que se puede utilizar. Ya sabemos bastante sobre expresiones y los principios de su construcción. Las operaciones matemáticas (suma, resta), así como las operaciones de cadenas (concatenación), - todas estas son expresiones: + Cuando escribimos programas, necesitamos conectar acciones entre sí. La suma de números, la unión de cadenas y el trabajo con variables son ejemplos de cómo pasos simples se combinan en un comportamiento más complejo. ```javascript - 1 + 5 * 3; - 'Hex' + 'Let'; - // Las variables pueden ser parte de una expresión - rate * 5; + const rate = 10; + const hours = 5; + const salary = rate * hours + 100; + console.log(salary); // => 150 ``` - La característica de las expresiones es que devuelven un resultado que se puede asignar a una constante o mostrar en pantalla. Por ejemplo: + En programación, para esto se usa el concepto de **expresión**: una construcción que se evalúa y produce un resultado. En el ejemplo anterior, `rate * hours + 100` es una expresión compuesta por variables, un literal numérico y operaciones aritméticas. El resultado se puede guardar en una variable o usar más adelante. + + Las expresiones se pueden combinar infinitamente, complicando gradualmente la lógica. Cada nueva expresión se convierte en parte de una mayor: ```javascript - // Aquí la expresión es 1 + 5 - const sum = 1 + 5; - console.log(1 + 5); + const bonus = 50; + const salary = (rate * hours + bonus) * 12 - 500; + console.log(salary); ``` - Pero no todo en programación es una expresión. La declaración de una variable es una instrucción; no puede ser parte de una expresión. Es decir, este código dará un error: + Así es exactamente como se construyen los programas: los pasos pequeños se suman en grandes construcciones. Por eso es imposible memorizar de antemano todas las combinaciones; es mucho más importante entender cómo se conectan las expresiones entre sí. + + ## Expresiones como argumentos de funciones + + Un argumento de una función siempre es algún valor. Pero un valor no solo se puede escribir directamente, también se puede calcular. Y esto significa que en los argumentos de una función se pueden sustituir cualesquiera expresiones: ```javascript - // Código sin sentido que no funcionará - 10 + const sum = 1 + 5; + // Aquí el argumento es el número 150 + console.log(150); + + // Y aquí el argumento es una expresión que primero se evalúa + console.log(10 * 15); // => 150 + + // Se puede combinar de forma más compleja + const rate = 10; + const hours = 15; + const bonus = 50; + console.log(rate * hours + bonus); // => 200 ``` - ¿Por qué es importante saber esto? Como verás más adelante, las expresiones se pueden combinar para obtener un comportamiento más complejo en lugares inesperados y de formas inesperadas. Entenderás mejor cómo se pueden combinar las partes del código para obtener el resultado deseado. + La función `console.log()` simplemente recibe un valor ya listo y lo muestra en pantalla. La forma de obtener ese valor le es indiferente a la función; por eso las llamadas a funciones combinan perfectamente con cualquier expresión. - Hablemos de las funciones. ¿Una llamada a una función es una expresión o no? Sabemos que las funciones devuelven un resultado, por lo tanto, sí, son expresiones. De esto se deduce automáticamente muchas cosas interesantes. Por ejemplo, podemos usar una llamada a una función directamente en operaciones matemáticas. Así es como se puede obtener el índice del último carácter en una palabra: + ## Llamada a una función dentro de una función - ```javascript - import { length } from 'hexlet-basics/string'; + Como una llamada a una función es en sí misma una expresión, su resultado se puede pasar de inmediato a otra función: - const name = 'JavaScript'; - // Los índices comienzan desde cero - // ¡Llamada al método y resta juntos! - const lastIndex = length(name) - 1; - console.log(lastIndex); // 9 + ```javascript + // Math.abs(-5) devuelve 5 + // Este resultado se usa de inmediato como argumento de console.log() + console.log(Math.abs(-5)); // => 5 ``` - En este código no hay una nueva sintaxis. Solamente hemos combinado partes conocidas basándonos en su naturaleza. Podemos ir aún más lejos: + Aquí `Math.abs(-5)` se evalúa primero y devuelve `5`. Luego este valor se sustituye en la llamada a `console.log()`. Tal combinación puede ser tan profunda como se quiera: - ```javascript - console.log(length(name) - 1); // 9 + ```text + console.log(Math.abs(-5)) + + Paso 1: Math.abs(-5) → 5 + Paso 2: console.log(5) → muestra 5 ``` - Todo esto es válido para cualquier función, por ejemplo, las funciones de cadenas: + Primero se evalúan las llamadas anidadas, luego la externa. Por ejemplo, en `Math.round(Math.random() * 10)` primero se ejecuta `Math.random()`, luego la multiplicación y solo después `Math.round()`. + + ## Uso de funciones como parte de expresiones + + Las funciones devuelven valores, lo que significa que sus llamadas se pueden usar como parte de cualquier otra expresión. Para obtener la longitud de una cadena, usaremos la función `length()`: ```javascript import { length } from 'hexlet-basics/string'; - const name = 'JavaScript'; - // Se utiliza interpolación - console.log(`Último carácter: ${name[length(name) - 1]}`); - // 'Último carácter: t' + const name = 'python'; + + // La longitud de la cadena menos 1: el índice del último carácter + const lastIndex = length(name) - 1; + console.log(lastIndex); // => 5 + + // El resultado se puede usar en aritmética + const text = 'hexlet'; + const double = length(text) * 2; + console.log(double); // => 12 ``` + Aquí `length(name)` y `length(text)` son expresiones completas: devuelven valores que se pueden combinar con números, variables y otras operaciones. + instructions: | - Muestra en pantalla la primera y la última letra de la oración que está almacenada en la constante `text`, en el siguiente formato: + Dada la cadena `text = 'Hexlet'`. Muestra en pantalla el primer y el último carácter en el formato: ```text - First: N + First: H Last: t ``` - Intenta crear solamente una constante en la que se almacene el texto necesario antes de imprimirlo en pantalla. En esta lección, estamos practicando la habilidad de construir una expresión compuesta. - -# tips: [] - definitions: - name: Expresión description: | - una secuencia de acciones sobre datos que conduce a un resultado que se puede utilizar. + una secuencia de acciones sobre datos que conduce a algún resultado que se puede utilizar. diff --git a/modules/35-calling-functions/150-calling-functions-expression/en/EXERCISE.md b/modules/35-calling-functions/150-calling-functions-expression/en/EXERCISE.md index e436633b..33136595 100644 --- a/modules/35-calling-functions/150-calling-functions-expression/en/EXERCISE.md +++ b/modules/35-calling-functions/150-calling-functions-expression/en/EXERCISE.md @@ -1,9 +1,6 @@ - -Print the first and last letters of the sentence stored in the variable `text` using this format: +Given the string `text = 'Hexlet'`. Print the first and last characters in the format: ```text -First: N +First: H Last: t ``` - -Try to create only one variable you want to assign the text to before you print it. In this lesson, we're practicing building a compound expression. diff --git a/modules/35-calling-functions/150-calling-functions-expression/en/README.md b/modules/35-calling-functions/150-calling-functions-expression/en/README.md index 98ba6b62..acce1b27 100644 --- a/modules/35-calling-functions/150-calling-functions-expression/en/README.md +++ b/modules/35-calling-functions/150-calling-functions-expression/en/README.md @@ -1,55 +1,82 @@ - -In programming, an expression is something that returns a usable output value. We already know a lot about expressions and their principles of composition. Math operations (addition, subtraction, etc.) and string operations (concatenation) are all expressions: +When we write programs, we need to connect actions to each other. Adding numbers, joining strings, and working with variables are examples of how simple steps combine into more complex behavior. ```javascript -1 + 5 * 3; -'Hex' + 'Let'; -// Variables can be a part of an expression -rate * 5; +const rate = 10; +const hours = 5; +const salary = rate * hours + 100; +console.log(salary); // => 150 ``` -One feature of expressions is that they return a result that can be assigned to a variable or printed. For instance: +In programming, the concept of an **expression** is used for this — a construct that is evaluated and produces a result. In the example above, `rate * hours + 100` is an expression composed of variables, a numeric literal, and arithmetic operations. The result can be saved in a variable or used further. + +Expressions can be combined endlessly, gradually making the logic more complex. Each new expression becomes part of a bigger one: ```javascript -// Here the expression is 1 + 5 -const sum = 1 + 5; -console.log(1 + 5); +const bonus = 50; +const salary = (rate * hours + bonus) * 12 - 500; +console.log(salary); ``` -But not any code can be an expression. The definition of a variable is a statement, it can't be part of an expression, and it will lead to an error: +This is exactly how programs are built: small steps add up into large constructs. That is why it is impossible to memorize all the combinations in advance — it is far more important to understand how expressions connect to each other. + +## Expressions as function arguments + +A function argument is always some value. But a value can not only be written directly, it can also be calculated. This means any expressions can be substituted into function arguments: ```javascript -// Pointless code that won't work -10 + const sum = 1 + 5; +// Here the argument is the number 150 +console.log(150); + +// And here the argument is an expression that is evaluated first +console.log(10 * 15); // => 150 + +// You can combine in more complex ways +const rate = 10; +const hours = 15; +const bonus = 50; +console.log(rate * hours + bonus); // => 200 ``` -Why is this important to know? You can combine expressions to get more and more complex behavior in the most unexpected places and the most surprising ways, as you will see. You will get a better understanding of how you can combine pieces of code to get the desired results. +The `console.log()` function simply receives a ready value and prints it. The way this value is obtained is irrelevant to the function — that is why function calls combine perfectly with any expressions. -Let's talk about functions. Is a function call an expression or not? We know that functions return results, which means that, yes, they are expressions. It leads to a lot of interesting possibilities. For example, we can call functions directly in math operations. This is how we can get the last character index in a word: +## Calling a function inside a function -```javascript -import { length } from 'hexlet-basics/string'; +Since a function call is itself an expression, its result can be passed directly to another function: -const name = 'JavaScript'; -// Indexes count from zero -// Function call and subtraction combined! -const lastIndex = length(name) - 1; -console.log(lastIndex); // 9 +```javascript +// Math.abs(-5) returns 5 +// This result is immediately used as the argument of console.log() +console.log(Math.abs(-5)); // => 5 ``` -This code has no new syntax. We've just combined what we already know. We could go even further: +Here `Math.abs(-5)` is evaluated first and returns `5`. Then this value is substituted into the `console.log()` call. Such a combination can be as deep as you like: -```javascript -console.log(length(name) - 1); // 9 +```text +console.log(Math.abs(-5)) + +Step 1: Math.abs(-5) → 5 +Step 2: console.log(5) → prints 5 ``` -All of this holds for any function, e.g. string functions: +First the nested calls are evaluated, then the outer one. For example, in `Math.round(Math.random() * 10)`, `Math.random()` runs first, then the multiplication, and only then `Math.round()`. + +## Using functions as part of expressions + +Functions return values, which means their calls can be used as part of any other expressions. To get the length of a string, we will use the `length()` function: ```javascript import { length } from 'hexlet-basics/string'; -const name = 'JavaScript'; -// Interpolation -console.log(`Last char: ${name[length(name) - 1]}`); -// 'Last char: t' +const name = 'python'; + +// The length of the string minus 1 — the index of the last character +const lastIndex = length(name) - 1; +console.log(lastIndex); // => 5 + +// The result can be used in arithmetic +const text = 'hexlet'; +const double = length(text) * 2; +console.log(double); // => 12 ``` + +Here `length(name)` and `length(text)` are full-fledged expressions: they return values that can be combined with numbers, variables, and other operations. diff --git a/modules/35-calling-functions/150-calling-functions-expression/en/data.yml b/modules/35-calling-functions/150-calling-functions-expression/en/data.yml index eea55a53..b23e29b3 100644 --- a/modules/35-calling-functions/150-calling-functions-expression/en/data.yml +++ b/modules/35-calling-functions/150-calling-functions-expression/en/data.yml @@ -1,3 +1,7 @@ --- -name: Function call as an expression -tips: [] +name: A function call is an expression +definitions: + - name: Expression + description: > + a sequence of actions on data that produces some result + which can be used. diff --git a/modules/35-calling-functions/150-calling-functions-expression/es/EXERCISE.md b/modules/35-calling-functions/150-calling-functions-expression/es/EXERCISE.md index f8da9e5d..39529b30 100644 --- a/modules/35-calling-functions/150-calling-functions-expression/es/EXERCISE.md +++ b/modules/35-calling-functions/150-calling-functions-expression/es/EXERCISE.md @@ -1,9 +1,6 @@ - -Muestra en pantalla la primera y la última letra de la oración que está almacenada en la constante `text`, en el siguiente formato: +Dada la cadena `text = 'Hexlet'`. Muestra en pantalla el primer y el último carácter en el formato: ```text -First: N +First: H Last: t ``` - -Intenta crear solamente una constante en la que se almacene el texto necesario antes de imprimirlo en pantalla. En esta lección, estamos practicando la habilidad de construir una expresión compuesta. diff --git a/modules/35-calling-functions/150-calling-functions-expression/es/README.md b/modules/35-calling-functions/150-calling-functions-expression/es/README.md index cfb9b6ef..455f62ff 100644 --- a/modules/35-calling-functions/150-calling-functions-expression/es/README.md +++ b/modules/35-calling-functions/150-calling-functions-expression/es/README.md @@ -1,55 +1,82 @@ - -En programación, una expresión es algo que devuelve un resultado que se puede utilizar. Ya sabemos bastante sobre expresiones y los principios de su construcción. Las operaciones matemáticas (suma, resta), así como las operaciones de cadenas (concatenación), - todas estas son expresiones: +Cuando escribimos programas, necesitamos conectar acciones entre sí. La suma de números, la unión de cadenas y el trabajo con variables son ejemplos de cómo pasos simples se combinan en un comportamiento más complejo. ```javascript -1 + 5 * 3; -'Hex' + 'Let'; -// Las variables pueden ser parte de una expresión -rate * 5; +const rate = 10; +const hours = 5; +const salary = rate * hours + 100; +console.log(salary); // => 150 ``` -La característica de las expresiones es que devuelven un resultado que se puede asignar a una constante o mostrar en pantalla. Por ejemplo: +En programación, para esto se usa el concepto de **expresión**: una construcción que se evalúa y produce un resultado. En el ejemplo anterior, `rate * hours + 100` es una expresión compuesta por variables, un literal numérico y operaciones aritméticas. El resultado se puede guardar en una variable o usar más adelante. + +Las expresiones se pueden combinar infinitamente, complicando gradualmente la lógica. Cada nueva expresión se convierte en parte de una mayor: ```javascript -// Aquí la expresión es 1 + 5 -const sum = 1 + 5; -console.log(1 + 5); +const bonus = 50; +const salary = (rate * hours + bonus) * 12 - 500; +console.log(salary); ``` -Pero no todo en programación es una expresión. La declaración de una variable es una instrucción; no puede ser parte de una expresión. Es decir, este código dará un error: +Así es exactamente como se construyen los programas: los pasos pequeños se suman en grandes construcciones. Por eso es imposible memorizar de antemano todas las combinaciones; es mucho más importante entender cómo se conectan las expresiones entre sí. + +## Expresiones como argumentos de funciones + +Un argumento de una función siempre es algún valor. Pero un valor no solo se puede escribir directamente, también se puede calcular. Y esto significa que en los argumentos de una función se pueden sustituir cualesquiera expresiones: ```javascript -// Código sin sentido que no funcionará -10 + const sum = 1 + 5; +// Aquí el argumento es el número 150 +console.log(150); + +// Y aquí el argumento es una expresión que primero se evalúa +console.log(10 * 15); // => 150 + +// Se puede combinar de forma más compleja +const rate = 10; +const hours = 15; +const bonus = 50; +console.log(rate * hours + bonus); // => 200 ``` -¿Por qué es importante saber esto? Como verás más adelante, las expresiones se pueden combinar para obtener un comportamiento más complejo en lugares inesperados y de formas inesperadas. Entenderás mejor cómo se pueden combinar las partes del código para obtener el resultado deseado. +La función `console.log()` simplemente recibe un valor ya listo y lo muestra en pantalla. La forma de obtener ese valor le es indiferente a la función; por eso las llamadas a funciones combinan perfectamente con cualquier expresión. -Hablemos de las funciones. ¿Una llamada a una función es una expresión o no? Sabemos que las funciones devuelven un resultado, por lo tanto, sí, son expresiones. De esto se deduce automáticamente muchas cosas interesantes. Por ejemplo, podemos usar una llamada a una función directamente en operaciones matemáticas. Así es como se puede obtener el índice del último carácter en una palabra: +## Llamada a una función dentro de una función -```javascript -import { length } from 'hexlet-basics/string'; +Como una llamada a una función es en sí misma una expresión, su resultado se puede pasar de inmediato a otra función: -const name = 'JavaScript'; -// Los índices comienzan desde cero -// ¡Llamada al método y resta juntos! -const lastIndex = length(name) - 1; -console.log(lastIndex); // 9 +```javascript +// Math.abs(-5) devuelve 5 +// Este resultado se usa de inmediato como argumento de console.log() +console.log(Math.abs(-5)); // => 5 ``` -En este código no hay una nueva sintaxis. Solamente hemos combinado partes conocidas basándonos en su naturaleza. Podemos ir aún más lejos: +Aquí `Math.abs(-5)` se evalúa primero y devuelve `5`. Luego este valor se sustituye en la llamada a `console.log()`. Tal combinación puede ser tan profunda como se quiera: -```javascript -console.log(length(name) - 1); // 9 +```text +console.log(Math.abs(-5)) + +Paso 1: Math.abs(-5) → 5 +Paso 2: console.log(5) → muestra 5 ``` -Todo esto es válido para cualquier función, por ejemplo, las funciones de cadenas: +Primero se evalúan las llamadas anidadas, luego la externa. Por ejemplo, en `Math.round(Math.random() * 10)` primero se ejecuta `Math.random()`, luego la multiplicación y solo después `Math.round()`. + +## Uso de funciones como parte de expresiones + +Las funciones devuelven valores, lo que significa que sus llamadas se pueden usar como parte de cualquier otra expresión. Para obtener la longitud de una cadena, usaremos la función `length()`: ```javascript import { length } from 'hexlet-basics/string'; -const name = 'JavaScript'; -// Se utiliza interpolación -console.log(`Último carácter: ${name[length(name) - 1]}`); -// 'Último carácter: t' +const name = 'python'; + +// La longitud de la cadena menos 1: el índice del último carácter +const lastIndex = length(name) - 1; +console.log(lastIndex); // => 5 + +// El resultado se puede usar en aritmética +const text = 'hexlet'; +const double = length(text) * 2; +console.log(double); // => 12 ``` + +Aquí `length(name)` y `length(text)` son expresiones completas: devuelven valores que se pueden combinar con números, variables y otras operaciones. diff --git a/modules/35-calling-functions/150-calling-functions-expression/es/data.yml b/modules/35-calling-functions/150-calling-functions-expression/es/data.yml index aeccdb62..dfd4b6c1 100644 --- a/modules/35-calling-functions/150-calling-functions-expression/es/data.yml +++ b/modules/35-calling-functions/150-calling-functions-expression/es/data.yml @@ -1,7 +1,7 @@ --- -name: Llamada a una función - expresión +name: Llamada a una función es una expresión definitions: - name: Expresión description: > - una secuencia de acciones sobre datos que conduce a un resultado que se - puede utilizar. + una secuencia de acciones sobre datos que conduce a algún resultado + que se puede utilizar. diff --git a/modules/35-calling-functions/180-variadic-parameters/description.es.yml b/modules/35-calling-functions/180-variadic-parameters/description.es.yml index bad346c2..71fe3a98 100644 --- a/modules/35-calling-functions/180-variadic-parameters/description.es.yml +++ b/modules/35-calling-functions/180-variadic-parameters/description.es.yml @@ -3,41 +3,47 @@ name: Funciones con número variable de parámetros theory: | - Una característica interesante de algunas funciones es que pueden aceptar un número variable de parámetros. No estamos hablando de valores predeterminados. Mira este ejemplo: + Una característica interesante de algunas funciones es la capacidad de aceptar un número variable de parámetros. No se trata de valores por defecto. Observa este ejemplo: ```javascript Math.max(1, 10, 3); // 10 ``` - La función `Math.max()` encuentra el valor máximo entre los parámetros proporcionados. ¿Cuántos parámetros crees que espera esta función? Si abrimos la documentación de esta función, veremos una construcción extraña: + La función `Math.max()` encuentra el valor máximo entre los parámetros proporcionados. ¿Cuántos parámetros crees que espera como entrada? Si abres la documentación de esta función, verás una construcción extraña: - ``` - Math.max([value1[, value2[, ...]]]) - ``` + ``` + Math.max([value1[, value2[, ...]]]) + ``` - Esta notación indica que esta función acepta cualquier número de parámetros (e incluso puede ser llamada sin ellos). La opcionalidad de los parámetros se describe con corchetes *[ ]*, de la misma manera que se describen los parámetros opcionales que tienen valores predeterminados. La posibilidad de pasar cualquier número de parámetros está representada por esta parte *[, ...]*. + Esta notación indica que esta función acepta cualquier número de parámetros como entrada (e incluso puede ser llamada sin ellos). La opcionalidad de los parámetros proporcionados se describe con los corchetes *[ ]*, exactamente igual que se describen los parámetros opcionales que tienen valores por defecto. La posibilidad de pasar cualquier número de parámetros está codificada en esta parte *[, ...]*. - ```javascript - Math.max(1, -3, 2, 3, 2); // 3 - ``` + ```javascript + Math.max(1, -3, 2, 3, 2); // 3 + ``` - Todo lo que se indica entre corchetes no es obligatorio. En esta notación `Math.max([value1[, value2[, ...]]])`, hay varios corchetes y están anidados entre sí. Analicemos cada uno de ellos: + Todo lo que se indica entre corchetes es opcional. En esta notación `Math.max([value1[, value2[, ...]]])` hay varios de estos corchetes, y están anidados unos dentro de otros. Analicemos cada uno de ellos: - * Los primeros corchetes contienen `[value1[, value2[, ...]]]`, lo que significa que se puede llamar a la función sin parámetros, ya que estos corchetes contienen todo lo que se pasa a la función. Si eliminamos todo el contenido de estos corchetes y los corchetes mismos, nos quedará `Math.max()` — una llamada sin parámetros. - * Los segundos corchetes están anidados dentro de los primeros y contienen `[, value2[, ...]]`. Indican que si hemos especificado el primer parámetro, opcionalmente podemos especificar el segundo parámetro. Sin estos corchetes y su contenido, la notación sería `Math.max([value1])`. - * Los terceros corchetes están anidados dentro de los segundos y contienen `[, ...]`. Los puntos suspensivos indican que puede haber cualquier número de parámetros. Si eliminamos estos corchetes y su contenido, obtendremos una notación como `Math.max([value1[, value2]])`. + * Los primeros corchetes contienen `[value1[, value2[, ...]]]`, lo que significa que se puede llamar a la función sin parámetros, ya que estos corchetes contienen todo lo que se pasa a la función. Si eliminas todo el contenido de estos corchetes y los corchetes mismos, queda `Math.max()` — una llamada sin parámetros. + * Los segundos corchetes están anidados dentro de los primeros y contienen `[, value2[, ...]]`. Indican que si especificamos el primer parámetro, entonces podemos especificar opcionalmente un segundo parámetro. Sin estos corchetes y su contenido, la notación sería de la forma `Math.max([value1])`. + * Los terceros corchetes están anidados dentro de los segundos y contienen `[, ...]`. Los puntos suspensivos indican que puede haber cualquier número de parámetros. Si eliminas estos corchetes y su contenido, obtienes una notación de la forma `Math.max([value1[, value2]])`. - La coma está dentro de los corchetes, ya que si no especificamos un parámetro, la coma no es necesaria. De lo contrario, una llamada con un solo parámetro se vería así `Math.max(value1,)`. + La coma está dentro de los corchetes porque si no especificamos un parámetro, la coma no es necesaria. De lo contrario, una llamada con un solo parámetro se vería así `Math.max(value1,)`. -instructions: | + La función `Math.min()` funciona de manera similar, sólo que busca el valor más pequeño: - Calcula programáticamente (no mentalmente) el número mínimo entre 3, 10, 22, -3, 0, y muéstralo en pantalla. Utiliza la función `Math.min()`, que funciona de manera similar a `Math.max()`. + ```javascript + Math.min(1, 10, 3); // 1 + Math.min(1, -3, 2, 3, 2); // -3 + ``` + +instructions: | + Encuentra el valor mínimo entre los números `3`, `-3`, `10`, `22`, `0` usando la función `Math.min()` e imprime el resultado en la pantalla. tips: - | - [Ejemplo de función con número variable de parámetros](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Math/max) + [Ejemplo de función con número variable de parámetros](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math/max) definitions: - - name: Argumento predeterminado - description: Argumento opcional de una función. + - name: Argumento por defecto + description: argumento opcional de una función. diff --git a/modules/35-calling-functions/180-variadic-parameters/en/EXERCISE.md b/modules/35-calling-functions/180-variadic-parameters/en/EXERCISE.md index a1267429..7a47eede 100644 --- a/modules/35-calling-functions/180-variadic-parameters/en/EXERCISE.md +++ b/modules/35-calling-functions/180-variadic-parameters/en/EXERCISE.md @@ -1,2 +1 @@ - -Write a program to calculate the minimum value of 3, 10, 22, -3, 0, and print it. Use the function `Math.min()`, which works similarly to `Math.max()`. +Find the minimum value among the numbers `3`, `-3`, `10`, `22`, `0` using the `Math.min()` function and print the result to the screen. diff --git a/modules/35-calling-functions/180-variadic-parameters/en/README.md b/modules/35-calling-functions/180-variadic-parameters/en/README.md index c809c51f..cd76beb8 100644 --- a/modules/35-calling-functions/180-variadic-parameters/en/README.md +++ b/modules/35-calling-functions/180-variadic-parameters/en/README.md @@ -1,18 +1,33 @@ -Some functions have the interesting feature of accepting an indefinite number of parameters. And we're not talking about default values. Check out this example: +An interesting feature of some functions is the ability to accept a variable number of parameters. This is not about default values. Take a look at this example: ```javascript Math.max(1, 10, 3); // 10 ``` -The function `Math.max()` finds the maximum value among the passed parameters. How many parameters do you think it expects? This function's documentation shows something interesting: +The `Math.max()` function finds the maximum value among the passed parameters. How many parameters do you think it expects as input? If you open the documentation for this function, you will see a strange construct: ``` Math.max([value1[, value2[, ...]]]) ``` - The way it is written means this function accepts any number of parameters (even none). The optional parameters are specified by square brackets _[ ]_, and so are the optional parameters with default values. The ability to pass any number of parameters is encoded with _[, ...]_. + This notation means that this function accepts any number of parameters as input (and can even be called without them). The optionality of the passed parameters is described by the brackets *[ ]*, exactly the same way optional parameters with default values are described. The ability to pass any number of parameters is encoded in this part *[, ...]*. ```javascript Math.max(1, -3, 2, 3, 2); // 3 ``` + + Everything specified in square brackets is optional. In this notation `Math.max([value1[, value2[, ...]]])` there are several such brackets, and they are nested within each other. Let's break down each of them: + + * The first square brackets contain `[value1[, value2[, ...]]]`, which means you can call the function without parameters, since these square brackets contain everything that is passed into the function. If you remove all the contents of these brackets and the brackets themselves, you are left with `Math.max()` — a call without parameters. + * The second square brackets are nested inside the first and contain `[, value2[, ...]]`. They indicate that if we specified the first parameter, then we can optionally specify a second parameter. Without these brackets and their contents, the notation would look like `Math.max([value1])`. + * The third square brackets are nested inside the second and contain `[, ...]`. The ellipsis indicates that there can be any number of parameters. If you remove these brackets and their contents, you get a notation like `Math.max([value1[, value2]])`. + + The comma is inside the square brackets because if we do not specify a parameter, the comma is not needed. Otherwise, a call with a single parameter would look like this `Math.max(value1,)`. + +The `Math.min()` function works similarly, only it looks for the smallest value: + +```javascript +Math.min(1, 10, 3); // 1 +Math.min(1, -3, 2, 3, 2); // -3 +``` diff --git a/modules/35-calling-functions/180-variadic-parameters/en/data.yml b/modules/35-calling-functions/180-variadic-parameters/en/data.yml index 8bac5cbe..59f1a1b5 100644 --- a/modules/35-calling-functions/180-variadic-parameters/en/data.yml +++ b/modules/35-calling-functions/180-variadic-parameters/en/data.yml @@ -1,3 +1,8 @@ --- -name: Functions with variadic parameters -tips: [] +name: Functions with a variable number of parameters +tips: + - | + [Example of a function with a variable number of parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) +definitions: + - name: Default argument + description: an optional argument of a function. diff --git a/modules/35-calling-functions/180-variadic-parameters/es/EXERCISE.md b/modules/35-calling-functions/180-variadic-parameters/es/EXERCISE.md index 05b2186f..c672ec26 100644 --- a/modules/35-calling-functions/180-variadic-parameters/es/EXERCISE.md +++ b/modules/35-calling-functions/180-variadic-parameters/es/EXERCISE.md @@ -1,2 +1 @@ - -Calcula programáticamente (no mentalmente) el número mínimo entre 3, 10, 22, -3, 0, y muéstralo en pantalla. Utiliza la función `Math.min()`, que funciona de manera similar a `Math.max()`. +Encuentra el valor mínimo entre los números `3`, `-3`, `10`, `22`, `0` usando la función `Math.min()` e imprime el resultado en la pantalla. diff --git a/modules/35-calling-functions/180-variadic-parameters/es/README.md b/modules/35-calling-functions/180-variadic-parameters/es/README.md index c610ecec..edc1091a 100644 --- a/modules/35-calling-functions/180-variadic-parameters/es/README.md +++ b/modules/35-calling-functions/180-variadic-parameters/es/README.md @@ -1,26 +1,33 @@ -Una característica interesante de algunas funciones es que pueden aceptar un número variable de parámetros. No estamos hablando de valores predeterminados. Mira este ejemplo: +Una característica interesante de algunas funciones es la capacidad de aceptar un número variable de parámetros. No se trata de valores por defecto. Observa este ejemplo: ```javascript Math.max(1, 10, 3); // 10 ``` -La función `Math.max()` encuentra el valor máximo entre los parámetros proporcionados. ¿Cuántos parámetros crees que espera esta función? Si abrimos la documentación de esta función, veremos una construcción extraña: +La función `Math.max()` encuentra el valor máximo entre los parámetros proporcionados. ¿Cuántos parámetros crees que espera como entrada? Si abres la documentación de esta función, verás una construcción extraña: ``` Math.max([value1[, value2[, ...]]]) ``` - Esta notación indica que esta función acepta cualquier número de parámetros (e incluso puede ser llamada sin ellos). La opcionalidad de los parámetros se describe con corchetes *[ ]*, de la misma manera que se describen los parámetros opcionales que tienen valores predeterminados. La posibilidad de pasar cualquier número de parámetros está representada por esta parte *[, ...]*. + Esta notación indica que esta función acepta cualquier número de parámetros como entrada (e incluso puede ser llamada sin ellos). La opcionalidad de los parámetros proporcionados se describe con los corchetes *[ ]*, exactamente igual que se describen los parámetros opcionales que tienen valores por defecto. La posibilidad de pasar cualquier número de parámetros está codificada en esta parte *[, ...]*. ```javascript Math.max(1, -3, 2, 3, 2); // 3 ``` - Todo lo que se indica entre corchetes no es obligatorio. En esta notación `Math.max([value1[, value2[, ...]]])`, hay varios corchetes y están anidados entre sí. Analicemos cada uno de ellos: + Todo lo que se indica entre corchetes es opcional. En esta notación `Math.max([value1[, value2[, ...]]])` hay varios de estos corchetes, y están anidados unos dentro de otros. Analicemos cada uno de ellos: - * Los primeros corchetes contienen `[value1[, value2[, ...]]]`, lo que significa que se puede llamar a la función sin parámetros, ya que estos corchetes contienen todo lo que se pasa a la función. Si eliminamos todo el contenido de estos corchetes y los corchetes mismos, nos quedará `Math.max()` — una llamada sin parámetros. - * Los segundos corchetes están anidados dentro de los primeros y contienen `[, value2[, ...]]`. Indican que si hemos especificado el primer parámetro, opcionalmente podemos especificar el segundo parámetro. Sin estos corchetes y su contenido, la notación sería `Math.max([value1])`. - * Los terceros corchetes están anidados dentro de los segundos y contienen `[, ...]`. Los puntos suspensivos indican que puede haber cualquier número de parámetros. Si eliminamos estos corchetes y su contenido, obtendremos una notación como `Math.max([value1[, value2]])`. + * Los primeros corchetes contienen `[value1[, value2[, ...]]]`, lo que significa que se puede llamar a la función sin parámetros, ya que estos corchetes contienen todo lo que se pasa a la función. Si eliminas todo el contenido de estos corchetes y los corchetes mismos, queda `Math.max()` — una llamada sin parámetros. + * Los segundos corchetes están anidados dentro de los primeros y contienen `[, value2[, ...]]`. Indican que si especificamos el primer parámetro, entonces podemos especificar opcionalmente un segundo parámetro. Sin estos corchetes y su contenido, la notación sería de la forma `Math.max([value1])`. + * Los terceros corchetes están anidados dentro de los segundos y contienen `[, ...]`. Los puntos suspensivos indican que puede haber cualquier número de parámetros. Si eliminas estos corchetes y su contenido, obtienes una notación de la forma `Math.max([value1[, value2]])`. - La coma está dentro de los corchetes, ya que si no especificamos un parámetro, la coma no es necesaria. De lo contrario, una llamada con un solo parámetro se vería así `Math.max(value1,)`. + La coma está dentro de los corchetes porque si no especificamos un parámetro, la coma no es necesaria. De lo contrario, una llamada con un solo parámetro se vería así `Math.max(value1,)`. + +La función `Math.min()` funciona de manera similar, sólo que busca el valor más pequeño: + +```javascript +Math.min(1, 10, 3); // 1 +Math.min(1, -3, 2, 3, 2); // -3 +``` diff --git a/modules/35-calling-functions/180-variadic-parameters/es/data.yml b/modules/35-calling-functions/180-variadic-parameters/es/data.yml index d9291950..e85812cd 100644 --- a/modules/35-calling-functions/180-variadic-parameters/es/data.yml +++ b/modules/35-calling-functions/180-variadic-parameters/es/data.yml @@ -1,9 +1,8 @@ --- name: Funciones con número variable de parámetros tips: - - > - [Ejemplo de función con número variable de - parámetros](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Math/max) + - | + [Ejemplo de función con número variable de parámetros](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math/max) definitions: - - name: Argumento predeterminado - description: Argumento opcional de una función. + - name: Argumento por defecto + description: argumento opcional de una función. diff --git a/modules/35-calling-functions/270-deterministic/description.es.yml b/modules/35-calling-functions/270-deterministic/description.es.yml index 7731cb05..ffb06855 100644 --- a/modules/35-calling-functions/270-deterministic/description.es.yml +++ b/modules/35-calling-functions/270-deterministic/description.es.yml @@ -3,7 +3,9 @@ name: Determinismo theory: | - Independientemente del lenguaje de programación utilizado, las funciones dentro de él tienen algunas propiedades fundamentales. Conocer estas propiedades facilita predecir el comportamiento de las funciones, las formas de probarlas y el lugar donde se utilizan. Una de estas propiedades es el determinismo. Una función se considera determinista cuando devuelve el mismo resultado para los mismos parámetros de entrada. Por ejemplo, la función que cuenta la cantidad de caracteres es determinista: + Las funciones en cualquier lenguaje de programación tienen propiedades fundamentales. Nos ayudan a entender cómo se comportará una función en diferentes situaciones, cómo probarla y dónde aplicarla. Una de esas propiedades es el **determinismo**. + + Una **función determinista** siempre devuelve el mismo resultado para los mismos datos de entrada. Por ejemplo, se puede llamar determinista a una función que cuenta la cantidad de caracteres: ```javascript import { length } from 'hexlet-basics/string'; @@ -15,29 +17,45 @@ theory: | length('wow'); // 3 ``` - No importa cuántas veces llamemos a esta función pasando el valor `'hexlet'`, siempre devolverá `6`. Por otro lado, una función que devuelve un número aleatorio no es determinista, ya que para una misma entrada (incluso si está vacía, es decir, no se aceptan parámetros) siempre obtendremos un resultado diferente. No importa cuán diferente sea, incluso si una de cada millón de llamadas devuelve algo diferente, esta función se considera automáticamente no determinista. + No importa cuántas veces llamemos a esta función con el argumento `'hexlet'`, siempre devolverá `6`. + + ## Funciones no deterministas + + El tipo opuesto son las **funciones no deterministas**. Pueden devolver resultados diferentes para los mismos datos de entrada o en ausencia de ellos (funciones sin parámetros). Un buen ejemplo es una función que devuelve un número aleatorio: ```javascript - // Función que devuelve un número aleatorio Math.random(); // 0.09856613113197676 Math.random(); // 0.8839904367241888 ``` - ¿Por qué es importante saber esto? El determinismo afecta seriamente muchos aspectos. Las funciones deterministas son convenientes para trabajar, son fáciles de optimizar y de probar. Si es posible hacer que una función sea determinista, es mejor hacerlo así. + Esta función no tiene argumentos, pero el resultado es diferente cada vez. Si aunque sea una llamada de un millón produce un resultado diferente, la función se considera no determinista. -instructions: | + ```text + Determinista: No determinista: + length('abc') → siempre 3 Math.random() → 0.42 + length('abc') → siempre 3 Math.random() → 0.91 + length('abc') → siempre 3 Math.random() → 0.07 + ``` - La función `Math.random()` devuelve un número aleatorio entre 0 y 1 con varios dígitos decimales. Pero para atender problemas reales, a veces necesitamos obtener números enteros aleatorios, por ejemplo, en el rango de 0 a 10. Implementa el código que imprime precisamente esos números en la pantalla. Para este problema, necesitarás las funciones [Math.random()](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math/random) y [Math.round()](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math/round). + ## Por qué esto importa - Intenta resolver este ejercicio en una sola línea. + El determinismo afecta cómo trabajamos con las funciones: + + - las funciones deterministas son fáciles de probar y predecir; + - son más fáciles de optimizar y reutilizar; + - las funciones no deterministas son más difíciles de verificar porque el resultado cambia. + + Por eso, siempre que sea posible, es mejor procurar que una función sea determinista. + +instructions: | - ## Algoritmo + Genera un número entero aleatorio de 0 a 10 (inclusive) e imprímelo en la pantalla. - Dado que `Math.random()` devuelve números en el rango de 0 a 1, para obtener números en el rango de 0 a 10, debemos multiplicar por 10. Luego, el número resultante se redondea y así obtenemos lo que necesitamos. + Usa `Math.random()` (devuelve un número de 0 a 1) y `Math.round()` (redondea a un entero). tips: - | - [Funciones deterministas](https://es.wikipedia.org/wiki/Funci%C3%B3n_determinista) + [Funciones deterministas](https://es.wikipedia.org/wiki/Pureza_de_funciones#Determinismo_de_la_funci%C3%B3n) definitions: - name: Efecto secundario diff --git a/modules/35-calling-functions/270-deterministic/en/EXERCISE.md b/modules/35-calling-functions/270-deterministic/en/EXERCISE.md index 1df1191b..f369eb1a 100644 --- a/modules/35-calling-functions/270-deterministic/en/EXERCISE.md +++ b/modules/35-calling-functions/270-deterministic/en/EXERCISE.md @@ -1,7 +1,3 @@ +Generate a random integer from 0 to 10 (inclusive) and print it to the screen. -The function `Math.random()` returns a random number from 0 to 1 with many decimal places. But in real tasks, you sometimes want to get random integers, for example, a random number 0 to 10. Write a program printing specifically those numbers. To solve it you'll need [Math.random()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) and [Math.round()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round). -Try to solve this task using only 1 line. - -## Algorithm - -Since `Math.random()` only returns numbers between 0 and 1, we need to multiply it by 10 to get numbers between 0 and 10. Then we round the result to get what we need. +Use `Math.random()` (returns a number from 0 to 1) and `Math.round()` (rounds to an integer). diff --git a/modules/35-calling-functions/270-deterministic/en/README.md b/modules/35-calling-functions/270-deterministic/en/README.md index 83c91466..bf6653cd 100644 --- a/modules/35-calling-functions/270-deterministic/en/README.md +++ b/modules/35-calling-functions/270-deterministic/en/README.md @@ -1,5 +1,6 @@ +Functions in any programming language have fundamental properties. They help us understand how a function will behave in different situations, how to test it, and where to use it. One such property is **determinism**. -Regardless of the programming language, functions possess certain fundamental properties. Knowing these properties makes it easier to predict the behavior of functions, as well as their testing and their usage. These properties include determinism. A function is deterministic when it returns the same result for the same input parameters. For example, a function counting the number of characters is deterministic: +A **deterministic function** always returns the same result for the same input data. For example, a function that counts the number of characters can be called deterministic: ```javascript import { length } from 'hexlet-basics/string'; @@ -11,12 +12,32 @@ length('wow'); // 3 length('wow'); // 3 ``` -No matter how many times we call this function and pass `'hexlet'`, it will always return `6`. In turn, a function that returns a random number is not deterministic, as the same input (even if it is empty, i.e. without parameters) will always output a different result. How it differs doesn't matter, even if at least one of a million calls returns something different, this function is deemed non-deterministic. +No matter how many times we call this function with the argument `'hexlet'`, it will always return `6`. + +## Non-deterministic functions + +The opposite type is **non-deterministic functions**. They can return different results for the same input data or in its absence (functions without parameters). A good example is a function that returns a random number: ```javascript -// A function that returns a random number Math.random(); // 0.09856613113197676 Math.random(); // 0.8839904367241888 ``` -So what use is knowing that to us? Determinism seriously affects many different aspects. Deterministic functions are easy to work with, easy to optimize, and easy to test. If you can make a function deterministic, it's best to make it one. +This function has no arguments, but the result is different every time. If even one call out of a million produces a different result, the function is considered non-deterministic. + +```text +Deterministic: Non-deterministic: +length('abc') → always 3 Math.random() → 0.42 +length('abc') → always 3 Math.random() → 0.91 +length('abc') → always 3 Math.random() → 0.07 +``` + +## Why this matters + +Determinism affects how we work with functions: + +- deterministic functions are easy to test and predict; +- they are easier to optimize and reuse; +- non-deterministic functions are harder to verify because the result changes. + +That is why, where possible, it is better to strive to make a function deterministic. diff --git a/modules/35-calling-functions/270-deterministic/en/data.yml b/modules/35-calling-functions/270-deterministic/en/data.yml index e40a55b6..b253aeae 100644 --- a/modules/35-calling-functions/270-deterministic/en/data.yml +++ b/modules/35-calling-functions/270-deterministic/en/data.yml @@ -1,6 +1,10 @@ --- -name: Determinacy +name: Determinism tips: - - > - [Deterministic - algorithm](https://en.wikipedia.org/wiki/Deterministic_algorithm) + - | + [Deterministic functions](https://en.wikipedia.org/wiki/Pure_function#Determinism) +definitions: + - name: Side effect + description: >- + an action that changes the external environment (the execution + environment). For example, printing to the screen or sending an email. diff --git a/modules/35-calling-functions/270-deterministic/es/EXERCISE.md b/modules/35-calling-functions/270-deterministic/es/EXERCISE.md index af2de333..af0cd9fb 100644 --- a/modules/35-calling-functions/270-deterministic/es/EXERCISE.md +++ b/modules/35-calling-functions/270-deterministic/es/EXERCISE.md @@ -1,8 +1,3 @@ +Genera un número entero aleatorio de 0 a 10 (inclusive) e imprímelo en la pantalla. -La función `Math.random()` devuelve un número aleatorio entre 0 y 1 con varios dígitos decimales. Pero para atender problemas reales, a veces necesitamos obtener números enteros aleatorios, por ejemplo, en el rango de 0 a 10. Implementa el código que imprime precisamente esos números en la pantalla. Para este problema, necesitarás las funciones [Math.random()](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math/random) y [Math.round()](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math/round). - -Intenta resolver este ejercicio en una sola línea. - -## Algoritmo - -Dado que `Math.random()` devuelve números en el rango de 0 a 1, para obtener números en el rango de 0 a 10, debemos multiplicar por 10. Luego, el número resultante se redondea y así obtenemos lo que necesitamos. +Usa `Math.random()` (devuelve un número de 0 a 1) y `Math.round()` (redondea a un entero). diff --git a/modules/35-calling-functions/270-deterministic/es/README.md b/modules/35-calling-functions/270-deterministic/es/README.md index 15d6cc0e..3f2a2e72 100644 --- a/modules/35-calling-functions/270-deterministic/es/README.md +++ b/modules/35-calling-functions/270-deterministic/es/README.md @@ -1,5 +1,6 @@ +Las funciones en cualquier lenguaje de programación tienen propiedades fundamentales. Nos ayudan a entender cómo se comportará una función en diferentes situaciones, cómo probarla y dónde aplicarla. Una de esas propiedades es el **determinismo**. -Independientemente del lenguaje de programación utilizado, las funciones dentro de él tienen algunas propiedades fundamentales. Conocer estas propiedades facilita predecir el comportamiento de las funciones, las formas de probarlas y el lugar donde se utilizan. Una de estas propiedades es el determinismo. Una función se considera determinista cuando devuelve el mismo resultado para los mismos parámetros de entrada. Por ejemplo, la función que cuenta la cantidad de caracteres es determinista: +Una **función determinista** siempre devuelve el mismo resultado para los mismos datos de entrada. Por ejemplo, se puede llamar determinista a una función que cuenta la cantidad de caracteres: ```javascript import { length } from 'hexlet-basics/string'; @@ -11,12 +12,32 @@ length('wow'); // 3 length('wow'); // 3 ``` -No importa cuántas veces llamemos a esta función pasando el valor `'hexlet'`, siempre devolverá `6`. Por otro lado, una función que devuelve un número aleatorio no es determinista, ya que para una misma entrada (incluso si está vacía, es decir, no se aceptan parámetros) siempre obtendremos un resultado diferente. No importa cuán diferente sea, incluso si una de cada millón de llamadas devuelve algo diferente, esta función se considera automáticamente no determinista. +No importa cuántas veces llamemos a esta función con el argumento `'hexlet'`, siempre devolverá `6`. + +## Funciones no deterministas + +El tipo opuesto son las **funciones no deterministas**. Pueden devolver resultados diferentes para los mismos datos de entrada o en ausencia de ellos (funciones sin parámetros). Un buen ejemplo es una función que devuelve un número aleatorio: ```javascript -// Función que devuelve un número aleatorio Math.random(); // 0.09856613113197676 Math.random(); // 0.8839904367241888 ``` -¿Por qué es importante saber esto? El determinismo afecta seriamente muchos aspectos. Las funciones deterministas son convenientes para trabajar, son fáciles de optimizar y de probar. Si es posible hacer que una función sea determinista, es mejor hacerlo así. +Esta función no tiene argumentos, pero el resultado es diferente cada vez. Si aunque sea una llamada de un millón produce un resultado diferente, la función se considera no determinista. + +```text +Determinista: No determinista: +length('abc') → siempre 3 Math.random() → 0.42 +length('abc') → siempre 3 Math.random() → 0.91 +length('abc') → siempre 3 Math.random() → 0.07 +``` + +## Por qué esto importa + +El determinismo afecta cómo trabajamos con las funciones: + +- las funciones deterministas son fáciles de probar y predecir; +- son más fáciles de optimizar y reutilizar; +- las funciones no deterministas son más difíciles de verificar porque el resultado cambia. + +Por eso, siempre que sea posible, es mejor procurar que una función sea determinista. diff --git a/modules/35-calling-functions/270-deterministic/es/data.yml b/modules/35-calling-functions/270-deterministic/es/data.yml index ca047c02..1b6b89f5 100644 --- a/modules/35-calling-functions/270-deterministic/es/data.yml +++ b/modules/35-calling-functions/270-deterministic/es/data.yml @@ -1,9 +1,8 @@ --- name: Determinismo tips: - - > - [Funciones - deterministas](https://es.wikipedia.org/wiki/Funci%C3%B3n_determinista) + - | + [Funciones deterministas](https://es.wikipedia.org/wiki/Pureza_de_funciones#Determinismo_de_la_funci%C3%B3n) definitions: - name: Efecto secundario description: >- diff --git a/modules/40-define-functions/150-return/test.js b/modules/40-define-functions/150-return/test.js index 0adcef8a..b0d1c54b 100644 --- a/modules/40-define-functions/150-return/test.js +++ b/modules/40-define-functions/150-return/test.js @@ -4,6 +4,6 @@ import { expect, test } from 'vitest'; import f from './index.js'; test('test', () => { - expect(f('текст', 3)).toBe('тек...'); - expect(f('и пошла вода', 5)).toBe('и пош...'); + expect(f('text', 3)).toBe('tex...'); + expect(f('hexlet learning', 6)).toBe('hexlet...'); }); diff --git a/modules/40-define-functions/350-type-annotations/test.js b/modules/40-define-functions/350-type-annotations/test.js index a6f8056d..40a2e69d 100644 --- a/modules/40-define-functions/350-type-annotations/test.js +++ b/modules/40-define-functions/350-type-annotations/test.js @@ -1,4 +1,4 @@ -// @ts-nocheck — в tsconfig нет типов Node.js (types: []), а тест читает исходник через node:fs +// @ts-nocheck -- tsconfig has no Node.js types (types: []), and the test reads the source via node:fs import { readFileSync } from 'node:fs'; import { expect, test } from 'vitest'; @@ -9,11 +9,11 @@ test('test', () => { const paramAnnotations = source.match(/@param\s*\{/g) ?? []; expect( paramAnnotations.length, - 'Укажите JSDoc-аннотации @param для обоих параметров', + 'Add JSDoc @param annotations for both parameters', ).toBeGreaterThanOrEqual(2); expect( source, - 'Укажите JSDoc-аннотацию @returns для возвращаемого значения', + 'Add a JSDoc @returns annotation for the return value', ).toMatch(/@returns\s*\{/); expect(f('javascript', 1)).toBe('javascript'); diff --git a/modules/45-logic/10-bool-type/description.es.yml b/modules/45-logic/10-bool-type/description.es.yml index 231b9273..878a22e0 100644 --- a/modules/45-logic/10-bool-type/description.es.yml +++ b/modules/45-logic/10-bool-type/description.es.yml @@ -2,78 +2,81 @@ name: Tipo lógico theory: | + Además de las operaciones aritméticas, en matemáticas existen las operaciones de comparación, por ejemplo `5 > 4` o `3 < 1`. También existen en programación. Las comparaciones se usan con frecuencia en tareas del mundo real. Por ejemplo, cuando realizamos una compra en una tienda en línea, el sistema verifica si el usuario tiene suficiente dinero en su cuenta: si el monto en la cuenta es mayor o igual que el precio del producto, el pedido se confirma; de lo contrario, aparece un mensaje de fondos insuficientes. - Además de las operaciones aritméticas que conocemos desde la escuela, también existen las operaciones de comparación. Por ejemplo, `5 > 4`. Esto se lee como una pregunta: "¿Es 5 mayor que 4?". En este caso, la respuesta es "sí". En otros casos, la respuesta puede ser "no", por ejemplo, para `3 < 1`. + ## Comparación en programación - Las operaciones de comparación no están limitadas a números. Podemos comparar prácticamente cualquier cosa, como cadenas de texto. Cada vez que ingresamos a un sitio web, se realiza una comparación entre el nombre de usuario y la contraseña ingresados y los que están en la base de datos. Sólo si coinciden, se nos permite ingresar (autenticarnos). + Empecemos con un ejemplo en el que se comparan dos números: - Los lenguajes de programación han adaptado todas las operaciones matemáticas de comparación prácticamente sin cambios. La única diferencia importante son los operadores de igualdad y desigualdad. En matemáticas, se utiliza el signo de igual `=`, pero en programación esto no se ve muy a menudo. En muchos lenguajes, el símbolo `=` se utiliza para asignar valores a variables, por lo que para las comparaciones se utilizan `==` o `===`. - - Aquí tienes una lista de las operaciones de comparación en JavaScript: - - * `<` menor que - * `<=` menor o igual que - * `>` mayor que - * `>=` mayor o igual que - * `===` igual que - * `!==` no igual que - - _Un pequeño comentario: también existen los operadores `==` y `!=` para igualdad y desigualdad, pero no los utilizaremos, debido al riesgo potencial. Hablaremos de esto en futuras lecciones._ + ```javascript + console.log(5 > 4); // => true + console.log(4 > 4); // => false + ``` - Una operación lógica como `5 > 4` o `password === text` es una expresión y su resultado es un valor especial: `true` (verdadero) o `false` (falso). Este es un nuevo tipo de dato para nosotros: booleano. Solo puede tener uno de estos dos valores. + El resultado de una comparación es un valor del tipo **boolean** (tipo lógico). Tiene solo dos valores posibles: `true` (verdadero) y `false` (falso). Son valores especiales del lenguaje y se pueden usar directamente: ```javascript - const result = 5 > 4; - console.log(result); // => true - console.log('one' !== 'one'); // => false + console.log(true); + console.log(false); ``` - Junto con las cadenas de texto (string), los números enteros y racionales (number), el tipo lógico (boolean) es uno de los tipos de datos primitivos en JavaScript. + En la práctica, rara vez se usan de esta forma, pero sobre ellos se construye toda la lógica del comportamiento del programa. Nos encontramos con esto cada día: ingresamos códigos PIN y contraseñas, ejecutamos acciones cuyo resultado puede ser distinto. El programa razona más o menos así: *si es así — haz una cosa, si es de otro modo — haz otra*. + + En JavaScript están disponibles las siguientes operaciones de comparación: - --- + | Operador | Significado | + |----------|-------------| + | `<` | menor que | + | `<=` | menor o igual que | + | `>` | mayor que | + | `>=` | mayor o igual que | + | `===` | estrictamente igual | + | `!==` | estrictamente distinto | - Intentemos escribir una función simple que tome la edad de un niño y determine si es un bebé. Consideramos bebés a los niños menores de un año: + Los lenguajes de programación adoptaron las operaciones matemáticas de comparación casi sin cambios, excepto la igualdad y la desigualdad. En matemáticas se usa el `=` habitual, pero en programación el símbolo `=` ya está ocupado: asigna valores a las variables. Por eso, para la comparación de igualdad JavaScript usa `===` y para la desigualdad `!==` (el triple y el del signo de exclamación son la comparación "estricta", a la que volveremos más adelante). ```javascript - const isInfant = (age) => age < 1; + console.log(5 >= 3); // => true + console.log(7 < 0); // => false + console.log(5 > 5); // => false + console.log(5 >= 5); // => true + console.log(2 === 5); // => false + console.log(2 !== 5); // => true ``` - Aprovechamos el hecho de que cualquier operación es una expresión, por lo que en una sola línea de la función escribimos "devolver el resultado de la comparación `edad < 1`". - - Dependiendo del argumento que se pase, la comparación será verdadera (`true`) o falsa (`false`), y `return` devolverá ese resultado. + Cuando en una comparación se usan valores concretos, la operación parece carecer de sentido: el resultado ya se conoce y siempre es el mismo. Pero todo cambia cuando los valores pueden ser distintos. Escribamos una función simple que reciba la edad de un niño y determine si es un bebé. Se consideran bebés a los niños menores de dos años (dos no se incluye): ```javascript - const isInfant = (age) => age < 1; + const isInfant = (age) => age < 2; - console.log(isInfant(3)); + console.log(isInfant(3)); // => false + console.log(isInfant(2)); // => false + console.log(isInfant(1)); // => true + console.log(isInfant(0)); // => true ``` - ```textfalse``` + ## Predicados - - Ahora probemos con un niño de seis meses: + Cuando las funciones devuelven el resultado de una comparación, suelen responder a la pregunta "sí" o "no". Tales funciones se llaman **predicados**. Son fáciles de reconocer: devuelven un valor lógico `true` o `false`, y su nombre a menudo contiene la afirmación que se comprueba (`is`, `has`, `can`). Aquí tienes una función que comprueba si un número es negativo: ```javascript - console.log(isInfant(0.5)); - ``` + const isNegative = (number) => number < 0; - ```texttrue``` + console.log(isNegative(-5)); // => true + console.log(isNegative(7)); // => false + ``` + Los nombres de los predicados se construyen de modo que la pregunta se lea directamente a partir del nombre: `hasChildren()` — "¿hay hijos?", `isEmpty()` — "¿la cadena está vacía?", `hasErrors()` — "¿hay errores?". Al mismo tiempo, se considera predicado solo a una función que devuelve precisamente un valor lógico, sin excepciones. instructions: | - - Escribe una función llamada `isPensioner()` que reciba un parámetro, la edad de una persona, y determine si es jubilada. Se considera jubilada a una persona que tiene 60 años o más. - - Ejemplos de uso: + Escribe una función `isPensioner(age)` que devuelva `true` si la edad `age` es 60 o mayor, y `false` en caso contrario. ```javascript - isPensioner(75); // true - isPensioner(18); // false + isPensioner(65); // => true + isPensioner(30); // => false ``` - tips: - | [Boolean en JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Boolean) - definitions: - - name: "Tipo lógico (booleano)" - description: "un tipo de dato con dos posibles valores: true (verdadero) y false (falso)." + - name: Tipo lógico (booleano) + description: 'un tipo de dato con dos posibles valores: true (verdadero) y false (falso).' diff --git a/modules/45-logic/10-bool-type/en/EXERCISE.md b/modules/45-logic/10-bool-type/en/EXERCISE.md index 8e427596..39761919 100644 --- a/modules/45-logic/10-bool-type/en/EXERCISE.md +++ b/modules/45-logic/10-bool-type/en/EXERCISE.md @@ -1,9 +1,6 @@ - -Write a function, `isPensioner()`, which takes one parameter (a person's age), and check whether that person is retired or not. A pensioner is a person who has reached the age of 60 or higher. - -Examples: +Write a function `isPensioner(age)` that returns `true` if the age `age` is 60 or greater, and `false` otherwise. ```javascript -isPensioner(75); // true -isPensioner(18); // false +isPensioner(65); // => true +isPensioner(30); // => false ``` diff --git a/modules/45-logic/10-bool-type/en/README.md b/modules/45-logic/10-bool-type/en/README.md index c226969c..efa36136 100644 --- a/modules/45-logic/10-bool-type/en/README.md +++ b/modules/45-logic/10-bool-type/en/README.md @@ -1,55 +1,65 @@ +In addition to arithmetic operations, mathematics has comparison operations, for example `5 > 4` or `3 < 1`. They exist in programming too. Comparisons are often used in real-world tasks. For example, when we place an order in an online store, the system checks whether the user has enough money in their account: if the amount in the account is greater than or equal to the price of the item, the order is confirmed, otherwise a message about insufficient funds appears. -As well as arithmetic operators, we also know comparison operators from school. For example, `5 > 4`. It sounds like a question, "Is 5 greater than 4?" The answer is "yes". In other cases, the answer may be "no", say, for `3 < 1`. +## Comparison in programming -Comparison operators aren't restricted to numbers. You can put them in almost anything, e.g., strings. Every time we visit a website, it compares the username and password we've entered with those in the database. If they exist, we are let in (authorized). +Let's start with an example that compares two numbers: -Programming languages have borrowed all the comparison operators from math virtually unchanged. The only major change concerns the equality and inequality operators. In math, the usual equal sign is `=`, which is rare in programming. In many languages, the symbol `=` is used to assign values to variables, so you need to use `==` or `===` for comparison. - -List of comparison operators in JavaScript: - -* `<` less than -* `<=` less than or equal to -* `>` greater than -* `>=` greater than or equal to -* `===` equal to -* `!==` not equal to - -_A tiny note: for equality and inequality, there are also `==` and `!=`, neither of which we'll use because of the possible risks. We'll discuss it later._ +```javascript +console.log(5 > 4); // => true +console.log(4 > 4); // => false +``` -A logical operation like `5 > 4` or `password === text` is an expression resulting in a special value, `true` or `false`. This is a new data type for us, which is called boolean. It has only these two values. +The result of a comparison is a value of the **boolean** type. It has only two possible values: `true` and `false`. These are special language values, and they can be used directly: ```javascript -const result = 5 > 4; -console.log(result); // => true -console.log('one' !== 'one'); // => false +console.log(true); +console.log(false); ``` -Along with strings and integers with rationals (which are numbers), the logical type (boolean) is one of JavaScript's primitive data types. +In practice, they are rarely used this way, but the entire logic of a program's behavior is built on them. We encounter this every day: we enter PIN codes and passwords, perform actions whose results may differ. The program reasons roughly like this: *if this — do one thing, if otherwise — do another*. + +JavaScript provides the following comparison operations: ---- +| Operator | Meaning | +|----------|---------| +| `<` | less than | +| `<=` | less than or equal to | +| `>` | greater than | +| `>=` | greater than or equal to | +| `===` | strictly equal | +| `!==` | strictly not equal | -Try to write a primitive function that takes a child's age as an input and decides whether they are an infant or not. Infants are defined as children under a year old: +Programming languages adopted mathematical comparison operations almost without changes, except for equality and inequality. In mathematics, the ordinary `=` is used, but in programming the `=` symbol is already taken — it assigns values to variables. That is why JavaScript uses `===` for equality comparison and `!==` for inequality (the triple one and the one with the exclamation mark are "strict" comparison, which we will come back to). ```javascript -const isInfant = (age) => age < 1; +console.log(5 >= 3); // => true +console.log(7 < 0); // => false +console.log(5 > 5); // => false +console.log(5 >= 5); // => true +console.log(2 === 5); // => false +console.log(2 !== 5); // => true ``` -We can take advantage of the fact that any operation is an expression, so the only line we need to write here is "return the value that results from `age < 1`". - -Depending on the input, the comparison will either be true or false, and `return` will return that result. +When specific values are used in a comparison, the operation seems pointless: the result is already known and is always the same. But everything changes when the values can be different. Let's write a simple function that takes a child's age and determines whether they are an infant. Children under two years old are considered infants (two is not included): ```javascript -const isInfant = (age) => age < 1; +const isInfant = (age) => age < 2; -console.log(isInfant(3)); +console.log(isInfant(3)); // => false +console.log(isInfant(2)); // => false +console.log(isInfant(1)); // => true +console.log(isInfant(0)); // => true ``` -```textfalse``` +## Predicates -Now, perform the check on a child who is six months old: +When functions return the result of a comparison, they usually answer the question "yes" or "no". Such functions are called **predicates**. They are easy to recognize: they return a logical value `true` or `false`, and their name often contains the statement being checked (`is`, `has`, `can`). Here is a function that checks whether a number is negative: ```javascript -console.log(isInfant(0.5)); +const isNegative = (number) => number < 0; + +console.log(isNegative(-5)); // => true +console.log(isNegative(7)); // => false ``` -```texttrue``` +Predicate names are built so that the question can be read directly from the name: `hasChildren()` — "are there any children?", `isEmpty()` — "is the string empty?", `hasErrors()` — "are there any errors?". At the same time, only a function that returns exactly a logical value is considered a predicate — without exceptions. diff --git a/modules/45-logic/10-bool-type/en/data.yml b/modules/45-logic/10-bool-type/en/data.yml index 238ce817..4bd8fbf8 100644 --- a/modules/45-logic/10-bool-type/en/data.yml +++ b/modules/45-logic/10-bool-type/en/data.yml @@ -1,5 +1,8 @@ --- name: Boolean type +tips: + - | + [Boolean in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean) definitions: - - name: Logical type (boolean) + - name: Boolean type description: 'a data type with two possible values: true and false.' diff --git a/modules/45-logic/10-bool-type/es/EXERCISE.md b/modules/45-logic/10-bool-type/es/EXERCISE.md index 0cd15a63..5936b597 100644 --- a/modules/45-logic/10-bool-type/es/EXERCISE.md +++ b/modules/45-logic/10-bool-type/es/EXERCISE.md @@ -1,9 +1,6 @@ - -Escribe una función llamada `isPensioner()` que reciba un parámetro, la edad de una persona, y determine si es jubilada. Se considera jubilada a una persona que tiene 60 años o más. - -Ejemplos de uso: +Escribe una función `isPensioner(age)` que devuelva `true` si la edad `age` es 60 o mayor, y `false` en caso contrario. ```javascript -isPensioner(75); // true -isPensioner(18); // false +isPensioner(65); // => true +isPensioner(30); // => false ``` diff --git a/modules/45-logic/10-bool-type/es/README.md b/modules/45-logic/10-bool-type/es/README.md index a2a97856..ed607378 100644 --- a/modules/45-logic/10-bool-type/es/README.md +++ b/modules/45-logic/10-bool-type/es/README.md @@ -1,55 +1,65 @@ +Además de las operaciones aritméticas, en matemáticas existen las operaciones de comparación, por ejemplo `5 > 4` o `3 < 1`. También existen en programación. Las comparaciones se usan con frecuencia en tareas del mundo real. Por ejemplo, cuando realizamos una compra en una tienda en línea, el sistema verifica si el usuario tiene suficiente dinero en su cuenta: si el monto en la cuenta es mayor o igual que el precio del producto, el pedido se confirma; de lo contrario, aparece un mensaje de fondos insuficientes. -Además de las operaciones aritméticas que conocemos desde la escuela, también existen las operaciones de comparación. Por ejemplo, `5 > 4`. Esto se lee como una pregunta: "¿Es 5 mayor que 4?". En este caso, la respuesta es "sí". En otros casos, la respuesta puede ser "no", por ejemplo, para `3 < 1`. +## Comparación en programación -Las operaciones de comparación no están limitadas a números. Podemos comparar prácticamente cualquier cosa, como cadenas de texto. Cada vez que ingresamos a un sitio web, se realiza una comparación entre el nombre de usuario y la contraseña ingresados y los que están en la base de datos. Sólo si coinciden, se nos permite ingresar (autenticarnos). +Empecemos con un ejemplo en el que se comparan dos números: -Los lenguajes de programación han adaptado todas las operaciones matemáticas de comparación prácticamente sin cambios. La única diferencia importante son los operadores de igualdad y desigualdad. En matemáticas, se utiliza el signo de igual `=`, pero en programación esto no se ve muy a menudo. En muchos lenguajes, el símbolo `=` se utiliza para asignar valores a variables, por lo que para las comparaciones se utilizan `==` o `===`. - -Aquí tienes una lista de las operaciones de comparación en JavaScript: - -* `<` menor que -* `<=` menor o igual que -* `>` mayor que -* `>=` mayor o igual que -* `===` igual que -* `!==` no igual que - -_Un pequeño comentario: también existen los operadores `==` y `!=` para igualdad y desigualdad, pero no los utilizaremos, debido al riesgo potencial. Hablaremos de esto en futuras lecciones._ +```javascript +console.log(5 > 4); // => true +console.log(4 > 4); // => false +``` -Una operación lógica como `5 > 4` o `password === text` es una expresión y su resultado es un valor especial: `true` (verdadero) o `false` (falso). Este es un nuevo tipo de dato para nosotros: booleano. Solo puede tener uno de estos dos valores. +El resultado de una comparación es un valor del tipo **boolean** (tipo lógico). Tiene solo dos valores posibles: `true` (verdadero) y `false` (falso). Son valores especiales del lenguaje y se pueden usar directamente: ```javascript -const result = 5 > 4; -console.log(result); // => true -console.log('one' !== 'one'); // => false +console.log(true); +console.log(false); ``` -Junto con las cadenas de texto (string), los números enteros y racionales (number), el tipo lógico (boolean) es uno de los tipos de datos primitivos en JavaScript. +En la práctica, rara vez se usan de esta forma, pero sobre ellos se construye toda la lógica del comportamiento del programa. Nos encontramos con esto cada día: ingresamos códigos PIN y contraseñas, ejecutamos acciones cuyo resultado puede ser distinto. El programa razona más o menos así: *si es así — haz una cosa, si es de otro modo — haz otra*. + +En JavaScript están disponibles las siguientes operaciones de comparación: ---- +| Operador | Significado | +|----------|-------------| +| `<` | menor que | +| `<=` | menor o igual que | +| `>` | mayor que | +| `>=` | mayor o igual que | +| `===` | estrictamente igual | +| `!==` | estrictamente distinto | -Intentemos escribir una función simple que tome la edad de un niño y determine si es un bebé. Consideramos bebés a los niños menores de un año: +Los lenguajes de programación adoptaron las operaciones matemáticas de comparación casi sin cambios, excepto la igualdad y la desigualdad. En matemáticas se usa el `=` habitual, pero en programación el símbolo `=` ya está ocupado: asigna valores a las variables. Por eso, para la comparación de igualdad JavaScript usa `===` y para la desigualdad `!==` (el triple y el del signo de exclamación son la comparación "estricta", a la que volveremos más adelante). ```javascript -const isInfant = (age) => age < 1; +console.log(5 >= 3); // => true +console.log(7 < 0); // => false +console.log(5 > 5); // => false +console.log(5 >= 5); // => true +console.log(2 === 5); // => false +console.log(2 !== 5); // => true ``` -Aprovechamos el hecho de que cualquier operación es una expresión, por lo que en una sola línea de la función escribimos "devolver el resultado de la comparación `edad < 1`". - -Dependiendo del argumento que se pase, la comparación será verdadera (`true`) o falsa (`false`), y `return` devolverá ese resultado. +Cuando en una comparación se usan valores concretos, la operación parece carecer de sentido: el resultado ya se conoce y siempre es el mismo. Pero todo cambia cuando los valores pueden ser distintos. Escribamos una función simple que reciba la edad de un niño y determine si es un bebé. Se consideran bebés a los niños menores de dos años (dos no se incluye): ```javascript -const isInfant = (age) => age < 1; +const isInfant = (age) => age < 2; -console.log(isInfant(3)); +console.log(isInfant(3)); // => false +console.log(isInfant(2)); // => false +console.log(isInfant(1)); // => true +console.log(isInfant(0)); // => true ``` -```textfalse``` +## Predicados -Ahora probemos con un niño de seis meses: +Cuando las funciones devuelven el resultado de una comparación, suelen responder a la pregunta "sí" o "no". Tales funciones se llaman **predicados**. Son fáciles de reconocer: devuelven un valor lógico `true` o `false`, y su nombre a menudo contiene la afirmación que se comprueba (`is`, `has`, `can`). Aquí tienes una función que comprueba si un número es negativo: ```javascript -console.log(isInfant(0.5)); +const isNegative = (number) => number < 0; + +console.log(isNegative(-5)); // => true +console.log(isNegative(7)); // => false ``` -```texttrue``` +Los nombres de los predicados se construyen de modo que la pregunta se lea directamente a partir del nombre: `hasChildren()` — "¿hay hijos?", `isEmpty()` — "¿la cadena está vacía?", `hasErrors()` — "¿hay errores?". Al mismo tiempo, se considera predicado solo a una función que devuelve precisamente un valor lógico, sin excepciones. diff --git a/modules/45-logic/10-bool-type/es/data.yml b/modules/45-logic/10-bool-type/es/data.yml index f2c6a0d9..af115ea1 100644 --- a/modules/45-logic/10-bool-type/es/data.yml +++ b/modules/45-logic/10-bool-type/es/data.yml @@ -1,11 +1,8 @@ --- name: Tipo lógico tips: - - > - [Boolean en - JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Boolean) + - | + [Boolean en JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Boolean) definitions: - name: Tipo lógico (booleano) - description: >- - un tipo de dato con dos posibles valores: true (verdadero) y false - (falso). + description: 'un tipo de dato con dos posibles valores: true (verdadero) y false (falso).' diff --git a/modules/45-logic/17-bool-strings/description.es.yml b/modules/45-logic/17-bool-strings/description.es.yml new file mode 100644 index 00000000..32c67b22 --- /dev/null +++ b/modules/45-logic/17-bool-strings/description.es.yml @@ -0,0 +1,80 @@ +--- + +name: Comparación de cadenas +theory: | + + Las operaciones de comparación funcionan no solo con números, sino también con cadenas. En JavaScript, las cadenas se comparan lexicográficamente: carácter por carácter de izquierda a derecha según los códigos numéricos de los caracteres (Unicode). + + ```javascript + console.log('apple' < 'banana'); // => true + console.log('cat' > 'dog'); // => false + console.log('abc' === 'abc'); // => true + console.log('hello' !== 'world'); // => true + ``` + + Aquí `'apple' < 'banana'`, porque el código del carácter `a` (97) es menor que el código de `b` (98), y es el primer carácter diferente el que decide el resultado de la comparación. Puedes averiguar el código de un carácter con el método `charCodeAt()`: + + ```javascript + console.log('a'.charCodeAt(0)); // => 97 + console.log('b'.charCodeAt(0)); // => 98 + ``` + + La comparación distingue entre mayúsculas y minúsculas: el código de `'Z'` (90) es menor que el código de `'a'` (97). Aquí hay algunos ejemplos donde las primeras letras están en distinto caso: + + ```javascript + console.log('Zebra' < 'apple'); // => true — 'Z'(90) < 'a'(97) + console.log('apple' < 'Banana'); // => false — 'a'(97) > 'B'(66) + console.log('Apple' < 'apple'); // => true — 'A'(65) < 'a'(97) + ``` + + Escribamos una función que verifique si una palabra comienza con una letra dada. Para ello, tomamos el primer carácter de la cadena y lo comparamos con la letra requerida: + + ```javascript + const startsWithLetter = (word, letter) => word[0] === letter; + + console.log(startsWithLetter('apple', 'a')); // => true + console.log(startsWithLetter('banana', 'a')); // => false + ``` + + Las operaciones de comparación son expresiones igual que las aritméticas. En ellas puedes sustituir valores ya preparados y otras expresiones, por ejemplo `word[0]` más arriba. También puedes usar la propiedad `.length`: + + ```javascript + console.log('apple'.length > 3); // => true, porque la longitud es 5 + console.log('hi'.length > 3); // => false, porque la longitud es 2 + ``` + + Primero se evalúa `'apple'.length` (que da el número `5`), y luego ese número se compara con `3`. Es decir, primero se calculan los operandos de la expresión y después se realiza la comparación. + + ## Predicados útiles + + Las cadenas en JavaScript tienen métodos predicados incorporados. Devuelven `true` o `false` y ayudan a verificar distintas propiedades de una cadena: + + ```javascript + console.log('hello'.startsWith('he')); // => true — la cadena comienza con 'he' + console.log('hello'.endsWith('lo')); // => true — la cadena termina con 'lo' + console.log('hello'.includes('ell')); // => true — la cadena contiene 'ell' + ``` + + Estos métodos permiten verificar cadenas contra las condiciones requeridas directamente en el código, sin escribir funciones adicionales. + +instructions: | + + Durante el registro en un sitio web, el programa verifica que la contraseña sea lo suficientemente larga — más de 5 caracteres. Escribe una función `isLongWord()` que devuelva `true` si la longitud de la palabra pasada es mayor a 5 caracteres, y `false` en caso contrario. + + Ejemplo de uso: + + ```javascript + isLongWord('apple'); // => false + isLongWord('banana'); // => true + ``` + +tips: + - > + [Comparación de cadenas en + JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Less_than) + +definitions: + - name: Comparación lexicográfica + description: >- + comparación de cadenas carácter por carácter de izquierda a derecha según + los códigos numéricos de los caracteres (Unicode). diff --git a/modules/45-logic/17-bool-strings/en/EXERCISE.md b/modules/45-logic/17-bool-strings/en/EXERCISE.md new file mode 100644 index 00000000..86ebce33 --- /dev/null +++ b/modules/45-logic/17-bool-strings/en/EXERCISE.md @@ -0,0 +1,8 @@ +During registration on a website, the program checks that the password is long enough — more than 5 characters. Write a function `isLongWord()` that returns `true` if the length of the passed word is more than 5 characters, and `false` otherwise. + +Example usage: + +```javascript +isLongWord('apple'); // => false +isLongWord('banana'); // => true +``` diff --git a/modules/45-logic/17-bool-strings/en/README.md b/modules/45-logic/17-bool-strings/en/README.md new file mode 100644 index 00000000..4d2c4ea7 --- /dev/null +++ b/modules/45-logic/17-bool-strings/en/README.md @@ -0,0 +1,53 @@ +Comparison operations work not only with numbers but also with strings. In JavaScript, strings are compared lexicographically: character by character from left to right by the numeric codes of the characters (Unicode). + +```javascript +console.log('apple' < 'banana'); // => true +console.log('cat' > 'dog'); // => false +console.log('abc' === 'abc'); // => true +console.log('hello' !== 'world'); // => true +``` + +Here `'apple' < 'banana'`, because the code of the character `a` (97) is less than the code of `b` (98), and it is the first differing character that decides the outcome of the comparison. You can find out the code of a character with the `charCodeAt()` method: + +```javascript +console.log('a'.charCodeAt(0)); // => 97 +console.log('b'.charCodeAt(0)); // => 98 +``` + +The comparison is case-sensitive: the code of `'Z'` (90) is less than the code of `'a'` (97). Here are a few examples where the first letters are in different cases: + +```javascript +console.log('Zebra' < 'apple'); // => true — 'Z'(90) < 'a'(97) +console.log('apple' < 'Banana'); // => false — 'a'(97) > 'B'(66) +console.log('Apple' < 'apple'); // => true — 'A'(65) < 'a'(97) +``` + +Let's write a function that checks whether a word starts with a given letter. To do this, we take the first character of the string and compare it with the required letter: + +```javascript +const startsWithLetter = (word, letter) => word[0] === letter; + +console.log(startsWithLetter('apple', 'a')); // => true +console.log(startsWithLetter('banana', 'a')); // => false +``` + +Comparison operations are expressions just like arithmetic ones. You can substitute ready-made values and other expressions into them, for example `word[0]` above. You can also use the `.length` property: + +```javascript +console.log('apple'.length > 3); // => true, because the length is 5 +console.log('hi'.length > 3); // => false, because the length is 2 +``` + +First `'apple'.length` is evaluated (resulting in the number `5`), and then this number is compared with `3`. That is, the operands of the expression are computed first, and then the comparison is performed. + +## Useful predicates + +Strings in JavaScript have built-in predicate methods. They return `true` or `false` and help check various properties of a string: + +```javascript +console.log('hello'.startsWith('he')); // => true — the string starts with 'he' +console.log('hello'.endsWith('lo')); // => true — the string ends with 'lo' +console.log('hello'.includes('ell')); // => true — the string contains 'ell' +``` + +Such methods let you check strings against the required conditions right in the code, without writing additional functions. diff --git a/modules/45-logic/17-bool-strings/en/data.yml b/modules/45-logic/17-bool-strings/en/data.yml new file mode 100644 index 00000000..a9a2355f --- /dev/null +++ b/modules/45-logic/17-bool-strings/en/data.yml @@ -0,0 +1,11 @@ +--- +name: String comparison +tips: + - > + [String comparison in + JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than) +definitions: + - name: Lexicographic comparison + description: >- + comparing strings character by character from left to right by the + numeric codes of the characters (Unicode). diff --git a/modules/45-logic/17-bool-strings/es/EXERCISE.md b/modules/45-logic/17-bool-strings/es/EXERCISE.md new file mode 100644 index 00000000..d9b6f405 --- /dev/null +++ b/modules/45-logic/17-bool-strings/es/EXERCISE.md @@ -0,0 +1,8 @@ +Durante el registro en un sitio web, el programa verifica que la contraseña sea lo suficientemente larga — más de 5 caracteres. Escribe una función `isLongWord()` que devuelva `true` si la longitud de la palabra pasada es mayor a 5 caracteres, y `false` en caso contrario. + +Ejemplo de uso: + +```javascript +isLongWord('apple'); // => false +isLongWord('banana'); // => true +``` diff --git a/modules/45-logic/17-bool-strings/es/README.md b/modules/45-logic/17-bool-strings/es/README.md new file mode 100644 index 00000000..beed94c7 --- /dev/null +++ b/modules/45-logic/17-bool-strings/es/README.md @@ -0,0 +1,53 @@ +Las operaciones de comparación funcionan no solo con números, sino también con cadenas. En JavaScript, las cadenas se comparan lexicográficamente: carácter por carácter de izquierda a derecha según los códigos numéricos de los caracteres (Unicode). + +```javascript +console.log('apple' < 'banana'); // => true +console.log('cat' > 'dog'); // => false +console.log('abc' === 'abc'); // => true +console.log('hello' !== 'world'); // => true +``` + +Aquí `'apple' < 'banana'`, porque el código del carácter `a` (97) es menor que el código de `b` (98), y es el primer carácter diferente el que decide el resultado de la comparación. Puedes averiguar el código de un carácter con el método `charCodeAt()`: + +```javascript +console.log('a'.charCodeAt(0)); // => 97 +console.log('b'.charCodeAt(0)); // => 98 +``` + +La comparación distingue entre mayúsculas y minúsculas: el código de `'Z'` (90) es menor que el código de `'a'` (97). Aquí hay algunos ejemplos donde las primeras letras están en distinto caso: + +```javascript +console.log('Zebra' < 'apple'); // => true — 'Z'(90) < 'a'(97) +console.log('apple' < 'Banana'); // => false — 'a'(97) > 'B'(66) +console.log('Apple' < 'apple'); // => true — 'A'(65) < 'a'(97) +``` + +Escribamos una función que verifique si una palabra comienza con una letra dada. Para ello, tomamos el primer carácter de la cadena y lo comparamos con la letra requerida: + +```javascript +const startsWithLetter = (word, letter) => word[0] === letter; + +console.log(startsWithLetter('apple', 'a')); // => true +console.log(startsWithLetter('banana', 'a')); // => false +``` + +Las operaciones de comparación son expresiones igual que las aritméticas. En ellas puedes sustituir valores ya preparados y otras expresiones, por ejemplo `word[0]` más arriba. También puedes usar la propiedad `.length`: + +```javascript +console.log('apple'.length > 3); // => true, porque la longitud es 5 +console.log('hi'.length > 3); // => false, porque la longitud es 2 +``` + +Primero se evalúa `'apple'.length` (que da el número `5`), y luego ese número se compara con `3`. Es decir, primero se calculan los operandos de la expresión y después se realiza la comparación. + +## Predicados útiles + +Las cadenas en JavaScript tienen métodos predicados incorporados. Devuelven `true` o `false` y ayudan a verificar distintas propiedades de una cadena: + +```javascript +console.log('hello'.startsWith('he')); // => true — la cadena comienza con 'he' +console.log('hello'.endsWith('lo')); // => true — la cadena termina con 'lo' +console.log('hello'.includes('ell')); // => true — la cadena contiene 'ell' +``` + +Estos métodos permiten verificar cadenas contra las condiciones requeridas directamente en el código, sin escribir funciones adicionales. diff --git a/modules/45-logic/17-bool-strings/es/data.yml b/modules/45-logic/17-bool-strings/es/data.yml new file mode 100644 index 00000000..f721cb49 --- /dev/null +++ b/modules/45-logic/17-bool-strings/es/data.yml @@ -0,0 +1,11 @@ +--- +name: Comparación de cadenas +tips: + - > + [Comparación de cadenas en + JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Less_than) +definitions: + - name: Comparación lexicográfica + description: >- + comparación de cadenas carácter por carácter de izquierda a derecha según + los códigos numéricos de los caracteres (Unicode). diff --git a/modules/45-logic/25-logical-operators/description.es.yml b/modules/45-logic/25-logical-operators/description.es.yml index 5cc984d1..08d4480e 100644 --- a/modules/45-logic/25-logical-operators/description.es.yml +++ b/modules/45-logic/25-logical-operators/description.es.yml @@ -3,7 +3,7 @@ name: Operadores lógicos theory: | - Las expresiones lógicas pueden combinarse entre sí para crear verificaciones más complejas. Un buen ejemplo es la verificación de contraseñas. Como sabes, algunos sitios web requieren contraseñas de entre 8 y 20 caracteres de longitud. Honestamente, esta es una restricción extraña, pero qué se le va a hacer. En matemáticas, escribiríamos `8 < x < 20` (donde `x` es la longitud de una contraseña específica), pero en JavaScript esto no funcionaría. Tendremos que hacer dos expresiones lógicas separadas y combinarlas con el operador especial "Y": + Las expresiones lógicas pueden combinarse entre sí para crear verificaciones cada vez más complejas. Un buen ejemplo es la verificación de contraseñas. Como sabes, algunos sitios web requieren contraseñas de entre 8 y 20 caracteres de longitud durante el registro. Honestamente, esta es una restricción extraña, pero qué se le va a hacer. En matemáticas, escribiríamos `8 < x < 20` (donde `x` es la longitud de una contraseña específica), pero en JavaScript esto no funcionaría. Tendremos que hacer dos expresiones lógicas separadas y combinarlas con el operador especial "Y": ``` La contraseña es más larga de 8 caracteres **Y** más corta de 20 caracteres. @@ -60,17 +60,16 @@ theory: | isGoodApartment(80, 'Main Street'); // true ``` - El área de las matemáticas que estudia los operadores lógicos se llama álgebra booleana. A continuación se muestran las "tablas de verdad" que permiten determinar el resultado de la aplicación de un operador: ## Y `&&` | A | B | A && B | |-------| ------|----------| - | VERDADERO | VERDADERO | **VERDADERO** | - | VERDADERO | FALSO | FALSO | - | FALSO | VERDADERO | FALSO | - | FALSO | FALSO | FALSO | + | TRUE | TRUE | **TRUE** | + | TRUE | FALSE | FALSE | + | FALSE | TRUE | FALSE | + | FALSE | FALSE | FALSE | Algunos ejemplos: @@ -86,10 +85,10 @@ theory: | | A | B | A || B | |-------|-------|----------| - | VERDADERO | VERDADERO | **VERDADERO** | - | VERDADERO | FALSO | **VERDADERO** | - | FALSO | VERDADERO | **VERDADERO** | - | FALSO | FALSO | FALSO | + | TRUE | TRUE | **TRUE** | + | TRUE | FALSE | **TRUE** | + | FALSE | TRUE | **TRUE** | + | FALSE | FALSE | FALSE | Algunos ejemplos: @@ -103,23 +102,17 @@ theory: | instructions: | - Implementa la función `isLeapYear()`, que determina si un año es bisiesto o no. Un año es bisiesto si es divisible (es decir, no tiene residuo) por 400 o si es divisible por 4 y no es divisible por 100. Como puedes ver, toda la lógica necesaria ya está incluida en la definición, sólo falta convertirla en código: + Escribe una función `isLeapYear(year)` que devuelva `true` si el año es bisiesto. - ```javascript - isLeapYear(2018); // false - isLeapYear(2017); // false - isLeapYear(2016); // true - ``` - - Puedes verificar la divisibilidad de la siguiente manera: + Un año es bisiesto si: + - es divisible por 4, **pero no** por 100, **o** + - es divisible por 400. ```javascript - // % - devuelve el residuo de la división del operando izquierdo por el operando derecho - // Verifica si number es divisible por 10 - number % 10 === 0 - - // Verifica si number no es divisible por 10 - number % 10 !== 0 + isLeapYear(2000); // => true + isLeapYear(1900); // => false + isLeapYear(2024); // => true + isLeapYear(2023); // => false ``` tips: @@ -132,4 +125,4 @@ tips: definitions: - name: "Operadores lógicos" - description: "operadores 'Y' (&&) y 'O' (||) que permiten crear condiciones lógicas compuestas." + description: "los operadores 'Y' (&&) y 'O' (||) que permiten crear condiciones lógicas compuestas." diff --git a/modules/45-logic/25-logical-operators/en/EXERCISE.md b/modules/45-logic/25-logical-operators/en/EXERCISE.md index e22ad4b9..6f2d77cc 100644 --- a/modules/45-logic/25-logical-operators/en/EXERCISE.md +++ b/modules/45-logic/25-logical-operators/en/EXERCISE.md @@ -1,19 +1,12 @@ +Write a function `isLeapYear(year)` that returns `true` if the year is a leap year. -Write a function, `isLeapYear()`, to determine whether a year is a leap year or not. A leap year is a multiple of 400 (i.e. divisible without a remainder), or it is both a multiple of 4 and not a multiple of 100. As you can see, the definition already contains all the required logic, all we need to do is to put it into code: +A year is a leap year if: +- it is divisible by 4, **but not** by 100, **or** +- it is divisible by 400. ```javascript -isLeapYear(2018); // false -isLeapYear(2017); // false -isLeapYear(2016); // true -``` - -You can test multiplicity as follows: - -```javascript -// % - returns the remainder after dividing the left operand by the right one -// Check if number is a multiple of 10 -number % 10 === 0 - -// Check if number is not a multiple of 10 -number % 10 !== 0 +isLeapYear(2000); // => true +isLeapYear(1900); // => false +isLeapYear(2024); // => true +isLeapYear(2023); // => false ``` diff --git a/modules/45-logic/25-logical-operators/en/README.md b/modules/45-logic/25-logical-operators/en/README.md index 0d224055..19cd9921 100644 --- a/modules/45-logic/25-logical-operators/en/README.md +++ b/modules/45-logic/25-logical-operators/en/README.md @@ -1,11 +1,11 @@ -You can combine logical expressions to create increasingly cleverer and more useful checks. One good example is password verification. As you know, some websites want a password of 8 to 20 characters on signup. Frankly, it's a weird restriction, but whatever, it is what it is. In math, we would write `8 < x < 20` (where `x` is the length of a particular password), but that trick won't work in JavaScript. We would have to make two separate logical expressions and connect them with the special "AND" operator: +Logical expressions can be combined with one another, creating increasingly tricky checks. A good example is password validation. As you know, some websites require a password between 8 and 20 characters long during registration. Honestly, it's a strange restriction, but what can you do. In math, we would write `8 < x < 20` (where `x` is the length of a specific password), but in JavaScript this trick won't work. We will have to make two separate logical expressions and join them with a special "AND" operator: ``` -A password longer than 8 characters **AND** a password shorter than 20 characters. +The password is longer than 8 characters **AND** the password is shorter than 20 characters. ``` -Here's a function that takes the password and says whether it meets the conditions or not: +Here is a function that takes a password and says whether it meets the conditions or not: ```javascript const isStrongPassword = (password) => { @@ -18,29 +18,31 @@ isStrongPassword('qwerty1234'); // true isStrongPassword('zxcvbnmasdfghjkqwertyui'); // false ``` -`&&` means "AND" (called a conjunction in mathematical logic). The whole expression is true only when every operand, which are all part of the compound expressions, is true. In other words, `&&` means "both". +`&&` means "AND" (in mathematical logic this is called conjunction). The whole expression is considered true only when each operand is true — each of the component expressions. In other words, `&&` means "both one and the other". -This operator's priority is lower than that of comparison operators, so the expression works correctly without parentheses. +The precedence of this operator is lower than that of the comparison operators, so the expression works correctly without parentheses. -Another widespread operator along with `&&` is `||` — "OR" (disjunction). It means "one or the other, or both". Operators can be combined in any number and any sequence, but when `&&` and `||` appear together, you should label priority with parentheses. Below is an example of an advanced function validating a password: +Besides `&&`, the operator `||` — "OR" (disjunction) is often used. It means "either one, or the other, or both". Operators can be combined in any number and in any sequence, but when `&&` and `||` occur together, it's better to set precedence with parentheses. Below is an example of an extended function for determining password correctness: ```javascript -const hasSpecialChars = (str) => /* checks for special characters in the string */; +const hasSpecialChars = (str) => /* checks whether the string contains special characters */; + +const hasCapitalChars = (str) => /* checks whether the string contains capital letters */ const isStrongPassword = (password) => { const length = password.length; - // The parentheses set the priority, making it clear how each part is related - return (length > 8 && length < 20) || hasSpecialChars(password); + // Parentheses set the precedence. It's clear what relates to what. + return length > 8 && (hasSpecialChars(password) || hasCapitalChars(password)); }; ``` -Another example. We want to buy an apartment that meets these conditions: an area of 100 square meters or more on any street **OR** an area of 80 square meters or more, but on `Main Street`. +Another example. We want to buy an apartment that meets the conditions: an area of 100 square meters or more on any street **OR** an area of 80 square meters or more, but on the central street `Main Street`. -We'll write a function checking the apartment. It takes two arguments: the area (a number) and the street name (a string): +Let's write a function that checks the apartment. It takes two arguments: the area (a number) and the street name (a string): ```javascript const isGoodApartment = (area, street) => { - // Via a variable to make sure the function is not too long + // Via a variable so the function isn't too long const result = area >= 100 || (area >= 80 && street === 'Main Street'); return result; }; @@ -54,7 +56,7 @@ isGoodApartment(120, 'Main Street'); // true isGoodApartment(80, 'Main Street'); // true ``` -The area of mathematics dealing with logical operators is called Boolean algebra. The "truth tables" are shown below and can be used to figure out the result of an operator: +The branch of mathematics that studies logical operators is called Boolean algebra. Below are the "truth tables" — you can use them to determine the result of applying an operator: ## AND `&&` @@ -65,7 +67,7 @@ The area of mathematics dealing with logical operators is called Boolean algebra | FALSE | TRUE | FALSE | | FALSE | FALSE | FALSE | -Few examples: +A couple of examples: ```javascript // true && true; @@ -84,7 +86,7 @@ Few examples: | FALSE | TRUE | **TRUE** | | FALSE | FALSE | FALSE | -Few examples: +A couple of examples: ```javascript // true || true; diff --git a/modules/45-logic/25-logical-operators/en/data.yml b/modules/45-logic/25-logical-operators/en/data.yml index c902c3f7..d4911648 100644 --- a/modules/45-logic/25-logical-operators/en/data.yml +++ b/modules/45-logic/25-logical-operators/en/data.yml @@ -2,7 +2,7 @@ name: Logical operators tips: - | - [Boolean algebra](https://en.wikipedia.org/wiki/Boolean_algebra_(structure)) + [Boolean algebra](https://en.wikipedia.org/wiki/Boolean_algebra) - | [Conjunction](https://en.wikipedia.org/wiki/Logical_conjunction) - | @@ -10,5 +10,5 @@ tips: definitions: - name: Logical operators description: >- - are the AND (&&) and OR (||) operators, which allow you to create compound + the AND (&&) and OR (||) operators, which allow you to create compound logical conditions. diff --git a/modules/45-logic/25-logical-operators/es/EXERCISE.md b/modules/45-logic/25-logical-operators/es/EXERCISE.md index 6f23e9b9..3f689785 100644 --- a/modules/45-logic/25-logical-operators/es/EXERCISE.md +++ b/modules/45-logic/25-logical-operators/es/EXERCISE.md @@ -1,19 +1,12 @@ +Escribe una función `isLeapYear(year)` que devuelva `true` si el año es bisiesto. -Implementa la función `isLeapYear()`, que determina si un año es bisiesto o no. Un año es bisiesto si es divisible (es decir, no tiene residuo) por 400 o si es divisible por 4 y no es divisible por 100. Como puedes ver, toda la lógica necesaria ya está incluida en la definición, sólo falta convertirla en código: +Un año es bisiesto si: +- es divisible por 4, **pero no** por 100, **o** +- es divisible por 400. ```javascript -isLeapYear(2018); // false -isLeapYear(2017); // false -isLeapYear(2016); // true -``` - -Puedes verificar la divisibilidad de la siguiente manera: - -```javascript -// % - devuelve el residuo de la división del operando izquierdo por el operando derecho -// Verifica si number es divisible por 10 -number % 10 === 0 - -// Verifica si number no es divisible por 10 -number % 10 !== 0 +isLeapYear(2000); // => true +isLeapYear(1900); // => false +isLeapYear(2024); // => true +isLeapYear(2023); // => false ``` diff --git a/modules/45-logic/25-logical-operators/es/README.md b/modules/45-logic/25-logical-operators/es/README.md index d7d9999d..7066ed3e 100644 --- a/modules/45-logic/25-logical-operators/es/README.md +++ b/modules/45-logic/25-logical-operators/es/README.md @@ -1,5 +1,5 @@ -Las expresiones lógicas pueden combinarse entre sí para crear verificaciones más complejas. Un buen ejemplo es la verificación de contraseñas. Como sabes, algunos sitios web requieren contraseñas de entre 8 y 20 caracteres de longitud. Honestamente, esta es una restricción extraña, pero qué se le va a hacer. En matemáticas, escribiríamos `8 < x < 20` (donde `x` es la longitud de una contraseña específica), pero en JavaScript esto no funcionaría. Tendremos que hacer dos expresiones lógicas separadas y combinarlas con el operador especial "Y": +Las expresiones lógicas pueden combinarse entre sí para crear verificaciones cada vez más complejas. Un buen ejemplo es la verificación de contraseñas. Como sabes, algunos sitios web requieren contraseñas de entre 8 y 20 caracteres de longitud durante el registro. Honestamente, esta es una restricción extraña, pero qué se le va a hacer. En matemáticas, escribiríamos `8 < x < 20` (donde `x` es la longitud de una contraseña específica), pero en JavaScript esto no funcionaría. Tendremos que hacer dos expresiones lógicas separadas y combinarlas con el operador especial "Y": ``` La contraseña es más larga de 8 caracteres **Y** más corta de 20 caracteres. @@ -62,10 +62,10 @@ El área de las matemáticas que estudia los operadores lógicos se llama álgeb | A | B | A && B | |-------| ------|----------| -| VERDADERO | VERDADERO | **VERDADERO** | -| VERDADERO | FALSO | FALSO | -| FALSO | VERDADERO | FALSO | -| FALSO | FALSO | FALSO | +| TRUE | TRUE | **TRUE** | +| TRUE | FALSE | FALSE | +| FALSE | TRUE | FALSE | +| FALSE | FALSE | FALSE | Algunos ejemplos: @@ -81,10 +81,10 @@ Algunos ejemplos: | A | B | A || B | |-------|-------|----------| -| VERDADERO | VERDADERO | **VERDADERO** | -| VERDADERO | FALSO | **VERDADERO** | -| FALSO | VERDADERO | **VERDADERO** | -| FALSO | FALSO | FALSO | +| TRUE | TRUE | **TRUE** | +| TRUE | FALSE | **TRUE** | +| FALSE | TRUE | **TRUE** | +| FALSE | FALSE | FALSE | Algunos ejemplos: diff --git a/modules/45-logic/25-logical-operators/es/data.yml b/modules/45-logic/25-logical-operators/es/data.yml index 6d3015d7..b9f0173c 100644 --- a/modules/45-logic/25-logical-operators/es/data.yml +++ b/modules/45-logic/25-logical-operators/es/data.yml @@ -10,5 +10,5 @@ tips: definitions: - name: Operadores lógicos description: >- - operadores 'Y' (&&) y 'O' (||) que permiten crear condiciones lógicas + los operadores "Y" (&&) y "O" (||) que permiten crear condiciones lógicas compuestas. diff --git a/modules/45-logic/28-logical-negation/description.es.yml b/modules/45-logic/28-logical-negation/description.es.yml index 3eed1231..839af7c7 100644 --- a/modules/45-logic/28-logical-negation/description.es.yml +++ b/modules/45-logic/28-logical-negation/description.es.yml @@ -2,10 +2,14 @@ name: Negación theory: | + Junto con los operadores lógicos **Y** (`&&`) y **O** (`||`), se utiliza con frecuencia la operación de «**negación**». Esta invierte un valor booleano a su opuesto. En JavaScript, la negación corresponde al operador unario `!`: - Junto con la conjunción (Y) y la disyunción (O), a menudo se utiliza la operación de "negación". La negación cambia el valor lógico al opuesto. En programación, se corresponde con el operador unario `!`. + ```javascript + !true; // false + !false; // true + ``` - Si hay una función que verifica si un número es par, se puede realizar una verificación de si es impar utilizando la negación: + Por ejemplo, si hay una función que comprueba si un número es par, con la negación se puede comprobar la imparidad: ```javascript const isEven = (number) => number % 2 === 0; @@ -14,12 +18,11 @@ theory: | !isEven(10); // false ``` + Simplemente añadimos `!` a la izquierda de la llamada a la función y obtuvimos la acción inversa. La negación permite expresar las reglas previstas en el código sin escribir nuevas funciones. - Es decir, simplemente agregamos `!` antes de llamar a la función y obtenemos la acción opuesta. + ## Doble negación - La negación es una herramienta poderosa que permite expresar reglas previstas de manera concisa en el código sin necesidad de escribir nuevas funciones. - - ¿Y qué pasa si escribimos `!!isEven(10)`? Sorprendentemente, el código funcionará. En lógica, la doble negación es similar a la ausencia de negación en absoluto. + ¿Y qué pasa si se escribe `!!isEven(10)`? Sorprendentemente, el código funciona. En lógica, la doble negación equivale a la ausencia de negación: ```javascript isEven(10); // true @@ -27,43 +30,75 @@ theory: | !!isEven(10); // true ``` -instructions: | + ## Combinación con && y || + + `!` se puede combinar con `&&` y `||`. Entre los operadores lógicos, la negación tiene la mayor prioridad, por lo que se aplica primero: + + ```javascript + !true || true; // (!true) || true => false || true => true + !true && false; // (!true) && false => false && false => false + ``` + + Los paréntesis cambian el orden de evaluación: + + ```javascript + !(true || true); // !true => false + !(true && false); // !false => true + ``` + + Un ejemplo práctico: una función comprueba si un conductor puede ponerse al volante — se necesita licencia y sobriedad: + + ```javascript + const canDrive = (hasLicense, isDrunk) => hasLicense && !isDrunk; - En esta lección, deberás implementar dos funciones: `isPalindrome()` e `isNotPalindrome()` + console.log(canDrive(true, false)); // => true (tiene licencia, sobrio) + console.log(canDrive(true, true)); // => false (tiene licencia, pero borracho) + console.log(canDrive(false, false)); // => false (sin licencia) + ``` - 1. La función `isPalindrome()` determina si una palabra es un palíndromo o no. Un palíndromo es una palabra que se lee igual en ambos sentidos. + ## Leyes de De Morgan - ```javascript - isPalindrome('ala'); // true - isPalindrome('radar'); // true - isPalindrome('hexlet'); // false + Al trabajar con expresiones lógicas complejas, a veces es necesario invertirlas o reescribirlas en una forma equivalente y más legible. Para esto existen las **leyes de De Morgan** — dos reglas que describen cómo se distribuye la negación sobre una expresión compuesta: - // Las palabras pueden ser pasadas a la función en cualquier caso - // Por lo tanto, primero debes convertir la palabra a minúsculas word.toLowerCase() - isPalindrome('ala'); // true - ``` + ```javascript + !(a && b) === !a || !b + !(a || b) === !a && !b + ``` + + La primera ley: la negación de una conjunción es igual a la disyunción de las negaciones. Comprobémoslo: + + ```javascript + !(true && false); // !false => true + !true || !false; // false || true => true + ``` - Para determinar si una palabra es un palíndromo, debes invertir la cadena y compararla con la original. Para ello, utiliza la función `reverse()` + La segunda ley: la negación de una disyunción es igual a la conjunción de las negaciones: - ```javascript - reverse('mama'); // mama - ``` + ```javascript + !(true || false); // !true => false + !true && !false; // false && true => false + ``` - 2. La función `isNotPalindrome()` verifica que una palabra NO sea un palíndromo: + En la práctica, las leyes de De Morgan ayudan a simplificar condiciones. Por ejemplo, en lugar de `!(isAdmin || isModerator)` se puede escribir `!isAdmin && !isModerator` — que se lee como «no es administrador y no es moderador». +instructions: | + Escribe dos funciones: - ```javascript - isNotPalindrome('radar'); // false - isNotPalindrome('ala'); // false - isNotPalindrome('hexlet'); // true - ``` + 1. `isPalindrome(str)` — devuelve `true` si la cadena es un palíndromo (se lee igual en ambas direcciones). + 2. `isNotPalindrome(str)` — devuelve `true` si la cadena **no** es un palíndromo. - Para ello, llama a la función `isPalindrome()` dentro de `isNotPalindrome()` y aplica la negación. + ```javascript + isPalindrome('level'); // => true + isPalindrome('hello'); // => false + isNotPalindrome('level'); // => false + isNotPalindrome('hello'); // => true + ``` + Usa los métodos `.split('')`, `.reverse()`, `.join('')` para invertir la cadena. tips: - | [Leyes de De Morgan](https://es.wikipedia.org/wiki/Leyes_de_De_Morgan) - definitions: - name: Negación - description: | - operación lógica que cambia el valor lógico al opuesto. + description: > + una operación lógica que invierte un valor booleano a su + opuesto. diff --git a/modules/45-logic/28-logical-negation/en/EXERCISE.md b/modules/45-logic/28-logical-negation/en/EXERCISE.md index 92097e9c..ccfb4dae 100644 --- a/modules/45-logic/28-logical-negation/en/EXERCISE.md +++ b/modules/45-logic/28-logical-negation/en/EXERCISE.md @@ -1,28 +1,13 @@ +Write two functions: -1. Write a function, `isPalindrome()`, to check if a word is a palindrome. A palindrome is a word that reads the same backwards as it does forward. +1. `isPalindrome(str)` — returns `true` if the string is a palindrome (reads the same in both directions). +2. `isNotPalindrome(str)` — returns `true` if the string is **not** a palindrome. - ```javascript - isPalindrome('refer'); // true - isPalindrome('level'); // true - isPalindrome('hexlet'); // false +```javascript +isPalindrome('level'); // => true +isPalindrome('hello'); // => false +isNotPalindrome('level'); // => false +isNotPalindrome('hello'); // => true +``` - // You can pass words to the function in any case - // So first you have to make the word lower case: word.toLowerCase() - isPalindrome('Madam'); // true - ``` - - To find a palindrome, you need to reverse the string and compare it to the initial one. To do this, use the `reverse()` function. - - ```javascript - reverse('hexlet'); // 'telhex' - ``` - -2. Write a function, `isNotPalindrome()`, to check if a word is NOT a palindrome: - - ```javascript - isNotPalindrome('level'); // false - isNotPalindrome('wow'); // false - isNotPalindrome('hexlet'); // true - ``` - - All you need is to negate the `isPalindrome()` function call within the `isNotPalindrome()` function's body. +Use the `.split('')`, `.reverse()`, `.join('')` methods to reverse the string. diff --git a/modules/45-logic/28-logical-negation/en/README.md b/modules/45-logic/28-logical-negation/en/README.md index 75975464..7498643f 100644 --- a/modules/45-logic/28-logical-negation/en/README.md +++ b/modules/45-logic/28-logical-negation/en/README.md @@ -1,7 +1,11 @@ +Along with the logical operators **AND** (`&&`) and **OR** (`||`), the "**negation**" operation is often used. It flips a boolean value to its opposite. In JavaScript, negation corresponds to the unary operator `!`: -Along with the conjunction (AND) and disjunction (OR) we often use the "negation" operator, too. It changes the logical value to the opposite one. It is denoted by the unary operator `!` in programming. +```javascript +!true; // false +!false; // true +``` -If there is a function that checks for even numbers, then negation will allow you to check for odd numbers: +For example, if you have a function that checks whether a number is even, you can use negation to check for oddness: ```javascript const isEven = (number) => number % 2 === 0; @@ -10,14 +14,65 @@ isEven(10); // true !isEven(10); // false ``` -I.e., we can just put a `!` to the left of the function call and get the opposite result. +We simply added `!` to the left of the function call and got the opposite result. Negation lets you express the intended rules in code without writing new functions. -Negation is a powerful tool that allows you to concisely express the desired rules in your code without having to write new functions. +## Double negation -What if you wrote `!!isEven(10)` like this? Suddenly, the code would work. Double negation in logic is equivalent to no negation at all. +But what if you write `!!isEven(10)`? Surprisingly, the code works. In logic, double negation is equivalent to no negation at all: ```javascript isEven(10); // true !isEven(10); // false !!isEven(10); // true ``` + +## Combining with && and || + +`!` can be combined with `&&` and `||`. Among the logical operators, negation has the highest precedence, so it is applied first: + +```javascript +!true || true; // (!true) || true => false || true => true +!true && false; // (!true) && false => false && false => false +``` + +Parentheses change the order of evaluation: + +```javascript +!(true || true); // !true => false +!(true && false); // !false => true +``` + +A practical example: a function checks whether a driver can get behind the wheel — a license and sobriety are required: + +```javascript +const canDrive = (hasLicense, isDrunk) => hasLicense && !isDrunk; + +console.log(canDrive(true, false)); // => true (has a license, sober) +console.log(canDrive(true, true)); // => false (has a license, but drunk) +console.log(canDrive(false, false)); // => false (no license) +``` + +## De Morgan's laws + +When working with complex logical expressions, you sometimes need to invert them or rewrite them in an equivalent, more readable form. For this there are **De Morgan's laws** — two rules that describe how negation distributes over a compound expression: + +```javascript +!(a && b) === !a || !b +!(a || b) === !a && !b +``` + +The first law: the negation of a conjunction equals the disjunction of the negations. Let's check: + +```javascript +!(true && false); // !false => true +!true || !false; // false || true => true +``` + +The second law: the negation of a disjunction equals the conjunction of the negations: + +```javascript +!(true || false); // !true => false +!true && !false; // false && true => false +``` + +In practice, De Morgan's laws help simplify conditions. For example, instead of `!(isAdmin || isModerator)` you can write `!isAdmin && !isModerator` — which reads as "not an administrator and not a moderator". diff --git a/modules/45-logic/28-logical-negation/en/data.yml b/modules/45-logic/28-logical-negation/en/data.yml index 359abfe5..75a1d8fa 100644 --- a/modules/45-logic/28-logical-negation/en/data.yml +++ b/modules/45-logic/28-logical-negation/en/data.yml @@ -3,3 +3,8 @@ name: Negation tips: - | [De Morgan's laws](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) +definitions: + - name: Negation + description: > + a logical operation that flips a boolean value to its + opposite. diff --git a/modules/45-logic/28-logical-negation/es/EXERCISE.md b/modules/45-logic/28-logical-negation/es/EXERCISE.md index 67332cee..2e358fd0 100644 --- a/modules/45-logic/28-logical-negation/es/EXERCISE.md +++ b/modules/45-logic/28-logical-negation/es/EXERCISE.md @@ -1,30 +1,13 @@ +Escribe dos funciones: -En esta lección, deberás implementar dos funciones: `isPalindrome()` e `isNotPalindrome()` +1. `isPalindrome(str)` — devuelve `true` si la cadena es un palíndromo (se lee igual en ambas direcciones). +2. `isNotPalindrome(str)` — devuelve `true` si la cadena **no** es un palíndromo. -1. La función `isPalindrome()` determina si una palabra es un palíndromo o no. Un palíndromo es una palabra que se lee igual en ambos sentidos. +```javascript +isPalindrome('level'); // => true +isPalindrome('hello'); // => false +isNotPalindrome('level'); // => false +isNotPalindrome('hello'); // => true +``` - ```javascript - isPalindrome('ala'); // true - isPalindrome('radar'); // true - isPalindrome('hexlet'); // false - - // Las palabras pueden ser pasadas a la función en cualquier caso - // Por lo tanto, primero debes convertir la palabra a minúsculas word.toLowerCase() - isPalindrome('ala'); // true - ``` - - Para determinar si una palabra es un palíndromo, debes invertir la cadena y compararla con la original. Para ello, utiliza la función `reverse()` - - ```javascript - reverse('mama'); // mama - ``` - -2. La función `isNotPalindrome()` verifica que una palabra NO sea un palíndromo: - - ```javascript - isNotPalindrome('radar'); // false - isNotPalindrome('ala'); // false - isNotPalindrome('hexlet'); // true - ``` - - Para ello, llama a la función `isPalindrome()` dentro de `isNotPalindrome()` y aplica la negación. +Usa los métodos `.split('')`, `.reverse()`, `.join('')` para invertir la cadena. diff --git a/modules/45-logic/28-logical-negation/es/README.md b/modules/45-logic/28-logical-negation/es/README.md index da989857..54780c25 100644 --- a/modules/45-logic/28-logical-negation/es/README.md +++ b/modules/45-logic/28-logical-negation/es/README.md @@ -1,7 +1,11 @@ +Junto con los operadores lógicos **Y** (`&&`) y **O** (`||`), se utiliza con frecuencia la operación de «**negación**». Esta invierte un valor booleano a su opuesto. En JavaScript, la negación corresponde al operador unario `!`: -Junto con la conjunción (Y) y la disyunción (O), a menudo se utiliza la operación de "negación". La negación cambia el valor lógico al opuesto. En programación, se corresponde con el operador unario `!`. +```javascript +!true; // false +!false; // true +``` -Si hay una función que verifica si un número es par, se puede realizar una verificación de si es impar utilizando la negación: +Por ejemplo, si hay una función que comprueba si un número es par, con la negación se puede comprobar la imparidad: ```javascript const isEven = (number) => number % 2 === 0; @@ -10,14 +14,65 @@ isEven(10); // true !isEven(10); // false ``` -Es decir, simplemente agregamos `!` antes de llamar a la función y obtenemos la acción opuesta. +Simplemente añadimos `!` a la izquierda de la llamada a la función y obtuvimos la acción inversa. La negación permite expresar las reglas previstas en el código sin escribir nuevas funciones. -La negación es una herramienta poderosa que permite expresar reglas previstas de manera concisa en el código sin necesidad de escribir nuevas funciones. +## Doble negación -¿Y qué pasa si escribimos `!!isEven(10)`? Sorprendentemente, el código funcionará. En lógica, la doble negación es similar a la ausencia de negación en absoluto. +¿Y qué pasa si se escribe `!!isEven(10)`? Sorprendentemente, el código funciona. En lógica, la doble negación equivale a la ausencia de negación: ```javascript isEven(10); // true !isEven(10); // false !!isEven(10); // true ``` + +## Combinación con && y || + +`!` se puede combinar con `&&` y `||`. Entre los operadores lógicos, la negación tiene la mayor prioridad, por lo que se aplica primero: + +```javascript +!true || true; // (!true) || true => false || true => true +!true && false; // (!true) && false => false && false => false +``` + +Los paréntesis cambian el orden de evaluación: + +```javascript +!(true || true); // !true => false +!(true && false); // !false => true +``` + +Un ejemplo práctico: una función comprueba si un conductor puede ponerse al volante — se necesita licencia y sobriedad: + +```javascript +const canDrive = (hasLicense, isDrunk) => hasLicense && !isDrunk; + +console.log(canDrive(true, false)); // => true (tiene licencia, sobrio) +console.log(canDrive(true, true)); // => false (tiene licencia, pero borracho) +console.log(canDrive(false, false)); // => false (sin licencia) +``` + +## Leyes de De Morgan + +Al trabajar con expresiones lógicas complejas, a veces es necesario invertirlas o reescribirlas en una forma equivalente y más legible. Para esto existen las **leyes de De Morgan** — dos reglas que describen cómo se distribuye la negación sobre una expresión compuesta: + +```javascript +!(a && b) === !a || !b +!(a || b) === !a && !b +``` + +La primera ley: la negación de una conjunción es igual a la disyunción de las negaciones. Comprobémoslo: + +```javascript +!(true && false); // !false => true +!true || !false; // false || true => true +``` + +La segunda ley: la negación de una disyunción es igual a la conjunción de las negaciones: + +```javascript +!(true || false); // !true => false +!true && !false; // false && true => false +``` + +En la práctica, las leyes de De Morgan ayudan a simplificar condiciones. Por ejemplo, en lugar de `!(isAdmin || isModerator)` se puede escribir `!isAdmin && !isModerator` — que se lee como «no es administrador y no es moderador». diff --git a/modules/45-logic/28-logical-negation/es/data.yml b/modules/45-logic/28-logical-negation/es/data.yml index d8339fe4..3c2de98a 100644 --- a/modules/45-logic/28-logical-negation/es/data.yml +++ b/modules/45-logic/28-logical-negation/es/data.yml @@ -5,5 +5,6 @@ tips: [Leyes de De Morgan](https://es.wikipedia.org/wiki/Leyes_de_De_Morgan) definitions: - name: Negación - description: | - operación lógica que cambia el valor lógico al opuesto. + description: > + una operación lógica que invierte un valor booleano a su + opuesto. diff --git a/modules/48-conditionals/30-if/description.es.yml b/modules/48-conditionals/30-if/description.es.yml index e5bbab64..efc4ba57 100644 --- a/modules/48-conditionals/30-if/description.es.yml +++ b/modules/48-conditionals/30-if/description.es.yml @@ -2,63 +2,111 @@ name: Estructura condicional (if) theory: | + Las expresiones lógicas permiten comprobar distintas condiciones, pero por sí solas solo devuelven `true` o `false`. Para que un programa pueda ejecutar diferentes acciones según el resultado, JavaScript tiene una construcción especial llamada `if`. - Las estructuras condicionales permiten cambiar el comportamiento de un programa según las condiciones que se evalúen. Gracias a ellas, podemos escribir programas complejos que se comporten de manera diferente según la situación. + ```javascript + if (5 > 3) { + console.log('Yes, it is true'); + } + ``` - Por ejemplo, escribamos una función que determine el tipo de una oración dada. Al principio, esta función distinguirá entre oraciones normales y preguntas. + Aquí se imprimirá la cadena `'Yes, it is true'` porque la condición `5 > 3` es verdadera. + + ```text + ┌────────────┐ + │ ¿condición?│ + └─────┬──────┘ + true │ + ↓ + ┌────────────┐ + │ cuerpo if │ + └────────────┘ + ``` - ```javascript - const getTypeOfSentence = (sentence) => { - const lastChar = sentence[sentence.length - 1]; - if (lastChar === '?') { - return 'question'; - } + ## Sintaxis - return 'general'; - }; + Después de `if`, la condición se escribe entre paréntesis, y el cuerpo va entre llaves: - getTypeOfSentence('Hodor'); // general - getTypeOfSentence('Hodor?'); // question + ```javascript + if (condición) { + // el bloque se ejecuta si la condición es true + } ``` + Una condición es cualquier expresión que se convierte a `true` o `false`. + + ## Bloques de código + + Todo lo que está dentro de las llaves `{}` pertenece al cuerpo del `if`. El código después del bloque se ejecuta en cualquier caso: + + ```javascript + if (10 === 10) { + console.log('First'); + console.log('Second'); + } - `if` es una estructura del lenguaje que controla el orden de ejecución de las instrucciones. Entre paréntesis se le pasa una expresión booleana, y luego se describe un bloque de código entre llaves. Este bloque de código se ejecutará solo si el predicado es verdadero. + console.log('Goodbye!'); + ``` - Si el predicado es falso, se omitirá el bloque de código entre llaves y la función continuará su ejecución. En nuestro caso, la siguiente línea de código, `return 'general';`, hará que la función devuelva una cadena y termine. + Aquí se imprimirán `First` y `Second` porque se cumplió la condición. Y `Goodbye!` se imprime siempre, ya que esta línea está fuera del bloque. El principio es el mismo que en la definición de funciones. - Como puedes ver, `return` puede estar en cualquier lugar de la función, incluso dentro del bloque de código condicional. + ## Uso de if dentro de una función - Si después de `if` entre llaves solo hay una línea de código, las llaves se pueden omitir y hacerlo así: + Consideremos una función que determina el tipo de una oración dada. Si termina con un signo de interrogación, la función devuelve `'question'`, de lo contrario, `'normal'`: ```javascript const getTypeOfSentence = (sentence) => { - const lastChar = sentence[sentence.length - 1]; - if (lastChar === '?') + if (sentence.endsWith('?')) { return 'question'; - - return 'general'; + } + return 'normal'; }; - console.log(getTypeOfSentence('Hodor')); // => general + console.log(getTypeOfSentence('Hodor')); // => normal console.log(getTypeOfSentence('Hodor?')); // => question ``` - Recomendamos no hacer esto y **siempre escribir las llaves**. De esta manera, se ve claramente dónde comienza y termina el cuerpo de la condición. El código se vuelve más claro y comprensible. + Aquí se usan dos `return`. Si se cumple la condición dentro del `if`, se ejecuta `return 'question'` y la función termina. Si la condición no se cumple, el control pasa a la siguiente línea con `return 'normal'`. -instructions: | + De esta manera, la función tiene varios puntos de salida posibles. Esta es una práctica común: dependiendo de las condiciones, una función puede terminar de diferentes maneras. - Implementa la función `guessNumber()`, la cual recibe un número y verifica si es igual al número dado (supongamos que es 42). Si es igual, la función debe devolver la cadena `'You win!'`, de lo contrario, debe devolver la cadena `'Try again!'`. + Aunque la función `getTypeOfSentence` usa `if`, devuelve cadenas, lo que significa que no es un predicado. Como predicado, consideremos una función que comprueba si hay suficiente dinero para una compra: ```javascript - guessNumber(42) // You win! - guessNumber(61) // Try again! + const hasEnoughMoney = (balance, price) => { + if (balance >= price) { + return true; + } + return false; + }; + + console.log(hasEnoughMoney(100, 50)); // => true + console.log(hasEnoughMoney(30, 50)); // => false ``` + ## if y las expresiones lógicas + + Escribimos la función `hasEnoughMoney` usando `if`. Pero en esta forma podría prescindir de él, porque el resultado de la comparación es en sí mismo una expresión lógica: + + ```javascript + const hasEnoughMoney = (balance, price) => balance >= price; + ``` + + En los casos simples, es mejor devolver esa expresión directamente. El `if` es necesario allí donde se ejecutan acciones adicionales dentro del bloque además de devolver el resultado. Cuanto más complejos sean los programas, más a menudo surgirán tales situaciones. +instructions: | + Escribe una función `guessNumber(guess)` que: + + - devuelva `'You win!'` si `guess === 42` + - devuelva `'Try again!'` en caso contrario + + ```javascript + guessNumber(42); // => 'You win!' + guessNumber(7); // => 'Try again!' + ``` tips: - | - [if](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Sentencias/if...else) - + [if](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/if...else) definitions: - name: Estructuras condicionales description: | - cambian el comportamiento del programa según las condiciones evaluadas + cambian el comportamiento de un programa según las condiciones que se comprueban diff --git a/modules/48-conditionals/30-if/en/EXERCISE.md b/modules/48-conditionals/30-if/en/EXERCISE.md index e7ea62ec..e9bb1910 100644 --- a/modules/48-conditionals/30-if/en/EXERCISE.md +++ b/modules/48-conditionals/30-if/en/EXERCISE.md @@ -1,7 +1,9 @@ +Write a function `guessNumber(guess)` that: -Write the `guessNumber()` function that takes a number and checks if it's equal to a given number (say, for example, 42). If it's equal, the function should return the string `You win!'`; otherwise, it should return the string `'Try again!'`. +- returns `'You win!'` if `guess === 42` +- returns `'Try again!'` otherwise ```javascript -guessNumber(42) # 'You win!' -guessNumber(61) # 'Try again!' +guessNumber(42); // => 'You win!' +guessNumber(7); // => 'Try again!' ``` diff --git a/modules/48-conditionals/30-if/en/README.md b/modules/48-conditionals/30-if/en/README.md index 9af74675..3f7411cf 100644 --- a/modules/48-conditionals/30-if/en/README.md +++ b/modules/48-conditionals/30-if/en/README.md @@ -1,41 +1,91 @@ +Logical expressions let you check various conditions, but on their own they only return `true` or `false`. To make a program perform different actions depending on the result, JavaScript has a special construct called `if`. -Conditional statements control the program's behavior depending on the conditions we want to test. They allow us to write complex programs that behave differently depending on the situation. +```javascript +if (5 > 3) { + console.log('Yes, it is true'); +} +``` -Consider a function to which we can pass a sentence and determine what type of sentence it is. To begin with, it will distinguish between normal sentences and question sentences. +Here the string `'Yes, it is true'` will be printed because the condition `5 > 3` is true. -```javascript -const getTypeOfSentence = (sentence) => { - const lastChar = sentence[sentence.length - 1]; - if (lastChar === '?') { - return 'question'; - } +```text +┌────────────┐ +│ condition? │ +└─────┬──────┘ + true │ + ↓ +┌────────────┐ +│ if body │ +└────────────┘ +``` - return 'general'; -}; +## Syntax -getTypeOfSentence('Hodor'); // general -getTypeOfSentence('Hodor?'); // question +After `if`, the condition is written in parentheses, and the body goes in curly braces: + +```javascript +if (condition) { + // the block runs if the condition is true +} ``` -`if` is a construct that controls the procedure by which statements are executed. You need to pass predicate expression to it in parentheses and then define a block of code in curly brackets. This code block executes only if the predicate is true. +A condition is any expression that is coerced to `true` or `false`. + +## Code blocks + +Everything inside the curly braces `{}` belongs to the body of the `if`. The code after the block runs in any case: + +```javascript +if (10 === 10) { + console.log('First'); + console.log('Second'); +} + +console.log('Goodbye!'); +``` -If the predicate is false, we skip the code block in curly brackets, and the function keeps executing. Here, the next line of code, `return 'general';`, causes the function to return a string and terminate. +Here `First` and `Second` will be printed because the condition was met. And `Goodbye!` is always printed since this line is already outside the block. The principle is the same as in function definitions. -As you can see, `return` can be anywhere in a function. Including the interior of a conditional code block. +## Using if inside a function -If the curly brackets after `if` contains only one line of code, you can leave out the brackets: +Consider a function that determines the type of a given sentence. If it ends with a question mark, the function returns `'question'`, otherwise — `'normal'`: ```javascript const getTypeOfSentence = (sentence) => { - const lastChar = sentence[sentence.length - 1]; - if (lastChar === '?') + if (sentence.endsWith('?')) { return 'question'; - - return 'general'; + } + return 'normal'; }; -console.log(getTypeOfSentence('Hodor')); // => general +console.log(getTypeOfSentence('Hodor')); // => normal console.log(getTypeOfSentence('Hodor?')); // => question ``` -We advise against it and to **always use curly brackets**. That way you can clearly see where the conditional's body starts and ends. The code becomes clearer and more readable. +Two `return` statements are used here. If the condition inside `if` is met, `return 'question'` fires and the function ends. If the condition is not met, control passes to the next line with `return 'normal'`. + +This way, the function has several possible exit points. This is a common practice: depending on the conditions, a function may end in different ways. + +Even though the `getTypeOfSentence` function uses `if`, it returns strings, which means it is not a predicate. As a predicate, let's consider a function that checks whether there is enough money for a purchase: + +```javascript +const hasEnoughMoney = (balance, price) => { + if (balance >= price) { + return true; + } + return false; +}; + +console.log(hasEnoughMoney(100, 50)); // => true +console.log(hasEnoughMoney(30, 50)); // => false +``` + +## if and logical expressions + +We wrote the `hasEnoughMoney` function using `if`. But in this form it could do without it, because the result of the comparison is itself a logical expression: + +```javascript +const hasEnoughMoney = (balance, price) => balance >= price; +``` + +In simple cases, it is better to return such an expression right away. `if` is needed where additional actions are performed inside the block besides returning the result. The more complex the programs, the more often such situations will arise. diff --git a/modules/48-conditionals/30-if/en/data.yml b/modules/48-conditionals/30-if/en/data.yml index 1a339c5b..11a66d03 100644 --- a/modules/48-conditionals/30-if/en/data.yml +++ b/modules/48-conditionals/30-if/en/data.yml @@ -1,4 +1,9 @@ --- -name: Conditionals (`if`) -tips: [] -definitions: [] +name: Conditional statement (if) +tips: + - > + [if](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else) +definitions: + - name: Conditional statements + description: | + change the behavior of a program depending on the conditions being checked diff --git a/modules/48-conditionals/30-if/es/EXERCISE.md b/modules/48-conditionals/30-if/es/EXERCISE.md index d8b3e69e..986c1f89 100644 --- a/modules/48-conditionals/30-if/es/EXERCISE.md +++ b/modules/48-conditionals/30-if/es/EXERCISE.md @@ -1,7 +1,9 @@ +Escribe una función `guessNumber(guess)` que: -Implementa la función `guessNumber()`, la cual recibe un número y verifica si es igual al número dado (supongamos que es 42). Si es igual, la función debe devolver la cadena `'You win!'`, de lo contrario, debe devolver la cadena `'Try again!'`. +- devuelva `'You win!'` si `guess === 42` +- devuelva `'Try again!'` en caso contrario ```javascript -guessNumber(42) // You win! -guessNumber(61) // Try again! +guessNumber(42); // => 'You win!' +guessNumber(7); // => 'Try again!' ``` diff --git a/modules/48-conditionals/30-if/es/README.md b/modules/48-conditionals/30-if/es/README.md index 64416164..aaac9365 100644 --- a/modules/48-conditionals/30-if/es/README.md +++ b/modules/48-conditionals/30-if/es/README.md @@ -1,41 +1,91 @@ +Las expresiones lógicas permiten comprobar distintas condiciones, pero por sí solas solo devuelven `true` o `false`. Para que un programa pueda ejecutar diferentes acciones según el resultado, JavaScript tiene una construcción especial llamada `if`. -Las estructuras condicionales permiten cambiar el comportamiento de un programa según las condiciones que se evalúen. Gracias a ellas, podemos escribir programas complejos que se comporten de manera diferente según la situación. +```javascript +if (5 > 3) { + console.log('Yes, it is true'); +} +``` -Por ejemplo, escribamos una función que determine el tipo de una oración dada. Al principio, esta función distinguirá entre oraciones normales y preguntas. +Aquí se imprimirá la cadena `'Yes, it is true'` porque la condición `5 > 3` es verdadera. -```javascript -const getTypeOfSentence = (sentence) => { - const lastChar = sentence[sentence.length - 1]; - if (lastChar === '?') { - return 'question'; - } +```text +┌────────────┐ +│ ¿condición?│ +└─────┬──────┘ + true │ + ↓ +┌────────────┐ +│ cuerpo if │ +└────────────┘ +``` - return 'general'; -}; +## Sintaxis -getTypeOfSentence('Hodor'); // general -getTypeOfSentence('Hodor?'); // question +Después de `if`, la condición se escribe entre paréntesis, y el cuerpo va entre llaves: + +```javascript +if (condición) { + // el bloque se ejecuta si la condición es true +} ``` -`if` es una estructura del lenguaje que controla el orden de ejecución de las instrucciones. Entre paréntesis se le pasa una expresión booleana, y luego se describe un bloque de código entre llaves. Este bloque de código se ejecutará solo si el predicado es verdadero. +Una condición es cualquier expresión que se convierte a `true` o `false`. + +## Bloques de código + +Todo lo que está dentro de las llaves `{}` pertenece al cuerpo del `if`. El código después del bloque se ejecuta en cualquier caso: + +```javascript +if (10 === 10) { + console.log('First'); + console.log('Second'); +} + +console.log('Goodbye!'); +``` -Si el predicado es falso, se omitirá el bloque de código entre llaves y la función continuará su ejecución. En nuestro caso, la siguiente línea de código, `return 'general';`, hará que la función devuelva una cadena y termine. +Aquí se imprimirán `First` y `Second` porque se cumplió la condición. Y `Goodbye!` se imprime siempre, ya que esta línea está fuera del bloque. El principio es el mismo que en la definición de funciones. -Como puedes ver, `return` puede estar en cualquier lugar de la función, incluso dentro del bloque de código condicional. +## Uso de if dentro de una función -Si después de `if` entre llaves solo hay una línea de código, las llaves se pueden omitir y hacerlo así: +Consideremos una función que determina el tipo de una oración dada. Si termina con un signo de interrogación, la función devuelve `'question'`, de lo contrario, `'normal'`: ```javascript const getTypeOfSentence = (sentence) => { - const lastChar = sentence[sentence.length - 1]; - if (lastChar === '?') + if (sentence.endsWith('?')) { return 'question'; - - return 'general'; + } + return 'normal'; }; -console.log(getTypeOfSentence('Hodor')); // => general +console.log(getTypeOfSentence('Hodor')); // => normal console.log(getTypeOfSentence('Hodor?')); // => question ``` -Recomendamos no hacer esto y **siempre escribir las llaves**. De esta manera, se ve claramente dónde comienza y termina el cuerpo de la condición. El código se vuelve más claro y comprensible. +Aquí se usan dos `return`. Si se cumple la condición dentro del `if`, se ejecuta `return 'question'` y la función termina. Si la condición no se cumple, el control pasa a la siguiente línea con `return 'normal'`. + +De esta manera, la función tiene varios puntos de salida posibles. Esta es una práctica común: dependiendo de las condiciones, una función puede terminar de diferentes maneras. + +Aunque la función `getTypeOfSentence` usa `if`, devuelve cadenas, lo que significa que no es un predicado. Como predicado, consideremos una función que comprueba si hay suficiente dinero para una compra: + +```javascript +const hasEnoughMoney = (balance, price) => { + if (balance >= price) { + return true; + } + return false; +}; + +console.log(hasEnoughMoney(100, 50)); // => true +console.log(hasEnoughMoney(30, 50)); // => false +``` + +## if y las expresiones lógicas + +Escribimos la función `hasEnoughMoney` usando `if`. Pero en esta forma podría prescindir de él, porque el resultado de la comparación es en sí mismo una expresión lógica: + +```javascript +const hasEnoughMoney = (balance, price) => balance >= price; +``` + +En los casos simples, es mejor devolver esa expresión directamente. El `if` es necesario allí donde se ejecutan acciones adicionales dentro del bloque además de devolver el resultado. Cuanto más complejos sean los programas, más a menudo surgirán tales situaciones. diff --git a/modules/48-conditionals/30-if/es/data.yml b/modules/48-conditionals/30-if/es/data.yml index 8d94909e..4b31da14 100644 --- a/modules/48-conditionals/30-if/es/data.yml +++ b/modules/48-conditionals/30-if/es/data.yml @@ -2,8 +2,8 @@ name: Estructura condicional (if) tips: - > - [if](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Sentencias/if...else) + [if](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/if...else) definitions: - name: Estructuras condicionales description: | - cambian el comportamiento del programa según las condiciones evaluadas + cambian el comportamiento de un programa según las condiciones que se comprueban diff --git a/modules/48-conditionals/40-if-else/description.es.yml b/modules/48-conditionals/40-if-else/description.es.yml index 1706c333..e95511bc 100644 --- a/modules/48-conditionals/40-if-else/description.es.yml +++ b/modules/48-conditionals/40-if-else/description.es.yml @@ -2,47 +2,77 @@ name: else theory: | - - Vamos a escribir la función `getTypeOfSentence()`, la cual analiza un texto y devuelve una descripción de su tono: para las oraciones normales - *General sentence*, para las preguntas - *Question sentence*. + Escribamos una función `getTypeOfSentence()` que analiza un texto y devuelve una descripción de su tono: para las oraciones ordinarias – *General sentence*, para las interrogativas – *Question sentence*. ```javascript getTypeOfSentence('Hodor'); // General sentence getTypeOfSentence('Hodor?'); // Question sentence ``` - Implementación de la función: + La implementación de la función: ```javascript const getTypeOfSentence = (sentence) => { - // Declaramos una variable donde guardaremos el tipo de oración + // Declaramos una variable en la que guardaremos el tipo de oración let sentenceType; - // Predicado que verifica el final del texto - // Si termina con el símbolo '?', devuelve true, - // de lo contrario, devuelve false + // Un predicado que comprueba el final del texto + // Si termina con el carácter '?', devuelve true, + // de lo contrario false if (sentence.endsWith('?')) { - // Si la condición anterior se cumple, + // Si la condición anterior se cumplió, // entonces es una oración interrogativa. // Asignamos a sentenceType el valor correspondiente. sentenceType = 'Question'; } else { - // En todos los demás casos, la oración es general + // En todos los demás casos la oración es ordinaria sentenceType = 'General'; } - // Usando interpolación, formamos la cadena + // Mediante la interpolación construimos una cadena return `${sentenceType} sentence`; }; ``` + Agregamos la palabra clave `else` y un nuevo bloque con llaves. Este bloque se ejecuta solo si la condición en `if` es falsa. + + ```text + ┌───────────┐ + │ condición?│ + └─────┬─────┘ + true │ │ false + ↓ ↓ + ┌──────────┐ ┌──────────┐ + │ cuerpo if│ │cuerpo else│ + └──────────┘ └──────────┘ + ``` + + ## Condiciones anidadas + + Dentro del bloque `else` (al igual que dentro del bloque `if`) se pueden anidar otras condiciones. Gracias a las llaves, el anidamiento siempre es visible de forma explícita: + + ```javascript + const number = 10; + + if (number > 10) { + console.log('Number is greater than 10'); + } else { + if (number === 10) { + console.log('Number is exactly 10'); + } else { + console.log('Number is less than 10'); + } + } + // => Number is exactly 10 + ``` - Hemos agregado la palabra clave `else` y un nuevo bloque con llaves. Este bloque se ejecutará solo si la condición en `if` es falsa. + Aquí primero se comprueba `number > 10`. La condición es falsa, por lo que el control pasa a `else`, donde se comprueba la condición anidada `number === 10`. Es verdadera — se imprime `Number is exactly 10`. - Hay dos formas de estructurar la construcción *if-else*. Usando la negación, se puede cambiar el orden de los bloques: + Existen dos maneras de organizar la construcción *if-else*. Mediante la negación se puede cambiar el orden de los bloques: ```javascript const getTypeOfSentence = (sentence) => { let sentenceType; - // Se agregó la negación + // Se agregó una negación // El contenido de else se movió a if y viceversa if (!sentence.endsWith('?')) { sentenceType = 'General'; @@ -54,27 +84,21 @@ theory: | }; ``` - ¿Cuál es el método preferido? El cerebro humano tiende a pensar de manera directa y no a través de negaciones. Trate de elegir una condición que no contenga negaciones y ajuste el contenido de los bloques en consecuencia. - + ¿Qué manera es preferible? Al cerebro humano le resulta más fácil pensar de forma directa, no a través de la negación. Procura elegir una comprobación que no contenga negaciones y ajusta el contenido de los bloques a ella. instructions: | + Escribe una función `normalizeUrl(url)` que recibe una cadena con la dirección de un sitio web y devuelve una URL con el protocolo `https://`. - Implementa la función `normalizeUrl()`, que realiza lo que se conoce como normalización de datos. Recibe una dirección de un sitio web y devuelve la misma con *https://* al principio. - - La función acepta direcciones en forma de *DIRECCIÓN* o *https://DIRECCIÓN*, pero siempre devuelve la dirección en forma de *https://DIRECCIÓN*. - - Puedes usar el método [startsWith()](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/String/startsWith) para verificar si una cadena comienza con el prefijo *https://*. Luego, en base a eso, agregar o no agregar *https://*. - - Ejemplos de llamadas: + Si la cadena ya comienza con `https://` — devuélvela tal cual. Si no comienza con él — agrega `https://` al principio. ```javascript - normalizeUrl("google.com"); // "https://google.com" - normalizeUrl("https://ai.fi"); // "https://ai.fi" + normalizeUrl('https://hexlet.io'); // => 'https://hexlet.io' + normalizeUrl('hexlet.io'); // => 'https://hexlet.io' ``` - tips: - | - [if...else](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Sentencias/if...else) - + [if...else](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/if...else) definitions: - - name: "else" - description: "forma de especificar un bloque de código que se ejecutará si la condición del `if` no se cumple" + - name: else + description: >- + una forma de definir un bloque de código que se ejecutará si la condición + con `if` no se cumple diff --git a/modules/48-conditionals/40-if-else/en/EXERCISE.md b/modules/48-conditionals/40-if-else/en/EXERCISE.md index 6873ec17..834f18d3 100644 --- a/modules/48-conditionals/40-if-else/en/EXERCISE.md +++ b/modules/48-conditionals/40-if-else/en/EXERCISE.md @@ -1,13 +1,8 @@ +Write a function `normalizeUrl(url)` that takes a string with a website address and returns a URL with the `https://` protocol. -Write the `normalizeUrl()` function that carries out so-called data normalization. It takes a site address and returns it with *https://* at the beginning. - -The function accepts URLs both as *URL* or *https://URL*, but will always return it as *https://URL* - -You can use a method, [startsWith()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith), to check if the string starts with the prefix *https://*. And then add or don't add *https://* accordingly. - -Examples: +If the string already starts with `https://` — return it as is. If it does not start with it — add `https://` at the beginning. ```javascript -normalizeUrl("google.com"); // "https://google.com" -normalizeUrl("https://ai.fi"); // "https://ai.fi" +normalizeUrl('https://hexlet.io'); // => 'https://hexlet.io' +normalizeUrl('hexlet.io'); // => 'https://hexlet.io' ``` diff --git a/modules/48-conditionals/40-if-else/en/README.md b/modules/48-conditionals/40-if-else/en/README.md index 9641ec03..615a7b74 100644 --- a/modules/48-conditionals/40-if-else/en/README.md +++ b/modules/48-conditionals/40-if-else/en/README.md @@ -1,44 +1,76 @@ -Let's write a function `getTypeOfSentence()` to analyze a piece of text and return its type: *General sentence* for normal sentences and *Question sentence* for questions. +Let's write a function `getTypeOfSentence()` that analyzes text and returns a description of its tone: for ordinary sentences – *General sentence*, for interrogative ones – *Question sentence*. ```javascript getTypeOfSentence('Hodor'); // General sentence getTypeOfSentence('Hodor?'); // Question sentence ``` -Implementation: +The function implementation: ```javascript const getTypeOfSentence = (sentence) => { // Declare a variable to store the sentence type let sentenceType; - // Predicate checking the text ending - // If it ends with '?', it will return true, - // otherwise, it'll return false + // A predicate that checks the end of the text + // If it ends with the '?' character, it returns true, + // otherwise false if (sentence.endsWith('?')) { - // If the condition above holds true, - // we have a question sentence. - // Assign an appropriate value to sentenceType + // If the condition above was met, + // then this is an interrogative sentence. + // Assign the corresponding value to sentenceType. sentenceType = 'Question'; } else { - // Otherwise, the sentenceType is 'General' + // In all other cases the sentence is a general one sentenceType = 'General'; } - // Build a string via interpolation + // Using interpolation we build a string return `${sentenceType} sentence`; }; ``` -We have added the keyword `else` and a new block with curly brackets. This block executes only if the condition in `if` is false. +We added the keyword `else` and a new block with curly braces. This block runs only if the condition in `if` is false. -There are two ways to design an *if-else* clause. The negation allows you to change the order of the blocks: +```text + ┌───────────┐ + │ condition?│ + └─────┬─────┘ + true │ │ false + ↓ ↓ +┌──────────┐ ┌──────────┐ +│ if body │ │ else body│ +└──────────┘ └──────────┘ +``` + +## Nested conditions + +Inside the `else` block (just like inside the `if` block) you can nest other conditions. Thanks to the curly braces, the nesting is always explicitly visible: + +```javascript +const number = 10; + +if (number > 10) { + console.log('Number is greater than 10'); +} else { + if (number === 10) { + console.log('Number is exactly 10'); + } else { + console.log('Number is less than 10'); + } +} +// => Number is exactly 10 +``` + +Here `number > 10` is checked first. The condition is false, so control passes to `else`, where the nested condition `number === 10` is checked. It is true — `Number is exactly 10` is printed. + +There are two ways to lay out an *if-else* construct. Using negation, you can swap the order of the blocks: ```javascript const getTypeOfSentence = (sentence) => { let sentenceType; - // Add negation - // The code blocks with the 'else' and 'if' statements are swapped + // A negation was added + // The contents of else moved to if and vice versa if (!sentence.endsWith('?')) { sentenceType = 'General'; } else { @@ -49,4 +81,4 @@ const getTypeOfSentence = (sentence) => { }; ``` -Which way is preferable? It is easier for the human brain to reason in a straightforward manner rather than via negation. Try to pick a test that has no negations, and then modify the contents of the code blocks to suit it. +Which way is preferable? The human brain finds it easier to think in a straightforward way rather than through negation. Try to choose a check that does not contain negations, and adjust the contents of the blocks to fit it. diff --git a/modules/48-conditionals/40-if-else/en/data.yml b/modules/48-conditionals/40-if-else/en/data.yml index a0bd6b5c..39b4c3f0 100644 --- a/modules/48-conditionals/40-if-else/en/data.yml +++ b/modules/48-conditionals/40-if-else/en/data.yml @@ -1,8 +1,10 @@ --- name: else -tips: [] +tips: + - > + [if...else](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else) definitions: - name: else description: >- - is a way to define a block of code that executes if the `if` condition is - not satisfied + a way to define a block of code that will be executed if the condition + with `if` is not satisfied diff --git a/modules/48-conditionals/40-if-else/es/EXERCISE.md b/modules/48-conditionals/40-if-else/es/EXERCISE.md index 5b190d91..34072859 100644 --- a/modules/48-conditionals/40-if-else/es/EXERCISE.md +++ b/modules/48-conditionals/40-if-else/es/EXERCISE.md @@ -1,13 +1,8 @@ +Escribe una función `normalizeUrl(url)` que recibe una cadena con la dirección de un sitio web y devuelve una URL con el protocolo `https://`. -Implementa la función `normalizeUrl()`, que realiza lo que se conoce como normalización de datos. Recibe una dirección de un sitio web y devuelve la misma con *https://* al principio. - -La función acepta direcciones en forma de *DIRECCIÓN* o *https://DIRECCIÓN*, pero siempre devuelve la dirección en forma de *https://DIRECCIÓN*. - -Puedes usar el método [startsWith()](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/String/startsWith) para verificar si una cadena comienza con el prefijo *https://*. Luego, en base a eso, agregar o no agregar *https://*. - -Ejemplos de llamadas: +Si la cadena ya comienza con `https://` — devuélvela tal cual. Si no comienza con él — agrega `https://` al principio. ```javascript -normalizeUrl("google.com"); // "https://google.com" -normalizeUrl("https://ai.fi"); // "https://ai.fi" +normalizeUrl('https://hexlet.io'); // => 'https://hexlet.io' +normalizeUrl('hexlet.io'); // => 'https://hexlet.io' ``` diff --git a/modules/48-conditionals/40-if-else/es/README.md b/modules/48-conditionals/40-if-else/es/README.md index b1f7c12e..3c411e8c 100644 --- a/modules/48-conditionals/40-if-else/es/README.md +++ b/modules/48-conditionals/40-if-else/es/README.md @@ -1,43 +1,75 @@ -Vamos a escribir la función `getTypeOfSentence()`, la cual analiza un texto y devuelve una descripción de su tono: para las oraciones normales - *General sentence*, para las preguntas - *Question sentence*. +Escribamos una función `getTypeOfSentence()` que analiza un texto y devuelve una descripción de su tono: para las oraciones ordinarias – *General sentence*, para las interrogativas – *Question sentence*. ```javascript getTypeOfSentence('Hodor'); // General sentence getTypeOfSentence('Hodor?'); // Question sentence ``` -Implementación de la función: +La implementación de la función: ```javascript const getTypeOfSentence = (sentence) => { - // Declaramos una variable donde guardaremos el tipo de oración + // Declaramos una variable en la que guardaremos el tipo de oración let sentenceType; - // Predicado que verifica el final del texto - // Si termina con el símbolo '?', devuelve true, - // de lo contrario, devuelve false + // Un predicado que comprueba el final del texto + // Si termina con el carácter '?', devuelve true, + // de lo contrario false if (sentence.endsWith('?')) { - // Si la condición anterior se cumple, + // Si la condición anterior se cumplió, // entonces es una oración interrogativa. // Asignamos a sentenceType el valor correspondiente. sentenceType = 'Question'; } else { - // En todos los demás casos, la oración es general + // En todos los demás casos la oración es ordinaria sentenceType = 'General'; } - // Usando interpolación, formamos la cadena + // Mediante la interpolación construimos una cadena return `${sentenceType} sentence`; }; ``` -Hemos agregado la palabra clave `else` y un nuevo bloque con llaves. Este bloque se ejecutará solo si la condición en `if` es falsa. +Agregamos la palabra clave `else` y un nuevo bloque con llaves. Este bloque se ejecuta solo si la condición en `if` es falsa. -Hay dos formas de estructurar la construcción *if-else*. Usando la negación, se puede cambiar el orden de los bloques: +```text + ┌───────────┐ + │ condición?│ + └─────┬─────┘ + true │ │ false + ↓ ↓ +┌──────────┐ ┌──────────┐ +│ cuerpo if│ │cuerpo else│ +└──────────┘ └──────────┘ +``` + +## Condiciones anidadas + +Dentro del bloque `else` (al igual que dentro del bloque `if`) se pueden anidar otras condiciones. Gracias a las llaves, el anidamiento siempre es visible de forma explícita: + +```javascript +const number = 10; + +if (number > 10) { + console.log('Number is greater than 10'); +} else { + if (number === 10) { + console.log('Number is exactly 10'); + } else { + console.log('Number is less than 10'); + } +} +// => Number is exactly 10 +``` + +Aquí primero se comprueba `number > 10`. La condición es falsa, por lo que el control pasa a `else`, donde se comprueba la condición anidada `number === 10`. Es verdadera — se imprime `Number is exactly 10`. + +Existen dos maneras de organizar la construcción *if-else*. Mediante la negación se puede cambiar el orden de los bloques: ```javascript const getTypeOfSentence = (sentence) => { let sentenceType; - // Se agregó la negación + // Se agregó una negación // El contenido de else se movió a if y viceversa if (!sentence.endsWith('?')) { sentenceType = 'General'; @@ -49,4 +81,4 @@ const getTypeOfSentence = (sentence) => { }; ``` -¿Cuál es el método preferido? El cerebro humano tiende a pensar de manera directa y no a través de negaciones. Trate de elegir una condición que no contenga negaciones y ajuste el contenido de los bloques en consecuencia. +¿Qué manera es preferible? Al cerebro humano le resulta más fácil pensar de forma directa, no a través de la negación. Procura elegir una comprobación que no contenga negaciones y ajusta el contenido de los bloques a ella. diff --git a/modules/48-conditionals/40-if-else/es/data.yml b/modules/48-conditionals/40-if-else/es/data.yml index ec271dea..c17ef246 100644 --- a/modules/48-conditionals/40-if-else/es/data.yml +++ b/modules/48-conditionals/40-if-else/es/data.yml @@ -2,9 +2,9 @@ name: else tips: - > - [if...else](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Sentencias/if...else) + [if...else](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/if...else) definitions: - name: else description: >- - forma de especificar un bloque de código que se ejecutará si la condición - del `if` no se cumple + una forma de definir un bloque de código que se ejecutará si la condición + con `if` no se cumple diff --git a/modules/48-conditionals/50-else-if/description.es.yml b/modules/48-conditionals/50-else-if/description.es.yml index 2f5c922d..faa9b538 100644 --- a/modules/48-conditionals/50-else-if/description.es.yml +++ b/modules/48-conditionals/50-else-if/description.es.yml @@ -1,9 +1,9 @@ --- -name: Estructura else if +name: La construcción else if theory: | - La función `getTypeOfSentence()` del ejercicio anterior sólo distingue entre oraciones interrogativas y oraciones normales. Intentemos agregar soporte para oraciones exclamativas: + La función `getTypeOfSentence()` de la lección anterior distingue solo entre preguntas y oraciones normales. Intentemos agregar soporte para oraciones exclamativas: ```javascript const getTypeOfSentence = (sentence) => { @@ -28,13 +28,12 @@ theory: | getTypeOfSentence('No!'); // Sentence is exclamation ``` + Agregamos una comprobación más. Técnicamente la función funciona, pero desde el punto de vista de la semántica hay problemas. - Hemos agregado otra verificación ("exclamation" se traduce como «exclamación»). Técnicamente, la función funciona, pero hay problemas desde el punto de vista semántico. + - La comprobación del signo de interrogación se ejecuta en cualquier caso, incluso si ya se detectó un signo de exclamación. + - La rama `else` está descrita solo para la primera condición, pero no para la segunda. - - La verificación de la presencia del signo de interrogación ocurre de todos modos, incluso si ya se ha detectado el signo de exclamación. - - La rama `else` está descrita sólo para la primera condición, pero no para la segunda. - - Sería más correcto utilizar otra posibilidad de la estructura condicional: + Será más correcto usar una posibilidad más de la construcción condicional: ```javascript const getTypeOfSentence = (sentence) => { @@ -57,39 +56,49 @@ theory: | getTypeOfSentence('No!'); // Sentence is exclamation ``` - Ahora todas las condiciones están organizadas en una única estructura. `else if` significa "si la condición anterior no se cumple, pero la actual sí". La estructura es la siguiente: + Ahora todas las condiciones están organizadas en una única construcción. `else if` significa "si no se cumplió la condición anterior, pero se cumple la actual". + + ```text + ┌─────────────────┐ + │ ¿condición 1? │ + └────┬────────┬───┘ + true │ │ false + ↓ ↓ + ┌──────────┐ ┌─────────────────┐ + │ cuerpo if│ │ ¿condición 2? │ + └──────────┘ └────┬────────┬───┘ + true │ │ false + ↓ ↓ + ┌────────────────┐ ┌──────────────┐ + │ cuerpo else if │ │ cuerpo else │ + └────────────────┘ └──────────────┘ + ``` + + La lógica de la función resulta en el siguiente esquema: - si el último carácter es `?`, entonces `'question'` - de lo contrario, si el último carácter es `!`, entonces `'exclamation'` - - de lo contrario, `'normal'` - - Sólo se ejecutará uno de los bloques de código relacionados con toda la estructura `if`. + - de lo contrario `'normal'` + Se ejecutará solo uno de los bloques de código que pertenecen a toda la construcción `if`. instructions: | - En el mapa electrónico de Westeros que Sam implementó, los aliados de los Stark se representan con un círculo verde, los enemigos con un círculo rojo y las familias neutrales con un círculo gris. - - Escribe una función para Sam llamada `whoIsThisHouseToStarks()` que reciba el apellido de una familia y devuelva uno de los tres valores: `'friend'`, `'enemy'`, `'neutral'`. + Implementa la función `getTrafficLightAction(color)`, que recibe un color de semáforo y devuelve lo que debe hacer el conductor: - Reglas de determinación: - - * Amigos (`'friend'`): 'Karstark', 'Tally' - * Enemigos (`'enemy'`): 'Lannister', 'Frey' - * Todas las demás familias se consideran neutrales - - Ejemplos de llamadas: + - `'green'` → `'go'` + - `'yellow'` → `'slow down'` + - `'red'` → `'stop'` + - cualquier otro color → `'unknown'` ```javascript - whoIsThisHouseToStarks('Karstark'); // amigo - whoIsThisHouseToStarks('Frey'); // enemigo - whoIsThisHouseToStarks('Joar'); // neutral - whoIsThisHouseToStarks('Ivanov'); // neutral + getTrafficLightAction('green'); // => 'go' + getTrafficLightAction('red'); // => 'stop' + getTrafficLightAction('purple'); // => 'unknown' ``` - tips: - | - [else if](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/if...else#usando_else_if) - + [else + if](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/if...else#usando_else_if) definitions: - - name: "else if" - description: "forma de establecer múltiples condiciones alternativas." + - name: else if + description: una forma de especificar varias condiciones alternativas. diff --git a/modules/48-conditionals/50-else-if/en/EXERCISE.md b/modules/48-conditionals/50-else-if/en/EXERCISE.md index 7f85cc67..a0163e91 100644 --- a/modules/48-conditionals/50-else-if/en/EXERCISE.md +++ b/modules/48-conditionals/50-else-if/en/EXERCISE.md @@ -1,19 +1,12 @@ +Implement the `getTrafficLightAction(color)` function, which takes a traffic light color and returns what the driver should do: -The digital map of Westeros that Sam has made shows Stark allies in green, enemies in red, and neutral families in gray. - -Write the `whoIsThisHouseToStarks()` function that takes a family name as input and returns one of three values: `'friend'`, `'enemy'`, `'neutral'`. - -Rules: - -* Friends: 'Karstark', 'Tally' -* Enemies: 'Lannister', 'Frey' -* Any other families are considered neutral - -Examples: +- `'green'` → `'go'` +- `'yellow'` → `'slow down'` +- `'red'` → `'stop'` +- any other color → `'unknown'` ```javascript -whoIsThisHouseToStarks('Karstark'); // 'friend' -whoIsThisHouseToStarks('Frey'); // 'enemy' -whoIsThisHouseToStarks('Joar'); // 'neutral' -whoIsThisHouseToStarks('Ivanov'); // 'neutral' +getTrafficLightAction('green'); // => 'go' +getTrafficLightAction('red'); // => 'stop' +getTrafficLightAction('purple'); // => 'unknown' ``` diff --git a/modules/48-conditionals/50-else-if/en/README.md b/modules/48-conditionals/50-else-if/en/README.md index ebbae063..5b451b76 100644 --- a/modules/48-conditionals/50-else-if/en/README.md +++ b/modules/48-conditionals/50-else-if/en/README.md @@ -1,5 +1,5 @@ -The `getTypeOfSentence()` function from the previous lesson only distinguishes between questions and normal sentences. Let's try to extend it to exclamation sentences: +The `getTypeOfSentence()` function from the previous lesson distinguishes only between questions and regular sentences. Let's try to add support for exclamatory sentences: ```javascript const getTypeOfSentence = (sentence) => { @@ -19,17 +19,17 @@ const getTypeOfSentence = (sentence) => { return `Sentence is ${sentenceType}`; }; -getTypeOfSentence('Who?'); // 'Sentence is question' -getTypeOfSentence('No'); // 'Sentence is normal' -getTypeOfSentence('No!'); // 'Sentence is exclamation' +getTypeOfSentence('Who?'); // Sentence is question +getTypeOfSentence('No'); // Sentence is normal +getTypeOfSentence('No!'); // Sentence is exclamation ``` -We added one more test. Technically the function works, but there are semantics issues. +We added one more check. Technically the function works, but from a semantics standpoint there are problems. -- It tests for the question mark in any case, regardless of whether an exclamation point was found or not -- The `else` branch is defined for the first condition, not for the second +- The check for a question mark runs in any case, even if an exclamation mark has already been detected. +- The `else` branch is described for the first condition only, but not for the second. -It would be better to use another condition feature: +It would be more correct to use one more feature of the conditional construct: ```javascript const getTypeOfSentence = (sentence) => { @@ -47,15 +47,33 @@ const getTypeOfSentence = (sentence) => { return `Sentence is ${sentenceType}`; }; -getTypeOfSentence('Who?'); // 'Sentence is question' -getTypeOfSentence('No'); // 'Sentence is normal' -getTypeOfSentence('No!'); // 'Sentence is exclamation' +getTypeOfSentence('Who?'); // Sentence is question +getTypeOfSentence('No'); // Sentence is normal +getTypeOfSentence('No!'); // Sentence is exclamation ``` -Now all the conditions are framed in a single construction. `else if` means "if the previous condition is not satisfied, but this condition is". This is the scenario we get: +Now all conditions are arranged into a single construct. `else if` means "if the previous condition was not met, but the current one is". + +```text + ┌─────────────────┐ + │ condition 1? │ + └────┬────────┬───┘ + true │ │ false + ↓ ↓ +┌──────────┐ ┌─────────────────┐ +│ if body │ │ condition 2? │ +└──────────┘ └────┬────────┬───┘ + true │ │ false + ↓ ↓ + ┌──────────────┐ ┌────────────┐ + │ else if body │ │ else body │ + └──────────────┘ └────────────┘ +``` + +The function logic results in the following scheme: -- if the last character is `?`, then it's a `'question'` -- else, if the last character is `!`, then it's an `'exclamation'` -- else it's `'normal'` +- if the last character is `?`, then `'question'` +- otherwise, if the last character is `!`, then `'exclamation'` +- otherwise `'normal'` -Only one of the code blocks belonging to the entire `if` construct will be executed. +Only one of the code blocks belonging to the whole `if` construct will be executed. diff --git a/modules/48-conditionals/50-else-if/en/data.yml b/modules/48-conditionals/50-else-if/en/data.yml index a8f22638..e13f56d7 100644 --- a/modules/48-conditionals/50-else-if/en/data.yml +++ b/modules/48-conditionals/50-else-if/en/data.yml @@ -1,6 +1,9 @@ --- -name: else if statement -tips: [] +name: The else if construct +tips: + - > + [else + if](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else#using_else_if) definitions: - name: else if - description: is a way to set multiple alternate conditions + description: a way to specify several alternative conditions. diff --git a/modules/48-conditionals/50-else-if/es/EXERCISE.md b/modules/48-conditionals/50-else-if/es/EXERCISE.md index cd8fcfca..d9f38e51 100644 --- a/modules/48-conditionals/50-else-if/es/EXERCISE.md +++ b/modules/48-conditionals/50-else-if/es/EXERCISE.md @@ -1,19 +1,12 @@ +Implementa la función `getTrafficLightAction(color)`, que recibe un color de semáforo y devuelve lo que debe hacer el conductor: -En el mapa electrónico de Westeros que Sam implementó, los aliados de los Stark se representan con un círculo verde, los enemigos con un círculo rojo y las familias neutrales con un círculo gris. - -Escribe una función para Sam llamada `whoIsThisHouseToStarks()` que reciba el apellido de una familia y devuelva uno de los tres valores: `'friend'`, `'enemy'`, `'neutral'`. - -Reglas de determinación: - -* Amigos (`'friend'`): 'Karstark', 'Tally' -* Enemigos (`'enemy'`): 'Lannister', 'Frey' -* Todas las demás familias se consideran neutrales - -Ejemplos de llamadas: +- `'green'` → `'go'` +- `'yellow'` → `'slow down'` +- `'red'` → `'stop'` +- cualquier otro color → `'unknown'` ```javascript -whoIsThisHouseToStarks('Karstark'); // amigo -whoIsThisHouseToStarks('Frey'); // enemigo -whoIsThisHouseToStarks('Joar'); // neutral -whoIsThisHouseToStarks('Ivanov'); // neutral +getTrafficLightAction('green'); // => 'go' +getTrafficLightAction('red'); // => 'stop' +getTrafficLightAction('purple'); // => 'unknown' ``` diff --git a/modules/48-conditionals/50-else-if/es/README.md b/modules/48-conditionals/50-else-if/es/README.md index 05dda50a..bd71dfbe 100644 --- a/modules/48-conditionals/50-else-if/es/README.md +++ b/modules/48-conditionals/50-else-if/es/README.md @@ -1,5 +1,5 @@ -La función `getTypeOfSentence()` del ejercicio anterior sólo distingue entre oraciones interrogativas y oraciones normales. Intentemos agregar soporte para oraciones exclamativas: +La función `getTypeOfSentence()` de la lección anterior distingue solo entre preguntas y oraciones normales. Intentemos agregar soporte para oraciones exclamativas: ```javascript const getTypeOfSentence = (sentence) => { @@ -24,12 +24,12 @@ getTypeOfSentence('No'); // Sentence is normal getTypeOfSentence('No!'); // Sentence is exclamation ``` -Hemos agregado otra verificación ("exclamation" se traduce como «exclamación»). Técnicamente, la función funciona, pero hay problemas desde el punto de vista semántico. +Agregamos una comprobación más. Técnicamente la función funciona, pero desde el punto de vista de la semántica hay problemas. -- La verificación de la presencia del signo de interrogación ocurre de todos modos, incluso si ya se ha detectado el signo de exclamación. -- La rama `else` está descrita sólo para la primera condición, pero no para la segunda. +- La comprobación del signo de interrogación se ejecuta en cualquier caso, incluso si ya se detectó un signo de exclamación. +- La rama `else` está descrita solo para la primera condición, pero no para la segunda. -Sería más correcto utilizar otra posibilidad de la estructura condicional: +Será más correcto usar una posibilidad más de la construcción condicional: ```javascript const getTypeOfSentence = (sentence) => { @@ -52,10 +52,28 @@ getTypeOfSentence('No'); // Sentence is normal getTypeOfSentence('No!'); // Sentence is exclamation ``` -Ahora todas las condiciones están organizadas en una única estructura. `else if` significa "si la condición anterior no se cumple, pero la actual sí". La estructura es la siguiente: +Ahora todas las condiciones están organizadas en una única construcción. `else if` significa "si no se cumplió la condición anterior, pero se cumple la actual". + +```text + ┌─────────────────┐ + │ ¿condición 1? │ + └────┬────────┬───┘ + true │ │ false + ↓ ↓ +┌──────────┐ ┌─────────────────┐ +│ cuerpo if│ │ ¿condición 2? │ +└──────────┘ └────┬────────┬───┘ + true │ │ false + ↓ ↓ + ┌────────────────┐ ┌──────────────┐ + │ cuerpo else if │ │ cuerpo else │ + └────────────────┘ └──────────────┘ +``` + +La lógica de la función resulta en el siguiente esquema: - si el último carácter es `?`, entonces `'question'` - de lo contrario, si el último carácter es `!`, entonces `'exclamation'` -- de lo contrario, `'normal'` +- de lo contrario `'normal'` -Sólo se ejecutará uno de los bloques de código relacionados con toda la estructura `if`. +Se ejecutará solo uno de los bloques de código que pertenecen a toda la construcción `if`. diff --git a/modules/48-conditionals/50-else-if/es/data.yml b/modules/48-conditionals/50-else-if/es/data.yml index 0d4bd444..141acd05 100644 --- a/modules/48-conditionals/50-else-if/es/data.yml +++ b/modules/48-conditionals/50-else-if/es/data.yml @@ -1,9 +1,9 @@ --- -name: Estructura else if +name: La construcción else if tips: - > [else if](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/if...else#usando_else_if) definitions: - name: else if - description: forma de establecer múltiples condiciones alternativas. + description: una forma de especificar varias condiciones alternativas. diff --git a/modules/48-conditionals/60-ternary-operator/description.es.yml b/modules/48-conditionals/60-ternary-operator/description.es.yml index 029ac317..7895edbf 100644 --- a/modules/48-conditionals/60-ternary-operator/description.es.yml +++ b/modules/48-conditionals/60-ternary-operator/description.es.yml @@ -2,8 +2,7 @@ name: Operador ternario theory: | - - Echa un vistazo a la definición de una función que devuelve el valor absoluto de un número: + Observa la definición de una función que devuelve el valor absoluto del número pasado: ```javascript const abs = (number) => { @@ -18,11 +17,11 @@ theory: | abs(-10); // 10 ``` - ¿Se puede escribir de forma más concisa? Algo como `return `? Para eso, a la derecha de `return` debe haber una expresión, pero `if` es una instrucción, no una expresión. + ¿Se puede escribir de forma más concisa? ¿Algo como `return `? Para eso, a la derecha de return debe haber una expresión, pero `if` es una instrucción, no una expresión. - En JavaScript existe una construcción que es similar a la estructura *if-else*, pero a la vez es una expresión. Se llama **operador ternario**. + En JavaScript existe una construcción que por su comportamiento es análoga a la construcción *if-else*, pero que a la vez es una expresión. Se llama **operador ternario**. - El operador ternario es único en su tipo, ya que requiere tres operandos: + El operador ternario es el único operador de su tipo que requiere tres operandos: ```javascript const abs = (number) => { @@ -40,7 +39,7 @@ theory: | Ten en cuenta los paréntesis alrededor del operador ternario. No son obligatorios, pero el linter [recomienda encarecidamente](https://eslint.org/docs/rules/no-confusing-arrow) usarlos para evitar ambigüedades. - Ahora reescribamos la función inicial `getTypeOfSentence()` de manera similar: + Ahora reescribamos la versión inicial de `getTypeOfSentence()` de manera similar: Antes: @@ -69,44 +68,21 @@ theory: | getTypeOfSentence('Hodor?'); // question ``` - --- - Si recuerdas el poder de las expresiones, probablemente ya te hayas dado cuenta de que se puede anidar un operador ternario dentro de otro. **No hagas esto :)**. Este tipo de código es difícil de leer y depurar, y es una mala práctica. - + Si recuerdas el poder de las expresiones, probablemente ya te hayas dado cuenta de que se puede anidar un operador ternario dentro de otro. **No hagas esto :)** Este tipo de código es difícil de leer y depurar, y es una muy mala práctica. instructions: | - - Implementa la función `convertText()`, que recibe una cadena de texto y, si la primera letra no está en mayúscula, devuelve la versión invertida de la cadena original. Si la primera letra está en mayúscula, la función devuelve la cadena sin cambios. Si se pasa una cadena vacía como argumento, la función debe devolver una cadena vacía. - - Ejemplos de uso: + Un botón en la aplicación funciona como un interruptor: cada pulsación cambia el estado al opuesto. Implementa la función `flipFlop(str)`: si la cadena es igual a `'flip'`, devuelve `'flop'`; en caso contrario, devuelve `'flip'`. ```javascript - convertText('Hello'); // Hello - convertText('hello'); // olleh - - // No olvides tener en cuenta la cadena vacía - convertText(''); // '' + flipFlop('flip'); // => 'flop' + flipFlop('flop'); // => 'flip' ``` - Puedes invertir una cadena utilizando la función `reverse()`. Debes pasar la cadena que deseas invertir como argumento: - - ```javascript - const result = reverse('Hello!'); - console.log(result); // => !olleH - ``` - - Hay diferentes enfoques para resolver este problema. Es posible que necesites el método [toUpperCase()](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) y la capacidad de obtener un carácter de una cadena (por ejemplo, `str[0]`). - - Intenta escribir dos versiones de la función: una con un if-else normal y otra con un operador ternario. - - ## Consejos - - * Piensa en qué verificación debes hacer primero: si la primera letra es mayúscula o si la cadena está vacía. ¿Qué es más importante? - + Usa el operador ternario. tips: - | - [Más información sobre el operador ternario](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) - + [Más sobre el operador ternario](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) definitions: - name: Operador ternario description: | diff --git a/modules/48-conditionals/60-ternary-operator/en/EXERCISE.md b/modules/48-conditionals/60-ternary-operator/en/EXERCISE.md index 00e2084e..e71680db 100644 --- a/modules/48-conditionals/60-ternary-operator/en/EXERCISE.md +++ b/modules/48-conditionals/60-ternary-operator/en/EXERCISE.md @@ -1,27 +1,8 @@ - -Write the `convertText()` function that takes a string as input, and if the first letter is not capitalized, returns a reversed version of that string. If the first letter is capitalized, it returns the string unchanged. If the input is an empty string, the function must return an empty string. - -Examples: - -```javascript -convertText('Hello'); // 'Hello' -convertText('hello'); // 'olleh' - -// Be sure to take the empty line into account -convertText(''); // '' -``` - -You can reverse a string using the `reverse()` function. It takes a string we want to reverse as an argument: +A button in the application works as a toggle: each press switches the state to the opposite one. Implement the function `flipFlop(str)`: if the string equals `'flip'`, return `'flop'`; otherwise return `'flip'`. ```javascript -const result = reverse('Hello!'); -console.log(result); // => '!olleH' +flipFlop('flip'); // => 'flop' +flipFlop('flop'); // => 'flip' ``` -There are various approaches to solve this problem. You may want to use the [toUpperCase()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) method and feature that allows you to get a character from a string (for example, `str[0]`). - -Try to write two versions of the function: with the usual if-else, and with a ternary operator. - -## Tips - -* Consider the first condition you need to write. Is it a capitalization check or an empty line check? Which is primary? +Use the ternary operator. diff --git a/modules/48-conditionals/60-ternary-operator/en/README.md b/modules/48-conditionals/60-ternary-operator/en/README.md index c8de8423..3b82d015 100644 --- a/modules/48-conditionals/60-ternary-operator/en/README.md +++ b/modules/48-conditionals/60-ternary-operator/en/README.md @@ -1,5 +1,5 @@ -Look at the definition of this function, which returns the modulus of a given number: +Look at the definition of a function that returns the absolute value of the passed number: ```javascript const abs = (number) => { @@ -14,11 +14,11 @@ abs(10); // 10 abs(-10); // 10 ``` -Can we write it more concisely? Something like `return `? That would require an expression following return, but `if` is a statement, not an expression. +Can we write it more concisely? Something like `return `? For this, there must be an expression to the right of return, but `if` is a statement, not an expression. -We have a construct in JavaScript that works the same way as the *if-else* construct, except it's an expression. It's called the **ternary operator**. +In JavaScript there is a construct that behaves like the *if-else* construct but is itself an expression. It is called the **ternary operator**. -The ternary operator is the only JavaScript operator that takes three operands: +The ternary operator is the only operator of its kind that requires three operands: ```javascript const abs = (number) => { @@ -28,13 +28,13 @@ const abs = (number) => { The general pattern looks like this: ` ? : `. -Here is a shortened version of the `abs()` function: +The shortened version of the `abs()` function looks like this: ```javascript const abs = (number) => (number >= 0 ? number : -number); ``` -Note the parentheses around the ternary. They are optional, but linter [strongly recommends](https://eslint.org/docs/rules/no-confusing-arrow) to put them to avoid ambiguities. +Pay attention to the parentheses around the ternary. They are not required, but the linter [strongly recommends](https://eslint.org/docs/rules/no-confusing-arrow) using them to avoid ambiguities. Let's rewrite the initial version of `getTypeOfSentence()` in the same way: @@ -67,4 +67,4 @@ getTypeOfSentence('Hodor?'); // question --- -If you remember the main strength of expressions, then you probably figured out by now that you can put a ternary operator into a ternary operator. **Don't do it :)** Such code is hard both to read and to debug, it's very bad practice. +If you remember the power of expressions, you have probably already guessed that a ternary operator can be nested inside another ternary operator. **Don't do this :)** Such code is hard to both read and debug, and it is very bad practice. diff --git a/modules/48-conditionals/60-ternary-operator/en/data.yml b/modules/48-conditionals/60-ternary-operator/en/data.yml index a707c6af..d02efbff 100644 --- a/modules/48-conditionals/60-ternary-operator/en/data.yml +++ b/modules/48-conditionals/60-ternary-operator/en/data.yml @@ -1,8 +1,11 @@ --- name: Ternary operator -tips: [] +tips: + - > + [More about the ternary + operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) definitions: - name: Ternary operator description: > - is a way to convert a simple conditional statement into an expression, - e.g., `number >= 0 ? number : -number` + A way to turn a simple conditional statement into an expression, for + example, `number >= 0 ? number : -number`. diff --git a/modules/48-conditionals/60-ternary-operator/es/EXERCISE.md b/modules/48-conditionals/60-ternary-operator/es/EXERCISE.md index 7d21e14b..94720b5a 100644 --- a/modules/48-conditionals/60-ternary-operator/es/EXERCISE.md +++ b/modules/48-conditionals/60-ternary-operator/es/EXERCISE.md @@ -1,27 +1,8 @@ - -Implementa la función `convertText()`, que recibe una cadena de texto y, si la primera letra no está en mayúscula, devuelve la versión invertida de la cadena original. Si la primera letra está en mayúscula, la función devuelve la cadena sin cambios. Si se pasa una cadena vacía como argumento, la función debe devolver una cadena vacía. - -Ejemplos de uso: - -```javascript -convertText('Hello'); // Hello -convertText('hello'); // olleh - -// No olvides tener en cuenta la cadena vacía -convertText(''); // '' -``` - -Puedes invertir una cadena utilizando la función `reverse()`. Debes pasar la cadena que deseas invertir como argumento: +Un botón en la aplicación funciona como un interruptor: cada pulsación cambia el estado al opuesto. Implementa la función `flipFlop(str)`: si la cadena es igual a `'flip'`, devuelve `'flop'`; en caso contrario, devuelve `'flip'`. ```javascript -const result = reverse('Hello!'); -console.log(result); // => !olleH +flipFlop('flip'); // => 'flop' +flipFlop('flop'); // => 'flip' ``` -Hay diferentes enfoques para resolver este problema. Es posible que necesites el método [toUpperCase()](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) y la capacidad de obtener un carácter de una cadena (por ejemplo, `str[0]`). - -Intenta escribir dos versiones de la función: una con un if-else normal y otra con un operador ternario. - -## Consejos - -* Piensa en qué verificación debes hacer primero: si la primera letra es mayúscula o si la cadena está vacía. ¿Qué es más importante? +Usa el operador ternario. diff --git a/modules/48-conditionals/60-ternary-operator/es/README.md b/modules/48-conditionals/60-ternary-operator/es/README.md index 9b653ba6..4b815f4d 100644 --- a/modules/48-conditionals/60-ternary-operator/es/README.md +++ b/modules/48-conditionals/60-ternary-operator/es/README.md @@ -1,5 +1,5 @@ -Echa un vistazo a la definición de una función que devuelve el valor absoluto de un número: +Observa la definición de una función que devuelve el valor absoluto del número pasado: ```javascript const abs = (number) => { @@ -14,11 +14,11 @@ abs(10); // 10 abs(-10); // 10 ``` -¿Se puede escribir de forma más concisa? Algo como `return `? Para eso, a la derecha de `return` debe haber una expresión, pero `if` es una instrucción, no una expresión. +¿Se puede escribir de forma más concisa? ¿Algo como `return `? Para eso, a la derecha de return debe haber una expresión, pero `if` es una instrucción, no una expresión. -En JavaScript existe una construcción que es similar a la estructura *if-else*, pero a la vez es una expresión. Se llama **operador ternario**. +En JavaScript existe una construcción que por su comportamiento es análoga a la construcción *if-else*, pero que a la vez es una expresión. Se llama **operador ternario**. -El operador ternario es único en su tipo, ya que requiere tres operandos: +El operador ternario es el único operador de su tipo que requiere tres operandos: ```javascript const abs = (number) => { @@ -36,7 +36,7 @@ const abs = (number) => (number >= 0 ? number : -number); Ten en cuenta los paréntesis alrededor del operador ternario. No son obligatorios, pero el linter [recomienda encarecidamente](https://eslint.org/docs/rules/no-confusing-arrow) usarlos para evitar ambigüedades. -Ahora reescribamos la función inicial `getTypeOfSentence()` de manera similar: +Ahora reescribamos la versión inicial de `getTypeOfSentence()` de manera similar: Antes: @@ -67,4 +67,4 @@ getTypeOfSentence('Hodor?'); // question --- -Si recuerdas el poder de las expresiones, probablemente ya te hayas dado cuenta de que se puede anidar un operador ternario dentro de otro. **No hagas esto :)**. Este tipo de código es difícil de leer y depurar, y es una mala práctica. +Si recuerdas el poder de las expresiones, probablemente ya te hayas dado cuenta de que se puede anidar un operador ternario dentro de otro. **No hagas esto :)** Este tipo de código es difícil de leer y depurar, y es una muy mala práctica. diff --git a/modules/48-conditionals/60-ternary-operator/es/data.yml b/modules/48-conditionals/60-ternary-operator/es/data.yml index 80f892c9..fc760333 100644 --- a/modules/48-conditionals/60-ternary-operator/es/data.yml +++ b/modules/48-conditionals/60-ternary-operator/es/data.yml @@ -2,7 +2,7 @@ name: Operador ternario tips: - > - [Más información sobre el operador + [Más sobre el operador ternario](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) definitions: - name: Operador ternario diff --git a/modules/50-loops/10-while/description.es.yml b/modules/50-loops/10-while/description.es.yml index 24a53073..d28efcba 100644 --- a/modules/50-loops/10-while/description.es.yml +++ b/modules/50-loops/10-while/description.es.yml @@ -1,130 +1,108 @@ --- -name: Ciclo While +name: El bucle While theory: | + Además de las construcciones condicionales, la programación es imposible sin bucles. Este es un mecanismo especial que permite ejecutar cualquier acción varias veces. Casi todos los cálculos se basan en él, desde calcular la nota media de un grupo hasta procesar las solicitudes entrantes en los sitios web. - Los programas que escribimos se vuelven cada vez más complejos y extensos. Aunque todavía están muy lejos de ser programas reales, que pueden tener decenas, cientos e incluso millones de líneas de código, la complejidad actual puede ser desafiante para aquellos sin experiencia. A partir de esta lección, entraremos en uno de los temas básicos más desafiantes de la programación: los bucles. + Un bucle almacena una acción repetida en un solo lugar y la ejecuta de nuevo mientras la condición siga siendo verdadera. - Todas las aplicaciones de software cumplen propósitos muy prácticos. Ayudan a gestionar a los empleados, las finanzas y, en última instancia, entretienen al público. A pesar de las diferencias, todos estos programas ejecutan algoritmos incorporados en ellos, y estos algoritmos tienden a ser muy similares entre sí. ¿Qué es un algoritmo? Un algoritmo es una secuencia de pasos (instrucciones) que nos lleva a un resultado esperado. En teoría, esta descripción podría aplicarse a cualquier programa, pero generalmente se refiere a algo más específico. + ## Primer ejemplo - Imagina que tienes un libro y quieres encontrar una frase específica dentro de él. Conoces la frase, pero no sabes en qué página está. ¿Cómo encontrarías la página correcta? El enfoque más simple (aunque lento) sería revisar cada página secuencialmente hasta encontrarla. En el peor de los casos, tendrías que revisar todas las páginas, pero de todos modos obtendrías el resultado deseado. Esto es lo que se llama un algoritmo. Involucra verificaciones lógicas (¿encontraste la frase?) y la iteración a través de las páginas. Aunque el número de páginas que tendrías que revisar no se conoce de antemano, el proceso de revisión se realiza de la misma manera en cada iteración. Aquí es donde los bucles entran en juego. Cada repetición se llama una iteración. + Supongamos que un programa debe mostrar la cadena `'Hello!'` cinco veces. Para detener la repetición en el momento adecuado, el programa necesita una variable que almacene el número del paso actual. A esa variable se le suele llamar contador. - Supongamos que queremos escribir una función que muestre en pantalla todos los números del 1 al número especificado (usando un argumento): + En el ejemplo, el contador se llama `counter`. Antes del bucle es igual a `0`. Después de cada salida de la cadena, lo incrementamos en uno. ```javascript - printNumbers(3); - // => 1 - // => 2 - // => 3 + let counter = 0; + while (counter < 5) { + console.log('Hello!'); + counter = counter + 1; + } + + // => Hello! + // => Hello! + // => Hello! + // => Hello! + // => Hello! ``` - Esta función no puede implementarse utilizando los conceptos que hemos aprendido hasta ahora, ya que el número de impresiones no es conocido de antemano. Sin embargo, con los bucles esto no es un problema: + Después de `while`, la condición se escribe entre paréntesis, y el cuerpo del bucle entre llaves. Mientras `counter < 5`, se ejecuta el cuerpo del bucle. Después de ejecutar el cuerpo, el motor vuelve a la condición y la comprueba de nuevo. Cuando la condición se vuelve falsa (`false`), el programa sale del bucle y continúa ejecutando el resto del código. - ```javascript - const printNumbers = (lastNumber) => { - // i abreviatura de índice (número de serie) - // se usa por convención común en muchos idiomas - // como contador de bucle + Sin cambiar el contador, la condición nunca se volverá falsa, y el bucle se convertirá en un bucle **infinito**. Desde fuera, parece que el programa se ha colgado. - while (i <= lastNumber) { - console.log(i); - i = i + 1; - } - console.log('finished!'); - }; + ## Cómo funciona el bucle paso a paso - printNumbers(3); - ``` + Antes de la primera repetición, `counter` es igual a `0`. - ```text - 1 - 2 - 3 - finished! - ``` + **Paso 1.** Se comprueba la condición `counter < 5`. El valor `0` es menor que `5`, por lo que se ejecuta el cuerpo del bucle. Se muestra `Hello!` en la pantalla, y `counter` aumenta a `1`. + **Paso 2.** La condición se comprueba de nuevo. El valor `1` sigue siendo menor que `5`, por lo que el cuerpo del bucle se ejecuta una vez más. Se muestra `Hello!` en la pantalla otra vez, y `counter` aumenta a `2`. - En el código de la función, se utiliza un bucle `while`. Este bucle consta de tres elementos: + Esto continúa hasta que `counter` se vuelve igual a `5`. En la siguiente comprobación, la condición `counter < 5` será falsa, por lo que el bucle terminará. - * La palabra clave `while`. Aunque se parece a una llamada de función, no es lo mismo. - * El predicado. La condición especificada entre paréntesis después de `while`. Esta condición se evalúa y se verifica antes de ejecutar el cuerpo del bucle en cada iteración. - * El cuerpo del bucle. El bloque de código dentro de las llaves. Este bloque es similar a los bloques en las funciones. Cualquier constante o variable definida dentro de este bloque sólo es visible dentro de este bloque. + ```text + counter = 0 + ┌──→ counter < 5? + │ true │ + │ ↓ + │ console.log('Hello!') + │ counter = counter + 1 + └──────────┘ + false → salir del bucle + ``` - La estructura se lee así: "mientras la condición (predicado) `i <= lastNumber` sea verdadera, ejecutar lo que está en el cuerpo del bucle". Analicemos cómo funciona este código para la llamada `printNumbers(3)`: + ## El cuerpo del bucle y la continuación del programa + + El cuerpo del bucle incluye todo lo que está dentro de las llaves. El código posterior al bucle se ejecuta una vez: ```javascript - // Se inicializa i - let i = 1; - - // El predicado es verdadero, por lo que se ejecuta el cuerpo del bucle - while (1 <= 3) - // console.log(1); - // i = 1 + 1; - - // Se ha completado el cuerpo del bucle, por lo que se regresa al inicio - while (2 <= 3) - // console.log(2); - // i = 2 + 1; - - // Se ha completado el cuerpo del bucle, por lo que se regresa al inicio - while (3 <= 3) - // console.log(3); - // i = 3 + 1; - - // El predicado es falso, por lo que se sale del bucle - while (4 <= 3) - - // console.log('finished!'); - // En este punto, i es igual a 4, pero ya no lo necesitamos - // la función termina + let counter = 0; + while (counter < 2) { + console.log('Hello!'); + counter = counter + 1; + } + + console.log('End of loop'); ``` - Lo más importante en un bucle es asegurarse de que termine (es decir, salir del bucle). El proceso que impulsa el bucle debe detenerse eventualmente. La responsabilidad de detener el bucle recae completamente en el programador. Por lo general, esto se logra mediante la introducción de una variable llamada "contador de bucle". Inicialmente, el contador se establece en su valor inicial. Luego, en el predicado del bucle, se verifica si el contador ha alcanzado su valor máximo. Finalmente, el contador se actualiza en el cuerpo del bucle (por ejemplo, `i = i + 1`). + Aquí `console.log('Hello!')` y `counter = counter + 1` están dentro del bucle, mientras que `console.log('End of loop')` está fuera de él, por lo que se ejecuta una vez después de que el bucle termina. + + ## Un bucle dentro de una función - Aquí es donde los novatos suelen cometer errores. Por ejemplo, olvidar actualizar el contador o verificar incorrectamente el predicado puede provocar un bucle infinito. Esto significa que el bucle seguirá ejecutándose indefinidamente y el programa nunca se detendrá. En este caso, a menudo es necesario detener el programa manualmente (quien sabe, tal vez cuando las aplicaciones reales se bloquean, están atrapadas en un bucle infinito). + Ahora movamos el bucle a una función. Mostrará los números desde `1` hasta el valor pasado: ```javascript - const printNumbers = (lastNumber) => { + const printNumbers = (n) => { let i = 1; - - // Este bucle nunca se detendrá - // y siempre imprimirá el mismo valor - while (i <= lastNumber) { + while (i <= n) { console.log(i); + i = i + 1; } - console.log('finished!'); + console.log('Finished!'); }; - ``` - En algunos casos, los bucles infinitos pueden ser útiles. No discutiremos esos casos aquí, pero es bueno saber cómo se ve el código: - - ```javascript - while (true) { - // Hacer algo - } + printNumbers(3); + // => 1 + // => 2 + // => 3 + // => Finished! ``` - En resumen, ¿cuándo se necesitan bucles y cuándo se pueden evitar? No se puede evitar usar bucles cuando el algoritmo para resolver un problema requiere repetir ciertas acciones, como en el ejemplo del libro, y no se conoce de antemano cuántas operaciones se requerirán. + El bucle `while` muestra los números hasta que `i` se vuelve mayor que `n`. Después de eso, el programa sale del bucle y ejecuta `console.log('Finished!')`. + La condición y el cambio del contador dependen de la tarea. El contador se puede incrementar en `1`, en `2` o en `10` de una vez. Se puede disminuir si el bucle va de un valor mayor a uno menor. Lo principal es que la condición eventualmente se vuelva falsa, de lo contrario el bucle se ejecutará indefinidamente. instructions: | - - Modifica la función `printNumbers()` para que muestre los números en orden inverso. Para hacerlo, debes empezar desde el límite superior y disminuir el contador en lugar de aumentarlo en el cuerpo del bucle. + Escribe una función `printNumbers(initialNumber)` que reciba un número y muestre todos los números desde `initialNumber` hasta `1` inclusive, cada uno en su propia línea. ```javascript - printNumbers(4); + printNumbers(3); + // 3 + // 2 + // 1 ``` - - ```text - 4 - 3 - 2 - 1 - finished!``` - tips: - | - [Bucle while](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/while) - + [El bucle while](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/while) definitions: - - name: Ciclo While - description: una instrucción que permite repetir un bloque de código mientras se cumple una condición. + - name: El bucle While + description: una instrucción para repetir código mientras se cumple alguna condición. diff --git a/modules/50-loops/10-while/en/EXERCISE.md b/modules/50-loops/10-while/en/EXERCISE.md index b492b649..8db92fa6 100644 --- a/modules/50-loops/10-while/en/EXERCISE.md +++ b/modules/50-loops/10-while/en/EXERCISE.md @@ -1,13 +1,8 @@ - -Edit the `printNumbers()` function so that it prints the numbers in reverse order. To do this, go from the upper bound to the lower bound. In other words, you should initialize the counter with the maximum value, and in the loop body, you should iterate it backwards down to the lower limit. +Write a function `printNumbers(initialNumber)` that takes a number and prints all numbers from `initialNumber` down to `1` inclusive, each on its own line. ```javascript -printNumbers(4); +printNumbers(3); +// 3 +// 2 +// 1 ``` - -```text -4 -3 -2 -1 -finished!``` diff --git a/modules/50-loops/10-while/en/README.md b/modules/50-loops/10-while/en/README.md index b87c9e81..582bbb8a 100644 --- a/modules/50-loops/10-while/en/README.md +++ b/modules/50-loops/10-while/en/README.md @@ -1,105 +1,89 @@ +Besides conditional constructs, programming is impossible without loops. This is a special mechanism that lets you perform any action multiple times. Almost all computations are built on it — from calculating the average grade in a group to handling incoming requests on websites. -Our code is getting more and more complex and extensive. It's still quite far from real applications, which contain tens or hundreds of thousands (sometimes millions) of lines of code. However, our code is already complex enough to make inexperienced programmers feel a bit tense. Starting from this lesson, we're moving on to one of the most difficult basic topics in programming: loops. +A loop stores a repeated action in one place and runs it again while a condition remains true. -All applications serve very pragmatic purposes. They help to manage employees, finances, and entertain, after all. Despite the differences, all these programs contain and execute similar algorithms. What's that? An algorithm is a sequence of actions (statements) which lead us to an expected result. This description fits any program in general, but with algorithms, we usually mean something more specific. +## First example -Imagine that we have a book, and we want to find a particular phrase within it. We remember the phrase itself, but we don't know what page it is on. How do we find the right page? The easiest (and longest) way is to look through the pages one by one until we find the right one. In the worst case we have to look through all the pages, but we still get the result. This very process is called an algorithm. It includes a logical verification (if the phrase is found) and an exhaustive page search. The number of pages you will have to look through is unknown, but the process repeats itself from time to time in exactly the same way. This is why we need loops to perform repetitive actions. In this case, each repetition is called an iteration. +Suppose a program needs to print the string `'Hello!'` five times. To stop repeating at the right moment, the program needs a variable that holds the number of the current step. Such a variable is usually called a counter. -Let's say we want to write a function that prints all numbers between 1 and a given number (via arguments): +In the example, the counter is named `counter`. Before the loop it equals `0`. After each string output, we increase it by one. ```javascript -printNumbers(3); -// => 1 -// => 2 -// => 3 +let counter = 0; +while (counter < 5) { + console.log('Hello!'); + counter = counter + 1; +} + +// => Hello! +// => Hello! +// => Hello! +// => Hello! +// => Hello! ``` -You can't implement this function with the tools you've already learned, because the number of outputs isn't known beforehand. But with loops this won't be a problem: +After `while`, the condition is written in parentheses, and the loop body is in curly braces. While `counter < 5`, the loop body executes. After the body runs, the engine returns to the condition and checks it again. When the condition becomes false (`false`), the program exits the loop and continues executing the rest of the code. -```javascript -const printNumbers = (lastNumber) => { - // i means index - // it's widely accepted in many languages - // as a loop counter - let i = 1; +Without changing the counter, the condition will never become false, and the loop turns into an **infinite** one. From the outside, it looks as if the program has frozen. - while (i <= lastNumber) { - console.log(i); - i = i + 1; - } - console.log('finished!'); -}; +## How the loop works step by step -printNumbers(3); -``` +Before the first repetition, `counter` equals `0`. -```text -1 -2 -3 -finished! -``` +**Step 1.** The condition `counter < 5` is checked. The value `0` is less than `5`, so the loop body executes. `Hello!` is printed to the screen, and `counter` increases to `1`. -Here we use a `while` loop. It has three elements: +**Step 2.** The condition is checked again. The value `1` is still less than `5`, so the loop body executes once more. `Hello!` is printed to the screen again, and `counter` increases to `2`. -* The keyword here is `while`. It is not a function call, although it resembles it +This continues until `counter` becomes equal to `5`. On the next check, the condition `counter < 5` will be false, so the loop will finish. -* Predicate. A condition given in parentheses after `while`. This condition must be evaluated and tested before executing the loop body at each iteration +```text +counter = 0 +┌──→ counter < 5? +│ true │ +│ ↓ +│ console.log('Hello!') +│ counter = counter + 1 +└──────────┘ + false → exit the loop +``` -* Loop body. Block of code in curly braces. This block is equivalent to the block of code in functions. Anything that is defined inside this block (constants or variables) is visible only within this block +## Loop body and continuing the program -You can read it as follows: "as long as the condition (predicate) `i <= lastNumber` is true, execute the code from the body of the loop". Let's analyze how this code works for a function call `printNumbers(3)`: +The loop body includes everything inside the curly braces. The code after the loop runs once: ```javascript -// Initializing i -let i = 1; - -// Predicate is true, so execute loop body -while (1 <= 3) -// console.log(1); -// i = 1 + 1; - -// The loop body is executed, so we return to the beginning -while (2 <= 3) -// console.log(2); -// i = 2 + 1; - -// The loop body is executed, so we return to the beginning -while (3 <= 3) -// console.log(3); -// i = 3 + 1; - -// Predicate is false, so execution goes beyond loop -while (4 <= 3) - -// console.log('finished!'); -// On this step i is 4, but we don't need it anymore -// function terminates +let counter = 0; +while (counter < 2) { + console.log('Hello!'); + counter = counter + 1; +} + +console.log('End of loop'); ``` -The main purpose of a loop is to end (exit from a loop). The process which generates the loop must eventually stop. It's up to the programmer to stop it. Usually this comes down to introducing a variable called the "loop counter". The counter should first be initialized, that is, you must assign it an initial value. In our example, it's the statement `let i = 1`, which is executed before the loop. Then the loop condition checks to see if the counter has reached its limiting value. Finally, the counter changes its value to `i = i + 1`. +Here `console.log('Hello!')` and `counter = counter + 1` are inside the loop, while `console.log('End of loop')` is outside it, so it runs once after the loop finishes. -This is where beginners make the most mistakes. For example, accidentally forgetting to increment the counter or having an incorrect predicate check can lead to an infinite loop. In this case the loop works endlessly and the program never stops. We then have to end it forcibly (it may sometimes be the case that when real applications freeze, there is an infinite loop running inside them). +## A loop inside a function + +Now let's move the loop into a function. It will print the numbers from `1` up to the passed value: ```javascript -const printNumbers = (lastNumber) => { +const printNumbers = (n) => { let i = 1; - - // This loop never ends - // and it will always print the same value - while (i <= lastNumber) { + while (i <= n) { console.log(i); + i = i + 1; } - console.log('finished!'); + console.log('Finished!'); }; -``` -In some cases, infinite loops are useful. We won't deal with those cases here, but it's useful to see what it looks like: - -```javascript -while (true) { - // do something -} +printNumbers(3); +// => 1 +// => 2 +// => 3 +// => Finished! ``` -To sum up. When do we need loops, and when can we do without them? It is physically impossible to do without loops when a problem-solving algorithm requires actions to be repeated, as in the example with the book, and the number of these actions is unpredictable. +The `while` loop prints numbers until `i` becomes greater than `n`. After that, the program exits the loop and executes `console.log('Finished!')`. + +The condition and the change of the counter depend on the task. The counter can be increased by `1`, by `2`, or by `10` at once. It can be decreased if the loop goes from a larger value to a smaller one. The main thing is that the condition eventually becomes false, otherwise the loop will run forever. diff --git a/modules/50-loops/10-while/en/data.yml b/modules/50-loops/10-while/en/data.yml index 345a7d27..e76c8a9d 100644 --- a/modules/50-loops/10-while/en/data.yml +++ b/modules/50-loops/10-while/en/data.yml @@ -1,12 +1,8 @@ --- -name: While loop +name: The While Loop tips: - - > - [*while* - loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while) + - | + [The while loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while) definitions: - - name: | - *while* loop - description: >- - is a statement that repeatedly executes code as long as a given test - condition is true + - name: The While Loop + description: a statement for repeating code while some condition is satisfied. diff --git a/modules/50-loops/10-while/es/EXERCISE.md b/modules/50-loops/10-while/es/EXERCISE.md index fc08efa1..800df5d6 100644 --- a/modules/50-loops/10-while/es/EXERCISE.md +++ b/modules/50-loops/10-while/es/EXERCISE.md @@ -1,13 +1,8 @@ - -Modifica la función `printNumbers()` para que muestre los números en orden inverso. Para hacerlo, debes empezar desde el límite superior y disminuir el contador en lugar de aumentarlo en el cuerpo del bucle. +Escribe una función `printNumbers(initialNumber)` que reciba un número y muestre todos los números desde `initialNumber` hasta `1` inclusive, cada uno en su propia línea. ```javascript -printNumbers(4); +printNumbers(3); +// 3 +// 2 +// 1 ``` - -```text -4 -3 -2 -1 -finished!``` diff --git a/modules/50-loops/10-while/es/README.md b/modules/50-loops/10-while/es/README.md index c26afd49..da6aeeaf 100644 --- a/modules/50-loops/10-while/es/README.md +++ b/modules/50-loops/10-while/es/README.md @@ -1,102 +1,89 @@ +Además de las construcciones condicionales, la programación es imposible sin bucles. Este es un mecanismo especial que permite ejecutar cualquier acción varias veces. Casi todos los cálculos se basan en él, desde calcular la nota media de un grupo hasta procesar las solicitudes entrantes en los sitios web. -Los programas que escribimos se vuelven cada vez más complejos y extensos. Aunque todavía están muy lejos de ser programas reales, que pueden tener decenas, cientos e incluso millones de líneas de código, la complejidad actual puede ser desafiante para aquellos sin experiencia. A partir de esta lección, entraremos en uno de los temas básicos más desafiantes de la programación: los bucles. +Un bucle almacena una acción repetida en un solo lugar y la ejecuta de nuevo mientras la condición siga siendo verdadera. -Todas las aplicaciones de software cumplen propósitos muy prácticos. Ayudan a gestionar a los empleados, las finanzas y, en última instancia, entretienen al público. A pesar de las diferencias, todos estos programas ejecutan algoritmos incorporados en ellos, y estos algoritmos tienden a ser muy similares entre sí. ¿Qué es un algoritmo? Un algoritmo es una secuencia de pasos (instrucciones) que nos lleva a un resultado esperado. En teoría, esta descripción podría aplicarse a cualquier programa, pero generalmente se refiere a algo más específico. +## Primer ejemplo -Imagina que tienes un libro y quieres encontrar una frase específica dentro de él. Conoces la frase, pero no sabes en qué página está. ¿Cómo encontrarías la página correcta? El enfoque más simple (aunque lento) sería revisar cada página secuencialmente hasta encontrarla. En el peor de los casos, tendrías que revisar todas las páginas, pero de todos modos obtendrías el resultado deseado. Esto es lo que se llama un algoritmo. Involucra verificaciones lógicas (¿encontraste la frase?) y la iteración a través de las páginas. Aunque el número de páginas que tendrías que revisar no se conoce de antemano, el proceso de revisión se realiza de la misma manera en cada iteración. Aquí es donde los bucles entran en juego. Cada repetición se llama una iteración. +Supongamos que un programa debe mostrar la cadena `'Hello!'` cinco veces. Para detener la repetición en el momento adecuado, el programa necesita una variable que almacene el número del paso actual. A esa variable se le suele llamar contador. -Supongamos que queremos escribir una función que muestre en pantalla todos los números del 1 al número especificado (usando un argumento): +En el ejemplo, el contador se llama `counter`. Antes del bucle es igual a `0`. Después de cada salida de la cadena, lo incrementamos en uno. ```javascript -printNumbers(3); -// => 1 -// => 2 -// => 3 +let counter = 0; +while (counter < 5) { + console.log('Hello!'); + counter = counter + 1; +} + +// => Hello! +// => Hello! +// => Hello! +// => Hello! +// => Hello! ``` -Esta función no puede implementarse utilizando los conceptos que hemos aprendido hasta ahora, ya que el número de impresiones no es conocido de antemano. Sin embargo, con los bucles esto no es un problema: +Después de `while`, la condición se escribe entre paréntesis, y el cuerpo del bucle entre llaves. Mientras `counter < 5`, se ejecuta el cuerpo del bucle. Después de ejecutar el cuerpo, el motor vuelve a la condición y la comprueba de nuevo. Cuando la condición se vuelve falsa (`false`), el programa sale del bucle y continúa ejecutando el resto del código. -```javascript -const printNumbers = (lastNumber) => { - // i abreviatura de índice (número de serie) - // se usa por convención común en muchos idiomas - // como contador de bucle +Sin cambiar el contador, la condición nunca se volverá falsa, y el bucle se convertirá en un bucle **infinito**. Desde fuera, parece que el programa se ha colgado. - while (i <= lastNumber) { - console.log(i); - i = i + 1; - } - console.log('finished!'); -}; +## Cómo funciona el bucle paso a paso -printNumbers(3); -``` +Antes de la primera repetición, `counter` es igual a `0`. + +**Paso 1.** Se comprueba la condición `counter < 5`. El valor `0` es menor que `5`, por lo que se ejecuta el cuerpo del bucle. Se muestra `Hello!` en la pantalla, y `counter` aumenta a `1`. + +**Paso 2.** La condición se comprueba de nuevo. El valor `1` sigue siendo menor que `5`, por lo que el cuerpo del bucle se ejecuta una vez más. Se muestra `Hello!` en la pantalla otra vez, y `counter` aumenta a `2`. + +Esto continúa hasta que `counter` se vuelve igual a `5`. En la siguiente comprobación, la condición `counter < 5` será falsa, por lo que el bucle terminará. ```text -1 -2 -3 -finished! +counter = 0 +┌──→ counter < 5? +│ true │ +│ ↓ +│ console.log('Hello!') +│ counter = counter + 1 +└──────────┘ + false → salir del bucle ``` -En el código de la función, se utiliza un bucle `while`. Este bucle consta de tres elementos: +## El cuerpo del bucle y la continuación del programa -* La palabra clave `while`. Aunque se parece a una llamada de función, no es lo mismo. -* El predicado. La condición especificada entre paréntesis después de `while`. Esta condición se evalúa y se verifica antes de ejecutar el cuerpo del bucle en cada iteración. -* El cuerpo del bucle. El bloque de código dentro de las llaves. Este bloque es similar a los bloques en las funciones. Cualquier constante o variable definida dentro de este bloque sólo es visible dentro de este bloque. - -La estructura se lee así: "mientras la condición (predicado) `i <= lastNumber` sea verdadera, ejecutar lo que está en el cuerpo del bucle". Analicemos cómo funciona este código para la llamada `printNumbers(3)`: +El cuerpo del bucle incluye todo lo que está dentro de las llaves. El código posterior al bucle se ejecuta una vez: ```javascript -// Se inicializa i -let i = 1; - -// El predicado es verdadero, por lo que se ejecuta el cuerpo del bucle -while (1 <= 3) -// console.log(1); -// i = 1 + 1; - -// Se ha completado el cuerpo del bucle, por lo que se regresa al inicio -while (2 <= 3) -// console.log(2); -// i = 2 + 1; - -// Se ha completado el cuerpo del bucle, por lo que se regresa al inicio -while (3 <= 3) -// console.log(3); -// i = 3 + 1; - -// El predicado es falso, por lo que se sale del bucle -while (4 <= 3) - -// console.log('finished!'); -// En este punto, i es igual a 4, pero ya no lo necesitamos -// la función termina +let counter = 0; +while (counter < 2) { + console.log('Hello!'); + counter = counter + 1; +} + +console.log('End of loop'); ``` -Lo más importante en un bucle es asegurarse de que termine (es decir, salir del bucle). El proceso que impulsa el bucle debe detenerse eventualmente. La responsabilidad de detener el bucle recae completamente en el programador. Por lo general, esto se logra mediante la introducción de una variable llamada "contador de bucle". Inicialmente, el contador se establece en su valor inicial. Luego, en el predicado del bucle, se verifica si el contador ha alcanzado su valor máximo. Finalmente, el contador se actualiza en el cuerpo del bucle (por ejemplo, `i = i + 1`). +Aquí `console.log('Hello!')` y `counter = counter + 1` están dentro del bucle, mientras que `console.log('End of loop')` está fuera de él, por lo que se ejecuta una vez después de que el bucle termina. + +## Un bucle dentro de una función -Aquí es donde los novatos suelen cometer errores. Por ejemplo, olvidar actualizar el contador o verificar incorrectamente el predicado puede provocar un bucle infinito. Esto significa que el bucle seguirá ejecutándose indefinidamente y el programa nunca se detendrá. En este caso, a menudo es necesario detener el programa manualmente (quien sabe, tal vez cuando las aplicaciones reales se bloquean, están atrapadas en un bucle infinito). +Ahora movamos el bucle a una función. Mostrará los números desde `1` hasta el valor pasado: ```javascript -const printNumbers = (lastNumber) => { +const printNumbers = (n) => { let i = 1; - - // Este bucle nunca se detendrá - // y siempre imprimirá el mismo valor - while (i <= lastNumber) { + while (i <= n) { console.log(i); + i = i + 1; } - console.log('finished!'); + console.log('Finished!'); }; -``` - -En algunos casos, los bucles infinitos pueden ser útiles. No discutiremos esos casos aquí, pero es bueno saber cómo se ve el código: -```javascript -while (true) { - // Hacer algo -} +printNumbers(3); +// => 1 +// => 2 +// => 3 +// => Finished! ``` -En resumen, ¿cuándo se necesitan bucles y cuándo se pueden evitar? No se puede evitar usar bucles cuando el algoritmo para resolver un problema requiere repetir ciertas acciones, como en el ejemplo del libro, y no se conoce de antemano cuántas operaciones se requerirán. +El bucle `while` muestra los números hasta que `i` se vuelve mayor que `n`. Después de eso, el programa sale del bucle y ejecuta `console.log('Finished!')`. + +La condición y el cambio del contador dependen de la tarea. El contador se puede incrementar en `1`, en `2` o en `10` de una vez. Se puede disminuir si el bucle va de un valor mayor a uno menor. Lo principal es que la condición eventualmente se vuelva falsa, de lo contrario el bucle se ejecutará indefinidamente. diff --git a/modules/50-loops/10-while/es/data.yml b/modules/50-loops/10-while/es/data.yml index 8f2ae913..b36b324a 100644 --- a/modules/50-loops/10-while/es/data.yml +++ b/modules/50-loops/10-while/es/data.yml @@ -1,11 +1,8 @@ --- -name: Ciclo While +name: El bucle While tips: - - > - [Bucle - while](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/while) + - | + [El bucle while](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/while) definitions: - - name: Ciclo While - description: >- - una instrucción que permite repetir un bloque de código mientras se cumple - una condición. + - name: El bucle While + description: una instrucción para repetir código mientras se cumple alguna condición. diff --git a/modules/50-loops/20-aggregation-numbers/description.es.yml b/modules/50-loops/20-aggregation-numbers/description.es.yml index 19248026..c445c832 100644 --- a/modules/50-loops/20-aggregation-numbers/description.es.yml +++ b/modules/50-loops/20-aggregation-numbers/description.es.yml @@ -45,7 +45,6 @@ theory: | }; ``` - La estructura general del bucle aquí es estándar. Hay un contador que se inicializa con el valor inicial del rango, luego viene el bucle con la condición de detenerse cuando se alcanza el final del rango, y finalmente, se cambia el contador al final del cuerpo del bucle. El número de iteraciones en este bucle es igual a `finish - start + 1`. Es decir, para un rango de 5 a 7, esto es 7 - 5 + 1, es decir, 3 iteraciones. Las principales diferencias con el procesamiento normal están relacionadas con la lógica de cálculo del resultado. En los problemas de agregación, siempre hay una variable que almacena el resultado del bucle. En el código anterior, esta variable es `sum`. En cada iteración del bucle, se actualiza sumando el siguiente número en el rango: `sum = sum + i`. Todo el proceso se ve así: @@ -83,21 +82,22 @@ theory: | El elemento neutro de la multiplicación es 1. - instructions: | - Implementa la función `multiplyNumbersFromRange()`, que multiplica los números en un rango especificado, incluyendo los límites del rango. Ejemplo de llamada: + Implementa la función `calculateElectricityBill()`, que recibe la cantidad de kilovatios-hora consumidos y devuelve el importe de la factura de electricidad. + + Se aplica una tarifa escalonada: los primeros `100` kWh cuestan `5` rublos cada uno, los siguientes `100` kWh cuestan `7` rublos cada uno, y todos los kWh por encima de `200` cuestan `10` rublos cada uno. + + Recorre el consumo con un bucle y acumula gradualmente el importe total. ```javascript - multiplyNumbersFromRange(1, 5); // 1 * 2 * 3 * 4 * 5 = 120 - multiplyNumbersFromRange(2, 3); // 2 * 3 = 6 - multiplyNumbersFromRange(6, 6); // 6 + calculateElectricityBill(80); // => 400 + calculateElectricityBill(150); // => 850 + calculateElectricityBill(250); // => 1700 ``` - tips: - | [Iteración](https://es.wikipedia.org/wiki/Iteración) - definitions: - name: Agregación - description: "Acumulación del resultado durante las iteraciones y trabajo con él después del bucle." + description: Acumulación del resultado durante las iteraciones y trabajo con él después del bucle. diff --git a/modules/50-loops/20-aggregation-numbers/en/EXERCISE.md b/modules/50-loops/20-aggregation-numbers/en/EXERCISE.md index 8d63b9f8..bff59785 100644 --- a/modules/50-loops/20-aggregation-numbers/en/EXERCISE.md +++ b/modules/50-loops/20-aggregation-numbers/en/EXERCISE.md @@ -1,8 +1,11 @@ +Implement the function `calculateElectricityBill()`, which takes the number of kilowatt-hours consumed and returns the amount of the electricity bill. -Write the `multiplyNumbersFromRange()` function that multiplies numbers in a given range, including its bounds. An example: +A tiered tariff is in effect: the first `100` kWh cost `5` rubles each, the next `100` kWh cost `7` rubles each, and all kWh above `200` cost `10` rubles each. + +Iterate over the consumption with a loop and gradually accumulate the total amount. ```javascript -multiplyNumbersFromRange(1, 5); // 1 * 2 * 3 * 4 * 5 = 120 -multiplyNumbersFromRange(2, 3); // 2 * 3 = 6 -multiplyNumbersFromRange(6, 6); // 6 +calculateElectricityBill(80); // => 400 +calculateElectricityBill(150); // => 850 +calculateElectricityBill(250); // => 1700 ``` diff --git a/modules/50-loops/20-aggregation-numbers/en/README.md b/modules/50-loops/20-aggregation-numbers/en/README.md index c66099dd..24d773fa 100644 --- a/modules/50-loops/20-aggregation-numbers/en/README.md +++ b/modules/50-loops/20-aggregation-numbers/en/README.md @@ -1,52 +1,52 @@ -One particular class of tasks that cannot be done without loops is data aggregation. These problems include searching for the maximum and minimum values, as well as finding sums and averages. Their main feature is that their result depends on the whole data set. Calculating the sum requires you to add **all** the numbers together, and calculating the maximum requires you to compare **all** the numbers. +A separate class of problems that cannot do without loops is called data aggregation. Such problems include finding the maximum, the minimum, the sum, the arithmetic mean, and so on. Their main feature is that the result depends on the entire data set. To calculate the sum, you need to add up **all** the numbers; to find the maximum, you need to compare **all** the numbers. -Anyone who deals with numbers, e.g., accountants or marketers, will be familiar with these tasks. It's usually done using spreadsheet software like Microsoft Excel or Google Tables. +Everyone who works with numbers is well familiar with such problems, for example, accountants or marketers. They are usually solved in spreadsheets like Microsoft Excel or Google Tables. -Let's consider a simple example: the sum of a set of numbers. We can implement a function to add numbers in a given range, including bounds. Here we have a range of numbers from a minimum value (lower bound) to a maximum (upper bound). For example, the range [1, 10] includes all integers from 1 to 10. +Let's look at the simplest example – finding the sum of a set of numbers. We will implement a function that adds up the numbers in a given range, including the boundaries. A range in this case is a series of numbers from some beginning to a certain end. For example, the range [1, 10] includes all integers from 1 to 10. ```javascript sumNumbersFromRange(5, 7); // 5 + 6 + 7 = 18 sumNumbersFromRange(1, 2); // 1 + 2 = 3 -// The range [1, 1] is also a range -// it includes just one number, the bound of the range itself +// [1, 1] a range with the same beginning and end is also a range +// it includes exactly one number – the boundary of the range itself sumNumbersFromRange(1, 1); // 1 sumNumbersFromRange(100, 100); // 100 ``` -To implement this function, we need a loop because adding numbers is an iterative process (an iteration for each number), and the number of iterations depends on the size of the range. Before looking at the code, try answering the questions below: +To implement this code, we will need a loop, since adding numbers is an iterative process (it repeats for each number), and the number of iterations depends on the size of the range. Before looking at the code, try to answer the questions below: -* Which value should you initialize the counter with? +* What value should the counter be initialized with? * How will it change? * When should the loop stop? -Try and think through these questions first and then take a look at the code below: +First try to think about these questions, and then look at the code below: ```javascript const sumNumbersFromRange = (start, finish) => { - // You can, of course, change the 'start' value - // But the input arguments must be left unchanged - // It makes the code easier to analyze + // Technically you can change start + // But the input arguments should be left at their original value + // This makes the code easier to analyze let i = start; - let sum = 0; // Sum initialization + let sum = 0; // Initializing the sum - while (i <= finish) { // Move to the end of the range - sum = sum + i; // Calculate sum for each number - i = i + 1; // Go to the next number in the range + while (i <= finish) { // Moving to the end of the range + sum = sum + i; // Computing the sum for each number + i = i + 1; // Moving to the next number in the range } - // Return loop result + // Returning the resulting value return sum; }; ``` -The general structure of the loop here is standard. A counter initialized with a start value for the range, a loop with a condition to stop at the end of the range and, finally, a counter change at the end of the loop. The number of iterations in this type of loop is `finish - start + 1`. Thus, for the range from 5 to 7, it is 7 - 5 + 1, or three iterations. +The general structure of the loop here is standard. There is a counter that is initialized with the starting value of the range, there is the loop itself with a stop condition when the end of the range is reached, and, finally, the change of the counter at the end of the loop body. The number of iterations in such a loop is equal to `finish - start + 1`. That is, for the range from 5 to 7 it is 7 - 5 + 1, which is 3 iterations. -The main difference from regular processing is related to the logic of computing the result. In aggregation tasks, there is always a variable that stores the result of the loop. In the code above, it is `sum`. With each loop iteration, this variable changes, adding another number from the range: `sum = sum + i`. The whole process looks like this: +The main differences from ordinary processing are related to the logic of computing the result. In aggregation problems, there is always some variable that stores the result of the loop's work inside itself. In the code above this is `sum`. On each iteration of the loop it changes, adding the next number in the range: `sum = sum + i`. The whole process looks like this: ```javascript -// Calling sumNumbersFromRange(2, 5); +// For the call sumNumbersFromRange(2, 5); let sum = 0; sum = sum + 2; // 2 sum = sum + 3; // 5 @@ -55,19 +55,26 @@ sum = sum + 5; // 14 // 14 – the result of adding the numbers in the range [2, 5] ``` -The `sum` variable has an initial value of 0. Why do you need to set the value at all? Any iterative operation starts with a value. You can't just declare an empty variable and start working with it within a loop. It will lead to an incorrect result: +The variable `sum` has an initial value equal to 0. Why set a value at all? Any repeating operation starts with some value. You cannot just declare a variable and start working with it inside a loop. This will lead to an incorrect result: ```javascript -// when there is no initial value -// js sets it to undefined +// the initial value is not set +// js automatically makes it equal to undefined let sum; -// first iteration +// the first iteration of the loop sum = sum + 2; // ? ``` -It will result in `NaN`, i.e. not a number, in `sum`. It occurs due to an attempt to add `2` and `undefined`. So you need to have an initial value. Why is 0 chosen in the code above? Well, it is easy to check that all the other options would lead to the wrong result. If the initial value is 1, the sum will be 1 more than it should be. +As a result of such a call, `sum` will contain `NaN`, that is, not a number. It arises from an attempt to add `2` and `undefined`. So some value is still needed. Why was 0 chosen in the code above? It is very easy to verify that all other options will lead to an incorrect result. If the initial value is equal to 1, then the result will be 1 more than needed. -In mathematics, there is a concept of an **identity element/neutral element**, an element for each type of operation. Its meaning is easy to grasp. An operation with this element doesn't change the operand. In addition, any number plus zero results in the number itself. The same goes for subtraction. Even concatenation has a neutral element, which is an empty string: `'' + 'one'` will be 'one'. +In mathematics there is the concept of a **neutral element of an operation** (each operation has its own element). This concept has a very simple meaning. An operation with this element does not change the value on which the operation is performed. In addition, any number plus zero gives the number itself. With subtraction it is the same. Even concatenation has a neutral element – it is the empty string: `'' + 'one'` will be 'one'. -Self-check. What is the neutral element of a multiplication operation? +A self-check question. What is the neutral element of the multiplication operation? To answer this question, find the number that does not change any other numbers when multiplied by it. + +
+Answer + +The neutral element of multiplication is 1. + +
diff --git a/modules/50-loops/20-aggregation-numbers/en/data.yml b/modules/50-loops/20-aggregation-numbers/en/data.yml index 86afd019..d0e47ea5 100644 --- a/modules/50-loops/20-aggregation-numbers/en/data.yml +++ b/modules/50-loops/20-aggregation-numbers/en/data.yml @@ -1,3 +1,8 @@ --- -name: Data aggregation (numbers) -tips: [] +name: Data Aggregation (Numbers) +tips: + - | + [Iteration](https://en.wikipedia.org/wiki/Iteration) +definitions: + - name: Aggregation + description: Accumulating a result during iterations and working with it after the loop. diff --git a/modules/50-loops/20-aggregation-numbers/es/EXERCISE.md b/modules/50-loops/20-aggregation-numbers/es/EXERCISE.md index f28a00fe..aaba7631 100644 --- a/modules/50-loops/20-aggregation-numbers/es/EXERCISE.md +++ b/modules/50-loops/20-aggregation-numbers/es/EXERCISE.md @@ -1,8 +1,11 @@ +Implementa la función `calculateElectricityBill()`, que recibe la cantidad de kilovatios-hora consumidos y devuelve el importe de la factura de electricidad. -Implementa la función `multiplyNumbersFromRange()`, que multiplica los números en un rango especificado, incluyendo los límites del rango. Ejemplo de llamada: +Se aplica una tarifa escalonada: los primeros `100` kWh cuestan `5` rublos cada uno, los siguientes `100` kWh cuestan `7` rublos cada uno, y todos los kWh por encima de `200` cuestan `10` rublos cada uno. + +Recorre el consumo con un bucle y acumula gradualmente el importe total. ```javascript -multiplyNumbersFromRange(1, 5); // 1 * 2 * 3 * 4 * 5 = 120 -multiplyNumbersFromRange(2, 3); // 2 * 3 = 6 -multiplyNumbersFromRange(6, 6); // 6 +calculateElectricityBill(80); // => 400 +calculateElectricityBill(150); // => 850 +calculateElectricityBill(250); // => 1700 ``` diff --git a/modules/50-loops/23-aggregation-strings/description.es.yml b/modules/50-loops/23-aggregation-strings/description.es.yml index 4afe0bda..457138dd 100644 --- a/modules/50-loops/23-aggregation-strings/description.es.yml +++ b/modules/50-loops/23-aggregation-strings/description.es.yml @@ -3,24 +3,24 @@ name: Agregación de datos (Cadenas) theory: | - La agregación se aplica no sólo a números, sino también a cadenas de texto. Estos son problemas en los que la cadena se genera dinámicamente, es decir, no se sabe de antemano su tamaño ni su contenido. + La agregación se aplica no solo a los números, sino también a las cadenas. Estas son tareas en las que una cadena se construye dinámicamente, es decir, no se sabe de antemano qué tamaño tendrá ni qué contendrá. - Imagina una función que puede "multiplicar" una cadena, es decir, repetirla un número determinado de veces: + Imagina una función que sabe "multiplicar" una cadena, es decir, la repite una cantidad determinada de veces: ```javascript repeat('hexlet', 3); // hexlethexlethexlet ``` - El principio de funcionamiento de esta función es bastante simple: se realiza una concatenación de la cadena un número determinado de veces en un bucle: + El principio de funcionamiento de esta función es bastante simple: en un bucle se produce el "crecimiento" de la cadena la cantidad de veces indicada: ```javascript const repeat = (text, times) => { - // El elemento neutro para las cadenas es una cadena vacía + // El elemento neutro para las cadenas es la cadena vacía let result = ''; let i = 1; while (i <= times) { - // Agregamos la cadena al resultado en cada iteración + // Cada vez agregamos la cadena al resultado result = `${result}${text}`; i = i + 1; } @@ -29,31 +29,55 @@ theory: | }; ``` - - Veamos cómo se ejecuta este código paso a paso: + Detallemos la ejecución de este código paso a paso: ```javascript - // Para llamar a repeat('hexlet', 3); + // Para la llamada repeat('hexlet', 3); let result = ''; result = `${result}hexlet`; // hexlet result = `${result}hexlet`; // hexlethexlet result = `${result}hexlet`; // hexlethexlethexlet ``` + Visualmente, el proceso de crecimiento de la cadena se ve así: + + ```text + repeat('hexlet', 3): + + i=1: result = '' + 'hexlet' = 'hexlet' + i=2: result = 'hexlet' + 'hexlet' = 'hexlethexlet' + i=3: result = 'hexlethexlet' + 'hexlet' = 'hexlethexlethexlet' + └── resultado + ``` + + ## Elemento neutro + + Para que el crecimiento funcione, se necesita un valor inicial. Para las cadenas, ese valor es la **cadena vacía** `''`. + + Se llama elemento neutro porque no cambia nada durante la concatenación: + + ```javascript + console.log('' + 'abc'); // => abc + console.log('abc' + ''); // => abc + ``` + + Por eso la cadena vacía siempre se usa como valor inicial al agregar cadenas. instructions: | - Implementa la función `joinNumbersFromRange()`, que une todos los números de un rango en una cadena: + Implementa una función `sanitizePhoneNumber()` que reciba un número de teléfono de un formulario y devuelva una cadena sin espacios, paréntesis ni guiones. + + Los usuarios introducen los números de diferentes maneras, pero antes de guardarlos se normalizan a un formato único. Recorre la cadena original carácter por carácter y arma un nuevo número solo con los caracteres útiles. ```javascript - joinNumbersFromRange(1, 1); // 1 - joinNumbersFromRange(2, 3); // 23 - joinNumbersFromRange(5, 10); // 5678910 + sanitizePhoneNumber('+7 (999) 123-45-67'); // => '+79991234567' + sanitizePhoneNumber('8 800 555 35 35'); // => '88005553535' + sanitizePhoneNumber('(123) 456-7890'); // => '1234567890' ``` + Usa la cadena vacía como valor inicial. tips: - | - [Iteración](https://es.wikipedia.org/wiki/Iteraci%C3%B3n) - + [Iteración](https://es.wikipedia.org/wiki/Iteración) definitions: - name: Agregación - description: "Acumulación de resultados durante las iteraciones y manipulación de ellos después del ciclo." + description: Acumulación del resultado durante las iteraciones y trabajo con él después del bucle. diff --git a/modules/50-loops/23-aggregation-strings/en/EXERCISE.md b/modules/50-loops/23-aggregation-strings/en/EXERCISE.md index 06b35acc..56ecf82c 100644 --- a/modules/50-loops/23-aggregation-strings/en/EXERCISE.md +++ b/modules/50-loops/23-aggregation-strings/en/EXERCISE.md @@ -1,8 +1,11 @@ +Implement a function `sanitizePhoneNumber()` that takes a phone number from a form and returns a string without spaces, parentheses, and hyphens. -Write the `joinNumbersFromRange()` function that joins all numbers in a range into a string: +Users enter numbers in different ways, but before saving them they are normalized to a single format. Go through the original string character by character and assemble a new number using only the useful characters. ```javascript -joinNumbersFromRange(1, 1); // '1' -joinNumbersFromRange(2, 3); // '23' -joinNumbersFromRange(5, 10); // '5678910' +sanitizePhoneNumber('+7 (999) 123-45-67'); // => '+79991234567' +sanitizePhoneNumber('8 800 555 35 35'); // => '88005553535' +sanitizePhoneNumber('(123) 456-7890'); // => '1234567890' ``` + +Use the empty string as the initial value. diff --git a/modules/50-loops/23-aggregation-strings/en/README.md b/modules/50-loops/23-aggregation-strings/en/README.md index 181358dc..2ac31fbc 100644 --- a/modules/50-loops/23-aggregation-strings/en/README.md +++ b/modules/50-loops/23-aggregation-strings/en/README.md @@ -1,22 +1,22 @@ -You can use aggregation with strings as well as with numbers. In most cases, this applies to dynamic string generation, where you don't know in advance what size the string will be and what it will contain. +Aggregation applies not only to numbers but also to strings. These are tasks in which a string is built dynamically, that is, it is not known in advance how big it will be or what it will contain. -Imagine a function "multiplying" a string, that is, repeating a string a given number of times: +Imagine a function that can "multiply" a string, that is, it repeats it a specified number of times: ```javascript -repeat('hexlet', 3); // 'hexlethexlethexlet' +repeat('hexlet', 3); // hexlethexlethexlet ``` -The core mechanism of this function is simple, the loop "increments" the string a given number of times: +The way this function works is quite simple: in a loop, the string is "grown" the specified number of times: ```javascript const repeat = (text, times) => { - // A neutral element in terms of strings is an empty string + // The neutral element for strings is the empty string let result = ''; let i = 1; while (i <= times) { - // Add a string on each iteration + // Each time we add the string to the result result = `${result}${text}`; i = i + 1; } @@ -25,12 +25,36 @@ const repeat = (text, times) => { }; ``` -Break down the code's execution into steps: +Let's break down the execution of this code step by step: ```javascript -// Calling repeat('hexlet', 3); +// For the call repeat('hexlet', 3); let result = ''; result = `${result}hexlet`; // hexlet result = `${result}hexlet`; // hexlethexlet result = `${result}hexlet`; // hexlethexlethexlet ``` + +Visually, the process of growing the string looks like this: + +```text +repeat('hexlet', 3): + +i=1: result = '' + 'hexlet' = 'hexlet' +i=2: result = 'hexlet' + 'hexlet' = 'hexlethexlet' +i=3: result = 'hexlethexlet' + 'hexlet' = 'hexlethexlethexlet' + └── result +``` + +## Neutral element + +For growing to work, a starting value is needed. For strings, this value is the **empty string** `''`. + +It is called the neutral element because it changes nothing during concatenation: + +```javascript +console.log('' + 'abc'); // => abc +console.log('abc' + ''); // => abc +``` + +That is why the empty string is always used as the initial value when aggregating strings. diff --git a/modules/50-loops/23-aggregation-strings/en/data.yml b/modules/50-loops/23-aggregation-strings/en/data.yml index 10848082..f56222e6 100644 --- a/modules/50-loops/23-aggregation-strings/en/data.yml +++ b/modules/50-loops/23-aggregation-strings/en/data.yml @@ -1,3 +1,8 @@ --- -name: Data aggregation (strings) -tips: [] +name: Data aggregation (Strings) +tips: + - | + [Iteration](https://en.wikipedia.org/wiki/Iteration) +definitions: + - name: Aggregation + description: Accumulating a result during iterations and working with it after the loop. diff --git a/modules/50-loops/23-aggregation-strings/es/EXERCISE.md b/modules/50-loops/23-aggregation-strings/es/EXERCISE.md index dcb0b833..faad0906 100644 --- a/modules/50-loops/23-aggregation-strings/es/EXERCISE.md +++ b/modules/50-loops/23-aggregation-strings/es/EXERCISE.md @@ -1,8 +1,11 @@ +Implementa una función `sanitizePhoneNumber()` que reciba un número de teléfono de un formulario y devuelva una cadena sin espacios, paréntesis ni guiones. -Implementa la función `joinNumbersFromRange()`, que une todos los números de un rango en una cadena: +Los usuarios introducen los números de diferentes maneras, pero antes de guardarlos se normalizan a un formato único. Recorre la cadena original carácter por carácter y arma un nuevo número solo con los caracteres útiles. ```javascript -joinNumbersFromRange(1, 1); // 1 -joinNumbersFromRange(2, 3); // 23 -joinNumbersFromRange(5, 10); // 5678910 +sanitizePhoneNumber('+7 (999) 123-45-67'); // => '+79991234567' +sanitizePhoneNumber('8 800 555 35 35'); // => '88005553535' +sanitizePhoneNumber('(123) 456-7890'); // => '1234567890' ``` + +Usa la cadena vacía como valor inicial. diff --git a/modules/50-loops/23-aggregation-strings/es/README.md b/modules/50-loops/23-aggregation-strings/es/README.md index 72d9ae2f..fdbba4fc 100644 --- a/modules/50-loops/23-aggregation-strings/es/README.md +++ b/modules/50-loops/23-aggregation-strings/es/README.md @@ -1,22 +1,22 @@ -La agregación se aplica no sólo a números, sino también a cadenas de texto. Estos son problemas en los que la cadena se genera dinámicamente, es decir, no se sabe de antemano su tamaño ni su contenido. +La agregación se aplica no solo a los números, sino también a las cadenas. Estas son tareas en las que una cadena se construye dinámicamente, es decir, no se sabe de antemano qué tamaño tendrá ni qué contendrá. -Imagina una función que puede "multiplicar" una cadena, es decir, repetirla un número determinado de veces: +Imagina una función que sabe "multiplicar" una cadena, es decir, la repite una cantidad determinada de veces: ```javascript repeat('hexlet', 3); // hexlethexlethexlet ``` -El principio de funcionamiento de esta función es bastante simple: se realiza una concatenación de la cadena un número determinado de veces en un bucle: +El principio de funcionamiento de esta función es bastante simple: en un bucle se produce el "crecimiento" de la cadena la cantidad de veces indicada: ```javascript const repeat = (text, times) => { - // El elemento neutro para las cadenas es una cadena vacía + // El elemento neutro para las cadenas es la cadena vacía let result = ''; let i = 1; while (i <= times) { - // Agregamos la cadena al resultado en cada iteración + // Cada vez agregamos la cadena al resultado result = `${result}${text}`; i = i + 1; } @@ -25,12 +25,36 @@ const repeat = (text, times) => { }; ``` -Veamos cómo se ejecuta este código paso a paso: +Detallemos la ejecución de este código paso a paso: ```javascript -// Para llamar a repeat('hexlet', 3); +// Para la llamada repeat('hexlet', 3); let result = ''; result = `${result}hexlet`; // hexlet result = `${result}hexlet`; // hexlethexlet result = `${result}hexlet`; // hexlethexlethexlet ``` + +Visualmente, el proceso de crecimiento de la cadena se ve así: + +```text +repeat('hexlet', 3): + +i=1: result = '' + 'hexlet' = 'hexlet' +i=2: result = 'hexlet' + 'hexlet' = 'hexlethexlet' +i=3: result = 'hexlethexlet' + 'hexlet' = 'hexlethexlethexlet' + └── resultado +``` + +## Elemento neutro + +Para que el crecimiento funcione, se necesita un valor inicial. Para las cadenas, ese valor es la **cadena vacía** `''`. + +Se llama elemento neutro porque no cambia nada durante la concatenación: + +```javascript +console.log('' + 'abc'); // => abc +console.log('abc' + ''); // => abc +``` + +Por eso la cadena vacía siempre se usa como valor inicial al agregar cadenas. diff --git a/modules/50-loops/23-aggregation-strings/es/data.yml b/modules/50-loops/23-aggregation-strings/es/data.yml index 96ce5f08..55b19678 100644 --- a/modules/50-loops/23-aggregation-strings/es/data.yml +++ b/modules/50-loops/23-aggregation-strings/es/data.yml @@ -2,9 +2,7 @@ name: Agregación de datos (Cadenas) tips: - | - [Iteración](https://es.wikipedia.org/wiki/Iteraci%C3%B3n) + [Iteración](https://es.wikipedia.org/wiki/Iteración) definitions: - name: Agregación - description: >- - Acumulación de resultados durante las iteraciones y manipulación de ellos - después del ciclo. + description: Acumulación del resultado durante las iteraciones y trabajo con él después del bucle. diff --git a/modules/50-loops/25-iteration-over-string/description.es.yml b/modules/50-loops/25-iteration-over-string/description.es.yml index c22997c1..62526ce4 100644 --- a/modules/50-loops/25-iteration-over-string/description.es.yml +++ b/modules/50-loops/25-iteration-over-string/description.es.yml @@ -8,7 +8,7 @@ theory: | ```javascript const printNameBySymbol = (name) => { let i = 0; - // Esta condición se evaluará hasta el final de la cadena, + // Esta comprobación se ejecuta hasta el final de la cadena, // incluyendo el último carácter. Su índice es `length - 1`. while (i < name.length) { // Accedemos al carácter mediante su índice @@ -25,23 +25,46 @@ theory: | // => a ``` - Lo más importante en este código es establecer la condición correcta en el `while`. Esto se puede hacer de dos formas: `i < name.length` o `i <= name.length - 1`. Ambas formas conducen al mismo resultado. + El bucle recorre cada carácter de la cadena por turnos: + + ```text + 'Arya' + │ │ │ │ + A r y a + ↓ ↓ ↓ ↓ + cada carácter se procesa por turnos + ``` + + ## Invertir una cadena + + En lugar de imprimir, puedes construir una nueva cadena. Por ejemplo, escribamos una función que invierta una cadena: + + ```javascript + const reverseString = (text) => { + let result = ''; + let i = text.length - 1; + while (i >= 0) { + result = `${result}${text[i]}`; + i -= 1; + } + return result; + }; + + console.log(reverseString('Arya')); // => ayrA + console.log(reverseString('hexlet')); // => telxeh + ``` + + La variable `result` se inicializa con una cadena vacía como elemento neutro para la concatenación. El bucle comienza en el último índice (`text.length - 1`), avanza hacia cero y termina cuando el índice se vuelve menor que cero. En cada paso, el carácter actual se añade al resultado, y la cadena se construye en orden inverso. + instructions: | - Implementa la función `printReversedWordBySymbol()`, que imprime la palabra pasada como argumento carácter por carácter, como se muestra en el ejemplo de la teoría, pero en orden inverso. + Escribe una función `maskCardNumber()` que oculte el número de una tarjeta bancaria: reemplaza todos los caracteres de la cadena por `*`, excepto los últimos cuatro. ```javascript - const word = 'Hexlet'; - - printReversedWordBySymbol(word); - // => t - // => e - // => l - // => x - // => e - // => H + maskCardNumber('1234567812345678'); // => '************5678' + maskCardNumber('12345678'); // => '****5678' ``` tips: diff --git a/modules/50-loops/25-iteration-over-string/en/EXERCISE.md b/modules/50-loops/25-iteration-over-string/en/EXERCISE.md index 7843d68b..35b093f3 100644 --- a/modules/50-loops/25-iteration-over-string/en/EXERCISE.md +++ b/modules/50-loops/25-iteration-over-string/en/EXERCISE.md @@ -1,14 +1,6 @@ - -Write the `printReversedWordBySymbol()` function that takes a word as input and prints it by character, just as in the example we gave, but does it in reverse order. +Write a `maskCardNumber()` function that hides a bank card number: it replaces all characters of the string with `*`, except for the last four. ```javascript -const word = 'Hexlet'; - -printReversedWordBySymbol(word); -// => 't' -// => 'e' -// => 'l' -// => 'x' -// => 'e' -// => 'H' +maskCardNumber('1234567812345678'); // => '************5678' +maskCardNumber('12345678'); // => '****5678' ``` diff --git a/modules/50-loops/25-iteration-over-string/en/README.md b/modules/50-loops/25-iteration-over-string/en/README.md index 9f3a14a6..cfd6b2ca 100644 --- a/modules/50-loops/25-iteration-over-string/en/README.md +++ b/modules/50-loops/25-iteration-over-string/en/README.md @@ -1,13 +1,13 @@ -You can use loops to process strings as well as numbers. Mainly as a method for retrieving a specific character by its index. Below is an example of code that prints each letter of a word on a single line: +Loops are suitable not only for processing numbers but also for working with strings. This is primarily due to the ability to access a specific character by its index. Below is an example of code that prints each letter of a word on a separate line: ```javascript const printNameBySymbol = (name) => { let i = 0; - // This test works until a string ends, - // including the last character. The last index is `length - 1` + // This check runs until the end of the string, + // including the last character. Its index is `length - 1`. while (i < name.length) { - // Get a character by its index + // Access the character by its index console.log(name[i]); i = i + 1; } @@ -15,10 +15,41 @@ const printNameBySymbol = (name) => { const name = 'Arya'; printNameBySymbol(name); -// => 'A' -// => 'r' -// => 'y' -// => 'a' +// => A +// => r +// => y +// => a ``` -The right test condition for the `while` loop is essential in this code. You can do it two ways: `i < name.length` or `i <= name.length - 1`. Both lead to the same result. +The most important thing in this code is to set the right condition in `while`. This can be done in two ways at once: `i < name.length` or `i <= name.length - 1`. Both approaches lead to the same result. + +The loop goes through each character of the string in turn: + +```text +'Arya' + │ │ │ │ + A r y a + ↓ ↓ ↓ ↓ +each character is processed in turn +``` + +## Reversing a string + +Instead of printing, you can build a new string. For example, let's write a function that reverses a string: + +```javascript +const reverseString = (text) => { + let result = ''; + let i = text.length - 1; + while (i >= 0) { + result = `${result}${text[i]}`; + i -= 1; + } + return result; +}; + +console.log(reverseString('Arya')); // => ayrA +console.log(reverseString('hexlet')); // => telxeh +``` + +The `result` variable is initialized with an empty string as a neutral element for concatenation. The loop starts at the last index (`text.length - 1`), moves toward zero, and ends when the index becomes less than zero. At each step, the current character is added to the result — and the string is built in reverse order. diff --git a/modules/50-loops/25-iteration-over-string/en/data.yml b/modules/50-loops/25-iteration-over-string/en/data.yml index 07d266d5..62b51999 100644 --- a/modules/50-loops/25-iteration-over-string/en/data.yml +++ b/modules/50-loops/25-iteration-over-string/en/data.yml @@ -1,3 +1,5 @@ --- name: Iterating over a string -tips: [] +tips: + - | + [Iteration](https://en.wikipedia.org/wiki/Iteration) diff --git a/modules/50-loops/25-iteration-over-string/es/EXERCISE.md b/modules/50-loops/25-iteration-over-string/es/EXERCISE.md index 0c4cb574..adfefe86 100644 --- a/modules/50-loops/25-iteration-over-string/es/EXERCISE.md +++ b/modules/50-loops/25-iteration-over-string/es/EXERCISE.md @@ -1,14 +1,6 @@ - -Implementa la función `printReversedWordBySymbol()`, que imprime la palabra pasada como argumento carácter por carácter, como se muestra en el ejemplo de la teoría, pero en orden inverso. +Escribe una función `maskCardNumber()` que oculte el número de una tarjeta bancaria: reemplaza todos los caracteres de la cadena por `*`, excepto los últimos cuatro. ```javascript -const word = 'Hexlet'; - -printReversedWordBySymbol(word); -// => t -// => e -// => l -// => x -// => e -// => H +maskCardNumber('1234567812345678'); // => '************5678' +maskCardNumber('12345678'); // => '****5678' ``` diff --git a/modules/50-loops/25-iteration-over-string/es/README.md b/modules/50-loops/25-iteration-over-string/es/README.md index 1f0547c1..8909bcd4 100644 --- a/modules/50-loops/25-iteration-over-string/es/README.md +++ b/modules/50-loops/25-iteration-over-string/es/README.md @@ -4,7 +4,7 @@ Los bucles no sólo son útiles para trabajar con números, sino también para t ```javascript const printNameBySymbol = (name) => { let i = 0; - // Esta condición se evaluará hasta el final de la cadena, + // Esta comprobación se ejecuta hasta el final de la cadena, // incluyendo el último carácter. Su índice es `length - 1`. while (i < name.length) { // Accedemos al carácter mediante su índice @@ -22,3 +22,34 @@ printNameBySymbol(name); ``` Lo más importante en este código es establecer la condición correcta en el `while`. Esto se puede hacer de dos formas: `i < name.length` o `i <= name.length - 1`. Ambas formas conducen al mismo resultado. + +El bucle recorre cada carácter de la cadena por turnos: + +```text +'Arya' + │ │ │ │ + A r y a + ↓ ↓ ↓ ↓ +cada carácter se procesa por turnos +``` + +## Invertir una cadena + +En lugar de imprimir, puedes construir una nueva cadena. Por ejemplo, escribamos una función que invierta una cadena: + +```javascript +const reverseString = (text) => { + let result = ''; + let i = text.length - 1; + while (i >= 0) { + result = `${result}${text[i]}`; + i -= 1; + } + return result; +}; + +console.log(reverseString('Arya')); // => ayrA +console.log(reverseString('hexlet')); // => telxeh +``` + +La variable `result` se inicializa con una cadena vacía como elemento neutro para la concatenación. El bucle comienza en el último índice (`text.length - 1`), avanza hacia cero y termina cuando el índice se vuelve menor que cero. En cada paso, el carácter actual se añade al resultado, y la cadena se construye en orden inverso. diff --git a/modules/50-loops/25-iteration-over-string/index.js b/modules/50-loops/25-iteration-over-string/index.js index d86599e4..14b3de37 100644 --- a/modules/50-loops/25-iteration-over-string/index.js +++ b/modules/50-loops/25-iteration-over-string/index.js @@ -6,7 +6,7 @@ const maskCardNumber = (cardNumber) => { const visiblePartStart = cardNumber.length - 4; while (i < cardNumber.length) { if (i < visiblePartStart) { - // biome-ignore lint/style/useTemplate: учебный пример до урока 30-syntax-sugar + // biome-ignore lint/style/useTemplate: teaching example before the 30-syntax-sugar lesson result = result + '*'; } else { result = result + cardNumber[i]; diff --git a/modules/50-loops/55-return-from-loops/description.es.yml b/modules/50-loops/55-return-from-loops/description.es.yml index 6ad3ea13..39aac999 100644 --- a/modules/50-loops/55-return-from-loops/description.es.yml +++ b/modules/50-loops/55-return-from-loops/description.es.yml @@ -1,16 +1,24 @@ --- -name: Salida de Bucles +name: Retorno desde bucles theory: | + El trabajo con bucles normalmente se reduce a dos escenarios: - Trabajar con bucles generalmente se reduce a dos escenarios: + 1. Agregación. Acumular un resultado durante las iteraciones y trabajar con él después del bucle. Invertir una cadena es precisamente este tipo de caso. + 2. Ejecutar el bucle hasta alcanzar el resultado necesario y salir. Por ejemplo, la tarea de buscar números primos. Recordemos que un número primo es un número que se divide sin resto solo por sí mismo y por uno. - 1. Agregación. Acumulación de resultados durante las iteraciones y trabajar con ellos después del bucle. La inversión de una cadena es un ejemplo de este enfoque. - 2. Ejecución de un bucle hasta alcanzar un resultado deseado y luego salir del bucle. Por ejemplo, la tarea de buscar números primos. Recordemos que un número primo es aquel que solo es divisible entre sí mismo y uno. + Veamos un algoritmo sencillo para comprobar si un número es primo. Dividiremos el número buscado `x` por todos los números del rango de dos a `x - 1` y observaremos el resto de la división. Si en este rango no se encuentra ningún divisor que divida `x` sin resto, entonces tenemos un número primo. - Consideremos un algoritmo simple para verificar la primalidad de un número. Dividiremos el número deseado `x` entre todos los números en el rango desde dos hasta `x - 1` y verificaremos el residuo de la división. Si no encontramos ningún divisor en este rango que divida al número `x` sin residuo, entonces estamos ante un número primo. + ## Comprobar si 5 es primo: un análisis paso a paso - Si lo pensamos un poco, notaremos que solamente necesitamos verificar números hasta `x / 2`, en lugar de llegar a `x - 1`. Por ejemplo, el 11 no es divisible por 2, 3, 4, 5. Además, no habrá divisores mayores que la mitad del número. Por lo tanto, podemos optimizar y verificar solo hasta `x / 2`. + 1. Tomamos el número `x = 5`. Buscamos los posibles divisores en el rango de 2 a `x - 1`, es decir, de 2 a 4. + 2. Dividimos 5 entre 2. El resto es 1 — no se encontró divisor, continuamos. + 3. Dividimos 5 entre 3. El resto es 2 — no se encontró divisor, continuamos. + 4. Dividimos 5 entre 4. El resto es 1 — no se encontró divisor, terminamos la búsqueda. + + Resultado: en el rango 2…4 no se encontró ningún número por el que 5 se divida sin resto. Por lo tanto, 5 es un número primo. + + Si lo piensas, puedes notar que basta con comprobar los números no hasta `x - 1`, sino hasta la mitad del número. Por ejemplo, 11 no se divide entre 2, 3, 4, 5. Y más allá tampoco se dividirá, con seguridad, entre números mayores que su mitad. Así que podemos hacer una pequeña optimización y comprobar la división solo hasta `x / 2`. ```javascript const isPrime = (number) => { @@ -37,28 +45,37 @@ theory: | isPrime(4); // false ``` + ```text + while (...) { + if (condición) { + return valor; ← salida de la función (y del bucle) + } + ... + } + ───────────────────────── + Sin return el bucle continúa hasta el final + ``` - El algoritmo está diseñado de tal manera que, si encontramos al menos un divisor en el rango de la división secuencial entre números de 2 a `x / 2`, entonces el número pasado como argumento no es primo, y no tiene sentido continuar las comprobaciones. En este punto, deberíamos devolver `false`. + El algoritmo está construido así: si durante la división secuencial por los números hasta `x / 2` se encuentra al menos uno que divide sin resto, entonces el argumento pasado no es un número primo, y los cálculos posteriores no tienen sentido. En este punto se coloca el retorno `false`. - Solamente si el bucle se ejecuta por completo, podemos concluir que el número es primo, ya que no se encontró ningún número que sea divisor sin residuo. + Y solo si el bucle se ha ejecutado por completo y no se encontró ningún número que divida sin resto, podemos concluir que el número es primo. + *Para ser totalmente honestos, para resolver la tarea basta con comprobar los números hasta la raíz cuadrada de `number`. Pero aquí lo importante para nosotros es centrarnos en entender cómo trabajar con condiciones y el retorno dentro de un bucle.* instructions: | + Implementa la función `hasAtSymbol()`, que comprueba si un email contiene el símbolo `@`. - Implementa la función `hasChar()`, que verifica si una cadena contiene una letra específica (considerando la diferencia entre mayúsculas y minúsculas). La función toma dos parámetros: - - * Una cadena - * La letra a buscar + La función debe devolver `true` en cuanto encuentre `@`. Si el bucle llega al final de la cadena y el símbolo no se encuentra, devuelve `false`. ```javascript - hasChar('Hexlet', 'H'); // true - hasChar('Hexlet', 'h'); // false - hasChar('Awesomeness', 'm'); // true - hasChar('Awesomeness', 'd'); // false + hasAtSymbol('support@example.com'); // => true + hasAtSymbol('wrong-email'); // => false + hasAtSymbol('@admin'); // => true ``` + Usa un bucle con un `return` temprano. tips: - - "[Lista de números primos](https://es.wikipedia.org/wiki/Anexo:N%C3%BAmeros_primos)" - + - | + [Lista de números primos](https://es.wikipedia.org/wiki/Número_primo) definitions: - name: Agregación - description: "Acumulación de resultados durante las iteraciones y trabajar con ellos después del bucle." + description: Acumular un resultado durante las iteraciones y trabajar con él después del bucle. diff --git a/modules/50-loops/55-return-from-loops/en/EXERCISE.md b/modules/50-loops/55-return-from-loops/en/EXERCISE.md index d82ed406..42dd9244 100644 --- a/modules/50-loops/55-return-from-loops/en/EXERCISE.md +++ b/modules/50-loops/55-return-from-loops/en/EXERCISE.md @@ -1,12 +1,11 @@ +Implement the function `hasAtSymbol()`, which checks whether an email contains the `@` symbol. -Write the `hasChar()` function that checks whether a string contains a given character (case-sensitive). The function takes two arguments: - -* String -* Character to look for +The function should return `true` as soon as it finds `@`. If the loop reaches the end of the string and the symbol is not found, return `false`. ```javascript -hasChar('Hexlet', 'H'); // true -hasChar('Hexlet', 'h'); // false -hasChar('Awesomeness', 'm'); // true -hasChar('Awesomeness', 'd'); // false +hasAtSymbol('support@example.com'); // => true +hasAtSymbol('wrong-email'); // => false +hasAtSymbol('@admin'); // => true ``` + +Use a loop with an early `return`. diff --git a/modules/50-loops/55-return-from-loops/en/README.md b/modules/50-loops/55-return-from-loops/en/README.md index 54c5c2cb..593aed64 100644 --- a/modules/50-loops/55-return-from-loops/en/README.md +++ b/modules/50-loops/55-return-from-loops/en/README.md @@ -1,12 +1,21 @@ -Dealing with loops usually comes down to two cases: +Working with loops usually comes down to two scenarios: -1. Aggregation. Accumulation of data during iterations and handling it after the loop. String reversal is just one of these cases -2. Executing a loop until you get the required result and breaking from it. For example, if the job of the loop is to find prime numbers. Remember that a prime number is a number that can only be divided without a remainder by itself and by one +1. Aggregation. Accumulating a result during iterations and working with it after the loop. Reversing a string is exactly this kind of case. +2. Running the loop until the required result is reached and then exiting. For example, the task of finding prime numbers. Recall that a prime number is a number that is divisible without a remainder only by itself and by one. -Consider a simple algorithm to check prime numbers. We will divide a given number `x` by all numbers between 2 and `x - 1` and check the remainder. If we don't find a divisor that divides the number `x` without a remainder in this range, then we are looking at a prime number. +Let's look at a simple algorithm for checking whether a number is prime. We'll divide the target number `x` by all numbers in the range from two to `x - 1` and look at the remainder of the division. If no divisor that divides `x` without a remainder is found in this range, then we have a prime number. -If you think about it, it's actually enough to check numbers not up to `x - 1`, but up to half the given number. For example, 11 is not divisible by 2, 3, 4, or 5. But it's also guaranteed that it can't be divided by numbers greater than its half. So, you can do a little optimization and check division only up to `x / 2`. +## Checking whether 5 is prime: a step-by-step walkthrough + +1. Take the number `x = 5`. We look for possible divisors in the range from 2 to `x - 1`, that is, from 2 to 4. +2. Divide 5 by 2. The remainder is 1 — no divisor found, continue. +3. Divide 5 by 3. The remainder is 2 — no divisor found, continue. +4. Divide 5 by 4. The remainder is 1 — no divisor found, finish the search. + +Result: in the range 2…4 there was no number by which 5 is divisible without a remainder. Therefore, 5 is a prime number. + +If you think about it, you can notice that it's enough to check numbers not up to `x - 1`, but up to half of the number. For example, 11 is not divisible by 2, 3, 4, 5. And beyond that it is guaranteed not to be divisible by numbers larger than its half. So we can make a small optimization and check division only up to `x / 2`. ```javascript const isPrime = (number) => { @@ -33,6 +42,19 @@ isPrime(3); // true isPrime(4); // false ``` -The algorithm is built like so: if during the successive division by numbers up to `x / 2`, there is at least one result without a remainder, then the given argument is not a prime number, and therefore further computations are pointless. At this point, it returns `false`. +```text +while (...) { + if (condition) { + return value; ← exit from the function (and from the loop) + } + ... +} +───────────────────────── +Without return the loop continues to the end +``` + +The algorithm is built like this: if during the sequential division by numbers up to `x / 2` at least one is found that divides without a remainder, then the passed argument is not a prime number, and further calculations make no sense. At this point there is a `false` return. + +And only if the loop has run completely and no number that divides without a remainder was found, can we conclude that the number is prime. -And only if the entire loop is completed can we say that the number is prime since no number by which it can be divided without a remainder can be found. +*To be completely honest, checking numbers up to the square root of `number` is enough to solve the task. But here it's important for us to focus on understanding how to work with conditions and returning inside a loop.* diff --git a/modules/50-loops/55-return-from-loops/en/data.yml b/modules/50-loops/55-return-from-loops/en/data.yml index 3040c2a6..330721c2 100644 --- a/modules/50-loops/55-return-from-loops/en/data.yml +++ b/modules/50-loops/55-return-from-loops/en/data.yml @@ -1,4 +1,8 @@ --- name: Returning from loops tips: - - '[List of prime numbers](https://en.wikipedia.org/wiki/List_of_prime_numbers)' + - | + [List of prime numbers](https://en.wikipedia.org/wiki/List_of_prime_numbers) +definitions: + - name: Aggregation + description: Accumulating a result during iterations and working with it after the loop. diff --git a/modules/50-loops/55-return-from-loops/es/EXERCISE.md b/modules/50-loops/55-return-from-loops/es/EXERCISE.md index 28e00ef6..e66166ac 100644 --- a/modules/50-loops/55-return-from-loops/es/EXERCISE.md +++ b/modules/50-loops/55-return-from-loops/es/EXERCISE.md @@ -1,12 +1,11 @@ +Implementa la función `hasAtSymbol()`, que comprueba si un email contiene el símbolo `@`. -Implementa la función `hasChar()`, que verifica si una cadena contiene una letra específica (considerando la diferencia entre mayúsculas y minúsculas). La función toma dos parámetros: - -* Una cadena -* La letra a buscar +La función debe devolver `true` en cuanto encuentre `@`. Si el bucle llega al final de la cadena y el símbolo no se encuentra, devuelve `false`. ```javascript -hasChar('Hexlet', 'H'); // true -hasChar('Hexlet', 'h'); // false -hasChar('Awesomeness', 'm'); // true -hasChar('Awesomeness', 'd'); // false +hasAtSymbol('support@example.com'); // => true +hasAtSymbol('wrong-email'); // => false +hasAtSymbol('@admin'); // => true ``` + +Usa un bucle con un `return` temprano. diff --git a/modules/50-loops/55-return-from-loops/es/README.md b/modules/50-loops/55-return-from-loops/es/README.md index 8136cf90..a4aae683 100644 --- a/modules/50-loops/55-return-from-loops/es/README.md +++ b/modules/50-loops/55-return-from-loops/es/README.md @@ -1,12 +1,21 @@ -Trabajar con bucles generalmente se reduce a dos escenarios: +El trabajo con bucles normalmente se reduce a dos escenarios: -1. Agregación. Acumulación de resultados durante las iteraciones y trabajar con ellos después del bucle. La inversión de una cadena es un ejemplo de este enfoque. -2. Ejecución de un bucle hasta alcanzar un resultado deseado y luego salir del bucle. Por ejemplo, la tarea de buscar números primos. Recordemos que un número primo es aquel que solo es divisible entre sí mismo y uno. +1. Agregación. Acumular un resultado durante las iteraciones y trabajar con él después del bucle. Invertir una cadena es precisamente este tipo de caso. +2. Ejecutar el bucle hasta alcanzar el resultado necesario y salir. Por ejemplo, la tarea de buscar números primos. Recordemos que un número primo es un número que se divide sin resto solo por sí mismo y por uno. -Consideremos un algoritmo simple para verificar la primalidad de un número. Dividiremos el número deseado `x` entre todos los números en el rango desde dos hasta `x - 1` y verificaremos el residuo de la división. Si no encontramos ningún divisor en este rango que divida al número `x` sin residuo, entonces estamos ante un número primo. +Veamos un algoritmo sencillo para comprobar si un número es primo. Dividiremos el número buscado `x` por todos los números del rango de dos a `x - 1` y observaremos el resto de la división. Si en este rango no se encuentra ningún divisor que divida `x` sin resto, entonces tenemos un número primo. -Si lo pensamos un poco, notaremos que solamente necesitamos verificar números hasta `x / 2`, en lugar de llegar a `x - 1`. Por ejemplo, el 11 no es divisible por 2, 3, 4, 5. Además, no habrá divisores mayores que la mitad del número. Por lo tanto, podemos optimizar y verificar solo hasta `x / 2`. +## Comprobar si 5 es primo: un análisis paso a paso + +1. Tomamos el número `x = 5`. Buscamos los posibles divisores en el rango de 2 a `x - 1`, es decir, de 2 a 4. +2. Dividimos 5 entre 2. El resto es 1 — no se encontró divisor, continuamos. +3. Dividimos 5 entre 3. El resto es 2 — no se encontró divisor, continuamos. +4. Dividimos 5 entre 4. El resto es 1 — no se encontró divisor, terminamos la búsqueda. + +Resultado: en el rango 2…4 no se encontró ningún número por el que 5 se divida sin resto. Por lo tanto, 5 es un número primo. + +Si lo piensas, puedes notar que basta con comprobar los números no hasta `x - 1`, sino hasta la mitad del número. Por ejemplo, 11 no se divide entre 2, 3, 4, 5. Y más allá tampoco se dividirá, con seguridad, entre números mayores que su mitad. Así que podemos hacer una pequeña optimización y comprobar la división solo hasta `x / 2`. ```javascript const isPrime = (number) => { @@ -33,6 +42,19 @@ isPrime(3); // true isPrime(4); // false ``` -El algoritmo está diseñado de tal manera que, si encontramos al menos un divisor en el rango de la división secuencial entre números de 2 a `x / 2`, entonces el número pasado como argumento no es primo, y no tiene sentido continuar las comprobaciones. En este punto, deberíamos devolver `false`. +```text +while (...) { + if (condición) { + return valor; ← salida de la función (y del bucle) + } + ... +} +───────────────────────── +Sin return el bucle continúa hasta el final +``` + +El algoritmo está construido así: si durante la división secuencial por los números hasta `x / 2` se encuentra al menos uno que divide sin resto, entonces el argumento pasado no es un número primo, y los cálculos posteriores no tienen sentido. En este punto se coloca el retorno `false`. + +Y solo si el bucle se ha ejecutado por completo y no se encontró ningún número que divida sin resto, podemos concluir que el número es primo. -Solamente si el bucle se ejecuta por completo, podemos concluir que el número es primo, ya que no se encontró ningún número que sea divisor sin residuo. +*Para ser totalmente honestos, para resolver la tarea basta con comprobar los números hasta la raíz cuadrada de `number`. Pero aquí lo importante para nosotros es centrarnos en entender cómo trabajar con condiciones y el retorno dentro de un bucle.* diff --git a/modules/50-loops/55-return-from-loops/es/data.yml b/modules/50-loops/55-return-from-loops/es/data.yml index 6fdc7842..e185ef5c 100644 --- a/modules/50-loops/55-return-from-loops/es/data.yml +++ b/modules/50-loops/55-return-from-loops/es/data.yml @@ -1,11 +1,8 @@ --- -name: Salida de Bucles +name: Retorno desde bucles tips: - - >- - [Lista de números - primos](https://es.wikipedia.org/wiki/Anexo:N%C3%BAmeros_primos) + - | + [Lista de números primos](https://es.wikipedia.org/wiki/Número_primo) definitions: - name: Agregación - description: >- - Acumulación de resultados durante las iteraciones y trabajar con ellos - después del bucle. + description: Acumular un resultado durante las iteraciones y trabajar con él después del bucle. diff --git a/modules/50-loops/70-for/description.es.yml b/modules/50-loops/70-for/description.es.yml index 2e5b4967..2967a4a8 100644 --- a/modules/50-loops/70-for/description.es.yml +++ b/modules/50-loops/70-for/description.es.yml @@ -2,7 +2,6 @@ name: Bucle For theory: | - El bucle `while` es ideal para situaciones en las que no se conoce de antemano la cantidad de iteraciones, por ejemplo, al buscar un número primo. Cuando se conoce la cantidad de iteraciones, es preferible utilizar el bucle `for`. Veamos la implementación de invertir una cadena utilizando el bucle `for`: @@ -18,8 +17,19 @@ theory: | }; ``` + Se puede leer de la siguiente manera: *el bucle con el índice `i` se repite mientras `i < str.length` e incrementa `i` en 1 después de cada paso*. + + Analicemos cómo funciona el bucle paso a paso para la llamada `reverseString('go!')`: + + ```text + antes del bucle: result = '' - Se puede leer de la siguiente manera: *el bucle con el índice `i` se repite mientras `i < str.length`. Después de cada paso incrementa `i` en 1*. + i=0: result = `${str[0]}${result}` = 'g' + '' = 'g' + i=1: result = `${str[1]}${result}` = 'o' + 'g' = 'og' + i=2: result = `${str[2]}${result}` = '!' + 'og' = '!og' + ``` + + Cada nuevo carácter se antepone a la izquierda del resultado acumulado, por lo que la cadena se construye en orden inverso. En la definición del bucle `for`, entre paréntesis, hay tres expresiones separadas por punto y coma: @@ -29,6 +39,29 @@ theory: | En lo demás, el funcionamiento es exactamente igual al del bucle `while`. + ## Otro ejemplo: contar caracteres + + Contemos cuántas veces aparece un carácter en una cadena, sin distinguir entre mayúsculas y minúsculas: + + ```javascript + const charsCount = (text, char) => { + let result = 0; + for (let i = 0; i < text.length; i += 1) { + // convertimos a minúsculas para no depender de mayúsculas y minúsculas + if (text[i].toLowerCase() === char.toLowerCase()) { + result += 1; + } + } + return result; + }; + + charsCount('hexlet!', 'e'); // 2 + charsCount('hExlet!', 'E'); // 2 + charsCount('hexlet!', 'a'); // 0 + ``` + + Aquí `for` controla el recorrido de los caracteres, mientras que la condición interna decide si incrementar el contador. + En la definición de `for`, no es necesario especificar las tres expresiones. Si no se especifica la condición de repetición del bucle, el bucle se ejecutará infinitamente: ```javascript @@ -39,29 +72,37 @@ theory: | i += 1; } ``` - instructions: | + FizzBuzz es una de las tareas de entrevista más conocidas para programadores principiantes. Se plantea para comprobar la capacidad de trabajar con bucles y condiciones. Implementa una función `fizzBuzz(n)` que devuelve una cadena con los números del 1 al `n`. + + En este caso: + + - si un número es divisible por 3, en su lugar se sustituye la palabra `"Fizz"`; + - si es divisible por 5, la palabra `"Buzz"`; + - si es divisible tanto por 3 como por 5, la palabra `"FizzBuzz"`. - Samwell descubrió que sus mensajes estaban siendo interceptados y leídos en la fortaleza "Gemelos", por lo que sus ataques dejaron de ser sorpresivos. Después de pensar un poco, desarrolló un programa que cifra los mensajes transmitidos utilizando el siguiente algoritmo. El programa recibe una cadena como entrada y cambia de lugar cada par de caracteres consecutivos. Si la longitud de la cadena es impar, el último carácter permanece en su lugar. + Todos los elementos se unen con un espacio. + + Ejemplo de llamada a la función: ```javascript - encrypt('move'); // omev - encrypt('attack'); // taatkc - // Si la longitud de la cadena es impar, - // el último carácter permanece en su lugar - encrypt('go!'); // og! + fizzBuzz(15); + // => '1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz' ``` - Implementa la función `encrypt()`, que recibe el mensaje original como entrada y devuelve el mensaje cifrado. - - Piensa. ¿Puede esta función descifrar un mensaje cifrado? + ### Algoritmo + 1. Declarar el elemento neutro de agregación (una cadena vacía). + 2. Recorrer con un bucle `for` los números del 1 al `n`. + 3. Comprobar el número según las condiciones de divisibilidad. + 4. Añadir el resultado de cada iteración a la cadena final, separado por un espacio. tips: - | [for](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/for) + [plantillas de cadena](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Template_literals) - [Operador lógico OR (||)](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Logical_OR) + [Operador lógico OR (||)](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Logical_OR) definitions: - name: Agregación - description: "Acumulación de resultados durante las iteraciones y trabajo con ellos después del bucle." + description: Acumulación de resultados durante las iteraciones y trabajo con ellos después del bucle. diff --git a/modules/50-loops/70-for/en/EXERCISE.md b/modules/50-loops/70-for/en/EXERCISE.md index e24ba99d..2ecced99 100644 --- a/modules/50-loops/70-for/en/EXERCISE.md +++ b/modules/50-loops/70-for/en/EXERCISE.md @@ -1,14 +1,23 @@ +FizzBuzz is one of the most famous interview tasks for beginner programmers. It's given to test the ability to work with loops and conditions. Implement a function `fizzBuzz(n)` that returns a string with the numbers from 1 to `n`. -Samwell discovered that his messages were being intercepted at Castle Gemini and being read there. This made his attacks no longer a surprise. After some thought, he developed a program to encrypt the messages according to the following algorithm. It would take the text and rearrange it every two consecutive characters. +In this case: + +- if a number is divisible by 3, the word `"Fizz"` is substituted instead; +- if it's divisible by 5 — the word `"Buzz"`; +- if it's divisible by both 3 and 5 — the word `"FizzBuzz"`. + +All elements are joined with a space. + +Example of calling the function: ```javascript -encrypt('move'); // 'omev' -encrypt('attack'); // 'taatkc' -// If the number of characters is odd -// the last character remains unchanged -encrypt('go!'); // 'og!' +fizzBuzz(15); +// => '1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz' ``` -Write a function, `encrypt()`, which takes the original message and returns an encrypted one. +### Algorithm -Think about it. Can this function decrypt an encrypted message? +1. Declare the neutral element of aggregation (an empty string). +2. Iterate through the numbers from 1 to `n` with a `for` loop. +3. Check the number against the divisibility conditions. +4. Add the result of each iteration to the resulting string, separated by a space. diff --git a/modules/50-loops/70-for/en/README.md b/modules/50-loops/70-for/en/README.md index 0b265879..40ca16ec 100644 --- a/modules/50-loops/70-for/en/README.md +++ b/modules/50-loops/70-for/en/README.md @@ -1,7 +1,7 @@ -A `while` loop works perfectly for situations where the number of iterations isn't known in advance, e.g., finding a prime number. When we know the number of iterations, it's better to use a `for` loop. +The `while` loop is ideal for situations where the number of iterations is unknown in advance, for example, when searching for a prime number. When the number of iterations is known, it's preferable to use the `for` loop. -Let's take a look at a function that reverses strings using a `for` loop: +Let's look at the implementation of reversing a string using a `for` loop: ```javascript const reverseString = (str) => { @@ -14,12 +14,58 @@ const reverseString = (str) => { }; ``` -We could read it as follows: *a loop with index `i` repeats until `i < str.length` and after each step increases `i` by 1*. +It can be read as follows: *the loop with index `i` repeats while `i < str.length` and increases `i` by 1 after each step*. -When defining the `for` loop, we have three expressions in parentheses, separated by semicolons: +Let's go through how the loop works step by step for the call `reverseString('go!')`: -1. The initial counter value. This code runs exactly once before the first iteration. -2. A predicate - the condition for the loop to iterate. It's executed on each iteration. Exactly like what we have with `while`. -3. Description of the counter change. This code is executed at the end of each iteration. +```text +before the loop: result = '' -Other than that, it works exactly the same as the `while` loop. +i=0: result = `${str[0]}${result}` = 'g' + '' = 'g' +i=1: result = `${str[1]}${result}` = 'o' + 'g' = 'og' +i=2: result = `${str[2]}${result}` = '!' + 'og' = '!og' +``` + +Each new character is prepended to the left of the accumulated result, so the string is built in reverse order. + +In the definition of the `for` loop, there are three expressions inside the parentheses, separated by semicolons: + +1. The initial value of the counter. This code runs exactly once before the first iteration. +2. The predicate — the condition for repeating the loops. It runs on every iteration. Just like in `while`. +3. The description of how the counter changes. This code runs at the end of each iteration. + +In all other respects, the principle of operation is exactly the same as the `while` loop. + +## Another example: counting characters + +Let's count how many times a character occurs in a string, case-insensitively: + +```javascript +const charsCount = (text, char) => { + let result = 0; + for (let i = 0; i < text.length; i += 1) { + // convert to lowercase so as not to depend on the case + if (text[i].toLowerCase() === char.toLowerCase()) { + result += 1; + } + } + return result; +}; + +charsCount('hexlet!', 'e'); // 2 +charsCount('hExlet!', 'E'); // 2 +charsCount('hexlet!', 'a'); // 0 +``` + +Here `for` controls the iteration over characters, while the condition inside decides whether to increment the counter. + +In the `for` definition, you don't have to specify all three expressions. If you don't specify the loop repetition condition, the loop will run infinitely: + +```javascript +let i = 1; +// You don't even have to specify all three expressions +for (;;) { + console.log(i); + i += 1; +} +``` diff --git a/modules/50-loops/70-for/en/data.yml b/modules/50-loops/70-for/en/data.yml index 36c35bde..e3b1db5e 100644 --- a/modules/50-loops/70-for/en/data.yml +++ b/modules/50-loops/70-for/en/data.yml @@ -1,3 +1,12 @@ --- -name: For loop -tips: [] +name: The For Loop +tips: + - | + [for](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for) + + [template strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) + + [Logical OR (||)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR) +definitions: + - name: Aggregation + description: Accumulating a result during iterations and working with it after the loop. diff --git a/modules/50-loops/70-for/es/EXERCISE.md b/modules/50-loops/70-for/es/EXERCISE.md index 14b9cecf..b01e5880 100644 --- a/modules/50-loops/70-for/es/EXERCISE.md +++ b/modules/50-loops/70-for/es/EXERCISE.md @@ -1,14 +1,23 @@ +FizzBuzz es una de las tareas de entrevista más conocidas para programadores principiantes. Se plantea para comprobar la capacidad de trabajar con bucles y condiciones. Implementa una función `fizzBuzz(n)` que devuelve una cadena con los números del 1 al `n`. -Samwell descubrió que sus mensajes estaban siendo interceptados y leídos en la fortaleza "Gemelos", por lo que sus ataques dejaron de ser sorpresivos. Después de pensar un poco, desarrolló un programa que cifra los mensajes transmitidos utilizando el siguiente algoritmo. El programa recibe una cadena como entrada y cambia de lugar cada par de caracteres consecutivos. Si la longitud de la cadena es impar, el último carácter permanece en su lugar. +En este caso: + +- si un número es divisible por 3, en su lugar se sustituye la palabra `"Fizz"`; +- si es divisible por 5, la palabra `"Buzz"`; +- si es divisible tanto por 3 como por 5, la palabra `"FizzBuzz"`. + +Todos los elementos se unen con un espacio. + +Ejemplo de llamada a la función: ```javascript -encrypt('move'); // omev -encrypt('attack'); // taatkc -// Si la longitud de la cadena es impar, -// el último carácter permanece en su lugar -encrypt('go!'); // og! +fizzBuzz(15); +// => '1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz' ``` -Implementa la función `encrypt()`, que recibe el mensaje original como entrada y devuelve el mensaje cifrado. +### Algoritmo -Piensa. ¿Puede esta función descifrar un mensaje cifrado? +1. Declarar el elemento neutro de agregación (una cadena vacía). +2. Recorrer con un bucle `for` los números del 1 al `n`. +3. Comprobar el número según las condiciones de divisibilidad. +4. Añadir el resultado de cada iteración a la cadena final, separado por un espacio. diff --git a/modules/50-loops/70-for/es/README.md b/modules/50-loops/70-for/es/README.md index d09b7d88..c9c3281e 100644 --- a/modules/50-loops/70-for/es/README.md +++ b/modules/50-loops/70-for/es/README.md @@ -14,7 +14,19 @@ const reverseString = (str) => { }; ``` -Se puede leer de la siguiente manera: *el bucle con el índice `i` se repite mientras `i < str.length`. Después de cada paso incrementa `i` en 1*. +Se puede leer de la siguiente manera: *el bucle con el índice `i` se repite mientras `i < str.length` e incrementa `i` en 1 después de cada paso*. + +Analicemos cómo funciona el bucle paso a paso para la llamada `reverseString('go!')`: + +```text +antes del bucle: result = '' + +i=0: result = `${str[0]}${result}` = 'g' + '' = 'g' +i=1: result = `${str[1]}${result}` = 'o' + 'g' = 'og' +i=2: result = `${str[2]}${result}` = '!' + 'og' = '!og' +``` + +Cada nuevo carácter se antepone a la izquierda del resultado acumulado, por lo que la cadena se construye en orden inverso. En la definición del bucle `for`, entre paréntesis, hay tres expresiones separadas por punto y coma: @@ -24,6 +36,29 @@ En la definición del bucle `for`, entre paréntesis, hay tres expresiones separ En lo demás, el funcionamiento es exactamente igual al del bucle `while`. +## Otro ejemplo: contar caracteres + +Contemos cuántas veces aparece un carácter en una cadena, sin distinguir entre mayúsculas y minúsculas: + +```javascript +const charsCount = (text, char) => { + let result = 0; + for (let i = 0; i < text.length; i += 1) { + // convertimos a minúsculas para no depender de mayúsculas y minúsculas + if (text[i].toLowerCase() === char.toLowerCase()) { + result += 1; + } + } + return result; +}; + +charsCount('hexlet!', 'e'); // 2 +charsCount('hExlet!', 'E'); // 2 +charsCount('hexlet!', 'a'); // 0 +``` + +Aquí `for` controla el recorrido de los caracteres, mientras que la condición interna decide si incrementar el contador. + En la definición de `for`, no es necesario especificar las tres expresiones. Si no se especifica la condición de repetición del bucle, el bucle se ejecutará infinitamente: ```javascript diff --git a/modules/50-loops/70-for/es/data.yml b/modules/50-loops/70-for/es/data.yml index 2182656c..5b48c7f8 100644 --- a/modules/50-loops/70-for/es/data.yml +++ b/modules/50-loops/70-for/es/data.yml @@ -1,16 +1,12 @@ --- name: Bucle For tips: - - > + - | [for](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/for) - [plantillas de - cadena](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Template_literals) + [plantillas de cadena](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Template_literals) - [Operador lógico OR - (||)](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Logical_OR) + [Operador lógico OR (||)](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Logical_OR) definitions: - name: Agregación - description: >- - Acumulación de resultados durante las iteraciones y trabajo con ellos - después del bucle. + description: Acumulación de resultados durante las iteraciones y trabajo con ellos después del bucle.