diff --git a/modules/10-basics/10-hello-world/es/EXERCISE.md b/modules/10-basics/10-hello-world/es/EXERCISE.md new file mode 100644 index 00000000..e2dbe21c --- /dev/null +++ b/modules/10-basics/10-hello-world/es/EXERCISE.md @@ -0,0 +1,11 @@ +Escribe en el editor el código del ejercicio carácter por carácter y haz clic en "Verificar". + +```java +class App { + public static void main(String[] args) { + System.out.println("Hello, World!"); + } +} +``` + +Si escribes *heLLo, woRld!* en lugar de *¡Hola, Mundo!*, se considerará un texto diferente, ya que las mayúsculas y minúsculas son caracteres distintos. El tamaño de las letras se llama *mayúsculas y minúsculas*, y se dice: **¡las mayúsculas y minúsculas importan!** Esto se aplica a casi todo 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 new file mode 100644 index 00000000..990fb5a3 --- /dev/null +++ b/modules/10-basics/10-hello-world/es/README.md @@ -0,0 +1,41 @@ +Tradicionalmente, se comienza a aprender un lenguaje de programación con el programa "Hello, World!", que muestra este texto en la pantalla. + +
+ ¡Hola, Mundo! ++ +En Java, este programa se vería así: + +```java +class App { + public static void main(String[] args) { + System.out.println("¡Hola, Mundo!"); + } +} +``` + +https://replit.com/@hexlet/java-basics-hello-world + +El texto *¡Hola, Mundo!* aparecerá en la pantalla gracias al comando `System.out.println()`, donde `println()` es una abreviatura de la expresión en inglés *print line*. Este comando muestra en la pantalla el valor especificado entre paréntesis `("¡Hola, Mundo!")`, en este caso, una cadena de texto. La cadena de texto se encierra entre comillas dobles `""`. Si no se hace esto, el compilador mostrará un error de sintaxis: + +```bash +# Por ejemplo, así +App.java:5: error: unclosed character literal +System.out.println('¡Hola, Mundo!'); +``` + +Este comando se encuentra dentro de varias construcciones que son necesarias incluso para los programas más simples en Java. En este caso, se trata de la clase `App` y el método `main()`. + +Por ahora, no nos detendremos en ellos, ya que para entenderlos es necesario tener un poco de conocimiento en programación. Por lo tanto, en muchos ejercicios se proporcionan "tal cual", es decir, no tendrás que definirlos tú mismo. Cuando llegue el momento, los analizaremos. + +## JShell + +A medida que avances en las lecciones, te encontrarás constantemente con ejemplos de código y descripciones de su funcionamiento. Para comprenderlos mejor y poder utilizar el lenguaje, es necesario practicar y experimentar constantemente. + +Por lo tanto, siempre que sea posible, ejecuta todos los ejemplos de la teoría y realiza experimentos con los aspectos que no entiendas. + +La forma más sencilla de comenzar con Java es en el sitio web [onecompiler](https://onecompiler.com/jshell), que te permite ejecutar el código línea por línea directamente en el navegador. Intenta ir allí ahora mismo y escribir este código: + +``` +System.out.println(85 * 3); +``` diff --git a/modules/10-basics/10-hello-world/es/data.yml b/modules/10-basics/10-hello-world/es/data.yml new file mode 100644 index 00000000..502e9352 --- /dev/null +++ b/modules/10-basics/10-hello-world/es/data.yml @@ -0,0 +1,7 @@ +name: ¡Hola, Mundo! +tips: + - > + Si en el editor hay una línea que dice `// BEGIN` y `// END`, el código debe + escribirse entre esas líneas. + - | + [¿Qué es un compilador?](https://codica.la/guides/compiler/) diff --git a/modules/10-basics/10-hello-world/ru/EXERCISE.md b/modules/10-basics/10-hello-world/ru/EXERCISE.md new file mode 100644 index 00000000..86f37882 --- /dev/null +++ b/modules/10-basics/10-hello-world/ru/EXERCISE.md @@ -0,0 +1,11 @@ +Наберите в редакторе код из задания символ в символ и нажмите «Проверить». + +```java +class App { + public static void main(String[] args) { + System.out.println("Hello, World!"); + } +} +``` + +Если вы напишете *heLLo, woRld!* вместо *Hello, World!*, то это будет считаться другим текстом, потому что заглавные и строчные буквы — это разные символы. Размер буквы называют *регистром*, и говорят: **регистр — важен!** Это касается почти всего в коде, поэтому привыкайте всегда обращать внимание на регистр. diff --git a/modules/10-basics/10-hello-world/ru/README.md b/modules/10-basics/10-hello-world/ru/README.md new file mode 100644 index 00000000..26496f96 --- /dev/null +++ b/modules/10-basics/10-hello-world/ru/README.md @@ -0,0 +1,42 @@ +Изучать язык программирования по традиции начинают с программы "Hello, World!", которая выводит этот текст на экран. + +
+ Hello, World! ++ +На языке Java эта программа будет выглядеть так: + +```java +class App { + public static void main(String[] args) { + System.out.println("Hello, World!"); + } +} +``` + +https://replit.com/@hexlet/java-basics-hello-world + +Текст *Hello, World!* появится на экране благодаря команде `System.out.println()`, где `println()` — это сокращение от английского *print line*. Она выводит на экран значение, указанное в скобках `("Hello, World!")` — в данном случае строку. Сама строка обрамляется двойными кавычками `""`. Если этого не сделать, то компилятор укажет на синтаксическую ошибку: + +```bash +# Например, вот так +App.java:5: error: unclosed character literal +System.out.println('Hello, World!'); +``` + +Сама команда находится внутри нескольких конструкций, которые нужны для работы даже простейших программ на Java. +В данном случае это класс `App` и метод `main()`. + +Сейчас мы не будем на них останавливаться, так как для их понимания нужно уметь немного программировать. Поэтому во многих заданиях они даются «как есть», то есть вам не придется их задавать самостоятельно. Когда придет время, мы их разберем. + +## JShell + +Двигаясь по урокам, вы постоянно будете встречаться с примерами кода и описаниями его работы. Чтобы их лучше понимать и уметь пользоваться языком, нужно постоянно практиковаться и экспериментировать. + +Поэтому по возможности запускайте все примеры из теории и проводите эксперименты с непонятными моментами. + +С Java проще всего начать на сайте [onecompiler](https://onecompiler.com/jshell), который позволяет запускать построчно код прямо в браузере. Попробуйте перейти туда прямо сейчас и набрать такой код: + +``` +System.out.println(85 * 3); +``` diff --git a/modules/10-basics/10-hello-world/ru/data.yml b/modules/10-basics/10-hello-world/ru/data.yml new file mode 100644 index 00000000..34dd3f2a --- /dev/null +++ b/modules/10-basics/10-hello-world/ru/data.yml @@ -0,0 +1,7 @@ +name: Привет, Мир! +tips: + - > + Если в редакторе есть запись `// BEGIN` и `// END`, то код нужно писать + между этими строчками. + - | + [Что такое компилятор?](https://guides.hexlet.io/compiler/) diff --git a/modules/10-basics/20-comments/es/EXERCISE.md b/modules/10-basics/20-comments/es/EXERCISE.md new file mode 100644 index 00000000..5c4bea9d --- /dev/null +++ b/modules/10-basics/20-comments/es/EXERCISE.md @@ -0,0 +1 @@ +Crea un comentario de una línea con el texto: *No sabes nada, Jon Nieve!*. diff --git a/modules/10-basics/20-comments/es/README.md b/modules/10-basics/20-comments/es/README.md new file mode 100644 index 00000000..06d5e16f --- /dev/null +++ b/modules/10-basics/20-comments/es/README.md @@ -0,0 +1,31 @@ +Casi todos los lenguajes de programación permiten dejar comentarios en el código. Estos comentarios no son utilizados por el código y son únicamente para las personas: para que los programadores dejen notas para sí mismos y para otros programadores. + +En Java, hay tres tipos de comentarios: + +* **Comentarios de una línea** que comienzan con `//`. Después de estos dos caracteres puede seguir cualquier texto, la línea completa no será analizada ni ejecutada. + + El comentario puede ocupar toda la línea: + + ```java + // Por Winterfell! + ``` + + También el comentario puede estar en la línea después de algún código: + + ```java + System.out.println("Soy el Rey"); // => Por los Lannister! + ``` + +* **Comentarios de varias líneas** que comienzan con `/*` y terminan con `*/`. Es común comenzar cada línea con el carácter `*`, aunque técnicamente no es obligatorio: + + ```java + /* + * La noche es oscura y + * está llena de terrores. + */ + System.out.println("Soy el Rey"); // => Soy el Rey + ``` + +* **Comentarios de documentación** que comienzan con `/**` y terminan con `*/`. Para estos comentarios es obligatorio comenzar cada línea con el carácter `*`. + + Los comentarios de documentación son un subtipo de los comentarios de varias líneas. Además, tienen una función adicional: se pueden recopilar con la herramienta especial javadoc y se pueden generar como documentación para su código. Hablaremos de ellos más adelante, cuando veamos las clases y los métodos. diff --git a/modules/10-basics/20-comments/es/data.yml b/modules/10-basics/20-comments/es/data.yml new file mode 100644 index 00000000..4566c55b --- /dev/null +++ b/modules/10-basics/20-comments/es/data.yml @@ -0,0 +1 @@ +name: Comentarios diff --git a/modules/10-basics/20-comments/ru/EXERCISE.md b/modules/10-basics/20-comments/ru/EXERCISE.md new file mode 100644 index 00000000..2b78e678 --- /dev/null +++ b/modules/10-basics/20-comments/ru/EXERCISE.md @@ -0,0 +1 @@ +Создайте однострочный комментарий с текстом: *You know nothing, Jon Snow!*. diff --git a/modules/10-basics/20-comments/ru/README.md b/modules/10-basics/20-comments/ru/README.md new file mode 100644 index 00000000..4ab3673c --- /dev/null +++ b/modules/10-basics/20-comments/ru/README.md @@ -0,0 +1,31 @@ +Практически все языки программирования позволяют оставлять в коде комментарии. Они никак не используются кодом и нужны исключительно для людей: чтобы программист оставлял пометки для себя и для других программистов. + +Комментарии в Java бывают трех видов: + +* **Однострочные комментарии** начинаются с `//`. После этих двух символов может следовать любой текст, вся строка не будет анализироваться и исполняться. + + Комментарий может занимать всю строку: + + ```java + // For Winterfell! + ``` + + Также комментарий может находиться на строке после какого-нибудь кода: + + ```java + System.out.println("I am the King"); // => For Lannisters! + ``` + +* *Многострочные комментарии* начинаются с `/*` и заканчиваются на `*/`. Принято каждую строку начинать с символа `*`, хотя технически это и необязательно: + + ```java + /* + * The night is dark and + * full of terrors. + */ + System.out.println("I am the King"); // => I am the King + ``` + +* **Документирующие комментарии** начинаются с `/**` и заканчиваются на `*/`. Уже для них обязательно каждую строку начинать с символа `*`. + + Документирующие комментарии — это подвид многострочных. При этом несут дополнительную функцию — их можно собрать при помощи специальной утилиты javadoc и выдать в качестве документации к вашему коду. Мы поговорим о них позже – когда разберем классы и методы. diff --git a/modules/10-basics/20-comments/ru/data.yml b/modules/10-basics/20-comments/ru/data.yml new file mode 100644 index 00000000..4ec7171b --- /dev/null +++ b/modules/10-basics/20-comments/ru/data.yml @@ -0,0 +1 @@ +name: Комментарии diff --git a/modules/10-basics/30-statements/es/EXERCISE.md b/modules/10-basics/30-statements/es/EXERCISE.md new file mode 100644 index 00000000..c07aa02c --- /dev/null +++ b/modules/10-basics/30-statements/es/EXERCISE.md @@ -0,0 +1,9 @@ +Imprime en pantalla uno tras otro tres nombres: *Robert*, *Stannis*, *Renly*. Como resultado, se mostrará en pantalla: + +
+Robert +Stannis +Renly ++ +Utiliza una llamada `System.out.println()` para cada nombre. diff --git a/modules/10-basics/30-statements/es/README.md b/modules/10-basics/30-statements/es/README.md new file mode 100644 index 00000000..96934f7c --- /dev/null +++ b/modules/10-basics/30-statements/es/README.md @@ -0,0 +1,23 @@ +Una instrucción es un comando para la computadora. El código en Java es un conjunto de instrucciones que generalmente se separan entre sí con el símbolo `;`. Aquí hay un ejemplo de código con dos instrucciones: + +```java +System.out.println("Madre de Dragones"); +System.out.println("¡Dracarys!"); +``` + +Al ejecutar este código, se mostrarán en pantalla dos frases de forma secuencial: + +
+Madre de Dragones +¡Dracarys! ++ +¿Por qué es importante saber esto? Una instrucción es una unidad de ejecución. El programa que ejecuta el código en Java realiza las instrucciones estrictamente en orden. Los desarrolladores deben comprender este orden y ser capaces de dividir mentalmente el programa en partes independientes que sean fáciles de analizar. + +Teóricamente, las instrucciones se pueden escribir una tras otra sin saltar a una nueva línea: + +```java +System.out.println("Madre de Dragones."); System.out.println("¡Dracarys!"); +``` + +El resultado en pantalla será el mismo, pero en la práctica, este enfoque se considera incorrecto. diff --git a/modules/10-basics/30-statements/es/data.yml b/modules/10-basics/30-statements/es/data.yml new file mode 100644 index 00000000..5f31df85 --- /dev/null +++ b/modules/10-basics/30-statements/es/data.yml @@ -0,0 +1 @@ +name: Instrucciones diff --git a/modules/10-basics/30-statements/ru/EXERCISE.md b/modules/10-basics/30-statements/ru/EXERCISE.md new file mode 100644 index 00000000..3d3a5846 --- /dev/null +++ b/modules/10-basics/30-statements/ru/EXERCISE.md @@ -0,0 +1,9 @@ +Выведите на экран друг за другом три имени: *Robert*, *Stannis*, *Renly*. В результате на экране должно отобразиться: + +
+Robert +Stannis +Renly ++ +Для каждого имени используйте свой собственный вызов `System.out.println()`. diff --git a/modules/10-basics/30-statements/ru/README.md b/modules/10-basics/30-statements/ru/README.md new file mode 100644 index 00000000..1fc691af --- /dev/null +++ b/modules/10-basics/30-statements/ru/README.md @@ -0,0 +1,23 @@ +Инструкция — это команда для компьютера. Код на Java — это набор инструкций, которые, обычно, отделяются друг от друга символом `;`. Вот пример кода с двумя инструкциями: + +```java +System.out.println("Mother of Dragons"); +System.out.println("Dracarys!"); +``` + +При запуске этого кода на экран последовательно выводятся два предложения: + +
+Mother of Dragons +Dracarys! ++ +Почему это важно знать? Инструкция — это единица исполнения. Программа, которая запускает код на Java, выполняет инструкции строго по очереди. Разработчики должны понимать этот порядок и уметь мысленно разделять программу на независимые части, удобные для анализа. + +Теоретически инструкции можно написать последовательно друг за другом без переноса на новую строчку: + +```java +System.out.println("Mother of Dragons."); System.out.println("Dracarys!"); +``` + +Результат на экране будет таким же, но на практике такой подход считается плохим. diff --git a/modules/10-basics/30-statements/ru/data.yml b/modules/10-basics/30-statements/ru/data.yml new file mode 100644 index 00000000..a8c513b9 --- /dev/null +++ b/modules/10-basics/30-statements/ru/data.yml @@ -0,0 +1 @@ +name: Инструкции (Statements) diff --git a/modules/10-basics/40-testing/es/EXERCISE.md b/modules/10-basics/40-testing/es/EXERCISE.md new file mode 100644 index 00000000..faf853f9 --- /dev/null +++ b/modules/10-basics/40-testing/es/EXERCISE.md @@ -0,0 +1,7 @@ +Solo es un ejercicio. Muestra en la pantalla el número 420262531. + +
+420262531 ++ +Experimenta con la salida. Pasa otro número o una cadena. Observa la respuesta del sistema, intenta traducirla y entenderla. diff --git a/modules/10-basics/40-testing/es/README.md b/modules/10-basics/40-testing/es/README.md new file mode 100644 index 00000000..5c3dd5e3 --- /dev/null +++ b/modules/10-basics/40-testing/es/README.md @@ -0,0 +1,21 @@ +Nuestro sitio web verifica automáticamente tus soluciones. ¿Cómo funciona? + +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 métodos, que son pequeños programas que toman información del mundo exterior y realizan ciertas 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 exacta debería devolver el método correcto para esos datos de entrada. + +Por ejemplo, si tu tarea es escribir código para sumar dos números, el sistema de verificación le pasará diferentes combinaciones de números y comparará la respuesta de tu código con las sumas reales. Si las respuestas coinciden en todos los casos, la solución se considera correcta. + +Aquí tienes un ejemplo sencillo: en una de las futuras lecciones, tendrás que escribir código que realice cálculos y devuelva una respuesta. Supongamos que cometiste un pequeño error y el método devolvió un número incorrecto. El sistema responderá algo como esto: + +
expected: "35" but was: "10"+ +Lo más importante comienza después de los dos puntos: "se esperaba: "35", pero fue "10"". Es decir, el código correcto debería haber devuelto 35, pero la solución actual no funciona correctamente y devuelve 10. + +Además de nuestras pruebas, será extremadamente útil utilizar el servicio [repl.it](https://repl.it/languages/java). + +--- + +A veces, durante el proceso de resolución, puede parecer que has hecho todo correctamente, pero el sistema se "comporta de manera caprichosa" y no acepta la solución. Este comportamiento es prácticamente imposible. Las pruebas no funcionales simplemente no pueden llegar al sitio web, 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 a lo largo de los 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 de la tarea y los resultados de las pruebas. Casi seguro que habrá alguna indicación del error. + +Sin embargo, si estás seguro del 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 es completamente abierto!). Al ir allí, puedes escribir un issue, ver el contenido de las pruebas (se puede ver cómo se llama tu código) e incluso enviar un pull request. Si esto todavía te resulta confuso, únete a nuestra comunidad en [Comunidad de Hexlet en Telegram](https://t.me/hexletcommunity/12), allí en el canal de Voluntarios siempre estaremos dispuestos a ayudar. diff --git a/modules/10-basics/40-testing/es/data.yml b/modules/10-basics/40-testing/es/data.yml new file mode 100644 index 00000000..278b83b1 --- /dev/null +++ b/modules/10-basics/40-testing/es/data.yml @@ -0,0 +1,11 @@ +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/12) diff --git a/modules/10-basics/40-testing/ru/EXERCISE.md b/modules/10-basics/40-testing/ru/EXERCISE.md new file mode 100644 index 00000000..a6a99b16 --- /dev/null +++ b/modules/10-basics/40-testing/ru/EXERCISE.md @@ -0,0 +1,7 @@ +Просто тренировка. Выведите на экран число 420262531. + +
+420262531 ++ +Поэкспериментируйте с выводом. Передайте туда другое число или строку. Посмотрите на ответ системы, попробуйте его перевести и понять. diff --git a/modules/10-basics/40-testing/ru/README.md b/modules/10-basics/40-testing/ru/README.md new file mode 100644 index 00000000..c835717c --- /dev/null +++ b/modules/10-basics/40-testing/ru/README.md @@ -0,0 +1,21 @@ +Наш сайт автоматически проверяет ваши решения. Как это работает? + +В самом простом случае система просто запускает ваш код и смотрит на то, что вывелось на экран. А потом сверяет с тем, что мы «ожидали» по заданию. + +В следующих, более сложных уроках вы будете писать методы — некие мини-программы, принимающие информацию из внешнего мира и производящие какие-то операции. Проверка ваших решений в таких случаях выглядит немного сложнее: система запускает ваше решение и передаёт какую-то информацию. Система также знает — «ожидает» — какой именно ответ должен вернуть правильный метод при таких входных данных. + +Например, если ваша задача — написать код для сложения двух чисел, то проверочная система будет передавать ему разные комбинации чисел и сверять ответ вашего кода с реальными суммами. Если во всех случаях ответы совпадут, то решение считается верным. + +Вот простой пример: в одном из будущих уроков вам нужно будет написать код, который производит вычисления и выдаёт ответ. Допустим, вы допустили небольшую ошибку, и метод выдал неправильное число. Система ответит примерно так: + +
expected: "35" but was: "10"+ +Самое главное начинается после двоеточия: «ожидалось: "35", но было "10"». То есть правильный код должен был выдать 35, но текущее решение работает неправильно и выдаёт 10. + +Кроме наших тестов, будет крайне полезно использовать сервис [repl.it](https://repl.it/languages/java). + +--- + +Иногда в процессе решения будет казаться, что вы сделали все правильно, но система "капризничает" и не принимает решение. Подобное поведение практически исключено. Нерабочие тесты просто не могут попасть на сайт, они автоматически запускаются после каждого изменения. В подавляющем большинстве таких случаев, (а все наши проекты в сумме провели миллионы проверок за много лет), ошибка содержится в коде решения. Она может быть очень незаметной, вместо английской буквы случайно ввели русскую, вместо верхнего регистра использовали нижний или забыли вывести запятую. Другие случаи сложнее. Возможно ваше решение работает для одного набора входных данных, но не работает для другого. Поэтому всегда внимательно читайте условие задачи и вывод тестов. Там почти наверняка есть указание на ошибку. + +Однако, если вы уверены в ошибке или нашли какую-то неточность, то вы всегда можете указать на нее. В конце каждой теории есть ссылка на содержимое урока на гитхабе (этот проект полностью открытый!). Перейдя туда, вы можете написать issue, посмотреть содержимое тестов (там видно, как вызывается ваш код) и даже отправить pullrequest. Если для вас это пока темный лес, то подключитесь в наше сообщество [Сообщество Хекслета в Telegram](https://t.me/hexletcommunity/12), там в канале Волонтеры мы всегда поможем. diff --git a/modules/10-basics/40-testing/ru/data.yml b/modules/10-basics/40-testing/ru/data.yml new file mode 100644 index 00000000..31368ce8 --- /dev/null +++ b/modules/10-basics/40-testing/ru/data.yml @@ -0,0 +1,11 @@ +name: Как мы проверяем ваши решения +definitions: + - name: Тесты + description: > + специальный код, проверяющий программы на корректность, сверяя правильный + результат с реальным. +tips: + - | + [TDD](https://ru.wikipedia.org/wiki/Разработка_через_тестирование) + - | + [Сообщество Хекслета в Telegram](https://t.me/hexletcommunity/12) diff --git a/modules/10-basics/50-syntax-error/es/EXERCISE.md b/modules/10-basics/50-syntax-error/es/EXERCISE.md new file mode 100644 index 00000000..4b773853 --- /dev/null +++ b/modules/10-basics/50-syntax-error/es/EXERCISE.md @@ -0,0 +1,2 @@ + +Esta tarea no está directamente relacionada con la lección, pero será útil practicar la salida en pantalla. Imprime en pantalla *What Is Dead May Never Die*. diff --git a/modules/10-basics/50-syntax-error/es/README.md b/modules/10-basics/50-syntax-error/es/README.md new file mode 100644 index 00000000..da7cd5e2 --- /dev/null +++ b/modules/10-basics/50-syntax-error/es/README.md @@ -0,0 +1,27 @@ +En los lenguajes humanos, la gramática es importante, pero generalmente se puede entender y leer un texto con errores. En la programación, todo es estricto. Cualquier pequeña violación y el programa no se ejecutará. + +Un ejemplo puede ser un punto y coma olvidado, paréntesis mal colocados y otros detalles. Estos errores se llaman **errores de sintaxis** porque violan las reglas de sintaxis del lenguaje. + +Si un programa escrito en Java es sintácticamente incorrecto, el compilador muestra en pantalla: + +* Un mensaje de error +* Una indicación del archivo +* La línea en el archivo donde, según el compilador, ocurrió el error + +A continuación se muestra un ejemplo de código con un error de sintaxis: + +```java +System.out.println("alala +``` + +Si ejecutamos el código anterior, veremos el siguiente mensaje: + +
+| Error: +| unclosed string literal +| System.out.println("alala ++ +Por un lado, los errores de sintaxis son los más simples porque están relacionados únicamente con las reglas gramaticales de escribir código, no con el significado del código en sí. Son fáciles de corregir, solo hay que encontrar la violación en la escritura. + +Por otro lado, el compilador no siempre puede señalar claramente esta violación. Por lo tanto, a veces es necesario colocar el paréntesis olvidado no donde indica el mensaje de error. diff --git a/modules/10-basics/50-syntax-error/es/data.yml b/modules/10-basics/50-syntax-error/es/data.yml new file mode 100644 index 00000000..be8a418a --- /dev/null +++ b/modules/10-basics/50-syntax-error/es/data.yml @@ -0,0 +1,8 @@ +name: Errores de sintaxis +definitions: + - name: Compilador + description: >- + Un programa que realiza la transformación del código fuente a un lenguaje + de bajo nivel adecuado para la ejecución. + - name: Error de sintaxis + description: Una violación de las reglas gramaticales del lenguaje de programación. diff --git a/modules/10-basics/50-syntax-error/ru/EXERCISE.md b/modules/10-basics/50-syntax-error/ru/EXERCISE.md new file mode 100644 index 00000000..18314ebe --- /dev/null +++ b/modules/10-basics/50-syntax-error/ru/EXERCISE.md @@ -0,0 +1,2 @@ + +Это задание не связано с уроком напрямую. Но будет полезным потренироваться с выводом на экран. Выведите на экран *What Is Dead May Never Die* diff --git a/modules/10-basics/50-syntax-error/ru/README.md b/modules/10-basics/50-syntax-error/ru/README.md new file mode 100644 index 00000000..f726517b --- /dev/null +++ b/modules/10-basics/50-syntax-error/ru/README.md @@ -0,0 +1,27 @@ +В человеческих языках грамматика важна, но текст с ошибками чаще всего можно понять и прочитать. В программировании все строго. Любое мельчайшее нарушение, и программа не запустится. + +Примером может быть забытая `;`, неправильно расставленные скобки и другие детали. Подобные ошибки называются **синтаксическими**, потому что они нарушают правила синтаксиса языка. + +Если программа на Java написана синтаксически некорректно, то компилятор выводит на экран: + +* Сообщение об ошибке +* Указание на файл +* Строчка в файле, где по его мнению произошла ошибка + +Ниже пример кода с синтаксической ошибкой: + +```java +System.out.println("alala +``` + +Если запустить код выше, то мы увидим следующее сообщение: + +
+| Error: +| unclosed string literal +| System.out.println("alala ++ +С одной стороны, ошибки синтаксиса — самые простые, потому что они связаны исключительно с грамматическими правилами написания кода, а не с самим смыслом кода. Их легко исправить — нужно лишь найти нарушение в записи. + +С другой стороны, компилятор не всегда может четко указать на это нарушение. Поэтому бывает, что забытую скобку нужно поставить не туда, куда указывает сообщение об ошибке. diff --git a/modules/10-basics/50-syntax-error/ru/data.yml b/modules/10-basics/50-syntax-error/ru/data.yml new file mode 100644 index 00000000..d1785be0 --- /dev/null +++ b/modules/10-basics/50-syntax-error/ru/data.yml @@ -0,0 +1,8 @@ +name: Ошибки оформления (синтаксиса) +definitions: + - name: Компилятор + description: >- + Программа выполняющая преобразование исходного кода в низкоуровневый язык + подходящий для выполнения + - name: Синтаксическая ошибка + description: Нарушение грамматических правил языка программирования diff --git a/modules/20-arithmetics/10-basics/es/EXERCISE.md b/modules/20-arithmetics/10-basics/es/EXERCISE.md new file mode 100644 index 00000000..af1a905f --- /dev/null +++ b/modules/20-arithmetics/10-basics/es/EXERCISE.md @@ -0,0 +1,2 @@ + +Muestra en pantalla el resultado de dividir el número *81* entre *9*. diff --git a/modules/20-arithmetics/10-basics/es/README.md b/modules/20-arithmetics/10-basics/es/README.md new file mode 100644 index 00000000..54b13027 --- /dev/null +++ b/modules/20-arithmetics/10-basics/es/README.md @@ -0,0 +1,44 @@ +A nivel básico, las computadoras operan solo 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: + +```java +class App { + public static void main(String[] args) { + 3 + 4; + } +} +``` + +Si ejecutas este programa, se ejecutará en silencio y finalizará. No se mostrará nada en la pantalla. La operación de suma, al igual que las demás operaciones, no hace nada más que sumar. + +Para utilizar el resultado de la suma, debes mostrarlo en la pantalla: + +```java +System.out.println(3 + 4); +``` + +Después de ejecutarlo, se mostrará el resultado en la pantalla: + +
7+ +Además de la suma, están disponibles las siguientes operaciones: + +* `*` — multiplicación +* `/` — división +* `-` — resta +* `%` — [módulo](https://es.wikipedia.org/wiki/Operaci%C3%B3n_m%C3%B3dulo) + +Ahora, vamos a mostrar en pantalla el resultado de una división y luego el resultado de elevar un número a una potencia: + +```java +System.out.println(8 / 2); +System.out.println(3 * 3 * 3); +``` + +
+4 +27 +diff --git a/modules/20-arithmetics/10-basics/es/data.yml b/modules/20-arithmetics/10-basics/es/data.yml new file mode 100644 index 00000000..826fdfa3 --- /dev/null +++ b/modules/20-arithmetics/10-basics/es/data.yml @@ -0,0 +1,5 @@ +name: Operaciones aritméticas +tips: + - >- + La división por cero produce un error. Para evitarlo, debes conocer las + estructuras condicionales (las aprenderás en las próximas lecciones). diff --git a/modules/20-arithmetics/10-basics/ru/EXERCISE.md b/modules/20-arithmetics/10-basics/ru/EXERCISE.md new file mode 100644 index 00000000..6a4d4b03 --- /dev/null +++ b/modules/20-arithmetics/10-basics/ru/EXERCISE.md @@ -0,0 +1,2 @@ + +Выведите на экран результат деления числа *81* на *9*. diff --git a/modules/20-arithmetics/10-basics/ru/README.md b/modules/20-arithmetics/10-basics/ru/README.md new file mode 100644 index 00000000..f255d5ac --- /dev/null +++ b/modules/20-arithmetics/10-basics/ru/README.md @@ -0,0 +1,44 @@ +На базовом уровне компьютеры оперируют только числами. Даже в прикладных программах на высокоуровневых языках внутри много чисел и операций над ними. + +К счастью, для старта достаточно знать обычную арифметику — с нее и начнем. + +Для сложения двух чисел в математике мы пишем, например, *3 + 4*. В программировании — то же самое. Вот программа, складывающая два числа: + +```java +class App { + public static void main(String[] args) { + 3 + 4; + } +} +``` + +Если запустить эту программу на выполнение, то она тихо отработает и завершится. На экран ничего не будет выведено. Операция сложения, как и остальные операции, сама по себе ничего не делает, кроме сложения. + +Чтобы воспользоваться результатом сложения, его нужно вывести на экран: + +```java +System.out.println(3 + 4); +``` + +После запуска на экране появится результат: + +
7+ +Кроме сложения доступны следующие операции: + +* `*` — умножение +* `/` — деление +* `-` — вычитание +* `%` — [остаток от деления](https://ru.wikipedia.org/wiki/Деление_с_остатком) + +Теперь давайте выведем на экран результат деления, а потом результат возведения в степень: + +```java +System.out.println(8 / 2); +System.out.println(3 * 3 * 3); +``` + +
+4 +27 +diff --git a/modules/20-arithmetics/10-basics/ru/data.yml b/modules/20-arithmetics/10-basics/ru/data.yml new file mode 100644 index 00000000..c624915a --- /dev/null +++ b/modules/20-arithmetics/10-basics/ru/data.yml @@ -0,0 +1,5 @@ +name: Арифметические операции +tips: + - >- + Деление на ноль приводит к ошибке. Чтобы его не допустить, нужно знать про + условные конструкции (о них вы узнаете в следующих уроках). diff --git a/modules/20-arithmetics/20-operators/es/EXERCISE.md b/modules/20-arithmetics/20-operators/es/EXERCISE.md new file mode 100644 index 00000000..ad7f1423 --- /dev/null +++ b/modules/20-arithmetics/20-operators/es/EXERCISE.md @@ -0,0 +1,2 @@ + +Escribe un programa que calcule la diferencia entre los números `6` y `-81` y muestre la respuesta en pantalla. diff --git a/modules/20-arithmetics/20-operators/es/README.md b/modules/20-arithmetics/20-operators/es/README.md new file mode 100644 index 00000000..f6b11faf --- /dev/null +++ b/modules/20-arithmetics/20-operators/es/README.md @@ -0,0 +1,33 @@ +Antes de continuar, vamos a repasar la terminología básica. Un signo de operación, como `+`, se llama operador. Un **operador** es simplemente un símbolo que realiza una operación, como la suma: + +```java +System.out.println(8 + 2); // => 10 +``` + +En este ejemplo, `+` es el operador, y los números *8* y *2* son los **operandos**. + +En el caso de la suma, tenemos dos operandos: + +* Uno a la izquierda +* Otro a la derecha del signo *+* + +Las operaciones que requieren dos operandos se llaman **binarias**. Si falta al menos un operando, el programa dará un error de sintaxis. Por ejemplo: + +``` +`3 + ;` +``` + +Las operaciones no solo pueden ser binarias. También pueden ser: + +* Unarias: con un solo operando +* Ternarias: con tres operandos + +Además, los operadores pueden tener la misma apariencia pero representar operaciones diferentes: + +```java +System.out.println(-3); // => -3 +``` + +En el ejemplo anterior, se aplica una operación unaria al número *3*. El operador "menos" antes del tres le indica al intérprete que tome el número *3* y encuentre su opuesto, es decir, *-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 así es la estructura de los lenguajes de programación. diff --git a/modules/20-arithmetics/20-operators/es/data.yml b/modules/20-arithmetics/20-operators/es/data.yml new file mode 100644 index 00000000..4d4cc6af --- /dev/null +++ b/modules/20-arithmetics/20-operators/es/data.yml @@ -0,0 +1,18 @@ +name: Operadores +definitions: + - name: Operación aritmética + description: suma, resta, multiplicación y división. + - name: Operador + description: >- + un símbolo especial que crea una operación. Por ejemplo, `+` crea una + operación de suma. + - name: Operando + description: >- + un objeto que participa en una operación. `3 * 6`: aquí, 3 y 6 son + operandos. + - name: Operación unaria + description: >- + una 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 + description: una operación con dos operandos. Por ejemplo, `3 + 9`. diff --git a/modules/20-arithmetics/20-operators/ru/EXERCISE.md b/modules/20-arithmetics/20-operators/ru/EXERCISE.md new file mode 100644 index 00000000..06cfd474 --- /dev/null +++ b/modules/20-arithmetics/20-operators/ru/EXERCISE.md @@ -0,0 +1,2 @@ + +Напишите программу, которая посчитает разность между числами `6` и `-81` и выведет ответ на экран. diff --git a/modules/20-arithmetics/20-operators/ru/README.md b/modules/20-arithmetics/20-operators/ru/README.md new file mode 100644 index 00000000..852752e4 --- /dev/null +++ b/modules/20-arithmetics/20-operators/ru/README.md @@ -0,0 +1,33 @@ +Перед тем, как двигаться дальше, разберем базовую терминологию. Знак операции, такой как `+`, называют оператором. **Оператор** — просто символ, который выполняет операцию, например, сложение: + +```java +System.out.println(8 + 2); // => 10 +``` + +В этом примере `+` — это оператор, а числа *8* и *2* — это **операнды**. + +В случае сложения у нас есть два операнда: + +* Один слева +* Другой справа от знака *+* + +Операции, которые требуют наличия двух операндов, называются **бинарными**. Если пропустить хотя бы один операнд, то программа завершится с синтаксической ошибкой. Например: + +``` +`3 + ;` +``` + +Операции бывают не только бинарными. Бывают еще: + +* Унарные — с одним операндом +* Тернарные — с тремя операндами + +Причем операторы могут выглядеть одинаково, но обозначать разные операции: + +```java +System.out.println(-3); // => -3 +``` + +Выше пример применения унарной операции к числу *3*. Оператор «минус» перед тройкой говорит интерпретатору — возьми число *3* и найди противоположное, то есть *-3*. + +Это немного может сбить с толку, потому что *-3* — это одновременно и число само по себе, и оператор с операндом, но у языков программирования такая структура. diff --git a/modules/20-arithmetics/20-operators/ru/data.yml b/modules/20-arithmetics/20-operators/ru/data.yml new file mode 100644 index 00000000..e0e8a5cf --- /dev/null +++ b/modules/20-arithmetics/20-operators/ru/data.yml @@ -0,0 +1,16 @@ +name: Операторы +definitions: + - name: Арифметическая операция + description: сложение, вычитание, умножение и деление. + - name: Оператор + description: >- + специальный символ, создающий операцию. Например, `+` создает операцию + сложения. + - name: Операнд + description: 'объект, который участвует в операции. `3 * 6`: здесь 3 и 6 — операнды.' + - name: Унарная операция + description: >- + операция с одним операндом. Например, `-3` — унарная операция для + получения числа, противоположного числу три. + - name: Бинарная операция + description: операция с двумя операндами. Например, `3 + 9`. diff --git a/modules/20-arithmetics/30-commutative/es/EXERCISE.md b/modules/20-arithmetics/30-commutative/es/EXERCISE.md new file mode 100644 index 00000000..b8eae707 --- /dev/null +++ b/modules/20-arithmetics/30-commutative/es/EXERCISE.md @@ -0,0 +1,9 @@ + +Esta tarea no está directamente relacionada con el tema de la lección. Sin embargo, será útil practicar con operaciones aritméticas y mostrar resultados en pantalla. + +Escriba un programa que calcule y muestre en pantalla los valores de las siguientes expresiones matemáticas de forma secuencial: "3 multiplicado por 5" y "-8 dividido por -4". + +
+15 +2 +diff --git a/modules/20-arithmetics/30-commutative/es/README.md b/modules/20-arithmetics/30-commutative/es/README.md new file mode 100644 index 00000000..a2bc0578 --- /dev/null +++ b/modules/20-arithmetics/30-commutative/es/README.md @@ -0,0 +1,15 @@ +Todos recordamos de la escuela: "el resultado no cambia al cambiar el orden de los sumandos". Este es uno de los principios básicos e intuitivos de la aritmética, conocido como la **ley conmutativa**. + +Una operación binaria se considera conmutativa si se obtiene el mismo resultado al intercambiar los operandos. Es evidente que la suma es una operación conmutativa: + +``` +3 + 2 = 2 + 3 +``` + +Sin embargo, la resta no es una operación conmutativa: + +``` +2 - 3 ≠ 3 - 2 +``` + +En programación, esta ley funciona de la misma manera que en aritmética. Además, la mayoría de las operaciones no son conmutativas. Por lo tanto, siempre preste atención al orden con el que trabaja. diff --git a/modules/20-arithmetics/30-commutative/es/data.yml b/modules/20-arithmetics/30-commutative/es/data.yml new file mode 100644 index 00000000..8f2da133 --- /dev/null +++ b/modules/20-arithmetics/30-commutative/es/data.yml @@ -0,0 +1,7 @@ +name: Operación conmutativa +definitions: + - name: Conmutatividad + description: >- + propiedad de una operación en la que el cambio de orden de los operandos + no afecta al resultado. Por ejemplo, la suma es una operación conmutativa: + el resultado no cambia al cambiar el orden de los sumandos. diff --git a/modules/20-arithmetics/30-commutative/ru/EXERCISE.md b/modules/20-arithmetics/30-commutative/ru/EXERCISE.md new file mode 100644 index 00000000..fcc22e1f --- /dev/null +++ b/modules/20-arithmetics/30-commutative/ru/EXERCISE.md @@ -0,0 +1,9 @@ + +Это задание напрямую не связано с темой урока. Но будет полезным попрактиковаться с арифметическими операциями и выводом на экран. + +Напишите программу, которая считает и последовательно выводит на экран значения следующих математических выражений: «3 умножить на 5» и «-8 разделить на -4». + +
+15 +2 +diff --git a/modules/20-arithmetics/30-commutative/ru/README.md b/modules/20-arithmetics/30-commutative/ru/README.md new file mode 100644 index 00000000..30e13861 --- /dev/null +++ b/modules/20-arithmetics/30-commutative/ru/README.md @@ -0,0 +1,15 @@ +Мы все помним со школы: «от перемены мест слагаемых сумма не меняется». Это один из базовых и интуитивно понятных принципов арифметики — **коммутативный закон**. + +Бинарная операция считается коммутативной, если, вы получаете тот же самый результат, поменяв местами операнды. Очевидно, что сложение — коммутативная операция: + +``` +3 + 2 = 2 + 3 +``` + +А вот вычитание — это не коммутативная операция: + +``` +2 - 3 ≠ 3 - 2 +``` + +В программировании этот закон работает точно так же, как в арифметике. Более того, большинство операций не являются коммутативными. Отсюда вывод: всегда обращайте внимание на порядок того, с чем работаете. diff --git a/modules/20-arithmetics/30-commutative/ru/data.yml b/modules/20-arithmetics/30-commutative/ru/data.yml new file mode 100644 index 00000000..4a856c11 --- /dev/null +++ b/modules/20-arithmetics/30-commutative/ru/data.yml @@ -0,0 +1,7 @@ +name: Коммутативная операция +definitions: + - name: Коммутативность + description: >- + свойство операции, когда изменения порядка операндов не влияет на + результат. Например, сложение — коммутативная операция: от перемены мест + слагаемых сумма не меняется. diff --git a/modules/20-arithmetics/40-composition/es/EXERCISE.md b/modules/20-arithmetics/40-composition/es/EXERCISE.md new file mode 100644 index 00000000..a9690f7c --- /dev/null +++ b/modules/20-arithmetics/40-composition/es/EXERCISE.md @@ -0,0 +1,8 @@ + +Implementa un programa que calcule el valor de la expresión `8 / 2 + 5 - -3 / 2` y muestre el resultado en pantalla. No calcules nada por tu cuenta, tu programa debe realizar todos los cálculos por sí mismo. +
+10 ++Observa que el intérprete realiza las operaciones aritméticas en el orden correcto: primero la división y la multiplicación, luego la suma y la resta. A veces es necesario cambiar este orden, lo veremos en la siguiente lección. + +También ten en cuenta que en Java, la división entera es la que se utiliza por defecto, `3 / 2` será `1`. diff --git a/modules/20-arithmetics/40-composition/es/README.md b/modules/20-arithmetics/40-composition/es/README.md new file mode 100644 index 00000000..b2f5862a --- /dev/null +++ b/modules/20-arithmetics/40-composition/es/README.md @@ -0,0 +1,25 @@ +¿Qué pasa si necesitamos calcular una expresión como *3 + 5 - 2*? Así es como lo escribiríamos: + +```java +System.out.println(3 + 5 - 2); // 3 + 5 - 2 => 8 - 2 => 6 +``` + +Observa que la computadora realiza las operaciones aritméticas en el orden correcto: primero la división y la multiplicación, luego la suma y la resta. A veces es necesario cambiar este orden, lo veremos más adelante. + +Otro ejemplo: + +```java +System.out.println(2 * 4 * 5 * 10); // 2 * 4 * 5 * 10 => 8 * 5 * 10 => 40 * 10 => 400 +``` + +Como puedes ver, las operaciones se pueden combinar entre sí y así calcular expresiones compuestas más complejas. Para entender cómo se realizan los cálculos dentro del intérprete, analicemos un ejemplo: + +``` +2 * 4 * 5 * 10 +``` + +En este ejemplo: + +1. Primero calculamos *2 * 4* y obtenemos la expresión *8 * 5 * 10* +2. Luego multiplicamos *8 * 5*. Al final tenemos *40 * 10* +3. Finalmente, se realiza la última multiplicación y se obtiene el resultado *400* diff --git a/modules/20-arithmetics/40-composition/es/data.yml b/modules/20-arithmetics/40-composition/es/data.yml new file mode 100644 index 00000000..90d83325 --- /dev/null +++ b/modules/20-arithmetics/40-composition/es/data.yml @@ -0,0 +1 @@ +name: Composición de operaciones diff --git a/modules/20-arithmetics/40-composition/ru/EXERCISE.md b/modules/20-arithmetics/40-composition/ru/EXERCISE.md new file mode 100644 index 00000000..07979785 --- /dev/null +++ b/modules/20-arithmetics/40-composition/ru/EXERCISE.md @@ -0,0 +1,8 @@ + +Реализуйте программу, которая вычисляет значение выражения `8 / 2 + 5 - -3 / 2` и выводит результат на экран. Не вычисляйте ничего самостоятельно, ваша программа должна производить все вычисления сама. +
+10 ++Обратите внимание, что интерпретатор производит арифметические вычисления в правильном порядке: сначала деление и умножение, потом сложение и вычитание. Иногда этот порядок нужно изменить — об этом следующий урок. + +Также обратите внимание на то, что в java по умолчанию используется целочисленное деление, `3 / 2` будет `1`. diff --git a/modules/20-arithmetics/40-composition/ru/README.md b/modules/20-arithmetics/40-composition/ru/README.md new file mode 100644 index 00000000..cea3686d --- /dev/null +++ b/modules/20-arithmetics/40-composition/ru/README.md @@ -0,0 +1,25 @@ +А что, если понадобится вычислить такое выражение: *3 + 5 - 2*? Именно так мы и запишем: + +```java +System.out.println(3 + 5 - 2); // 3 + 5 - 2 => 8 - 2 => 6 +``` + +Обратите внимание, что компьютер производит арифметические вычисления в правильном порядке: сначала деление и умножение, потом сложение и вычитание. Иногда этот порядок нужно изменить — об этом немного далее. + +Или другой пример: + +```java +System.out.println(2 * 4 * 5 * 10); // 2 * 4 * 5 * 10 => 8 * 5 * 10 => 40 * 10 => 400 +``` + +Как видно, операции можно соединять друг с другом и таким образом вычислять все более сложные составные выражения. Чтобы представить себе то, как происходят вычисления внутри интерпретатора, давайте разберем пример: + +``` +2 * 4 * 5 * 10 +``` + +В этом примере: + +1. Сначала вычисляем *2 * 4* и получаем выражение *8 * 5 * 10* +2. Затем умножаем *8 * 5*. В итоге имеем *40 * 10* +3. В конце концов происходит последнее умножение, и получается результат *400* diff --git a/modules/20-arithmetics/40-composition/ru/data.yml b/modules/20-arithmetics/40-composition/ru/data.yml new file mode 100644 index 00000000..ea206ade --- /dev/null +++ b/modules/20-arithmetics/40-composition/ru/data.yml @@ -0,0 +1 @@ +name: Композиция операций diff --git a/modules/20-arithmetics/50-priority/en/EXERCISE.md b/modules/20-arithmetics/50-priority/en/EXERCISE.md new file mode 100644 index 00000000..6cd0475f --- /dev/null +++ b/modules/20-arithmetics/50-priority/en/EXERCISE.md @@ -0,0 +1,4 @@ + +Consider an expression: `70 * 3 + 4 / 8 + 2`. + +Place the brackets correctly, so that both additions (`3 + 4` и `8 + 2`) are calculated first. Print the result onto the screen. diff --git a/modules/20-arithmetics/50-priority/en/README.md b/modules/20-arithmetics/50-priority/en/README.md new file mode 100644 index 00000000..fafadee5 --- /dev/null +++ b/modules/20-arithmetics/50-priority/en/README.md @@ -0,0 +1,34 @@ +What is the result of `2 + 2 * 2`? + +It's `6`. + +If you thought it's `8`, then this lesson is for you ;-) In primary school you've learned about operation priority. Priority defines the order of operations in complex expressions. For example, multiplication and division have higher priority than addition or division. So, 2 + 3 * 2 is `8`. + +But sometimes we want different, non-standard order. Just like in math, we can use brackets to change the order, like so: `(2 + 2) * 2`. + +Here are few more examples: + +```java +System.out.println(3 * (4 - 2)); // => 6 +System.out.println(7 * 3 + (4 / 2) - (8 + (2 - 1))); // => 14 +``` + +Be sure to pair all the brackets in correct order. This is often the problem for both beginners and experienced programmers alike. To make things easier, put both opening and closing brackets, and then type the stuff inside. The editor on our website (and most code editors) do that by default automatically: you type `(`, and the editor adds `)`. This works for some other symbols, like quotation marks, for example. We'll talk about them later. + +Sometimes an expression is too complication to understand visually. Feel free to put brackets even if then won't change the priority, but will make things clearer: + +Before: + +```java +System.out.println(8 / 2 + 5 - -3 / 2); // => 11 +``` + +After: + +```java +System.out.println(((8 / 2) + 5) - (-3 / 2)); // => 11 +``` + +Remember: code is for people, because it'll be read by people, and machines will only execute it. The only thing that matters for the machines is the correctness of code. They don't distinguish between "clear" or "confusing". + +https://replit.com/@hexlet/java-basics-arithmetics diff --git a/modules/20-arithmetics/50-priority/en/data.yml b/modules/20-arithmetics/50-priority/en/data.yml new file mode 100644 index 00000000..d50afc6c --- /dev/null +++ b/modules/20-arithmetics/50-priority/en/data.yml @@ -0,0 +1 @@ +name: Priority diff --git a/modules/20-arithmetics/50-priority/es/EXERCISE.md b/modules/20-arithmetics/50-priority/es/EXERCISE.md new file mode 100644 index 00000000..333a0f29 --- /dev/null +++ b/modules/20-arithmetics/50-priority/es/EXERCISE.md @@ -0,0 +1,4 @@ + +Dada la expresión `70 * 3 + 4 / 8 + 2`. + +Coloca paréntesis de manera que ambas sumas (`3 + 4` y `8 + 2`) se calculen primero. Muestra el resultado en pantalla. diff --git a/modules/20-arithmetics/50-priority/es/README.md b/modules/20-arithmetics/50-priority/es/README.md new file mode 100644 index 00000000..199af9fd --- /dev/null +++ b/modules/20-arithmetics/50-priority/es/README.md @@ -0,0 +1,38 @@ +Observa detenidamente la expresión *2 + 2 * 2* y calcula mentalmente el resultado. La respuesta correcta es *6*. Si obtuviste *8*, entonces esta lección es para ti. + +En matemáticas escolares, estudiamos 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: + +``` +2 + 3 * 2 = 8 +``` + +Sin embargo, a menudo los cálculos deben realizarse en un orden diferente al de la prioridad estándar. En situaciones complicadas, se puede especificar la prioridad utilizando paréntesis, al igual que en la escuela, por ejemplo: + +``` +(2 + 2) * 2 +``` + +Los paréntesis se pueden colocar alrededor de cualquier operación. Pueden anidarse tantas veces como sea necesario. Aquí tienes un par de ejemplos: + +```java +System.out.println(3 * (4 - 2)); // => 6 +System.out.println(7 * 3 + (4 / 2) - (8 + (2 - 1))); // => 14 +``` + +A veces, una expresión puede ser difícil de comprender visualmente. En ese caso, se pueden agregar paréntesis para hacerla más clara, aunque no afectarán la prioridad: + +Antes: +```java +System.out.println(8 / 2 + 5 - -4 / 2); // => 11 +``` + +Después: +```java +System.out.println(((8 / 2) + 5) - (-4 / 2)); // => 11 +``` + +Recuerda: el código se escribe para las personas, porque las personas lo leerán, y las máquinas solo lo ejecutarán. Para las máquinas, no hay código "más" o "menos" comprensible, independientemente de si el código es correcto o no. + +https://replit.com/@hexlet/java-basics-arithmetics diff --git a/modules/20-arithmetics/50-priority/es/data.yml b/modules/20-arithmetics/50-priority/es/data.yml new file mode 100644 index 00000000..a077937e --- /dev/null +++ b/modules/20-arithmetics/50-priority/es/data.yml @@ -0,0 +1 @@ +name: Prioridad de las operaciones diff --git a/modules/20-arithmetics/50-priority/ru/EXERCISE.md b/modules/20-arithmetics/50-priority/ru/EXERCISE.md new file mode 100644 index 00000000..223657b9 --- /dev/null +++ b/modules/20-arithmetics/50-priority/ru/EXERCISE.md @@ -0,0 +1,4 @@ + +Дано выражение `70 * 3 + 4 / 8 + 2`. + +Расставьте скобки так, чтобы оба сложения (`3 + 4` и `8 + 2`) высчитывались в первую очередь. Выведите результат на экран. diff --git a/modules/20-arithmetics/50-priority/ru/README.md b/modules/20-arithmetics/50-priority/ru/README.md new file mode 100644 index 00000000..22ad28a9 --- /dev/null +++ b/modules/20-arithmetics/50-priority/ru/README.md @@ -0,0 +1,38 @@ +Посмотрите внимательно на выражение *2 + 2 * 2* и посчитайте в уме ответ. Правильный ответ: *6*. Если у вас получилось *8*, то этот урок для вас. + +В школьной математике мы изучали понятие «приоритет операции». Приоритет определяет, в какой последовательности должны выполняться операции. + +Например, умножение и деление имеют больший приоритет, чем сложение и вычитание: + +``` +2 + 3 * 2 = 8 +``` + +Но нередко вычисления должны происходить в порядке, отличном от стандартного приоритета. В сложных ситуациях приоритет можно задавать круглыми скобками, точно так же, как в школе, например: + +``` +(2 + 2) * 2 +``` + +Скобки можно ставить вокруг любой операции. Они могут вкладываться друг в друга сколько угодно раз. Вот пара примеров: + +```java +System.out.println(3 * (4 - 2)); // => 6 +System.out.println(7 * 3 + (4 / 2) - (8 + (2 - 1))); // => 14 +``` + +Иногда выражение сложно воспринимать визуально. Тогда можно сделать его понятнее, расставив скобки, хотя они и не повлияют на приоритет: + +Было: +```java +System.out.println(8 / 2 + 5 - -4 / 2); // => 11 +``` + +Стало: +```java +System.out.println(((8 / 2) + 5) - (-4 / 2)); // => 11 +``` + +Запомните: код пишется для людей, потому что код будут читать люди, а машины будут только исполнять его. Для машин нет «более» понятного или «менее» понятного кода, независимо от того, является ли код корректным или нет. + +https://replit.com/@hexlet/java-basics-arithmetics diff --git a/modules/20-arithmetics/50-priority/ru/data.yml b/modules/20-arithmetics/50-priority/ru/data.yml new file mode 100644 index 00000000..8b356173 --- /dev/null +++ b/modules/20-arithmetics/50-priority/ru/data.yml @@ -0,0 +1 @@ +name: Приоритет операций diff --git a/modules/20-arithmetics/60-float/es/EXERCISE.md b/modules/20-arithmetics/60-float/es/EXERCISE.md new file mode 100644 index 00000000..31bfd253 --- /dev/null +++ b/modules/20-arithmetics/60-float/es/EXERCISE.md @@ -0,0 +1,2 @@ + +Calcule y muestre en pantalla el producto de dos números: *0.39* y *0.22* diff --git a/modules/20-arithmetics/60-float/es/README.md b/modules/20-arithmetics/60-float/es/README.md new file mode 100644 index 00000000..cb883365 --- /dev/null +++ b/modules/20-arithmetics/60-float/es/README.md @@ -0,0 +1,34 @@ + +En matemáticas, existen diferentes tipos de números, por ejemplo: + +* **Naturales** - son números enteros mayores o iguales a 1 +* **Racionales** - son números con decimales, por ejemplo, 0.5 + +Desde la perspectiva de los dispositivos informáticos, hay una brecha entre estos tipos de números. Intentemos sumar dos números racionales: + +``` +0.2 + 0.1 = 0.3 +``` + +Y ahora veamos qué dice Java al respecto: + +```java +0.2 + 0.1; // 0.30000000000000004 +``` + +La operación de suma 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. A diferencia de los números, la memoria tiene un límite finito, y un número infinito requeriría una cantidad infinita de memoria para almacenarlo. + +Con los números naturales, este problema se resuelve estableciendo un límite superior. Hay un número máximo que se puede ingresar: + +```java +System.out.println(Integer.MAX_VALUE); +// => 2147483647 +``` + +Sin embargo, esto no funciona con los números racionales. La razón es que no están dispuestos en una cadena continua, hay un conjunto infinito de números entre *0.1* y *0.2*. + +¿Entonces, cómo se almacenan los números racionales? La mayoría de los lenguajes de programación se basan en un estándar común que describe cómo organizar la memoria en estos casos. + +Es importante que los desarrolladores comprendan que las operaciones con números de punto flotante no son precisas, pero esta precisión se puede ajustar. Esto significa que al resolver problemas con este tipo de números, es necesario recurrir a trucos especiales que permitan lograr la precisión deseada. diff --git a/modules/20-arithmetics/60-float/es/data.yml b/modules/20-arithmetics/60-float/es/data.yml new file mode 100644 index 00000000..c3563b95 --- /dev/null +++ b/modules/20-arithmetics/60-float/es/data.yml @@ -0,0 +1,5 @@ +name: Números de punto flotante +tips: + - > + [Qué necesitas saber sobre aritmética de punto + flotante](https://habr.com/post/112953/) diff --git a/modules/20-arithmetics/60-float/ru/EXERCISE.md b/modules/20-arithmetics/60-float/ru/EXERCISE.md new file mode 100644 index 00000000..6b472cb1 --- /dev/null +++ b/modules/20-arithmetics/60-float/ru/EXERCISE.md @@ -0,0 +1,2 @@ + +Вычислите и выведите на экран произведение двух чисел: *0.39* и *0.22* diff --git a/modules/20-arithmetics/60-float/ru/README.md b/modules/20-arithmetics/60-float/ru/README.md new file mode 100644 index 00000000..bbadebde --- /dev/null +++ b/modules/20-arithmetics/60-float/ru/README.md @@ -0,0 +1,34 @@ + +В математике существуют разные виды чисел, например: + +* **Натуральные** — это целые числа от 1 и больше +* **Рациональные** — это числа с точкой, например, 0.5 + +С точки зрения устройства компьютеров, между этими видами чисел — пропасть. Попробуем сложить два рациональных числа: + +``` +0.2 + 0.1 = 0.3 +``` + +А теперь посмотрим, что на это скажет Java: + +```java +0.2 + 0.1; // 0.30000000000000004 +``` + +Операция сложения двух рациональных чисел внезапно привела к неточному вычислению результата. Тот же самый результат выдадут и другие языки программирования. + +Такое поведение обуславливается ограничениями вычислительных мощностей. В отличие от чисел, объем памяти конечен — при этом бесконечное количество чисел требовало бы бесконечного количества памяти для своего хранения. + +С натуральными числами эта проблема решается простым ограничением по верхней границе. Есть некоторое максимальное число, которое можно ввести: + +```java +System.out.println(Integer.MAX_VALUE); +// => 2147483647 +``` + +С рациональными числами такой финт не пройдет. Дело в том, что они не выстроены в непрерывную цепочку, между *0.1* и *0.2* лежит бесконечное множество чисел. + +А как тогда хранить рациональные числа? Подавляющее число языков программирования в этом случае опирается на единый стандарт, который описывает как организовывать память в таких случаях. + +Разработчикам важно понимать, что операции с плавающими числами неточны, но эту точность можно регулировать. Это значит, что при решении задач с подобными числами необходимо прибегать к специальным трюкам, которые позволяют добиться необходимой точности. diff --git a/modules/20-arithmetics/60-float/ru/data.yml b/modules/20-arithmetics/60-float/ru/data.yml new file mode 100644 index 00000000..d0fda2ba --- /dev/null +++ b/modules/20-arithmetics/60-float/ru/data.yml @@ -0,0 +1,5 @@ +name: Числа с плавающей точкой +tips: + - > + [Что нужно знать про арифметику с плавающей + запятой](https://habr.com/post/112953/) diff --git a/modules/20-arithmetics/80-linting/es/EXERCISE.md b/modules/20-arithmetics/80-linting/es/EXERCISE.md new file mode 100644 index 00000000..ba61446b --- /dev/null +++ b/modules/20-arithmetics/80-linting/es/EXERCISE.md @@ -0,0 +1,2 @@ + +Muestra en pantalla el resultado de la siguiente operación: "la diferencia entre la suma de cinco y dos y el producto de tres y siete". Compara el resultado obtenido con la solución del profesor en términos de formato del código. diff --git a/modules/20-arithmetics/80-linting/es/README.md b/modules/20-arithmetics/80-linting/es/README.md new file mode 100644 index 00000000..73b3b47e --- /dev/null +++ b/modules/20-arithmetics/80-linting/es/README.md @@ -0,0 +1,37 @@ +Ahora que ya hemos aprendido a escribir programas simples, podemos hablar un poco sobre cómo escribirlos. + +El código del programa debe ser formateado de una manera específica para que sea lo suficientemente comprensible y fácil de mantener. + +Conjuntos especiales de reglas, llamados **estándares**, describen varios aspectos de la escritura de código. En Java, el estándar más común es el estándar de [Sun](https://checkstyle.sourceforge.io/checks.html). + +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 Java, esto se hace con [checkstyle](https://github.com/checkstyle/checkstyle). Echa un vistazo a este ejemplo: + +```java +System.out.println( "Hello, World!" ); System.out.println("I'm a developer!") ; +``` + +El linter mostrará errores en varios lugares: + +* '(' está seguido de un espacio en blanco. [ParenPad] +* ')' está precedido de un espacio en blanco. [ParenPad] +* ';' está precedido de un espacio en blanco. [NoWhitespaceBefore] +* Solo se permite una instrucción por línea. [OneStatementPerLine] + +Analicemos estos errores: + +* La regla **ParenPad**, indicada entre corchetes, requiere que no haya espacios después del paréntesis de apertura y antes del paréntesis de cierre. +* La regla **NoWhitespaceBefore** indica que no se debe colocar un espacio adicional antes del punto y coma. +* Es común escribir cada nueva instrucción en una nueva línea. Esto es lo que indica la regla *OneStatementPerLine*. + +Cumplir con estas reglas no afecta el resultado, pero ayuda a escribir un código más comprensible y fácil de entender. + +El código con estas reglas se vería así: + +```java +System.out.println("Hello, World!"); +System.out.println("I'm a developer!"); +``` + +Ahora el linter no mostrará errores. ¿Qué conclusión podemos sacar? El linter ayuda a escribir código que es más fácil de leer y analizar. + +Recuerda que tener un linter no reemplaza el análisis y la simplificación independiente del código. En tus futuras prácticas en [Hexlet](https://ru.hexlet.io) y en el desarrollo real, el linter funcionará y te informará sobre cualquier violación. diff --git a/modules/20-arithmetics/80-linting/es/data.yml b/modules/20-arithmetics/80-linting/es/data.yml new file mode 100644 index 00000000..d14182b1 --- /dev/null +++ b/modules/20-arithmetics/80-linting/es/data.yml @@ -0,0 +1,2 @@ +name: Linter +tips: [] diff --git a/modules/20-arithmetics/80-linting/ru/EXERCISE.md b/modules/20-arithmetics/80-linting/ru/EXERCISE.md new file mode 100644 index 00000000..25fb8cdb --- /dev/null +++ b/modules/20-arithmetics/80-linting/ru/EXERCISE.md @@ -0,0 +1,2 @@ + +Выведите на экран результат следующего вычисления: «разница между суммой пяти и двух и произведением трёх и семи». Сравните получившийся результат с решением учителя с точки зрения оформления кода. diff --git a/modules/20-arithmetics/80-linting/ru/README.md b/modules/20-arithmetics/80-linting/ru/README.md new file mode 100644 index 00000000..d6005981 --- /dev/null +++ b/modules/20-arithmetics/80-linting/ru/README.md @@ -0,0 +1,37 @@ +Теперь, когда мы уже научились писать простые программы, можно немного поговорить о том, как их писать. + +Код программы следует оформлять определенным образом, чтобы он был достаточно понятным и простым в поддержке. + +Специальные наборы правил — **стандарты** — описывают различные аспекты написания кода. Конкретно в Java самым распространенным стандартом является стандарт от [Sun](https://checkstyle.sourceforge.io/checks.html). + +В любом языке программирования существуют утилиты — так называемые **линтеры**. Они проверяют код на соответствие стандартам. В Java это [checkstyle](https://github.com/checkstyle/checkstyle). Взгляните на пример: + +```java +System.out.println( "Hello, World!" ); System.out.println("I'm a developer!") ; +``` + +Линтер будет ругаться на нарушение сразу в нескольких местах: + +* '(' is followed by whitespace. [ParenPad] +* ')' is preceded with whitespace. [ParenPad] +* ';' is preceded with whitespace. [NoWhitespaceBefore] +* Only one statement per line allowed. [OneStatementPerLine] + +Проанализируем данные ошибки: + +* Правило **ParenPad**, указанное в квадратных скобках, требует отсутствия пробелов после открывающейся и перед закрывающейся круглыми скобками +* Правило **NoWhitespaceBefore** указывает, что перед точкой с запятой не нужно устанавливать лишний пробел +* Каждую новую инструкцию принято записывать с новой строки. На это указывает правило *OneStatementPerLine* + +Соблюдение данных правил не влияет на результат, но помогает писать код понятнее и проще для восприятия. + +Код с учетом этих правил выглядит так: + +```java +System.out.println("Hello, World!"); +System.out.println("I'm a developer!"); +``` + +Теперь линтер ругаться не будет. Какой мы делаем вывод? Линтер помогает писать код, который будет легче читать и анализировать. + +Помните, что наличие линтера не отменяет самостоятельного анализа и упрощения чтения кода. В ваших будущих практиках на [Хекслете](https://ru.hexlet.io) и в реальной разработке линтер будет работать и сообщать вам о нарушениях. diff --git a/modules/20-arithmetics/80-linting/ru/data.yml b/modules/20-arithmetics/80-linting/ru/data.yml new file mode 100644 index 00000000..d3e5043c --- /dev/null +++ b/modules/20-arithmetics/80-linting/ru/data.yml @@ -0,0 +1,2 @@ +name: Линтер +tips: [] diff --git a/modules/25-strings/10-quotes/en/EXERCISE.md b/modules/25-strings/10-quotes/en/EXERCISE.md new file mode 100644 index 00000000..ee5b34cc --- /dev/null +++ b/modules/25-strings/10-quotes/en/EXERCISE.md @@ -0,0 +1,8 @@ + +Write a program that displays: + +``` +"Khal Drogo's favorite word is "athjahakar"" +``` + +The program should display this phrase exactly. Note the quotes at the beginning and at the end of a phrase. diff --git a/modules/25-strings/10-quotes/en/README.md b/modules/25-strings/10-quotes/en/README.md new file mode 100644 index 00000000..41305b22 --- /dev/null +++ b/modules/25-strings/10-quotes/en/README.md @@ -0,0 +1,37 @@ + +```java +"Hello" +"Goodbye" + +"G" +" " +"" +``` + +Which of these five options are strings? + +Everything is clear with the first two, these are exactly strings, we have already worked with similar constructions and said that strings are character sets. + +Any single character in quotes is a string. The empty string `" "` is also a string. That is, we consider everything to be inside the quotes, even if it is a space, one character or no characters at all. + +Imagine that you want to print _dragon's mother_ line. The apostrophe before the letter **s** is the same character as a single quote. Let's try: + +This version of the program will work correctly: + +```java +System.out.println("Dragon's mother"); +``` + +And what if we want to create such a string: + +``` +Dragon's mother said "No" +``` + +It contains both single and double quotes. How to be in this situation? + +To do this, use the **escape character**: `\`. If you put `\` before the quotation mark (single or double), it will mean that the quotation mark should be viewed not as the beginning or end of the line, but as part of the line. + +```java +System.out.println("Dragon's mother said \"No\""); +``` diff --git a/modules/25-strings/10-quotes/en/data.yml b/modules/25-strings/10-quotes/en/data.yml new file mode 100644 index 00000000..dd7055f0 --- /dev/null +++ b/modules/25-strings/10-quotes/en/data.yml @@ -0,0 +1 @@ +name: quotes diff --git a/modules/25-strings/10-quotes/es/EXERCISE.md b/modules/25-strings/10-quotes/es/EXERCISE.md new file mode 100644 index 00000000..53c0af27 --- /dev/null +++ b/modules/25-strings/10-quotes/es/EXERCISE.md @@ -0,0 +1,8 @@ + +Escribe un programa que imprima en la pantalla: + +
+"Khal Drogo's favorite word is "athjahakar"" ++ +El programa debe imprimir exactamente esta frase. Presta atención a las comillas al principio y al final de la frase. diff --git a/modules/25-strings/10-quotes/es/README.md b/modules/25-strings/10-quotes/es/README.md new file mode 100644 index 00000000..d60e2fe8 --- /dev/null +++ b/modules/25-strings/10-quotes/es/README.md @@ -0,0 +1,44 @@ +```java +"Hola" +"Adiós" +"G" +" " +"" +``` + +¿Cuáles de estas cinco opciones son cadenas de texto? Con las primeras dos está claro: son definitivamente cadenas de texto, ya hemos trabajado con construcciones similares. ¿Pero qué pasa con las demás? + +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 las comillas, incluso si es un espacio, un solo carácter o la ausencia total de caracteres. + +Imagina que quieres imprimir la frase *la madre del dragón*. El apóstrofe antes de la letra **s** es un carácter igual que una comilla simple. Intentemos. Esta versión del programa funcionará correctamente: + +```java +System.out.println("La madre del dragón"); +``` + +Pero, ¿qué pasa si queremos crear una cadena de texto como esta: + +
+La madre del dragón dijo "No" ++ +En ella hay tanto comillas simples como comillas dobles. ¿Qué hacer en esta situación? Si simplemente intentamos imprimir esta cadena de texto, obtendremos un error: + +```java +// Terminará con un error de sintaxis +System.out.println("La madre del dragón dijo "No""); +``` + +Desde el punto de vista de Java, esta es una construcción extraña de dos componentes de tres: + +- La cadena de texto *"La madre del dragón dijo "* +- La cadena de texto *""* +- La palabra *No* entre ellos, que no se considera una cadena de texto porque no está entre comillas + +No se puede imprimir esta cadena de texto de la manera habitual. Para imprimir cadenas de texto como esta, se utiliza el **carácter de escape**: `\`. + +Si colocamos `\` antes de una comilla, significa que la comilla debe considerarse como parte de la cadena de texto, no como el inicio o el final de la misma: + +```java +System.out.println("La madre del dragón dijo \"No\""); +``` diff --git a/modules/25-strings/10-quotes/es/data.yml b/modules/25-strings/10-quotes/es/data.yml new file mode 100644 index 00000000..1f1d2cd4 --- /dev/null +++ b/modules/25-strings/10-quotes/es/data.yml @@ -0,0 +1 @@ +name: Comillas diff --git a/modules/25-strings/10-quotes/ru/EXERCISE.md b/modules/25-strings/10-quotes/ru/EXERCISE.md new file mode 100644 index 00000000..a8d56c81 --- /dev/null +++ b/modules/25-strings/10-quotes/ru/EXERCISE.md @@ -0,0 +1,8 @@ + +Напишите программу, которая выведет на экран: + +
+"Khal Drogo's favorite word is "athjahakar"" ++ +Программа должна вывести на экран эту фразу в точности. Обратите внимание на кавычки в начале и в конце фразы. diff --git a/modules/25-strings/10-quotes/ru/README.md b/modules/25-strings/10-quotes/ru/README.md new file mode 100644 index 00000000..5e71cc2b --- /dev/null +++ b/modules/25-strings/10-quotes/ru/README.md @@ -0,0 +1,44 @@ +```java +"Hello" +"Goodbye" +"G" +" " +"" +``` + +Какие из этих пяти вариантов — строки? С первыми двумя все понятно: это точно строки, мы уже работали с подобными конструкциями. А что насчет остальных? + +Любой одиночный символ в кавычках — это строка. Пустая строка `""` — это тоже строка. То есть строкой мы считаем все, что находится внутри кавычек, даже если это пробел, один символ или вообще отсутствие символов. + +Представьте, что вы хотите напечатать строчку *dragon's mother*. Апостроф перед буквой **s** — это такой же символ, как одинарная кавычка. Попробуем. Такой вариант программы отработает корректно: + +```java +System.out.println("Dragon's mother"); +``` + +А что, если мы хотим создать такую строку: + +
+Dragon's mother said "No" ++ +В ней есть и одинарные, и двойные кавычки. Как быть в этой ситуации? Если просто попытаться вывести такую строку, то мы получим ошибку: + +```java +// Завершится с синтаксической ошибкой +System.out.println("Dragon's mother said "No""); +``` + +С точки зрения Java, здесь странная конструкция из двух трех компонентов: + +- Строки *"Dragon's mother said "* +- Строки *""* +- Слова *No* между ними, которые не рассматривается как строка, потому что оно не в кавычках + +Привычным способом эту строчку не вывести. Для вывода таких строк используют **символ экранирования**: `\`. + +Если поставить `\` перед кавычкой, это будет означать, что кавычку нужно рассматривать не как начало или конец строки, а как ее часть: + +```java +System.out.println("Dragon's mother said \"No\""); +``` diff --git a/modules/25-strings/10-quotes/ru/data.yml b/modules/25-strings/10-quotes/ru/data.yml new file mode 100644 index 00000000..d30e1d4f --- /dev/null +++ b/modules/25-strings/10-quotes/ru/data.yml @@ -0,0 +1 @@ +name: Кавычки diff --git a/modules/25-strings/15-escape-characters/en/EXERCISE.md b/modules/25-strings/15-escape-characters/en/EXERCISE.md new file mode 100644 index 00000000..3d39a201 --- /dev/null +++ b/modules/25-strings/15-escape-characters/en/EXERCISE.md @@ -0,0 +1,7 @@ + +Write a program that displays: + + — Did Joffrey agree? + — He did. He also said "I love using \n". + +The program uses only one `println`, but the result on the screen should look exactly like the one shown above. diff --git a/modules/25-strings/15-escape-characters/en/README.md b/modules/25-strings/15-escape-characters/en/README.md new file mode 100644 index 00000000..792dc039 --- /dev/null +++ b/modules/25-strings/15-escape-characters/en/README.md @@ -0,0 +1,111 @@ + +We want to show the dialogue of the Mother of Dragons with her child: + +``` +- Are you hungry? +- Aaaarrrgh! +``` + +If you display a line with the following text: + +```java +System.out.print("— Are you hungry?— Aaaarrrgh!"); +``` + +it will turn out like this: + +``` +— Are you hungry?— Aaaarrrgh! +``` + +We need to somehow tell the interpreter "click on enter" — to make a line break after the question mark. + +In Java, `\n` is a line break: + +```java +System.out.print("— Are you hungry?\n— Aaaarrrgh!"); +``` + +result: + +``` +— Are you hungry? +— Aaaarrrgh! +``` + +`\n` is an example **of the escape sequence** (escape sequence). They are also called control structures. + +While typing in some Word, you press Enter at the end of the line. The editor puts a special invisible character at the end of the line, which is called LINE FEED (LF). In some editors, you can even turn on the display of invisible characters. Then the text will look something like this: + +``` +— Hello!¶ +— Oh, hi!¶ +— How are you? +``` + +A device that outputs the corresponding text takes this symbol into account. For example, the printer, when meeting with LF, pulls the paper up one line, and the text editor transfers all subsequent text below, also one line. + +Although there are more than a dozen of such characters, there are often only a few in programming. In addition to line breaks, these characters include tabulation (a break, obtained by pressing the Tab button) and carriage returnValue (only in Windows). We, programmers, often need to use, for example, the translation of the string `\n` to properly format the text. + +```java +System.out.print("Gregor Clegane\nDunsen\nPolliver\nChiswyck"); +``` + +**Attention! Escaping sequences like `\n` work only inside double quotes!** + +The screen will display: + +``` +Gregor Clegane +Dunsen +Polliver +Chiswyck +``` + +For convenience, there is a method `System.out.println`, which allows you to display some value on the console and then transfer the console to the next line. For example: + +```java +System.out.println("Hello"); +System.out.println("World"); +``` +The screen will display: + +``` +Hello +World +``` + +Pay attention to the following points: + +1\. It does not matter what comes before or after `\n`: a character or an empty string. The transfer will be detected and executed in any case. + +2\. Remember that a string can contain only one character or zero characters at all? And the line can contain only `\n`: + +```java +System.out.print("Gregor Clegane"); +System.out.print("\n"); +System.out.print("Dunsen"); +``` + +Here we print one line with the name, then one line “line feed”, and then another line. The program will display: + +``` +Gregor Clegane +Dunsen +``` + +3\. Despite the fact that in the source code of a program, a sequence of type `\n` looks like two characters, from the point of view of the interpreter it is a special single character. + +4\. If we need to display `\n` exactly as text (two separate printable characters), then we can use the already known screening method, adding one more `\` at the beginning. That is, the sequence `\\n` is displayed as the characters `\` and `n` following each other. + +```java +System.out.print("Joffrey loves using \\n"); +``` + +the screen will be released: + +``` +Joffrey loves using \n +``` + +A small but important note about Windows. On Windows, `\r\n` is used to translate strings by default. Such a combination works well only in Windows, but creates problems when transferring to other systems (for example, when the development team has both Windows and Linux users). The fact is that the sequence `\r\n` has a different interpretation depending on the selected encoding (discussed later). For this reason, in the development environment, it is customary to always use `\n` without `\r`, since LF is always treated the same way and works fine in any system. Remember to configure your editor to use `\n`. diff --git a/modules/25-strings/15-escape-characters/en/data.yml b/modules/25-strings/15-escape-characters/en/data.yml new file mode 100644 index 00000000..8e4382aa --- /dev/null +++ b/modules/25-strings/15-escape-characters/en/data.yml @@ -0,0 +1,4 @@ +name: Escaping sequences +tips: + - | + [String History](https://en.wikipedia.org/wiki/Newline#History)j diff --git a/modules/25-strings/15-escape-characters/es/EXERCISE.md b/modules/25-strings/15-escape-characters/es/EXERCISE.md new file mode 100644 index 00000000..3a37fa34 --- /dev/null +++ b/modules/25-strings/15-escape-characters/es/EXERCISE.md @@ -0,0 +1,7 @@ + +Escribe un programa que muestre en la pantalla: + + - Did Joffrey agree? + - He did. He also said "I love using \n". + +El programa debe usar solo un `System.out.println()`, pero el resultado en la pantalla debe verse exactamente como se muestra arriba. diff --git a/modules/25-strings/15-escape-characters/es/README.md b/modules/25-strings/15-escape-characters/es/README.md new file mode 100644 index 00000000..88bae0af --- /dev/null +++ b/modules/25-strings/15-escape-characters/es/README.md @@ -0,0 +1,140 @@ +Queremos mostrar un diálogo entre la Madre de los Dragones y su hijo: + +```text +- ¿Tienes hambre? +- ¡Aaaarrrgh! +``` + +Si imprimimos una cadena de texto con este contenido: + +```java +System.out.println("- ¿Tienes hambre?- ¡Aaaarrrgh!"); +``` + +Obtendremos esto: + +
+- ¿Tienes hambre?- ¡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" - hacer 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`: + +```java +System.out.println("- ¿Tienes hambre?\n- ¡Aaaarrrgh!"); +``` + +resultado: + +
+- ¿Tienes hambre? +- ¡Aaaarrrgh! ++ +`\n` es un carácter especial. En la literatura a menudo se le llama *LF* (Line Feed). Es posible que ahora estés pensando que esto es un error tipográfico, 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: + +```java +// No hemos estudiado esto, pero debes saber la verdad +// A continuación, el código que devuelve la longitud de una cadena +"a".length(); // 1 +"\n".length(); // 1 !!! +"\n\n".length(); // 2 !!! +``` + +¿Por qué se hizo así? `\n` es solo 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 representarlo de alguna manera en el teclado. Y dado que la cantidad de caracteres en el teclado es limitada y se destina a los más importantes, todos los caracteres especiales se implementan en forma de estas 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 usado el salto de línea al presionar Enter. + +Muchos editores tienen una opción que permite mostrar caracteres invisibles. Esta opción ayuda a comprender dónde se encuentran, aunque es solo una representación esquemática, ya que estos caracteres invisibles no tienen una representación gráfica: + +
+- ¡Hola!¶ +- ¡Oh, hola!¶ +- ¿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 solo se encuentran unos pocos con frecuencia. + +Además del salto de línea, estos caracteres incluyen: + +* Tabulación - la separación que se obtiene al presionar la tecla Tab +* Retorno de carro (solo en Windows) + +Los programadores a menudo necesitan usar el salto de línea `\n` para formatear correctamente el texto: + +```java +System.out.println("Gregor Clegane\nDunsen\nPolliver\nChiswyck"); +``` + +Se mostrará en la pantalla: + +```text +Gregor Clegane +Dunsen +Polliver +Chiswyck +``` + +Ten en cuenta los siguientes puntos: + +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: + + ```java + System.out.println("\n"); + System.out.println("Dunsen"); + ``` + + Aquí primero imprimimos una cadena "salto de línea" y luego imprimimos una cadena normal. El programa mostrará en la pantalla: + +
++ + ¿Por qué aparecieron dos líneas vacías antes de la cadena *Dunsen* en lugar de una? El caso es que `System.out.println()` 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 de secuencia de escape como argumento a la función, y el segundo salto de línea se agregó automáticamente por la función. + + Otro ejemplo de código: + + ```java + System.out.println("Polliver"); + System.out.println("Gregor Clegane"); + System.out.println(); + System.out.println("Chiswyck\n"); + System.out.println("Dunsen"); + ``` + + La salida será así: + + ```text + Polliver + Gregor Clegane + + Chiswyck + + Dunsen + ``` + + Ahora tienes suficiente conocimiento para entender por qué la salida se formó de esta manera. + +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 después del otro: + + ```java + System.out.println("Joffrey ama usar \\n"); + ``` + + se mostrará en la pantalla: + + ```text + Joffrey ama usar \n + ``` + +Una pequeña pero importante nota sobre Windows. En Windows, por defecto se utiliza `\r\n` para el salto de línea - esto se debe a razones históricas. Esta combinación funciona bien solo en Windows, pero crea problemas al transferir a otros sistemas, por ejemplo, cuando hay usuarios tanto de Windows como de Linux en el equipo de desarrollo. + +El caso es que la secuencia `\r\n` tiene diferentes interpretaciones dependiendo de la codificación seleccionada. Por lo tanto, en el entorno de desarrollo, siempre se usa `\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`. diff --git a/modules/25-strings/15-escape-characters/es/data.yml b/modules/25-strings/15-escape-characters/es/data.yml new file mode 100644 index 00000000..11bfd581 --- /dev/null +++ b/modules/25-strings/15-escape-characters/es/data.yml @@ -0,0 +1,5 @@ +name: Secuencias de escape +tips: + - > + [Historia del salto de + línea](https://es.wikipedia.org/wiki/Salto_de_l%C3%ADnea#Historia) diff --git a/modules/25-strings/15-escape-characters/ru/EXERCISE.md b/modules/25-strings/15-escape-characters/ru/EXERCISE.md new file mode 100644 index 00000000..e528517a --- /dev/null +++ b/modules/25-strings/15-escape-characters/ru/EXERCISE.md @@ -0,0 +1,7 @@ + +Напишите программу, которая выводит на экран: + + - Did Joffrey agree? + - He did. He also said "I love using \n". + +При этом программа использует только один `System.out.println()`, но результат на экране должен выглядеть в точности как показано выше. diff --git a/modules/25-strings/15-escape-characters/ru/README.md b/modules/25-strings/15-escape-characters/ru/README.md new file mode 100644 index 00000000..9c2ad525 --- /dev/null +++ b/modules/25-strings/15-escape-characters/ru/README.md @@ -0,0 +1,140 @@ +Мы хотим показать диалог Матери Драконов со своим ребенком: + +```text +- Are you hungry? +- Aaaarrrgh! +``` + +Если вывести на экран строку с таким текстом: + +```java +System.out.println("- Are you hungry?- Aaaarrrgh!"); +``` + +Получится так: + +
+ Dunsen +
+- Are you hungry?- Aaaarrrgh! ++ +Не то, что мы хотели. Строки расположены друг за другом, а не одна ниже другой. Нам нужно как-то сказать интерпретатору «нажать на Enter» — сделать перевод строки после вопросительного знака. Это можно сделать, используя символ перевода строки: `\n`: + +```java +System.out.println("- Are you hungry?\n- Aaaarrrgh!"); +``` + +результат: + +
+- Are you hungry? +- Aaaarrrgh! ++ +`\n` — это специальный символ. В литературе его часто обозначают как *LF* (Line Feed). Возможно, вы сейчас подумали, что это опечатка, ведь здесь мы видим два символа `\` и `n`, но это не так. С точки зрения компьютера — это один невидимый символ перевода строки: + +```java +// Мы это не изучали, но вы должны знать правду +// Ниже код, который возвращает длину строки +"a".length(); // 1 +"\n".length(); // 1 !!! +"\n\n".length(); // 2 !!! +``` + +Почему так сделано? `\n` — всего лишь способ записать символ перевода строки, но сам перевод строки по своему смыслу – это один символ, правда, невидимый. + +Именно поэтому и возникла такая задача. Нужно было как-то представить его на клавиатуре. А поскольку количество знаков на клавиатуре ограничено и отдано под самые важные, то все специальные символы реализуются в виде таких обозначений. + +Символ перевода строки не является чем-то специфичным для программирования. Все, кто хоть раз печатал на компьютере, использовал перевод строки, нажимая на Enter. + +Во многих редакторах есть опция, позволяющая включить отображение невидимых символов. Эта опция помогает понять, где они находятся, хотя это всего лишь схематичное отображение, ведь у этих невидимых символов нет графического представления: + +
+- Привет!¶ +- О, привет!¶ +- Как дела? ++ +Устройство, которое выводит соответствующий текст, учитывает этот символ. Например, принтер при встрече с LF протаскивает бумагу вверх на одну строку, а текстовый редактор переносит весь последующий текст ниже, также на одну строку. + +`\n` — это пример **экранирующей последовательности** (escape sequence). Их еще называют управляющими конструкциями. Хотя таких символов не один десяток, в программировании часто встречаются всего несколько. + +Кроме перевода строки, к таким символам относятся: + +* Табуляция — разрыв, получаемый при нажатии на кнопку Tab +* Возврат каретки (только в Windows) + +Программистам часто нужно использовать перевод строки `\n` для правильного форматирования текста: + +```java +System.out.println("Gregor Clegane\nDunsen\nPolliver\nChiswyck"); +``` + +На экран выведется: + +```text +Gregor Clegane +Dunsen +Polliver +Chiswyck +``` + +Обратите внимание на следующие моменты: + +1. Не имеет значения, что стоит перед или после `\n`: символ или пустая строка. Перевод будет обнаружен и выполнен в любом случае + +2. Помните, что строка может содержать один символ или вообще ноль символов. А еще строка может содержать только `\n`. Проанализируйте следующий пример: + + ```java + System.out.println("\n"); + System.out.println("Dunsen"); + ``` + + Здесь мы сначала выводим строку «перевод строки», а потом делаем вывод обыкновенной строки. Программа выведет на экран: + +
++ + Почему перед строкой *Dunsen* появилось две пустые строки, а не одна? Дело в том, что `System.out.println()` при выводе значения автоматически добавляет в конец символ перевода строки. + + Таким образом, один перевод строки мы указали явно, передав этот символ экранирующей последовательности аргументом в функцию, а второй перевод строки добавлен самой функцией автоматически. + + Еще пример кода: + + ```java + System.out.println("Polliver"); + System.out.println("Gregor Clegane"); + System.out.println(); + System.out.println("Chiswyck\n"); + System.out.println("Dunsen"); + ``` + + Вывод будет таким: + + ```text + Polliver + Gregor Clegane + + Chiswyck + + Dunsen + ``` + + Сейчас у вас достаточно знаний, чтобы самостоятельно разобраться и понять, почему вывод сформировался именно таким образом. + +3. Если нам понадобится вывести `\n` именно как текст (два отдельных печатных символа), то можно воспользоваться уже известным нам способом экранирования, добавив еще один `\` в начале. То есть последовательность `\\n` отобразится как символы `\` и `n`, идущие друг за другом: + + ```java + System.out.println("Joffrey loves using \\n"); + ``` + + на экран выйдет: + + ```text + Joffrey loves using \n + ``` + +Небольшое, но важное замечание про Windows. В Windows для перевода строк по умолчанию используется `\r\n` — это связано с историческими причинами. Такая комбинация хорошо работает только в Windows, но создает проблемы при переносе в другие системы: например, когда в команде разработчиков есть пользователи как Windows, так и Linux. + +Дело в том, что последовательность `\r\n` имеет разную трактовку в зависимости от выбранной кодировки. Поэтому в среде разработчиков принято всегда использовать `\n` без `\r`, так как LF всегда трактуется одинаково и отлично работает в любой системе. Не забудьте настроить ваш редактор на использование `\n`. diff --git a/modules/25-strings/15-escape-characters/ru/data.yml b/modules/25-strings/15-escape-characters/ru/data.yml new file mode 100644 index 00000000..3253c265 --- /dev/null +++ b/modules/25-strings/15-escape-characters/ru/data.yml @@ -0,0 +1,5 @@ +name: Экранирующие последовательности +tips: + - > + [История перевода + строки](https://ru.wikipedia.org/wiki/Перевод_строки#История) diff --git a/modules/25-strings/20-strings-concatenation/en/EXERCISE.md b/modules/25-strings/20-strings-concatenation/en/EXERCISE.md new file mode 100644 index 00000000..15c66a65 --- /dev/null +++ b/modules/25-strings/20-strings-concatenation/en/EXERCISE.md @@ -0,0 +1,8 @@ + +Display + +``` +Winter came for the House of Frey. +``` + +using concatenation of words. Each word must be represented in a separate line. Do not forget about the spaces. diff --git a/modules/25-strings/20-strings-concatenation/en/README.md b/modules/25-strings/20-strings-concatenation/en/README.md new file mode 100644 index 00000000..9014b5ea --- /dev/null +++ b/modules/25-strings/20-strings-concatenation/en/README.md @@ -0,0 +1,50 @@ + +We already know about the mathematical operation of addition. Such a program: + +```java +System.out.print(5 + 3); +``` + +will display `8` - the result of the binary operator `+` with the operands `5` and `3`. + +Above the strings defined their operations. You can "fold" two lines. Such a program: + +```java +System.out.print("Dragon" + "stone"); +``` + +will display `Dragonstone` - the result of the binary operator `+` with the 'Dragon' and 'stone' operands. + +This operation is called **concatenation**. Roughly speaking, this is the "gluing" of the lines. Gluing always happens in the same order in which the operands are written, in other words, the left operand becomes the left part of the string, and the right operand becomes the left. + +Here are some more examples: + +```java +System.out.print("Kings" + "wood"); // => Kingswood + +System.out.print("Kings" + "road"); // => Kingsroad + +System.out.print("King's" + "Landing"); // => King'sLanding +``` + +In the last example, the name of the city turned out to be with an error: *King's Landing* must be written with a space! But there were no spaces in our initial lines, and the spaces in the code to the left and right of the `+` character do not matter, because they are not part of the lines. + +Let's try to solve this problem in different ways: + +```java +System.out.print("King's " + "Landing"); // => King's Landing + +System.out.print("King's" + " Landing"); // => King's Landing + +System.out.print("King's" + " " + "Landing"); // => King's Landing +``` + +A space is the same character as the others, therefore, how many spaces to put in a line will be as much: + +```java +System.out.print("King's " + " Landing"); // => King's Landing + +System.out.print("King's " + " Landing"); // => King's Landing +``` + +https://replit.com/@hexlet/java-basics-strings diff --git a/modules/25-strings/20-strings-concatenation/en/data.yml b/modules/25-strings/20-strings-concatenation/en/data.yml new file mode 100644 index 00000000..a2c97c1d --- /dev/null +++ b/modules/25-strings/20-strings-concatenation/en/data.yml @@ -0,0 +1 @@ +name: Concatenation diff --git a/modules/25-strings/20-strings-concatenation/es/EXERCISE.md b/modules/25-strings/20-strings-concatenation/es/EXERCISE.md new file mode 100644 index 00000000..dbec67dc --- /dev/null +++ b/modules/25-strings/20-strings-concatenation/es/EXERCISE.md @@ -0,0 +1,8 @@ + +Utilizando `System.out.println()`, realiza la concatenación de palabras y muestra en la pantalla la siguiente frase: + +
+ Dunsen +
+Winter came for the House of Frey. ++ +Cada palabra debe ser escrita por separado y entre comillas, por ejemplo "Winter ". No olvides los espacios después de cada palabra. diff --git a/modules/25-strings/20-strings-concatenation/es/README.md b/modules/25-strings/20-strings-concatenation/es/README.md new file mode 100644 index 00000000..add2c344 --- /dev/null +++ b/modules/25-strings/20-strings-concatenation/es/README.md @@ -0,0 +1,40 @@ +Los programas constantemente operan con cadenas de texto. Todo lo que vemos en sitios web o aplicaciones móviles está representado de alguna manera como texto. Este texto, en su mayoría, es **dinámico**, es decir, se obtiene a partir de diferentes partes que se unen entre sí. La operación de unir cadenas de texto en programación se llama **concatenación** y se ve así: + +```java +// El operador es el mismo que se utiliza para sumar números, +// pero aquí tiene un significado diferente (semántica) +System.out.println("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 se convierte en la parte derecha. Aquí hay algunos ejemplos más: + +```java +System.out.println("Kings" + "wood"); // => Kingswood +// Orden inverso de las palabras +System.out.println("road" + "Kings"); // => roadKings +// Se pueden concatenar cualquier tipo de cadenas +System.out.println("King's" + "Landing"); // => King'sLanding +``` + +En el último ejemplo, el nombre de la ciudad se escribió incorrectamente: *King's Landing* debería tener un espacio en medio. Pero en nuestras cadenas iniciales no había espacios, y los espacios alrededor del símbolo `+` en el código no tienen importancia, ya que no forman parte de las cadenas. + +Hay tres formas de solucionar esta situación: + +```java +// Agregar un espacio en la parte izquierda +System.out.println("King's " + "Landing"); // => King's Landing +// Agregar un espacio en la parte derecha +System.out.println("King's" + " Landing"); // => King's Landing +// Agregar un espacio por separado +System.out.println("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 grande será la separación: + +```java +System.out.println("King's " + " Landing"); // => King's Landing +System.out.println("King's " + " Landing"); // => King's Landing +``` + +https://replit.com/@hexlet/java-basics-strings#Main.java diff --git a/modules/25-strings/20-strings-concatenation/es/data.yml b/modules/25-strings/20-strings-concatenation/es/data.yml new file mode 100644 index 00000000..05e69a79 --- /dev/null +++ b/modules/25-strings/20-strings-concatenation/es/data.yml @@ -0,0 +1 @@ +name: Concatenación diff --git a/modules/25-strings/20-strings-concatenation/ru/EXERCISE.md b/modules/25-strings/20-strings-concatenation/ru/EXERCISE.md new file mode 100644 index 00000000..6a40bdc1 --- /dev/null +++ b/modules/25-strings/20-strings-concatenation/ru/EXERCISE.md @@ -0,0 +1,8 @@ + +Используя `System.out.println()`, выполните конкатенацию слов и выведите на экран фразу: + +
+Winter came for the House of Frey. ++ +Каждое слово должно быть записано отдельно и взято в кавычки, например "Winter ". Не забудьте о пробелах после каждого слова. diff --git a/modules/25-strings/20-strings-concatenation/ru/README.md b/modules/25-strings/20-strings-concatenation/ru/README.md new file mode 100644 index 00000000..18f050c1 --- /dev/null +++ b/modules/25-strings/20-strings-concatenation/ru/README.md @@ -0,0 +1,40 @@ +Программы постоянно оперируют строками. Все, что мы видим на сайтах или в мобильных приложениях, так или иначе представлено в виде текста. Этот текст чаще всего **динамический** — полученный из разных частей, которые соединяются вместе. Операция соединения строк в программировании называется **конкатенацией** и выглядит так: + +```java +// Оператор такой же, как и при сложении чисел, +// но здесь он имеет другой смысл (семантику) +System.out.println("Dragon" + "stone"); +// => Dragonstone +``` + +Склеивание строк всегда происходит в том же порядке, в котором записаны операнды. Левый операнд становится левой частью строки, а правый — правой. Вот еще несколько примеров: + +```java +System.out.println("Kings" + "wood"); // => Kingswood +// Обратный порядок слов +System.out.println("road" + "Kings"); // => roadKings +// Конкатенировать можно абсолютно любые строки +System.out.println("King's" + "Landing"); // => King'sLanding +``` + +В последнем примере название города получилось с ошибкой: *King's Landing* нужно писать через пробел. Но в наших начальных строках не было пробелов, а пробелы в самом коде вокруг символа `+` не имеют значения, потому что они не являются частью строк. + +Из этой ситуации есть три выхода: + +```java +// Ставим пробел в левой части +System.out.println("King's " + "Landing"); // => King's Landing +// Ставим пробел в правой части +System.out.println("King's" + " Landing"); // => King's Landing +// Добавляем пробел отдельно +System.out.println("King's" + " " + "Landing"); // => King's Landing +``` + +Пробел — такой же символ, как и другие. Чем больше пробелов, тем шире отступы: + +```java +System.out.println("King's " + " Landing"); // => King's Landing +System.out.println("King's " + " Landing"); // => King's Landing +``` + +https://replit.com/@hexlet/java-basics-strings#Main.java diff --git a/modules/25-strings/20-strings-concatenation/ru/data.yml b/modules/25-strings/20-strings-concatenation/ru/data.yml new file mode 100644 index 00000000..c5324258 --- /dev/null +++ b/modules/25-strings/20-strings-concatenation/ru/data.yml @@ -0,0 +1 @@ +name: Конкатенация diff --git a/modules/30-variables/10-definition/en/EXERCISE.md b/modules/30-variables/10-definition/en/EXERCISE.md new file mode 100644 index 00000000..adcbe3f0 --- /dev/null +++ b/modules/30-variables/10-definition/en/EXERCISE.md @@ -0,0 +1 @@ + Create a variable with the name `motto` and the contents of `What is Dead May Never Die!`. Print the contents of the variable. diff --git a/modules/30-variables/10-definition/en/README.md b/modules/30-variables/10-definition/en/README.md new file mode 100644 index 00000000..65539c7b --- /dev/null +++ b/modules/30-variables/10-definition/en/README.md @@ -0,0 +1,41 @@ +Imagine the task, we need to print the phrase _Father!_ On the screen twice or even five times. This problem can be solved in the forehead: + +```java +System.out.print("Father!"); +System.out.print("Father!"); +``` + +In the simplest case, this is what you should do, but if the phrase _Father!_ Begins to be used more often, and even in different parts of the program, you will have to repeat it everywhere. Problems with this approach will begin when you need to change our phrase, and this happens quite often. We will have to find all the places where the phrase _Father!_ Was used and perform the necessary replacement. And you can do differently. Instead of copying our expression, just create a variable with this phrase. + +``` +//greeting - translated as greeting +var greeting = "Father!"; +System.out.print(greeting); +System.out.print(greeting); +``` + +In the `var greeting = "Father!"` - the value of `"Father!"` is assigned to a variable of type String named `greeting`. + +When the variable is created, you can start using it. It is substituted in those places where our phrase used to stand. During code execution, the line `System.out.print(greeting)` replaces the variable with its contents, and then the code is executed. As a result, the output of our program will be as follows: + +
+ Father! + Father! ++ +https://replit.com/@hexlet/java-basics-variables-1 + +For the name of the variable, any set of valid characters is used, which include letters of the English alphabet, numbers and the underscore character `_`. In this case, the number can not be put at the beginning. Variable names are case-sensitive, that is, the name `hello` and the name `heLLo` are two different names, and therefore two variables. + +The number of variables created is not limited in any way; large programs contain tens and hundreds of thousands of variable names: + +```java +var greeting1 = "Father!"; +System.out.print(greeting1); +System.out.print(greeting1); +var greeting2 = "Mother!"; +System.out.print(greeting2); +System.out.print(greeting2); +``` + +For the convenience of program analysis, it is customary to create variables as close as possible to the place where they are used. diff --git a/modules/30-variables/10-definition/en/data.yml b/modules/30-variables/10-definition/en/data.yml new file mode 100644 index 00000000..ea8555f2 --- /dev/null +++ b/modules/30-variables/10-definition/en/data.yml @@ -0,0 +1,5 @@ +name: What is a variable +tips: + - > + [Naming in + programming](https://ru.hexlet.io/blog/posts/naming-in-programming) diff --git a/modules/30-variables/10-definition/es/EXERCISE.md b/modules/30-variables/10-definition/es/EXERCISE.md new file mode 100644 index 00000000..72726cba --- /dev/null +++ b/modules/30-variables/10-definition/es/EXERCISE.md @@ -0,0 +1,4 @@ +Crea una variable llamada `motto` con el contenido `What Is Dead May Never Die!`. Imprime el contenido de la variable. +
+What Is Dead May Never Die! +diff --git a/modules/30-variables/10-definition/es/README.md b/modules/30-variables/10-definition/es/README.md new file mode 100644 index 00000000..f66c466d --- /dev/null +++ b/modules/30-variables/10-definition/es/README.md @@ -0,0 +1,47 @@ +Imagina que tienes la tarea de imprimir en la pantalla la frase *¡Padre!* dos veces. Puedes resolver este problema de manera directa: + +```java +System.out.println("¡Padre!"); // => ¡Padre! +System.out.println("¡Padre!"); // => ¡Padre! +``` + +En el caso más simple, esto funciona bien. Sin embargo, si la frase *¡Padre!* se utiliza con más frecuencia y en diferentes partes del programa, tendrás que repetirla en todas partes. Los problemas con este enfoque surgirán cuando necesites cambiar la frase, lo cual ocurre con bastante frecuencia. Tendrás que encontrar todos los lugares donde se utilizó la frase *¡Padre!* y realizar el reemplazo necesario. Pero hay otra forma de hacerlo. En lugar de copiar nuestra expresión, simplemente crea una variable con esta frase: + +```java +// greeting - se traduce como saludo +// var - solo se necesita al definir la variable +var greeting = "¡Padre!"; +System.out.println(greeting); +System.out.println(greeting); +``` + +En la línea `var greeting = "¡Padre!"`, se asigna el valor `"¡Padre!"` a la variable con el nombre `greeting`. + +Una vez que se crea la variable, puedes comenzar a usarla. Se inserta en los lugares donde solía estar nuestra frase. Durante la ejecución del código, en la línea `System.out.println(greeting)`, el contenido de la variable se inserta en lugar de la variable misma, y luego se ejecuta el código. Como resultado, la salida de nuestro programa será la siguiente: + +
+¡Padre! +¡Padre! ++ +Para el nombre de la variable, se puede utilizar cualquier conjunto de caracteres válidos, que incluyen letras del alfabeto inglés, números y el guión bajo `_`. 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 dos variables diferentes. A continuación se muestra un ejemplo con dos variables diferentes: + +```java +var greeting1 = "¡Padre!"; +System.out.println(greeting1); +System.out.println(greeting1); +var greeting2 = "¡Madre!"; +System.out.println(greeting2); +System.out.println(greeting2); +``` + +
+¡Padre! +¡Padre! +¡Madre! +¡Madre! ++ +https://replit.com/@hexlet/java-basics-variables-1 + +Para facilitar el análisis del programa, se recomienda crear variables lo más cerca posible del lugar donde se utilizan. diff --git a/modules/30-variables/10-definition/es/data.yml b/modules/30-variables/10-definition/es/data.yml new file mode 100644 index 00000000..a04b053b --- /dev/null +++ b/modules/30-variables/10-definition/es/data.yml @@ -0,0 +1,4 @@ +name: ¿Qué es una variable? +tips: + - | + [Nomenclatura en programación](https://codica.la/blog/naming-in-programming) diff --git a/modules/30-variables/10-definition/ru/EXERCISE.md b/modules/30-variables/10-definition/ru/EXERCISE.md new file mode 100644 index 00000000..3a764fa5 --- /dev/null +++ b/modules/30-variables/10-definition/ru/EXERCISE.md @@ -0,0 +1,4 @@ +Создайте переменную с именем `motto` и содержимым `What Is Dead May Never Die!`. Распечатайте содержимое переменной. +
+What Is Dead May Never Die! +diff --git a/modules/30-variables/10-definition/ru/README.md b/modules/30-variables/10-definition/ru/README.md new file mode 100644 index 00000000..a001e2e5 --- /dev/null +++ b/modules/30-variables/10-definition/ru/README.md @@ -0,0 +1,47 @@ +Представьте себе задачу — нужно напечатать на экран фразу *Father!* два раза. Эту задачу можно решить в лоб: + +```java +System.out.println("Father!"); // => Father! +System.out.println("Father!"); // => Father! +``` + +В простейшем случае так и стоит поступить, но если фраза *Father!* начнет использоваться чаще, да еще и в разных частях программы, то придется ее везде повторять. Проблемы с таким подходом начнутся тогда, когда понадобится изменить нашу фразу, а такое происходит довольно часто. Нам придется найти все места, где использовалась фраза *Father!* и выполнить необходимую замену. А можно поступить по-другому. Вместо копирования нашего выражения, достаточно создать переменную с этой фразой: + +```java +// greeting – переводится как приветствие +// var – нужен только при определении переменной +var greeting = "Father!"; +System.out.println(greeting); +System.out.println(greeting); +``` + +В строчке `var greeting = "Father!"` - происходит присваивание значения `"Father!"` переменной с именем `greeting`. + +Когда переменная создана, можно начать ее использовать. Она подставляется в те места, где раньше стояла наша фраза. Во время выполнения кода в строке `System.out.println(greeting)` вместо переменной подставляется ее содержимое, а затем выполняется код. В результате вывод нашей программы будет таким: + +
+Father! +Father! ++ +Для имени переменной используется любой набор допустимых символов, к которым относятся буквы английского алфавита, цифры, символ нижнего подчеркивания `_`. При этом цифру нельзя ставить в начале. Имена переменных регистрозависимы, то есть имя `hello` и имя `heLLo` - это два разных имени и две переменные. Ниже пример с двумя разными переменными: + +```java +var greeting1 = "Father!"; +System.out.println(greeting1); +System.out.println(greeting1); +var greeting2 = "Mother!"; +System.out.println(greeting2); +System.out.println(greeting2); +``` + +
+Father! +Father! +Mother! +Mother! ++ +https://replit.com/@hexlet/java-basics-variables-1 + +Для удобства анализа программы переменные принято создавать как можно ближе к тому месту, где они используются. diff --git a/modules/30-variables/10-definition/ru/data.yml b/modules/30-variables/10-definition/ru/data.yml new file mode 100644 index 00000000..2c41c792 --- /dev/null +++ b/modules/30-variables/10-definition/ru/data.yml @@ -0,0 +1,5 @@ +name: Что такое переменная +tips: + - > + [Именование в + программировании](https://ru.hexlet.io/blog/posts/naming-in-programming) diff --git a/modules/30-variables/12-change/en/EXERCISE.md b/modules/30-variables/12-change/en/EXERCISE.md new file mode 100644 index 00000000..8c081d6f --- /dev/null +++ b/modules/30-variables/12-change/en/EXERCISE.md @@ -0,0 +1 @@ +The code defines a variable with the value `'Brienna'`. Redefine the value of this variable and assign it the same line, but upside down. diff --git a/modules/30-variables/12-change/en/README.md b/modules/30-variables/12-change/en/README.md new file mode 100644 index 00000000..5ffdec92 --- /dev/null +++ b/modules/30-variables/12-change/en/README.md @@ -0,0 +1,18 @@ + +The word "variable" itself means that it can be changed. Indeed, over time within the program, the values of the variables may change. + +```java +// greeting - translated as greeting +var greeting = "Father!"; +System.out.print(greeting); +System.out.print(greeting); +greeting = "Mother!"; +System.out.print(greeting); +System.out.print(greeting); +``` + +https://replit.com/@hexlet/java-basics-variables-2 + +The name remains the same, but inside the other data. It should be noted that when changing variables, the type of data contained in them cannot change (this is not quite the case for object-oriented programming, but for the time being we will not go into details). If a variable was assigned a string, then when compiling this assignment — even before the program was started — java associates the data type “string” with this variable, and knows that there will always be only strings, and will not let it put something else in it. + +Variables are powerful, and at the same time dangerous thing. One can never be exactly sure what is written inside it without analyzing the code that is in front of the variable. This is exactly what the developers are doing during debugging, when they are trying to figure out why the program is not working or is not working as intended. diff --git a/modules/30-variables/12-change/en/data.yml b/modules/30-variables/12-change/en/data.yml new file mode 100644 index 00000000..e51b8b21 --- /dev/null +++ b/modules/30-variables/12-change/en/data.yml @@ -0,0 +1 @@ +name: Variable change diff --git a/modules/30-variables/12-change/es/EXERCISE.md b/modules/30-variables/12-change/es/EXERCISE.md new file mode 100644 index 00000000..fb4f66a8 --- /dev/null +++ b/modules/30-variables/12-change/es/EXERCISE.md @@ -0,0 +1,6 @@ + +En el código se define una variable con el valor `"Brienna"`. Reasigna el valor de esta variable para que sea el mismo, pero en orden inverso. + +
+anneirB +diff --git a/modules/30-variables/12-change/es/README.md b/modules/30-variables/12-change/es/README.md new file mode 100644 index 00000000..37887c31 --- /dev/null +++ b/modules/30-variables/12-change/es/README.md @@ -0,0 +1,25 @@ +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: + +```java +var saludo = "¡Padre!"; +System.out.println(saludo); +System.out.println(saludo); +// Ya no se utiliza "var" porque la variable fue definida anteriormente +saludo = "¡Madre!"; +System.out.println(saludo); +System.out.println(saludo); +``` + +https://replit.com/@hexlet/java-basics-variables-2 + +Java es un lenguaje de programación de tipado estático. Esto significa que el tipo de una variable se establece al definirla y no cambia después. + +En el ejemplo anterior, asignamos una cadena de texto al crear la variable. El compilador recuerda el tipo y verifica todos los cambios posteriores en la variable. Si intentamos asignar un número a esta misma variable, obtendremos el siguiente error: + +```java +saludo = 5; +# Error: +# tipos incompatibles: no se puede convertir un entero en java.lang.String +``` + +El compilador realiza esta verificación sin ejecutar el código, por eso se llama **tipado estático**. En JavaScript, Ruby, PHP, Python y otros lenguajes dinámicos, este comportamiento no es un error, ya que una variable puede cambiar fácilmente su tipo durante la ejecución. diff --git a/modules/30-variables/12-change/es/data.yml b/modules/30-variables/12-change/es/data.yml new file mode 100644 index 00000000..369d10ed --- /dev/null +++ b/modules/30-variables/12-change/es/data.yml @@ -0,0 +1 @@ +name: Cambio de variable diff --git a/modules/30-variables/12-change/ru/EXERCISE.md b/modules/30-variables/12-change/ru/EXERCISE.md new file mode 100644 index 00000000..b7147523 --- /dev/null +++ b/modules/30-variables/12-change/ru/EXERCISE.md @@ -0,0 +1,6 @@ + +В коде определена переменная со значением `"Brienna"`. Переопределите значение этой переменной и присвойте ей такую же, но в перевернутом виде. + +
+anneirB +diff --git a/modules/30-variables/12-change/ru/README.md b/modules/30-variables/12-change/ru/README.md new file mode 100644 index 00000000..4c3287db --- /dev/null +++ b/modules/30-variables/12-change/ru/README.md @@ -0,0 +1,26 @@ +Само слово «переменная» говорит, что ее можно менять. И действительно, с течением времени внутри программы, значения переменных могут изменяться: + +```java +var greeting = "Father!"; +System.out.println(greeting); +System.out.println(greeting); +// var уже не используется, так как переменная была определена выше +greeting = "Mother!"; +System.out.println(greeting); +System.out.println(greeting); +``` + +https://replit.com/@hexlet/java-basics-variables-2 + +Java — статически типизированный язык. Это значит, что тип переменной задается при определении и больше не меняется. + +В примере выше мы присвоили строку при создании переменной. Компилятор запоминает тип и проверяет все последующие изменения переменной. Если попробовать этой же переменной присвоить число, то мы получим следующую ошибку: + +```java +greeting = 5; +# Error: +# incompatible types: int cannot be converted to java.lang.String +# несовместимые типы: число не может быть превращено в строку +``` + +Компилятор делает такую проверку без запуска кода на выполнение, именно поэтому такой вид типизации называют **статическим**. В JavaScript, Ruby, PHP, Python и других динамических языках подобное поведение не является ошибкой, переменная может легко изменить свой тип в процессе работы. diff --git a/modules/30-variables/12-change/ru/data.yml b/modules/30-variables/12-change/ru/data.yml new file mode 100644 index 00000000..5176665b --- /dev/null +++ b/modules/30-variables/12-change/ru/data.yml @@ -0,0 +1 @@ +name: Изменение переменной diff --git a/modules/30-variables/13-variables-naming/en/EXERCISE.md b/modules/30-variables/13-variables-naming/en/EXERCISE.md new file mode 100644 index 00000000..92e86a26 --- /dev/null +++ b/modules/30-variables/13-variables-naming/en/EXERCISE.md @@ -0,0 +1,4 @@ + +Create two variables with the names “first number” and “second number” using lowerCamelCase. Write in the first variable the number `1.10`, in the second - `-100`. Display the product of the numbers written in the resulting variables. + +The code will work with any names, and our system always checks only the result on the screen, so the execution of this task is under your responsibility. diff --git a/modules/30-variables/13-variables-naming/en/README.md b/modules/30-variables/13-variables-naming/en/README.md new file mode 100644 index 00000000..1700d73c --- /dev/null +++ b/modules/30-variables/13-variables-naming/en/README.md @@ -0,0 +1,12 @@ + +Variable naming is an important aspect of programming. The names should not only convey the meaning, but also follow the syntactic rules, which, as a rule, are not checked at all at the level of the language, but are necessary during development. The process of writing programs in the modern world is teamwork, and for better teamwork in a team, the code is written in the same style, as if one person was working on it. + +The naming of variables can be divided into three main approaches, which sometimes combine with each other. All these approaches manifest themselves when the variable name consists of several words: + +* kebab-case - the variable components are separated by a hyphen. For example: `my-super-var`. +* snake_case - underscore is used for separation. For example: `my_super_var`. +* CamelCase - each word in a variable is written with a capital letter. For example: `MySuperVar`. + +In Java, CamelCase and its variation lowerCamelCase are used, in which the first letter of the first word is lowercase. It is lowerCamelCase that is used for variables. + +Another common rule is: do not use transliteration for names, only English. If you experience difficulties with English, use a translator. Over time, digging into someone else's code, you will form the right concepts for naming. diff --git a/modules/30-variables/13-variables-naming/en/data.yml b/modules/30-variables/13-variables-naming/en/data.yml new file mode 100644 index 00000000..fe8e2d6a --- /dev/null +++ b/modules/30-variables/13-variables-naming/en/data.yml @@ -0,0 +1 @@ +name: Variable naming diff --git a/modules/30-variables/13-variables-naming/es/EXERCISE.md b/modules/30-variables/13-variables-naming/es/EXERCISE.md new file mode 100644 index 00000000..c2b19367 --- /dev/null +++ b/modules/30-variables/13-variables-naming/es/EXERCISE.md @@ -0,0 +1,8 @@ + +Crea dos variables con los nombres "primerNumero" y "segundoNumero" en inglés, utilizando lowerCamelCase. Asigna el número `1.10` a la primera variable y `-100` a la segunda. Imprime en pantalla el producto de los números almacenados en las variables resultantes. + +
+-110.00000000000001 ++ +El código funcionará con cualquier nombre, y nuestro sistema siempre verifica solo el resultado en pantalla, por lo que completar esta tarea es responsabilidad tuya. diff --git a/modules/30-variables/13-variables-naming/es/README.md b/modules/30-variables/13-variables-naming/es/README.md new file mode 100644 index 00000000..522f5654 --- /dev/null +++ b/modules/30-variables/13-variables-naming/es/README.md @@ -0,0 +1,15 @@ +Imaginemos que el programa del último curso se ve así: + +```java +var x = "¡Padre!"; +System.out.println(x); +System.out.println(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. Los nombres son importantes para los programadores, ya que leemos código con mucha más frecuencia de lo que escribimos. Y no solo 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 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. + +Existe una regla general aceptada: no utilice transliteraciones para los nombres, solo use el idioma inglés. Si tiene dificultades con el inglés, utilice un traductor. Con el tiempo, al investigar el código de otras personas, 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 con deudas del trimestre anterior"? diff --git a/modules/30-variables/13-variables-naming/es/data.yml b/modules/30-variables/13-variables-naming/es/data.yml new file mode 100644 index 00000000..16c19da9 --- /dev/null +++ b/modules/30-variables/13-variables-naming/es/data.yml @@ -0,0 +1 @@ +name: Selección de nombres de variables diff --git a/modules/30-variables/13-variables-naming/ru/EXERCISE.md b/modules/30-variables/13-variables-naming/ru/EXERCISE.md new file mode 100644 index 00000000..f58a6d99 --- /dev/null +++ b/modules/30-variables/13-variables-naming/ru/EXERCISE.md @@ -0,0 +1,8 @@ + +Создайте две переменные с именами «первое число» и «второе число» на английском языке, используя lowerCamelCase. Запишите в первую переменную число `1.10`, во вторую — `-100`. Выведите на экран произведение чисел, записанных в получившиеся переменные. + +
+-110.00000000000001 ++ +Код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. diff --git a/modules/30-variables/13-variables-naming/ru/README.md b/modules/30-variables/13-variables-naming/ru/README.md new file mode 100644 index 00000000..30452ce5 --- /dev/null +++ b/modules/30-variables/13-variables-naming/ru/README.md @@ -0,0 +1,15 @@ +Представим себе, что программа из прошлого урока выглядит так: + +```java +var x = "Father!"; +System.out.println(x); +System.out.println(x); +``` + +Она по-прежнему работает, но в ней изменилось имя переменной на `x`. Компьютеру без разницы, как мы называем переменные. Названия важны для программистов, ведь мы гораздо чаще читаем код, чем пишем. Причем не свой, а написанный другими людьми. От качества и понятности имен переменных зависит половина успеха в анализе кода. + +Лучше посидеть и придумать название, которое описывает суть переменной, чем назвать ее как попало, а в будущем переделывать. Постарайтесь давать им такие имена, чтобы они были максимально понятны без контекста, без изучения окружающего кода. + +Существует общепринятое правило: не используйте транслит для имен, только английский язык. Если вы испытываете сложности с английским, то пользуйтесь переводчиком. Со временем, копаясь в чужом коде, вы сформируете правильные понятия для именования. + +Среди разработчиков есть шутка: «самое сложное в программировании — названия переменных и инвалидация кеша». Придумывать названия и правда сложно. Как бы вы назвали переменную, в которой хранится «количество неоплаченных заказов от клиентов, имеющих задолженность в предыдущем квартале»? diff --git a/modules/30-variables/13-variables-naming/ru/data.yml b/modules/30-variables/13-variables-naming/ru/data.yml new file mode 100644 index 00000000..e2dbfff7 --- /dev/null +++ b/modules/30-variables/13-variables-naming/ru/data.yml @@ -0,0 +1 @@ +name: Выбор имени переменной diff --git a/modules/30-variables/14-errors/en/EXERCISE.md b/modules/30-variables/14-errors/en/EXERCISE.md new file mode 100644 index 00000000..b49139e9 --- /dev/null +++ b/modules/30-variables/14-errors/en/EXERCISE.md @@ -0,0 +1 @@ +Find an undeclared variable in the program and declare it assigning to it the value of `"Dragon"`; diff --git a/modules/30-variables/14-errors/en/README.md b/modules/30-variables/14-errors/en/README.md new file mode 100644 index 00000000..ad8e770b --- /dev/null +++ b/modules/30-variables/14-errors/en/README.md @@ -0,0 +1,16 @@ + +The main rule: a variable must be declared before it is used. If you do this later, the program simply will not work. + +```java +System.out.print(greeting); +greeting = "Father!"; +``` + +The launch of the program the above ends with an error: + +Error: java: cannot find symbol +symbol: variable greeting + +This error means that the code uses a variable that is not defined. And in the error itself they say this directly: variable greeting. In addition to the wrong order of definition, in Java there are commonplace typos, both when using a variable and when it is declared. + +The number of such errors is reduced by using a properly configured editor. This editor highlights the names that are used without the announcement and warns of possible problems. diff --git a/modules/30-variables/14-errors/en/data.yml b/modules/30-variables/14-errors/en/data.yml new file mode 100644 index 00000000..3577bd47 --- /dev/null +++ b/modules/30-variables/14-errors/en/data.yml @@ -0,0 +1 @@ +name: Errors when working with variables diff --git a/modules/30-variables/14-errors/es/EXERCISE.md b/modules/30-variables/14-errors/es/EXERCISE.md new file mode 100644 index 00000000..f5464e7c --- /dev/null +++ b/modules/30-variables/14-errors/es/EXERCISE.md @@ -0,0 +1,4 @@ +Encuentra la variable no declarada en el programa y declárala asignándole el valor `"Dragon"`; +
+Targaryen and Dragon +diff --git a/modules/30-variables/14-errors/es/README.md b/modules/30-variables/14-errors/es/README.md new file mode 100644 index 00000000..a219202a --- /dev/null +++ b/modules/30-variables/14-errors/es/README.md @@ -0,0 +1,28 @@ +El orden de las instrucciones en el código con variables es de gran importancia. La variable debe ser definida antes de ser utilizada. A continuación se muestra un ejemplo de error que cometen con frecuencia los principiantes: + +```java +System.out.println(greeting); +var greeting = "¡Padre!"; +``` + +La ejecución del programa anterior termina con un error: + +```text +Error: java: no se puede encontrar el símbolo +símbolo: variable greeting +``` + +El error **cannot find symbol** significa que se está utilizando una variable en el código que no está definida. Además, el propio error lo indica claramente: `variable greeting`. + +Además del orden incorrecto de la definición, también se encuentran errores tipográficos tanto al utilizar la variable como al declararla. + +Otro error común es intentar declarar una variable que ya ha sido declarada: + +```java +var greeting = "¡Padre!"; +var greeting = "¡Padre!"; +``` + +Esto no se puede hacer. Tendrás que crear una nueva variable. + +La cantidad de este tipo de errores se reduce mediante el uso de un editor correctamente configurado. Este tipo de editor resalta los nombres que se utilizan sin ser declarados y advierte sobre posibles problemas. diff --git a/modules/30-variables/14-errors/es/data.yml b/modules/30-variables/14-errors/es/data.yml new file mode 100644 index 00000000..3f3d615e --- /dev/null +++ b/modules/30-variables/14-errors/es/data.yml @@ -0,0 +1 @@ +name: Errores al trabajar con variables diff --git a/modules/30-variables/14-errors/ru/EXERCISE.md b/modules/30-variables/14-errors/ru/EXERCISE.md new file mode 100644 index 00000000..20168ee1 --- /dev/null +++ b/modules/30-variables/14-errors/ru/EXERCISE.md @@ -0,0 +1,4 @@ +Найдите в программе необъявленную переменную и объявите ее, присвоив ей значение `"Dragon"`; +
+Targaryen and Dragon +diff --git a/modules/30-variables/14-errors/ru/README.md b/modules/30-variables/14-errors/ru/README.md new file mode 100644 index 00000000..e1aef78e --- /dev/null +++ b/modules/30-variables/14-errors/ru/README.md @@ -0,0 +1,28 @@ +Порядок инструкций в коде с переменными имеет огромное значение. Переменная должна быть определена до того, как будет использована. Ниже пример ошибки, которую очень часто допускают новички: + +```java +System.out.println(greeting); +var greeting = "Father!"; +``` + +Запуск программы выше завершается с ошибкой: + +```text +Error: java: cannot find symbol +symbol: variable greeting +``` + +Ошибка **cannot find symbol** означает, что в коде используется переменная, которая не определена. Причем в самой ошибке об этом говорят прямо: `variable greeting`. + +Кроме неправильного порядка определения, еще встречаются банальные опечатки, причем как при использовании переменной, так и при ее объявлении. + +Еще одна распространенная ошибка — попытаться объявить уже объявленную переменную: + +```java +var greeting = "Father!"; +var greeting = "Father!"; +``` + +Так делать нельзя. Придется создать новую переменную. + +Количество подобных ошибок уменьшается за счет использования правильно настроенного редактора. Такой редактор подсвечивает имена, которые используются без объявления, и предупреждает о возможных проблемах. diff --git a/modules/30-variables/14-errors/ru/data.yml b/modules/30-variables/14-errors/ru/data.yml new file mode 100644 index 00000000..52155dd2 --- /dev/null +++ b/modules/30-variables/14-errors/ru/data.yml @@ -0,0 +1 @@ +name: Ошибки при работе с переменными diff --git a/modules/30-variables/15-variable-expressions/en/EXERCISE.md b/modules/30-variables/15-variable-expressions/en/EXERCISE.md new file mode 100644 index 00000000..5b562085 --- /dev/null +++ b/modules/30-variables/15-variable-expressions/en/EXERCISE.md @@ -0,0 +1,13 @@ + +Write a program that takes the original amount of euros recorded in the variable `eurosCount`, converts the euro into dollars and displays on the screen. Then, the resulting value translates into rubles and displays on the new line. + +Example withdrawal for 100 euros: + +``` +125.0 +7500.0 +``` + +We believe that: +- 1 euro = 1.25 dollars +- 1 dollar = 60 rubles diff --git a/modules/30-variables/15-variable-expressions/en/README.md b/modules/30-variables/15-variable-expressions/en/README.md new file mode 100644 index 00000000..c242223c --- /dev/null +++ b/modules/30-variables/15-variable-expressions/en/README.md @@ -0,0 +1,55 @@ + +Variables are useful not only for storing and reusing information, but also for simplifying complex calculations. Let's look at an example: you need to convert euros to rubles in dollars. Such conversions through an intermediate currency are often made by banks when shopping abroad. + +To begin with we will transfer 50 euros to dollars. Suppose that one euro — 1.25 dollars: + +```java +var dollarsCount = 50 * 1.25; +System.out.print(dollarsCount); +``` + +In the previous lesson we wrote down a specific value in a variable. And here `var dollarsCount = 50 * 1.25;` to the right of the sign equals **expression**. The program will calculate the result — `62.5` — and write it into a variable. From the point of view of the program, it does not matter what is in front of him: `62.5` or `50 * 1.25`, both of these options are expressions that need to be calculated. And they are calculated in the same value — `62.5`. + +Any string is an expression. String concatenation is also an expression. When the program sees the expression, it processes it and generates the result — **the value of the expression**. Here are some examples of expressions, and in the comments to the right of each expression is the total value: + +```java +62.5 // => 62.5 +50 * 1.25 // => 62.5 +120 / 10 * 2 // => 24 +Integer.parseInt("100") // => 100 + +"hello" // => "hello" +"Good" + "will" // => "Goodwill" +``` + +The rules for constructing code (language grammar) are such that in those places where an expression is expected, you can put any calculation (not only mathematical, but also, for example, string — as concatenation), and the program will remain operable. For this reason, it is impossible to describe and show all use cases of all operations. + +Programs consist of many combinations of expressions, and understanding this concept is one of the key steps in your path. + +Let's return to our monetary program. We write the value of the dollar in rubles, as a separate variable. We calculate the price of 50 euros in dollars, multiplying them by `1.25`. Suppose that 1 dollar — 60 rubles: + +```java +var rublesPerDollar = 60; +var dollarsCount = 50 * 1.25; // => 62.5 +var rublesCount = dollarsCount * rublesPerDollar; // => 3750 + +System.out.print(rublesCount); +``` + +Now let's add text to the output using concatenation: + +```java +var rublesPerDollar = 60; +var dollarsCount = 50 * 1.25; // => 62.5 +var rublesCount = dollarsCount * rublesPerDollar; // => 3750 + +System.out.print("The price is" + rublesCount + "rubles"); +``` + +https://replit.com/@hexlet/java-basics-variables-3 + +The price is 3750 rubles + +Any variable can be part of any expression. At the time of calculation, the value of the variable is substituted for its value. + +The value of `dollarsCount` is calculated before it is used in other expressions. When the time comes to use a variable, Java "knows" the value, because it has already calculated it. diff --git a/modules/30-variables/15-variable-expressions/en/data.yml b/modules/30-variables/15-variable-expressions/en/data.yml new file mode 100644 index 00000000..6d7f96a6 --- /dev/null +++ b/modules/30-variables/15-variable-expressions/en/data.yml @@ -0,0 +1,5 @@ +name: Expressions in definitions +tips: + - > + To translate a line, you can use `\ n` between the withdrawal of dollars and + rubles. diff --git a/modules/30-variables/15-variable-expressions/es/EXERCISE.md b/modules/30-variables/15-variable-expressions/es/EXERCISE.md new file mode 100644 index 00000000..b5d7a45e --- /dev/null +++ b/modules/30-variables/15-variable-expressions/es/EXERCISE.md @@ -0,0 +1,14 @@ + +Escribe un programa que tome la cantidad inicial de euros almacenada en la variable `amountEuros`, convierta los euros a dólares y los muestre en la pantalla. Luego, convierte el valor obtenido a rublos y lo muestra en una nueva línea. + +Ejemplo de salida para 100 euros: + +
+125.0 +7500.0 ++ +Supongamos que: + +- 1 euro = 1.25 dólares +- 1 dólar = 60 rublos diff --git a/modules/30-variables/15-variable-expressions/es/README.md b/modules/30-variables/15-variable-expressions/es/README.md new file mode 100644 index 00000000..4408d9ab --- /dev/null +++ b/modules/30-variables/15-variable-expressions/es/README.md @@ -0,0 +1,57 @@ +Las variables son útiles no solo para almacenar y reutilizar información, sino también para simplificar cálculos complejos. + +Veamos un ejemplo: necesitamos convertir euros a rublos 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: + +```java +var amountDollars = 50 * 1.25; +System.out.println(amountDollars); +``` + +En el bloque anterior, asignamos un valor específico a una variable. Pero aquí, a la derecha del signo igual, hay una **expresión**: + +```java +var amountDollars = 50 * 1.25; +``` + +El programa calculará el resultado *62.5* y lo asignará a la variable. Desde el punto de vista del programa, no importa si está escrito *62.5* o *50 * 1.25*. Ambas opciones son expresiones que deben evaluarse. Y se evalúan en el mismo valor *62.5*. + +Cualquier cadena de texto es una expresión. La concatenación de cadenas también es una expresión. Cuando el programa encuentra una expresión, la evalúa y **devuelve** el resultado. + +Aquí tienes algunos ejemplos de expresiones. A la derecha de cada expresión, se muestra el valor resultante: + +```java +62.5 // 62.5 +50 * 1.25 // 62.5 +120 / 10 * 2 // 24 +"Hexlet" // "Hexlet" +"Good" + "will" // "Goodwill" +``` + +Las reglas de construcción del código permiten colocar cualquier cálculo donde se espera una expresión. Y el cálculo puede ser tanto matemático como de cadenas de texto, como la concatenación. El programa seguirá funcionando correctamente. + +Por esta razón, no es posible describir y mostrar todos los casos de uso de todas las operaciones. Los programas están compuestos por muchas combinaciones de expresiones, y comprender este concepto es uno de los pasos clave en tu camino. + +Volvamos a nuestro programa de conversión de moneda. Guardemos el valor del dólar en rublos 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 60 rublos: + +```java +var rublesPerDollar = 60; +var amountDollars = 50 * 1.25; // 62.5 +var amountRubles = amountDollars * rublesPerDollar; // 3750 +System.out.println(amountRubles); // => 3750 +``` + +Y ahora agreguemos texto a la salida utilizando la concatenación: + +```java +var rublesPerDollar = 60; +var amountDollars = 50 * 1.25; // 62.5 +var amountRubles = amountDollars * rublesPerDollar; // 3750 +System.out.println("El precio es " + amountRubles + " rublos"); +// => El precio es 3750 rublos +``` + +https://replit.com/@hexlet/java-basics-variables-3 + +Cualquier variable puede formar parte de cualquier expresión. En el momento de la evaluación, el valor de la variable se sustituye en lugar de su nombre. El valor de `amountDollars` se calcula antes de que se utilice en otras expresiones. Cuando llega el momento de usar la variable, Java conoce su valor porque ya lo ha calculado. diff --git a/modules/30-variables/15-variable-expressions/es/data.yml b/modules/30-variables/15-variable-expressions/es/data.yml new file mode 100644 index 00000000..184b0e4b --- /dev/null +++ b/modules/30-variables/15-variable-expressions/es/data.yml @@ -0,0 +1,6 @@ +name: Expresiones en definiciones +tips: + - > + Para imprimir una nueva línea, puedes usar `\n` entre la impresión de los + dólares y los rublos, o puedes usar el método `println()` la cantidad de + veces necesaria. diff --git a/modules/30-variables/15-variable-expressions/ru/EXERCISE.md b/modules/30-variables/15-variable-expressions/ru/EXERCISE.md new file mode 100644 index 00000000..4781d26a --- /dev/null +++ b/modules/30-variables/15-variable-expressions/ru/EXERCISE.md @@ -0,0 +1,14 @@ + +Напишите программу, которая берет исходное количество евро, записанное в переменную `eurosCount`, переводит евро в доллары и выводит на экран. Затем полученное значение переводит в рубли и выводит на новой строчке. + +Пример вывода для 100 евро: + +
+125.0 +7500.0 ++ +Считаем, что: + +- 1 евро = 1.25 долларов +- 1 доллар = 60 рублей diff --git a/modules/30-variables/15-variable-expressions/ru/README.md b/modules/30-variables/15-variable-expressions/ru/README.md new file mode 100644 index 00000000..fffa4b6f --- /dev/null +++ b/modules/30-variables/15-variable-expressions/ru/README.md @@ -0,0 +1,57 @@ +Переменные полезны не только для хранения и переиспользования информации, но и для упрощения сложных вычислений. + +Давайте рассмотрим пример: нужно перевести евро в рубли через доллары. Подобные конвертации через промежуточную валюту часто делают банки при покупках за рубежом. + +Для начала переведем 50 евро в доллары. Допустим, что один евро — 1.25 доллара: + +```java +var dollarsCount = 50 * 1.25; +System.out.println(dollarsCount); +``` + +В предыдущем блоке мы записывали в переменную конкретное значение. А здесь справа от знака равно находится **выражение**: + +```java +var dollarsCount = 50 * 1.25;` +``` + +Программа вычислит результат *62.5* и запишет его в переменную. С точки зрения программы не важно, что написано: *62.5* или *50 * 1.25*. Оба варианта — выражения, которые надо вычислить. И они вычисляются в одно и то же значение *62.5*. + +Любая строка — выражение. Конкатенация строк — тоже выражение. Когда программа видит выражение, она вычисляет его и **возвращает** результат. + +Вот несколько примеров выражений. В комментариях справа от каждого выражения записано итоговое значение: + +```java +62.5 // 62.5 +50 * 1.25 // 62.5 +120 / 10 * 2 // 24 +"Hexlet" // "Hexlet" +"Good" + "will" // "Goodwill" +``` + +Правила построения кода таковы, что в тех местах, где ожидается выражение, можно поставить любое вычисление. Причем вычисление может быть не только математическое, но и строковое — например, конкатенация. При этом программа останется работоспособной. + +По этой причине невозможно описать и показать все случаи использования всех операций. Программы состоят из множества комбинаций выражений, и понимание этой концепции — один из ключевых шагов на вашем пути. + +Вернемся к нашей валютной программе. Запишем стоимость доллара в рублях, как отдельную переменную. Вычислим цену 50 евро в долларах, умножив их на 1.25. Допустим, что 1 доллар — 60 рублей: + +```java +var rublesPerDollar = 60; +var dollarsCount = 50 * 1.25; // 62.5 +var rublesCount = dollarsCount * rublesPerDollar; // 3750 +System.out.println(rublesCount); // => 3750 +``` + +А теперь давайте добавим к выводу текст с помощью конкатенации: + +```java +var rublesPerDollar = 60; +var dollarsCount = 50 * 1.25; // 62.5 +var rublesCount = dollarsCount * rublesPerDollar; // 3750 +System.out.println("The price is " + rublesCount + " rubles"); +// => The price is 3750 rubles +``` + +https://replit.com/@hexlet/java-basics-variables-3 + +Любая переменная может быть частью любого выражения. В момент вычисления вместо имени переменной подставляется ее значение. Значение `dollarsCount` вычисляется до того, как она начнет использоваться в других выражениях. Когда подходит момент использования переменной, Java знает значение, потому что уже вычислил его. diff --git a/modules/30-variables/15-variable-expressions/ru/data.yml b/modules/30-variables/15-variable-expressions/ru/data.yml new file mode 100644 index 00000000..b3b869ee --- /dev/null +++ b/modules/30-variables/15-variable-expressions/ru/data.yml @@ -0,0 +1,5 @@ +name: Выражения в определениях +tips: + - > + Для перевода строчки можно использовать `\n` между выводом долларов и + рублей, либо нужное количество раз использовать метод `println()`. diff --git a/modules/30-variables/18-variables-concatenation/en/EXERCISE.md b/modules/30-variables/18-variables-concatenation/en/EXERCISE.md new file mode 100644 index 00000000..2baef310 --- /dev/null +++ b/modules/30-variables/18-variables-concatenation/en/EXERCISE.md @@ -0,0 +1,18 @@ + +Sites are constantly sending emails to their users. A typical task is to make an automatic sending of a personal letter, where the user name is in the header. If somewhere in the site base the name of the person is stored as a string, then the task of generating the header is reduced to concatenation: for example, you need to glue the string `Hello` with the string where the name is written. + +Write a program that will generate the header and body of the letter, using the ready-made variables, and display the resulting lines on the screen. + +For the title, use the variables `firstName` and `greeting`, a comma and an exclamation point. Display it in the correct order. + +For the body of the letter, use the variables `info` and `intro`, with the second sentence should be on a new line. + +The result on the screen will look like this: + +``` +Hello, Joffrey! +Here is an important information about your account security. +We couldn't verify you mother's maiden name. +``` + +Perform the job using only two `System.out.print`. diff --git a/modules/30-variables/18-variables-concatenation/en/README.md b/modules/30-variables/18-variables-concatenation/en/README.md new file mode 100644 index 00000000..8a46efac --- /dev/null +++ b/modules/30-variables/18-variables-concatenation/en/README.md @@ -0,0 +1,31 @@ + +To consolidate the previous topic, try using variables with concatenation. Syntactically nothing changes: we can concatenate (glue) two lines: + +```java + +var what = "Kings" + "road"; +System.out.print(what); // => "Kingsroad" +``` + +... which means we can concatenate a string and one variable in which the string is written: + +```java + +var first = "Kings"; +var what = first + "road"; + +System.out.print(what); // => "Kingsroad" +``` + +... and even concatenate two variables in which the lines are written: + +```java + +var first = "Kings"; +var last = "road"; + +var what = first + last; +System.out.print(what); // => "Kingsroad" +``` + +https://replit.com/@hexlet/java-basics-variables-4 diff --git a/modules/30-variables/18-variables-concatenation/en/data.yml b/modules/30-variables/18-variables-concatenation/en/data.yml new file mode 100644 index 00000000..3379bade --- /dev/null +++ b/modules/30-variables/18-variables-concatenation/en/data.yml @@ -0,0 +1,9 @@ +name: Variables and Concatenation +tips: + - > + Consider with which line and in what order you need to glue the + modules.variables together in order to get such a two-line output of the + letter body. + - > + Remember that you can create a string that contains only the control + sequence `\n`. diff --git a/modules/30-variables/18-variables-concatenation/es/EXERCISE.md b/modules/30-variables/18-variables-concatenation/es/EXERCISE.md new file mode 100644 index 00000000..2d4149d1 --- /dev/null +++ b/modules/30-variables/18-variables-concatenation/es/EXERCISE.md @@ -0,0 +1,18 @@ + +Los sitios web constantemente envían correos electrónicos a sus usuarios. Una tarea típica es enviar automáticamente un correo electrónico personalizado, donde el nombre de usuario estará en el asunto. Si el nombre del usuario se almacena en algún lugar de la base de datos del sitio web como una cadena, la tarea de generar el asunto se reduce a la concatenación: por ejemplo, debes concatenar la cadena Hola con la cadena que contiene el nombre. + +Escribe un programa que genere el asunto y el cuerpo del correo electrónico, utilizando las variables ya definidas, y muestre las cadenas resultantes en la pantalla. + +Para el asunto, utiliza las variables nombre y saludo, una coma y un signo de exclamación. Muestra esto en el orden correcto. + +Para el cuerpo del correo electrónico, utiliza las variables informacion e introduccion, con la segunda oración en una nueva línea. + +El resultado en la pantalla debería lucir así: + +
+Hello, Joffrey! +Here is important information about your account security. +We couldn't verify you mother's maiden name. ++ +Completa la tarea utilizando solamente dos System.out.println(). diff --git a/modules/30-variables/18-variables-concatenation/es/README.md b/modules/30-variables/18-variables-concatenation/es/README.md new file mode 100644 index 00000000..0605b374 --- /dev/null +++ b/modules/30-variables/18-variables-concatenation/es/README.md @@ -0,0 +1,25 @@ +Las variables y la concatenación se pueden combinar. Sintácticamente nada cambia, porque sabemos cómo concatenar, es decir, unir dos cadenas: + +```java +var que = "Camino" + "de Reyes"; +System.out.println(que); // => CaminodeReyes +``` + +Esto significa que podemos concatenar una cadena y una variable que contiene una cadena: + +```java +var primero = "Caminos"; +var que = primero + "de Reyes"; +System.out.println(que); // => CaminodeReyes +``` + +Incluso podemos concatenar dos variables que contienen cadenas: + +```java +var primero = "Caminos"; +var ultimo = "de Reyes"; +var que = primero + ultimo; +System.out.println(que); // => CaminodeReyes +``` + +https://replit.com/@hexlet/java-basics-variables-4 diff --git a/modules/30-variables/18-variables-concatenation/es/data.yml b/modules/30-variables/18-variables-concatenation/es/data.yml new file mode 100644 index 00000000..83c4a7e0 --- /dev/null +++ b/modules/30-variables/18-variables-concatenation/es/data.yml @@ -0,0 +1,8 @@ +name: Variables y Concatenación +tips: + - > + Piensa en qué cadena y en qué orden debes concatenar las variables para + obtener una salida de dos líneas para el cuerpo del correo electrónico. + - > + Recuerda que puedes crear una cadena que contenga solo la secuencia de + control '\n'. diff --git a/modules/30-variables/18-variables-concatenation/ru/EXERCISE.md b/modules/30-variables/18-variables-concatenation/ru/EXERCISE.md new file mode 100644 index 00000000..18a6d188 --- /dev/null +++ b/modules/30-variables/18-variables-concatenation/ru/EXERCISE.md @@ -0,0 +1,18 @@ + +Сайты постоянно посылают письма своим пользователям. Типичная задача — сделать автоматическую отправку персонального письма, где в заголовке будет имя пользователя. Если где-то в базе сайта хранится имя человека в виде строки, то задача генерации заголовка сводится к конкатенации: например, нужно склеить строку *Здравствуйте* со строкой, где записано имя. + +Напишите программу, которая будет генерировать заголовок и тело письма, используя уже готовые переменные, и выводить получившиеся строки на экран. + +Для заголовка используйте переменные `firstName` и `greeting`, запятую и восклицательный знак. Выведите это на экран в правильном порядке. + +Для тела письма используйте переменные `info` и `intro`, при этом второе предложение должно быть на новой строке. + +Результат на экране будет выглядеть так: + +
+Hello, Joffrey! +Here is important information about your account security. +We couldn't verify you mother's maiden name. ++ +Выполните задание, используя только два `System.out.println()`. diff --git a/modules/30-variables/18-variables-concatenation/ru/README.md b/modules/30-variables/18-variables-concatenation/ru/README.md new file mode 100644 index 00000000..33bf6ac6 --- /dev/null +++ b/modules/30-variables/18-variables-concatenation/ru/README.md @@ -0,0 +1,25 @@ +Переменные и конкатенацию можно объединять. Синтаксически ничего не меняется, ведь мы умеем конкатенировать — то есть склеивать две строки: + +```java +var what = "Kings" + "road"; +System.out.println(what); // => Kingsroad +``` + +Значит, мы сумеем конкатенировать строку и одну переменную, в которой записана строка: + +```java +var first = "Kings"; +var what = first + "road"; +System.out.println(what); // => Kingsroad +``` + +Можно даже конкатенировать две переменные, в которых записаны строки: + +```java +var first = "Kings"; +var last = "road"; +var what = first + last; +System.out.println(what); //=> Kingsroad +``` + +https://replit.com/@hexlet/java-basics-variables-4 diff --git a/modules/30-variables/18-variables-concatenation/ru/data.yml b/modules/30-variables/18-variables-concatenation/ru/data.yml new file mode 100644 index 00000000..5bfc0b79 --- /dev/null +++ b/modules/30-variables/18-variables-concatenation/ru/data.yml @@ -0,0 +1,8 @@ +name: Переменные и конкатенация +tips: + - > + Подумайте, с какой строкой и в каком порядке нужно склеивать переменные, + чтобы получить такой двухстрочный вывод тела письма. + - > + Помните, что можно создать строку, которая содержит только управляющую + последовательность `\n`. diff --git a/modules/30-variables/19-naming-style/en/EXERCISE.md b/modules/30-variables/19-naming-style/en/EXERCISE.md new file mode 100644 index 00000000..2baef310 --- /dev/null +++ b/modules/30-variables/19-naming-style/en/EXERCISE.md @@ -0,0 +1,18 @@ + +Sites are constantly sending emails to their users. A typical task is to make an automatic sending of a personal letter, where the user name is in the header. If somewhere in the site base the name of the person is stored as a string, then the task of generating the header is reduced to concatenation: for example, you need to glue the string `Hello` with the string where the name is written. + +Write a program that will generate the header and body of the letter, using the ready-made variables, and display the resulting lines on the screen. + +For the title, use the variables `firstName` and `greeting`, a comma and an exclamation point. Display it in the correct order. + +For the body of the letter, use the variables `info` and `intro`, with the second sentence should be on a new line. + +The result on the screen will look like this: + +``` +Hello, Joffrey! +Here is an important information about your account security. +We couldn't verify you mother's maiden name. +``` + +Perform the job using only two `System.out.print`. diff --git a/modules/30-variables/19-naming-style/en/README.md b/modules/30-variables/19-naming-style/en/README.md new file mode 100644 index 00000000..0b343206 --- /dev/null +++ b/modules/30-variables/19-naming-style/en/README.md @@ -0,0 +1,29 @@ + +To consolidate the previous topic, try using variables with concatenation. Syntactically nothing changes: we can concatenate (glue) two lines: + +```java + +var what = "Kings" + "road"; +System.out.print(what); // => "Kingsroad" +``` + +... which means we can concatenate a string and one variable in which the string is written: + +```java + +var first = "Kings"; +var what = first + "road"; + +System.out.print(what); // => "Kingsroad" +``` + +... and even concatenate two variables in which the lines are written: + +```java + +var first = "Kings"; +var last = "road"; + +var what = first + last; +System.out.print(what); // => "Kingsroad" +``` diff --git a/modules/30-variables/19-naming-style/en/data.yml b/modules/30-variables/19-naming-style/en/data.yml new file mode 100644 index 00000000..3379bade --- /dev/null +++ b/modules/30-variables/19-naming-style/en/data.yml @@ -0,0 +1,9 @@ +name: Variables and Concatenation +tips: + - > + Consider with which line and in what order you need to glue the + modules.variables together in order to get such a two-line output of the + letter body. + - > + Remember that you can create a string that contains only the control + sequence `\n`. diff --git a/modules/30-variables/19-naming-style/es/EXERCISE.md b/modules/30-variables/19-naming-style/es/EXERCISE.md new file mode 100644 index 00000000..bdedd500 --- /dev/null +++ b/modules/30-variables/19-naming-style/es/EXERCISE.md @@ -0,0 +1,4 @@ + +Crea dos variables con los nombres "primerNumero" y "segundoNumero" en inglés, utilizando lowerCamelCase. Asigna el número `11` a la primera variable y `-100` a la segunda variable. Imprime en pantalla el producto de los números almacenados en las variables resultantes. + +El código funcionará con cualquier nombre, y nuestro sistema siempre verifica solo el resultado en pantalla, por lo que la ejecución de esta tarea es responsabilidad tuya. diff --git a/modules/30-variables/19-naming-style/es/README.md b/modules/30-variables/19-naming-style/es/README.md new file mode 100644 index 00000000..f7e7aa60 --- /dev/null +++ b/modules/30-variables/19-naming-style/es/README.md @@ -0,0 +1,23 @@ + +`greeting` - es un ejemplo de un nombre simple, pero no todos los nombres son tan simples. Con frecuencia, los nombres de las variables son compuestos, es decir, incluyen varias palabras. Por ejemplo, "nombre de usuario". En diferentes lenguajes de programación se utilizan diferentes convenciones de codificación, por lo que el nombre de la variable puede variar. + +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: + +* kebab-case - las partes compuestas de la variable se separan con guiones (`mi-super-var`) +* snake_case - se utiliza un guion bajo para separar las palabras (`mi_super_var`) +* CamelCase - cada palabra en la variable se escribe con mayúscula inicial (`MiSuperVar`) +* lowerCamelCase - cada palabra en la variable se escribe con mayúscula inicial, excepto la primera (`miSuperVar`) + +En Java 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 escriben con mayúscula inicial: `nombreDeUsuario`. Con tres palabras, se vería así: `miSuperVariable`. + +Veamos cómo se ve esto en el código: + +```java +var primerNombre = "John"; +System.out.println(primerNombre); // => John + +var numeroJugador = 24; +System.out.println(numeroJugador); // => 24 +``` diff --git a/modules/30-variables/19-naming-style/es/data.yml b/modules/30-variables/19-naming-style/es/data.yml new file mode 100644 index 00000000..09a4fcdb --- /dev/null +++ b/modules/30-variables/19-naming-style/es/data.yml @@ -0,0 +1,5 @@ +name: Nomenclatura de variables +tips: [] +definitions: + - name: Convención de codificación + description: Un conjunto de reglas sintácticas y estilísticas para escribir código. diff --git a/modules/30-variables/19-naming-style/ru/EXERCISE.md b/modules/30-variables/19-naming-style/ru/EXERCISE.md new file mode 100644 index 00000000..1ba35405 --- /dev/null +++ b/modules/30-variables/19-naming-style/ru/EXERCISE.md @@ -0,0 +1,4 @@ + +Создайте две переменные с именами «первое число» и «второе число» на английском языке, используя lowerCamelCase. Запишите в первую переменную число `11`, во вторую — `-100`. Выведите на экран произведение чисел, записанных в получившихся переменных. + +Код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. diff --git a/modules/30-variables/19-naming-style/ru/README.md b/modules/30-variables/19-naming-style/ru/README.md new file mode 100644 index 00000000..bd7c3823 --- /dev/null +++ b/modules/30-variables/19-naming-style/ru/README.md @@ -0,0 +1,23 @@ + +`greeting` — пример простого имени, но не все имена так просты. Довольно часто они составные, то есть включают в себя несколько слов. Например, «имя пользователя». В разных языках применяются разные стили кодирования, и имя переменной будет отличаться. + +В именовании переменных можно выделить четыре основных подхода, которые иногда комбинируют друг с другом. Все эти подходы проявляют себя, когда имя переменной состоит из нескольких слов: + +* kebab-case — составные части переменной разделяются дефисом (`my-super-var`) +* snake_case — для разделения используется подчеркивание (`my_super_var`) +* CamelCase — каждое слово в переменной пишется с заглавной буквы (`MySuperVar`) +* lowerCamelCase — каждое слово в переменной пишется с заглавной буквы, кроме первого (`mySuperVar`) + +В Java используется CamelCase и его вариация lowerCamelCase, при котором первая буква первого слова — строчная. + +Именно lowerCamelCase применяется для переменных. Это значит, что имена соединяются друг с другом, при этом все имена кроме первого становятся с заглавной буквы: `userName`. С тремя словами это выглядит так: `mySuperVariable`. + +Посмотрим, как это выглядит в коде: + +```java +var firstName = "John"; +System.out.println(firstName); // => John + +var playerNumber = 24; +System.out.println(playerNumber); // => 24 +``` diff --git a/modules/30-variables/19-naming-style/ru/data.yml b/modules/30-variables/19-naming-style/ru/data.yml new file mode 100644 index 00000000..23918802 --- /dev/null +++ b/modules/30-variables/19-naming-style/ru/data.yml @@ -0,0 +1,5 @@ +name: Именование переменных +tips: [] +definitions: + - name: Стандарт кодирования + description: Набор синтаксических и стилистических правил написания кода. diff --git a/modules/30-variables/20-magic-numbers/en/EXERCISE.md b/modules/30-variables/20-magic-numbers/en/EXERCISE.md new file mode 100644 index 00000000..fd3d6117 --- /dev/null +++ b/modules/30-variables/20-magic-numbers/en/EXERCISE.md @@ -0,0 +1,23 @@ + +You are faced with this code, which displays the total number of rooms in the possession of the current king: + +```java +var king = "King Balon the 6th"; +System.out.print(king + "has" + (6 * 17) + "rooms."); +``` + +As you can see, these are magic numbers: it is not clear what 6 is and what 17. It is possible to guess if you know the history of the royal family: each new king inherits all the castles from their ancestors and builds a new castle - an exact copy of the parent. + +This strange dynasty just breeds the same castles ... + +Get rid of the magic numbers by creating new variables, and then display the text. + +It will turn out like this: + +``` +King Balon the 6th has 102 rooms. +``` + +Variable names should convey the meaning of numbers, but at the same time they should remain sufficiently short and capacious for comfortable reading. + +Remember: the code will work with any names, and our system always checks only the result on the screen, so the execution of this task is under your responsibility. diff --git a/modules/30-variables/20-magic-numbers/en/README.md b/modules/30-variables/20-magic-numbers/en/README.md new file mode 100644 index 00000000..2ab4a1a4 --- /dev/null +++ b/modules/30-variables/20-magic-numbers/en/README.md @@ -0,0 +1,35 @@ + +Recall one of the past lessons: + +```java + +var euros = 1000; +var dollars = euros * 1.25; // => 1250 +var rubles = dollars * 60; // => 75000 + +System.out.print(rubles); +``` + +From the point of view of professional development, this code "smells." This is how code that does not correspond to the so-called best practices is described. And the reason is this: right now, looking at the numbers `60` and `1.25`, you are most likely wondering: "What are these numbers?". And imagine what will happen in a month! And how will a new programmer understand him, who has not seen the code before? In our example, the context is restored due to proper naming, but in real life the code is much more complicated, and therefore it is often impossible to guess the meaning of numbers. + +This “smell” is called magic numbers. Numbers whose origin is impossible to understand without a deep knowledge of what is happening inside this part of the code. + +The way out is simple: it is enough to create variables with the correct names, how everything will fall into place. + +```java + +var dollarsInEuro = 1.25; +var roublesInDollar = 60; + +var euros = 1000; +var dollars = euros * dollarsInEuro; // => 1250 +var rubles = dollars * roublesInDollar; // => 75000 + +System.out.print(rubles); +``` + +Pay attention to the following details: + +* Naming _lowerCamelCase_ +* Two new variables are separated from subsequent calculations by a blank line. These variables make sense without computations, so this separation is appropriate, it improves readability. +* It came out well-named and structured code, but it is longer than the previous version. This is often the case, and this is normal, because the code should be readable. diff --git a/modules/30-variables/20-magic-numbers/en/data.yml b/modules/30-variables/20-magic-numbers/en/data.yml new file mode 100644 index 00000000..469bc192 --- /dev/null +++ b/modules/30-variables/20-magic-numbers/en/data.yml @@ -0,0 +1 @@ +name: Magic Numbers diff --git a/modules/30-variables/20-magic-numbers/es/EXERCISE.md b/modules/30-variables/20-magic-numbers/es/EXERCISE.md new file mode 100644 index 00000000..d9154908 --- /dev/null +++ b/modules/30-variables/20-magic-numbers/es/EXERCISE.md @@ -0,0 +1,22 @@ + +Te has encontrado con un código que muestra en pantalla la cantidad total de habitaciones en posesión del actual rey: + +```java +var rey = "King Balon the 6th"; +System.out.println(rey + " has " + (6 * 17) + " rooms."); +``` + +Como puedes ver, estos son números mágicos: no está claro qué significa el _6_ y qué significa el _17_. Se puede adivinar si se conoce 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 luego muestra el texto en pantalla. + +El resultado será el siguiente: +
+King Balon the 6th has 102 rooms. ++ +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 solo el resultado en 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 new file mode 100644 index 00000000..8c511e9d --- /dev/null +++ b/modules/30-variables/20-magic-numbers/es/README.md @@ -0,0 +1,33 @@ +Recordemos una de las lecciones anteriores: + +```java +// Conversión de euros a rublos a través de dólares +var euros = 1000; +var dólares = euros * 1.25; // 1250 +var rublos = dólares * 60; // 75000 +System.out.println(rublos); // => 75000 +``` + +Desde el punto de vista del desarrollo profesional, este código "huele mal". Así se describe el código que no cumple con las llamadas mejores prácticas (best practices). Y la razón aquí 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 lo que sucederá en un mes! ¿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, por lo que a menudo es imposible adivinar el significado de los números. + +Este efecto es causado por los **números mágicos** (magic numbers) - números cuyo origen es imposible de entender sin un profundo conocimiento de lo que está sucediendo dentro de una sección de código. + +La solución es simple: basta con crear variables con nombres adecuados y todo encajará en su lugar: + +```java +var dólaresEnEuro = 1.25; +var rublosEnDólar = 60; + +var euros = 1000; +var dólares = euros * dólaresEnEuro; // 1250 +var rublos = dólares * rublosEnDólar; // 75000 +System.out.println(rublos); // => 75000 +``` + +Presta atención a los siguientes detalles: + +* Hemos utilizado la nomenclatura *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. +* Hemos obtenido un código bien nombrado y estructurado, pero es más largo que la versión anterior. Esto ocurre a menudo y es normal, porque el código debe ser legible. diff --git a/modules/30-variables/20-magic-numbers/es/data.yml b/modules/30-variables/20-magic-numbers/es/data.yml new file mode 100644 index 00000000..5e2b90a3 --- /dev/null +++ b/modules/30-variables/20-magic-numbers/es/data.yml @@ -0,0 +1 @@ +name: Números mágicos diff --git a/modules/30-variables/20-magic-numbers/ru/EXERCISE.md b/modules/30-variables/20-magic-numbers/ru/EXERCISE.md new file mode 100644 index 00000000..369a38fa --- /dev/null +++ b/modules/30-variables/20-magic-numbers/ru/EXERCISE.md @@ -0,0 +1,22 @@ + +Вы столкнулись с таким кодом, который выводит на экран общее количество комнат во владении нынешнего короля: + +```java +var king = "King Balon the 6th"; +System.out.println(king + " has " + (6 * 17) + " rooms."); +``` + +Как видите, это магические числа: непонятно, что такое _6_ и что такое _17_. Можно догадаться, если знать историю королевской семьи: каждый новый король получает в наследство все замки от предков и строит новый замок — точную копию родительского. + +Эта странная династия просто плодит одинаковые замки… + +Избавьтесь от магических чисел, создав новые переменные, а затем выведите текст на экран. + +Получится так: +
+King Balon the 6th has 102 rooms. ++ +Названия переменных должны передавать смысл чисел, но должны при этом оставаться достаточно короткими и ёмкими для комфортного чтения. + +Помните: код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. diff --git a/modules/30-variables/20-magic-numbers/ru/README.md b/modules/30-variables/20-magic-numbers/ru/README.md new file mode 100644 index 00000000..dd6f928f --- /dev/null +++ b/modules/30-variables/20-magic-numbers/ru/README.md @@ -0,0 +1,33 @@ +Вспомним один из прошлых уроков: + +```java +// Перевод евро в рубли через доллары +var euros = 1000; +var dollars = euros * 1.25; // 1250 +var rubles = dollars * 60; // 75000 +System.out.println(rubles); // => 75000 +``` + +С точки зрения профессиональной разработки, такой код «пахнет». Так описывают код, который не соответствует так называемым лучшим практикам (best practices). И причина здесь вот в чем: уже сейчас, глядя на числа *60* и *1.25*, вы скорее всего задаетесь вопросом: «что это за числа?». + +А представьте, что будет через месяц! А как его поймет новый программист, не видевший код ранее? В нашем примере контекст восстанавливается благодаря грамотному именованию. Но в реальной жизни код значительно сложнее, и поэтому догадаться до смысла чисел зачастую невозможно. + +Этот эффект вызывают **магические числа** (magic numbers) — числа, происхождение которых невозможно понять без глубокого знания происходящего внутри участка кода. + +Выход из ситуации прост: достаточно создать переменные с правильными именами, как все встанет на свои места: + +```java +var dollarsInEuro = 1.25; +var roublesInDollar = 60; + +var euros = 1000; +var dollars = euros * dollarsInEuro; // 1250 +var rubles = dollars * roublesInDollar; // 75000 +System.out.println(rubles); // => 75000 +``` + +Обратите внимание на следующие детали: + +* Мы использовали именование *lowerCamelCase* +* Две новые переменные отделены от последующих вычислений пустой строчкой. Эти переменные имеют смысл и без вычислений, поэтому такое отделение уместно, оно повышает читаемость +* Получился хорошо именованный и структурированный код, но он длиннее прошлой версии. Так часто бывает, и это нормально, потому что код должен быть читабельным diff --git a/modules/30-variables/20-magic-numbers/ru/data.yml b/modules/30-variables/20-magic-numbers/ru/data.yml new file mode 100644 index 00000000..473bb19e --- /dev/null +++ b/modules/30-variables/20-magic-numbers/ru/data.yml @@ -0,0 +1 @@ +name: Магические числа diff --git a/modules/30-variables/23-constants/en/EXERCISE.md b/modules/30-variables/23-constants/en/EXERCISE.md new file mode 100644 index 00000000..671a4e0d --- /dev/null +++ b/modules/30-variables/23-constants/en/EXERCISE.md @@ -0,0 +1,2 @@ + +Create the constant `dragonsBornCount` and write the number 3 in it - the number of dragons born to Dayenerys. diff --git a/modules/30-variables/23-constants/en/README.md b/modules/30-variables/23-constants/en/README.md new file mode 100644 index 00000000..3855cc09 --- /dev/null +++ b/modules/30-variables/23-constants/en/README.md @@ -0,0 +1,13 @@ + +Some data, such as mathematical constants, never changes. Take the number π. Approximately it is always equal to `3.14` and cannot change. + +To access such data in Java, it is customary to use constants. + +```java +final var pi = 3.14; +System.out.print(pi); // 3.14 +``` + +https://replit.com/@hexlet/java-basics-variables-5 + +A constant, like a variable, can be used in any expression. The only restriction is that the constant cannot be changed, which sounds quite logical. diff --git a/modules/30-variables/23-constants/en/data.yml b/modules/30-variables/23-constants/en/data.yml new file mode 100644 index 00000000..0dec2c8d --- /dev/null +++ b/modules/30-variables/23-constants/en/data.yml @@ -0,0 +1 @@ +name: Constants diff --git a/modules/30-variables/23-constants/es/EXERCISE.md b/modules/30-variables/23-constants/es/EXERCISE.md new file mode 100644 index 00000000..647ac745 --- /dev/null +++ b/modules/30-variables/23-constants/es/EXERCISE.md @@ -0,0 +1,2 @@ + +Crea una constante llamada `dragonsBornCount` y asígnale el valor de 3, que es la cantidad de dragones que nacieron de Daenerys. No es necesario mostrar el valor en pantalla. diff --git a/modules/30-variables/23-constants/es/README.md b/modules/30-variables/23-constants/es/README.md new file mode 100644 index 00000000..79b4f44e --- /dev/null +++ b/modules/30-variables/23-constants/es/README.md @@ -0,0 +1,14 @@ +Algunos datos nunca cambian, como las constantes matemáticas. Tomemos el número *π*. Aproximadamente siempre es igual a *3.14* y no puede cambiar. + +En Java, se acostumbra utilizar constantes para acceder a este tipo de datos: + +```java +final var pi = 3.14; +System.out.println(pi); // 3.14 +``` + +https://replit.com/@hexlet/java-basics-variables-5 + +A diferencia de las variables, al definir una constante se utiliza la palabra clave `final`. Esto le indica al compilador que no se puede modificar. Cualquier intento de cambiar una constante resultará en un error. + +Una constante, al igual que una variable, puede ser utilizada en cualquier expresión. La única restricción es que no se puede modificar una constante, lo cual tiene bastante sentido. diff --git a/modules/30-variables/23-constants/es/data.yml b/modules/30-variables/23-constants/es/data.yml new file mode 100644 index 00000000..48ab63f6 --- /dev/null +++ b/modules/30-variables/23-constants/es/data.yml @@ -0,0 +1 @@ +name: Constantes diff --git a/modules/30-variables/23-constants/ru/EXERCISE.md b/modules/30-variables/23-constants/ru/EXERCISE.md new file mode 100644 index 00000000..969a8aa0 --- /dev/null +++ b/modules/30-variables/23-constants/ru/EXERCISE.md @@ -0,0 +1,2 @@ + +Создайте константу `dragonsBornCount` и запишите в неё число 3 — это количество драконов, родившихся у Дайенерис. Выводить значение на экран не требуется. diff --git a/modules/30-variables/23-constants/ru/README.md b/modules/30-variables/23-constants/ru/README.md new file mode 100644 index 00000000..051eed53 --- /dev/null +++ b/modules/30-variables/23-constants/ru/README.md @@ -0,0 +1,14 @@ +Некоторые данные никогда не меняются — например, математические постоянные. Возьмем число *π*. Приближенно оно всегда равно *3.14* и не может измениться. + +Для обращения к подобным данным в Java принято использовать константы: + +```java +final var pi = 3.14; +System.out.println(pi); // 3.14 +``` + +https://replit.com/@hexlet/java-basics-variables-5 + +В отличие от переменных, в начале определения константы используют ключевое слово `final`. Оно сообщает компилятору запрет на изменение. Любая попытка поменять константу приведет к ошибке. + +Константа, как и переменная, может использоваться в любом выражении. Единственное ограничение — константу нельзя изменить, что звучит довольно логично. diff --git a/modules/30-variables/23-constants/ru/data.yml b/modules/30-variables/23-constants/ru/data.yml new file mode 100644 index 00000000..071babae --- /dev/null +++ b/modules/30-variables/23-constants/ru/data.yml @@ -0,0 +1 @@ +name: Константы diff --git a/modules/33-data-types/41-data-types-basics/en/EXERCISE.md b/modules/33-data-types/41-data-types-basics/en/EXERCISE.md new file mode 100644 index 00000000..a4eaba0e --- /dev/null +++ b/modules/33-data-types/41-data-types-basics/en/EXERCISE.md @@ -0,0 +1 @@ +Display the number `-0.304`. diff --git a/modules/33-data-types/41-data-types-basics/en/README.md b/modules/33-data-types/41-data-types-basics/en/README.md new file mode 100644 index 00000000..32b8c7a8 --- /dev/null +++ b/modules/33-data-types/41-data-types-basics/en/README.md @@ -0,0 +1,62 @@ + +Data types in Java are divided into two important groups according to how variables of this type are related and the values stored in them. + +What will the following code output? + +```java +var a = 10; +var b = a; +a = 20; +System.out.print(b); +``` + +10 will be output, because with the assignment b = a, the number 10, which at this moment is contained in a, will be written into the variable b. + +If you write + +```java +var a = "string"; +var b = a; +``` + +- then the situation will be different. + +#### Briefly + +Primitive data types in Java: + +- Strings in quotes +- The numbers `7`,` -198`, `0` and so on + +In fact, there are more, but now let's talk only about them. +--- + +There are different ways to present data in programs. + +There are **strings** - character sets in quotes like `"Hello, World!"`. There are **integers** - for example, `7`, `-198`, `0`. These are two different categories of information - two different **data types**. + +The multiplication operation makes sense for integers but it does not make sense for strings: to multiply the word "mother" by the word "notepad" is nonsense. + +**The data type determines what can be done with the elements of a specific set of information.** + +A programming language recognizes types. Therefore, Java will not allow us to multiply a line by line (“multiply text by text”). But it will allow to multiply an integer by another integer. The presence of types and such restrictions in the language protects programs from random errors. + +Unlike strings, numbers do not need to be wrapped in quotes. To print the number 5, just write: + +```java +System.out.print(5); +``` + +Note that the number `5` and the string `"5"` are completely different things, although the output of `println` for this data is identical. + +Integers (`1`, `34`, `-19`, etc.) and rational numbers (`1.3`, `1.0`, `-14.324`, etc.) are two separate **types data**. This separation is associated with the characteristics of the device computers. **There are other types**, we will get to know them later. + +Here is another example, but with a rational number: + +```java +System.out.print(10.234); +``` + +The lines in programming are called "strings", and the lines of text files are called "lines". For example, the code above has one line (lines), and there are no lines (strings). In all the lessons we will say **string** to indicate the data type "string", and **line** to indicate lines (lines) in files). + +Programmers themselves can create new data types, albeit with certain restrictions. diff --git a/modules/33-data-types/41-data-types-basics/en/data.yml b/modules/33-data-types/41-data-types-basics/en/data.yml new file mode 100644 index 00000000..fdeaf66b --- /dev/null +++ b/modules/33-data-types/41-data-types-basics/en/data.yml @@ -0,0 +1,4 @@ +name: Data Types +tips: + - | + [Article on fractional numbers](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/41-data-types-basics/es/EXERCISE.md b/modules/33-data-types/41-data-types-basics/es/EXERCISE.md new file mode 100644 index 00000000..648b623b --- /dev/null +++ b/modules/33-data-types/41-data-types-basics/es/EXERCISE.md @@ -0,0 +1 @@ +Muestra en pantalla el resultado de dividir los números enteros 3 entre 2. ¿Por qué se obtuvo ese resultado? diff --git a/modules/33-data-types/41-data-types-basics/es/README.md b/modules/33-data-types/41-data-types-basics/es/README.md new file mode 100644 index 00000000..dd7119f2 --- /dev/null +++ b/modules/33-data-types/41-data-types-basics/es/README.md @@ -0,0 +1,32 @@ +Dentro de los lenguajes de programación de alto nivel, los datos se dividen en tipos. Por ejemplo, las cadenas de texto se clasifican como *String*, mientras que los números se clasifican como *int*. + +¿Para qué sirven los tipos de datos? Para proteger el programa de errores difíciles de detectar. Los tipos de datos determinan dos cosas: + +* Valores permitidos. Por ejemplo, en Java, los números se dividen en dos grupos de tipos: enteros (*int*) y racionales (*float*). Esta división está relacionada con las características técnicas del hardware. +* Conjunto de operaciones permitidas. Por ejemplo, la operación de multiplicación tiene sentido para el tipo "números enteros". Pero no tiene sentido para el tipo "cadena de texto": multiplicar la palabra "mamá" por la palabra "cuaderno" no tiene sentido. + +El lenguaje de programación reconoce los tipos. Por lo tanto, Java no nos permitirá multiplicar una cadena de texto por otra cadena de texto. Pero sí nos permitirá multiplicar un número entero por otro número entero. La presencia de tipos y de tales restricciones en el lenguaje protege los programas de errores accidentales: + +``` +"uno" * "dos" +Error: +tipos de operandos incorrectos para el operador binario '*' + primer tipo: java.lang.String + segundo tipo: java.lang.String +``` + +¿Cómo sabe Java qué tipo de datos tiene delante? Cada valor se inicializa en algún lugar. Dependiendo de la forma de inicialización, se entiende qué es exactamente lo que tenemos delante. + +Por ejemplo, un número es simplemente un número, no está envuelto entre comillas u otros caracteres emparejados. Pero las cadenas de texto siempre están delimitadas por comillas dobles. Por ejemplo, el valor `"234"` se considera una cadena de texto, aunque dentro de ella se escriban números: + +```java +// El compilador entiende que aquí hay un número +var edad = 33; +``` + +En inglés, las cadenas de texto en programación se llaman *strings*, mientras que las líneas de los archivos de texto se llaman *lines*. Por ejemplo, en el código anterior hay una línea (*line*) y cero cadenas (*strings*). En el idioma ruso, a veces puede haber confusión, por lo tanto, en todas las lecciones utilizaremos los siguientes términos: + +* **Cadena de texto** - para denotar el tipo de datos *strings* +* **Línea** - para denotar *lines* (líneas en archivos de texto) + +Hay muchos tipos de datos en Java, y también se pueden crear tipos personalizados. Gradualmente nos familiarizaremos con todos los necesarios y aprenderemos a usarlos correctamente. diff --git a/modules/33-data-types/41-data-types-basics/es/data.yml b/modules/33-data-types/41-data-types-basics/es/data.yml new file mode 100644 index 00000000..e1d33a44 --- /dev/null +++ b/modules/33-data-types/41-data-types-basics/es/data.yml @@ -0,0 +1,4 @@ +name: ¿Para qué sirven los tipos de datos? +tips: + - | + [Artículo sobre números decimales](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/41-data-types-basics/ru/EXERCISE.md b/modules/33-data-types/41-data-types-basics/ru/EXERCISE.md new file mode 100644 index 00000000..7943c26c --- /dev/null +++ b/modules/33-data-types/41-data-types-basics/ru/EXERCISE.md @@ -0,0 +1 @@ +Выведите на экран результат деления целых чисел 3 на 2. Подумайте почему получился такой ответ? diff --git a/modules/33-data-types/41-data-types-basics/ru/README.md b/modules/33-data-types/41-data-types-basics/ru/README.md new file mode 100644 index 00000000..d1cdfdd6 --- /dev/null +++ b/modules/33-data-types/41-data-types-basics/ru/README.md @@ -0,0 +1,32 @@ +Внутри высокоуровневых языков программирования данные разделяются по типам. Например, строки относятся к типу *String*, а числа — к типу *int*. + +Зачем нужны типы? Для защиты программы от трудноотловимых ошибок. Типы определяют две вещи: + +* Допустимые значения. Например, числа в Java делятся на две группы типов: целые *int* и рациональные *float*. Такое разделение связано с техническими особенностями работы аппаратуры. +* Набор допустимых операций. Например, операция умножения имеет смысл для типа «целые числа». Но не имеет смысла для типа «строки»: умножать слово «мама» на слово «блокнот» — бессмыслица. + +Язык программирования распознает типы. Поэтому Java не позволит нам умножать строку на строку. Но позволит умножать целое число на другое целое число. Наличие типов и таких ограничений в языке защищает программы от случайных ошибок: + +``` +"one" * "two" +Error: +bad operand types for binary operator '*' + first type: java.lang.String + second type: java.lang.String +``` + +Каким образом Java понимает, что за тип данных перед ним? Любое значение где-то инициализируется. В зависимости от способа инициализации, становится понятно, что именно находится перед нами. + +Например, число — это просто число, не обернутое в кавычки или другие парные символы. А вот строки всегда ограничены двойными кавычками. Например, значение `"234"`считается строкой, хотя внутри нее записаны цифры: + +```java +// Компилятор понимает что тут число +var age = 33; +``` + +По-английски строки в программировании называются *strings*, а строчки текстовых файлов называются *lines*. Например, в коде выше одна строчка (*lines*) и ноль строк (*strings*). В русском языке иногда может быть путаница, поэтому во всех уроках мы будем использовать такие термины: + +* **Строка** — для обозначения типа данных *strings* +* **Строчка** — для обозначения *lines* (строчек в текстовых файлах) + +Типов данных в Java много, плюс можно создавать свои. Постепенно мы познакомимся со всеми необходимыми и научимся их правильно использовать. diff --git a/modules/33-data-types/41-data-types-basics/ru/data.yml b/modules/33-data-types/41-data-types-basics/ru/data.yml new file mode 100644 index 00000000..fcd0294f --- /dev/null +++ b/modules/33-data-types/41-data-types-basics/ru/data.yml @@ -0,0 +1,4 @@ +name: Зачем нужны типы данных +tips: + - | + [Статья о дробных числах](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/45-explicit-types/en/EXERCISE.md b/modules/33-data-types/45-explicit-types/en/EXERCISE.md new file mode 100644 index 00000000..a4eaba0e --- /dev/null +++ b/modules/33-data-types/45-explicit-types/en/EXERCISE.md @@ -0,0 +1 @@ +Display the number `-0.304`. diff --git a/modules/33-data-types/45-explicit-types/en/README.md b/modules/33-data-types/45-explicit-types/en/README.md new file mode 100644 index 00000000..32b8c7a8 --- /dev/null +++ b/modules/33-data-types/45-explicit-types/en/README.md @@ -0,0 +1,62 @@ + +Data types in Java are divided into two important groups according to how variables of this type are related and the values stored in them. + +What will the following code output? + +```java +var a = 10; +var b = a; +a = 20; +System.out.print(b); +``` + +10 will be output, because with the assignment b = a, the number 10, which at this moment is contained in a, will be written into the variable b. + +If you write + +```java +var a = "string"; +var b = a; +``` + +- then the situation will be different. + +#### Briefly + +Primitive data types in Java: + +- Strings in quotes +- The numbers `7`,` -198`, `0` and so on + +In fact, there are more, but now let's talk only about them. +--- + +There are different ways to present data in programs. + +There are **strings** - character sets in quotes like `"Hello, World!"`. There are **integers** - for example, `7`, `-198`, `0`. These are two different categories of information - two different **data types**. + +The multiplication operation makes sense for integers but it does not make sense for strings: to multiply the word "mother" by the word "notepad" is nonsense. + +**The data type determines what can be done with the elements of a specific set of information.** + +A programming language recognizes types. Therefore, Java will not allow us to multiply a line by line (“multiply text by text”). But it will allow to multiply an integer by another integer. The presence of types and such restrictions in the language protects programs from random errors. + +Unlike strings, numbers do not need to be wrapped in quotes. To print the number 5, just write: + +```java +System.out.print(5); +``` + +Note that the number `5` and the string `"5"` are completely different things, although the output of `println` for this data is identical. + +Integers (`1`, `34`, `-19`, etc.) and rational numbers (`1.3`, `1.0`, `-14.324`, etc.) are two separate **types data**. This separation is associated with the characteristics of the device computers. **There are other types**, we will get to know them later. + +Here is another example, but with a rational number: + +```java +System.out.print(10.234); +``` + +The lines in programming are called "strings", and the lines of text files are called "lines". For example, the code above has one line (lines), and there are no lines (strings). In all the lessons we will say **string** to indicate the data type "string", and **line** to indicate lines (lines) in files). + +Programmers themselves can create new data types, albeit with certain restrictions. diff --git a/modules/33-data-types/45-explicit-types/en/data.yml b/modules/33-data-types/45-explicit-types/en/data.yml new file mode 100644 index 00000000..fdeaf66b --- /dev/null +++ b/modules/33-data-types/45-explicit-types/en/data.yml @@ -0,0 +1,4 @@ +name: Data Types +tips: + - | + [Article on fractional numbers](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/45-explicit-types/es/EXERCISE.md b/modules/33-data-types/45-explicit-types/es/EXERCISE.md new file mode 100644 index 00000000..1756b090 --- /dev/null +++ b/modules/33-data-types/45-explicit-types/es/EXERCISE.md @@ -0,0 +1 @@ +Crea una cadena de texto *One more time* con una especificación explícita de tipo y muéstrala en pantalla. diff --git a/modules/33-data-types/45-explicit-types/es/README.md b/modules/33-data-types/45-explicit-types/es/README.md new file mode 100644 index 00000000..59552b14 --- /dev/null +++ b/modules/33-data-types/45-explicit-types/es/README.md @@ -0,0 +1,17 @@ +Hasta ahora, al definir variables, hemos utilizado la palabra clave `var`, lo cual puede sorprender a aquellos que tienen experiencia en Java. Normalmente, la definición de variables se muestra así: + +```java +int x = 3; +String greeting = "¡Hola Hexlet!"; + +// Error: tipos incompatibles: java.lang.String no se puede convertir a int +int ops = "test"; +``` + +¡Es hora de revelar la verdad! Java es un lenguaje de programación de tipado estático. En estos lenguajes, el tipo de una variable se establece al momento de su declaración. En la mayoría de los lenguajes, se especifica el tipo de la variable antes de su nombre, como en el ejemplo anterior, donde se utiliza el tipo entero (int) y el tipo cadena (String). + +Antes en Java, las variables solo se creaban de esta manera, hasta que apareció `var`. La palabra clave `var` es una característica especial que habilita la **inferencia de tipos**. La inferencia de tipos determina automáticamente el tipo del valor asignado y lo vincula a la variable. En los ejemplos anteriores, es obvio qué tipo corresponde a cada variable, entonces, ¿por qué especificarlo explícitamente? + +La inferencia de tipos en Java se introdujo en 2018, pero en otros lenguajes ha existido durante décadas. El primer lenguaje con inferencia de tipos se llama ML y se creó en 1973. Desde entonces, la inferencia de tipos se ha agregado a Ocaml, Haskell, C#, F#, Kotlin, Scala y muchos otros lenguajes. + +La inferencia de tipos es preferible en la mayoría de las situaciones, sin embargo, a veces no estamos satisfechos con el tipo inferido. En ese caso, podemos especificar el tipo explícitamente. Obtendrás más información al respecto en la próxima lección. diff --git a/modules/33-data-types/45-explicit-types/es/data.yml b/modules/33-data-types/45-explicit-types/es/data.yml new file mode 100644 index 00000000..919d690a --- /dev/null +++ b/modules/33-data-types/45-explicit-types/es/data.yml @@ -0,0 +1,4 @@ +name: Tipado explícito +tips: + - | + [Artículo sobre números decimales](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/45-explicit-types/ru/EXERCISE.md b/modules/33-data-types/45-explicit-types/ru/EXERCISE.md new file mode 100644 index 00000000..e1bacff9 --- /dev/null +++ b/modules/33-data-types/45-explicit-types/ru/EXERCISE.md @@ -0,0 +1 @@ +Создайте строку *One more time* с явным указанием типа и выведите ее на экран diff --git a/modules/33-data-types/45-explicit-types/ru/README.md b/modules/33-data-types/45-explicit-types/ru/README.md new file mode 100644 index 00000000..7239b97a --- /dev/null +++ b/modules/33-data-types/45-explicit-types/ru/README.md @@ -0,0 +1,17 @@ +До сих пор при определении переменных мы использовали ключевое слово `var`, что может удивить тех, кто имеет какой-то опыт на Java. Обычно определение переменных показывают так: + +```java +int x = 3; +String greeting = "Hello Hexlet!"; + +// Error: incompatible types: java.lang.String cannot be converted to int +int ops = "test"; +``` + +Пришло время раскрыть карты! Java — это статически типизированный язык. В таких языках тип переменной фиксируется при ее объявлении. В большинстве языков для этого перед именем переменной указывается ее тип — в примере выше это число (int) и строка (String). + +Раньше на Java создавали переменные только так, до тех пор пока не появился `var`. Слово `var` – специальное ключевое слово, которое включает механизм **вывода типов**. Вывод типов автоматически определяет тип присваиваемого значения и связывает его с переменной. В примерах выше очевидно, где какой тип, тогда зачем его явно прописывать? + +Вывод типов в Java появился в 2018 году, но в некоторых других язык он существует не один десяток лет. Первый язык с выводом типов называется ML и появился он аж в 1973 году. С тех пор вывод типов был добавлен в Ocaml, Haskell, C#, F#, Kotlin, Scala и множество других языков. + +Вывод типов и предпочтителен в большинстве ситуаций, однако бывает такое, что выводимый тип нас не устраивает. Тогда мы можем указать тип явно. Подробнее об этом в следующем уроке. diff --git a/modules/33-data-types/45-explicit-types/ru/data.yml b/modules/33-data-types/45-explicit-types/ru/data.yml new file mode 100644 index 00000000..08bb475a --- /dev/null +++ b/modules/33-data-types/45-explicit-types/ru/data.yml @@ -0,0 +1,4 @@ +name: Явная типизация +tips: + - | + [Статья о дробных числах](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/47-data-types-list/en/EXERCISE.md b/modules/33-data-types/47-data-types-list/en/EXERCISE.md new file mode 100644 index 00000000..a4eaba0e --- /dev/null +++ b/modules/33-data-types/47-data-types-list/en/EXERCISE.md @@ -0,0 +1 @@ +Display the number `-0.304`. diff --git a/modules/33-data-types/47-data-types-list/en/README.md b/modules/33-data-types/47-data-types-list/en/README.md new file mode 100644 index 00000000..32b8c7a8 --- /dev/null +++ b/modules/33-data-types/47-data-types-list/en/README.md @@ -0,0 +1,62 @@ + +Data types in Java are divided into two important groups according to how variables of this type are related and the values stored in them. + +What will the following code output? + +```java +var a = 10; +var b = a; +a = 20; +System.out.print(b); +``` + +10 will be output, because with the assignment b = a, the number 10, which at this moment is contained in a, will be written into the variable b. + +If you write + +```java +var a = "string"; +var b = a; +``` + +- then the situation will be different. + +#### Briefly + +Primitive data types in Java: + +- Strings in quotes +- The numbers `7`,` -198`, `0` and so on + +In fact, there are more, but now let's talk only about them. +--- + +There are different ways to present data in programs. + +There are **strings** - character sets in quotes like `"Hello, World!"`. There are **integers** - for example, `7`, `-198`, `0`. These are two different categories of information - two different **data types**. + +The multiplication operation makes sense for integers but it does not make sense for strings: to multiply the word "mother" by the word "notepad" is nonsense. + +**The data type determines what can be done with the elements of a specific set of information.** + +A programming language recognizes types. Therefore, Java will not allow us to multiply a line by line (“multiply text by text”). But it will allow to multiply an integer by another integer. The presence of types and such restrictions in the language protects programs from random errors. + +Unlike strings, numbers do not need to be wrapped in quotes. To print the number 5, just write: + +```java +System.out.print(5); +``` + +Note that the number `5` and the string `"5"` are completely different things, although the output of `println` for this data is identical. + +Integers (`1`, `34`, `-19`, etc.) and rational numbers (`1.3`, `1.0`, `-14.324`, etc.) are two separate **types data**. This separation is associated with the characteristics of the device computers. **There are other types**, we will get to know them later. + +Here is another example, but with a rational number: + +```java +System.out.print(10.234); +``` + +The lines in programming are called "strings", and the lines of text files are called "lines". For example, the code above has one line (lines), and there are no lines (strings). In all the lessons we will say **string** to indicate the data type "string", and **line** to indicate lines (lines) in files). + +Programmers themselves can create new data types, albeit with certain restrictions. diff --git a/modules/33-data-types/47-data-types-list/en/data.yml b/modules/33-data-types/47-data-types-list/en/data.yml new file mode 100644 index 00000000..fdeaf66b --- /dev/null +++ b/modules/33-data-types/47-data-types-list/en/data.yml @@ -0,0 +1,4 @@ +name: Data Types +tips: + - | + [Article on fractional numbers](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/47-data-types-list/es/EXERCISE.md b/modules/33-data-types/47-data-types-list/es/EXERCISE.md new file mode 100644 index 00000000..6635a1bf --- /dev/null +++ b/modules/33-data-types/47-data-types-list/es/EXERCISE.md @@ -0,0 +1 @@ +Muestra en la pantalla el resultado de concatenar la palabra *hexlet*, el carácter *-* y el número 7. diff --git a/modules/33-data-types/47-data-types-list/es/README.md b/modules/33-data-types/47-data-types-list/es/README.md new file mode 100644 index 00000000..c4c2ab28 --- /dev/null +++ b/modules/33-data-types/47-data-types-list/es/README.md @@ -0,0 +1,70 @@ +En esta lección, vamos a examinar el sistema de tipos en Java desde una perspectiva general, sin entrar en detalles. Pero primero, respondamos a la pregunta de por qué es importante conocerlos. + +En el código, siempre estamos trabajando con datos. Estos datos tienen diferentes naturalezas y pueden estar organizados de diferentes maneras, lo que afecta la facilidad de trabajar con ellos. Los tipos nos persiguen en cada paso, por lo que sin ellos, la programación en Java solo es posible a un nivel muy básico. + +Por otro lado, no intentes memorizar toda esta información sobre los tipos de memoria: se proporciona solo para tener una idea general. Todo lo importante sobre los tipos lo aprenderás durante el proceso de programación. En Java, los tipos de datos se dividen en dos grandes grupos: + +* **Primitivos** - predefinidos en Java +* **Referenciales** o **no primitivos** - creados por el programador, excepto *String* y *Array* + +Estos grupos tienen diferencias que discutiremos más adelante, cuando nos familiaricemos con `null` y la programación orientada a objetos. Por ahora, es suficiente saber que los nombres de los tipos primitivos comienzan con minúscula (`int`), mientras que los nombres de los tipos referenciales comienzan con mayúscula (`String`). + +En total, Java tiene ocho tipos primitivos de datos: + +* *byte* +* *short* +* *int* +* *long* +* *float* +* *double* +* *boolean* +* *char* + +Veamos los primeros cuatro tipos. Estos son números enteros de diferentes tamaños: + +* *byte* - ocupa 1 byte en memoria, por lo que puede almacenar números del -128 al 127 +* *short* - ocupa 2 bytes en memoria +* *int* - ocupa 4 bytes en memoria +* *long* - ocupa 8 bytes en memoria + +Veamos un ejemplo de código: + +```java +byte x = 3; // Funcionará sin problemas + +// Error: tipos incompatibles: posible conversión de int a byte con pérdida de información +byte y = 270; +``` + +La declaración de la variable `y` termina con un error porque hemos especificado el tipo *byte*, pero le hemos asignado el valor *270*, que está fuera del rango de valores permitidos. + +Surge una pregunta lógica. ¿Por qué necesitamos cuatro tipos para almacenar números? ¿Por qué no tener uno que pueda contener casi cualquier número grande? + +Técnicamente, esto es posible, pero estamos en el mundo de las soluciones de ingeniería. Cualquier solución siempre tiene un lado negativo, por lo que no se puede hacer perfectamente: tendrás que sacrificar algo. En este caso, el tamaño de la memoria ocupada. Si solo dejamos *long*, un programa que opera activamente con números comenzará a ocupar demasiado espacio en la memoria RAM, lo cual puede ser crítico. + +La misma lógica se aplica a los tipos *float* y *double*. Ambos representan números racionales. La diferencia es que *double* es el doble de *float*, es decir, ocupa el doble de espacio en memoria. + +Los creadores de Java confían en la sensatez de los programadores, en su capacidad para elegir los tipos adecuados según la tarea. Para algunas aplicaciones extremas, esto es cierto, pero en el desarrollo típico, es simple. Los programadores eligen *int* para números enteros y *double* para números racionales. + +Veamos los tipos de datos restantes. + +El tipo *boolean* representa los valores lógicos `true` y `false`. Le dedicaremos una sección completa más adelante, donde hablaremos de él. + +El tipo *char* es especial: representa un carácter. No es una cadena, se define de manera diferente, con comillas simples: + +```java +char ch = 'a'; + +// Error: tipos incompatibles: no se puede convertir java.lang.String a char +char ch2 = "b"; +``` + +Una cadena que consta de un solo carácter no es un carácter. Parece ilógico, pero desde el punto de vista de los tipos, debe ser así, y con el tiempo lo entenderás. + +Extraer un carácter de una cadena extrae un carácter, no una cadena que consta de un solo carácter: + +```java +"hexlet".charAt(1); // 'e' +``` + +Bien, ¿y dónde está el tipo de datos *String* - cadena? El caso es que no es un tipo primitivo. Internamente, es un conjunto de caracteres. A pesar de esta diferencia técnica, las cadenas se utilizan junto con los tipos primitivos sin ninguna diferencia especial. diff --git a/modules/33-data-types/47-data-types-list/es/data.yml b/modules/33-data-types/47-data-types-list/es/data.yml new file mode 100644 index 00000000..29238e59 --- /dev/null +++ b/modules/33-data-types/47-data-types-list/es/data.yml @@ -0,0 +1,6 @@ +name: Tipos de datos +tips: + - | + Intenta jugar con la concatenación de cadenas y caracteres en jshell. + - | + [Artículo sobre números decimales](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/47-data-types-list/ru/EXERCISE.md b/modules/33-data-types/47-data-types-list/ru/EXERCISE.md new file mode 100644 index 00000000..0756315c --- /dev/null +++ b/modules/33-data-types/47-data-types-list/ru/EXERCISE.md @@ -0,0 +1 @@ +Выведите на экран результат конкатенации слова *hexlet*, символа *-* и числа 7 diff --git a/modules/33-data-types/47-data-types-list/ru/README.md b/modules/33-data-types/47-data-types-list/ru/README.md new file mode 100644 index 00000000..155dcb4a --- /dev/null +++ b/modules/33-data-types/47-data-types-list/ru/README.md @@ -0,0 +1,70 @@ +В этом уроке мы рассмотрим систему типов в Java с высоты птичьего полета, не погружаясь в детали. Но сначала ответим на вопрос, зачем вообще про них знать? + +В коде мы все время оперируем данными. Эти данные имеют разную природу, могут быть по-разному организованы, что влияет на удобство работы с ними. Типы преследуют нас на каждом шагу, поэтому без них программирование на Java возможно только на очень базовом уровне. + +С другой стороны, не пытайтесь запомнить всю эту информацию про типы наизусть — она дается лишь для общего представления. Все важное о типах вы и так выучите в процессе программирования. Глобально, типы данных в Java делятся на две большие группы: + +* **Примитивные** — предопределены в Java +* **Ссылочные** или **не примитивные** — создаются самим программистом, за исключением *String* и *Array* + +У этих групп есть различия, которые мы разберем позже, когда познакомимся с `null` и объектно-ориентированным программированием. Пока достаточно знать, что имена примитивных типов начинаются с нижнего регистра (`int`), а ссылочных с верхнего (`String`). + +Всего в Java восемь примитивных типов данных: + +* *byte* +* *short* +* *int* +* *long* +* *float* +* *double* +* *boolean* +* *char* + +Рассмотрим первые четыре типа. Это целые числа разного размера: + +* *byte* — занимает в памяти 1 байт, значит может хранить числа от -128 до 127 +* *short* — занимает в памяти 2 байта +* *int* — занимает в памяти 4 байта +* *long* — занимает в памяти 8 байт + +Посмотрим на примере такого кода: + +```java +byte x = 3; // Отработает без проблем + +// Error: incompatible types: possible lossy conversion from int to byte +byte y = 270; +``` + +Определение переменной `y` завершилось с ошибкой, потому что мы указали тип *byte*, но присвоили переменной значение *270*, которое выходит за множество допустимых значений. + +Возникает закономерный вопрос. Зачем аж четыре типа для хранения чисел? Почему бы не сделать один, в который влезает почти любое большое число? + +Технически так сделать можно, но мы находимся в мире инженерных решений. У любого решения всегда есть обратная сторона, поэтому невозможно сделать идеально — придется чем-то пожертвовать. В данном случае, объемом занимаемой памяти. Если оставить только *long*, то программа, активно оперирующая числами, начнет занимать слишком много места в оперативной памяти, что может быть критично. + +Такая же логика использовалась для типов *float* и *double*. Они оба отвечают за рациональные числа. Разница лишь в том, что *double* — это двойной *float*, то есть в памяти он занимает в два раза больше места. + +Создатели Java полагаются на разумность программистов, на их способность правильно подобрать нужные типы в зависимости от задачи. Для каких-то экстремальных приложений так и происходит, но в типичной разработке все просто. Программисты выбирают *int* для целых чисел и *double* для рациональных. + +Рассмотрим оставшиеся типы данных. + +Тип *boolean* отвечает за логические значения `true` и `false`. Им посвящен целый раздел, там мы про него и поговорим. + +Особняком стоит тип *char* — символ. Это не строка, у него другой способ определения — через одиночные кавычки: + +```java +char ch = 'a'; + +// Error: incompatible types: java.lang.String cannot be converted to char +char ch2 = "b"; +``` + +Строка, состоящая из одного символа — это не символ. Кажется, нелогично, но с точки зрения типов все так и должно быть, со временем вы это прочувствуете. + +Извлечение символа из строки извлекает как раз символ, а не строку, состоящую из одного символа: + +```java +"hexlet".charAt(1); // 'e' +``` + +Хорошо, а где тип данных *String* — строка? Дело в том, что она не является примитивным типом. Внутри она представляет собой массив символов. Несмотря на это техническое различие, строки используются наравне с примитивными типами без особых отличий. diff --git a/modules/33-data-types/47-data-types-list/ru/data.yml b/modules/33-data-types/47-data-types-list/ru/data.yml new file mode 100644 index 00000000..9aaf1160 --- /dev/null +++ b/modules/33-data-types/47-data-types-list/ru/data.yml @@ -0,0 +1,6 @@ +name: Какие бывают типы +tips: + - | + Попробуйте поиграть с конкатенированием строк и символов в jshell + - | + [Статья о дробных числах](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/50-null/en/EXERCISE.md b/modules/33-data-types/50-null/en/EXERCISE.md new file mode 100644 index 00000000..a4eaba0e --- /dev/null +++ b/modules/33-data-types/50-null/en/EXERCISE.md @@ -0,0 +1 @@ +Display the number `-0.304`. diff --git a/modules/33-data-types/50-null/en/README.md b/modules/33-data-types/50-null/en/README.md new file mode 100644 index 00000000..32b8c7a8 --- /dev/null +++ b/modules/33-data-types/50-null/en/README.md @@ -0,0 +1,62 @@ + +Data types in Java are divided into two important groups according to how variables of this type are related and the values stored in them. + +What will the following code output? + +```java +var a = 10; +var b = a; +a = 20; +System.out.print(b); +``` + +10 will be output, because with the assignment b = a, the number 10, which at this moment is contained in a, will be written into the variable b. + +If you write + +```java +var a = "string"; +var b = a; +``` + +- then the situation will be different. + +#### Briefly + +Primitive data types in Java: + +- Strings in quotes +- The numbers `7`,` -198`, `0` and so on + +In fact, there are more, but now let's talk only about them. +--- + +There are different ways to present data in programs. + +There are **strings** - character sets in quotes like `"Hello, World!"`. There are **integers** - for example, `7`, `-198`, `0`. These are two different categories of information - two different **data types**. + +The multiplication operation makes sense for integers but it does not make sense for strings: to multiply the word "mother" by the word "notepad" is nonsense. + +**The data type determines what can be done with the elements of a specific set of information.** + +A programming language recognizes types. Therefore, Java will not allow us to multiply a line by line (“multiply text by text”). But it will allow to multiply an integer by another integer. The presence of types and such restrictions in the language protects programs from random errors. + +Unlike strings, numbers do not need to be wrapped in quotes. To print the number 5, just write: + +```java +System.out.print(5); +``` + +Note that the number `5` and the string `"5"` are completely different things, although the output of `println` for this data is identical. + +Integers (`1`, `34`, `-19`, etc.) and rational numbers (`1.3`, `1.0`, `-14.324`, etc.) are two separate **types data**. This separation is associated with the characteristics of the device computers. **There are other types**, we will get to know them later. + +Here is another example, but with a rational number: + +```java +System.out.print(10.234); +``` + +The lines in programming are called "strings", and the lines of text files are called "lines". For example, the code above has one line (lines), and there are no lines (strings). In all the lessons we will say **string** to indicate the data type "string", and **line** to indicate lines (lines) in files). + +Programmers themselves can create new data types, albeit with certain restrictions. diff --git a/modules/33-data-types/50-null/en/data.yml b/modules/33-data-types/50-null/en/data.yml new file mode 100644 index 00000000..fdeaf66b --- /dev/null +++ b/modules/33-data-types/50-null/en/data.yml @@ -0,0 +1,4 @@ +name: Data Types +tips: + - | + [Article on fractional numbers](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/50-null/es/EXERCISE.md b/modules/33-data-types/50-null/es/EXERCISE.md new file mode 100644 index 00000000..09423a4c --- /dev/null +++ b/modules/33-data-types/50-null/es/EXERCISE.md @@ -0,0 +1,2 @@ + +Declara una variable llamada `greeting`, pero no la inicialices. diff --git a/modules/33-data-types/50-null/es/README.md b/modules/33-data-types/50-null/es/README.md new file mode 100644 index 00000000..69657aa6 --- /dev/null +++ b/modules/33-data-types/50-null/es/README.md @@ -0,0 +1,27 @@ +En Java, el valor `null` es especial. No es un tipo en sí mismo, sino simplemente un valor con un significado y una lógica de funcionamiento específicos. Comencemos con un ejemplo: + +```java +// Declaración de una variable sin inicializar +// No se puede hacer esto con 'var' ya que no se puede inferir el tipo +String a; +``` + +¿Qué hay dentro de la variable `a`? Si la imprimimos, veremos `null`. El valor `null` se utiliza para tipos de referencia cuando el valor no está definido. + +¿Cómo es esto posible? Imagina que queremos obtener un usuario de una base de datos, pero no existe. ¿Qué nos devolverá la consulta a la base de datos? Ahí es donde entra en juego `null`. + +Hay muchas situaciones en las que se utiliza `null`, más de las que podrías pensar a primera vista. A medida que avancemos, lo encontraremos con mayor frecuencia: + +```java +var user = // aquí hacemos una consulta a la base de datos +// Si no hay datos, user se convierte en null +// La línea anterior es equivalente a +var user = null; +``` + +De lo anterior se deduce una conclusión importante. Cualquier tipo de referencia puede tener el valor `null`. Es decir, `null` es un valor válido para cualquier tipo de referencia. Sin embargo, los tipos primitivos y `null` no son compatibles. Un valor primitivo siempre debe estar definido: + +```java +// Error: tipos incompatibles:
+2 times +diff --git a/modules/33-data-types/55-type-casting/es/README.md b/modules/33-data-types/55-type-casting/es/README.md new file mode 100644 index 00000000..b77f50f3 --- /dev/null +++ b/modules/33-data-types/55-type-casting/es/README.md @@ -0,0 +1,26 @@ +En programación, a menudo nos encontramos con situaciones en las que es necesario convertir un tipo de datos en otro. Un ejemplo sencillo es trabajar con formularios en sitios web. + +Los datos de los formularios siempre llegan en formato de texto, incluso si el valor es un número. Así es cómo se puede convertir: + +```java +// se convierte en int +var number = Integer.parseInt("345"); +System.out.println(number); // => 345 +``` + +Si necesitas convertir de un tipo primitivo a otro tipo primitivo, es más sencillo. Solo necesitas especificar el tipo deseado entre paréntesis antes del valor. Como resultado, el valor se convertirá en el valor de otro tipo especificado entre paréntesis: + +```java +var result = (int) 5.1; +System.out.println(result); // => 5 +``` + +La conversión de tipos se puede utilizar dentro de expresiones compuestas: + +```java +// Los paréntesis adicionales ayudan a separar visualmente las partes de la expresión +var result = 10 + ((int) 5.1); +System.out.println(result); // => 15 +``` + +https://replit.com/@hexlet/java-basics-data-types diff --git a/modules/33-data-types/55-type-casting/es/data.yml b/modules/33-data-types/55-type-casting/es/data.yml new file mode 100644 index 00000000..75a0b116 --- /dev/null +++ b/modules/33-data-types/55-type-casting/es/data.yml @@ -0,0 +1 @@ +name: Conversión explícita de tipos diff --git a/modules/33-data-types/55-type-casting/ru/EXERCISE.md b/modules/33-data-types/55-type-casting/ru/EXERCISE.md new file mode 100644 index 00000000..c098e14f --- /dev/null +++ b/modules/33-data-types/55-type-casting/ru/EXERCISE.md @@ -0,0 +1,5 @@ + +Выведите на экран строку `2 times`, полученную из числа 2.9 и строки `times`, используя преобразования типов и конкатенацию. +
+2 times +diff --git a/modules/33-data-types/55-type-casting/ru/README.md b/modules/33-data-types/55-type-casting/ru/README.md new file mode 100644 index 00000000..b5506cbb --- /dev/null +++ b/modules/33-data-types/55-type-casting/ru/README.md @@ -0,0 +1,26 @@ +В программировании регулярно встречаются задачи, когда один тип данных нужно преобразовать в другой. Простейший пример – работа с формами на сайтах. + +Данные формы всегда приходят в текстовом виде, даже если значение число. Вот как его можно преобразовать: + +```java +// станет int +var number = Integer.parseInt("345"); +System.out.println(number); // => 345 +``` + +Если нужно конвертировать из примитивного типа в примитивный, то все проще. Достаточно перед значением указать в скобках желаемый тип. В результате значение преобразуется в значение другого типа, указанного в скобках: + +```java +var result = (int) 5.1; +System.out.println(result); // => 5 +``` + +Преобразование типов можно использовать внутри составных выражений: + +```java +// Дополнительные скобки помогают визуально отделить части выражения друг от друга +var result = 10 + ((int) 5.1); +System.out.println(result); // => 15 +``` + +https://replit.com/@hexlet/java-basics-data-types diff --git a/modules/33-data-types/55-type-casting/ru/data.yml b/modules/33-data-types/55-type-casting/ru/data.yml new file mode 100644 index 00000000..10f1d916 --- /dev/null +++ b/modules/33-data-types/55-type-casting/ru/data.yml @@ -0,0 +1 @@ +name: Явное преобразование типов diff --git a/modules/35-methods-using/100-methods/es/EXERCISE.md b/modules/35-methods-using/100-methods/es/EXERCISE.md new file mode 100644 index 00000000..29b5a691 --- /dev/null +++ b/modules/35-methods-using/100-methods/es/EXERCISE.md @@ -0,0 +1,2 @@ + +En el código del programa se han definido dos variables que contienen nombres de empresas. Calcule la longitud total de los nombres en caracteres y muéstrela en pantalla. diff --git a/modules/35-methods-using/100-methods/es/README.md b/modules/35-methods-using/100-methods/es/README.md new file mode 100644 index 00000000..69e8196e --- /dev/null +++ b/modules/35-methods-using/100-methods/es/README.md @@ -0,0 +1,47 @@ +La suma, la concatenación, el cálculo del resto de la división y otras operaciones previamente discutidas son capacidades bastante básicas de los lenguajes de programación. + +Las matemáticas no se limitan a la aritmética, también hay muchas otras ramas 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 solo lo más básico. A un nivel más alto, existe la lógica aplicada a una aplicación específica. + +Los programas realizan transacciones monetarias, 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. + +## Cómo se expresan las operaciones + +Para expresar cualquier operación arbitraria en programación, existe el concepto de **función**. Las funciones pueden ser tanto incorporadas en el lenguaje como agregadas por el programador. Ya estamos familiarizados con una función incorporada: `println()`. + +Las funciones son una de las construcciones clave en programación, sin ellas no se puede hacer prácticamente nada. Primero aprenderemos a utilizar las funciones ya creadas y luego aprenderemos a crear nuestras propias funciones. + +Aquí es necesario hacer una pequeña aclaración. En Java no es posible crear una función común, como lo permiten la mayoría de los otros lenguajes. Todas las funciones en Java se crean solo dentro de clases, que aún no hemos estudiado. Y las funciones que están definidas dentro de las clases se llaman **métodos**. Por lo tanto, en el futuro nos adheriremos a esta terminología. + +Comenzaremos con métodos simples para trabajar con cadenas de texto. A continuación se muestra un ejemplo de llamada al método `length()`, que cuenta la cantidad de caracteres en una cadena: + +```java +"Hexlet".length(); // 6 +"ABBA".length(); // 4 +``` + +Los **métodos** son acciones que se deben realizar sobre los datos a los que se aplican. En programación, los **objetos** son los datos que tienen métodos. En realidad, es un poco más complicado, pero por ahora esta definición es suficiente. En Java, todos los tipos de datos no primitivos (de referencia) son objetos. Veamos algunos ejemplos más con la adición de variables: + +```java +var company = "Hexlet"; + +var companyLength = company.length(); +System.out.println(companyLength); // => 6 + +// Convertir a mayúsculas +company.toUpperCase(); // "HEXLET" +``` + +https://replit.com/@hexlet/java-basics-methods-calling + +Lo más importante en el trabajo con métodos es comprender el concepto de retorno de valor. Los métodos casi nunca muestran datos en la pantalla, sino que los devuelven. Gracias a esta propiedad, podemos dividir nuestro programa en fragmentos que luego se combinan en algo más complejo. + +En los ejemplos anteriores, el resultado de llamar a cada método se guarda en variables. Pero esto no es obligatorio, podemos usar los métodos directamente: + +```java +var company = "Hexlet"; +System.out.println(company.length()); // => 6 +``` + +Gradualmente nos familiarizaremos con cada vez más métodos incorporados en el lenguaje. Hay tantos métodos que es imposible recordarlos todos. La buena noticia es que no es necesario. Nadie recuerda los nombres de los métodos de memoria. + +Lo más importante es tener una idea aproximada de lo que se necesita, y luego se pueden utilizar las sugerencias del editor, la documentación y Google. Los programadores pasan mucho tiempo en la documentación, tratando de entender cómo funciona todo. diff --git a/modules/35-methods-using/100-methods/es/data.yml b/modules/35-methods-using/100-methods/es/data.yml new file mode 100644 index 00000000..5452da94 --- /dev/null +++ b/modules/35-methods-using/100-methods/es/data.yml @@ -0,0 +1 @@ +name: Métodos y su llamada diff --git a/modules/35-methods-using/100-methods/ru/EXERCISE.md b/modules/35-methods-using/100-methods/ru/EXERCISE.md new file mode 100644 index 00000000..a0576ed5 --- /dev/null +++ b/modules/35-methods-using/100-methods/ru/EXERCISE.md @@ -0,0 +1,2 @@ + +В коде программы определены две переменные, содержащие имена компаний. Посчитайте их общую длину в символах и выведите ее на экран. diff --git a/modules/35-methods-using/100-methods/ru/README.md b/modules/35-methods-using/100-methods/ru/README.md new file mode 100644 index 00000000..9734dce6 --- /dev/null +++ b/modules/35-methods-using/100-methods/ru/README.md @@ -0,0 +1,47 @@ +Сложение, конкатенация, нахождение остатка от деления и остальные ранее рассмотренные операции – все это довольно базовые возможности языков программирования. + +Математика не ограничена арифметикой, кроме нее есть и множество других разделов со своими операциями — например, геометрия. То же самое касается и строк: их можно переворачивать, менять регистр букв, удалять лишние символы — и это только самое простое. На более высоком уровне есть прикладная логика конкретного приложения. + +Программы списывают деньги, считают налоги, формируют отчеты. Количество подобных операций бесконечно и индивидуально для каждой программы. И все они должны быть как-то выражены в коде. + +## Как выражаются операции + +Для выражения любой произвольной операции в программировании существует понятие **функция**. Функции бывают как встроенные в язык, так и добавленные программистом. С одной встроенной функцией мы уже знакомы — это `println()`. + +Функции — одна из ключевых конструкций в программировании, без них невозможно сделать практически ничего. Сначала мы научимся пользоваться уже созданными функциями, а уже потом научимся создавать свои собственные. + +Здесь нужно сделать небольшую оговорку. В Java невозможно создать обычную функцию, как это позволяет делать большинство других языков. Все функции Java создаются только внутри классов, которые мы пока не разбирали. А функции, которые определены внутри классов принято называть **методами**. Поэтому в дальнейшем мы будем придерживаться этой терминологии. + +Начнем с простых методов для работы над строками. Ниже пример вызова метода `length()`, который считает количество символов в строке: + +```java +"Hexlet".length(); // 6 +"ABBA".length(); // 4 +``` + +**Методы** — это действия, которые нужно выполнить над данными, к которым они применяются. В программировании **объектами** называют данные, у которых есть методы. В реальности все чуть сложнее, но пока нам достаточно и такого определения. В Java все не примитивные (ссылочные) типы данных — это объекты. Рассмотрим еще несколько примеров с добавлением переменных: + +```java +var company = "Hexlet"; + +var companyLength = company.length(); +System.out.println(companyLength); // => 6 + +// Приводим к верхнему регистру +company.toUpperCase(); // "HEXLET" +``` + +https://replit.com/@hexlet/java-basics-methods-calling + +Основное в работе с методами – понять принцип возврата значения. Методы почти никогда не выводят данные на экран, они их возвращают. Благодаря этому свойству, мы можем разбить нашу программу на кусочки, из которых потом составляется что-то сложное. + +В примерах выше результат вызова каждого метода записывается в переменные. Но это не обязательно, мы можем использовать методы напрямую: + +```java +var company = "Hexlet"; +System.out.println(company.length()); // => 6 +``` + +Постепенно мы начнем знакомиться со все большим количеством встроенных методов в язык. Этих методов настолько много, что их невозможно запомнить. Хорошая новость в том, что это и не требуется. Никто не помнит названий методов наизусть. + +Главное — примерно представлять себе, что требуется, а дальше можно использовать подсказки редактора, документацию и Google. Программисты постоянно сидят в документации разбираясь с тем, как что работает. diff --git a/modules/35-methods-using/100-methods/ru/data.yml b/modules/35-methods-using/100-methods/ru/data.yml new file mode 100644 index 00000000..a0adc55c --- /dev/null +++ b/modules/35-methods-using/100-methods/ru/data.yml @@ -0,0 +1 @@ +name: Методы и их вызов diff --git a/modules/35-methods-using/105-methods-parameters/es/EXERCISE.md b/modules/35-methods-using/105-methods-parameters/es/EXERCISE.md new file mode 100644 index 00000000..1116135c --- /dev/null +++ b/modules/35-methods-using/105-methods-parameters/es/EXERCISE.md @@ -0,0 +1,14 @@ + +Se te han dado tres variables con los apellidos de diferentes personas. Construye y muestra en la pantalla una palabra con los caracteres en el siguiente orden: + +1. El tercer carácter de la primera cadena; +2. El segundo carácter de la segunda cadena; +3. El cuarto carácter de la tercera cadena; +4. El quinto carácter de la segunda cadena; +5. El tercer carácter de la segunda cadena. + +La salida del resultado debe ser aproximadamente así: + +
+a b c d e +diff --git a/modules/35-methods-using/105-methods-parameters/es/README.md b/modules/35-methods-using/105-methods-parameters/es/README.md new file mode 100644 index 00000000..24f0dbb8 --- /dev/null +++ b/modules/35-methods-using/105-methods-parameters/es/README.md @@ -0,0 +1,49 @@ + +El método `length()` no requiere ninguna aclaración. Siempre funciona de manera unívoca y extrae la longitud completa de una cadena. + +Pero esto no siempre es así. Por ejemplo, si queremos extraer el primer carácter de una cadena, debemos especificar explícitamente que el carácter es el primero. Para esto, se pueden pasar parámetros a las llamadas de los métodos: + +```java +var searchEngine = "google"; +// Devuelve el primer carácter (tipo char) +searchEngine.charAt(0); // 'g' +``` + +¿Por qué el carácter es el primero pero se indica 0? En programación, la numeración comienza desde cero. Por lo tanto, el primer carácter se encuentra en la posición cero, es decir, "índice 0". + +En consecuencia, el índice del último carácter es igual a la longitud de la cadena menos 1: + +```java +// google length => 6 +searchEngine.charAt(5); // 'e' +``` + +## Varios parámetros + +Puede haber más de un parámetro. Por ejemplo, el método `replace()` trabaja con dos parámetros, donde el primero es lo que se va a reemplazar y el segundo es por qué se va a reemplazar: + +```java +searchEngine.replace("go", "mo"); // "moogle" +``` + +## Valores predeterminados + +Los parámetros pueden tener un valor predeterminado cuando ese valor se utiliza con mayor frecuencia. + +Esta posibilidad se ha agregado a los lenguajes de programación para liberar al programador de tareas rutinarias. Un ejemplo simple es un método que extrae una subcadena de una cadena. + +Este método acepta: + +* El primer parámetro es el índice desde el cual se debe comenzar a extraer la subcadena. +* El segundo parámetro es el índice hasta el cual se deben extraer los caracteres. + +Por defecto, se toma la cadena hasta el final: + +```java +"hexlet".substring(1); // "exlet" +"hexlet".substring(1, 2); // "e" +"hexlet".substring(1, 3); // "ex" +"hexlet".substring(3, 6); // "let" +``` + +https://replit.com/@hexlet/java-basics-methods-calling-1 diff --git a/modules/35-methods-using/105-methods-parameters/es/data.yml b/modules/35-methods-using/105-methods-parameters/es/data.yml new file mode 100644 index 00000000..0cc55c63 --- /dev/null +++ b/modules/35-methods-using/105-methods-parameters/es/data.yml @@ -0,0 +1 @@ +name: Parámetros de los métodos diff --git a/modules/35-methods-using/105-methods-parameters/ru/EXERCISE.md b/modules/35-methods-using/105-methods-parameters/ru/EXERCISE.md new file mode 100644 index 00000000..c5820e41 --- /dev/null +++ b/modules/35-methods-using/105-methods-parameters/ru/EXERCISE.md @@ -0,0 +1,14 @@ + +Вам даны три переменные с фамилиями разных людей. Составьте и выведите на экран слово из символов в таком порядке: + +1. третий символ из первой строки; +2. второй символ из второй строки; +3. четвертый символ из третьей строки; +4. пятый символ из второй строки; +5. третий символ из второй строки. + +Вывод результата должен быть примерно в таком виде: + +
+a b c d e +diff --git a/modules/35-methods-using/105-methods-parameters/ru/README.md b/modules/35-methods-using/105-methods-parameters/ru/README.md new file mode 100644 index 00000000..775a5c79 --- /dev/null +++ b/modules/35-methods-using/105-methods-parameters/ru/README.md @@ -0,0 +1,49 @@ + +Метод `length()` не требует никаких уточнений. Он всегда работает однозначно и извлекает полную длину строки. + +Но так бывает не всегда. Например, если мы хотим извлечь первый символ из строки, то нам нужно явно указать, что символ первый. Для этого в вызовы методов можно передавать параметры: + +```java +var searchEngine = "google"; +// Возвращает первый символ (тип char) +searchEngine.charAt(0); // 'g' +``` + +Почему символ первый, а указан 0? В программировании отсчет начинается с нуля. Поэтому первый символ находится на нулевой позиции — «индекс 0». + +Соответственно, у последнего символа индекс равен длине строки минус 1: + +```java +// google length => 6 +searchEngine.charAt(5); // 'e' +``` + +## Несколько параметров + +Параметров может быть больше, чем один. Например, метод `replace()` работает с двумя, где первый — что заменить, а второй – на что: + +```java +searchEngine.replace("go", "mo"); // "moogle" +``` + +## Значения по умолчанию + +Параметры могут содержать значение по умолчанию там, где это значение используется чаще всего. + +Такая возможность в языках добавлена, чтобы избавить программиста от рутины. Простой пример – метод, извлекающий из строки подстроку, то есть часть строки. + +Этот метод принимает на вход: + +* Первым параметром индекс, с которого надо начать извлекать подстроку +* Вторым параметром — индекс, до которого нужно извлекать символы + +По умолчанию берется строка до конца: + +```java +"hexlet".substring(1); // "exlet" +"hexlet".substring(1, 2); // "e" +"hexlet".substring(1, 3); // "ex" +"hexlet".substring(3, 6); // "let" +``` + +https://replit.com/@hexlet/java-basics-methods-calling-1 diff --git a/modules/35-methods-using/105-methods-parameters/ru/data.yml b/modules/35-methods-using/105-methods-parameters/ru/data.yml new file mode 100644 index 00000000..2b161391 --- /dev/null +++ b/modules/35-methods-using/105-methods-parameters/ru/data.yml @@ -0,0 +1 @@ +name: Параметры методов diff --git a/modules/35-methods-using/110-methods-as-expressions/es/EXERCISE.md b/modules/35-methods-using/110-methods-as-expressions/es/EXERCISE.md new file mode 100644 index 00000000..ec4488b3 --- /dev/null +++ b/modules/35-methods-using/110-methods-as-expressions/es/EXERCISE.md @@ -0,0 +1,9 @@ + +Muestra en pantalla la primera y la última letra de la oración que se encuentra en la variable `text`, en el siguiente formato: + +
+First: N +Last: t ++ +Intenta crear solo una variable en la que se almacene el texto necesario antes de imprimirlo en pantalla. En esta lección, practicamos la habilidad de construir expresiones compuestas. diff --git a/modules/35-methods-using/110-methods-as-expressions/es/README.md b/modules/35-methods-using/110-methods-as-expressions/es/README.md new file mode 100644 index 00000000..732ee8c8 --- /dev/null +++ b/modules/35-methods-using/110-methods-as-expressions/es/README.md @@ -0,0 +1,53 @@ +En programación, una expresión es algo que devuelve un resultado que se puede utilizar. + +Ya sabemos bastante sobre las expresiones y los principios de su construcción. La suma, la resta, la concatenación y otras operaciones matemáticas y de cadenas de texto son todas expresiones: + +```java +1 + 5 * 3; +"He" + "Let"; +// Las variables pueden formar parte de una expresión +rate * 5; +``` + +La característica de las expresiones es que devuelven un resultado que se puede utilizar, como asignarlo a una variable o mostrarlo en pantalla: + +```java +// Aquí la expresión es 1 + 5 +var sum = 1 + 5; +System.out.println(1 + 5); +``` + +Pero no todo en programación es una expresión. La declaración de una variable es una instrucción y no puede formar parte de una expresión. Es decir, este código dará un error: + +```java +// Código sin sentido que no funcionará +10 + var sum = 1 + 5; +``` + +Como verás más adelante, las expresiones se pueden combinar para obtener comportamientos más complejos en lugares inesperados y de formas inesperadas. Entenderás mejor cómo se pueden unir las partes del código para obtener el resultado deseado. + +Hablemos de los métodos. ¿Una llamada a un método es una expresión o no? Sabemos que los métodos devuelven un resultado, por lo que sí, son expresiones. De esto se deduce automáticamente muchas cosas interesantes. + +Por ejemplo, podemos utilizar una llamada a un método directamente en operaciones matemáticas. Así es como se puede obtener el índice del último carácter de una palabra: + +```java +// Los índices comienzan en cero +var name = "Java"; +// ¡Llamada al método y resta juntos! +var lastIndex = name.length() - 1; +System.out.println(lastIndex); // => 3 +``` + +En este código no hay una nueva sintaxis. Simplemente hemos combinado partes conocidas basándonos en su naturaleza. Podemos ir aún más lejos: + +```java +System.out.println(name.length() - 1); // => 3 +``` + +Todo esto es válido para cualquier método, incluyendo los métodos de cadenas de texto: + +```java +var name = "Java"; +// toUpperCase() convierte la palabra a mayúsculas +System.out.println("Hola " + name.toUpperCase()); // => Hola JAVA +``` diff --git a/modules/35-methods-using/110-methods-as-expressions/es/data.yml b/modules/35-methods-using/110-methods-as-expressions/es/data.yml new file mode 100644 index 00000000..21e9a6e4 --- /dev/null +++ b/modules/35-methods-using/110-methods-as-expressions/es/data.yml @@ -0,0 +1 @@ +name: Llamada al método - expresión diff --git a/modules/35-methods-using/110-methods-as-expressions/ru/EXERCISE.md b/modules/35-methods-using/110-methods-as-expressions/ru/EXERCISE.md new file mode 100644 index 00000000..6f5608bc --- /dev/null +++ b/modules/35-methods-using/110-methods-as-expressions/ru/EXERCISE.md @@ -0,0 +1,9 @@ + +Выведите на экран первую и последнюю буквы предложения, записанного в переменную `text`, в следующем формате: + +
+First: N +Last: t ++ +Постарайтесь создать только одну переменную, в которую сразу запишется нужный текст перед печатью на экран. В этом уроке мы отрабатываем умение собирать составное выражение. diff --git a/modules/35-methods-using/110-methods-as-expressions/ru/README.md b/modules/35-methods-using/110-methods-as-expressions/ru/README.md new file mode 100644 index 00000000..1cdc0162 --- /dev/null +++ b/modules/35-methods-using/110-methods-as-expressions/ru/README.md @@ -0,0 +1,53 @@ +В программировании выражение — нечто возвращающее результат, который можно использовать. + +Мы уже знаем достаточно много о выражениях и о принципах их построения. Сложение, вычитание, конкатенация, а также другие математические и строковые операции — все это выражения: + +```java +1 + 5 * 3; +"He" + "Let"; +// Переменные могут быть частью выражения +rate * 5; +``` + +Особенность выражений в том, что они возвращают результат, который можно использовать — например, присвоить переменной или вывести на экран: + +```java +// Тут выражение это 1 + 5 +var sum = 1 + 5; +System.out.println(1 + 5); +``` + +Но не все в программировании является выражением. Определение переменной — это инструкция, она не может быть частью выражения. То есть такой код выдаст ошибку: + +```java +// Бессмысленный код, который не сработает +10 + var sum = 1 + 5; +``` + +Как вы увидите дальше, выражения можно комбинировать, получая все более сложное поведение в самых неожиданных местах и неожиданным образом. Вы будете лучше понимать, как можно соединять части кода, чтобы получить нужный результат. + +Поговорим о методах. Вызов метода — это выражение или нет? Мы знаем, что методы возвращают результат, то есть да, они выражения. Из этого автоматически следует много интересного. + +Например, мы можем использовать вызов метода прямо в математических операциях. Вот как можно получить индекс последнего символа в слове: + +```java +// Индексы начинаются с нуля +var name = "Java"; +// Вызов метода и вычитание вместе! +var lastIndex = name.length() - 1; +System.out.println(lastIndex); // => 3 +``` + +В этом коде нет нового синтаксиса. Мы всего лишь соединили уже известные части, опираясь на их природу. Можно пойти еще дальше: + +```java +System.out.println(name.length() - 1); // => 3 +``` + +Все это справедливо для любых методов, в том числе строковых: + +```java +var name = "Java"; +// toUpperCase() – переводит слово в верхний регистр +System.out.println("Привет " + name.toUpperCase()); // => Привет JAVA +``` diff --git a/modules/35-methods-using/110-methods-as-expressions/ru/data.yml b/modules/35-methods-using/110-methods-as-expressions/ru/data.yml new file mode 100644 index 00000000..ec5f37a6 --- /dev/null +++ b/modules/35-methods-using/110-methods-as-expressions/ru/data.yml @@ -0,0 +1 @@ +name: Вызов метода — выражение diff --git a/modules/35-methods-using/115-string-immutability/es/EXERCISE.md b/modules/35-methods-using/115-string-immutability/es/EXERCISE.md new file mode 100644 index 00000000..3d413aec --- /dev/null +++ b/modules/35-methods-using/115-string-immutability/es/EXERCISE.md @@ -0,0 +1,7 @@ + +Los datos ingresados por los usuarios en los formularios a menudo contienen espacios en blanco adicionales al principio o al final de la cadena. Además, los usuarios pueden ingresar lo mismo en diferentes casos, lo que luego dificulta el trabajo con los datos. Por lo tanto, antes de agregarlos, los datos se procesan (se dice que se normalizan). El procesamiento básico incluye dos acciones: + +* Eliminar los espacios en blanco finales utilizando el método `.trim()`, por ejemplo, si era: `" hexlet\n "`, ahora es: `"hexlet"` +* Convertir a minúsculas utilizando el método `toLowerCase()`. Si era: `"SUPPORT@hexlet.io"`, ahora es: `"support@hexlet.io"`. + +Actualiza la variable `email` asignándole el mismo valor, pero procesado según el esquema mencionado anteriormente. Imprime en pantalla el resultado obtenido. diff --git a/modules/35-methods-using/115-string-immutability/es/README.md b/modules/35-methods-using/115-string-immutability/es/README.md new file mode 100644 index 00000000..9f0963d2 --- /dev/null +++ b/modules/35-methods-using/115-string-immutability/es/README.md @@ -0,0 +1,33 @@ +Pensemos en qué mostrará en pantalla el siguiente código: + +```java +var company = "hexlet"; +company.toUpperCase(); // en mayúsculas +System.out.println(company); // => ? +``` + +Parece que la respuesta será `"HEXLET"`, pero no es así. Este programa mostrará `"hexlet"` (compruébalo en [tryjshell](https://onecompiler.com/jshell)). ¿Por qué? + +El motivo es que las cadenas en Java son inmutables. No hay forma ni métodos que puedan modificar la cadena en sí misma. Cualquier método de cadena solo puede devolver una nueva cadena. + +La razón principal de esto es el rendimiento. Las cadenas y otros tipos de datos primitivos no se pueden modificar en prácticamente ningún lenguaje de programación moderno. + +La segunda razón está relacionada con la simplicidad del código. Cuando no modificamos los datos, sino que creamos nuevos datos basados en los antiguos, el código es más fácil de analizar y modificar. Especialmente cuando se realizan muchas manipulaciones con los datos, lo cual te encontrarás en el futuro. + +Pero, ¿qué hacer si necesitamos cambiar los datos? Para ello, simplemente debemos reemplazar el valor de la variable: + +```java +var language = "JAVA"; +language = language.toLowerCase(); +System.out.println(language); // => java +``` + +Por otro lado, en una situación como esta, también podemos crear una nueva variable con un nombre diferente: + +```java +var language = "JAVA"; +var processedLanguage = language.toLowerCase(); +System.out.println(processedLanguage); // => java +``` + +Este enfoque a menudo es preferible por motivos de legibilidad. Las variables que cambian constantemente son más difíciles de analizar. Al final, todo depende de la tarea. Con la experiencia, se adquiere la comprensión de qué enfoque es mejor. diff --git a/modules/35-methods-using/115-string-immutability/es/data.yml b/modules/35-methods-using/115-string-immutability/es/data.yml new file mode 100644 index 00000000..52413014 --- /dev/null +++ b/modules/35-methods-using/115-string-immutability/es/data.yml @@ -0,0 +1 @@ +name: Inmutabilidad de las cadenas diff --git a/modules/35-methods-using/115-string-immutability/ru/EXERCISE.md b/modules/35-methods-using/115-string-immutability/ru/EXERCISE.md new file mode 100644 index 00000000..96009f10 --- /dev/null +++ b/modules/35-methods-using/115-string-immutability/ru/EXERCISE.md @@ -0,0 +1,7 @@ + +Данные, вводимые пользователями в формах, часто содержат лишние пробельные символы в конце или начале строки. Кроме того, пользователи могут вводить одно и то же в разном регистре, что потом мешает работе с данными. Поэтому перед тем как добавлять их, данные обрабатывают (говорят нормализуют). В базовую обработку входят два действия: + +* Удаление концевых пробельных символов с помощью метода `.trim()`, например, было: `" hexlet\n "`, стало: `"hexlet"` +* Приведение к нижнему регистру с помощью метода `toLowerCase()`. Было: `"SUPPORT@hexlet.io"`, стало: `"support@hexlet.io"`. + +Обновите переменную `email` записав в неё то же самое значение, но обработанное по схеме указанной выше. Распечатайте то, что получилось, на экран. diff --git a/modules/35-methods-using/115-string-immutability/ru/README.md b/modules/35-methods-using/115-string-immutability/ru/README.md new file mode 100644 index 00000000..05f726cb --- /dev/null +++ b/modules/35-methods-using/115-string-immutability/ru/README.md @@ -0,0 +1,35 @@ +Подумаем, что выведет на экран следующий код: + +```java +var company = "hexlet"; +company.toUpperCase(); // в верхний регистр +System.out.println(company); // => ? +``` + +Кажется, что ответом будет `"HEXLET"`, но это не так. Эта программа выведет `"hexlet"` (проверьте на [tryjshell](https://onecompiler.com/jshell)). Почему? + +Дело в том, что строки в Java неизменяемы. Не существует способа и методов, способных изменить саму строку. Любой метод строки может только вернуть новую строку. + +Основная причина, почему так сделано – производительность. Строки, и другие примитивные типы данных нельзя менять практически ни в одном современном языке. + +Вторая причина связана с простотой кода. Когда мы не изменяем данные, а создаем новые данные на основе старых, то код проще анализировать и модифицировать. Особенно если с данными происходит много манипуляций, с этим вам еще предстоит столкнуться. + +Но как же поступать, если данные нужно поменять? Для этого достаточно заменить значение переменной: + +```java +var language = "JAVA"; +language = language.toLowerCase(); +System.out.println(language); // => java +``` + +С другой стороны, именно в такой ситуации можно создать новую переменную с другим именем: + +```java +var language = "JAVA"; +var processedLanguage = language.toLowerCase(); +System.out.println(processedLanguage); // => java +``` + +https://replit.com/@hexlet/java-basics-methods-as-expressions + +Такой подход нередко предпочтительнее по соображениям читаемости. Переменные, которые постоянно меняются, сложнее анализировать. В итоге все зависит от задачи. С опытом придет понимание, какой подход лучше. diff --git a/modules/35-methods-using/115-string-immutability/ru/data.yml b/modules/35-methods-using/115-string-immutability/ru/data.yml new file mode 100644 index 00000000..4445d4cf --- /dev/null +++ b/modules/35-methods-using/115-string-immutability/ru/data.yml @@ -0,0 +1 @@ +name: Неизменяемость строк diff --git a/modules/35-methods-using/120-methods-chain/es/EXERCISE.md b/modules/35-methods-using/120-methods-chain/es/EXERCISE.md new file mode 100644 index 00000000..ce6b43c8 --- /dev/null +++ b/modules/35-methods-using/120-methods-chain/es/EXERCISE.md @@ -0,0 +1,11 @@ + +Escriba un código que tome los datos de la variable `name` y los capitalice. En programación, esto se llama capitalización, que convierte la primera letra de una palabra en mayúscula y el resto en minúsculas. Por ejemplo: *heXlet => Hexlet*. El programa debe imprimir el resultado en la pantalla. + +Para extraer partes de una palabra, use el método [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java): + +```java +// El primer parámetro es el índice inicial, el segundo es el índice final (no incluido) +"hexlet".substring(0, 1); // "h" +// Por defecto, hasta el final de la cadena +"hexlet".substring(1); // "exlet" +``` diff --git a/modules/35-methods-using/120-methods-chain/es/README.md b/modules/35-methods-using/120-methods-chain/es/README.md new file mode 100644 index 00000000..13302cb3 --- /dev/null +++ b/modules/35-methods-using/120-methods-chain/es/README.md @@ -0,0 +1,56 @@ +El procesamiento de datos puede constar de una cantidad considerable de pasos que deben realizarse. + +Tomemos como ejemplo la tarea de crear una dirección de página web basada en el nombre de un artículo ingresado por el usuario. Esta tarea a menudo surge al publicar artículos en blogs. Estas direcciones se ven así: + +``` +https://codica.la/blog/de-obrero-a-programador +``` + +La última parte aquí, *de-obrero-a-programador*, se crea automáticamente con el código que hemos escrito en Hexlet. Por cierto, tiene un nombre especial: se llama [**slug**](https://en.wikipedia.org/wiki/Clean_URL#Slug). + +¿Qué pasos se deben seguir para obtener una cadena similar? Aquí hay solo algunos de ellos: + +* Convertir todo a minúsculas para evitar la creación accidental de duplicados de páginas en los motores de búsqueda. +* Limpiar el nombre de los espacios en blanco alrededor. Pueden aparecer accidentalmente al ingresar el nombre. +* Realizar transliteración. Es mejor que las direcciones solo contengan caracteres del alfabeto latino. +* Eliminar todos los caracteres especiales, como signos de interrogación, exclamaciones, etc. +* Reemplazar todos los espacios por guiones. + +Algunos de estos pasos requieren conocimientos nuevos para nosotros, por lo que los omitiremos. Los demás pasos se verán más o menos así: + +```java +// Nombre ingresado por el usuario. En inglés para mayor simplicidad +var name = " How much is the fish? \n"; +// Eliminamos los espacios y saltos de línea al final +name = name.trim(); +// Eliminamos el signo de interrogación +name = name.replace("?", ""); +// Reemplazamos los espacios por guiones +name = name.replace(" ", "-"); +// Convertimos a minúsculas +name = name.toLowerCase(); +System.out.println(name); // => how-much-is-the-fish +``` + +Si observamos detenidamente este código, podemos notar un patrón común. El método devuelve los datos que asignamos a la variable y luego los procesa en una cadena de llamadas de métodos. + +Este patrón se puede simplificar eliminando la reasignación intermedia de la variable: + +```java +var name = " How much is the fish? "; +name = name.trim().replace("?", "").replace(" ", "-").toLowerCase(); +System.out.println(name); // => how-much-is-the-fish +``` + +Gracias a que cada método devuelve una nueva cadena, podemos seguir procesándola llamando a los métodos uno tras otro. Si la cadena de métodos se vuelve demasiado larga, se puede dividir en varias líneas: + +```java +name = name.trim() + .replace("?", "") + .replace(" ", "-") + .toLowerCase(); +``` + +https://replit.com/@hexlet/java-basics-methods-chain + +A pesar de la conveniencia de este mecanismo, no se debe abusar de él. Las variables intermedias pueden facilitar la comprensión del código. diff --git a/modules/35-methods-using/120-methods-chain/es/data.yml b/modules/35-methods-using/120-methods-chain/es/data.yml new file mode 100644 index 00000000..21e2de0f --- /dev/null +++ b/modules/35-methods-using/120-methods-chain/es/data.yml @@ -0,0 +1 @@ +name: Cadenas de llamadas de métodos diff --git a/modules/35-methods-using/120-methods-chain/ru/EXERCISE.md b/modules/35-methods-using/120-methods-chain/ru/EXERCISE.md new file mode 100644 index 00000000..5cd65178 --- /dev/null +++ b/modules/35-methods-using/120-methods-chain/ru/EXERCISE.md @@ -0,0 +1,11 @@ + +Напишите код, который берет данные из переменной `name` и выполняет капитализацию. В программировании так называют операцию, которая делает заглавной первую букву в слове, а все остальные переводит в нижний регистр. Например: *heXlet => Hexlet*. Программа должна выводить результат на экран. + +Для извлечения частей слова, воспользуйтесь методом [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java): + +```java +// 1 параметр – начальный индекс, 2 – конечный индекс (не включая) +"hexlet".substring(0, 1); // "h" +// По умолчанию до конца строки +"hexlet".substring(1); // "exlet" +``` diff --git a/modules/35-methods-using/120-methods-chain/ru/README.md b/modules/35-methods-using/120-methods-chain/ru/README.md new file mode 100644 index 00000000..7e75a683 --- /dev/null +++ b/modules/35-methods-using/120-methods-chain/ru/README.md @@ -0,0 +1,56 @@ +Обработка данных может состоять из достаточно большого количества шагов, которые нужно выполнить. + +Возьмем для примера такую задачу: сформировать адрес страницы в интернете на основе введенного пользователем названия статьи. Такая задача часто возникает при публикации статей в блогах. Подобные адреса выглядят так: + +``` +https://ru.hexlet.io/blog/posts/iz-vahtovika-v-programmirovanie +``` + +Последняя часть здесь *iz-vahtovika-v-programmirovanie* создана автоматически кодом, который мы написали на Хекслете. Кстати, у нее есть специальное название – это [**слаг**](https://en.wikipedia.org/wiki/Clean_URL#Slug). + +Какие шаги нужно выполнить? чтобы получить подобную строку? Вот лишь некоторые из них: + +* Перевести все в нижний регистр, чтобы случайно не создавались дубли одинаковых страниц в поисковых системах +* Очистить название от пробельных символов на концах. Там они могут случайно появиться при вводе названия +* Выполнить транслитерацию. Лучше, когда в адресах только символы латинского алфавита +* Вырезать все специальные символы, такие как вопросы, восклицательные знаки и тому подобное +* Заменить все пробелы на дефисы + +Часть шагов тут требует новых для нас знаний, поэтому мы их опустим. Остальные шаги будут выглядеть примерно так: + +```java +// Название, введенное пользователем. Для простоты на английском +var name = " How much is the fish? \n"; +// вырезаем концевые пробелы и перенос строки +name = name.trim(); +// Удаляем вопрос +name = name.replace("?", ""); +// Заменяем пробелы на дефис +name = name.replace(" ", "-"); +// Переводим в нижний регистр +name = name.toLowerCase(); +System.out.println(name); // => how-much-is-the-fish +``` + +Если внимательно посмотреть на этот код, то можно заметить общий шаблон. Метод возвращает данные, которые мы присваиваем переменной, и дальше по цепочке обрабатывает их. + +Этот шаблон можно упростить, убрав промежуточное перезаписывание переменной: + +```java +var name = " How much is the fish? "; +name = name.trim().replace("?", "").replace(" ", "-").toLowerCase(); +System.out.println(name); // => how-much-is-the-fish +``` + +Благодаря тому, что каждый метод возвращает новую строку, мы можем продолжать обрабатывать ее, вызывая методы подряд. Если цепочка методов становится слишком длинной, то ее можно разбить на несколько строк: + +```java +name = name.trim() + .replace("?", "") + .replace(" ", "-") + .toLowerCase(); +``` + +https://replit.com/@hexlet/java-basics-methods-chain + +Несмотря на удобство этого механизма, им не стоит злоупотреблять. Промежуточные переменные могут упростить понимание кода. diff --git a/modules/35-methods-using/120-methods-chain/ru/data.yml b/modules/35-methods-using/120-methods-chain/ru/data.yml new file mode 100644 index 00000000..257c8768 --- /dev/null +++ b/modules/35-methods-using/120-methods-chain/ru/data.yml @@ -0,0 +1 @@ +name: Цепочки вызовов методов diff --git a/modules/35-methods-using/200-methods-deterministic/es/EXERCISE.md b/modules/35-methods-using/200-methods-deterministic/es/EXERCISE.md new file mode 100644 index 00000000..d1eb70db --- /dev/null +++ b/modules/35-methods-using/200-methods-deterministic/es/EXERCISE.md @@ -0,0 +1,10 @@ + +El método `Math.random()` devuelve un número aleatorio entre 0 y 1 con varios dígitos decimales. Sin embargo, en problemas reales, a veces es necesario obtener números enteros aleatorios. Implementa un código que imprima en pantalla un número entero aleatorio entre 0 y 10. Para obtener dicho número, debes multiplicar el resultado de llamar a `Math.random()` por 10 y convertir el tipo de dato del número obtenido de *double* a *int*. + +```java +// Conversión a int +(int) 0.932342; // 0 +(int) 8.123412; // 8 +``` + +Intenta resolver este ejercicio en una sola línea. diff --git a/modules/35-methods-using/200-methods-deterministic/es/README.md b/modules/35-methods-using/200-methods-deterministic/es/README.md new file mode 100644 index 00000000..f78ce65b --- /dev/null +++ b/modules/35-methods-using/200-methods-deterministic/es/README.md @@ -0,0 +1,18 @@ +Independientemente del lenguaje de programación utilizado, los métodos tienen algunas propiedades fundamentales. Conocer estas propiedades facilita predecir el comportamiento de los métodos, las formas de probarlos y dónde utilizarlos. Una de estas propiedades es el determinismo. Un método se considera determinista cuando, para los mismos parámetros de entrada, devuelve siempre el mismo resultado. Por ejemplo, un método que extrae un carácter de una cadena es determinista. + +```java +"wow".charAt(1); // 'o' +"wow".charAt(1); // 'o' +``` + +No importa cuántas veces llamemos a este método pasándole el valor `1`, siempre devolverá `'o'`. Por otro lado, un método 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, automáticamente se considera un método no determinista. + +```java +// Método que devuelve un número aleatorio +Math.random(); // 0.09856613113197676 +Math.random(); // 0.8839904367241888 +``` + +https://replit.com/@hexlet/java-basics-pure-functions + +¿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í. diff --git a/modules/35-methods-using/200-methods-deterministic/es/data.yml b/modules/35-methods-using/200-methods-deterministic/es/data.yml new file mode 100644 index 00000000..b54bb5b4 --- /dev/null +++ b/modules/35-methods-using/200-methods-deterministic/es/data.yml @@ -0,0 +1,5 @@ +name: Determinismo +tips: + - > + [Funciones + deterministas](https://es.wikipedia.org/wiki/Función_pura#Determinismo_de_la_función) diff --git a/modules/35-methods-using/200-methods-deterministic/ru/EXERCISE.md b/modules/35-methods-using/200-methods-deterministic/ru/EXERCISE.md new file mode 100644 index 00000000..f4d13e44 --- /dev/null +++ b/modules/35-methods-using/200-methods-deterministic/ru/EXERCISE.md @@ -0,0 +1,10 @@ + +Метод `Math.random()` возвращает случайное число от 0 до 1 с большим количеством знаков после запятой. Но в реальных задачах бывает нужно получать случайные целые числа. Реализуйте код, который печатает на экран случайное целое число от 0 до 10. Чтобы получить такое число, нужно умножить результат вызова `Math.random()` на 10 и преобразовать тип полученного числа из *double* в *int*. + +```java +// Преобразование в int +(int) 0.932342; // 0 +(int) 8.123412; // 8 +``` + +Попробуйте решить это задание в одну строчку diff --git a/modules/35-methods-using/200-methods-deterministic/ru/README.md b/modules/35-methods-using/200-methods-deterministic/ru/README.md new file mode 100644 index 00000000..f89ac488 --- /dev/null +++ b/modules/35-methods-using/200-methods-deterministic/ru/README.md @@ -0,0 +1,18 @@ +Независимо от того, какой язык программирования используется, методы внутри него обладают некоторыми фундаментальными свойствами. Зная эти свойства, легче прогнозировать поведение методов, способы их тестирования и место их использования. К таким свойствам относится детерминированность. Метод называется детерминированным тогда, когда для одних и тех же входных параметров он возвращает один и тот же результат. Например, метод, извлекающий символ из строки — детерминированный. + +```java +"wow".charAt(1); // 'o' +"wow".charAt(1); // 'o' +``` + +Сколько бы раз мы не вызывали этот метод, передавая туда значение `1`, он всегда вернет `'o'`. В свою очередь метод, возвращающий случайное число, не является детерминированным, так как у одного и того же входа (даже если он пустой, то есть параметры не принимаются) мы получим всегда разный результат. Насколько он разный - не важно, даже если хотя бы один из миллиона вызовов вернет что-то другое, этот метод автоматически считается недетерминированным. + +```java +// Метод, возвращающий случайное число +Math.random(); // 0.09856613113197676 +Math.random(); // 0.8839904367241888 +``` + +https://replit.com/@hexlet/java-basics-pure-functions + +Зачем это нужно знать? Детерминированность серьезно влияет на многие аспекты. Детерминированные функции удобны в работе, их легко оптимизировать, легко тестировать. Если есть возможность сделать функцию детерминированной, то лучше ее такой и сделать. diff --git a/modules/35-methods-using/200-methods-deterministic/ru/data.yml b/modules/35-methods-using/200-methods-deterministic/ru/data.yml new file mode 100644 index 00000000..21291930 --- /dev/null +++ b/modules/35-methods-using/200-methods-deterministic/ru/data.yml @@ -0,0 +1,5 @@ +name: Детерминированность +tips: + - > + [Детерминированные + функции](https://ru.wikipedia.org/wiki/Чистота_функции#Детерминированность_функции) diff --git a/modules/35-methods-using/400-stdlib/es/EXERCISE.md b/modules/35-methods-using/400-stdlib/es/EXERCISE.md new file mode 100644 index 00000000..3a7dd944 --- /dev/null +++ b/modules/35-methods-using/400-stdlib/es/EXERCISE.md @@ -0,0 +1,12 @@ + +Escribiremos código en el estilo "sigue al maestro". Calcularemos la cantidad de días entre dos fechas utilizando las capacidades incorporadas de Java. Intenta "jugar" con las fechas. + +```java +// Desde la fecha +LocalDate dateFrom = LocalDate.of(2017, Month.MAY, 24); +// Hasta la fecha +LocalDate dateTo = LocalDate.of(2017, Month.JULY, 29); +// Cantidad de días entre estas fechas +long noOfDaysBetween = ChronoUnit.DAYS.between(dateFrom, dateTo); +System.out.println(noOfDaysBetween); +``` diff --git a/modules/35-methods-using/400-stdlib/es/README.md b/modules/35-methods-using/400-stdlib/es/README.md new file mode 100644 index 00000000..e3e952e4 --- /dev/null +++ b/modules/35-methods-using/400-stdlib/es/README.md @@ -0,0 +1,9 @@ +Java, al igual que cualquier otro lenguaje, viene con un conjunto de métodos útiles. Todos juntos forman lo que se conoce como la **biblioteca estándar**. Por lo general, incluye miles de métodos que no se pueden aprender todos, y no es necesario hacerlo. Se supone que cualquier programador sabe dónde buscar la documentación y tiene una idea aproximada de lo que quiere lograr. A partir de ahí, es solo cuestión de técnica. Si se les quita a los programadores el acceso a Internet, la mayoría no podrá programar nada. + +Para los principiantes, esta información a menudo parece: "Ve allí, no sé dónde, trae eso, no sé qué". Es decir, no está claro cómo aprender sobre estos métodos cuando no sabes nada en absoluto. Curiosamente, no hay una forma de aprender todo lo que necesitas saber de una vez y para siempre. Cada desarrollador, a medida que crece profesionalmente, se familiariza con métodos cada vez más interesantes que resuelven sus problemas de manera más elegante, y así enriquece su arsenal. + +Aquí hay algunos consejos sobre cómo aprender sobre nuevos métodos: + +* Siempre sigue claramente el tipo de datos con el que estás trabajando. Casi siempre encontrarás el método necesario en la sección correspondiente de la documentación, por ejemplo, para trabajar con cadenas, debes estudiar los métodos de cadena. +* Abre periódicamente la sección de métodos estándar relacionados con el tema que estás estudiando y simplemente revísalos, estudiando las firmas y formas de uso. +* Lee el código de otras personas con más frecuencia, especialmente el código de las bibliotecas que estás utilizando. Todo está disponible en GitHub. diff --git a/modules/35-methods-using/400-stdlib/es/data.yml b/modules/35-methods-using/400-stdlib/es/data.yml new file mode 100644 index 00000000..fbb9aa82 --- /dev/null +++ b/modules/35-methods-using/400-stdlib/es/data.yml @@ -0,0 +1,4 @@ +name: Biblioteca estándar +tips: + - | + [Cómo buscar información técnica](https://guides.hexlet.io/how-to-search/) diff --git a/modules/35-methods-using/400-stdlib/ru/EXERCISE.md b/modules/35-methods-using/400-stdlib/ru/EXERCISE.md new file mode 100644 index 00000000..cdc8628c --- /dev/null +++ b/modules/35-methods-using/400-stdlib/ru/EXERCISE.md @@ -0,0 +1,12 @@ + +Напишем код в стиле "повтори за учителем". Рассчитаем количество дней между двумя датами используя встроенные возможности Java. Попробуйте "поиграть" с датами. + +```java +// С даты +LocalDate dateFrom = LocalDate.of(2017, Month.MAY, 24); +// По дату +LocalDate dateTo = LocalDate.of(2017, Month.JULY, 29); +// Количество дней между этими датами +long noOfDaysBetween = ChronoUnit.DAYS.between(dateFrom, dateTo); +System.out.println(noOfDaysBetween); +``` diff --git a/modules/35-methods-using/400-stdlib/ru/README.md b/modules/35-methods-using/400-stdlib/ru/README.md new file mode 100644 index 00000000..36a235f4 --- /dev/null +++ b/modules/35-methods-using/400-stdlib/ru/README.md @@ -0,0 +1,9 @@ +Java, как и любой другой язык, поставляется с набором полезных методов. Все вместе они составляют так называемую **стандартную библиотеку**. В нее обычно входят тысячи методов, которые невозможно выучить — этого и не нужно делать. Подразумевается, что любой программист знает, где искать документацию по ним и примерно представляет себе, чего он хочет достичь. А дальше — дело техники. Если отнять у программистов интернет, то большинство не сможет ничего запрограммировать. + +Для новичков эта информация часто выглядит так: «Сходи туда, не знаю куда, принеси то, не знаю что». То есть непонятно, как узнавать про эти методы, когда ты ничего не знаешь вообще. Как ни странно, не существует способа раз и навсегда познать все, что нужно познать. Любой разработчик в процессе своего профессионального взросления знакомится со все более интересными методами, решающими его задачи более элегантно, и таким образом пополняет свой арсенал. + +Вот некоторые советы, как узнавать о новых методах: + +* Всегда четко отслеживайте, с каким типом данных вы сейчас работаете. Почти всегда вы найдете необходимый метод в соответствующем разделе документации — например, для работы со строками нужно изучать строковые методы +* Периодически открывайте раздел со стандартными методами по изучаемой тематике и просто пробегайтесь по ним, изучая сигнатуры и способы использования +* Чаще читайте чужой код, особенно код библиотек, которые вы используете. Он весь доступен на GitHub diff --git a/modules/35-methods-using/400-stdlib/ru/data.yml b/modules/35-methods-using/400-stdlib/ru/data.yml new file mode 100644 index 00000000..99a22713 --- /dev/null +++ b/modules/35-methods-using/400-stdlib/ru/data.yml @@ -0,0 +1,4 @@ +name: Стандартная библиотека +tips: + - | + [Как искать техническую информацию](https://guides.hexlet.io/how-to-search/) diff --git a/modules/35-methods-using/500-methods-variants/es/EXERCISE.md b/modules/35-methods-using/500-methods-variants/es/EXERCISE.md new file mode 100644 index 00000000..594090f9 --- /dev/null +++ b/modules/35-methods-using/500-methods-variants/es/EXERCISE.md @@ -0,0 +1,7 @@ + +La variable `emoji` contiene un emoticón triste en forma de texto *-(*. Tu tarea es convertir este emoticón en uno alegre utilizando dos transformaciones: + + * Agregar un ojo a la izquierda *:* + * Reemplazar *(* por *)* (utilizando el método `replace()` de la cadena de texto) + +Debe quedar así: *:-)*. Imprímelo en pantalla. diff --git a/modules/35-methods-using/500-methods-variants/es/README.md b/modules/35-methods-using/500-methods-variants/es/README.md new file mode 100644 index 00000000..d59770b9 --- /dev/null +++ b/modules/35-methods-using/500-methods-variants/es/README.md @@ -0,0 +1,73 @@ +Uno de los temas fundamentales en Java en el que se basa el código son las clases y los objetos. Aparecen literalmente desde las primeras líneas de código, pero aprender a utilizarlos no es tan sencillo. Por eso, el estudio de los objetos y las clases se extiende a lo largo de múltiples lecciones. En esta lección nos adentraremos un poco más en el funcionamiento del lenguaje. No te preocupes si aún no encajan todas las piezas, es normal. Las clases, los objetos y los métodos son un tema complejo que requiere tiempo. + +Ya hemos visto métodos integrados en Java en diferentes formas: + +```java +System.out.println(); +varname.toLowerCase(); +varname.substring(); +Integer.parseInt(); +ChronoUnit.DAYS.between(); +``` + +Todos estos tipos de llamadas se pueden dividir en dos grupos: + +1. Llamadas a métodos de objetos, como cadenas de texto +2. Llamadas a métodos estáticos, que no están relacionados con objetos específicos + +## Llamadas a métodos de objetos + +Hasta ahora solo hemos trabajado con métodos de cadenas de texto, pero el principio es el mismo para cualquier tipo de objeto: + +```java +// Sintaxis para crear un objeto +// new - crea un nuevo objeto de la clase +var user = new User(); + +// Obtiene el nombre del usuario +user.getName(); + +// Ejemplos con otros objetos + +// Obtiene el día actual +currentDate.getDayOfMonth(); +// Comprueba si el archivo existe +file.exists(); +``` + +Estos métodos realizan acciones sobre los objetos en los que se llaman y a menudo no aceptan argumentos. Por simplicidad, se puede considerar que los objetos son datos que están disponibles dentro del método. Por ejemplo, el método `toLowerCase()` de una cadena de texto toma la cadena original, la transforma y devuelve el resultado. + +Por cierto, `System.out.println()` es un método del objeto `out`, que se encuentra dentro de la clase `System`. + +## Llamadas a métodos estáticos + +Pero no todas las llamadas a métodos están relacionadas con objetos: a veces hay una acción pero no hay un objeto específico. En estos casos se utilizan **métodos estáticos**. + +¿Qué puede ser esto? Operaciones matemáticas con números o acciones que no están relacionadas con un objeto específico, sino que se aplican a todos los objetos de un determinado tipo. En este caso, el método casi siempre se basa en los datos que se pasan como parámetros: + +```java +// Obtiene un número aleatorio, llamada directa a través de la clase Math +Math.random(); + +// Lee los datos de la ruta especificada +Files.readString(path); +``` + +En este caso, las clases `Math` y `Files` solo se necesitan para realizar la llamada, ya que los métodos están definidos dentro de ellas. Java no permite definir métodos fuera de las clases. + +Para ser honestos, no todo es tan sencillo. Siempre se puede imaginar algún objeto sobre el cual se realiza un cálculo. Lo contrario también es cierto: siempre se puede prescindir de los objetos. Hay lenguajes en los que no existen objetos en absoluto. Al final, todo depende de quien diseñe la parte específica del código: + +```java +// Sin objeto, método estático +Files.readString(path); + +// Aunque también se podría hacer a través de un objeto de archivo +path.read(); +``` + +## Conclusiones + +* Los métodos estáticos no están relacionados con objetos específicos y se llaman directamente desde la clase +* Los métodos no estáticos construyen su lógica en relación a los datos del objeto mismo y se llaman en objetos específicos + +Todo esto nos lleva suavemente a la posibilidad de crear nuestras propias clases, objetos y métodos, sin los cuales no se puede imaginar ningún programa, ni siquiera uno pequeño. diff --git a/modules/35-methods-using/500-methods-variants/es/data.yml b/modules/35-methods-using/500-methods-variants/es/data.yml new file mode 100644 index 00000000..3253e872 --- /dev/null +++ b/modules/35-methods-using/500-methods-variants/es/data.yml @@ -0,0 +1 @@ +name: Métodos disponibles diff --git a/modules/35-methods-using/500-methods-variants/ru/EXERCISE.md b/modules/35-methods-using/500-methods-variants/ru/EXERCISE.md new file mode 100644 index 00000000..d6062e83 --- /dev/null +++ b/modules/35-methods-using/500-methods-variants/ru/EXERCISE.md @@ -0,0 +1,7 @@ + +В переменной `emoji` находится текстовый грустный смайлик *-(*. Ваша задача — сделать этот смайлик веселым с помощью двух преобразований: + + * Добавить слева глаза *:* + * Заменить *(* на *)* (с помощью метода строки `replace()`) + +Должно получиться: *:-)*. Выведите его на экран. diff --git a/modules/35-methods-using/500-methods-variants/ru/README.md b/modules/35-methods-using/500-methods-variants/ru/README.md new file mode 100644 index 00000000..d60452be --- /dev/null +++ b/modules/35-methods-using/500-methods-variants/ru/README.md @@ -0,0 +1,73 @@ +Одна из базовых тем в Java, на которой строится код – классы и объекты. Они появляются буквально с первых строчек кода, но изучить их и начать использовать не совсем просто. Поэтому изучение объектов и классов растягивается на множество уроков. В этом уроке мы чуть больше окунемся в устройство языка. Не переживайте, если пазл все еще не складывается — это нормально. Классы, объекты и методы – сложная тема, требующая времени. + +Мы уже сталкивались с методами, встроенными в Java, в разных формах: + +```java +System.out.println(); +varname.toLowerCase(); +varname.substring(); +Integer.parseInt(); +ChronoUnit.DAYS.between(); +``` + +Все подобные вызовы можно разбить на две группы: + +1. Вызовы методов у объектов, таких как строки +2. Вызовы статических методов, которые не связаны с конкретными объектами + +## Вызовы методов у объектов + +Из объектов мы пока сталкивались только со строками, но принцип одинаковый для любых объектов: + +```java +// Синтаксис создания объекта +// new – создает новый объект класса +var user = new User(); + +// Извлекает имя у пользователя +user.getName(); + +// Пример с другими объектами + +// Извлекает текущий день +currentDate.getDayOfMonth(); +// Проверка того, что файл существует +file.exists(); +``` + +Такие методы выполняют действия над объектами, у которых они вызываются, и часто не принимают никаких аргументов. Объекты для простоты можно воспринимать как данные, которые доступны внутри метода. Например, метод строки `toLowerCase()` внутри себя берет исходную строку, преобразует ее и возвращает результат наружу. + +Кстати, `System.out.println()` — это метод объекта `out`, который лежит внутри класса `System`. + +## Вызовы статических методов + +Но не все вызовы методов связаны с объектами: иногда действие есть, а объекта нет. В таких случаях используются **статические методы**. + +Что это может быть? Математические операции над числами или какие-то действия, которые не относятся к конкретному объекту, а имеют отношение ко всем объектам данного типа. В таком случае метод почти всегда опирается на данные, которые приходят в виде параметров: + +```java +// Получение случайного числа, вызов напрямую из класса Math +Math.random(); + +// Чтение данных по указанному пути +Files.readString(path); +``` + +Классы `Math` и `Files` в данном случае нужны только для вызова, потому что методы определены внутри них. Java не позволяет определять методы вне классов. + +Честно говоря, не все так просто. Всегда можно придумать какой-то объект, над которым происходит вычисление. Также верно и обратное: всегда можно обойтись без объектов. Есть языки, в которых объектов нет вообще. В итоге все решает тот, кто проектирует конкретную часть кода: + +```java +// Без объекта, статический метод +Files.readString(path); + +// Хотя можно было бы и через объект файла +path.read(); +``` + +## Выводы + +* Статические методы не связаны с конкретными объектами и вызываются из класса напрямую +* Нестатические методы строят свою логику относительно данных самого объекта и вызываются у конкретных объектов + +Все это плавно подводит нас к возможности самостоятельно создавать классы, объекты и методы, без чего невозможно себе представить ни одну программу, даже небольшую. diff --git a/modules/35-methods-using/500-methods-variants/ru/data.yml b/modules/35-methods-using/500-methods-variants/ru/data.yml new file mode 100644 index 00000000..2bac02a1 --- /dev/null +++ b/modules/35-methods-using/500-methods-variants/ru/data.yml @@ -0,0 +1 @@ +name: Какие бывают методы diff --git a/modules/40-methods-definition/100-method-definition-static/es/EXERCISE.md b/modules/40-methods-definition/100-method-definition-static/es/EXERCISE.md new file mode 100644 index 00000000..22d13e56 --- /dev/null +++ b/modules/40-methods-definition/100-method-definition-static/es/EXERCISE.md @@ -0,0 +1,11 @@ + +Implementa un método estático llamado `printMotto()` que muestre en la pantalla la frase *Winter is coming*. + +```java +// La clase App ya está definida +App.printMotto(); // => Winter is coming +``` + +Para que podamos llamar a este método desde fuera, debemos marcarlo no solo con la palabra clave `static`, sino también con `public`. + +En los ejercicios en los que se requiere implementar un método, no es necesario llamar a ese método. Las pruebas automatizadas se encargarán de llamar al método y comprobar su funcionalidad. El ejemplo de llamada anterior se muestra solo para que entiendas cómo se utilizará tu método. diff --git a/modules/40-methods-definition/100-method-definition-static/es/README.md b/modules/40-methods-definition/100-method-definition-static/es/README.md new file mode 100644 index 00000000..c0d30353 --- /dev/null +++ b/modules/40-methods-definition/100-method-definition-static/es/README.md @@ -0,0 +1,82 @@ +La definición de métodos propios simplifica en gran medida la escritura y el mantenimiento de programas. Por ejemplo, los métodos permiten combinar operaciones compuestas en una sola. + +Por ejemplo, enviar un correo electrónico en un sitio web es un proceso bastante complejo que implica interactuar con Internet. Se puede definir un método y ocultar toda la complejidad detrás de una sola construcción simple: + +```java +// Lugar donde se encuentra el método +import com.example.Mailer; + +var email = "support@hexlet.io"; +var title = "Ayuda"; +var body = "He escrito una historia de éxito, ¿cómo puedo obtener un descuento?"; + +// Mailer - nombre de la clase en la que se define el método send() +// Una pequeña llamada - y mucha lógica interna +Mailer.send(email, title, body); +``` + +Este tipo de llamada realiza bastante lógica interna. Se conecta al servidor de correo, forma una solicitud correcta basada en el encabezado y el cuerpo del mensaje, y luego lo envía todo, sin olvidar cerrar la conexión. + +## Cómo crear métodos + +Crearemos nuestro primer método. Su tarea es mostrar la fecha actual en la pantalla: + +
+Hoy es: 2021-10-25 ++ +```java +import java.time.LocalDate; + +// Definición del método +// La definición no llama ni ejecuta el método +// Solo estamos diciendo que ahora existe este método +public class App { + public static void showCurrentDate() { + // Método incorporado en Java para obtener la fecha y hora actual + var currentDate = LocalDate.now(); + var text = "Hoy es: " + currentDate; + System.out.println(text); + } +} + +// Llamada al método +// Es obligatorio especificar el nombre de la clase +App.showCurrentDate(); // => Hoy es: 2021-10-25 +``` + +https://replit.com/@hexlet/java-basics-methods-definition + +La definición de un método en Java implica muchas acciones que iremos viendo gradualmente. + +Se pueden dividir en dos grupos: + +* Lo que afecta el funcionamiento del propio método +* Cómo se ve este método fuera de la clase + +La visibilidad está determinada por la palabra *public*. Esto permite llamar a los métodos desde fuera de la clase, como en el ejemplo anterior. Además de *public*, existe *private*, que se explica en Hexlet en el curso de [POO en Java](https://codica.la/courses/java-poo-basics). + +El funcionamiento del método está determinado por: + +* *static* - desvincula el método del objeto y permite llamarlo directamente desde la clase +* *void* se utiliza si el método no devuelve nada. Por ejemplo, esta es la definición del método `System.out.println()`. Si el método devuelve algún dato, en lugar de *void* se especifica el tipo de dato devuelto + +A diferencia de los datos normales, los métodos realizan acciones, por lo que sus nombres casi siempre deben ser verbos: "construir algo", "dibujar algo", "abrir algo". + +Todo lo que se describe dentro de las llaves `{}` se llama **cuerpo del método**. Dentro del cuerpo se puede escribir cualquier código. Considéralo como un pequeño programa independiente, un conjunto de instrucciones arbitrarias. + +El cuerpo se ejecuta exactamente en el momento en que se inicia el método. Además, cada llamada al método ejecuta el cuerpo de forma independiente de otras llamadas. Por cierto, el cuerpo puede estar vacío: + +```java +// Definición mínima del método +public class App { + public static void noop() { + // Aquí podría haber código, pero no lo hay + // Presta atención a la indentación + // Para mayor legibilidad, cualquier código dentro del cuerpo se desplaza a la derecha en 4 espacios + } +} +App.noop(); +``` + +El concepto de "crear un método" tiene muchos sinónimos: "implementar", "definir" e incluso "implementar". Todos estos términos se encuentran en la práctica diaria en el trabajo. diff --git a/modules/40-methods-definition/100-method-definition-static/es/data.yml b/modules/40-methods-definition/100-method-definition-static/es/data.yml new file mode 100644 index 00000000..d43307f5 --- /dev/null +++ b/modules/40-methods-definition/100-method-definition-static/es/data.yml @@ -0,0 +1,4 @@ +name: Creación (definición) de un método +tips: + - | + [Naming in Programming](https://codica.la/blog/naming-in-programming) diff --git a/modules/40-methods-definition/100-method-definition-static/ru/EXERCISE.md b/modules/40-methods-definition/100-method-definition-static/ru/EXERCISE.md new file mode 100644 index 00000000..48ac8f2d --- /dev/null +++ b/modules/40-methods-definition/100-method-definition-static/ru/EXERCISE.md @@ -0,0 +1,11 @@ + +Реализуйте статический метод с именем `printMotto()`, который выведет на экран фразу *Winter is coming*. + +```java +// Класс App уже определен +App.printMotto(); // => Winter is coming +``` + +Чтобы мы могли вызвать этот метод снаружи, нужно его пометить не только ключевым словом `static`, но еще и `public`. + +В задачах, в которых нужно реализовать метод, этот метод вызывать не нужно. Вызывать метод будут автоматизированные тесты, которые проверяют его работоспособность. Пример с вызовом выше показан только для того, чтобы вы понимали, как ваш метод будет использоваться. diff --git a/modules/40-methods-definition/100-method-definition-static/ru/README.md b/modules/40-methods-definition/100-method-definition-static/ru/README.md new file mode 100644 index 00000000..ecfa1404 --- /dev/null +++ b/modules/40-methods-definition/100-method-definition-static/ru/README.md @@ -0,0 +1,82 @@ +Определение собственных методов значительно упрощает написание и поддержку программ. Например, методы позволяют объединять составные операции в одну. + +К примеру, отправка письма на сайте — это достаточно сложный процесс, включающий в себя взаимодействие с интернетом. Можно определить метод и скрыть всю сложность за одной простой конструкцией: + +```java +// Место откуда берется метод +import com.example.Mailer; + +var email = "support@hexlet.io"; +var title = "Помогите"; +var body = "Я написал историю успеха, как я могу получить скидку?"; + +// Mailer – имя класса, в котором определен метод send() +// Один маленький вызов — и много логики внутри +Mailer.send(email, title, body); +``` + +Внутри себя подобный вызов выполняет довольно много логики. Он соединяется с почтовым сервером, формирует правильный запрос на основе заголовка и тела сообщения, а затем все это отправляет, не забыв закрыть соединение. + +## Как создавать методы + +Создадим наш первый метод. Его задача — вывести на экран текущую дату: + +
+Today is: 2021-10-25 ++ +```java +import java.time.LocalDate; + +// Определение метода +// Определение не вызывает и не выполняет метод +// Мы лишь говорим, что теперь такой метод существует +public class App { + public static void showCurrentDate() { + // Встроенный метод в Java для получения текущего времени и даты + var currentDate = LocalDate.now(); + var text = "Today is: " + currentDate; + System.out.println(text); + } +} + +// Вызов метода +// Обязательно указывать имя класса +App.showCurrentDate(); // => Today is: 2021-10-25 +``` + +https://replit.com/@hexlet/java-basics-methods-definition + +Определение метода в Java включает в себя много действий, которые мы постепенно разберем. + +Их можно разделить на две группы: + +* То, что влияет на работу самого метода +* То, как этот метод видим за пределами класса + +За видимость отвечает слово *public*. Оно дает возможность вызывать методы снаружи класса, как в примере выше. Кроме него существует *private*, который разбирается на Хекслете в курсе по [ООП в Java](https://ru.hexlet.io/courses/java-oop-basics). + +За работу метода отвечают: + +* *static* — отвязывает метод от объекта и делает возможным его вызов напрямую из класса +* *void* используется, если метод ничего не возвращает. Например, такое определение у метода `System.out.println()`. Если метод возвращает какие-то данные, то вместо *void* указывается тип возвращаемых данных + +В отличие от обычных данных, методы выполняют действия, поэтому их имена практически всегда должны быть глаголами: «построить что-то», «нарисовать что-то», «открыть что-то». + +Все, что описывается внутри фигурных скобок `{}`, называется **телом метода**. Внутри тела можно описывать любой код. Считайте, что это маленькая самостоятельная программа, набор произвольных инструкций. + +Тело выполняется ровно в тот момент, когда запускается метод. Причем каждый вызов метода запускает тело независимо от других вызовов. Кстати, тело может быть пустым: + +```java +// Минимальное определение метода +public class App { + public static void noop() { + // Тут мог бы быть код, но его нет + // Обратите внимание на отступы + // Для читаемости, любой код внутри тела сдвигается вправо на 4 пробела + } +} +App.noop(); +``` + +Понятие «создать метод» имеет много синонимов: «реализовать», «определить» и даже «заимплементить». Все эти термины встречаются в повседневной практике на работе. diff --git a/modules/40-methods-definition/100-method-definition-static/ru/data.yml b/modules/40-methods-definition/100-method-definition-static/ru/data.yml new file mode 100644 index 00000000..373010c1 --- /dev/null +++ b/modules/40-methods-definition/100-method-definition-static/ru/data.yml @@ -0,0 +1,5 @@ +name: Создание (определение) метода +tips: + - > + [Именование в + программировании](https://ru.hexlet.io/blog/posts/naming-in-programming) diff --git a/modules/40-methods-definition/150-method-main/es/EXERCISE.md b/modules/40-methods-definition/150-method-main/es/EXERCISE.md new file mode 100644 index 00000000..f9a92ea7 --- /dev/null +++ b/modules/40-methods-definition/150-method-main/es/EXERCISE.md @@ -0,0 +1,11 @@ + +Implementa una clase llamada `App` con dos métodos: + +1. El método `gogo()`, que imprime en la pantalla la cadena `It works!` +2. El método `main()`, como se define arriba, que llama al método `gogo()` + +El resultado de llamar a `main()` en este caso será: + +```java +// => "It works!" +``` diff --git a/modules/40-methods-definition/150-method-main/es/README.md b/modules/40-methods-definition/150-method-main/es/README.md new file mode 100644 index 00000000..9dd0ea02 --- /dev/null +++ b/modules/40-methods-definition/150-method-main/es/README.md @@ -0,0 +1,95 @@ +Es posible que te sorprendas, pero a lo largo de todas las lecciones anteriores, hemos estado creando nuestro propio método. El esqueleto del método ya estaba escrito de antemano, y se te pedía que añadieras su cuerpo. La práctica se veía así: + +```java +public class App { + public static void main(String[] args) { + // BEGIN + // Aquí escribías tu código + // END + } +} +``` + +¿Por qué creamos un método? Java está diseñado de tal manera que no se puede ejecutar código fuera de los métodos. No puedes simplemente escribir código a nivel de archivo y ejecutarlo. El compilador mostrará un error: + +```java +// El archivo con este código no se compila +System.out.println("Aunque parezca mentira"); +``` + +Pero este código funcionará: + +```java +public class App { + public static void main(String[] args) { + System.out.println("Aunque parezca mentira"); + } +} +``` + +En tu trabajo, a menudo verás ejemplos fuera de los métodos. ¿Por qué hacemos esto? Únicamente por conveniencia. + +Si envolvemos cada línea de código en una clase y un método, el volumen de ruido y material aumentará significativamente. Siempre ten esto en cuenta, ya que los creadores de estos materiales asumen que entiendes cómo funciona Java. + +Si ves código que se ejecuta sin métodos, siempre añade la envoltura como se muestra arriba. Así podrás ejecutar fácilmente ese código, por ejemplo, localmente. + +## Método main + +¿Por qué el método en nuestros ejemplos se llama `main`? Podríamos haber escrito un ejemplo como este: + +```java +public class App { + // run - el nombre se elige arbitrariamente + // el nombre puede ser cualquier cosa que el autor del código quiera + public static void run() { + // aquí hay algún código + } +} +``` + +Podríamos haberlo hecho así, y todo funcionaría, pero hay un detalle. En esta forma, el método `main`, tal como lo definimos, tiene un significado especial para Java. + +Java lo llama automáticamente cuando se ejecuta el programa desde la consola: + +```bash +# El archivo App contiene una clase llamada App +java App.java # compila y ejecuta +# Dentro se ejecutará el método App.main, si está definido +``` + +Otros métodos no se llaman automáticamente. Es por eso que siempre usamos `main`, ya que así puedes fácilmente llevar el código del entrenador a tu editor y ejecutarlo. + +¿Es obligatorio definirlo? No, Java no impone ninguna restricción sobre qué métodos y cuántos métodos defines en una clase. Tampoco hay restricciones sobre la cantidad y los nombres de las clases. + +Para simplificar, siempre usamos el nombre `App`, pero en el código real encontrarás miles de nombres y clases diferentes. Aunque con la condición de que en un archivo haya exactamente una clase: + +```java +class MySuperClassName { + public static void oneMethod() { + } + public static void twoMethod() { + } + public static void threeMethod() { + } +} +``` + +Hablaremos de esto en el curso de [POO en Java](https://codica.la/courses/java-poo-basics). + +Lo más importante que debes recordar ahora es que cualquier método estático se llama usando un punto después del nombre de la clase, y las llamadas en sí se realizan dentro de otros métodos: + +```java +// Solo un ejemplo de llamadas de métodos entre sí +class MySuperClassName { + public static void oneMethod() { + MySuperClassName.twoMethod(); + } + + public static void twoMethod() { + MySuperClassName.threeMethod(); + } + + public static void threeMethod() { + } +} +``` diff --git a/modules/40-methods-definition/150-method-main/es/data.yml b/modules/40-methods-definition/150-method-main/es/data.yml new file mode 100644 index 00000000..7f3f43be --- /dev/null +++ b/modules/40-methods-definition/150-method-main/es/data.yml @@ -0,0 +1 @@ +name: Método main diff --git a/modules/40-methods-definition/150-method-main/ru/EXERCISE.md b/modules/40-methods-definition/150-method-main/ru/EXERCISE.md new file mode 100644 index 00000000..ec9f59b2 --- /dev/null +++ b/modules/40-methods-definition/150-method-main/ru/EXERCISE.md @@ -0,0 +1,11 @@ + +Реализуйте класс с именем `App` и двумя методами: + +1. Метод `gogo()`, который печатает на экран строку `It works!` +2. `main()`, как в определении выше, который вызывает метод `gogo()` + +Результат вызова `main()` в таком случае будет таким: + +```java +// => "It works!" +``` diff --git a/modules/40-methods-definition/150-method-main/ru/README.md b/modules/40-methods-definition/150-method-main/ru/README.md new file mode 100644 index 00000000..3bdf94c6 --- /dev/null +++ b/modules/40-methods-definition/150-method-main/ru/README.md @@ -0,0 +1,96 @@ +Возможно вы удивитесь, но на протяжении всех предыдущих уроков, мы создавали свой собственный метод. Каркас метода был заранее написан, а от вас требовалось добавить его тело. Практика выглядела так: + +```java +public class App { + public static void main(String[] args) { + // BEGIN + // А здесь вы писали свой код + // END + } +} +``` + +Зачем мы создавали метод? Java так устроена, что в ней невозможно выполнять код вне методов. Вы не можете просто написать код на уровне файла и запустить его. Компилятор выдаст ошибку: + +```java +// Файл с таким кодом не компилируется +System.out.println("Хотя казалось бы"); +``` + +А вот такой код уже сработает: + +```java +public class App { + public static void main(String[] args) { + System.out.println("Хотя казалось бы"); + } +} +``` + +В работе вы часто будете видеть примеры вне методов. Почему мы и другие так делают? Исключительно для удобства. + +Если на каждую строчку добавлять обертку в виде класса и метода, то объем шума и материала вырастет значительно. Всегда учитывайте это, ведь создатели этих материалов рассчитывают на то, что вы понимаете как работает Java. + +Видите код, который вызывается без методов, всегда добавляйте обертку, как показано выше. Тогда вы легко сможете запустить этот код, например, локально. + +## Метод main + +Почему метод в наших примерах называется `main`? Мы ведь могли написать какой-то такой пример: + +```java +public class App { + // run - имя выбрано произвольно + // имя может быть любым, как захочет автор кода + public static void run() { + // здесь какой-то код + } +} +``` + +Мы могли бы так сделать, и все бы работало, но есть один момент. В таком виде метод `main`, как мы его определяем, имеет особенное значение для Java. + +Java автоматически его вызывает, когда программа запускается из консоли: + +```bash +# В файле App находится класс с именем App +java App.java # компилирует и запускает на исполнение +# Внутри запустится метод App.main, если он определен +``` + +Любой другой метод автоматически не вызывается. Именно поэтому мы везде используем `main`, ведь так можно легко перенести код из тренажера к себе в редактор и запустить его на выполнение. + +Обязательно ли его определять? Нет, Java не накладывает никакого ограничения на то, какие и сколько методов вы определите в классе. +Так же как и нет ограничения на количество и имена классов. + +Для простоты мы всегда используем имя `App`, но в реальном коде вы встретите тысячи разных имен и классов. Правда с условием, что в одном файле находится ровно один класс: + +```java +class MySuperClassName { + public static void oneMethod() { + } + public static void twoMethod() { + } + public static void threeMethod() { + } +} +``` + +Об этом мы поговорим в курсе по [ООП в Java](https://ru.hexlet.io/courses/java-oop-basics). + +Главное, что нужно сейчас запомнить — любые статические методы вызываются через точку после имени класса, а сами вызовы происходят внутри других методов: + +```java +// Просто пример вызовов методов друг из друга +class MySuperClassName { + public static void oneMethod() { + MySuperClassName.twoMethod(); + } + + public static void twoMethod() { + MySuperClassName.threeMethod(); + } + + public static void threeMethod() { + } +} +``` diff --git a/modules/40-methods-definition/150-method-main/ru/data.yml b/modules/40-methods-definition/150-method-main/ru/data.yml new file mode 100644 index 00000000..bf9effaa --- /dev/null +++ b/modules/40-methods-definition/150-method-main/ru/data.yml @@ -0,0 +1 @@ +name: Метод main diff --git a/modules/40-methods-definition/200-method-definition-return/es/EXERCISE.md b/modules/40-methods-definition/200-method-definition-return/es/EXERCISE.md new file mode 100644 index 00000000..d1d786e8 --- /dev/null +++ b/modules/40-methods-definition/200-method-definition-return/es/EXERCISE.md @@ -0,0 +1,7 @@ + +Implementa un método estático llamado `sayHurrayThreeTimes()` que devuelva la cadena 'hurray! hurray! hurray!'. + +```java +var viva = App.sayHurrayThreeTimes(); +System.out.println(viva); // => hurray! hurray! hurray! +``` diff --git a/modules/40-methods-definition/200-method-definition-return/es/README.md b/modules/40-methods-definition/200-method-definition-return/es/README.md new file mode 100644 index 00000000..d713af46 --- /dev/null +++ b/modules/40-methods-definition/200-method-definition-return/es/README.md @@ -0,0 +1,137 @@ +Los métodos que definimos en las lecciones anteriores finalizaban su trabajo imprimiendo algunos datos en la pantalla: + +```java +public class App { + public static void saludo() { + System.out.println("Se acerca el invierno"); + } +} +``` + +No hay mucho beneficio de tales métodos, ya que sus resultados no pueden ser utilizados dentro del programa. + +Veamos esto con un ejemplo. Tomemos la tarea de procesar correos electrónicos. Cuando un usuario se registra en un sitio web, puede ingresar su correo electrónico de cualquier manera: + +* Agregar espacios aleatorios al principio o al final `_soporte@hexlet.io__` +* Usar letras en diferentes casos `SOPORTE@hexlet.io` + +Si guardamos la dirección en esta forma en la base de datos, el usuario no podrá iniciar sesión en el sitio web si ingresa la dirección sin espacios y en un caso diferente. + +Para evitar que esto suceda, la dirección debe prepararse para su almacenamiento en la base de datos, es decir, convertirse a minúsculas y recortarse los espacios al principio y al final de la cadena. La tarea completa se puede resolver en un par de líneas: + +```java +class App { + public static void main(String[] args) { + // Obtén la dirección del formulario + var correo = " SoPORTE@hexlet.IO"; + // Recorta los caracteres de espacio en blanco + var correoRecortado = correo.trim(); + // Conviértelo a minúsculas + var correoPreparado = correoRecortado.toLowerCase(); + System.out.println(correoPreparado); // => soporte@hexlet.io + // Guardar en la base de datos + } +} +``` + +Este código se volvió posible solo gracias al valor de retorno. Los métodos `trim()` y `toLowerCase()` no imprimen nada en la pantalla. Ellos **devuelven** el resultado de su trabajo, por lo que podemos asignarlo a variables. Si en lugar de devolver el resultado, imprimieran en la pantalla, no podríamos asignar el resultado de su trabajo a una variable. Tal como no podemos hacerlo con el método `saludo()` definido arriba: + +```java +// Java se quejará de que `saludo()` no devuelve nada +// El código no funcionará +var mensaje = App.saludo(); +``` + +Modifiquemos el método `saludo()` para que comience a devolver datos en lugar de imprimirlos. Para hacerlo, necesitamos hacer dos cambios: + +* Especificar el tipo de datos de retorno, en este caso, es una cadena `String` +* Usar la instrucción `return` en lugar de imprimir en la pantalla + +Veamos el código modificado: + +```java +class App { + public static String saludo() { + return "¡Se acerca el invierno!"; + } +} +``` + +En lugar de `void`, ahora tenemos `String` porque el método tiene un valor de retorno. De esta manera, le decimos a Java que el resultado del trabajo del método será una cadena. + +También presta atención a la instrucción `return`, es una instrucción especial. Toma la expresión a la derecha y la pasa al código que llamó al método. Tan pronto como Java encuentra `return`, la ejecución del método termina: + +```java +// Ahora este código funciona +var mensaje = App.saludo(); +// Podemos realizar algunas acciones en el resultado +System.out.println(mensaje.toUpperCase()); // => ¡SE ACERCA EL INVIERNO! +``` + +Cualquier código después de `return` no se ejecuta: + +```java +class App { + public static String saludo() { + return "¡Se acerca el invierno!"; + // Ningún código debajo se ejecutará nunca + // El código inalcanzable en Java ni siquiera compilará + System.out.println("Nunca seré ejecutado"); + } +} +``` + +Incluso si un método devuelve datos, esto no lo limita para imprimir. Además de devolver datos, también podemos imprimirlos: + +```java +class App { + public static String saludo() { + System.out.println("Apareceré en la consola"); + return "¡Se acerca el invierno!"; + } +} + +// En algún lugar en otro método del programa +// imprimirá el texto en la pantalla y devolverá el valor +var valor = App.saludo(); +``` + +Es posible devolver no solo un valor específico. Dado que `return` funciona con expresiones, casi cualquier cosa puede aparecer a la derecha de él. Aquí debemos seguir los principios de legibilidad del código: + +```java +class App { + public static String saludo() { + var mensaje = "¡Se acerca el invierno!"; + return mensaje; + } +} +``` + +Aquí, no estamos devolviendo la variable en sí, siempre estamos devolviendo el valor que está almacenado en esta variable. A continuación, hay un ejemplo con cálculos: + +```java +class App { + public static long dobleCinco() { + // o return 5 + 5; + var resultado = 5 + 5; + return resultado; + } +} +``` + +En este ejemplo, se utilizó `long` en la definición del método porque se devuelve un entero. + +Para poner a prueba tus conocimientos de esta lección, intenta responder la pregunta. ¿Qué crees que mostrará este código? + +```java +// Definición +class App { + public static int ejecutar() { + return 5; + return 10; + } +} + +// Uso +App.ejecutar(); // => ? +``` diff --git a/modules/40-methods-definition/200-method-definition-return/es/data.yml b/modules/40-methods-definition/200-method-definition-return/es/data.yml new file mode 100644 index 00000000..0091c594 --- /dev/null +++ b/modules/40-methods-definition/200-method-definition-return/es/data.yml @@ -0,0 +1 @@ +name: Valores de Retorno diff --git a/modules/40-methods-definition/200-method-definition-return/ru/EXERCISE.md b/modules/40-methods-definition/200-method-definition-return/ru/EXERCISE.md new file mode 100644 index 00000000..4cf468e2 --- /dev/null +++ b/modules/40-methods-definition/200-method-definition-return/ru/EXERCISE.md @@ -0,0 +1,7 @@ + +Реализуйте статический метод `sayHurrayThreeTimes()`, которая возвращает строку 'hurray! hurray! hurray!'. + +```java +var hurray = App.sayHurrayThreeTimes(); +System.out.println(hurray); // => hurray! hurray! hurray! +``` diff --git a/modules/40-methods-definition/200-method-definition-return/ru/README.md b/modules/40-methods-definition/200-method-definition-return/ru/README.md new file mode 100644 index 00000000..57ce0619 --- /dev/null +++ b/modules/40-methods-definition/200-method-definition-return/ru/README.md @@ -0,0 +1,139 @@ +Методы, которые мы определяли в предыдущих уроках, заканчивали свою работу тем, что печатали на экран какие-то данные: + +```java +public class App { + public static void greeting() { + System.out.println("Winter is coming"); + } +} +``` + +Пользы от таких методов не очень много, ведь результатом их работы невозможно воспользоваться внутри программы. + +Рассмотрим это на примере. Возьмем задачу обработки электронной почты. Когда пользователь регистрируется на каком-то сайте, то он может ввести почту любым способом: + +* Добавить случайно пробелы в начале или в конце `_support@hexlet.io__` +* Использовать буквы в разном регистре `SUPPORT@hexlet.io` + +Если мы сохраним адрес в таком виде в базу данных, то пользователь не сможет войти на сайт, если будет вбивать адрес без пробелов и в другом регистре. + +Чтобы этого не произошло, адрес нужно подготовить к записи в базу — привести его к нижнему регистру и обрезать пробелы по краям строки. Вся задача решается в пару строчек: + +```java +class App { + public static void main(String[] args) { + // Получаем адрес из формы + var email = " SuppORT@hexlet.IO"; + // Обрезаем пробельные символы + var trimmedEmail = email.trim(); + // Приводим к нижнему регистру + var preparedEmail = trimmedEmail.toLowerCase(); + System.out.println(preparedEmail); // => support@hexlet.io + // Записываем в базу данных + } +} +``` + +Этот код стал возможен только благодаря возврату значения. Методы `trim()` и `toLowerCase()` ничего не печатают на экран. Они **возвращают** результат своей работы, и поэтому мы можем записать его в переменные. Если бы они вместо этого печатали на экран, мы бы не могли присвоить результат их работы переменной. Как мы не можем сделать с определенным выше методом `greeting()`: + +```java +// Java будет ругаться, что `greeting()` ничего не возвращает +// Код не заработает +var message = App.greeting(); +``` + +Изменим метод `greeting()` таким образом, чтобы он начал возвращать данные, а не печатать их. Для этого нам понадобится выполнить две правки: + +* Описать тип возвращаемых данных — здесь это строка `String` +* Выполнить возврат вместо печати на экран + +Посмотрим на измененный код: + +```java +class App { + public static String greeting() { + return "Winter is coming!"; + } +} +``` + +Вместо `void` теперь написано `String`, потому что у метода есть возврат. Так мы указали Java, что результатом работы метода будет строка. + +Еще обратите внимание на `return` – это особая инструкция. Она берет выражение справа и отдает его наружу тому коду, который вызвал метод. Как только Java натыкается на `return`, выполнение метода на этом завершается: + +```java +// Теперь этот код работает +var message = App.greeting(); +// Мы можем выполнить какие-то действия над результатом +System.out.println(message.toUpperCase()); // => WINTER IS COMING! +``` + +Любой код после `return` не выполняется: + +```java +class App { + public static String greeting() { + return "Winter is coming!"; + // Любой код ниже не выполнится никогда + // Недостижимый код в Java даже не скомпилируется + System.out.println("Я никогда не выполнюсь"); + } +} +``` + +Даже если метод возвращает данные, это не ограничивает его в том, что он печатает. Кроме возврата данных, мы можем и печатать их: + +```java +class App { + public static String greeting() { + System.out.println("Я появлюсь в консоли"); + return "Winter is coming!"; + } +} + +// Где-то в другом методе программа +// и напечатает текст на экран, и вернет значение +var value = App.greeting(); +``` + +Возвращать можно не только конкретное значение. Так как `return` работает с выражениями, то справа от него может появиться почти что угодно. Здесь нужно руководствоваться принципами читаемости кода: + +```java +class App { + public static String greeting() { + var message = "Winter is coming!"; + return message; + } +} +``` + +Здесь мы не возвращаем переменную — возвращается всегда значение, которое находится в этой переменной. Ниже пример с вычислениями: + +```java +class App { + public static long doubleFive() { + // или return 5 + 5; + var result = 5 + 5; + return result; + } +} +``` + +https://replit.com/@hexlet/java-basics-return + +В этом примере в определении метода использовался `long`, так как возвращается целое число. + +Чтобы проверить знания из этого урока, попробуйте ответить на вопрос. Как думаете, что выведет этот код? + +```java +// Определение +class App { + public static int run() { + return 5; + return 10; + } +} + +// Использование +App.run(); // => ? +``` diff --git a/modules/40-methods-definition/200-method-definition-return/ru/data.yml b/modules/40-methods-definition/200-method-definition-return/ru/data.yml new file mode 100644 index 00000000..cb100e99 --- /dev/null +++ b/modules/40-methods-definition/200-method-definition-return/ru/data.yml @@ -0,0 +1 @@ +name: Возврат значений diff --git a/modules/40-methods-definition/300-method-definition-parameters/es/EXERCISE.md b/modules/40-methods-definition/300-method-definition-parameters/es/EXERCISE.md new file mode 100644 index 00000000..7a5d7e1d --- /dev/null +++ b/modules/40-methods-definition/300-method-definition-parameters/es/EXERCISE.md @@ -0,0 +1,29 @@ + +Implementa el método estático `App.truncate()`, que recorta la cadena pasada como parámetro hasta el número de caracteres especificado, agrega puntos suspensivos al final y devuelve la cadena resultante. Esta lógica se utiliza a menudo en sitios web para mostrar texto largo de forma abreviada. El método recibe dos parámetros: + +1. Una cadena (`String`) que se debe truncar +2. Un número (`int`) de caracteres que se deben conservar + +Aquí tienes un ejemplo de cómo debería funcionar el método que escribas: + +```java +// Pasando el texto directamente +// Se recorta el texto dejando 2 caracteres +App.truncate("hexlet", 2); // he... + +// A través de una variable +var text = "¡funciona!" +// Se recorta el texto dejando 4 caracteres +App.truncate(text, 4); // it w... +``` + +Puedes implementar este método de diferentes maneras, solo te daremos una pista. Para resolverlo de esta manera, necesitarás tomar una subcadena de la cadena pasada como primer parámetro en el método `truncate()`. Utiliza el método [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java) para esto. Piensa, según la tarea, desde qué índice y hasta qué índice debes extraer la subcadena. + + ```java + var text = "bienvenido"; + // Puedes pasar parámetros al método a través de variables + var index = 3; + text.substring(0, index); // bie + ``` + +Desde el punto de vista del sistema de evaluación, no importa qué método uses para implementar `truncate()` internamente, lo importante es que cumpla con la tarea planteada. diff --git a/modules/40-methods-definition/300-method-definition-parameters/es/README.md b/modules/40-methods-definition/300-method-definition-parameters/es/README.md new file mode 100644 index 00000000..a2a390bf --- /dev/null +++ b/modules/40-methods-definition/300-method-definition-parameters/es/README.md @@ -0,0 +1,112 @@ +Los métodos no solo pueden devolver valores, sino también recibirlos como parámetros. Ya nos hemos encontrado con métodos con parámetros muchas veces: + +```java +// Recibe un parámetro de cualquier tipo +System.out.println("soy un parámetro"); +// Recibe un índice y devuelve el carácter correspondiente +"algún texto".charAt(3); // 'n' +// Recibe dos parámetros de tipo cadena +// El primero es lo que buscamos, el segundo es por qué lo reemplazamos +"google".replace("go", "mo"); // "moogle" +// Recibe dos parámetros numéricos +// el primero es el índice inicial (inclusive), el segundo es el índice final (no inclusivo) +"hexlet".substring(1, 3); // "ex" +``` + +En esta lección aprenderemos a crear métodos que reciben parámetros. + +Supongamos que tenemos la tarea de implementar el método estático `App.getLastChar()`. Debe devolver el último carácter de la cadena que se pasa como parámetro. + +Así es como se usaría este método: + +```java +// Pasando parámetros directamente sin variables +App.getLastChar("Hexlet"); // 't' +App.getLastChar("Goo"); // 'o' +// Pasando parámetros a través de variables +var name1 = "Hexlet"; +App.getLastChar(name1); // 't' +var name2 = "Goo"; +App.getLastChar(name2); // 'o' +``` + +De la descripción y los ejemplos de código, podemos hacer las siguientes conclusiones: + +* Necesitamos definir el método estático `getLastChar()` en la clase `App` +* El método debe recibir un parámetro de tipo `String` +* El método debe devolver un valor de tipo `char` + +Para empezar, definamos el método: + +```java +class App { + public static char getLastChar(String str) { + // Calculamos el índice del último carácter como la longitud de la cadena menos 1 + return str.charAt(str.length() - 1); + } +} +``` + +https://replit.com/@hexlet/java-basics-methods-parameters-1 + +Analicemos este código en detalle. `char` nos indica el tipo de valor que se devuelve. Luego, entre paréntesis, se especifica el tipo del parámetro `String` y su nombre `str`. + +Dentro del método, no sabemos con qué valor específico estamos trabajando, por lo que los parámetros siempre se describen como variables. + +El nombre del parámetro puede ser cualquier cosa, no está relacionado con la forma en que se llama al método. Lo importante es que este nombre refleje el significado del valor que contiene. El valor específico del parámetro dependerá de cómo se llame a este método. + +Los parámetros en Java siempre son obligatorios. Si un método requiere parámetros y intentamos escribir código sin ellos, el compilador mostrará un error: + +```sh +App.getLastChar(); // este código no tiene sentido +method getLastChar in class App cannot be applied to given types; + required: String + found: no arguments + reason: actual and formal argument lists differ in length +``` + +De la misma manera, se pueden especificar dos o más parámetros. Cada parámetro se separa por comas: + +```java +class App { + // Método para encontrar el número medio + // El tipo de retorno es double porque + // la división puede dar como resultado un número decimal + public static double average(int x, int y) { + return (x + y) / 2.0; + } +} + +App.average(1, 5); // 3.0 +App.average(1, 2); // 1.5 +``` + +https://replit.com/@hexlet/java-basics-methods-parameters-2 + +Los métodos pueden requerir cualquier cantidad de parámetros que necesiten para funcionar: + +```java +// el primer parámetro es lo que buscamos +// el segundo parámetro es por qué lo reemplazamos +'google'.replace('go', 'mo'); // moogle +``` + +Para crear tales métodos, debemos especificar la cantidad necesaria de parámetros en la definición, separados por comas, dándoles nombres descriptivos. A continuación se muestra un ejemplo de definición del método `replace()`, que reemplaza una parte de una cadena por otra: + +```java +class App { + public static String replace(String text, String from, String to) { + // aquí va el cuerpo del método, pero lo omitimos para no distraernos + } +} + +App.replace('google', 'go', 'mo'); // moogle +``` + +Cuando hay dos o más parámetros, el orden en que se pasan esos parámetros se vuelve importante para casi todos los métodos. Si se cambia el orden, el método se ejecutará de manera diferente: + +```java +// no se reemplaza nada, +// ya que no hay 'mo' dentro de google +App.replace('google', 'mo', 'go'); // google +``` diff --git a/modules/40-methods-definition/300-method-definition-parameters/es/data.yml b/modules/40-methods-definition/300-method-definition-parameters/es/data.yml new file mode 100644 index 00000000..5d13474c --- /dev/null +++ b/modules/40-methods-definition/300-method-definition-parameters/es/data.yml @@ -0,0 +1 @@ +name: Definición de métodos diff --git a/modules/40-methods-definition/300-method-definition-parameters/ru/EXERCISE.md b/modules/40-methods-definition/300-method-definition-parameters/ru/EXERCISE.md new file mode 100644 index 00000000..e105e5f5 --- /dev/null +++ b/modules/40-methods-definition/300-method-definition-parameters/ru/EXERCISE.md @@ -0,0 +1,29 @@ + +Реализуйте статический метод `App.truncate()`, который обрезает переданную строку до указанного количества символов, добавляет в конце многоточие и возвращает получившуюся строку. Подобная логика часто используется на сайтах, чтобы отобразить длинный текст в сокращенном виде. Метод принимает два параметра: + +1. Строка (`String`), которую нужно обрезать +2. Число (`int`) символов, которые нужно оставить + +Пример того, как должен работать написанный вами метод: + +```java +// Передаем текст напрямую +// Обрезаем текст, оставляя 2 символа +App.truncate("hexlet", 2); // he... + +// Через переменную +var text = "it works!" +// Обрезаем текст, оставляя 4 символа +App.truncate(text, 4); // it w... +``` + +Реализовать этот метод можно различными способами, подскажем лишь один из них. Для решения этим способом вам понадобится взять подстроку из строки, переданной первым параметром в метод `truncate()`. Используйте для этого метод [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java). Подумайте, исходя из задания, с какого индекса и по какой вам надо извлечь подстроку? + + ```java + var text = "welcome"; + // Передавать параметры в метод можно через переменные + var index = 3; + text.substring(0, index); // wel + ``` + +С точки зрения проверочной системы не имеет значения, каким из способов будет реализован метод `truncate()` внутри, главное – чтобы он выполнял поставленную задачу diff --git a/modules/40-methods-definition/300-method-definition-parameters/ru/README.md b/modules/40-methods-definition/300-method-definition-parameters/ru/README.md new file mode 100644 index 00000000..7679634e --- /dev/null +++ b/modules/40-methods-definition/300-method-definition-parameters/ru/README.md @@ -0,0 +1,113 @@ +Методы могут не только возвращать значения, но и принимать их в виде параметров. С параметрами методов мы уже сталкивались много раз: + +```java +// Принимает на вход один параметр любого типа +System.out.println("я параметр"); +// Принимает на вход индекс, по которому извлекается символ +"какой-то текст".charAt(3); // 'о' +// Принимает на вход два строковых параметра +// Первый — что ищем, второй — на что меняем +"google".replace("go", "mo"); // "moogle" +// Принимает на вход два числовых параметра +// первый — начальный индекс включительно, второй — конечный индекс не включительно +"hexlet".substring(1, 3); // "ex" +``` + +В этом уроке мы научимся создавать методы, которые принимают на вход параметры. + +Представим, что перед нами стоит задача — реализовать статический метод `App.getLastChar()`. Он должен возвращать последний символ в строке, переданной на вход как параметр. + +Вот как будет выглядеть использование этого метода: + +```java +// Передача параметров напрямую без переменных +App.getLastChar("Hexlet"); // 't' +App.getLastChar("Goo"); // 'o' +// Передача параметров через переменные +var name1 = "Hexlet"; +App.getLastChar(name1); // 't' +var name2 = "Goo"; +App.getLastChar(name2); // 'o' +``` + +Из описания и примеров кода мы можем сделать следующие выводы: + +* Нам нужно определить статический метод `getLastChar()` в классе `App` +* Метод должен принимать на вход один параметр типа `String` +* Метод должен возвращать значение типа `char` + +Для начала определим метод: + +```java +class App { + public static char getLastChar(String str) { + // Вычисляем индекс последнего символа как длина строки, то есть 1 + return str.charAt(str.length() - 1); + } +} +``` + +https://replit.com/@hexlet/java-basics-methods-parameters-1 + +Разберем этот код подробнее. `char` говорит нам о типе возвращаемого значения. Далее в скобках указывается тип параметра `String` и его имя `str`. + +Внутри метода мы не знаем, с каким конкретно значением идет работа, поэтому параметры всегда описываются как переменные. + +Имя параметра может быть любым — оно не связано с тем, как вызывается метод. Главное, чтобы это имя отражало смысл того значения, которое содержится внутри. Конкретное значение параметра будет зависеть от вызова этого метода. + +Параметры в Java всегда обязательны. Если методу нужны параметры, а мы попробуем написать код без параметра, то компилятор выдаст ошибку: + +```sh +App.getLastChar(); // такой код не имеет смысла +method getLastChar in class App cannot be applied to given types; + required: String + found: no arguments + reason: actual and formal argument lists differ in length +``` + +Точно таким же образом можно указывать два и более параметра. Каждый параметр отделяется запятой: + +```java +class App { + // Метод по нахождению среднего числа + // Возвращаемый тип — double, потому что + // при делении может получиться дробное число + public static double average(int x, int y) { + return (x + y) / 2.0; + } +} + +App.average(1, 5); // 3.0 +App.average(1, 2); // 1.5 +``` + +https://replit.com/@hexlet/java-basics-methods-parameters-2 + +Методы могут требовать на вход любое количество параметров, которое им нужно для работы: + +```java +// первый параметр – что ищем +// второй параметр – на что меняем +'google'.replace('go', 'mo'); // moogle +```` + +Для создания таких методов, нужно в определении указать нужное количество параметров через запятую, дав им понятные имена. Ниже пример определения метода `replace()`, который заменяет в слове одну часть строки на другую: + +```java +class App { + public static String replace(String text, String from, String to) { + // здесь тело метода, но мы его + // опускаем, чтобы не отвлекаться + } +} + +App.replace('google', 'go', 'mo'); // moogle +``` + +Когда параметров два и более, то практически для всех методов становится важен порядок передачи этих параметров. Если его поменять, то метод отработает по-другому: + +```java +// ничего не заменилось, +// так как внутри google нет mo +App.replace('google', 'mo', 'go'); // google +``` diff --git a/modules/40-methods-definition/300-method-definition-parameters/ru/data.yml b/modules/40-methods-definition/300-method-definition-parameters/ru/data.yml new file mode 100644 index 00000000..a3781062 --- /dev/null +++ b/modules/40-methods-definition/300-method-definition-parameters/ru/data.yml @@ -0,0 +1 @@ +name: Определение методов diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/es/EXERCISE.md b/modules/40-methods-definition/400-method-definition-default-parameters/es/EXERCISE.md new file mode 100644 index 00000000..6656154d --- /dev/null +++ b/modules/40-methods-definition/400-method-definition-default-parameters/es/EXERCISE.md @@ -0,0 +1,17 @@ + +Implementa el método `getHiddenCard()`, que recibe como entrada el número de una tarjeta de crédito (compuesto por 16 dígitos) como una cadena y devuelve su versión oculta, que se puede utilizar en el sitio web para su visualización. Si la tarjeta original tenía el número *2034399002125581*, entonces la versión oculta se vería así: *\*\*\*\*5581*. En otras palabras, la función reemplaza los primeros 12 caracteres por asteriscos. La cantidad de asteriscos se controla mediante un segundo parámetro opcional. El valor predeterminado es 4. + +```java +// La tarjeta de crédito se pasa como una cadena +App.getHiddenCard("1234567812345678", 2); // "**5678" +App.getHiddenCard("1234567812345678", 3); // "***5678" +App.getHiddenCard("1234567812345678"); // "****5678" +App.getHiddenCard("2034399002121100", 1); // "*1100" +``` + +Para completar esta tarea, necesitarás el método `repeat` de la cadena, que repite la cadena un número determinado de veces. + +```java +"+".repeat(5); // "+++++" +"o".repeat(5); // "ooooo" +``` diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/es/README.md b/modules/40-methods-definition/400-method-definition-default-parameters/es/README.md new file mode 100644 index 00000000..0d2e5f12 --- /dev/null +++ b/modules/40-methods-definition/400-method-definition-default-parameters/es/README.md @@ -0,0 +1,92 @@ + + +En programación, muchas funciones y métodos tienen parámetros que rara vez cambian. + +En estos casos, se les asignan **valores predeterminados** a estos parámetros, que se pueden cambiar según sea necesario. Esto reduce un poco la cantidad de código repetitivo. + +Esto se puede ver claramente en el siguiente ejemplo: + +```java +class App { + // Función de potenciación + // El exponente es el segundo parámetro con un valor predeterminado de 2 + function pow(x, base = 2) { + return x ** base; + } +} + +App.pow(3); // Resultado: 9, ya que se eleva al cuadrado de forma predeterminada +// Elevar al cubo +App.pow(3, 3); // 27 +``` + +A diferencia de otros lenguajes, en Java no es posible asignar un valor predeterminado, pero se puede simular utilizando la **sobrecarga de métodos**. + +¿Qué es la sobrecarga de métodos? Java permite crear varios métodos con el mismo nombre. Estos métodos deben tener: + +* Diferentes tipos de parámetros de entrada +* Diferente cantidad de parámetros +* O ambas cosas a la vez + +Veamos un ejemplo de un método que suma dos números: + +```java +class App { + public static int sum(int x, int y) { + return x + y; + } +} + +App.sum(2, 3); // 5 +``` + +Ahora escribamos otro método `sum()` que solo recibe un parámetro y lo suma con el número 10: + +```java +class App { + public static int sum(int x) { + return x + 10; + } +} + +App.sum(2); // 12 +App.sum(2, 1); // 3 +``` + +El compilador ejecutará este código sin problemas y creará dos métodos con el mismo nombre. ¿Cómo sabe Java qué método utilizar? + +Es muy simple: durante la compilación, se elige la versión del método que coincide en tipo y cantidad de parámetros. Si no se encuentra dicho método, se producirá un error. + +Ya hemos visto al menos un método sobrecargado: `substring()`. Por defecto, extrae una subcadena hasta el final, pero se le puede pasar un segundo parámetro que limite la longitud: + +```java +// Se llaman a dos métodos diferentes con el mismo nombre +"hexlet".substring(3); // "let" +"hexlet".substring(3, 5); // "le" +``` + +La sobrecarga de métodos puede llevar a la duplicación de código, especialmente cuando se trata de valores predeterminados. En tales situaciones, la lógica es la misma, solo difiere en la inicialización inicial. + +Para reducir la duplicación, basta con seguir estos dos pasos: + +* Primero, definir un método común que acepte la mayor cantidad de parámetros +* Luego, llamar a ese método desde los métodos que tienen valores predeterminados + +En el código, se vería así: + +```java +class App { + public static int sum(int x, int y) { + return x + y; + } + + public static int sum(int x) { + // Llamamos al método de suma ya existente + return App.sum(x, 10); + } +} +``` + +https://replit.com/@hexlet/java-basics-default-parameters + +En este ejemplo, no hemos reducido el código, pero muestra claramente el principio descrito anteriormente. diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/es/data.yml b/modules/40-methods-definition/400-method-definition-default-parameters/es/data.yml new file mode 100644 index 00000000..b9b63cad --- /dev/null +++ b/modules/40-methods-definition/400-method-definition-default-parameters/es/data.yml @@ -0,0 +1 @@ +name: Parámetros opcionales de los métodos diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/ru/EXERCISE.md b/modules/40-methods-definition/400-method-definition-default-parameters/ru/EXERCISE.md new file mode 100644 index 00000000..823acc36 --- /dev/null +++ b/modules/40-methods-definition/400-method-definition-default-parameters/ru/EXERCISE.md @@ -0,0 +1,17 @@ + +Реализуйте метод `getHiddenCard()`, который принимает на вход номер кредитки (состоящий из 16 цифр) в виде строки и возвращает его скрытую версию, которая может использоваться на сайте для отображения. Если исходная карта имела номер *2034399002125581*, то скрытая версия выглядит так *\*\*\*\*5581*. Другими словами, функция заменяет первые 12 символов, на звездочки. Количество звездочек регулируется вторым необязательным параметром. Значение по умолчанию — 4. + +```java +// Кредитка передается внутрь как строка +App.getHiddenCard("1234567812345678", 2); // "**5678" +App.getHiddenCard("1234567812345678", 3); // "***5678" +App.getHiddenCard("1234567812345678"); // "****5678" +App.getHiddenCard("2034399002121100", 1); // "*1100" +``` + +Для выполнения задания вам понадобится метод строки `repeat`, который повторяет строку указанное количество раз + +```java +"+".repeat(5); // "+++++" +"o".repeat(5); // "ooooo" +``` diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/ru/README.md b/modules/40-methods-definition/400-method-definition-default-parameters/ru/README.md new file mode 100644 index 00000000..428a3173 --- /dev/null +++ b/modules/40-methods-definition/400-method-definition-default-parameters/ru/README.md @@ -0,0 +1,92 @@ + + +В программировании большое количество функций и методов имеют параметры, которые редко меняются. + +В таких случаях этим параметрам задают **значения по умолчанию**, которые можно поменять по необходимости. Этим немного сокращается количество одинакового кода. + +Это наглядно видно на таком примере: + +```java +class App { + // Функция возведения в степень + // Степень — это второй параметр со значением по умолчанию 2 + function pow(x, base = 2) { + return x ** base; + } +} + +App.pow(3); // Результат — 9, так как по умолчанию возводим во вторую степень +// Возводим в третью степень +App.pow(3, 3); // 27 +``` + +В отличие от других языков, в Java нет возможности задать значение по умолчанию, но ее можно имитировать с помощью **перегрузки методов**. + +Что это такое? Java позволяет создать несколько методов с одинаковым именем. У таких одинаковых методов должны быть: + +* Разные типы входных параметров +* Разное количество параметров +* Или все это одновременно + +Посмотрим на примере метода, складывающего два числа: + +```java +class App { + public static int sum(int x, int y) { + return x + y; + } +} + +App.sum(2, 3); // 5 +``` + +Теперь напишем другой метод `sum()`, который принимает только один параметр и складывает его с числом 10: + +```java +class App { + public static int sum(int x) { + return x + 10; + } +} + +App.sum(2); // 12 +App.sum(2, 1); // 3 +``` + +Компилятор без проблем выполнит такой код и создаст два метода с одним именем. Как Java узнает, какой метод нужно использовать? + +Все очень просто: во время компиляции выбирается та версия метода, которая совпадает по типу и количеству параметров. Если такой метод не был найден, то возникнет ошибка. + +Как минимум с одним перегруженным методом мы уже встречались — это метод `substring()`. По умолчанию он извлекает подстроку до конца, но ему можно передать второй параметр, который ограничит длину: + +```java +// Вызываются два разных метода с одним именем +"hexlet".substring(3); // "let" +"hexlet".substring(3, 5); // "le" +``` + +Перегрузка методов может приводить к дублированию кода, особенно когда речь идет про значения по умолчанию. В таких ситуациях логика одинаковая, разница лишь в начальной инициализации. + +Для снижения дублирования достаточно сделать два шага: + +* Сначала определить общий метод, который принимает больше всего параметров +* Затем вызывать его из тех методов, где есть значения по умолчанию + +В коде это выглядит так: + +```java +class App { + public static int sum(int x, int y) { + return x + y; + } + + public static int sum(int x) { + // Вызываем уже готовый метод суммирования + return App.sum(x, 10); + } +} +``` + +https://replit.com/@hexlet/java-basics-default-parameters + +В этом примере мы не сократили код, но он наглядно показывает принцип, описанный выше. diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/ru/data.yml b/modules/40-methods-definition/400-method-definition-default-parameters/ru/data.yml new file mode 100644 index 00000000..e214cc48 --- /dev/null +++ b/modules/40-methods-definition/400-method-definition-default-parameters/ru/data.yml @@ -0,0 +1 @@ +name: Необязательные параметры методов diff --git a/modules/45-logic/10-bool-type/es/EXERCISE.md b/modules/45-logic/10-bool-type/es/EXERCISE.md new file mode 100644 index 00000000..00cea42a --- /dev/null +++ b/modules/45-logic/10-bool-type/es/EXERCISE.md @@ -0,0 +1,9 @@ + +Implementa el método `isPensioner()`, que toma un parámetro: la edad de una persona, y verifica si es un pensionista. Se considera pensionista a una persona que tiene 60 años o más. + +Ejemplos de llamadas: + +```java +App.isPensioner(75); // true +App.isPensioner(18); // false +``` diff --git a/modules/45-logic/10-bool-type/es/README.md b/modules/45-logic/10-bool-type/es/README.md new file mode 100644 index 00000000..bf9d50ee --- /dev/null +++ b/modules/45-logic/10-bool-type/es/README.md @@ -0,0 +1,64 @@ +Además de las operaciones aritméticas, en matemáticas escolares también conocemos las operaciones de comparación, por ejemplo: + +``` +5 > 4 +``` + +Esto se lee como una pregunta: "¿Cinco es mayor que cuatro?". En este caso, la respuesta es "sí". En otros casos, la respuesta puede ser "no", por ejemplo, para la siguiente expresión: + +``` +3 < 1 +``` + +Las operaciones de comparación no están limitadas a números. Se pueden comparar casi cualquier cosa, como cadenas de texto. Cuando ingresamos a un sitio web, se compara el nombre de usuario y la contraseña ingresados con los que están en la base de datos. Si hay una coincidencia, se realiza la autenticación. + +Los lenguajes de programación han adaptado todas las operaciones de comparación matemáticas 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 encuentra con frecuencia. En muchos lenguajes, el símbolo `=` se utiliza para asignar valores a variables, por lo que se utiliza `==` para las comparaciones. + +Aquí tienes una lista de las operaciones de comparación en Java: + +* `<` — menor que +* `<=` — menor o igual que +* `>` — mayor que +* `>=` — mayor o igual que +* `==` — igual que +* `!=` — no igual que + +Veamos algunos ejemplos de operaciones lógicas: + +``` +5 > 4 +password == text +``` + +Ambos ejemplos son expresiones. El resultado de evaluar estas expresiones es uno de los dos valores especiales: + +* `true` — "verdadero" +* `false`— "falso" + +Este es un nuevo tipo de dato para nosotros, llamado **booleano**. Solo puede tener estos dos valores. Aquí tienes un ejemplo de código que lo utiliza: + +```java +var resultado = 5 > 4; +System.out.println(resultado); // => true +``` + +Intentemos escribir un método que tome la edad de un niño y determine si es un bebé. Se considera bebé a un niño menor de un año: + +```java +// Un método que devuelve un booleano se llama predicado +// Por lo general, estos métodos tienen un prefijo como has, can, is, was, etc. +public static boolean esBebe(int edad) { + return edad < 1; +} +``` + +Aprovechamos el hecho de que cualquier operación es una expresión. Por lo tanto, en una sola línea de la función, escribimos "devolver el resultado de la comparación `edad < 1`". + +Dependiendo del parámetro recibido, la comparación será verdadera (`true`) o falsa (`false`). Finalmente, `return` devuelve ese resultado: + +```java +System.out.println(App.esBebe(3)); // => false +System.out.println(App.esBebe(0)); // => true +``` diff --git a/modules/45-logic/10-bool-type/es/data.yml b/modules/45-logic/10-bool-type/es/data.yml new file mode 100644 index 00000000..9838ba2f --- /dev/null +++ b/modules/45-logic/10-bool-type/es/data.yml @@ -0,0 +1,6 @@ +name: Tipo lógico +definitions: + - name: Tipo lógico (boolean) + description: >- + un tipo de dato con dos posibles valores: true (verdadero) y false + (falso). diff --git a/modules/45-logic/10-bool-type/ru/EXERCISE.md b/modules/45-logic/10-bool-type/ru/EXERCISE.md new file mode 100644 index 00000000..4e2c97ba --- /dev/null +++ b/modules/45-logic/10-bool-type/ru/EXERCISE.md @@ -0,0 +1,9 @@ + +Реализуйте метод `isPensioner()`, который принимает один параметр — возраст человека, и проверяет, является ли он пенсионным. Пенсионером считается человек, достигший возраста 60 лет и больше. + +Примеры вызова: + +```java +App.isPensioner(75); // true +App.isPensioner(18); // false +``` diff --git a/modules/45-logic/10-bool-type/ru/README.md b/modules/45-logic/10-bool-type/ru/README.md new file mode 100644 index 00000000..3e337c52 --- /dev/null +++ b/modules/45-logic/10-bool-type/ru/README.md @@ -0,0 +1,64 @@ +Кроме арифметических операций, из школьной математики нам известны еще и операции сравнения, например: + +``` +5 > 4 +``` + +Это звучит как вопрос: «Пять больше четырех?». В данном случае, ответ «да». В других случаях, ответом может быть «нет», например, для такого выражения: + +``` +3 < 1 +``` + +Операции сравнения не имеют привязки к числам. Сравнивать можно практически что угодно — например, строки. Когда мы входим на какой-то сайт, внутри происходит сравнение введенного логина и пароля с теми, какие есть в базе. Если совпадение есть, то происходит авторизация. + +Языки программирования адаптировали все математические операции сравнения практически в неизменном виде. Единственное серьезное отличие – **операторы равенства и неравенства**. + +В математике для этого используется обычное равно `=`, но в программировании такое встречается нечасто. Во многих языках символ `=` используется для присваивания значений переменным, поэтому для сравнения взяли `==`. + +Список операций сравнения в Java: + +* `<` — меньше +* `<=` — меньше или равно +* `>` — больше +* `>=` — больше или равно +* `==` — равно +* `!=` — не равно + +Посмотрим на пару примеров логических операций: + +``` +5 > 4 +password == text +``` + +Оба примера — это выражения. Результат вычисления этих выражений — это одно из двух специальных значений + +* `true` — «истина» +* `false`— «ложь» + +Это новый для нас тип данных — **boolean**. Он содержит всего лишь два этих значения. Так выглядит пример кода с ним: + +```java +var result = 5 > 4; +System.out.println(result); // => true +``` + +Попробуем написать метод, который принимает на вход возраст ребенка и определяет, младенец ли он. Младенцами считаются дети до года: + +```java +// Метод, возвращающий boolean, называется предикатом +// Обычно такие методы имеют префикс has, can, is, was и так далее +public static boolean isInfant(int age) { + return age < 1; +} +``` + +Пользуемся тем фактом, что любая операция — это выражение. Поэтому единственной строчкой функции пишем «вернуть то значение, которое получится в результате сравнения `age < 1`». + +В зависимости от пришедшего параметра, сравнение будет либо истинным (`true`), либо ложным (`false`). В итоге `return` вернет этот результат: + +```java +System.out.println(App.isInfant(3)); // => false +System.out.println(App.isInfant(0)); // => true +``` diff --git a/modules/45-logic/10-bool-type/ru/data.yml b/modules/45-logic/10-bool-type/ru/data.yml new file mode 100644 index 00000000..4521ff1f --- /dev/null +++ b/modules/45-logic/10-bool-type/ru/data.yml @@ -0,0 +1,4 @@ +name: Логический тип +definitions: + - name: Логический тип (boolean) + description: 'тип данных с двумя возможными значениями: true (истина) и false (ложь).' diff --git a/modules/45-logic/12-string-comparasion/es/EXERCISE.md b/modules/45-logic/12-string-comparasion/es/EXERCISE.md new file mode 100644 index 00000000..96f5c2b9 --- /dev/null +++ b/modules/45-logic/12-string-comparasion/es/EXERCISE.md @@ -0,0 +1,17 @@ + +Implementa el método `isPalindrome()`, que determina si una palabra es un palíndromo o no. Un palíndromo es una palabra que se lee igual en ambos sentidos. + +```java +App.isPalindrome("шалаш"); // true +App.isPalindrome("ага"); // true +App.isPalindrome("хекслет"); // false + +// Las palabras pueden estar en cualquier caso +App.isPalindrome("Ага"); // true +``` + +Para determinar si una palabra es un palíndromo, debes invertir la cadena y compararla con la original. Para esto, utiliza el método `StringUtils.reverse()` + +```java +StringUtils.reverse("мама"); // "амам" +``` diff --git a/modules/45-logic/12-string-comparasion/es/README.md b/modules/45-logic/12-string-comparasion/es/README.md new file mode 100644 index 00000000..efe25ffc --- /dev/null +++ b/modules/45-logic/12-string-comparasion/es/README.md @@ -0,0 +1,121 @@ +Echa un vistazo al código y trata de responder cuáles son los valores de estas expresiones: + +```java +// ¿Cuál es el resultado de estos ejemplos: `true` o `false`? + +"a" == "a"; +"a".toUpperCase() == "a".toUpperCase(); +``` + +Respuesta correcta: en el primer caso es `true`, en el segundo es `false`. ¿Por qué? Para responder a esta pregunta, es necesario entender cómo funcionan las computadoras. + +En nuestros programas, operamos con datos: números, cadenas, valores booleanos. Realizamos diversas operaciones: los almacenamos en variables, los multiplicamos, los dividimos, los concatenamos. + +Así es como ve su trabajo un programador. Pero dentro de la computadora, todo es un poco diferente. Durante la ejecución del programa, este accede y manipula los datos a través de sus direcciones en la memoria: + +```java +// Se asigna un área de memoria para almacenar la variable +// El programa recuerda la dirección de esta área y trabaja con ella internamente +var name = "CodeBasics"; +// El programa lee el valor de la variable en la dirección de memoria donde se almacena el valor +System.out.println(name); +``` + +**Memoria** es una gran área para almacenar datos, similar a un almacén. Cada valor en la memoria recibe un número, que se utiliza para recuperarlo y reemplazarlo. Ese número es la **dirección**. + +## Comparación por referencia y por valor + +Debido a estas características técnicas, podemos ver la comparación de datos de dos maneras: + +* *Lo mismo* - la misma área de memoria +* *Igual* - valores idénticos, independientemente de las direcciones a las que apuntan + +Un ejemplo de la vida real: dos vasos idénticos de un mismo conjunto. A pesar de su similitud, siguen siendo vasos diferentes. + +Los lenguajes de programación manejan estos conceptos de diferentes maneras. Al igual que en muchos otros lenguajes, en Java los datos se dividen en dos tipos principales: + +* Los datos primitivos se comparan por valor, independientemente de las direcciones +* Los datos de referencia se comparan por direcciones + +Así es como funcionan los datos primitivos: + +```java +// La comparación se realiza por valor, no por direcciones +4 == 4; // true +true == true; // true +10.0 == 10.0; // true +``` + +Hasta ahora solo hemos trabajado con datos de referencia en forma de cadenas, pero se comportan de manera especial. Por lo tanto, como ejemplo, veamos cómo funcionan los arreglos. No te preocupes por la sintaxis desconocida, solo presta atención a que en este código, cosas aparentemente iguales no son iguales: + +```java +// Creación de arreglos +int[] a = {1, 2} +int[] b = {1, 2} +// Los valores son iguales, pero las referencias son diferentes +a == b; // false +``` + +## Características de las cadenas + +Las cadenas son consideradas datos de referencia, pero se comportan de manera extraña: + +```java +// Comparación como datos primitivos +"hm" == "hm"; // true +// Comparación como datos de referencia +"hexlet".toUpperCase() == "hexlet".toUpperCase(); // false +``` + +Los programas operan constantemente con cadenas, por lo que la eficiencia en su manipulación es primordial. Si las cadenas siempre se comportaran como datos de referencia, se asignaría memoria adicional para cada valor en el código: + +```java +// Sin optimizaciones, esta expresión resultaría en una asignación de memoria duplicada +// Una unidad de memoria para cada "hm" +"hm" == "hm"; +``` + +Pero eso no sucede. Cuando Java encuentra una cadena creada explícitamente, verifica si ya existe en la memoria. + +Si existe, se reutiliza; si no, se crea: + +```java +// Se asigna memoria +var name1 = "Java"; +// Como ya existe una cadena igual en la memoria, se utiliza una referencia a la cadena existente +// Esto ahorra memoria +var name2 = "Java"; +// Comparación por referencia +// Ambas variables apuntan a la misma área de memoria +name1 == name2; // true +``` + +Pero si una cadena se devuelve desde un método, se coloca en su propia área de memoria con su dirección única: + +```java +// Se asigna nueva memoria de todos modos +var name1 = "java".toUpperCase(); // "JAVA" +// Se asigna nueva memoria de todos modos +var name2 = "java".toUpperCase(); // "JAVA" +name1 == name2; // false +``` + +Puede parecer que los datos de referencia solo causan problemas. En realidad, son necesarios. Esto se entenderá cuando nos enfrentemos a la mutabilidad en el futuro. + +En la programación aplicada, a menudo comparamos cadenas por valor en lugar de por referencia. Para esto, las cadenas tienen el método `equals()` incorporado: + +```java +var name1 = "java".toUpperCase(); // "JAVA" +var name2 = "java".toUpperCase(); // "JAVA" +name1.equals(name2); // true +``` + +Además de `equals()`, las cadenas tienen el método `equalsIgnoreCase()`, que realiza una comparación sin tener en cuenta el caso: + +```java +var name1 = "java".toUpperCase(); // "JAVA" +var name2 = "java".toLowerCase(); // "java" +name1.equalsIgnoreCase(name2); // true +``` + +A veces, la comparación de cadenas en Java se comporta como una comparación de valores, pero nunca confíes en eso. Al cambiar el código, es fácil olvidar corregir la comparación y obtener un error. Siempre utiliza los métodos cuando necesites comparar por valor. diff --git a/modules/45-logic/12-string-comparasion/es/data.yml b/modules/45-logic/12-string-comparasion/es/data.yml new file mode 100644 index 00000000..ac545140 --- /dev/null +++ b/modules/45-logic/12-string-comparasion/es/data.yml @@ -0,0 +1 @@ +name: Comparación de cadenas diff --git a/modules/45-logic/12-string-comparasion/ru/EXERCISE.md b/modules/45-logic/12-string-comparasion/ru/EXERCISE.md new file mode 100644 index 00000000..e44f0e71 --- /dev/null +++ b/modules/45-logic/12-string-comparasion/ru/EXERCISE.md @@ -0,0 +1,17 @@ + +Реализуйте метод `isPalindrome()`, который определяет, является ли слово палиндромом или нет. Палиндром это слово, которое читается одинаково в обоих направлениях. + +```java +App.isPalindrome("шалаш"); // true +App.isPalindrome("ага"); // true +App.isPalindrome("хекслет"); // false + +// Слова в метод могут быть переданы в любом регистре +App.isPalindrome("Ага"); // true +``` + +Для определения палиндрома, необходимо перевернуть строку и сравнить ее с исходной. Для этого воспользуйтесь методом `StringUtils.reverse()` + +```java +StringUtils.reverse("мама"); // "амам" +``` diff --git a/modules/45-logic/12-string-comparasion/ru/README.md b/modules/45-logic/12-string-comparasion/ru/README.md new file mode 100644 index 00000000..4934aa1e --- /dev/null +++ b/modules/45-logic/12-string-comparasion/ru/README.md @@ -0,0 +1,124 @@ +Посмотрите на код и попытайтесь ответить, чему равны значения этих выражений: + +```java +// Какой результат будет в этих примерах — `true` или `false`? + +"a" == "a"; +"a".toUpperCase() == "a".toUpperCase(); +``` + +Правильный ответ: в первом случае `true`, во втором — `false`. Почему? Для ответа на этот вопрос нужно немного погрузиться в то, как работают компьютеры. + + +В наших программах мы оперируем данными — числами, строками, булевыми значениями. Мы выполняем разнообразные операции — записываем их в переменные, умножаем, делим, конкатенируем. + +Так свою работу видит программист. Но внутри компьютера все немного по-другому. Во время работы программа получает доступ и манипулирует данными через их адреса в памяти: + +```java +// Под хранение переменной выделяется область памяти +// Программа запоминает адрес этой области и работает с ней внутри себя +var name = "CodeBasics"; +// Программа считала значение переменной по адресу, где хранится значение +System.out.println(name); +``` + +**Память** — это большая область для хранения данных, которая очень похожа на склад. В памяти любое значение получает номер, по которому его можно извлечь и заменить. Этот номер и есть **адрес**. + +## Сравнение по ссылке и по значению + +Из-за этих технических особенностей на сравнение данных между собой можно смотреть двумя способами: + +* *То же самое* — тот же участок памяти +* *Такое же* — одинаковые значения независимо от того, куда указывают адреса + +Пример из реальной жизни: два одинаковых стакана из одного набора. Несмотря на свою одинаковость, все же разные стаканы. + +Языки программирования по-разному работают с этими понятиями. Как и во многих других языках, в Java все данные делятся на два больших типа: + +* Примитивные данные сравниваются по значению, независимо от адресов +* Ссылочные данные сравниваются по адресам + +Так работают примитивные данные: + +```java +// Сравнение идет по значению, а не адресам +4 == 4; // true +true == true; // true +10.0 == 10.0; // true +``` + +Из ссылочных данных мы пока знакомы только со строками, но они работают хитро, поэтому в качестве примера посмотрим на массивы. Не обращайте внимание на незнакомый синтаксис. Просто обратите внимание, что в этом коде вроде бы одинаковые штуки не равны друг другу: + +```java +// Создание массивов +int[] a = {1, 2} +int[] b = {1, 2} +// Значения одинаковые, но ссылки разные +a == b; // false +``` + +## Особенности строк + +Строки относятся к ссылочным типам данных, но ведут себя странно: + +```java +// Сравнение, как у примитивных типов данных +"hm" == "hm"; // true +// Сравнение, как у ссылочных типов данных +"hexlet".toUpperCase() == "hexlet".toUpperCase(); // false +``` + +Программы постоянно оперируют строками, поэтому эффективность работы с ними выходит на первое место. Если бы строка всегда вела себя как ссылочный тип, то на каждое значение в коде выделялась дополнительная память: + +```java +// Без оптимизаций это выражение привело бы к двойному выделению памяти +// По одной единице памяти на каждый "hm" +"hm" == "hm"; +``` + +Но этого не происходит. Когда Java встречает явно создаваемую строку, выполняется проверка, а есть ли уже в памяти такая строка. + +Если есть, то она переиспользуется, если нет — создается: + +```java +// Выделяется память +var name1 = "Java"; +// Такая строка уже есть, поэтому подставляется ссылка на уже созданную строку +// В результате экономится память +var name2 = "Java"; +// Сравнение по ссылке +// Обе переменные указывают на один участок памяти +name1 == name2; // true +``` + +Но если строка возвращается из метода, то она помещается в свою область памяти со своим уникальным адресом: + +```java +// Выделяется новая память в любом случае +var name1 = "java".toUpperCase(); // "JAVA" +// Выделяется новая память в любом случае +var name2 = "java".toUpperCase(); // "JAVA" +name1 == name2; // false +``` + +Может показаться, что ссылочные данные приносят сплошные проблемы. На самом деле они нужны. Это станет понятно, когда мы столкнемся с изменяемостью в будущем. + +В прикладном программировании мы чаще сравниваем строки по значению, чем по ссылке. Для этого в строки встроен метод `equals()`: + +```java +var name1 = "java".toUpperCase(); // "JAVA" +var name2 = "java".toUpperCase(); // "JAVA" +name1.equals(name2); // true +``` + +https://replit.com/@hexlet/java-basics-logical-operations + +Помимо `equals()`, в строки встроен метод `equalsIgnoreCase()`, который выполняет проверку по значению без учета регистра: + +```java +var name1 = "java".toUpperCase(); // "JAVA" +var name2 = "java".toLowerCase(); // "java" +name1.equalsIgnoreCase(name2); // true +``` + +Иногда сравнение строк в Java ведет себя как сравнение значений, но никогда не делайте ставку на это. При изменении кода легко забыть поправить проверку и получить ошибку. Всегда используйте методы, когда нужно сравнивать по значению. diff --git a/modules/45-logic/12-string-comparasion/ru/data.yml b/modules/45-logic/12-string-comparasion/ru/data.yml new file mode 100644 index 00000000..b04612b9 --- /dev/null +++ b/modules/45-logic/12-string-comparasion/ru/data.yml @@ -0,0 +1 @@ +name: Сравнение строк diff --git a/modules/45-logic/20-combine-expressions/es/EXERCISE.md b/modules/45-logic/20-combine-expressions/es/EXERCISE.md new file mode 100644 index 00000000..18d4d3c4 --- /dev/null +++ b/modules/45-logic/20-combine-expressions/es/EXERCISE.md @@ -0,0 +1,7 @@ + +Implementa el método `isInternationalPhone()`, que verifica el formato de un número de teléfono dado. Si el teléfono comienza con un *+*, significa que está en formato internacional. + +```java +App.isInternationalPhone("89602223423"); // false +App.isInternationalPhone("+79602223423"); // true +``` diff --git a/modules/45-logic/20-combine-expressions/es/README.md b/modules/45-logic/20-combine-expressions/es/README.md new file mode 100644 index 00000000..dabbd1f0 --- /dev/null +++ b/modules/45-logic/20-combine-expressions/es/README.md @@ -0,0 +1,62 @@ + +Las operaciones lógicas son expresiones. Esto significa que **las operaciones lógicas se pueden combinar con otras expresiones**. Veamos un ejemplo. Supongamos que queremos verificar si un número es par. En programación, la paridad se verifica mediante el residuo de la división por 2: + +* Si el residuo es 0, entonces el número es par +* Si el residuo no es 0, entonces el número es impar + +El residuo de la división es un concepto simple pero muy importante en aritmética, álgebra, teoría de números y criptografía. La idea es simple: se debe dividir un número en grupos iguales. Si queda algo al final, eso es el residuo de la división. + +Dividimos caramelos entre personas: + +* 7 caramelos, 2 personas: 2 x 3 + **residuo 1**. Esto significa que 7 no es divisible por 2 +* 21 caramelos, 3 personas: 3 x 7 + **residuo 0**. Esto significa que 21 es divisible por 3 +* 19 caramelos, 5 personas: 5 x 3 + **residuo 4**. Esto significa que 19 no es divisible por 5 + +En el código, el residuo se calcula utilizando el operador `%`: + +* `7 % 2` → `1` +* `21 % 3` → `0` +* `19 % 5` → `4` + +Usando esto, escribiremos un método para verificar la paridad: + +```java +// Definido en la clase App +public static boolean esPar(int numero) { + return numero % 2 == 0; +} + +App.esPar(10); // true +App.esPar(3); // false +``` + +https://replit.com/@hexlet/java-basics-logical-operations-1 + +En una sola expresión hemos combinado dos operadores lógicos: + +* `==` - verificación de igualdad +* `%` - operador aritmético de residuo de la división + +**La prioridad de las operaciones aritméticas es mayor que la de las operaciones lógicas**. Esto significa que primero se calcula la expresión aritmética `numero % 2`, y luego el resultado se utiliza en la comparación lógica. + +En ruso, esto se puede descifrar de la siguiente manera: "Es necesario calcular el residuo de la división del número `numero` por 2 y compararlo con cero; luego devolver el resultado de la comparación". + +Veamos otro ejemplo. Escribiremos un método que toma una cadena y verifica si la primera letra es mayúscula. El algoritmo será el siguiente: + +1. Obtener y guardar en una variable el primer carácter de la cadena argumento +2. Comparar si el carácter es igual a su versión en mayúscula +3. Devolver el resultado + +La implementación en código se verá así: + +```java +public static boolean esPrimeraLetraMayuscula(String cadena) { + var primeraLetra = cadena.charAt(0); + // La clase Character contiene varios métodos para trabajar con caracteres + // El método isUpperCase() verifica si el carácter pasado está en mayúscula + return Character.isUpperCase(primeraLetra); +} + +App.esPrimeraLetraMayuscula("marmont"); // false +App.esPrimeraLetraMayuscula("Robb"); // true +``` diff --git a/modules/45-logic/20-combine-expressions/es/data.yml b/modules/45-logic/20-combine-expressions/es/data.yml new file mode 100644 index 00000000..32ce4900 --- /dev/null +++ b/modules/45-logic/20-combine-expressions/es/data.yml @@ -0,0 +1 @@ +name: Combinación de operaciones y métodos diff --git a/modules/45-logic/20-combine-expressions/ru/EXERCISE.md b/modules/45-logic/20-combine-expressions/ru/EXERCISE.md new file mode 100644 index 00000000..044d2db7 --- /dev/null +++ b/modules/45-logic/20-combine-expressions/ru/EXERCISE.md @@ -0,0 +1,7 @@ + +Реализуйте метод `isInternationalPhone()`, который проверяет формат указанного телефона. Если телефон начинается с *+*, значит это международный формат. + +```java +App.isInternationalPhone("89602223423"); // false +App.isInternationalPhone("+79602223423"); // true +``` diff --git a/modules/45-logic/20-combine-expressions/ru/README.md b/modules/45-logic/20-combine-expressions/ru/README.md new file mode 100644 index 00000000..ae55b282 --- /dev/null +++ b/modules/45-logic/20-combine-expressions/ru/README.md @@ -0,0 +1,62 @@ + +Логические операции — это выражения. Значит, **логические операции можно комбинировать с другими выражениями**. Разберем на примере. Допустим, мы хотим проверить четность числа. В программировании четность проверяется через остаток от деления на 2: + +* Если остаток 0, то число было четным +* Если остаток не 0, то число было нечетным + +Остаток от деления — простая, но очень важная концепция в арифметике, алгебре, теории чисел и криптографии. Идея проста: нужно разделить число на несколько равных групп. Если в конце что-то останется, это и есть остаток от деления. + +Делим конфеты поровну между людьми: + +* 7 конфет, 2 человека: 2 x 3 + **остаток 1**. Значит, 7 не кратно 2 +* 21 конфету, 3 человека: 3 x 7 + **остаток 0**. Значит, 21 кратно 3 +* 19 конфет, 5 человек: 5 x 3 + **остаток 4**. Значит, 19 не кратно 5 + +В коде остаток вычисляется с помощью оператора `%`: + +* `7 % 2` → `1` +* `21 % 3` → `0` +* `19 % 5` → `4` + +С помощью него напишем метод для проверки четности: + +```java +// Определен в классе App +public static boolean isEven(int number) { + return number % 2 == 0; +} + +App.isEven(10); // true +App.isEven(3); // false +``` + +https://replit.com/@hexlet/java-basics-logical-operations-1 + +В одном выражении мы скомбинировали два логических оператора: + +* `==` — проверка равенства +* `%` — арифметический оператор остатка от деления + +**Приоритет арифметических операций выше логических.** Значит, сначала вычисляется арифметическое выражение `number % 2`, затем результат участвует в логическом сравнении. + +По-русски это можно расшифровать так: «Нужно вычислить остаток от деления числа `number` на 2 и сравнить с нулем; затем вернуть результат сравнения». + +Рассмотрим еще один пример. Напишем метод, который принимает строку и проверяет, заглавная ли первая буква. Алгоритм действий будет такой: + +1. Получим и запишем в переменную первый символ из строки-аргумента +2. Сравним, равен ли символ своей заглавной версии +3. Вернем результат + +А так будет выглядеть реализация в коде: + +```java +public static boolean isFirstLetterInUpperCase(String string) { + var firstLetter = string.charAt(0); + // Класс Character содержит различные методы для работы с символом + // Метод isUpperCase() проверяет, что переданный символ в верхнем регистре + return Character.isUpperCase(firstLetter); +} + +App.isFirstLetterInUpperCase("marmont"); // false +App.isFirstLetterInUpperCase("Robb"); // true +``` diff --git a/modules/45-logic/20-combine-expressions/ru/data.yml b/modules/45-logic/20-combine-expressions/ru/data.yml new file mode 100644 index 00000000..fd88f216 --- /dev/null +++ b/modules/45-logic/20-combine-expressions/ru/data.yml @@ -0,0 +1 @@ +name: Комбинирование операций и методов diff --git a/modules/45-logic/25-logical-operators/es/EXERCISE.md b/modules/45-logic/25-logical-operators/es/EXERCISE.md new file mode 100644 index 00000000..bbde2e31 --- /dev/null +++ b/modules/45-logic/25-logical-operators/es/EXERCISE.md @@ -0,0 +1,19 @@ + +Implementa el método `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, la lógica necesaria ya está definida en la descripción, solo falta convertirla en código: + +```java +App.isLeapYear(2018); // false +App.isLeapYear(2017); // false +App.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 +// Verificar si number es divisible por 10 +number % 10 == 0 + +// Verificar si number no es divisible por 10 +number % 10 != 0 +``` diff --git a/modules/45-logic/25-logical-operators/es/README.md b/modules/45-logic/25-logical-operators/es/README.md new file mode 100644 index 00000000..7c8ea587 --- /dev/null +++ b/modules/45-logic/25-logical-operators/es/README.md @@ -0,0 +1,72 @@ + +Ya sabemos cómo escribir métodos que verifican condiciones individuales. En esta lección continuaremos trabajando con métodos y aprenderemos a construir condiciones compuestas. + +Estas habilidades son útiles en tareas bastante comunes, como verificar contraseñas. Como sabes, algunos sitios web solicitan contraseñas de 8 a 20 caracteres de longitud durante el registro. + +En matemáticas, escribiríamos `8 <= x <= 20`, pero en Java esto no funciona. Tendremos que hacer dos expresiones lógicas separadas y combinarlas con el operador especial "Y". + +Escribamos un método que tome una contraseña y determine si cumple con las condiciones: + +```java +// La contraseña tiene más de 8 caracteres **Y** menos de 20 caracteres +public static boolean esContraseñaCorrecta(String contraseña) { + var longitud = contraseña.length(); + return longitud > 8 && longitud < 20; +} + +esContraseñaCorrecta("qwerty"); // false +esContraseñaCorrecta("qwerty1234"); // true +``` + +El operador `&&` significa "Y". En este caso, la expresión se considera verdadera solo si cada *operando* es verdadero, es decir, cada una de las expresiones compuestas. En otras palabras, `&&` significa "y esto, y aquello". + +La prioridad de este operador es menor que la de los operadores de comparación, por lo que la expresión funciona correctamente sin paréntesis. + +Además de `&&`, se utiliza con frecuencia el operador `||`, que significa "O". Significa "o esto, o aquello, o ambos". Los operadores se pueden combinar en cualquier cantidad y en cualquier secuencia. La única excepción es cuando se encuentran `&&` y `||` al mismo tiempo, en ese caso es mejor establecer la prioridad con paréntesis: + +```java +a && b || c; // Sin paréntesis es difícil entender la prioridad +a && (b || c) // La prioridad es obvia +``` + +Veamos otro ejemplo. Supongamos que queremos comprar un apartamento que cumpla con las siguientes condiciones: + +> Más de 100 m^2 en cualquier calle **O** más de 80 m^2 en la calle central *Main Street* + +Escribamos un método que verifique el apartamento. Toma dos parámetros: el área y el nombre de la calle: + +```java +esBuenApartamento(91, "Queens Street"); // false +esBuenApartamento(78, "Queens Street"); // false +esBuenApartamento(70, "Main Street"); // false + +esBuenApartamento(120, "Queens Street"); // true +esBuenApartamento(120, "Main Street"); // true +esBuenApartamento(80, "Main Street"); // true + +public static boolean esBuenApartamento(int area, String calle) { + return area >= 100 || (area >= 80 && "Main Street".equals(calle)); +} +``` + +https://replit.com/@hexlet/java-basics-logical-operators + +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 nos permiten determinar el resultado de la aplicación de un operador: + +### Operador Y `&&` + +| A | B | A && B | +| ----- | ----- | ------- | +| TRUE | TRUE | **TRUE** | +| TRUE | FALSE | FALSE | +| FALSE | TRUE | FALSE | +| FALSE | FALSE | FALSE | + +### Operador O `||` + +| A | B | A ❘❘ B | +| ----- | ----- | -------- | +| TRUE | TRUE | **TRUE** | +| TRUE | FALSE | **TRUE** | +| FALSE | TRUE | **TRUE** | +| FALSE | FALSE | FALSE | diff --git a/modules/45-logic/25-logical-operators/es/data.yml b/modules/45-logic/25-logical-operators/es/data.yml new file mode 100644 index 00000000..b2fc7195 --- /dev/null +++ b/modules/45-logic/25-logical-operators/es/data.yml @@ -0,0 +1,8 @@ +name: Operadores lógicos +tips: + - | + [Álgebra booleana](https://es.wikipedia.org/wiki/%C3%81lgebra_booleana) + - | + [Conjunción](https://es.wikipedia.org/wiki/Conjunci%C3%B3n) + - | + [Disyunción](https://es.wikipedia.org/wiki/Disyunci%C3%B3n) diff --git a/modules/45-logic/25-logical-operators/ru/EXERCISE.md b/modules/45-logic/25-logical-operators/ru/EXERCISE.md new file mode 100644 index 00000000..270120c8 --- /dev/null +++ b/modules/45-logic/25-logical-operators/ru/EXERCISE.md @@ -0,0 +1,19 @@ + +Реализуйте метод `isLeapYear()`, который определяет является ли год високосным или нет. Год будет високосным, если он кратен (то есть делится без остатка) 400 или он одновременно кратен 4 и не кратен 100. Как видите, в определении уже заложена вся необходимая логика, осталось только переложить её на код: + +```java +App.isLeapYear(2018); // false +App.isLeapYear(2017); // false +App.isLeapYear(2016); // true +``` + +Кратность можно проверять так: + +```javascript +// % - возвращает остаток от деления левого операнда на правый +// Проверяем что number кратен 10 +number % 10 == 0 + +// Проверяем что number не кратен 10 +number % 10 != 0 +``` diff --git a/modules/45-logic/25-logical-operators/ru/README.md b/modules/45-logic/25-logical-operators/ru/README.md new file mode 100644 index 00000000..ec998f5c --- /dev/null +++ b/modules/45-logic/25-logical-operators/ru/README.md @@ -0,0 +1,72 @@ + +Мы уже умеем писать методы, которые проверяют одиночные условия. В этом уроке мы продолжим работу с методами и научимся строить составные условия. + +Такие навыки пригождаются в довольно распространенных задачах — например, при проверке пароля. Как вы знаете, некоторые сайты при регистрации просят придумать пароль от 8 до 20 символов в длину. + +В математике мы бы написали `8 <= x <= 20`, но в Java такой трюк не пройдет. Нам придется сделать два отдельных логических выражения и соединить их специальным оператором «И». + +Напишем метод, который принимает пароль и говорит, соответствует ли он условиям: + +```java +// Пароль длиннее 8 символов **И** пароль короче 20 символов +public static boolean isCorrectPassword(String password) { + var length = password.length(); + return length > 8 && length < 20; +} + +isCorrectPassword("qwerty"); // false +isCorrectPassword("qwerty1234"); // true +``` + +Оператор `&&` означает «И». В этом случае выражение считается истинным, только если истинен каждый *операнд* — каждое из составных выражений. Другими словами, `&&` означает «и то, и другое». + +Приоритет этого оператора ниже, чем приоритет операторов сравнения, поэтому выражение отрабатывает правильно без скобок. + +Кроме `&&` часто используется оператор `||` — «ИЛИ». Он означает «или то, или другое, или оба». Операторы можно комбинировать в любом количестве и любой последовательности. Единственное исключение — когда одновременно встречаются `&&` и `||`, то приоритет лучше задавать скобками: + +```java +a && b || c; // Без скобок сложно понять приоритет +a && (b || c) // Приоритет очевиден +``` + +Рассмотрим еще один пример. Представим, что мы хотим купить квартиру, которая удовлетворяет таким условиям: + +> Больше 100 м^2 на любой улице **ИЛИ** больше 80 м^2 на центральной улице *Main Street* + +Напишем метод, проверяющий квартиру. Он принимает два параметра: площадь и название улицы: + +```java +isGoodApartment(91, "Queens Street"); // false +isGoodApartment(78, "Queens Street"); // false +isGoodApartment(70, "Main Street"); // false + +isGoodApartment(120, "Queens Street"); // true +isGoodApartment(120, "Main Street"); // true +isGoodApartment(80, "Main Street"); // true + +public static boolean isGoodApartment(int area, String street) { + return area >= 100 || (area >= 80 && "Main Street".equals(street)); +} +``` + +https://replit.com/@hexlet/java-basics-logical-operators + +Область математики, в которой изучаются логические операторы, называется **булевой алгеброй**. Ниже показаны «таблицы истинности» — по ним можно определить, каким будет результат применения оператора: + +### Оператор И `&&` + +| A | B | A && B | +| ----- | ----- | ------- | +| TRUE | TRUE | **TRUE** | +| TRUE | FALSE | FALSE | +| FALSE | TRUE | FALSE | +| FALSE | FALSE | FALSE | + +### Оператор ИЛИ `||` + +| A | B | A ❘❘ B | +| ----- | ----- | -------- | +| TRUE | TRUE | **TRUE** | +| TRUE | FALSE | **TRUE** | +| FALSE | TRUE | **TRUE** | +| FALSE | FALSE | FALSE | diff --git a/modules/45-logic/25-logical-operators/ru/data.yml b/modules/45-logic/25-logical-operators/ru/data.yml new file mode 100644 index 00000000..4a21514a --- /dev/null +++ b/modules/45-logic/25-logical-operators/ru/data.yml @@ -0,0 +1,8 @@ +name: Логические операторы +tips: + - | + [Булева алгебра](https://ru.wikipedia.org/wiki/Булева_алгебра) + - | + [Конъюнкция](https://ru.wikipedia.org/wiki/Конъюнкция) + - | + [Дизъюнкция](https://ru.wikipedia.org/wiki/Дизъюнкция) diff --git a/modules/45-logic/28-logical-negation/es/EXERCISE.md b/modules/45-logic/28-logical-negation/es/EXERCISE.md new file mode 100644 index 00000000..d562c004 --- /dev/null +++ b/modules/45-logic/28-logical-negation/es/EXERCISE.md @@ -0,0 +1,11 @@ + +Implementa el método `notToday()`, que verifica si la fecha pasada no es la fecha de hoy: + +```java +// supongamos que hoy es 2012-11-25 +notToday("2012-11-25"); // false +notToday("2013-11-25"); // true +notToday("2013-09-01"); // true +``` + +Para obtener la fecha actual como una cadena: `LocalDate.now().toString()`. diff --git a/modules/45-logic/28-logical-negation/es/README.md b/modules/45-logic/28-logical-negation/es/README.md new file mode 100644 index 00000000..50fd0a61 --- /dev/null +++ b/modules/45-logic/28-logical-negation/es/README.md @@ -0,0 +1,24 @@ +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 a su opuesto. En programación, se corresponde con el operador `!`. Si hay un método que verifica si un número es par, se puede realizar una verificación de impar utilizando la negación: + +```java +public static boolean esPar(int numero) { + return numero % 2 == 0; +} + +esPar(10); // true +!esPar(10); // false +``` + +Es decir, simplemente agregamos `!` antes de llamar al método y obtenemos la acción opuesta. La negación se puede aplicar no solo a la llamada de un método, sino también a una expresión completa: + +```java +!(x == 5 || x == 3) + +// Esta misma expresión se puede escribir de otra manera: +// x no es igual a 5 y no es igual a 3 +x != 5 && x != 3 +``` + +La negación es una herramienta poderosa que permite expresar reglas de manera concisa en el código sin necesidad de escribir nuevos métodos. diff --git a/modules/45-logic/28-logical-negation/es/data.yml b/modules/45-logic/28-logical-negation/es/data.yml new file mode 100644 index 00000000..0b9449b5 --- /dev/null +++ b/modules/45-logic/28-logical-negation/es/data.yml @@ -0,0 +1,4 @@ +name: Negación +tips: + - | + [Leyes de De Morgan](https://es.wikipedia.org/wiki/Leyes_de_De_Morgan) diff --git a/modules/45-logic/28-logical-negation/ru/EXERCISE.md b/modules/45-logic/28-logical-negation/ru/EXERCISE.md new file mode 100644 index 00000000..fd5db3ba --- /dev/null +++ b/modules/45-logic/28-logical-negation/ru/EXERCISE.md @@ -0,0 +1,11 @@ + +Реализуйте метод `notToday()`, который проверяет что переданная дата это не сегодняшнее число: + +```java +// предположим сегодня 2012-11-25 +notToday("2012-11-25"); // false +notToday("2013-11-25"); // true +notToday("2013-09-01"); // true +``` + +Для получения текущей даты в виде строки: `LocalDate.now().toString()`. diff --git a/modules/45-logic/28-logical-negation/ru/README.md b/modules/45-logic/28-logical-negation/ru/README.md new file mode 100644 index 00000000..5ed18858 --- /dev/null +++ b/modules/45-logic/28-logical-negation/ru/README.md @@ -0,0 +1,24 @@ +Наряду с конъюнкцией (**И**) и дизъюнкцией (**ИЛИ**), часто используется операция «**отрицание**». + +Отрицание меняет логическое значение на противоположное. В программировании ему соответствует оператор `!`. Если есть метод, проверяющий четность числа, то с помощью отрицания можно выполнить проверку нечетности: + +```java +public static boolean isEven(int number) { + return number % 2 == 0; +} + +isEven(10); // true +!isEven(10); // false +``` + +То есть мы просто добавили `!` слева от вызова метода и получили обратное действие. Отрицание можно применять не только к вызову метода, но и к целому выражению: + +```java +!(x == 5 || x == 3) + +// Это же выражение можно записать и по-другому: +// x не равен 5 и не равен 3 +x != 5 && x != 3 +``` + +Отрицание — мощный инструмент, который позволяет лаконично выражать задуманные правила в коде без необходимости писать новые методы. diff --git a/modules/45-logic/28-logical-negation/ru/data.yml b/modules/45-logic/28-logical-negation/ru/data.yml new file mode 100644 index 00000000..f736cbfb --- /dev/null +++ b/modules/45-logic/28-logical-negation/ru/data.yml @@ -0,0 +1,4 @@ +name: Отрицание +tips: + - | + [Законы Де Моргана](https://ru.wikipedia.org/wiki/Законы_де_Моргана) diff --git a/modules/80-conditionals/30-if/es/EXERCISE.md b/modules/80-conditionals/30-if/es/EXERCISE.md new file mode 100644 index 00000000..c246075a --- /dev/null +++ b/modules/80-conditionals/30-if/es/EXERCISE.md @@ -0,0 +1,16 @@ + +Implementa el método `getSentenceTone()`, que recibe una cadena y determina el tono de la oración. Si todos los caracteres están en mayúsculas, es un grito (`scream`). De lo contrario, es una oración normal (`normal`). + +Ejemplos de llamadas: + +```java +App.getSentenceTone("Hola"); // "normal" +App.getSentenceTone("WOW"); // "scream" +``` + +Algoritmo: + +1. Genera una cadena en mayúsculas basada en la cadena de argumento utilizando `toUpperCase()`. +2. Compara esta cadena con la cadena original: + * Si las cadenas son iguales, significa que la cadena de argumento está en mayúsculas. + * De lo contrario, la cadena de argumento no está en mayúsculas. diff --git a/modules/80-conditionals/30-if/es/README.md b/modules/80-conditionals/30-if/es/README.md new file mode 100644 index 00000000..ecccf400 --- /dev/null +++ b/modules/80-conditionals/30-if/es/README.md @@ -0,0 +1,24 @@ +Las estructuras condicionales permiten ejecutar diferentes fragmentos de código basados en comprobaciones lógicas. Veamos un ejemplo típico: + +* Una persona quiere pagar una compra con tarjeta. +* Si hay suficiente dinero en la cuenta, se deducirá automáticamente la cantidad necesaria. +* Si no hay suficiente dinero, la operación será rechazada. + +Para el ejemplo, escribiremos un método que determina el tipo de una oración dada. Al principio, distinguirá entre oraciones normales e interrogativas: + +```java +public static String getTypeOfSentence(String sentence) { + if (sentence.endsWith("?")) { + return "pregunta"; + } + + return "general"; +} + +App.getTypeOfSentence("Hola"); // "general" +App.getTypeOfSentence("¿Hola?"); // "pregunta" +``` + +`if` es una construcción del lenguaje que controla el orden de las instrucciones. Se le pasa una expresión lógica entre paréntesis y luego se describe un bloque de código entre llaves. Este bloque de código se ejecutará solo si la condición se cumple. + +Si la condición no se cumple, se omitirá el bloque de código entre llaves y el método continuará su ejecución. En nuestro caso, la siguiente línea de código, `return "general";`, hará que el método devuelva una cadena y finalice. diff --git a/modules/80-conditionals/30-if/es/data.yml b/modules/80-conditionals/30-if/es/data.yml new file mode 100644 index 00000000..7e9def0a --- /dev/null +++ b/modules/80-conditionals/30-if/es/data.yml @@ -0,0 +1,3 @@ +name: Estructura condicional (if) +tips: [] +definitions: [] diff --git a/modules/80-conditionals/30-if/ru/EXERCISE.md b/modules/80-conditionals/30-if/ru/EXERCISE.md new file mode 100644 index 00000000..d35ad010 --- /dev/null +++ b/modules/80-conditionals/30-if/ru/EXERCISE.md @@ -0,0 +1,16 @@ + +Реализуйте метод `getSentenceTone()`, который принимает строку и определяет тон предложения. Если все символы в верхнем регистре, то это вопль — `scream`. В ином случае — нормальное предложение — `normal`. + +Примеры вызова: + +```java +App.getSentenceTone("Hello"); // "normal" +App.getSentenceTone("WOW"); // "scream" +``` + +Алгоритм: + +1. Сгенерируйте строку в верхнем регистре на основе строки-аргумента с помощью `toUpperCase()`. +2. Сравните её с исходной строкой: + * Если строки равны, значит, строка-аргумент в верхнем регистре + * В ином случае — строка-аргумент не в верхнем регистре diff --git a/modules/80-conditionals/30-if/ru/README.md b/modules/80-conditionals/30-if/ru/README.md new file mode 100644 index 00000000..329fed3a --- /dev/null +++ b/modules/80-conditionals/30-if/ru/README.md @@ -0,0 +1,24 @@ +Условные конструкции позволяют выполнять разный код, основываясь на логических проверках. Посмотрим на таком типичном примере: + +* Человек хочет оплатить покупку с карты +* Если на счету есть деньги, то нужная сумма спишется автоматически +* Если денег нет, то операция будет отклонена + +Для примера напишем метод, который определяет тип переданного предложения. Для начала он будет отличать обычные предложения от вопросительных: + +```java +public static String getTypeOfSentence(String sentence) { + if (sentence.endsWith("?")) { + return "question"; + } + + return "general"; +} + +App.getTypeOfSentence("Hodor"); // "general" +App.getTypeOfSentence("Hodor?"); // "question" +``` + +`if` — конструкция языка, управляющая порядком инструкций. В скобках ей передается логическое выражение, а затем описывается блок кода в фигурных скобках. Этот блок кода будет выполнен, только если условие выполняется. + +Если условие не выполняется, то блок кода в фигурных скобках пропускается, и метод продолжает свое выполнение дальше. В нашем случае следующая строчка кода — `return "general";` — заставит метод вернуть строку и завершиться. diff --git a/modules/80-conditionals/30-if/ru/data.yml b/modules/80-conditionals/30-if/ru/data.yml new file mode 100644 index 00000000..60a8d44a --- /dev/null +++ b/modules/80-conditionals/30-if/ru/data.yml @@ -0,0 +1,3 @@ +name: Условная конструкция (if) +tips: [] +definitions: [] diff --git a/modules/80-conditionals/40-if-else/es/EXERCISE.md b/modules/80-conditionals/40-if-else/es/EXERCISE.md new file mode 100644 index 00000000..ffe11157 --- /dev/null +++ b/modules/80-conditionals/40-if-else/es/EXERCISE.md @@ -0,0 +1,11 @@ + +Implementa el método `normalizeUrl()`, que realiza lo que se conoce como normalización de datos. Recibe una dirección de un sitio web y devuelve la dirección con *https://* al principio. + +El método recibe 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()` para verificar si una cadena comienza con el prefijo *https://*. Luego, en base a esto, agregar o no agregar *https://*. + +```java +App.normalizeUrl("google.com"); // "https://google.com" +App.normalizeUrl("https://ai.fi"); // "https://ai.fi" +``` diff --git a/modules/80-conditionals/40-if-else/es/README.md b/modules/80-conditionals/40-if-else/es/README.md new file mode 100644 index 00000000..2de53335 --- /dev/null +++ b/modules/80-conditionals/40-if-else/es/README.md @@ -0,0 +1,33 @@ +La estructura condicional `if` tiene varias variantes. Una variante incluye un bloque que se ejecuta si la condición es falsa: + +```java +if (x > 5) { + // Si la condición es verdadera +} else { + // Si la condición es falsa +} +``` + +Esta estructura puede ser útil para la inicialización de valores. En el siguiente ejemplo, se verifica la existencia de un `email`. Si está ausente, se establece un valor predeterminado; si se proporciona, se realiza una normalización: + +```java +// Aquí viene el email + +if (email.equals("")) { // Si el email está vacío, establecer el valor predeterminado + email = "support@hexlet.io"; +} else { // De lo contrario, realizar la normalización + email = email.trim().toLowerCase(); +} + +// Aquí se utiliza este correo electrónico +``` + +Si la rama `if` contiene un `return`, entonces el `else` no es necesario, se puede omitir simplemente: + +```java +if (/* condición */) { + return /* algún valor */; +} + +// Continuar haciendo algo, porque no se necesita el else +``` diff --git a/modules/80-conditionals/40-if-else/es/data.yml b/modules/80-conditionals/40-if-else/es/data.yml new file mode 100644 index 00000000..765bfbeb --- /dev/null +++ b/modules/80-conditionals/40-if-else/es/data.yml @@ -0,0 +1 @@ +name: Estructura if-else diff --git a/modules/80-conditionals/40-if-else/ru/EXERCISE.md b/modules/80-conditionals/40-if-else/ru/EXERCISE.md new file mode 100644 index 00000000..75d0823e --- /dev/null +++ b/modules/80-conditionals/40-if-else/ru/EXERCISE.md @@ -0,0 +1,11 @@ + +Реализуйте метод `normalizeUrl()`, который выполняет так называемую нормализацию данных. Он принимает адрес сайта и возвращает его с *https://* в начале. + +Метод принимает адреса в виде *АДРЕС* или *https://АДРЕС*, но всегда возвращает адрес в виде *https://АДРЕС* + +Можно использовать метод `startsWith()` чтобы проверить начинается ли строка с префикса *https://*. А потом на основе этого добавлять или не добавлять *https://*. + +```java +App.normalizeUrl("google.com"); // "https://google.com" +App.normalizeUrl("https://ai.fi"); // "https://ai.fi" +``` diff --git a/modules/80-conditionals/40-if-else/ru/README.md b/modules/80-conditionals/40-if-else/ru/README.md new file mode 100644 index 00000000..c7b51238 --- /dev/null +++ b/modules/80-conditionals/40-if-else/ru/README.md @@ -0,0 +1,33 @@ +Условная конструкция `if` имеет несколько разновидностей. Одна разновидность включает в себя блок, который выполняется, если условие ложно: + +```java +if (x > 5) { + // Если условие true +} else { + // Если условие false +} +``` + +Такая структура может понадобиться при начальной инициализации значения. В примере ниже проверяется наличие `email`. Если он отсутствует, то устанавливаем значение по умолчанию, если его передали, то выполняем нормализацию: + +```java +// Здесь приходит email + +if (email.equals("")) { // Если email пустой, то ставим дефолт + email = "support@hexlet.io"; +} else { // Иначе выполняем нормализацию + email = email.trim().toLowerCase(); +} + +// Здесь используем эту почту +``` + +Если ветка `if` содержит `return`, то `else` становится не нужен — его можно просто опустить: + +```java +if (/* условие */) { + return /* какое-то значение */; +} + +// Продолжаем что-то делать, потому что else не нужен +``` diff --git a/modules/80-conditionals/40-if-else/ru/data.yml b/modules/80-conditionals/40-if-else/ru/data.yml new file mode 100644 index 00000000..eb5e61c8 --- /dev/null +++ b/modules/80-conditionals/40-if-else/ru/data.yml @@ -0,0 +1 @@ +name: Конструкция if-else diff --git a/modules/80-conditionals/50-else-if/es/EXERCISE.md b/modules/80-conditionals/50-else-if/es/EXERCISE.md new file mode 100644 index 00000000..5fc6ee85 --- /dev/null +++ b/modules/80-conditionals/50-else-if/es/EXERCISE.md @@ -0,0 +1,19 @@ + +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. + +Escriba un método `whoIsThisHouseToStarks()` para Sam, 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: + +```java +App.whoIsThisHouseToStarks("Karstark"); // "friend" +App.whoIsThisHouseToStarks("Frey"); // "enemy" +App.whoIsThisHouseToStarks("Joar"); // "neutral" +App.whoIsThisHouseToStarks("Ivanov"); // "neutral" +``` diff --git a/modules/80-conditionals/50-else-if/es/README.md b/modules/80-conditionals/50-else-if/es/README.md new file mode 100644 index 00000000..7d3b4651 --- /dev/null +++ b/modules/80-conditionals/50-else-if/es/README.md @@ -0,0 +1,51 @@ +En su versión más completa, la estructura `if` no solo contiene la rama `else`, sino también otras comprobaciones condicionales utilizando `else if`. Esta variante se utiliza cuando hay muchas comprobaciones que se excluyen mutuamente: + +```java +if (/* algo */) { + +} else if (/* otra comprobación */) { + +} else if (/* otra comprobación */) { + +} else { + +} +``` + +Aquí hay dos puntos a tener en cuenta: + +* La rama `else` puede estar ausente. +* El número de condiciones `else if` puede ser cualquier cantidad. + +Escribamos un método extendido como ejemplo para determinar el tipo de oración. Reconoce tres tipos de oraciones: + +```java +App.getTypeOfSentence("¿Quién?"); // "La oración es una pregunta" +App.getTypeOfSentence("No"); // "La oración es general" +App.getTypeOfSentence("¡No!"); // "La oración es una exclamación" + +public static String getTypeOfSentence(String sentence) +{ + var sentenceType = ""; + + if (sentence.endsWith("?")) { + sentenceType = "pregunta"; + } else if (sentence.endsWith("!")) { + sentenceType = "exclamación"; + } else { + sentenceType = "general"; + } + + return "La oración es " + sentenceType; +} +``` + +https://replit.com/@hexlet/java-basics-if-else + +Ahora todas las condiciones están organizadas en una única estructura. El operador `else if` significa "si la condición anterior no se cumple, pero la condición actual sí se cumple". La estructura es la siguiente: + +- Si el último carácter es `?`, entonces "pregunta" +- De lo contrario, si el último carácter es `!`, entonces "exclamación" +- De lo contrario, "general" + +En consecuencia, solo se ejecutará uno de los bloques de código relacionados con toda la estructura `if`. diff --git a/modules/80-conditionals/50-else-if/es/data.yml b/modules/80-conditionals/50-else-if/es/data.yml new file mode 100644 index 00000000..81ddf343 --- /dev/null +++ b/modules/80-conditionals/50-else-if/es/data.yml @@ -0,0 +1 @@ +name: Estructura else if diff --git a/modules/80-conditionals/50-else-if/ru/EXERCISE.md b/modules/80-conditionals/50-else-if/ru/EXERCISE.md new file mode 100644 index 00000000..58a06e3d --- /dev/null +++ b/modules/80-conditionals/50-else-if/ru/EXERCISE.md @@ -0,0 +1,19 @@ + +На электронной карте Вестероса, которую реализовал Сэм, союзники Старков отображены зеленым кружком, враги — красным, а нейтральные семьи — серым. + +Напишите для Сэма метод `whoIsThisHouseToStarks()`, который принимает на вход фамилию семьи и возвращает одно из трех значений: `"friend"`, `"enemy"`, `"neutral"`. + +Правила определения: + + * Друзья (`"friend"`): "Karstark", "Tally" + * Враги (`"enemy"`): "Lannister", "Frey" + * Любые другие семьи считаются нейтральными + +Примеры вызова: + +```java +App.whoIsThisHouseToStarks("Karstark"); // "friend" +App.whoIsThisHouseToStarks("Frey"); // "enemy" +App.whoIsThisHouseToStarks("Joar"); // "neutral" +App.whoIsThisHouseToStarks("Ivanov"); // "neutral" +``` diff --git a/modules/80-conditionals/50-else-if/ru/README.md b/modules/80-conditionals/50-else-if/ru/README.md new file mode 100644 index 00000000..7867658b --- /dev/null +++ b/modules/80-conditionals/50-else-if/ru/README.md @@ -0,0 +1,51 @@ +В самой полной версии конструкция `if` содержит не только ветку `else`, но и другие условные проверки с помощью `else if`. Такой вариант используется при большом количестве проверок, которые взаимоисключают друг друга: + +```java +if (/* что-то */) { + +} else if (/* другая проверка */) { + +} else if (/* другая проверка */) { + +} else { + +} +``` + +Здесь стоит обратить внимание на два момента: + +* Ветка `else` может отсутствовать +* Количество `else if` условий может быть любым + +Напишем для примера расширенный метод определяющий тип предложения. Он распознает три вида предложений: + +```java +App.getTypeOfSentence("Who?"); // "Sentence is question" +App.getTypeOfSentence("No"); // "Sentence is general" +App.getTypeOfSentence("No!"); // "Sentence is exclamation" + +public static String getTypeOfSentence(String sentence) +{ + var sentenceType = ""; + + if (sentence.endsWith("?")) { + sentenceType = "question"; + } else if (sentence.endsWith("!")) { + sentenceType = "exclamation"; + } else { + sentenceType = "general"; + } + + return "Sentence is " + sentenceType; +} +``` + +https://replit.com/@hexlet/java-basics-if-else + +Теперь все условия выстроены в единую конструкцию. Оператор `else if` — это «если не выполнено предыдущее условие, но выполнено текущее». Получается такая схема: + +- Если последний символ `?`, то "question" +- Иначе, если последний символ `!`, то "exclamation" +- Иначе "general" + +В итоге выполнится только один из блоков кода, относящихся ко всей конструкции `if`. diff --git a/modules/80-conditionals/50-else-if/ru/data.yml b/modules/80-conditionals/50-else-if/ru/data.yml new file mode 100644 index 00000000..31be8f2c --- /dev/null +++ b/modules/80-conditionals/50-else-if/ru/data.yml @@ -0,0 +1 @@ +name: Конструкция else if diff --git a/modules/80-conditionals/60-ternary-operator/es/EXERCISE.md b/modules/80-conditionals/60-ternary-operator/es/EXERCISE.md new file mode 100644 index 00000000..dda8c303 --- /dev/null +++ b/modules/80-conditionals/60-ternary-operator/es/EXERCISE.md @@ -0,0 +1,13 @@ + +Implementa el método `convertString()`, que recibe una cadena de texto y, si la primera letra no es mayúscula, devuelve la versión invertida de la cadena original. Si la primera letra es mayúscula, la cadena se devuelve sin cambios. Si se pasa una cadena vacía como entrada, el método debe devolver una cadena vacía. + +```java +App.convertString("Hello"); // "Hello" +App.convertString("hello"); // "olleh" + +// ¡No olvides tener en cuenta la cadena vacía! +App.convertString(""); // "" +``` + +* `StringUtils.reverse()` – invierte una cadena de texto +* `Character.isUpperCase()` – verifica si un carácter está en mayúscula diff --git a/modules/80-conditionals/60-ternary-operator/es/README.md b/modules/80-conditionals/60-ternary-operator/es/README.md new file mode 100644 index 00000000..4dfcdcdb --- /dev/null +++ b/modules/80-conditionals/60-ternary-operator/es/README.md @@ -0,0 +1,36 @@ +Observa la definición de un método que devuelve el módulo de un número: + +```java +// Si es mayor o igual a cero, devuelve el número. Si es menor, quita el signo +public static int abs(int number) { + if (number >= 0) { + return number; + } + + return -number; +} + +App.abs(10); // 10 +App.abs(-10); // 10 +``` + +En Java existe una construcción que es similar a la estructura *if-else*, pero es una expresión. Se llama **operador ternario**. + +El operador ternario es único en su tipo, ya que requiere tres operandos. Ayuda a escribir menos código para expresiones condicionales simples. Nuestro ejemplo anterior con el operador ternario se reduce a tres líneas de código: + +```java +public static int abs(int number) { + return number >= 0 ? number : -number; +} +``` + +El patrón general se ve así: + +```java +
+4diff --git a/modules/90-loops/100-while/es/README.md b/modules/90-loops/100-while/es/README.md new file mode 100644 index 00000000..52ff8e2e --- /dev/null +++ b/modules/90-loops/100-while/es/README.md @@ -0,0 +1,121 @@ +Los programas que escribimos durante el aprendizaje se vuelven cada vez más complejos y extensos. Aunque todavía están muy lejos de los programas reales, donde la cantidad de líneas de código se mide en decenas y cientos de miles, la complejidad actual puede ser desafiante para las personas sin experiencia. + +A partir de esta lección, nos adentraremos en uno de los temas básicos más complejos de la programación: los **ciclos**. + +Todos los programas de aplicación tienen objetivos muy pragmáticos. Ayudan a gestionar empleados, finanzas y, en última instancia, a entretener. A pesar de las diferencias, todos estos programas ejecutan algoritmos que son muy similares entre sí. + +Un **algoritmo** es una secuencia de acciones o instrucciones que nos lleva a un resultado esperado. Esta descripción se aplica a cualquier programa, pero los algoritmos suelen ser algo más específicos. + +Imagina que tenemos un libro y queremos encontrar una frase específica en su interior. Recordamos la frase, pero no sabemos en qué página está. ¿Cómo podemos encontrar la página que buscamos? + +La forma más sencilla y lenta es revisar el libro secuencialmente hasta encontrar la página deseada. En el peor de los casos, tendríamos que revisar todas las páginas, pero de todas formas obtendríamos el resultado. + +Este proceso se llama **algoritmo**. Incluye la búsqueda de páginas y comprobaciones lógicas para determinar si encontramos la frase o no. No sabemos de antemano cuántas páginas tendremos que revisar, pero el proceso de revisión se repite de la misma manera una y otra vez. + +Para realizar acciones repetitivas, necesitamos los ciclos. Cada repetición se llama **iteración**. + +Supongamos que queremos escribir un método que imprima en pantalla todos los números del 1 al número que se especifica como parámetro: + +```java +App.printNumbers(3); +// 1 +// 2 +// 3 +``` + +No podemos implementar este método con los conocimientos que ya tenemos, ya que no sabemos de antemano cuántas veces se imprimirá en pantalla. Pero con los ciclos, esto no es un problema: + +```java +public static void printNumbers(int lastNumber) { + // i es una abreviatura de "índice" + // Se utiliza por convención en muchos lenguajes como contador del ciclo + var i = 1; + + while (i <= lastNumber) { + System.out.println(i); + i = i + 1; + } + System.out.println("finished!"); +} + +App.printNumbers(3); +``` + +
3
2
1
finished! +
+1 +2 +3 +finished! ++ +https://replit.com/@hexlet/java-basics-while + +En el código del método se utiliza el ciclo `while`. Está compuesto por tres elementos: + +* La **palabra clave** `while`. Aunque se parece a una llamada a un método, no lo es. +* El **predicado** es una condición que se especifica entre paréntesis después de `while` y se evalúa en cada iteración. +* El **cuerpo del ciclo** es un bloque de código entre llaves, similar a un bloque de código en un método. Todas las constantes o variables definidas dentro de este bloque solo serán visibles dentro de él. + +La construcción se lee de la siguiente manera: "haz lo que se especifica en el cuerpo del ciclo mientras la condición `i <= lastNumber` sea verdadera". Veamos cómo funciona este código para la llamada `App.printNumbers(3)`: + +```java +// Se inicializa i +var i = 1; + +// El predicado devuelve true, por lo que se ejecuta el cuerpo del ciclo +while (1 <= 3) +// System.out.println(1); +// i = 1 + 1; + +// Se termina el cuerpo del ciclo, por lo que se vuelve al principio +while (2 <= 3) +// System.out.println(2); +// i = 2 + 1; + +// Se termina el cuerpo del ciclo, por lo que se vuelve al principio +while (3 <= 3) +// System.out.println(3); +// i = 3 + 1; + +// El predicado devuelve false, por lo que la ejecución continúa después del ciclo +while (4 <= 3) + +// System.out.println("finished!"); +// En este punto, i es igual a 4, pero ya no lo necesitamos +// El método finaliza +``` + +Lo más importante en un ciclo es su **finalización**, es decir, **salir del ciclo**. El proceso que genera el ciclo debe detenerse en algún momento. La responsabilidad de detenerlo recae completamente en el programador. + +Por lo general, la tarea se reduce a introducir una variable llamada **contador del ciclo**. Funciona de la siguiente manera: + +* Primero, se inicializa el contador, es decir, se le asigna un valor inicial. En el ejemplo anterior, el contador es la instrucción `var i = 1`, que se ejecuta antes de entrar al ciclo. +* Luego, en la condición del ciclo, se verifica si el contador ha alcanzado su valor límite. +* Finalmente, el contador cambia su valor `i = i + 1` + +Los principiantes cometen la mayoría de los errores en este punto. Supongamos que hay un error en la verificación del predicado. Esto puede llevar a un **bucle infinito**, una situación en la que el ciclo se ejecuta indefinidamente y el programa nunca se detiene. + +En ese caso, tendríamos que detenerlo forzosamente: + +```java +public static void printNumbers(int lastNumber) { + var i = 1; + + // Este ciclo nunca se detendrá + // y siempre imprimirá el mismo valor + while (i <= lastNumber) { + System.out.println(i); + } + System.out.println("finished!"); +} +``` + +En algunos casos, los bucles infinitos son útiles. No los estamos considerando aquí, pero es útil ver cómo se ve este código: + +```java +while (true) { + // Hacer algo +} +``` + +En resumen, ¿cuándo se necesitan los ciclos y cuándo se pueden evitar? No se pueden evitar los ciclos cuando el algoritmo para resolver un problema requiere la repetición de ciertas acciones y no se conoce de antemano la cantidad de operaciones necesarias. Esto fue evidente en el ejemplo del libro que vimos al comienzo de la lección. diff --git a/modules/90-loops/100-while/es/data.yml b/modules/90-loops/100-while/es/data.yml new file mode 100644 index 00000000..94c16f5e --- /dev/null +++ b/modules/90-loops/100-while/es/data.yml @@ -0,0 +1,6 @@ +name: Ciclo While +definitions: + - name: Bucle While + description: >- + una instrucción para repetir un bloque de código mientras se cumple una + determinada condición. diff --git a/modules/90-loops/100-while/ru/EXERCISE.md b/modules/90-loops/100-while/ru/EXERCISE.md new file mode 100644 index 00000000..3f4c40be --- /dev/null +++ b/modules/90-loops/100-while/ru/EXERCISE.md @@ -0,0 +1,12 @@ + +Модифицируйте метод `printNumbers()` так, чтобы он выводил числа в обратном порядке. Для этого нужно идти от верхней границы к нижней. То есть счётчик должен быть инициализирован максимальным значением, а в теле цикла его нужно уменьшать до нижней границы. + +Пример вызова и вывода: + +```java +printNumbers(4); +``` + +
+ 4diff --git a/modules/90-loops/100-while/ru/README.md b/modules/90-loops/100-while/ru/README.md new file mode 100644 index 00000000..8bed61b7 --- /dev/null +++ b/modules/90-loops/100-while/ru/README.md @@ -0,0 +1,121 @@ +Программы, которые мы пишем во время обучения, становятся все сложнее и объемнее. Они все еще очень далеки от реальных программ, где количество строк кода измеряется десятками и сотнями тысяч, но текущая сложность уже способна заставить напрячься людей без опыта. + +Начиная с этого урока, мы переходим к одной из самых сложных базовых тем в программировании – **циклам**. + +Любые прикладные программы служат очень прагматичным целям. Они помогают управлять сотрудниками, финансами, развлекают в конце концов. Несмотря на различия, все эти программы выполняют заложенные в них алгоритмы, которые очень похожи между собой. + +**Алгоритм** — это последовательность действий или инструкций, которая приводит нас к какому-то ожидаемому результату. Это описание подходит под любую программу, но под алгоритмами обычно понимается что-то более специфичное. + +Представьте себе, что у нас есть книга и мы хотим найти внутри нее какую-то конкретную фразу. Саму фразу мы помним, но не знаем, на какой она странице. Как найти нужную страницу? + +Самый простой и долгий способ — последовательно просматривать книгу до тех пор, пока мы не найдем нужную страницу. В худшем случае придется просмотреть все страницы, но результат мы все равно получим. + +Именно этот процесс и называется **алгоритмом**. Он включает в себя перебор страниц и логические проверки, нашли мы фразу или нет. Количество страниц, которое придется посмотреть, заранее неизвестно, но сам процесс просмотра повторяется из раза в раз совершенно одинаковым образом. + +Для выполнения повторяющихся действий как раз и нужны циклы. Каждый такой повтор называется **итерацией**. + +Допустим, мы хотим написать метод. Он должен выводить на экран все числа от 1 до того числа, которое мы указали через параметры: + +```java +App.printNumbers(3); +// 1 +// 2 +// 3 +``` + +Этот метод невозможно реализовать уже изученными средствами, так как количество выводов на экран заранее неизвестно. А с циклами это не составит никаких проблем: + +```java +public static void printNumbers(int lastNumber) { + // i — это сокращение от index (порядковый номер) + // Используется по общему соглашению во множестве языков как счетчик цикла + var i = 1; + + while (i <= lastNumber) { + System.out.println(i); + i = i + 1; + } + System.out.println("finished!"); +} + +App.printNumbers(3); +``` + +
3
2
1
finished! +
+1 +2 +3 +finished! ++ +https://replit.com/@hexlet/java-basics-while + +В коде метода использован цикл `while`. Он состоит из трех элементов: + +* **Ключевое слово** `while`. Несмотря на схожесть с вызовом методов, это не вызов метода +* **Предикат** — условие, которое указывается в скобках после `while` и вычисляется на каждой итерации +* **Тело цикла** — блок кода в фигурных скобках, аналогичный блоку кода в методе. Все константы или переменные, определенные внутри этого блока, будут видны только внутри этого блока + +Конструкция читается так: «делать то, что указано в теле цикла, пока истинно условие `i <= lastNumber`». Разберем работу этого кода для вызова `App.printNumbers(3)`: + +```java +// Инициализируется i +var i = 1; + +// Предикат возвращает true, поэтому выполняется тело цикла +while (1 <= 3) +// System.out.println(1); +// i = 1 + 1; + +// Закончилось тело цикла, поэтому происходит возврат в начало +while (2 <= 3) +// System.out.println(2); +// i = 2 + 1; + +// Закончилось тело цикла, поэтому происходит возврат в начало +while (3 <= 3) +// System.out.println(3); +// i = 3 + 1; + +// Предикат возвращает false, поэтому выполнение переходит за цикл +while (4 <= 3) + +// System.out.println("finished!"); +// На этом этапе i равен 4, но он нам уже не нужен +// Метод завершается +``` + +Самое главное в цикле — завершение его работы, то есть **выход из цикла**. Процесс, который порождает цикл, должен в конце концов остановиться. Ответственность за остановку полностью лежит на программисте. + +Обычно задача сводится к введению переменной, называемой **счетчиком цикла**. Он работает по такому принципу: + +* Сначала счетчик инициализируется, то есть ему задается начальное значение. В примере выше счетчик — это инструкция `var i = 1`, выполняемая до входа в цикл +* Затем в условии цикла проверяется, достиг ли счетчик своего предельного значения. +* В итоге счетчик меняет свое значение `i = i + 1` + +На этом моменте новички делают больше всего ошибок. Представим, что в коде неправильно написана проверка в предикате. Это может привести к **зацикливанию** — ситуация, при которой цикл работает бесконечно и программа никогда не останавливается. + +В таком случае приходится ее завершать принудительно: + +```java +public static void printNumbers(int lastNumber) { + var i = 1; + + // Этот цикл никогда не остановится + // и будет печатать всегда одно значение + while (i <= lastNumber) { + System.out.println(i); + } + System.out.println("finished!"); +} +``` + +В некоторых случаях бесконечные циклы полезны. Здесь мы такие случаи не рассматриваем, но полезно увидеть, как выглядит этот код: + +```java +while (true) { + // Что-то делаем +} +``` + +Подведем итог. Когда все же нужны циклы, а когда можно обойтись без них? Невозможно обойтись без циклов тогда, когда алгоритм решения задачи требует повторения каких-то действий, при этом количество этих операций заранее неизвестно. Так и было в примере с книгой, который мы рассматривали в начале урока. diff --git a/modules/90-loops/100-while/ru/data.yml b/modules/90-loops/100-while/ru/data.yml new file mode 100644 index 00000000..46d012fe --- /dev/null +++ b/modules/90-loops/100-while/ru/data.yml @@ -0,0 +1,4 @@ +name: Цикл While +definitions: + - name: Цикл While + description: инструкция для повторения кода, пока удовлетворяется какое-то условие. diff --git a/modules/90-loops/150-aggregation-numbers/es/EXERCISE.md b/modules/90-loops/150-aggregation-numbers/es/EXERCISE.md new file mode 100644 index 00000000..dbde9fe5 --- /dev/null +++ b/modules/90-loops/150-aggregation-numbers/es/EXERCISE.md @@ -0,0 +1,8 @@ + +Implementa el método `multiplyNumbersFromRange()`, que multiplica los números en el rango especificado, incluyendo los límites del rango. Ejemplo de llamada: + +```java +App.multiplyNumbersFromRange(1, 5); // 1 * 2 * 3 * 4 * 5 = 120 +App.multiplyNumbersFromRange(2, 3); // 2 * 3 = 6 +App.multiplyNumbersFromRange(6, 6); // 6 +``` diff --git a/modules/90-loops/150-aggregation-numbers/es/README.md b/modules/90-loops/150-aggregation-numbers/es/README.md new file mode 100644 index 00000000..14f5c420 --- /dev/null +++ b/modules/90-loops/150-aggregation-numbers/es/README.md @@ -0,0 +1,87 @@ +En programación, hay una clase de problemas que no se pueden resolver sin bucles: se llaman **agregación de datos**. + +Estos problemas incluyen: + +* Encontrar el valor máximo +* Encontrar el valor mínimo +* Calcular la suma +* Calcular el promedio aritmético + +Su característica principal es que el resultado depende de todo el conjunto de datos. Para calcular la suma, es necesario sumar **todos** los números; para calcular el máximo, es necesario comparar **todos** los números. + +Todos aquellos que trabajan con números están familiarizados con este tema. Por ejemplo, los contadores o los especialistas en marketing a menudo trabajan con tablas en programas como Microsoft Excel o Google Sheets. + +Veamos el ejemplo más sencillo: encontrar la suma de un conjunto de números. Implementaremos una función que sume los números en un rango especificado, incluyendo los límites. + +En este caso, un **rango** es una serie de números desde un punto de inicio hasta un punto final. Por ejemplo, el rango `[1, 10]` incluye todos los números enteros del 1 al 10: + +```java +App.sumNumbersFromRange(5, 7); // 5 + 6 + 7 = 18 +App.sumNumbersFromRange(1, 2); // 1 + 2 = 3 + +// Un rango [1, 1] con el mismo inicio y fin también es un rango +// Incluye un solo número, que es el límite del rango +App.sumNumbersFromRange(1, 1); // 1 +App.sumNumbersFromRange(100, 100); // 100 +``` + +Para implementar este código, necesitaremos un bucle. Elegimos un bucle porque la suma de números es un proceso iterativo. Se repite para cada número, y el número de iteraciones depende del tamaño del rango. + +Para comprender mejor el tema, intenta responder a estas preguntas: + +* ¿Con qué valor inicializar el contador? +* ¿Cómo cambiará el contador? +* ¿Cuándo debe detenerse el bucle? + +Ahora echa un vistazo al siguiente código: + +```java +public static int sumNumbersFromRange(int start, int finish) { + // Técnicamente, se puede cambiar el valor de start, pero los argumentos de entrada deben mantenerse en su valor original + // Esto hace que el código sea más fácil de analizar + var i = start; + var sum = 0; // Inicialización de la suma + + while (i <= finish) { // Avanzamos hasta el final del rango + sum = sum + i; // Calculamos la suma para cada número + i = i + 1; // Pasamos al siguiente número en el rango + } + + // Devolvemos el resultado obtenido + return sum; +} +``` + +https://replit.com/@hexlet/java-basics-loops-using-1 + +La estructura general del bucle es la siguiente: + +* Un contador que se inicializa con el valor inicial del rango +* El bucle en sí, con una condición de finalización cuando se alcanza el final del rango +* La modificación del contador al final del cuerpo del bucle + +El número de iteraciones en este bucle es igual a `finish - start + 1`. Por ejemplo, se necesitan 3 iteraciones para calcular el rango del 5 al 7: + +```md +7 - 5 + 1 = 3 +``` + +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 del rango: `sum = sum + i`. Todo el proceso se ve así: + +```java +// Para llamar a sumNumbersFromRange(2, 5); +var sum = 0; +sum = sum + 2; // 2 +sum = sum + 3; // 5 +sum = sum + 4; // 9 +sum = sum + 5; // 14 +// 14 es la suma de los números en el rango [2, 5] +``` + +En matemáticas, existe el concepto de **elemento neutro de la operación**. Una operación con este elemento no cambia el valor sobre el que se realiza la operación: + +* En la suma, cualquier número más cero es igual al número original +* En la resta, es lo mismo +* Incluso en la concatenación, hay un elemento neutro: la cadena vacía `"" + "uno"` es `"uno"` diff --git a/modules/90-loops/150-aggregation-numbers/es/data.yml b/modules/90-loops/150-aggregation-numbers/es/data.yml new file mode 100644 index 00000000..f31c31fa --- /dev/null +++ b/modules/90-loops/150-aggregation-numbers/es/data.yml @@ -0,0 +1,2 @@ +name: Agregación de datos (Números) +tips: [] diff --git a/modules/90-loops/150-aggregation-numbers/ru/EXERCISE.md b/modules/90-loops/150-aggregation-numbers/ru/EXERCISE.md new file mode 100644 index 00000000..c0c12593 --- /dev/null +++ b/modules/90-loops/150-aggregation-numbers/ru/EXERCISE.md @@ -0,0 +1,8 @@ + +Реализуйте метод `multiplyNumbersFromRange()`, который перемножает числа в указанном диапазоне включая границы диапазона. Пример вызова: + +```java +App.multiplyNumbersFromRange(1, 5); // 1 * 2 * 3 * 4 * 5 = 120 +App.multiplyNumbersFromRange(2, 3); // 2 * 3 = 6 +App.multiplyNumbersFromRange(6, 6); // 6 +``` diff --git a/modules/90-loops/150-aggregation-numbers/ru/README.md b/modules/90-loops/150-aggregation-numbers/ru/README.md new file mode 100644 index 00000000..0fe39f3d --- /dev/null +++ b/modules/90-loops/150-aggregation-numbers/ru/README.md @@ -0,0 +1,87 @@ +В программировании есть отдельный класс задач, который не может обойтись без циклов — он называется **агрегированием данных**. + +К таким задачам относятся поиск: + +* Максимального значения +* Минимального значения +* Суммы +* Среднего арифметического + +Их главная особенность в том, что результат зависит от всего набора данных. Для расчета суммы нужно сложить **все** числа, для вычисления максимального нужно сравнить **все** числа. + +С этой темой хорошо знакомы все, кто занимаются числами. Например, с такими задачами часто работают бухгалтеры или маркетологи в таблицах наподобие Microsoft Excel или Google Sheets. + +Разберем самый простой пример — поиск суммы набора чисел. Реализуем функцию, которая складывает числа в указанном диапазоне, включая границы. + +В этом случае **диапазоном** называется ряд чисел от какого-то начала до определенного конца. Например, диапазон `[1, 10]` включает в себя все целые числа от 1 до 10: + +```java +App.sumNumbersFromRange(5, 7); // 5 + 6 + 7 = 18 +App.sumNumbersFromRange(1, 2); // 1 + 2 = 3 + +// Диапазон [1, 1] с одинаковым началом и концом – тоже диапазон +// Он включает одно число — саму границу диапазона +App.sumNumbersFromRange(1, 1); // 1 +App.sumNumbersFromRange(100, 100); // 100 +``` + +Для реализации этого кода нам понадобится цикл. Мы выбираем именно цикл, потому что сложение чисел – это итеративный процесс. Он повторяется для каждого числа, а количество итераций зависит от размера диапазона. + +Чтобы лучше понять тему, попробуйте ответить на вопросы: + +* Каким значением инициализировать счетчик? +* Как он будет изменяться? +* Когда цикл должен остановиться? + +А теперь посмотрите код ниже: + +```java +public static int sumNumbersFromRange(int start, int finish) { + // Технически можно менять start, но входные аргументы нужно оставлять в исходном значении + // Это сделает код проще для анализа + var i = start; + var sum = 0; // Инициализация суммы + + while (i <= finish) { // Двигаемся до конца диапазона + sum = sum + i; // Считаем сумму для каждого числа + i = i + 1; // Переходим к следующему числу в диапазоне + } + + // Возвращаем получившийся результат + return sum; +} +``` + +https://replit.com/@hexlet/java-basics-loops-using-1 + +Общая структура цикла здесь стандартна: + +* Счетчик, который инициализируется начальным значением диапазона +* Сам цикл с условием остановки при достижении конца диапазона +* Изменение счетчика в конце тела цикла + +Количество итераций в таком цикле равно `finish - start + 1`. Например, нужно 3 итерации, чтобы посчитать диапазон от 5 до 7: + +```md +7 - 5 + 1 = 3 +``` + +Главные отличия от обычной обработки связаны с логикой вычислений результата. В задачах на агрегацию всегда есть какая-то переменная, которая хранит внутри себя результат работы цикла. В коде выше это `sum`. + +На каждой итерации цикла происходит ее изменение, прибавление следующего числа в диапазоне: `sum = sum + i`. Весь процесс выглядит так: + +```java +// Для вызова sumNumbersFromRange(2, 5); +var sum = 0; +sum = sum + 2; // 2 +sum = sum + 3; // 5 +sum = sum + 4; // 9 +sum = sum + 5; // 14 +// 14 – результат сложения чисел в диапазоне [2, 5] +``` + +В математике существует понятие **нейтральный элемент операции**. Операция с таким элементом не изменяет то значение, над которым проводится операция: + +* В сложении любое число плюс ноль дает само число +* При вычитании – то же самое +* Даже у конкатенации есть нейтральный элемент – это пустая строка: `"" + "one"` будет `"one"` diff --git a/modules/90-loops/150-aggregation-numbers/ru/data.yml b/modules/90-loops/150-aggregation-numbers/ru/data.yml new file mode 100644 index 00000000..8d9f36e4 --- /dev/null +++ b/modules/90-loops/150-aggregation-numbers/ru/data.yml @@ -0,0 +1,2 @@ +name: Агрегация данных (Числа) +tips: [] diff --git a/modules/90-loops/200-aggregation-strings/es/EXERCISE.md b/modules/90-loops/200-aggregation-strings/es/EXERCISE.md new file mode 100644 index 00000000..85edf121 --- /dev/null +++ b/modules/90-loops/200-aggregation-strings/es/EXERCISE.md @@ -0,0 +1,8 @@ + +Implementa el método `joinNumbersFromRange()`, que une todos los números del rango en una cadena: + +```java +App.joinNumbersFromRange(1, 1); // "1" +App.joinNumbersFromRange(2, 3); // "23" +App.joinNumbersFromRange(5, 10); // "5678910" +``` diff --git a/modules/90-loops/200-aggregation-strings/es/README.md b/modules/90-loops/200-aggregation-strings/es/README.md new file mode 100644 index 00000000..962b4596 --- /dev/null +++ b/modules/90-loops/200-aggregation-strings/es/README.md @@ -0,0 +1,35 @@ +La agregación se aplica no solo a los números, sino también a las cadenas. + +Al agregar cadenas, la cadena se forma dinámicamente, es decir, no se sabe de antemano su tamaño ni qué contendrá. Imagina un método que puede multiplicar una cadena, es decir, repetirla la cantidad de veces especificada: + +```java +App.repeat("hexlet", 3); // "hexlethexlethexlet" +``` + +El principio de funcionamiento de este método es bastante simple. En un bucle, la cadena se incrementa la cantidad de veces especificada: + +```java +public static String repeat(String text, int times) { + // El elemento neutro para las cadenas es una cadena vacía + var result = ""; + var i = 1; + + while (i <= times) { + // Agregamos la cadena al resultado cada vez + result = result + text; + i = i + 1; + } + + return result; +} +``` + +Desglosemos la ejecución de este código paso a paso: + +```java +// Para llamar a repeat("hexlet", 3); +var result = ""; +result = result + "hexlet"; // "hexlet" +result = result + "hexlet"; // "hexlethexlet" +result = result + "hexlet"; // "hexlethexlethexlet" +``` diff --git a/modules/90-loops/200-aggregation-strings/es/data.yml b/modules/90-loops/200-aggregation-strings/es/data.yml new file mode 100644 index 00000000..616ef67d --- /dev/null +++ b/modules/90-loops/200-aggregation-strings/es/data.yml @@ -0,0 +1,2 @@ +name: Agregación de datos (Cadenas) +tips: [] diff --git a/modules/90-loops/200-aggregation-strings/ru/EXERCISE.md b/modules/90-loops/200-aggregation-strings/ru/EXERCISE.md new file mode 100644 index 00000000..e01aa22f --- /dev/null +++ b/modules/90-loops/200-aggregation-strings/ru/EXERCISE.md @@ -0,0 +1,8 @@ + +Реализуйте метод `joinNumbersFromRange()`, который объединяет все числа из диапазона в строку: + +```java +App.joinNumbersFromRange(1, 1); // "1" +App.joinNumbersFromRange(2, 3); // "23" +App.joinNumbersFromRange(5, 10); // "5678910" +``` diff --git a/modules/90-loops/200-aggregation-strings/ru/README.md b/modules/90-loops/200-aggregation-strings/ru/README.md new file mode 100644 index 00000000..33f92010 --- /dev/null +++ b/modules/90-loops/200-aggregation-strings/ru/README.md @@ -0,0 +1,35 @@ +Агрегация применяется не только к числам, но и к строкам. + +При агрегации строка формируется динамически, то есть заранее неизвестно, какого она размера и что будет содержать. Представьте себе метод, который умеет умножать строку — то есть он повторяет ее указанное количество раз: + +```java +App.repeat("hexlet", 3); // "hexlethexlethexlet" +``` + +Принцип работы этого метода довольно простой. В цикле происходит наращивание строки указанное количество раз: + +```java +public static String repeat(String text, int times) { + // Нейтральный элемент для строк – пустая строка + var result = ""; + var i = 1; + + while (i <= times) { + // Каждый раз добавляем строку к результату + result = result + text; + i = i + 1; + } + + return result; +} +``` + +Распишем выполнение этого кода по шагам: + +```java +// Для вызова repeat("hexlet", 3); +var result = ""; +result = result + "hexlet"; // "hexlet" +result = result + "hexlet"; // "hexlethexlet" +result = result + "hexlet"; // "hexlethexlethexlet" +``` diff --git a/modules/90-loops/200-aggregation-strings/ru/data.yml b/modules/90-loops/200-aggregation-strings/ru/data.yml new file mode 100644 index 00000000..d2983e20 --- /dev/null +++ b/modules/90-loops/200-aggregation-strings/ru/data.yml @@ -0,0 +1,2 @@ +name: Агрегация данных (Строки) +tips: [] diff --git a/modules/90-loops/250-iteration-over-strings/es/EXERCISE.md b/modules/90-loops/250-iteration-over-strings/es/EXERCISE.md new file mode 100644 index 00000000..68f82b62 --- /dev/null +++ b/modules/90-loops/250-iteration-over-strings/es/EXERCISE.md @@ -0,0 +1,11 @@ + +Implementa el método estático `App.printReversedNameBySymbol()`, que imprime la palabra pasada como argumento carácter por carácter, en orden inverso, como se muestra en el ejemplo de la teoría. + +```java +var name = "Arya"; +App.printReversedNameBySymbol(name); +// 'a' +// 'y' +// 'r' +// 'A' +``` diff --git a/modules/90-loops/250-iteration-over-strings/es/README.md b/modules/90-loops/250-iteration-over-strings/es/README.md new file mode 100644 index 00000000..7eb9ec47 --- /dev/null +++ b/modules/90-loops/250-iteration-over-strings/es/README.md @@ -0,0 +1,28 @@ +Los bucles no solo son útiles para trabajar con números, sino también para trabajar con cadenas de texto. Esto se debe principalmente a la capacidad de acceder a un carácter específico mediante su índice. A continuación se muestra un ejemplo de código que imprime las letras de cada palabra en líneas separadas: + +```java +public static void printNameBySymbol(String name) { + var i = 0; + // Esta condición se evaluará 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 + System.out.println(name.charAt(i)); + i += 1; + } +} + +var name = "Arya"; +App.printNameBySymbol(name); +// "A" +// "r" +// "y" +// "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()` +* `i <= name.length() - 1` + +Ambas formas conducen al mismo resultado. diff --git a/modules/90-loops/250-iteration-over-strings/es/data.yml b/modules/90-loops/250-iteration-over-strings/es/data.yml new file mode 100644 index 00000000..6c3f1b63 --- /dev/null +++ b/modules/90-loops/250-iteration-over-strings/es/data.yml @@ -0,0 +1,2 @@ +name: Recorrido de caracteres +tips: [] diff --git a/modules/90-loops/250-iteration-over-strings/ru/EXERCISE.md b/modules/90-loops/250-iteration-over-strings/ru/EXERCISE.md new file mode 100644 index 00000000..a0518bb2 --- /dev/null +++ b/modules/90-loops/250-iteration-over-strings/ru/EXERCISE.md @@ -0,0 +1,11 @@ + +Реализуйте статический метод `App.printReversedNameBySymbol()`, который печатает переданное слово посимвольно, как в примере из теории, но делает это в обратном порядке. + +```java +var name = "Arya"; +App.printReversedNameBySymbol(name); +// 'a' +// 'y' +// 'r' +// 'A' +``` diff --git a/modules/90-loops/250-iteration-over-strings/ru/README.md b/modules/90-loops/250-iteration-over-strings/ru/README.md new file mode 100644 index 00000000..dc7f50f2 --- /dev/null +++ b/modules/90-loops/250-iteration-over-strings/ru/README.md @@ -0,0 +1,28 @@ +Циклы подходят не только для обработки чисел, но и при работе со строками. В первую очередь благодаря возможности получить конкретный символ по его индексу. Ниже пример кода, который распечатывает буквы каждого слова на отдельной строке: + +```java +public static void printNameBySymbol(String name) { + var i = 0; + // Такая проверка будет выполняться до конца строки + // включая последний символ. Его индекс `length() - 1`. + while (i < name.length()) { + // Обращаемся к символу по индексу + System.out.println(name.charAt(i)); + i += 1; + } +} + +var name = "Arya"; +App.printNameBySymbol(name); +// "A" +// "r" +// "y" +// "a" +``` + +Самое главное в этом коде — поставить правильное условие в `while`. Это можно сделать сразу двумя способами: + +* `i < name.length()` +* `i <= name.length() - 1` + +Оба способа приводят к одному результату. diff --git a/modules/90-loops/250-iteration-over-strings/ru/data.yml b/modules/90-loops/250-iteration-over-strings/ru/data.yml new file mode 100644 index 00000000..b7b08fce --- /dev/null +++ b/modules/90-loops/250-iteration-over-strings/ru/data.yml @@ -0,0 +1,2 @@ +name: Обход строк +tips: [] diff --git a/modules/90-loops/300-conditions-inside-loops/es/EXERCISE.md b/modules/90-loops/300-conditions-inside-loops/es/EXERCISE.md new file mode 100644 index 00000000..1826aa2c --- /dev/null +++ b/modules/90-loops/300-conditions-inside-loops/es/EXERCISE.md @@ -0,0 +1,9 @@ + +El método de la teoría tiene en cuenta el caso de las letras. Es decir, `A` y `a` son considerados caracteres diferentes. Implementa una versión de este mismo método en la que el caso de las letras no importe: + +```java +App.countChars("HexlEt", 'e'); // 2 +App.countChars("HexlEt", 'E'); // 2 +``` + +* `Character.toLowerCase()` - convierte un carácter a minúscula diff --git a/modules/90-loops/300-conditions-inside-loops/es/README.md b/modules/90-loops/300-conditions-inside-loops/es/README.md new file mode 100644 index 00000000..88e8b892 --- /dev/null +++ b/modules/90-loops/300-conditions-inside-loops/es/README.md @@ -0,0 +1,39 @@ +El cuerpo de un bucle, al igual que el cuerpo de un método, es el lugar donde se ejecutan las instrucciones. Esto significa que podemos utilizar todo lo que hemos aprendido hasta ahora, incluyendo construcciones condicionales. + +Veamos un método que cuenta cuántas veces aparece una letra en una oración: + +```java +countChars("El miedo corta más profundo que las espadas.", 'e'); // 4 +// Si no se encuentra ninguna coincidencia, el resultado es 0 +countChars("Sansa", 'y'); // 0 +``` + +Primero, intenta responder las siguientes preguntas: + +* ¿Es esta operación una agregación? +* ¿Cuál será la condición para verificar la aparición del carácter? + +Ahora veamos el fragmento de código: + +```java +public static int countChars(String str, char ch) { + var i = 0; + var count = 0; + while (i < str.length()) { + if (str.charAt(i) == ch) { + // Solo contamos los caracteres que coinciden + count = count + 1; + } + // El contador se incrementa de todas formas + i = i + 1; + } + + return count; +} +``` + +https://replit.com/@hexlet/java-basics-conditions-inside-loops + +Este problema es una agregación. El método cuenta solo los caracteres deseados, pero aún así es necesario analizar cada carácter para calcular la suma total. + +La diferencia clave de este bucle con los que hemos visto anteriormente es que tiene una condición dentro del cuerpo. La variable `count` solo se incrementa cuando el carácter actual coincide con el carácter esperado. De lo contrario, es un método agregado típico que devuelve la cantidad de caracteres deseados al código que lo llama. diff --git a/modules/90-loops/300-conditions-inside-loops/es/data.yml b/modules/90-loops/300-conditions-inside-loops/es/data.yml new file mode 100644 index 00000000..acbcd652 --- /dev/null +++ b/modules/90-loops/300-conditions-inside-loops/es/data.yml @@ -0,0 +1,2 @@ +name: Condiciones dentro de un bucle +tips: [] diff --git a/modules/90-loops/300-conditions-inside-loops/ru/EXERCISE.md b/modules/90-loops/300-conditions-inside-loops/ru/EXERCISE.md new file mode 100644 index 00000000..828ae2e3 --- /dev/null +++ b/modules/90-loops/300-conditions-inside-loops/ru/EXERCISE.md @@ -0,0 +1,9 @@ + +Метод из теории учитывает регистр букв. То есть `A` и `a` с его точки зрения разные символы. Реализуйте вариант этого же метода, так чтобы регистр букв был не важен: + +```java +App.countChars("HexlEt", 'e'); // 2 +App.countChars("HexlEt", 'E'); // 2 +``` + +* `Character.toLowerCase()` – переводит символ в нижний регистр diff --git a/modules/90-loops/300-conditions-inside-loops/ru/README.md b/modules/90-loops/300-conditions-inside-loops/ru/README.md new file mode 100644 index 00000000..221ebaf6 --- /dev/null +++ b/modules/90-loops/300-conditions-inside-loops/ru/README.md @@ -0,0 +1,39 @@ +Тело цикла, как и тело метода — это место выполнения инструкций. Значит, мы можем использовать внутри него все изученное ранее — в том числе условные конструкции. + +Рассмотрим метод, который считает, сколько раз входит буква в предложение: + +```java +countChars("Fear cuts deeper than swords.", 'e'); // 4 +// Если вы ничего не нашли, то результат — 0 совпадений +countChars("Sansa", 'y'); // 0 +``` + +Сначала попробуйте ответить на вопросы: + +* Является ли эта операция агрегацией? +* Какой будет проверка на вхождение символа? + +А теперь посмотрим на фрагмент кода: + +```java +public static int countChars(String str, char ch) { + var i = 0; + var count = 0; + while (i < str.length()) { + if (str.charAt(i) == ch) { + // Считаем только подходящие символы + count = count + 1; + } + // Счетчик увеличивается в любом случае + i = i + 1; + } + + return count; +} +``` + +https://replit.com/@hexlet/java-basics-conditions-inside-loops + +Эта задача является агрегирующей. Метод считает не все символы, но при этом для подсчета самой суммы все равно приходится анализировать каждый символ. + +Ключевое отличие этого цикла от рассмотренных в наличии условия внутри тела. Переменная `count` увеличивается только в том случае, когда текущий рассматриваемый символ совпадает с ожидаемым. В остальном — это типичный агрегатный метод, который возвращает количество нужных символов вызываемому коду. diff --git a/modules/90-loops/300-conditions-inside-loops/ru/data.yml b/modules/90-loops/300-conditions-inside-loops/ru/data.yml new file mode 100644 index 00000000..20450e80 --- /dev/null +++ b/modules/90-loops/300-conditions-inside-loops/ru/data.yml @@ -0,0 +1,2 @@ +name: Условия внутри тела цикла +tips: [] diff --git a/modules/90-loops/350-build-strings/es/EXERCISE.md b/modules/90-loops/350-build-strings/es/EXERCISE.md new file mode 100644 index 00000000..60a257b2 --- /dev/null +++ b/modules/90-loops/350-build-strings/es/EXERCISE.md @@ -0,0 +1,2 @@ + +Implementa el mismo método `reverse()`, pero realiza el recorrido de la cadena desde el último elemento hasta el primero. La estructura general de la función seguirá siendo la misma. Cambiará el índice inicial, la condición de finalización del bucle, la construcción de la nueva cadena y la actualización del índice en el bucle. diff --git a/modules/90-loops/350-build-strings/es/README.md b/modules/90-loops/350-build-strings/es/README.md new file mode 100644 index 00000000..f4b5e4ac --- /dev/null +++ b/modules/90-loops/350-build-strings/es/README.md @@ -0,0 +1,33 @@ +Otro uso de los bucles es la **formación de cadenas**. Este tipo de tarea es común en programación y se reduce a una simple agregación mediante concatenación. + +Hay una tarea que es popular en las entrevistas: **invertir una cadena**. Se puede resolver de muchas formas diferentes, pero la forma más básica es recorrerla carácter por carácter: + +```java +App.reverse("Hexlet"); // "telxeH" +``` + +La idea general de la inversión es tomar los caracteres uno por uno desde el principio de la cadena y unirlos en orden inverso. Veamos cómo funciona: + +```java +public static String reverse(String str) { + var i = str.length() - 1; + // El elemento neutral para las cadenas es una cadena vacía + var result = ""; + while (i >= 0) { + // Unir en orden inverso + result = result + str.charAt(i); + i -= 1; + } + + return result; +} + +var name = "Bran"; +App.reverse(name); // "narB" +// Comprobación del elemento neutral +App.reverse(""); // "" +``` + +https://replit.com/@hexlet/java-basics-loops-using-2 + +Es importante comprender cómo se construye la cadena: cada carácter siguiente se une a la cadena resultante por la izquierda, y al final la cadena queda invertida. diff --git a/modules/90-loops/350-build-strings/es/data.yml b/modules/90-loops/350-build-strings/es/data.yml new file mode 100644 index 00000000..69f4d641 --- /dev/null +++ b/modules/90-loops/350-build-strings/es/data.yml @@ -0,0 +1,2 @@ +name: Formación de cadenas en bucles +tips: [] diff --git a/modules/90-loops/350-build-strings/ru/EXERCISE.md b/modules/90-loops/350-build-strings/ru/EXERCISE.md new file mode 100644 index 00000000..1749e155 --- /dev/null +++ b/modules/90-loops/350-build-strings/ru/EXERCISE.md @@ -0,0 +1,2 @@ + +Реализуйте такой же метод `reverse()`, но выполняющий обход строки не с первого элемента по последний, а наоборот, от последнего к первому. Общая структура функции при этом останется такой же. Изменится начальный индекс, условие окончания цикла, сборка новой строки и формирование нового индекса в цикле. diff --git a/modules/90-loops/350-build-strings/ru/README.md b/modules/90-loops/350-build-strings/ru/README.md new file mode 100644 index 00000000..89105146 --- /dev/null +++ b/modules/90-loops/350-build-strings/ru/README.md @@ -0,0 +1,33 @@ +Еще одно использование циклов — **формирование строк**. Подобная задача нередко встречается в программировании. Она сводится к обычной агрегации через конкатенацию. + +Есть одна задача, которая популярна на собеседованиях — это **переворот строки**. Ее можно решить множеством разных способов, но именно посимвольный перебор считается базовым: + +```java +App.reverse("Hexlet"); // "telxeH" +``` + +Общая идея переворота состоит в следующем — нужно брать символы по очереди с начала строки и соединять их в обратном порядке. Давайте проверим, как это работает: + +```java +public static String reverse(String str) { + var i = 0; + // Нейтральный элемент для строк — это пустая строка + var result = ""; + while (i < str.length()) { + // Соединяем в обратном порядке + result = str.charAt(i) + result; + i += 1; + } + + return result; +} + +var name = "Bran"; +App.reverse(name); // "narB" +// Проверка нейтрального элемента +App.reverse(""); // "" +``` + +https://replit.com/@hexlet/java-basics-loops-using-2 + +Важно прочувствовать, как собирается сама строка — каждый следующий символ прикрепляется к результирующей строке слева, и в итоге строка оказывается перевернута. diff --git a/modules/90-loops/350-build-strings/ru/data.yml b/modules/90-loops/350-build-strings/ru/data.yml new file mode 100644 index 00000000..9f340093 --- /dev/null +++ b/modules/90-loops/350-build-strings/ru/data.yml @@ -0,0 +1,2 @@ +name: Формирование строк в циклах +tips: [] diff --git a/modules/90-loops/400-syntax-sugar/es/EXERCISE.md b/modules/90-loops/400-syntax-sugar/es/EXERCISE.md new file mode 100644 index 00000000..e568d08e --- /dev/null +++ b/modules/90-loops/400-syntax-sugar/es/EXERCISE.md @@ -0,0 +1,10 @@ + +Implementa el método estático `App.filterString()`, que recibe una cadena y un carácter, y devuelve una nueva cadena en la que se elimina el carácter proporcionado en todas sus posiciones. + +Ejemplo de llamada: + +```java +var str = "If I look back I am lost"; +App.filterString(str, 'I'); // "f look back am lost" +App.filterString(str, 'o'); // "If I lk back I am lst" +``` diff --git a/modules/90-loops/400-syntax-sugar/es/README.md b/modules/90-loops/400-syntax-sugar/es/README.md new file mode 100644 index 00000000..8954ce28 --- /dev/null +++ b/modules/90-loops/400-syntax-sugar/es/README.md @@ -0,0 +1,9 @@ +Las construcciones como `index = index + 1` se utilizan con bastante frecuencia en Java, por lo que los creadores del lenguaje agregaron una forma abreviada de escribirlo: `index += 1`. Estas abreviaciones se conocen como **azúcar sintáctico**, porque hacen que el proceso de escribir código sea un poco más fácil y agradable. + +Hay formas abreviadas para todas las operaciones aritméticas y para la concatenación de cadenas: + +* `a = a + 1` → `a += 1` +* `a = a - 1` → `a -= 1` +* `a = a * 2` → `a *= 2` +* `a = a / 1` → `a /= 1` +* `a = a + "foo"` → `a += "foo"` diff --git a/modules/90-loops/400-syntax-sugar/es/data.yml b/modules/90-loops/400-syntax-sugar/es/data.yml new file mode 100644 index 00000000..ef781e56 --- /dev/null +++ b/modules/90-loops/400-syntax-sugar/es/data.yml @@ -0,0 +1,2 @@ +name: Azúcar sintáctico +tips: [] diff --git a/modules/90-loops/400-syntax-sugar/ru/EXERCISE.md b/modules/90-loops/400-syntax-sugar/ru/EXERCISE.md new file mode 100644 index 00000000..ee4d4899 --- /dev/null +++ b/modules/90-loops/400-syntax-sugar/ru/EXERCISE.md @@ -0,0 +1,10 @@ + +Реализуйте статический метод `App.filterString()`, принимающую на вход строку и символ, и возвращающую новую строку, в которой удален переданный символ во всех его позициях. + +Пример вызова: + +```java +var str = "If I look back I am lost"; +App.filterString(str, 'I'); // "f look back am lost" +App.filterString(str, 'o'); // "If I lk back I am lst" +``` diff --git a/modules/90-loops/400-syntax-sugar/ru/README.md b/modules/90-loops/400-syntax-sugar/ru/README.md new file mode 100644 index 00000000..add601ba --- /dev/null +++ b/modules/90-loops/400-syntax-sugar/ru/README.md @@ -0,0 +1,9 @@ +Подобные конструкции `index = index + 1` в Java используются довольно часто, поэтому создатели языка добавили сокращенный вариант записи: `index += 1`. Такие сокращения принято называть **синтаксическим сахаром**, потому что они делают процесс написания кода немного проще и приятнее. + +Существуют сокращенные формы для всех арифметических операций и для конкатенации строк: + +* `a = a + 1` → `a += 1` +* `a = a - 1` → `a -= 1` +* `a = a * 2` → `a *= 2` +* `a = a / 1` → `a /= 1` +* `a = a + "foo"` → `a += "foo"` diff --git a/modules/90-loops/400-syntax-sugar/ru/data.yml b/modules/90-loops/400-syntax-sugar/ru/data.yml new file mode 100644 index 00000000..9d5020ed --- /dev/null +++ b/modules/90-loops/400-syntax-sugar/ru/data.yml @@ -0,0 +1,2 @@ +name: Синтаксический сахар +tips: [] diff --git a/modules/90-loops/450-mutators/es/EXERCISE.md b/modules/90-loops/450-mutators/es/EXERCISE.md new file mode 100644 index 00000000..0fb60d69 --- /dev/null +++ b/modules/90-loops/450-mutators/es/EXERCISE.md @@ -0,0 +1,8 @@ + +Implementa el método estático `App.makeItFunny()`, que recibe una cadena de texto y devuelve una copia de la misma en la que cada elemento n-ésimo se convierte en mayúsculas. n se especifica como argumento de la función. Piensa en cómo puedes utilizar el operador de resto `%` para lograrlo. + +```java +var text = "I never look back"; +// Cada tercer elemento +App.makeItFunny(text, 3); // "I NevEr LooK bAck" +``` diff --git a/modules/90-loops/450-mutators/es/README.md b/modules/90-loops/450-mutators/es/README.md new file mode 100644 index 00000000..4043282e --- /dev/null +++ b/modules/90-loops/450-mutators/es/README.md @@ -0,0 +1,53 @@ +Del lenguaje C a Java se han trasladado dos operaciones: **incremento** `++` y **decremento** `--`, que se encuentran muy a menudo en combinación con bucles. + +Estas operaciones unarias aumentan y disminuyen en uno el número almacenado en una variable: + +```java +var i = 0; +i++; // 0 +i++; // 1 + +i--; // 2 +i--; // 1 +``` + +Además de la forma posfija, también tienen una forma prefija: + +```java +var i = 0; +++i; // 1 +++i; // 2 + +--i; // 1 +--i; // 0 +``` + +Parece que no hay ninguna diferencia entre las formas posfija y prefija, pero aquí es donde empiezan las dificultades. A diferencia de todas las demás operaciones, el incremento y el decremento no solo devuelven un valor, sino que también **modifican el valor de la variable**. + +Al utilizar la notación prefija, primero se produce la modificación de la variable y luego se devuelve. Al utilizar la notación posfija, ocurre lo contrario: se puede considerar que primero se devuelve y luego se modifica la variable. + +La regla funciona de la misma manera para el incremento y el decremento. Para simplificar, consideremos solo el incremento: + +```java +var x = 5; + +System.out.println(++x); // => 6 +System.out.println(x); // => 6 + +System.out.println(x++); // => 6 +System.out.println(x); // => 7 +``` + +Lo que sucede en el código anterior: + +1. Imprimimos `++x` en la pantalla, que es un incremento prefijo. Por lo tanto, primero el valor de la variable se incrementa en 1, luego se devuelve el resultado y se imprime en la pantalla. +2. Como el valor ha cambiado, `System.out.println(x)` imprime 6. +3. Ahora imprimimos `x++` en la pantalla, que es un incremento posfijo. Por lo tanto, obtenemos el valor que tenía la variable antes de incrementarse en 1. +4. Como el valor ha cambiado, `System.out.println(x)` imprime 7. + +Se vuelve especialmente complicado cuando se inserta el incremento en otras operaciones: `x = i++ - 7 + --h`. Es casi imposible entender un código así. + +Recomendaciones de uso: + +* Nunca mezcles operaciones sin efectos secundarios con operaciones con efectos secundarios. Lo mismo se aplica a los métodos. +* Utiliza el incremento y el decremento solo cuando no haya diferencia entre la forma prefija y la forma posfija, separados del resto del código, en una línea separada. diff --git a/modules/90-loops/450-mutators/es/data.yml b/modules/90-loops/450-mutators/es/data.yml new file mode 100644 index 00000000..d6f52890 --- /dev/null +++ b/modules/90-loops/450-mutators/es/data.yml @@ -0,0 +1,5 @@ +name: Incremento y decremento +tips: + - > + [Operador de resto + (%)](https://es.wikipedia.org/wiki/Resto_(matem%C3%A1tica)) diff --git a/modules/90-loops/450-mutators/ru/EXERCISE.md b/modules/90-loops/450-mutators/ru/EXERCISE.md new file mode 100644 index 00000000..d1f31212 --- /dev/null +++ b/modules/90-loops/450-mutators/ru/EXERCISE.md @@ -0,0 +1,8 @@ + +Реализуйте статический метод `App.makeItFunny()`, который принимает на вход строку и возвращает её копию, у которой каждый n-ный элемент переведен в верхний регистр. n – задается на входе в функцию. Для определения каждого n-ного элемента понадобится остаток от деления `%`. Подумайте, как его можно использовать. + +```java +var text = "I never look back"; +// Каждый третий элемент +App.makeItFunny(text, 3); // "I NevEr LooK bAck" +``` diff --git a/modules/90-loops/450-mutators/ru/README.md b/modules/90-loops/450-mutators/ru/README.md new file mode 100644 index 00000000..a9facdce --- /dev/null +++ b/modules/90-loops/450-mutators/ru/README.md @@ -0,0 +1,53 @@ +Из языка Си в Java перекочевали две операции: **инкремент** `++` и **декремент** `--`, которые очень часто встречаются вместе с циклами. + +Эти унарные операции увеличивают и уменьшают на единицу число, записанное в переменную: + +```java +var i = 0; +i++; // 0 +i++; // 1 + +i--; // 2 +i--; // 1 +``` + +Кроме постфиксной формы, у них есть и префиксная: + +```java +var i = 0; +++i; // 1 +++i; // 2 + +--i; // 1 +--i; // 0 +``` + +Кажется, что нет никакой разницы между постфиксной и префиксной формами, но тут начинаются сложности. В отличие от всех остальных операций, инкремент и декремент не только возвращают значение, но и **изменяют значение переменной**. + +При использовании префиксной нотации сначала происходит изменение переменной, а потом возврат. При использовании постфиксной нотации — наоборот: можно считать, что сначала происходит возврат, а потом изменение переменной. + +Правило работает одинаково для инкремента и декремента. Для простоты рассмотрим только инкремент: + +```java +var x = 5; + +System.out.println(++x); // => 6 +System.out.println(x); // => 6 + +System.out.println(x++); // => 6 +System.out.println(x); // => 7 +``` + +Что происходит в коде выше: + +1. Выводим на экран `++x` — префиксный инкремент. Поэтому сначала значение переменной увеличилось на 1, потом результат вернулся и вывелся на экран +2. Так как значение изменилось, `System.out.println(x)` вывел 6 +3. Теперь выводим на экран `x++` — постфиксный инкремент. Поэтому мы получили значение, содержавшееся в переменной до ее увеличения на 1 +4. Так как значение изменилось, `System.out.println(x)` вывел 7 + +Особенно сложно становится, когда инкремент вставляют внутрь других операций: `x = i++ - 7 + --h`. Понять такой код почти невозможно. + +Рекомендации по использованию: + +* Никогда не смешайте операции без побочных эффектов и операциями с побочными эффектами. То же самое касается и методов +* Используйте инкремент и декремент только там, где нет разницы между префиксным и постфиксным вариантом — отдельно от всего, на отдельной строчке кода diff --git a/modules/90-loops/450-mutators/ru/data.yml b/modules/90-loops/450-mutators/ru/data.yml new file mode 100644 index 00000000..8853065b --- /dev/null +++ b/modules/90-loops/450-mutators/ru/data.yml @@ -0,0 +1,4 @@ +name: Инкремент и декремент +tips: + - | + [Остаток от деления (%)](https://ru.wikipedia.org/wiki/Деление_с_остатком) diff --git a/modules/90-loops/500-return-from-loops/es/EXERCISE.md b/modules/90-loops/500-return-from-loops/es/EXERCISE.md new file mode 100644 index 00000000..ffca7746 --- /dev/null +++ b/modules/90-loops/500-return-from-loops/es/EXERCISE.md @@ -0,0 +1,12 @@ + +Implementa el método estático `App.hasChar()`, que verifica (teniendo en cuenta mayúsculas y minúsculas) si una cadena contiene una letra específica. El método toma dos parámetros: + +* Cadena +* Letra a buscar + +```java +App.hasChar("Renly", 'R'); // true +App.hasChar("Renly", 'r'); // false +App.hasChar("Tommy", 'm'); // true +App.hasChar("Tommy", 'd'); // false +``` diff --git a/modules/90-loops/500-return-from-loops/es/README.md b/modules/90-loops/500-return-from-loops/es/README.md new file mode 100644 index 00000000..d1ae8358 --- /dev/null +++ b/modules/90-loops/500-return-from-loops/es/README.md @@ -0,0 +1,40 @@ + +El trabajo 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 un ejemplo de este tipo de escenario. +2. Ejecutar el bucle hasta que se alcance un resultado deseado y salir. Por ejemplo, la tarea de buscar números primos. Recordemos que un número primo solo se divide exactamente por sí mismo y por uno. + +Veamos un algoritmo simple para verificar si un número es primo. Intentaremos dividir el número buscado `x` por todos los números en el rango desde dos hasta `x - 1` y observar el resto de la división. Si no se encuentra ningún divisor en este rango que divida al número `x` sin dejar resto, entonces tenemos un número primo. + +Podemos notar que es suficiente verificar los números hasta `x - 1/2`. Por ejemplo, 11 no se divide por 2, 3, 4, 5. Pero garantizamos que no se dividirá por números mayores que la mitad de sí mismo. + +Por lo tanto, podemos realizar una pequeña optimización y verificar la división solo hasta `x / 2`: + +```java +public static boolean isPrime(int number) { + if (number < 2) { + return false; + } + + var divider = 2; + + while (divider <= number / 2) { + if (number % divider == 0) { + return false; + } + + divider++; + } + + return true; +} + +App.isPrime(1); // false +App.isPrime(2); // true +App.isPrime(3); // true +App.isPrime(4); // false +``` + +El algoritmo está construido de tal manera que si durante la división secuencial por números hasta `x / 2` se encuentra al menos uno que divide sin dejar resto, entonces el argumento pasado no es un número primo y, por lo tanto, los cálculos posteriores no tienen sentido. En este punto, se debe devolver `false`. + +Y solo si el bucle se ejecuta por completo, se puede concluir que el número es primo, ya que no se encontró ningún número que divida al número sin dejar resto. diff --git a/modules/90-loops/500-return-from-loops/es/data.yml b/modules/90-loops/500-return-from-loops/es/data.yml new file mode 100644 index 00000000..bdff3348 --- /dev/null +++ b/modules/90-loops/500-return-from-loops/es/data.yml @@ -0,0 +1,4 @@ +name: Devolución de bucles +tips: + - | + [Lista de números primos](https://es.wikipedia.org/wiki/Números_primos) diff --git a/modules/90-loops/500-return-from-loops/ru/EXERCISE.md b/modules/90-loops/500-return-from-loops/ru/EXERCISE.md new file mode 100644 index 00000000..0d0e2a94 --- /dev/null +++ b/modules/90-loops/500-return-from-loops/ru/EXERCISE.md @@ -0,0 +1,12 @@ + +Реализуйте статический метод `App.hasChar()`, который проверяет (с учётом регистра), содержит ли строка указанную букву. Метод принимает два параметра: + +* Строка +* Буква для поиска + +```java +App.hasChar("Renly", 'R'); // true +App.hasChar("Renly", 'r'); // false +App.hasChar("Tommy", 'm'); // true +App.hasChar("Tommy", 'd'); // false +``` diff --git a/modules/90-loops/500-return-from-loops/ru/README.md b/modules/90-loops/500-return-from-loops/ru/README.md new file mode 100644 index 00000000..cc417eca --- /dev/null +++ b/modules/90-loops/500-return-from-loops/ru/README.md @@ -0,0 +1,40 @@ + +Работа с циклами обычно сводится к двум сценариям: + +1. Агрегация — накопление результата во время итераций и работа с ним после цикла. Переворот строки как раз относится к такому варианту +2. Выполнение цикла до достижения необходимого результата и выход. Например, задача поиска простых чисел. Вспомним, что простое число делится без остатка только на себя и на единицу + +Рассмотрим простой алгоритм проверки простоты числа. Попробуем поделить искомое число `x` на все числа из диапазона от двух до `x - 1` и смотреть остаток от деления. Если в этом диапазоне не найден делитель, который делит число `x` без остатка, значит перед нами простое число. + +Можно заметить, что достаточно проверять числа не до `x - 1`, а до половины числа. Например, 11 не делится на 2, 3, 4, 5. Но и дальше гарантированно не будет делиться на числа больше своей половины. + +Значит, можно провести небольшую оптимизацию и проверять деление только до `x / 2`: + +```java +public static boolean isPrime(int number) { + if (number < 2) { + return false; + } + + var divider = 2; + + while (divider <= number / 2) { + if (number % divider == 0) { + return false; + } + + divider++; + } + + return true; +} + +App.isPrime(1); // false +App.isPrime(2); // true +App.isPrime(3); // true +App.isPrime(4); // false +``` + +Алгоритм построен таким образом, что если во время последовательного деления на числа до `x / 2` находится хоть одно, которое делит без остатка, то переданный аргумент — не простое число, а значит дальнейшие вычисления не имеют смысла. В этом месте стоит возврат `false`. + +И только если цикл отработал целиком, можно сделать вывод, что число — простое, так как не было найдено ни одного числа, которое делит число без остатка. diff --git a/modules/90-loops/500-return-from-loops/ru/data.yml b/modules/90-loops/500-return-from-loops/ru/data.yml new file mode 100644 index 00000000..32c5dc6f --- /dev/null +++ b/modules/90-loops/500-return-from-loops/ru/data.yml @@ -0,0 +1,4 @@ +name: Возврат из циклов +tips: + - | + [Список простых чисел](https://ru.wikipedia.org/wiki/Список_простых_чисел) diff --git a/modules/90-loops/550-for/es/EXERCISE.md b/modules/90-loops/550-for/es/EXERCISE.md new file mode 100644 index 00000000..52158894 --- /dev/null +++ b/modules/90-loops/550-for/es/EXERCISE.md @@ -0,0 +1,12 @@ + +Samwell descubrió que sus mensajes estaban siendo interceptados en la fortaleza "Gemelos" y leídos allí. Como resultado, sus ataques dejaron de ser sorpresivos. Después de pensar un poco, desarrolló un programa que cifraba los mensajes utilizando el siguiente algoritmo. Tomaba el texto y reorganizaba cada dos caracteres consecutivos. + +```java +App.encrypt("move"); // "omev" +App.encrypt("attack"); // "taatkc" +// Si el número de caracteres es impar, +// el último carácter permanece en su lugar. +App.encrypt("go!"); // "og!" +``` + +Implementa el método estático `App.encrypt()`, que recibe el mensaje original y devuelve el mensaje cifrado. diff --git a/modules/90-loops/550-for/es/README.md b/modules/90-loops/550-for/es/README.md new file mode 100644 index 00000000..ba34cca7 --- /dev/null +++ b/modules/90-loops/550-for/es/README.md @@ -0,0 +1,30 @@ +El ciclo `while` es ideal para situaciones en las que la cantidad de iteraciones no se conoce de antemano, por ejemplo, al buscar un número primo. + +Cuando se conoce la cantidad de iteraciones, es preferible utilizar el ciclo `for`. Veamos la implementación de invertir una cadena utilizando el ciclo `for`: + +```java +public static String reverseString(String str) { + var result = ""; + // El contador se incrementa utilizando el operador de incremento. + // Hablaremos sobre esta operación más adelante. + for (var i = 0; i < str.length(); i++) { + result = str.charAt(i) + result; + } + + return result; +} +``` + +https://replit.com/@hexlet/java-basics-conditions-for + +Este código se puede describir de la siguiente manera: + +> El ciclo con el índice `i` se repite mientras `i < str.length()`, y después de cada paso, `i` se incrementa en 1. + +En la definición del ciclo `for` se encuentran: + +1. El valor inicial del contador. Este código se ejecuta exactamente una vez antes de la primera iteración. +2. El predicado: la condición de repetición del ciclo. Se evalúa en cada iteración, al igual que en el `while`. +3. La descripción del cambio del contador. Este código se ejecuta al final de cada iteración. + +Por lo demás, el principio de funcionamiento es exactamente el mismo que el del ciclo `while`. diff --git a/modules/90-loops/550-for/es/data.yml b/modules/90-loops/550-for/es/data.yml new file mode 100644 index 00000000..b0dffac4 --- /dev/null +++ b/modules/90-loops/550-for/es/data.yml @@ -0,0 +1,2 @@ +name: Ciclo For +tips: [] diff --git a/modules/90-loops/550-for/ru/EXERCISE.md b/modules/90-loops/550-for/ru/EXERCISE.md new file mode 100644 index 00000000..3493348b --- /dev/null +++ b/modules/90-loops/550-for/ru/EXERCISE.md @@ -0,0 +1,12 @@ + +Сэмвелл обнаружил, что его сообщения перехватываются в замке «Близнецы» и там читаются. Из-за этого их атаки перестали быть внезапными. Немного подумав, он разработал программу, которая бы шифровала сообщения по следующему алгоритму. Она бы брала текст и переставляла в нем каждые два подряд идущих символа. + +```java +App.encrypt("move"); // "omev" +App.encrypt("attack"); // "taatkc" +// Если число символов нечётное +// то последний символ остается на своем месте +App.encrypt("go!"); // "og!" +``` + +Реализуйте статический метод `App.encrypt()`, который принимает на вход исходное сообщение и возвращает зашифрованное. diff --git a/modules/90-loops/550-for/ru/README.md b/modules/90-loops/550-for/ru/README.md new file mode 100644 index 00000000..8d758fe6 --- /dev/null +++ b/modules/90-loops/550-for/ru/README.md @@ -0,0 +1,30 @@ +Цикл `while` идеален для ситуаций, когда количество итераций неизвестно заранее, например, при поиске простого числа. + +Когда количество итераций известно, предпочтительнее использовать цикл `for`. Посмотрим реализацию переворота строки через цикл `for`: + +```java +public static String reverseString(String str) { + var result = ""; + // Счетчик увеличивается с помощью инкремента. + // Об этой операции мы поговорим ниже. + for (var i = 0; i < str.length(); i++) { + result = str.charAt(i) + result; + } + + return result; +} +``` + +https://replit.com/@hexlet/java-basics-conditions-for + +Этот код можно описать так: + +> Цикл с индексом `i` повторяется, пока `i < str.length()`, а также после каждого шага увеличивает `i` на 1 + +В определении цикла `for` есть: + +1. Начальное значение счетчика. Этот код выполняется ровно один раз перед первой итерацией +2. Предикат — условие повторения циклов. Выполняется на каждой итерации. Точно так же как и в `while` +3. Описание изменения счетчика. Этот код выполняется в конце каждой итерации + +В остальном принцип работы точно такой же, как у цикла `while`. diff --git a/modules/90-loops/550-for/ru/data.yml b/modules/90-loops/550-for/ru/data.yml new file mode 100644 index 00000000..3debe3c2 --- /dev/null +++ b/modules/90-loops/550-for/ru/data.yml @@ -0,0 +1,2 @@ +name: Цикл For +tips: []