diff --git a/description.ru.yml b/description.ru.yml deleted file mode 100644 index 4979182..0000000 --- a/description.ru.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: | - Курс Java: обучение программированию на ява с нуля - -header: Подготовительный курс Java - -description: | - Изучение программирования — непростой и длительный процесс. Изучение синтаксиса языка — самая простая и короткая часть в пути, но без неё невозможно начать. Этот курс посвящен азам написания программ на Java. Он готовит плацдарм для написания осмысленных программ - -seo_description: | - Курс программирования на Java для начинающих от сообщества Хекслет. Обучение джава программированию: синтаксис языка, типы данных, азы написания программ на Java diff --git a/drafts/.gitkeep b/drafts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/drafts/10-basics/10-hello-world/description.en.yml b/drafts/10-basics/10-hello-world/description.en.yml deleted file mode 100644 index 9e06f27..0000000 --- a/drafts/10-basics/10-hello-world/description.en.yml +++ /dev/null @@ -1,65 +0,0 @@ ---- - -name: Привет, Мир! -theory: | - Изучать язык программирования по традиции начинают с программы "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); - ``` - -instructions: | - Наберите в редакторе код из задания символ в символ и нажмите «Проверить». - - ```java - class App { - public static void main(String[] args) { - System.out.println("Hello, World!"); - } - } - ``` - - Если вы напишете *heLLo, woRld!* вместо *Hello, World!*, то это будет считаться другим текстом, потому что заглавные и строчные буквы — это разные символы. Размер буквы называют *регистром*, и говорят: **регистр — важен!** Это касается почти всего в коде, поэтому привыкайте всегда обращать внимание на регистр. - -tips: - - | - Если в редакторе есть запись `// BEGIN` и `// END`, то код нужно писать между этими строчками. - - | - [Что такое компилятор?](https://guides.hexlet.io/compiler/) diff --git a/drafts/10-basics/20-comments/description.en.yml b/drafts/10-basics/20-comments/description.en.yml deleted file mode 100644 index 47b7165..0000000 --- a/drafts/10-basics/20-comments/description.en.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- - -name: Комментарии -theory: | - Практически все языки программирования позволяют оставлять в коде комментарии. Они никак не используются кодом и нужны исключительно для людей: чтобы программист оставлял пометки для себя и для других программистов. - - Комментарии в 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 и выдать в качестве документации к вашему коду. Мы поговорим о них позже – когда разберем классы и методы. - -instructions: | - Создайте однострочный комментарий с текстом: *You know nothing, Jon Snow!*. diff --git a/drafts/10-basics/30-statements/description.en.yml b/drafts/10-basics/30-statements/description.en.yml deleted file mode 100644 index 68a8fe4..0000000 --- a/drafts/10-basics/30-statements/description.en.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- - -name: Инструкции (Statements) -theory: | - Инструкция — это команда для компьютера. Код на 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!"); - ``` - - Результат на экране будет таким же, но на практике такой подход считается плохим. - -instructions: | - Выведите на экран друг за другом три имени: *Robert*, *Stannis*, *Renly*. В результате на экране должно отобразиться: - -
-  Robert
-  Stannis
-  Renly
-  
- - Для каждого имени используйте свой собственный вызов `System.out.println()`. diff --git a/drafts/10-basics/40-testing/description.en.yml b/drafts/10-basics/40-testing/description.en.yml deleted file mode 100644 index dfd26f2..0000000 --- a/drafts/10-basics/40-testing/description.en.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- - -name: Как мы проверяем ваши решения -theory: | - Наш сайт автоматически проверяет ваши решения. Как это работает? - - В самом простом случае система просто запускает ваш код и смотрит на то, что вывелось на экран. А потом сверяет с тем, что мы «ожидали» по заданию. - - В следующих, более сложных уроках вы будете писать методы — некие мини-программы, принимающие информацию из внешнего мира и производящие какие-то операции. Проверка ваших решений в таких случаях выглядит немного сложнее: система запускает ваше решение и передаёт какую-то информацию. Система также знает — «ожидает» — какой именно ответ должен вернуть правильный метод при таких входных данных. - - Например, если ваша задача — написать код для сложения двух чисел, то проверочная система будет передавать ему разные комбинации чисел и сверять ответ вашего кода с реальными суммами. Если во всех случаях ответы совпадут, то решение считается верным. - - Вот простой пример: в одном из будущих уроков вам нужно будет написать код, который производит вычисления и выдаёт ответ. Допустим, вы допустили небольшую ошибку, и метод выдал неправильное число. Система ответит примерно так: - -
expected: "35" but was: "10"
- - Самое главное начинается после двоеточия: «ожидалось: "35", но было "10"». То есть правильный код должен был выдать 35, но текущее решение работает неправильно и выдаёт 10. - - Кроме наших тестов, будет крайне полезно использовать сервис [repl.it](https://repl.it/languages/java). - - --- - - Иногда в процессе решения будет казаться, что вы сделали все правильно, но система "капризничает" и не принимает решение. Подобное поведение практически исключено. Нерабочие тесты просто не могут попасть на сайт, они автоматически запускаются после каждого изменения. В подавляющем большинстве таких случаев, (а все наши проекты в сумме провели миллионы проверок за много лет), ошибка содержится в коде решения. Она может быть очень незаметной, вместо английской буквы случайно ввели русскую, вместо верхнего регистра использовали нижний или забыли вывести запятую. Другие случаи сложнее. Возможно ваше решение работает для одного набора входных данных, но не работает для другого. Поэтому всегда внимательно читайте условие задачи и вывод тестов. Там почти наверняка есть указание на ошибку. - - Однако, если вы уверены в ошибке или нашли какую-то неточность, то вы всегда можете указать на нее. В конце каждой теории есть ссылка на содержимое урока на гитхабе (этот проект полностью открытый!). Перейдя туда, вы можете написать issue, посмотреть содержимое тестов (там видно, как вызывается ваш код) и даже отправить pullrequest. Если для вас это пока темный лес, то подключитесь в наше сообщество, там в канале _#hexlet-feedback_ мы всегда поможем. - -instructions: | - Просто тренировка. Выведите на экран число 420262531. - -
-  420262531
-  
- - Поэкспериментируйте с выводом. Передайте туда другое число или строку. Посмотрите на ответ системы, попробуйте его перевести и понять. - -definitions: - - name: Тесты - description: | - специальный код, проверяющий программы на корректность, сверяя правильный результат с реальным. - -tips: - - | - [TDD](https://ru.wikipedia.org/wiki/Разработка_через_тестирование) - - | - [Сообщество Хекслета в Telegram](https://t.me/hexletcommunity/12) diff --git a/drafts/10-basics/50-syntax-error/description.en.yml b/drafts/10-basics/50-syntax-error/description.en.yml deleted file mode 100644 index d9d3a49..0000000 --- a/drafts/10-basics/50-syntax-error/description.en.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- - -name: Ошибки оформления (синтаксиса) -theory: | - В человеческих языках грамматика важна, но текст с ошибками чаще всего можно понять и прочитать. В программировании все строго. Любое мельчайшее нарушение, и программа не запустится. - - Примером может быть забытая `;`, неправильно расставленные скобки и другие детали. Подобные ошибки называются **синтаксическими**, потому что они нарушают правила синтаксиса языка. - - Если программа на Java написана синтаксически некорректно, то компилятор выводит на экран: - - * Сообщение об ошибке - * Указание на файл - * Строчка в файле, где по его мнению произошла ошибка - - Ниже пример кода с синтаксической ошибкой: - - ```java - System.out.println("alala - ``` - - Если запустить код выше, то мы увидим следующее сообщение: - -
-  |  Error:
-  |  unclosed string literal
-  |  System.out.println("alala
-  
- - С одной стороны, ошибки синтаксиса — самые простые, потому что они связаны исключительно с грамматическими правилами написания кода, а не с самим смыслом кода. Их легко исправить — нужно лишь найти нарушение в записи. - - С другой стороны, компилятор не всегда может четко указать на это нарушение. Поэтому бывает, что забытую скобку нужно поставить не туда, куда указывает сообщение об ошибке. - -instructions: | - - Это задание не связано с уроком напрямую. Но будет полезным потренироваться с выводом на экран. Выведите на экран *What Is Dead May Never Die*. - -# tips: [] - -definitions: - - name: Компилятор - description: Программа выполняющая преобразование исходного кода в низкоуровневый язык подходящий для выполнения - - - name: Синтаксическая ошибка - description: Нарушение грамматических правил языка программирования diff --git a/drafts/10-basics/description.en.yml b/drafts/10-basics/description.en.yml deleted file mode 100644 index d429aaa..0000000 --- a/drafts/10-basics/description.en.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -name: Основы Java -description: | - Изучать Java мы будем с нуля, с самых азов. Первый модуль – плацдарм для написания осмысленных программ. В нем мы разберем, как написать свой первый код на Java. Расскажем, что такое комментарии и зачем они нужны. На примере проверки ваших решений рассмотрим, что такое тестирование и как читать вывод тестов. diff --git a/drafts/20-arithmetics/10-basics/description.en.yml b/drafts/20-arithmetics/10-basics/description.en.yml deleted file mode 100644 index c110f11..0000000 --- a/drafts/20-arithmetics/10-basics/description.en.yml +++ /dev/null @@ -1,55 +0,0 @@ ---- - -name: Арифметические операции -theory: | - На базовом уровне компьютеры оперируют только числами. Даже в прикладных программах на высокоуровневых языках внутри много чисел и операций над ними. - - К счастью, для старта достаточно знать обычную арифметику — с нее и начнем. - - Для сложения двух чисел в математике мы пишем, например, *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
-  
- -instructions: | - - Выведите на экран результат деления числа *81* на *9*. - -tips: - - Деление на ноль приводит к ошибке. Чтобы его не допустить, нужно знать про условные конструкции (о них вы узнаете в следующих уроках). diff --git a/drafts/20-arithmetics/20-operators/description.en.yml b/drafts/20-arithmetics/20-operators/description.en.yml deleted file mode 100644 index 919750c..0000000 --- a/drafts/20-arithmetics/20-operators/description.en.yml +++ /dev/null @@ -1,54 +0,0 @@ ---- - -name: Операторы -theory: | - Перед тем, как двигаться дальше, разберем базовую терминологию. Знак операции, такой как `+`, называют оператором. **Оператор** — просто символ, который выполняет операцию, например, сложение: - - ```java - System.out.println(8 + 2); // => 10 - ``` - - В этом примере `+` — это оператор, а числа *8* и *2* — это **операнды**. - - В случае сложения у нас есть два операнда: - - * Один слева - * Другой справа от знака *+* - - Операции, которые требуют наличия двух операндов, называются **бинарными**. Если пропустить хотя бы один операнд, то программа завершится с синтаксической ошибкой. Например: - - ``` - `3 + ;` - ``` - - Операции бывают не только бинарными. Бывают еще: - - * Унарные — с одним операндом - * Тернарные — с тремя операндами - - Причем операторы могут выглядеть одинаково, но обозначать разные операции: - - ```java - System.out.println(-3); // => -3 - ``` - - Выше пример применения унарной операции к числу *3*. Оператор «минус» перед тройкой говорит интерпретатору — возьми число *3* и найди противоположное, то есть *-3*. - - Это немного может сбить с толку, потому что *-3* — это одновременно и число само по себе, и оператор с операндом, но у языков программирования такая структура. - -instructions: | - - Напишите программу, которая посчитает разность между числами `6` и `-81` и выведет ответ на экран. - - -definitions: - - name: "Арифметическая операция" - description: "сложение, вычитание, умножение и деление." - - name: "Оператор" - description: "специальный символ, создающий операцию. Например, `+` создает операцию сложения." - - name: "Операнд" - description: "объект, который участвует в операции. `3 * 6`: здесь 3 и 6 — операнды." - - name: "Унарная операция" - description: "операция с одним операндом. Например, `-3` — унарная операция для получения числа, противоположного числу три." - - name: "Бинарная операция" - description: "операция с двумя операндами. Например, `3 + 9`." diff --git a/drafts/20-arithmetics/30-commutative/description.en.yml b/drafts/20-arithmetics/30-commutative/description.en.yml deleted file mode 100644 index c43bdd7..0000000 --- a/drafts/20-arithmetics/30-commutative/description.en.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- - -name: Коммутативная операция -theory: | - Мы все помним со школы: «от перемены мест слагаемых сумма не меняется». Это один из базовых и интуитивно понятных принципов арифметики — **коммутативный закон**. - - Бинарная операция считается коммутативной, если, вы получаете тот же самый результат, поменяв местами операнды. Очевидно, что сложение — коммутативная операция: - - ``` - 3 + 2 = 2 + 3 - ``` - - А вот вычитание — это не коммутативная операция: - - ``` - 2 - 3 ≠ 3 - 2 - ``` - - В программировании этот закон работает точно так же, как в арифметике. Более того, большинство операций не являются коммутативными. Отсюда вывод: всегда обращайте внимание на порядок того, с чем работаете. - -instructions: | - - Это задание напрямую не связано с темой урока. Но будет полезным попрактиковаться с арифметическими операциями и выводом на экран. - - Напишите программу, которая считает и последовательно выводит на экран значения следующих математических выражений: «3 умножить на 5» и «-8 разделить на -4». - -
-  15
-  2
-  
- -# tips: [] - -definitions: - - name: "Коммутативность" - description: "свойство операции, когда изменения порядка операндов не влияет на результат. Например, сложение — коммутативная операция: от перемены мест слагаемых сумма не меняется." diff --git a/drafts/20-arithmetics/40-composition/description.en.yml b/drafts/20-arithmetics/40-composition/description.en.yml deleted file mode 100644 index 6afec1c..0000000 --- a/drafts/20-arithmetics/40-composition/description.en.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- - -name: Композиция операций -theory: | - А что, если понадобится вычислить такое выражение: *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* - -instructions: | - - Реализуйте программу, которая вычисляет значение выражения `8 / 2 + 5 - -3 / 2`. Не вычисляйте ничего самостоятельно, ваша программа должна производить все вычисления сама. -
-  10
-  
- Обратите внимание, что интерпретатор производит арифметические вычисления в правильном порядке: сначала деление и умножение, потом сложение и вычитание. Иногда этот порядок нужно изменить — об этом следующий урок. - - Также обратите внимание на то, что в java по умолчанию используется целочисленное деление, `3 / 2` будет `1`. - - -# tips: [] diff --git a/drafts/20-arithmetics/50-priority/description.en.yml b/drafts/20-arithmetics/50-priority/description.en.yml deleted file mode 100644 index 46fde30..0000000 --- a/drafts/20-arithmetics/50-priority/description.en.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- - -name: Приоритет операций -theory: | - Посмотрите внимательно на выражение *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 - ``` - - Запомните: код пишется для людей, потому что код будут читать люди, а машины будут только исполнять его. Для машин нет «более» понятного или «менее» понятного кода, независимо от того, является ли код корректным или нет. - - -instructions: | - - Дано выражение `70 * 3 + 4 / 8 + 2`. - - Расставьте скобки так, чтобы оба сложения (`3 + 4` и `8 + 2`) высчитывались в первую очередь. Выведите результат на экран. - -# tips: [] diff --git a/drafts/20-arithmetics/60-float/description.en.yml b/drafts/20-arithmetics/60-float/description.en.yml deleted file mode 100644 index a5a0d91..0000000 --- a/drafts/20-arithmetics/60-float/description.en.yml +++ /dev/null @@ -1,47 +0,0 @@ ---- - -name: Числа с плавающей точкой - -theory: | - - В математике существуют разные виды чисел, например: - - * **Натуральные** — это целые числа от 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* лежит бесконечное множество чисел. - - А как тогда хранить рациональные числа? Подавляющее число язык программирования в этом случае опирается на единый стандарт, который описывает как организовывать память в таких случаях. - - Разработчикам важно понимать, что операции с плавающими числами неточны, но эту точность можно регулировать. Это значит, что при решении задач с подобными числами необходимо прибегать к специальным трюкам, которые позволяют добиться необходимой точности. - -instructions: | - - Вычислите и выведите на экран произведение двух чисел: *0.39* и *0.22* - -tips: - - | - [Что нужно знать про арифметику с плавающей запятой](https://habr.com/post/112953/) diff --git a/drafts/20-arithmetics/80-linting/description.en.yml b/drafts/20-arithmetics/80-linting/description.en.yml deleted file mode 100644 index 5bc5ba5..0000000 --- a/drafts/20-arithmetics/80-linting/description.en.yml +++ /dev/null @@ -1,47 +0,0 @@ ---- - -name: Линтер -theory: | - Теперь, когда мы уже научились писать простые программы, можно немного поговорить о том, как их писать. - - Код программы следует оформлять определенным образом, чтобы он был достаточно понятным и простым в поддержке. - - Специальные наборы правил — **стандарты** — описывают различные аспекты написания кода. Конкретно в 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/?utm_source=code-basics&utm_medium=referral&utm_campaign=programs&utm_content=lesson) и в реальной разработке линтер будет работать и сообщать вам о нарушениях. - -instructions: | - - Выведите на экран результат следующего вычисления: «разница между суммой пяти и двух и произведением трёх и семи». Сравните получившийся результат с решением учителя с точки зрения оформления кода. - -tips: [] diff --git a/drafts/20-arithmetics/description.en.yml b/drafts/20-arithmetics/description.en.yml deleted file mode 100644 index 2c1171b..0000000 --- a/drafts/20-arithmetics/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Арифметика -description: | - Современные программы создаются для обслуживания бизнесов, помощи в ежедневной жизни и развлечений. Но в основе их работы по-прежнему лежат вычисления. Наиболее простая и базовая тема в программировании — арифметика. В этом модуле мы переведем арифметические действия на язык программирования. Вспомним школьные правила из уроков математики и поговорим о приоритете операций. diff --git a/drafts/25-strings/10-quotes/description.en.yml b/drafts/25-strings/10-quotes/description.en.yml deleted file mode 100644 index e11b10e..0000000 --- a/drafts/25-strings/10-quotes/description.en.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- - -name: Кавычки -theory: | - ```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\""); - ``` - -instructions: | - - Напишите программу, которая выведет на экран: - -
-  "Khal Drogo's favorite word is "athjahakar""
-  
- - Программа должна вывести на экран эту фразу в точности. Обратите внимание на кавычки в начале и в конце фразы. - -# tips: [] diff --git a/drafts/25-strings/15-escape-characters/description.en.yml b/drafts/25-strings/15-escape-characters/description.en.yml deleted file mode 100644 index 26775f1..0000000 --- a/drafts/25-strings/15-escape-characters/description.en.yml +++ /dev/null @@ -1,161 +0,0 @@ ---- - -name: Экранирующие последовательности -theory: | - Мы хотим показать диалог Матери Драконов со своим ребенком: - - ```text - - Are you hungry? - - Aaaarrrgh! - ``` - - Если вывести на экран строку с таким текстом: - - ```java - System.out.println("- Are you hungry?- Aaaarrrgh!"); - ``` - - Получится так: - -
-  - 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 -
- - Почему перед строкой *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`. - -instructions: | - - Напишите программу, которая выводит на экран: - - - Did Joffrey agree? - - He did. He also said "I love using \n". - - При этом программа использует только один `System.out.println()`, но результат на экране должен выглядеть в точности как показано выше. - -tips: - - | - [История перевода строки](https://ru.wikipedia.org/wiki/Перевод_строки#История) - -# definitions: -# - name: "Экранирующая последовательность" -# description: "специальная комбинация символов в тексте. Например, \n — это перевод строки." diff --git a/drafts/25-strings/20-strings-concatenation/description.en.yml b/drafts/25-strings/20-strings-concatenation/description.en.yml deleted file mode 100644 index 426d83c..0000000 --- a/drafts/25-strings/20-strings-concatenation/description.en.yml +++ /dev/null @@ -1,59 +0,0 @@ ---- - -name: Конкатенация -theory: | - Программы постоянно оперируют строками. Все, что мы видим на сайтах или в мобильных приложениях, так или иначе представлено в виде текста. Этот текст чаще всего **динамический** — полученный из разных частей, которые соединяются вместе. Операция соединения строк в программировании называется **конкатенацией** и выглядит так: - - ```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 - -instructions: | - - Используя `System.out.println()`, выполните конкатенацию слов и выведите на экран фразу: - -
-  Winter came for the House of Frey.
-  
- - Каждое слово должно быть записано отдельно и взято в кавычки, например "Winter ". Не забудьте о пробелах после каждого слова. - -# definitions: -# - name: Конкатенация -# description: | -# операция соединения двух строк. Например, `System.out.println("King's " + " Landing");` diff --git a/drafts/25-strings/description.en.yml b/drafts/25-strings/description.en.yml deleted file mode 100644 index a4817a8..0000000 --- a/drafts/25-strings/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Строки -description: | - Текст в программировании называется «строками», и эта тема не так проста, как может показаться. Как вывести фразу, в которой есть и одинарные, и двойные кавычки? Как вообще быть с текстом, ведь компьютер не знает ничего о буквах! Модуль посвящен разным аспектам написания текста – от кавычек и экранирования до кодировки. diff --git a/drafts/30-variables/10-definition/description.en.yml b/drafts/30-variables/10-definition/description.en.yml deleted file mode 100644 index c12c137..0000000 --- a/drafts/30-variables/10-definition/description.en.yml +++ /dev/null @@ -1,66 +0,0 @@ ---- - -name: Что такое переменная - -theory: | - Представьте себе задачу — нужно напечатать на экран фразу *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 - - Для удобства анализа программы переменные принято создавать как можно ближе к тому месту, где они используются. - -instructions: | - Создайте переменную с именем `motto` и содержимым `What Is Dead May Never Die!`. Распечатайте содержимое переменной. -
-  What Is Dead May Never Die!
-  
- -tips: - - | - [Именование в программировании](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) - -# definitions: -# - name: Переменная -# description: "способ сохранить информацию и дать ей имя для последующего использования в коде." diff --git a/drafts/30-variables/12-change/description.en.yml b/drafts/30-variables/12-change/description.en.yml deleted file mode 100644 index d4b17b7..0000000 --- a/drafts/30-variables/12-change/description.en.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- - -name: Изменение переменной - -theory: | - Само слово «переменная» говорит, что ее можно менять. И действительно, с течением времени внутри программы, значения переменных могут изменяться: - - ```java - var greeting = "Father!"; - System.out.println(greeting); - System.out.println(greeting); - // var уже не используется, так как переменная была определена выше - greeting = "Mother!"; - System.out.println(greeting); - System.out.println(greeting); - ``` - - - Java — статически типизированный язык. Это значит, что тип переменной задается при определении и больше не меняется. - - В примере выше мы присвоили строку при создании переменной. Компилятор запоминает тип и проверяет все последующие изменения переменной. Если попробовать этой же переменной присвоить число, то мы получим следующую ошибку: - - ```java - greeting = 5; - # Error: - # incompatible types: int cannot be converted to java.lang.String - # несовместимые типы: число не может быть превращено в строку - ``` - - Компилятор делает такую проверку без запуска кода на выполнение, именно поэтому такой вид типизации называют **статическим**. В JavaScript, Ruby, PHP, Python и других динамических языках подобное поведение не является ошибкой, переменная может легко изменить свой тип в процессе работы. - -instructions: | - - В коде определена переменная со значением `"Brienna"`. Переопределите значение этой переменной и присвойте ей такую же, но в перевернутом виде. - -
-  anneirB
-  
- -# tips: [] - -# definitions: -# - name: Переменная -# description: Способ сохранить информацию и дать ей имя для последующего использования в коде. diff --git a/drafts/30-variables/13-variables-naming/description.en.yml b/drafts/30-variables/13-variables-naming/description.en.yml deleted file mode 100644 index 73a1f09..0000000 --- a/drafts/30-variables/13-variables-naming/description.en.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- - -name: Выбор имени переменной - -theory: | - Представим себе, что программа из прошлого урока выглядит так: - - ```java - var x = "Father!"; - System.out.println(x); - System.out.println(x); - ``` - - Она по-прежнему работает, но в ней изменилось имя переменной на `x`. Компьютеру без разницы, как мы называем переменные. Названия важны для программистов, ведь мы гораздо чаще читаем код, чем пишем. Причем не свой, а написанный другими людьми. От качества и понятности имен переменных зависит половина успеха в анализе кода. - - Лучше посидеть и придумать название, которое описывает суть переменной, чем назвать ее как попало, а в будущем переделывать. Постарайтесь давать им такие имена, чтобы они были максимально понятны без контекста, без изучения окружающего кода. - - Существует общепринятое правило: не используйте транслит для имен, только английский язык. Если вы испытываете сложности с английским, то пользуйтесь переводчиком. Со временем, копаясь в чужом коде, вы сформируете правильные понятия для именования. - - Среди разработчиков есть шутка: «самое сложное в программировании — названия переменных и инвалидация кеша». Придумывать названия и правда сложно. Как бы вы назвали переменную, в которой хранится «количество неоплаченных заказов от клиентов, имеющих задолженность в предыдущем квартале»? - -instructions: | - - Создайте две переменные с именами «первое число» и «второе число» на английском языке, используя lowerCamelCase. Запишите в первую переменную число `1.10`, во вторую — `-100`. Выведите на экран произведение чисел, записанных в получившиеся переменные. - -
-  -110.00000000000001
-  
- - Код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. - -# tips: [] - -# definitions: -# - name: Стандарт кодирования -# description: "набор синтаксических и стилистических правил написания кода." diff --git a/drafts/30-variables/14-errors/description.en.yml b/drafts/30-variables/14-errors/description.en.yml deleted file mode 100644 index b27ee46..0000000 --- a/drafts/30-variables/14-errors/description.en.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- - -name: Ошибки при работе с переменными - -theory: | - Порядок инструкций в коде с переменными имеет огромное значение. Переменная должна быть определена до того, как будет использована. Ниже пример ошибки, которую очень часто допускают новички: - - ```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!"; - ``` - - Так делать нельзя. Придется создать новую переменную. - - Количество подобных ошибок уменьшается за счет использования правильно настроенного редактора. Такой редактор подсвечивает имена, которые используются без объявления, и предупреждает о возможных проблемах. - -instructions: | - Найдите в программе необъявленную переменную и объявите ее, присвоив ей значение `"Dragon"`; -
-  Targaryen and Dragon
-  
- -# tips: [] - -# definitions: -# - name: Переменная -# description: Способ сохранить информацию и дать ей имя для последующего использования в коде. diff --git a/drafts/30-variables/15-variable-expressions/description.en.yml b/drafts/30-variables/15-variable-expressions/description.en.yml deleted file mode 100644 index a848e08..0000000 --- a/drafts/30-variables/15-variable-expressions/description.en.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- - -name: Выражения в определениях - -theory: | - Переменные полезны не только для хранения и переиспользования информации, но и для упрощения сложных вычислений. - - Давайте рассмотрим пример: нужно перевести евро в рубли через доллары. Подобные конвертации через промежуточную валюту часто делают банки при покупках за рубежом. - - Для начала переведем 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 знает значение, потому что уже вычислил его. - -instructions: | - - Напишите программу, которая берет исходное количество евро, записанное в переменную `eurosCount`, переводит евро в доллары и выводит на экран. Затем полученное значение переводит в рубли и выводит на новой строчке. - - Пример вывода для 100 евро: - -
-  125.0
-  7500.0
-  
- - Считаем, что: - - - 1 евро = 1.25 долларов - - 1 доллар = 60 рублей - -tips: - - | - Для перевода строчки можно использовать `\n` между выводом долларов и рублей, либо нужное количество раз использовать метод `println()`. diff --git a/drafts/30-variables/18-variables-concatenation/description.en.yml b/drafts/30-variables/18-variables-concatenation/description.en.yml deleted file mode 100644 index 52c7a19..0000000 --- a/drafts/30-variables/18-variables-concatenation/description.en.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- - -name: Переменные и конкатенация - -theory: | - Переменные и конкатенацию можно объединять. Синтаксически ничего не меняется, ведь мы умеем конкатенировать — то есть склеивать две строки: - - ```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 - -instructions: | - - Сайты постоянно посылают письма своим пользователям. Типичная задача — сделать автоматическую отправку персонального письма, где в заголовке будет имя пользователя. Если где-то в базе сайта хранится имя человека в виде строки, то задача генерации заголовка сводится к конкатенации: например, нужно склеить строку *Здравствуйте* со строкой, где записано имя. - - Напишите программу, которая будет генерировать заголовок и тело письма, используя уже готовые переменные, и выводить получившиеся строки на экран. - - Для заголовка используйте переменные `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()`. - -tips: - - | - Подумайте, с какой строкой и в каком порядке нужно склеивать переменные, чтобы получить такой двухстрочный вывод тела письма. - - | - Помните, что можно создать строку, которая содержит только управляющую последовательность `\n`. diff --git a/drafts/30-variables/19-naming-style/description.en.yml b/drafts/30-variables/19-naming-style/description.en.yml deleted file mode 100644 index c325061..0000000 --- a/drafts/30-variables/19-naming-style/description.en.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- - -name: Именование переменных - -theory: | - - `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 - ``` - -instructions: | - - Создайте две переменные с именами «первое число» и «второе число» на английском языке, используя lowerCamelCase. Запишите в первую переменную число `11`, во вторую — `-100`. Выведите на экран произведение чисел, записанных в получившихся переменных. - - Код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. - -tips: [] - -definitions: - - name: Стандарт кодирования - description: Набор синтаксических и стилистических правил написания кода. diff --git a/drafts/30-variables/20-magic-numbers/description.en.yml b/drafts/30-variables/20-magic-numbers/description.en.yml deleted file mode 100644 index d44e7c5..0000000 --- a/drafts/30-variables/20-magic-numbers/description.en.yml +++ /dev/null @@ -1,64 +0,0 @@ ---- - -name: Магические числа - -theory: | - Вспомним один из прошлых уроков: - - ```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* - * Две новые переменные отделены от последующих вычислений пустой строчкой. Эти переменные имеют смысл и без вычислений, поэтому такое отделение уместно, оно повышает читаемость - * Получился хорошо именованный и структурированный код, но он длиннее прошлой версии. Так часто бывает, и это нормально, потому что код должен быть читабельным - -instructions: | - - Вы столкнулись с таким кодом, который выводит на экран общее количество комнат во владении нынешнего короля: - - ```java - var king = "King Balon the 6th"; - System.out.println(king + " has " + (6 * 17) + " rooms."); - ``` - - Как видите, это магические числа: непонятно, что такое _6_ и что такое _17_. Можно догадаться, если знать историю королевской семьи: каждый новый король получает в наследство все замки от предков и строит новый замок — точную копию родительского. - - Эта странная династия просто плодит одинаковые замки… - - Избавьтесь от магических чисел, создав новые переменные, а затем выведите текст на экран. - - Получится так: -
-  King Balon the 6th has 102 rooms.
-  
- - Названия переменных должны передавать смысл чисел, но должны при этом оставаться достаточно короткими и ёмкими для комфортного чтения. - - Помните: код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. - -# tips: [] diff --git a/drafts/30-variables/23-constants/description.en.yml b/drafts/30-variables/23-constants/description.en.yml deleted file mode 100644 index 4fe780f..0000000 --- a/drafts/30-variables/23-constants/description.en.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- - -name: Константы - -theory: | - Некоторые данные никогда не меняются — например, математические постоянные. Возьмем число *π*. Приближенно оно всегда равно *3.14* и не может измениться. - - Для обращения к подобным данным в Java принято использовать константы: - - ```java - final var PI = 3.14; - System.out.println(PI); // 3.14 - ``` - - https://replit.com/@hexlet/java-basics-variables-5 - - В отличие от переменных, в начале определения константы используют ключевое слово `final`. Оно сообщает компилятору запрет на изменение. Любая попытка поменять константу приведет к ошибке. - - Константы принято именовать буквами в верхнем регистре с `_` в качестве разделителя. Константа, как и переменная, может использоваться в любом выражении. Единственное ограничение — константу нельзя изменить, что звучит довольно логично. - -instructions: | - - Создайте константу `DRAGONS_BORN_COUNT` и запишите в неё число 3 — это количество драконов, родившихся у Дайенерис. Выводить значение на экран не требуется. - - -# tips: [] - -# definitions: -# - name: "Константа" -# description: "способ сохранить информацию и дать ей имя для последующего использования в коде; константы нельзя изменять, в отличие от переменных" diff --git a/drafts/30-variables/description.en.yml b/drafts/30-variables/description.en.yml deleted file mode 100644 index b6f2f15..0000000 --- a/drafts/30-variables/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Переменные -description: | - Информацию можно помещать в специальные «хранилища» — переменные. Это позволяет переиспользовать уже существующие данные и не дублировать их в разных частях кода. В этом модуле мы разберем как изменять переменные и именовать их, чтобы чтение вашего кода было понятным для любого разработчика. Вы поймете, что придумать название переменной не так-то просто! А еще расскажем, как использовать переменные для упрощения сложных вычислений. diff --git a/drafts/33-data-types/41-data-types-basics/description.en.yml b/drafts/33-data-types/41-data-types-basics/description.en.yml deleted file mode 100644 index e05f95d..0000000 --- a/drafts/33-data-types/41-data-types-basics/description.en.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- - -name: Зачем нужны типы данных - -theory: | - Внутри высокоуровневых языков программирования данные разделяются по типам. Например, строки относятся к типу *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 много, плюс можно создавать свои. Постепенно мы познакомимся со всеми необходимыми и научимся их правильно использовать. - -instructions: | - Выведите на экран результат деления 3 на 2. Подумайте почему получился такой ответ? - -tips: - - | - [Статья о дробных числах](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Тип данных" -# description: "множество данных в коде (разновидность информации). Тип определяет, что можно делать с элементами конкретного множества. Например, целые числа, рациональные числа, строки — это разные типы данных." -# - name: "Примитивные типы данных" -# description: "простые типы, встроенные в сам язык программирования." -# - name: "Строка (String)" -# description: | -# тип данных, описывающий набор символов (иными словами — текст); например, `"text"` diff --git a/drafts/33-data-types/45-explicit-types/description.en.yml b/drafts/33-data-types/45-explicit-types/description.en.yml deleted file mode 100644 index 80d2f6f..0000000 --- a/drafts/33-data-types/45-explicit-types/description.en.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- - -name: Явная типизация - -theory: | - До сих пор при определении переменных мы использовали ключевое слово `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 и множество других языков. - - Вывод типов и предпочтителен в большинстве ситуаций, однако бывает такое, что выводимый тип нас не устраивает. Тогда мы можем указать тип явно. Подробнее об этом в следующем уроке. - -instructions: | - Создайте строку *One more time* с явным указанием типа и выведите ее на экран - -tips: - - | - [Статья о дробных числах](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Тип данных" -# description: "множество данных в коде (разновидность информации). Тип определяет, что можно делать с элементами конкретного множества. Например, целые числа, рациональные числа, строки — это разные типы данных." -# - name: "Примитивные типы данных" -# description: "простые типы, встроенные в сам язык программирования." -# - name: "Строка (String)" -# description: | -# тип данных, описывающий набор символов (иными словами — текст); например, `"text"` diff --git a/drafts/33-data-types/47-data-types-list/description.en.yml b/drafts/33-data-types/47-data-types-list/description.en.yml deleted file mode 100644 index e255a6b..0000000 --- a/drafts/33-data-types/47-data-types-list/description.en.yml +++ /dev/null @@ -1,93 +0,0 @@ ---- - -name: Какие бывают типы - -theory: | - В этом уроке мы рассмотрим систему типов в 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* — строка? Дело в том, что она не является примитивным типом. Внутри она представляет собой массив символов. Несмотря на это техническое различие, строки используются наравне с примитивными типами без особых отличий. - -instructions: | - Выведите на экран результат конкатенации слова *hexlet*, символа *-* и числа 7 - -tips: - - | - Попробуйте поиграть с конкатенированием строк и символов в jshell - - | - [Статья о дробных числах](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Тип данных" -# description: "множество данных в коде (разновидность информации). Тип определяет, что можно делать с элементами конкретного множества. Например, целые числа, рациональные числа, строки — это разные типы данных." -# - name: "Примитивные типы данных" -# description: "простые типы, встроенные в сам язык программирования." -# - name: "Строка (String)" -# description: | -# тип данных, описывающий набор символов (иными словами — текст); например, `"text"` diff --git a/drafts/33-data-types/50-null/description.en.yml b/drafts/33-data-types/50-null/description.en.yml deleted file mode 100644 index 7043f4a..0000000 --- a/drafts/33-data-types/50-null/description.en.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- - -name: Значение null - -theory: | - Особняком в Java стоит значение `null`. В Java оно не является типом. Это просто конкретное значение со специальным смыслом и логикой работы. Начнем с примера: - - ```java - // Определение переменной без инициализации значением - // С var такое не сработает, так как невозможно вывести тип - String a; - ``` - - Что находится внутри переменной `a`? Если мы ее распечатаем, то увидим `null`. Значение `null` используется для ссылочных типов, когда значение не определено. - - Как такое возможно? Представьте, что мы хотим извлечь из базы данных пользователя, а его там нет. Что вернет нам запрос в базу? Вот именно для таких ситуаций и нужен `null`. - - Их гораздо больше, чем может показаться на первый взгляд. Чем дальше мы будем двигаться, тем чаще он начнет встречаться: - - ```java - var user = // тут делаем запрос в базу - // Если данных нет, то user станет null - // Запись выше равносильна - var user = null; - ``` - - Из вышесказанного следует важный вывод. Любой ссылочный тип данных может принимать значение `null`. То есть, `null` является значением любого ссылочного типа. А вот примитивные типы и `null` не совместимы. Примитивное значение всегда должно быть определено: - - ```java - // Error: incompatible types: cannot be converted to int - int x = null; - ``` - -instructions: | - - Определите переменную с именем `greeting`, но не инициализируйте ее - -tips: - - | - [Статья о дробных числах](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Тип данных" -# description: "множество данных в коде (разновидность информации). Тип определяет, что можно делать с элементами конкретного множества. Например, целые числа, рациональные числа, строки — это разные типы данных." -# - name: "Примитивные типы данных" -# description: "простые типы, встроенные в сам язык программирования." -# - name: "Строка (String)" -# description: | -# тип данных, описывающий набор символов (иными словами — текст); например, `"text"` diff --git a/drafts/33-data-types/55-type-casting/description.en.yml b/drafts/33-data-types/55-type-casting/description.en.yml deleted file mode 100644 index 337f7ab..0000000 --- a/drafts/33-data-types/55-type-casting/description.en.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- - -name: Явное преобразование типов - -theory: | - В программировании регулярно встречаются задачи, когда один тип данных нужно преобразовать в другой. Простейший пример – работа с формами на сайтах. - - Данные формы всегда приходят в текстовом виде, даже если значение число. Вот как его можно преобразовать: - - ```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 - -instructions: | - - Выведите на экран строку `2 times`, полученную из числа 2.9 и строки `times`, используя преобразования типов и конкатенацию. -
-  2 times
-  
- -# definitions: [] - -# tips: [] diff --git a/drafts/33-data-types/description.en.yml b/drafts/33-data-types/description.en.yml deleted file mode 100644 index 86f4f6a..0000000 --- a/drafts/33-data-types/description.en.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- - -name: Типы данных Java -description: | - Java — язык со строгой статической типизацией. Как это влияет на код, что такое типы, какие они бывают и кто их выводит. Все это изучается в данном модуле. - diff --git a/drafts/35-methods-using/100-methods/description.en.yml b/drafts/35-methods-using/100-methods/description.en.yml deleted file mode 100644 index 8655be6..0000000 --- a/drafts/35-methods-using/100-methods/description.en.yml +++ /dev/null @@ -1,64 +0,0 @@ ---- - -name: Методы и их вызов - -theory: | - Сложение, конкатенация, нахождение остатка от деления и остальные ранее рассмотренные операции – все это довольно базовые возможности языков программирования. - - Математика не ограничена арифметикой, кроме нее есть и множество других разделов со своими операциями — например, геометрия. То же самое касается и строк: их можно переворачивать, менять регистр букв, удалять лишние символы — и это только самое простое. На более высоком уровне есть прикладная логика конкретного приложения. - - Программы списывают деньги, считают налоги, формируют отчеты. Количество подобных операций бесконечно и индивидуально для каждой программы. И все они должны быть как-то выражены в коде. - - ## Как выражаются операции - - Для выражения любой произвольной операции в программировании существует понятие **функция**. Функции бывают как встроенные в язык, так и добавленные программистом. С одной встроенной функцией мы уже знакомы — это `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. Программисты постоянно сидят в документации разбираясь с тем, как что работает. - -instructions: | - - В коде программы определены две переменные, содержащие имена компаний. Посчитайте их общую длину в символах и выведите ее на экран. - -# tips: [] - -# definitions: -# - name: Метод -# description: "операция, способная принимать данные и возвращать результат; Метод вызывается так: `foo()`." -# - name: Аргумент -# description: "информация, которую метод получает при вызове. Например, `foo(42)` — передача аргумента `42` методу `foo`" diff --git a/drafts/35-methods-using/105-methods-parameters/description.en.yml b/drafts/35-methods-using/105-methods-parameters/description.en.yml deleted file mode 100644 index 9c6e810..0000000 --- a/drafts/35-methods-using/105-methods-parameters/description.en.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- - -name: Параметры методов - -theory: | - - Метод `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 - -instructions: | - - Вам даны три переменные с фамилиями разных людей. Составьте и выведите на экран слово из символов в таком порядке: - - 1. третий символ из первой строки; - 2. второй символ из второй строки; - 3. четвертый символ из третьей строки; - 4. пятый символ из второй строки; - 5. третий символ из второй строки. - - Вывод результата должен быть примерно в таком виде: - -
-  a b c d e
-  
- -# tips: [] - -# definitions: -# - name: Метод -# description: "операция, способная принимать данные и возвращать результат; Метод вызывается так: `foo()`." -# - name: Аргумент -# description: "информация, которую метод получает при вызове. Например, `foo(42)` — передача аргумента `42` методу `foo`" diff --git a/drafts/35-methods-using/110-methods-as-expressions/description.en.yml b/drafts/35-methods-using/110-methods-as-expressions/description.en.yml deleted file mode 100644 index e6bffa7..0000000 --- a/drafts/35-methods-using/110-methods-as-expressions/description.en.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- - -name: Вызов метода — выражение - -theory: | - В программировании выражение — нечто возвращающее результат, который можно использовать. - - Мы уже знаем достаточно много о выражениях и о принципах их построения. Сложение, вычитание, конкатенация, а также другие математические и строковые операции — все это выражения: - - ```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 - ``` - -instructions: | - - Выведите на экран первую и последнюю буквы предложения, записанного в переменную `text`, в следующем формате: - -
-  First: N
-  Last: t
-  
- - Постарайтесь создать только одну переменную, в которую сразу запишется нужный текст перед печатью на экран. В этом уроке мы отрабатываем умение собирать составное выражение. - -# tips: [] diff --git a/drafts/35-methods-using/115-string-immutability/description.en.yml b/drafts/35-methods-using/115-string-immutability/description.en.yml deleted file mode 100644 index 0913155..0000000 --- a/drafts/35-methods-using/115-string-immutability/description.en.yml +++ /dev/null @@ -1,51 +0,0 @@ ---- - -name: Неизменяемость строк - -theory: | - Подумаем, что выведет на экран следующий код: - - ```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 - - Такой подход нередко предпочтительнее по соображениям читаемости. Переменные, которые постоянно меняются, сложнее анализировать. В итоге все зависит от задачи. С опытом придет понимание, какой подход лучше. - -instructions: | - - Данные, вводимые пользователями в формах, часто содержат лишние пробельные символы в конце или начале строки. Кроме того, пользователи могут вводить одно и то же в разном регистре, что потом мешает работе с данными. Поэтому перед тем как добавлять их, данные обрабатывают (говорят нормализуют). В базовую обработку входят два действия: - - * Удаление концевых пробельных символов с помощью метода `.trim()`, например, было: `" hexlet\n "`, стало: `"hexlet"` - * Приведение к нижнему регистру с помощью метода `toLowerCase()`. Было: `"SUPPORT@hexlet.io"`, стало: `"support@hexlet.io"`. - - Обновите переменную `email` записав в неё то же самое значение, но обработанное по схеме указанной выше. Распечатайте то, что получилось, на экран. - -# tips: [] diff --git a/drafts/35-methods-using/120-methods-chain/description.en.yml b/drafts/35-methods-using/120-methods-chain/description.en.yml deleted file mode 100644 index bfa6bbf..0000000 --- a/drafts/35-methods-using/120-methods-chain/description.en.yml +++ /dev/null @@ -1,75 +0,0 @@ ---- - -name: Цепочки вызовов методов - -theory: | - Обработка данных может состоять из достаточно большого количества шагов, которые нужно выполнить. - - Возьмем для примера такую задачу: сформировать адрес страницы в интернете на основе введенного пользователем названия статьи. Такая задача часто возникает при публикации статей в блогах. Подобные адреса выглядят так: - - ``` - 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(); - ``` - - - Несмотря на удобство этого механизма, им не стоит злоупотреблять. Промежуточные переменные могут упростить понимание кода. - -instructions: | - - Напишите код, который берет данные из переменной `name` и выполняет капитализацию. В программировании так называют операцию, которая делает заглавной первую букву в слове, а все остальные переводит в нижний регистр. Например: *heXlet => Hexlet*. Программа должна выводить результат на экран. - - Для извлечения частей слова, воспользуйтесь методом [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java?utm_source=code-basics&utm_medium=referral&utm_campaign=qna&utm_content=lesson): - - ```java - // 1 параметр – начальный индекс, 2 – конечный индекс (не включая) - "hexlet".substring(0, 1); // "h" - // По умолчанию до конца строки - "hexlet".substring(1); // "exlet" - ``` - -# tips: [] diff --git a/drafts/35-methods-using/200-methods-deterministic/description.en.yml b/drafts/35-methods-using/200-methods-deterministic/description.en.yml deleted file mode 100644 index 467e988..0000000 --- a/drafts/35-methods-using/200-methods-deterministic/description.en.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- - -name: Детерминированность - -theory: | - Независимо от того, какой язык программирования используется, методы внутри него обладают некоторыми фундаментальными свойствами. Зная эти свойства, легче прогнозировать поведение методов, способы их тестирования и место их использования. К таким свойствам относится детерминированность. Метод называется детерминированным тогда, когда для одних и тех же входных параметров он возвращает один и тот же результат. Например, метод, извлекающий символ из строки — детерминированный. - - ```java - "wow".charAt(1); // 'o' - "wow".charAt(1); // 'o' - ``` - - Сколько бы раз мы не вызывали этот метод, передавая туда значение `1`, он всегда вернет `'o'`. В свою очередь метод, возвращающий случайное число, не является детерминированным, так как у одного и того же входа (даже если он пустой, то есть параметры не принимаются) мы получим всегда разный результат. Насколько он разный - не важно, даже если хотя бы один из миллиона вызовов вернет что-то другое, этот метод автоматически считается недетерминированным. - - ```java - // Метод, возвращающий случайное число - Math.random(); // 0.09856613113197676 - Math.random(); // 0.8839904367241888 - ``` - - - Зачем это нужно знать? Детерминированность серьезно влияет на многие аспекты. Детерминированные функции удобны в работе, их легко оптимизировать, легко тестировать. Если есть возможность сделать функцию детерминированной, то лучше ее такой и сделать. - -instructions: | - - Метод `Math.random()` возвращает случайное число от 0 до 1 с большим количеством знаков после запятой. Но в реальных задачах бывает нужно получать случайные целые числа. Реализуйте код, который печатает на экран случайное целое число от 0 до 10. Чтобы получить такое число, нужно умножить результат вызова `Math.random()` на 10 и преобразовать тип полученного числа из *double* в *int*. - - ```java - // Преобразование в int - (int) 0.932342; // 0 - (int) 8.123412; // 8 - ``` - - Попробуйте решить это задание в одну строчку - -tips: - - | - [Детерминированные функции](https://ru.wikipedia.org/wiki/Чистота_функции#Детерминированность_функции) - -# definitions: -# - name: Побочный эффект -# description: "действие, которое изменяет внешнее окружение (среду выполнения). Например, вывод на экран или отправка письма." diff --git a/drafts/35-methods-using/400-stdlib/description.en.yml b/drafts/35-methods-using/400-stdlib/description.en.yml deleted file mode 100644 index 244c7bc..0000000 --- a/drafts/35-methods-using/400-stdlib/description.en.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- - -name: Стандартная библиотека - -theory: | - Java, как и любой другой язык, поставляется с набором полезных методов. Все вместе они составляют так называемую **стандартную библиотеку**. В нее обычно входят тысячи методов, которые невозможно выучить — этого и не нужно делать. Подразумевается, что любой программист знает, где искать документацию по ним и примерно представляет себе, чего он хочет достичь. А дальше — дело техники. Если отнять у программистов интернет, то большинство не сможет ничего запрограммировать. - - Для новичков эта информация часто выглядит так: «Сходи туда, не знаю куда, принеси то, не знаю что». То есть непонятно, как узнавать про эти методы, когда ты ничего не знаешь вообще. Как ни странно, не существует способа раз и навсегда познать все, что нужно познать. Любой разработчик в процессе своего профессионального взросления знакомится со все более интересными методами, решающими его задачи более элегантно, и таким образом пополняет свой арсенал. - - Вот некоторые советы, как узнавать о новых методах: - - * Всегда четко отслеживайте, с каким типом данных вы сейчас работаете. Почти всегда вы найдете необходимый метод в соответствующем разделе документации — например, для работы со строками нужно изучать строковые методы - * Периодически открывайте раздел со стандартными методами по изучаемой тематике и просто пробегайтесь по ним, изучая сигнатуры и способы использования - * Чаще читайте чужой код, особенно код библиотек, которые вы используете. Он весь доступен на GitHub - -instructions: | - - Напишем код в стиле "повтори за учителем". Рассчитаем количество дней между двумя датами используя встроенные возможности 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); - ``` - -tips: - - | - [Как искать техническую информацию](https://guides.hexlet.io/how-to-search/) - -# definitions: -# - name: Побочный эффект -# description: "действие, которое изменяет внешнее окружение (среду выполнения). Например, вывод на экран или отправка письма." diff --git a/drafts/35-methods-using/500-methods-variants/description.en.yml b/drafts/35-methods-using/500-methods-variants/description.en.yml deleted file mode 100644 index 2a008dd..0000000 --- a/drafts/35-methods-using/500-methods-variants/description.en.yml +++ /dev/null @@ -1,95 +0,0 @@ ---- - -name: Какие бывают методы - -theory: | - Одна из базовых тем в 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(); - ``` - - ## Выводы - - * Статические методы не связаны с конкретными объектами и вызываются из класса напрямую - * Нестатические методы строят свою логику относительно данных самого объекта и вызываются у конкретных объектов - - Все это плавно подводит нас к возможности самостоятельно создавать классы, объекты и методы, без чего невозможно себе представить ни одну программу, даже небольшую. - -instructions: | - - В переменной `emoji` находится текстовый грустный смайлик *-(*. Ваша задача — сделать этот смайлик веселым с помощью двух преобразований: - - * Добавить слева глаза *:* - * Заменить *(* на *)* (с помощью метода строки `replace()`) - - Должно получиться: *:-)*. Выведите его на экран. - -# tips: -# - | -# [Как искать техническую информацию](https://guides.hexlet.io/how-to-search/) - -# definitions: -# - name: Побочный эффект -# description: "действие, которое изменяет внешнее окружение (среду выполнения). Например, вывод на экран или отправка письма." diff --git a/drafts/35-methods-using/description.en.yml b/drafts/35-methods-using/description.en.yml deleted file mode 100644 index 6704035..0000000 --- a/drafts/35-methods-using/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Вызов методов -description: | - Для выражения любой произвольной операции в программировании существует понятие «функция». Функции — кирпичики, из которых программисты строят системы. В Java функции называют методами. В этом модуле мы научимся пользоваться уже созданными методами. Посмотрим на сигнатуру методов в документации и разберемся, как её использовать. diff --git a/drafts/40-methods-definition/100-method-definition-static/description.en.yml b/drafts/40-methods-definition/100-method-definition-static/description.en.yml deleted file mode 100644 index 8eed1d6..0000000 --- a/drafts/40-methods-definition/100-method-definition-static/description.en.yml +++ /dev/null @@ -1,105 +0,0 @@ ---- - -name: Создание (определение) метода - -theory: | - Определение собственных методов значительно упрощает написание и поддержку программ. Например, методы позволяют объединять составные операции в одну. - - К примеру, отправка письма на сайте — это достаточно сложный процесс, включающий в себя взаимодействие с интернетом. Можно определить метод и скрыть всю сложность за одной простой конструкцией: - - ```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/programs/java?utm_source=code-basics&utm_medium=referral&utm_campaign=programs&utm_content=lesson). - - За работу метода отвечают: - - * *static* — отвязывает метод от объекта и делает возможным его вызов напрямую из класса - * *void* используется, если метод ничего не возвращает. Например, такое определение у метода `System.out.println()`. Если метод возвращает какие-то данные, то вместо *void* указывается тип возвращаемых данных - - В отличие от обычных данных, методы выполняют действия, поэтому их имена практически всегда должны быть глаголами: «построить что-то», «нарисовать что-то», «открыть что-то». - - Все, что описывается внутри фигурных скобок `{}`, называется **телом метода**. Внутри тела можно описывать любой код. Считайте, что это маленькая самостоятельная программа, набор произвольных инструкций. - - Тело выполняется ровно в тот момент, когда запускается метод. Причем каждый вызов метода запускает тело независимо от других вызовов. Кстати, тело может быть пустым: - - ```java - // Минимальное определение метода - public class App { - public static void noop() { - // Тут мог бы быть код, но его нет - // Обратите внимание на отступы - // Для читаемости, любой код внутри тела сдвигается вправо на 4 пробела - } - } - App.noop(); - ``` - - Понятие «создать метод» имеет много синонимов: «реализовать», «определить» и даже «заимплементить». Все эти термины встречаются в повседневной практике на работе. - - -instructions: | - - Реализуйте статический метод с именем `printMotto()`, который выведет на экран фразу *Winter is coming*. - - ```java - // Класс App уже определен - App.printMotto(); // => Winter is coming - ``` - - Чтобы мы могли вызвать этот метод снаружи, нужно его пометить не только ключевым словом `static`, но еще и `public`. - - В задачах, в которых нужно реализовать метод, этот метод вызывать не нужно. Вызывать метод будут автоматизированные тесты, которые проверяют его работоспособность. Пример с вызовом выше показан только для того, чтобы вы понимали, как ваш метод будет использоваться. - -tips: - - | - [Именование в программировании](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) diff --git a/drafts/40-methods-definition/150-method-main/description.en.yml b/drafts/40-methods-definition/150-method-main/description.en.yml deleted file mode 100644 index 58a5f91..0000000 --- a/drafts/40-methods-definition/150-method-main/description.en.yml +++ /dev/null @@ -1,118 +0,0 @@ ---- - -name: Метод main - -theory: | - Возможно вы удивитесь, но на протяжении всех предыдущих уроков, мы создавали свой собственный метод. Каркас метода был заранее написан, а от вас требовалось добавить его тело. Практика выглядела так: - - ```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/programs/java?utm_source=code-basics&utm_medium=referral&utm_campaign=programs&utm_content=lesson). - - Главное, что нужно сейчас запомнить — любые статические методы вызываются через точку после имени класса, а сами вызовы происходят внутри других методов: - - ```java - // Просто пример вызовов методов друг из друга - class MySuperClassName { - public static void oneMethod() { - MySuperClassName.twoMethod(); - } - - public static void twoMethod() { - MySuperClassName.threeMethod(); - } - - public static void threeMethod() { - } - } - ``` - -instructions: | - - Реализуйте класс с именем `App` и двумя методами: - - 1. Метод `gogo()`, который печатает на экран строку `It works!` - 2. `main()`, как в определении выше, который вызывает метод `gogo()` - - Результат вызова `main()` в таком случае будет таким: - - ```java - // => "It works!" - ``` - -# tips: -# - | -# [Именование в программировании](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) diff --git a/drafts/40-methods-definition/200-method-definition-return/description.en.yml b/drafts/40-methods-definition/200-method-definition-return/description.en.yml deleted file mode 100644 index efab5da..0000000 --- a/drafts/40-methods-definition/200-method-definition-return/description.en.yml +++ /dev/null @@ -1,154 +0,0 @@ ---- - -name: Возврат значений - -theory: | - Методы, которые мы определяли в предыдущих уроках, заканчивали свою работу тем, что печатали на экран какие-то данные: - - ```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; - } - } - ``` - - - В этом примере в определении метода использовался `long`, так как возвращается целое число. - - Чтобы проверить знания из этого урока, попробуйте ответить на вопрос. Как думаете, что выведет этот код? - - ```java - // Определение - class App { - public static int run() { - return 5; - return 10; - } - } - - // Использование - App.run(); // => ? - ``` - -instructions: | - - Реализуйте статический метод `sayHurrayThreeTimes()`, которая возвращает строку 'hurray! hurray! hurray!'. - - ```java - var hurray = App.sayHurrayThreeTimes(); - System.out.println(hurray); // => hurray! hurray! hurray! - ``` - -# tips: [] diff --git a/drafts/40-methods-definition/300-method-definition-parameters/description.en.yml b/drafts/40-methods-definition/300-method-definition-parameters/description.en.yml deleted file mode 100644 index 5249082..0000000 --- a/drafts/40-methods-definition/300-method-definition-parameters/description.en.yml +++ /dev/null @@ -1,147 +0,0 @@ ---- - -name: Определение методов - -theory: | - Методы могут не только возвращать значения, но и принимать их в виде параметров. С параметрами методов мы уже сталкивались много раз: - - ```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); - } - } - ``` - - - Разберем этот код подробнее. `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 - ``` - - - Методы могут требовать на вход любое количество параметров, которое им нужно для работы: - - ```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 - ``` - -instructions: | - - Реализуйте статический метод `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?utm_source=code-basics&utm_medium=referral&utm_campaign=qna&utm_content=lesson). Подумайте, исходя из задания, с какого индекса и по какой вам надо извлечь подстроку? - - ```java - var text = "welcome"; - // Передавать параметры в метод можно через переменные - var index = 3; - text.substring(0, index); // wel - ``` - - С точки зрения проверочной системы не имеет значения, каким из способов будет реализован метод `truncate()` внутри, главное – чтобы он выполнял поставленную задачу diff --git a/drafts/40-methods-definition/400-method-definition-default-parameters/description.en.yml b/drafts/40-methods-definition/400-method-definition-default-parameters/description.en.yml deleted file mode 100644 index f6241b6..0000000 --- a/drafts/40-methods-definition/400-method-definition-default-parameters/description.en.yml +++ /dev/null @@ -1,118 +0,0 @@ ---- - -name: Необязательные параметры методов - -theory: | - - - В программировании большое количество функций и методов имеют параметры, которые редко меняются. - - В таких случаях этим параметрам задают **значения по умолчанию**, которые можно поменять по необходимости. Этим немного сокращается количество одинакового кода. - - Это наглядно видно на таком примере: - - ```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 - - В этом примере мы не сократили код, но он наглядно показывает принцип, описанный выше. - -instructions: | - - Реализуйте метод `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" - ``` - -# tips: [] diff --git a/drafts/40-methods-definition/description.en.yml b/drafts/40-methods-definition/description.en.yml deleted file mode 100644 index 78fbb50..0000000 --- a/drafts/40-methods-definition/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Определение методов -description: | - Определение собственных методов значительно упрощает написание и поддержку программ. Например, умение определять методы позволяет объединять сложные (составные) операции в одну – вся сложность может быть скрыта в одном простом методе. Научившись создавать методы, вы сделаете первый шаг на пути к построению по-настоящему полезных программ. И мы вам в этом поможем. В этом модуле вы создадите свой первый метод и научитесь давать ему (а заодно переменным) понятные названия. diff --git a/drafts/45-logic/10-bool-type/description.en.yml b/drafts/45-logic/10-bool-type/description.en.yml deleted file mode 100644 index d5de3eb..0000000 --- a/drafts/45-logic/10-bool-type/description.en.yml +++ /dev/null @@ -1,84 +0,0 @@ ---- - -name: Логический тип - -theory: | - Кроме арифметических операций, из школьной математики нам известны еще и операции сравнения, например: - - ``` - 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 - ``` - -instructions: | - - Реализуйте метод `isPensioner()`, который принимает один параметр — возраст человека, и проверяет, является ли он пенсионным. Пенсионером считается человек, достигший возраста 60 лет и больше. - - Примеры вызова: - - ```java - App.isPensioner(75); // true - App.isPensioner(18); // false - ``` - -definitions: - - name: "Логический тип (boolean)" - description: "тип данных с двумя возможными значениями: true (истина) и false (ложь)." diff --git a/drafts/45-logic/12-string-comparasion/description.en.yml b/drafts/45-logic/12-string-comparasion/description.en.yml deleted file mode 100644 index 188ef9a..0000000 --- a/drafts/45-logic/12-string-comparasion/description.en.yml +++ /dev/null @@ -1,151 +0,0 @@ ---- - -# Переписать на человеческий - -name: Сравнение строк - -theory: | - Посмотрите на код и попытайтесь ответить, чему равны значения этих выражений: - - ```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 - ``` - - - Помимо `equals()`, в строки встроен метод `equalsIgnoreCase()`, который выполняет проверку по значению без учета регистра: - - ```java - var name1 = "java".toUpperCase(); // "JAVA" - var name2 = "java".toLowerCase(); // "java" - name1.equalsIgnoreCase(name2); // true - ``` - - Иногда сравнение строк в Java ведет себя как сравнение значений, но никогда не делайте ставку на это. При изменении кода легко забыть поправить проверку и получить ошибку. Всегда используйте методы, когда нужно сравнивать по значению. - -instructions: | - - Реализуйте метод `isPalindrome()`, который определяет, является ли слово палиндромом или нет. Палиндром это слово, которое читается одинаково в обоих направлениях. - - ```java - App.isPalindrome("шалаш"); // true - App.isPalindrome("ага"); // true - App.isPalindrome("хекслет"); // false - - // Слова в метод могут быть переданы в любом регистре - App.isPalindrome("Ага"); // true - ``` - - Для определения палиндрома, необходимо перевернуть строку и сравнить ее с исходной. Для этого воспользуйтесь методом `StringUtils.reverse()` - - ```java - StringUtils.reverse("мама"); // "амам" - ``` - -# tips: [] diff --git a/drafts/45-logic/20-combine-expressions/description.en.yml b/drafts/45-logic/20-combine-expressions/description.en.yml deleted file mode 100644 index cc46ae8..0000000 --- a/drafts/45-logic/20-combine-expressions/description.en.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- - -name: Комбинирование операций и методов -theory: | - - Логические операции — это выражения. Значит, **логические операции можно комбинировать с другими выражениями**. Разберем на примере. Допустим, мы хотим проверить четность числа. В программировании четность проверяется через остаток от деления на 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 - ``` - - - В одном выражении мы скомбинировали два логических оператора: - - * `==` — проверка равенства - * `%` — арифметический оператор остатка от деления - - **Приоритет арифметических операций выше логических.** Значит, сначала вычисляется арифметическое выражение `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 - ``` - -instructions: | - - Реализуйте метод `isInternationalPhone()`, который проверяет формат указанного телефона. Если телефон начинается с *+*, значит это международный формат. - - ```java - App.isInternationalPhone("89602223423"); // false - App.isInternationalPhone("+79602223423"); // true - ``` - -# tips: -# - | -# Подробнее изучить метод `startsWith()` можно на странице [java.lang.String](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#startsWith(java.lang.String)) diff --git a/drafts/45-logic/25-logical-operators/description.en.yml b/drafts/45-logic/25-logical-operators/description.en.yml deleted file mode 100644 index afd7e6e..0000000 --- a/drafts/45-logic/25-logical-operators/description.en.yml +++ /dev/null @@ -1,108 +0,0 @@ ---- - -name: Логические операторы -theory: | - - Мы уже умеем писать методы, которые проверяют одиночные условия. В этом уроке мы продолжим работу с методами и научимся строить составные условия. - - Такие навыки пригождаются в довольно распространенных задачах — например, при проверке пароля. Как вы знаете, некоторые сайты при регистрации просят придумать пароль от 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)); - } - ``` - - - Область математики, в которой изучаются логические операторы, называется **булевой алгеброй**. Ниже показаны «таблицы истинности» — по ним можно определить, каким будет результат применения оператора: - - ### Оператор И `&&` - - | 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 | - -instructions: | - - Реализуйте метод `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 - ``` - -tips: - - | - [Булева алгебра](https://ru.wikipedia.org/wiki/Булева_алгебра) - - | - [Конъюнкция](https://ru.wikipedia.org/wiki/Конъюнкция) - - | - [Дизъюнкция](https://ru.wikipedia.org/wiki/Дизъюнкция) - -# definitions: -# - name: "Логические операторы" -# description: "операторы «И» (&&), ИЛИ (||), позволяющие создавать составные логические условия." diff --git a/drafts/45-logic/28-logical-negation/description.en.yml b/drafts/45-logic/28-logical-negation/description.en.yml deleted file mode 100644 index 5579451..0000000 --- a/drafts/45-logic/28-logical-negation/description.en.yml +++ /dev/null @@ -1,46 +0,0 @@ ---- - -name: Отрицание - -theory: | - Наряду с конъюнкцией (**И**) и дизъюнкцией (**ИЛИ**), часто используется операция «**отрицание**». - - Отрицание меняет логическое значение на противоположное. В программировании ему соответствует оператор `!`. Если есть метод, проверяющий четность числа, то с помощью отрицания можно выполнить проверку нечетности: - - ```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 - ``` - - Отрицание — мощный инструмент, который позволяет лаконично выражать задуманные правила в коде без необходимости писать новые методы. - -instructions: | - - Реализуйте метод `notToday()`, который проверяет что переданная дата это не сегодняшнее число: - - ```java - // предположим сегодня 2012-11-25 - notToday("2012-11-25"); // false - notToday("2013-11-25"); // true - notToday("2013-09-01"); // true - ``` - - Для получения текущей даты в виде строки: `LocalDate.now().toString()`. - -tips: - - | - [Законы Де Моргана](https://ru.wikipedia.org/wiki/Законы_де_Моргана) diff --git a/drafts/45-logic/description.en.yml b/drafts/45-logic/description.en.yml deleted file mode 100644 index 08519fb..0000000 --- a/drafts/45-logic/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Логика -description: | - Логические выражения позволяют отвечать на вопросы, которые возникают во время работы программы. Пользователь аутентифицирован? Подписка оплачена? Год високосный? В этом модуле изучаем функции-предикаты – те, которые задают вопрос и отвечают на него – правда это или ложь. Попрактикуемся в написании таких функций и перейдем к более сложным логическим выражениям. diff --git a/drafts/80-conditionals/30-if/description.en.yml b/drafts/80-conditionals/30-if/description.en.yml deleted file mode 100644 index 5989f3b..0000000 --- a/drafts/80-conditionals/30-if/description.en.yml +++ /dev/null @@ -1,51 +0,0 @@ ---- - -name: Условная конструкция (if) - -theory: | - Условные конструкции позволяют выполнять разный код, основываясь на логических проверках. Посмотрим на таком типичном примере: - - * Человек хочет оплатить покупку с карты - * Если на счету есть деньги на счету, то нужная сумма спишется автоматически - * Если денег нет, то операция будет отклонена - - Для примера напишем метод, который определяет тип переданного предложения. Для начала он будет отличать обычные предложения от вопросительных: - - ```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";` — заставит метод вернуть строку и завершиться. - -instructions: | - - Реализуйте метод `getSentenceTone()`, которая принимает строку и определяет тон предложения. Если все символы в верхнем регистре, то это вопль — `scream`. В ином случае — нормальное предложение — `normal`. - - Примеры вызова: - - ```java - App.getSentenceTone("Hello"); // "normal" - App.getSentenceTone("WOW"); // "scream" - ``` - - Алгоритм: - - 1. Сгенерируйте строку в верхнем регистре на основе строки-аргумента с помощью `toUpperCase()`. - 2. Сравните её с исходной строкой: - * Если строки равны, значит, строка-аргумент в верхнем регистре - * В ином случае — строка-аргумент не в верхнем регистре - -tips: [] - -definitions: [] diff --git a/drafts/80-conditionals/40-if-else/description.en.yml b/drafts/80-conditionals/40-if-else/description.en.yml deleted file mode 100644 index b265a51..0000000 --- a/drafts/80-conditionals/40-if-else/description.en.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- - -name: Конструкция if-else - -theory: | - Условная конструкция `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 не нужен - ``` - -instructions: | - - Реализуйте метод `normalizeUrl()`, который выполняет так называемую нормализацию данных. Он принимает адрес сайта и возвращает его с *https://* в начале. - - Метод принимает адреса в виде *АДРЕС* или *https://АДРЕС*, но всегда возвращает адрес в виде *https://АДРЕС* - - Можно использовать метод `startsWith()` чтобы проверить начинается ли строка с префикса *https://*. А потом на основе этого добавлять или не добавлять *https://*. - - ```java - App.normalizeUrl("google.com"); // "https://google.com" - App.normalizeUrl("https://ai.fi"); // "https://ai.fi" - ``` - -# tips: [] - -# definitions: -# - name: "else" -# description: "способ задать блок кода, который будет выполнен, если условие с `if` не удовлетворено" diff --git a/drafts/80-conditionals/50-else-if/description.en.yml b/drafts/80-conditionals/50-else-if/description.en.yml deleted file mode 100644 index 9650431..0000000 --- a/drafts/80-conditionals/50-else-if/description.en.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- - -name: Конструкция else if - -theory: | - В самой полной версии конструкция `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; - } - ``` - - - Теперь все условия выстроены в единую конструкцию. Оператор `else if` — это «если не выполнено предыдущее условие, но выполнено текущее». Получается такая схема: - - - Если последний символ `?`, то "question" - - Иначе, если последний символ `!`, то "exclamation" - - Иначе "general" - - В итоге выполнится только один из блоков кода, относящихся ко всей конструкции `if`. - -instructions: | - - На электронной карте Вестероса, которую реализовал Сэм, союзники Старков отображены зеленым кружком, враги — красным, а нейтральные семьи — серым. - - Напишите для Сэма метод `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" - ``` - -# tips: [] - -# definitions: -# - name: "else if" -# description: "способ задать несколько альтернативных условий" diff --git a/drafts/80-conditionals/60-ternary-operator/description.en.yml b/drafts/80-conditionals/60-ternary-operator/description.en.yml deleted file mode 100644 index c7b20c9..0000000 --- a/drafts/80-conditionals/60-ternary-operator/description.en.yml +++ /dev/null @@ -1,65 +0,0 @@ ---- - -name: Тернарный оператор - -theory: | - Посмотрите на определение метода, который возвращает модуль переданного числа: - - ```java - // Если больше нуля, то выдаем само число. Если меньше, то убираем знак - public static int abs(int number) { - if (number >= 0) { - return number; - } - - return -number; - } - - App.abs(10); // 10 - App.abs(-10); // 10 - ``` - - В Java существует конструкция, которая по своему действию аналогична конструкции *if-else*, но при этом является выражением. Она называется **тернарный оператор**. - - Тернарный оператор — единственный в своем роде оператор, требующий три операнда. Он помогает писать меньше кода для простых условных выражений. Наш пример выше с тернарным оператором превращается в три строки кода: - - ```java - public static int abs(int number) { - return number >= 0 ? number : -number; - } - ``` - - Общий шаблон выглядит так: - - ```java - ? : - ``` - - То есть сначала мы записываем логическое выражение, а дальше два разных варианта поведения: - - 1. Если условие истинно, выполняет вариант до двоеточия - 2. Если условие ложно, выполняет вариант после двоеточия - -instructions: | - - Реализуйте метод `convertString()`, который принимает на вход строку и, если первая буква не заглавная, возвращает перевернутый вариант исходной строки. Если первая буква заглавная, то строка возвращается без изменений. Если на вход передана пустая строка, метод должен вернуть пустую строку. - - ```java - App.convertString("Hello"); // "Hello" - App.convertString("hello"); // "olleh" - - // Не забудьте учесть пустую строку! - App.convertString(""); // "" - ``` - - * `StringUtils.reverse()` – переворот строки - * `Character.isUpperCase()` – проверка символа на верхний регистр - - Попробуйте написать два варианта функции: с обычным if-else, и с тернарным оператором. - -tips: [] - -definitions: - - name: Тернарный оператор - description: | - Способ превратить простую условную инструкцию в выражение, например, `number >= 0 ? number : -number`. diff --git a/drafts/80-conditionals/80-switch/description.en.yml b/drafts/80-conditionals/80-switch/description.en.yml deleted file mode 100644 index 4ca4a47..0000000 --- a/drafts/80-conditionals/80-switch/description.en.yml +++ /dev/null @@ -1,132 +0,0 @@ ---- - -name: Конструкция Switch - -theory: | - Многие языки используют не только условную конструкцию `if`, но и `switch` в дополнение к ней. Конструкция `switch` — это специализированная версия `if`, созданная для некоторых особых ситуаций. - - Например, ее стоит использовать там, где есть цепочка `if else` с проверками на равенство: - - ```java - if (status.equals("processing")) { - // Делаем раз - } else if (status.equals("paid")) { - // Делаем два - } else if (status.equals("new")) { - // Делаем три - } else { - // Делаем четыре - } - ``` - - Эта составная проверка обладает одной отличительной чертой: каждая ветка здесь — это проверка значения переменной `status`. Конструкция `switch` позволяет записать этот код короче и выразительнее: - - ```java - switch (status) { - case "processing": - // Делаем раз - break; - case "paid": - // Делаем два - break; - case "new": - // Делаем три - break; - default: // else - // Делаем четыре - } - ``` - - С точки зрения количества элементов, `switch` — довольно сложная конструкция. В нее входят: - - * Внешнее описание с ключевым словом `switch`. В нем два элемента: - - Переменная, по значениям которой `switch` будет выбирать поведение - - Фигурные скобки для вариантов выбора - * Конструкции `case` и `default`, внутри которых описывается поведение для разных значений рассматриваемой переменной. Каждый `case` соответствует `if`, как в примере выше. Здесь `default` — это особая ситуация, соответствующая ветке `else` в условных конструкциях. Как и в случае с `else`, указывать `default` необязательно - * Конструкция `break`, которая предотвращает «проваливание». Если ее не указать, то после выполнения нужного `case`, выполнение перейдет к следующему `case`. Этот цикл будет повторяться до ближайшего `break` или до конца `switch` - - Фигурные скобки в `switch` не определяют блок кода, как это было в других местах. Внутри допускается только тот синтаксис, который показан выше — там есть там можно использовать `case` или `default`. А вот внутри каждого `case` (и `default`) ситуация другая. Здесь можно выполнять любой произвольный код: - - ```java - switch (count) { - case 1: - // Делаем что-то полезное - break; - case 2: - // Делаем что-то полезное - break; - default: - // Что-то делаем - } - ``` - - Иногда результат, полученный внутри `case` — это конец выполнения метода, содержащего `switch`. В таком случае его нужно как-то вернуть наружу. Для решения этой задачи есть два способа. - - Первый способ — можно создать переменную перед `switch`, заполнить ее в `case` и затем вернуть значение этой переменной наружу: - - ```java - class App { - public static String getExplanation(int count) { - // Объявляем переменную - String result; - - // Заполняем - switch(count) { - case 1: - result = "one"; - break; - case 2: - result = "two"; - break; - default: - result = null; - } - - // Возвращаем - return result; - } - } - ``` - - Второй способ проще и короче. Вместо создания переменной можно использовать `case`, внутри которого можно делать обычный возврат из метода. После `return` никакой код не выполняется, так что мы можем избавиться от `break`: - - ```java - class App { - public static String getExplanation(int count) { - - switch(count) { - case 1: - return "one"; - case 2: - return "two"; - default: - return null; - } - } - } - ``` - - https://replit.com/@hexlet/java-basics-switch - - `Switch` хоть и встречается в коде, но технически всегда можно обойтись без него. - - Польза этой конструкции в том, что она лучше выражает намерение программиста, когда нужно проверять конкретные значения переменной. В отличие от блоков `else if`, код со `switch` становится немного длиннее, но читать его гораздо проще. - -instructions: | - - Реализуйте метод `getNumberExplanation()`, который принимает на вход число и возвращает объяснение этого числа. Если для числа нет объяснения, то возвращается `null`: - - ```java - App.getNumberExplanation(8); // null - - // Объяснения есть только для указанных ниже чисел - App.getNumberExplanation(666); // "devil number" - App.getNumberExplanation(42); // "answer for everything" - App.getNumberExplanation(7); // "prime number" - ``` - -# tips: -# - | -# [switch](https://developer.mozilla.org/ru/docs/Web/java/Reference/Statements/switch) - -definitions: [] diff --git a/drafts/80-conditionals/description.en.yml b/drafts/80-conditionals/description.en.yml deleted file mode 100644 index ac21dcf..0000000 --- a/drafts/80-conditionals/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Условные конструкции -description: | - Задача функции-предиката — получить ответ на вопрос, но обычно этого недостаточно и нужно выполнить определенное действие в зависимости от ответа. If и Switch – конструкции java, с помощью которых программист может выбирать необходимое поведение программы в зависимости от разных условий: пропускать одни инструкции и выполнять другие. Их и разберем на практике в этом модуле. diff --git a/drafts/90-loops/100-while/description.en.yml b/drafts/90-loops/100-while/description.en.yml deleted file mode 100644 index 839bfb5..0000000 --- a/drafts/90-loops/100-while/description.en.yml +++ /dev/null @@ -1,147 +0,0 @@ ---- - -name: Цикл While - -theory: | - Программы, которые мы пишем во время обучения, становятся все сложнее и объемнее. Они все еще очень далеки от реальных программ, где количество строк кода измеряется десятками и сотнями тысяч, но текущая сложность уже способна заставить напрячься людей без опыта. - - Начиная с этого урока, мы переходим к одной из самых сложных базовых тем в программировании – **циклам**. - - Любые прикладные программы служат очень прагматичным целям. Они помогают управлять сотрудниками, финансами, развлекают в конце концов. Несмотря на различия, все эти программы выполняют заложенные в них алгоритмы, которые очень похожи между собой. - - **Алгоритм** — это последовательность действий или инструкций, которая приводит нас к какому-то ожидаемому результату. Это описание подходит под любую программу, но под алгоритмами обычно понимается что-то более специфичное. - - Представьте себе, что у нас есть книга и мы хотим найти внутри нее какую-то конкретную фразу. Саму фразу мы помним, но не знаем, на какой она странице. Как найти нужную страницу? - - Самый простой и долгий способ — последовательно просматривать книгу до тех пор, пока мы не найдем нужную страницу. В худшем случае придется просмотреть все страницы, но результат мы все равно получим. - - Именно этот процесс и называется **алгоритмом**. Он включает в себя перебор страниц и логические проверки, нашли мы фразу или нет. Количество страниц, которое придется посмотреть, заранее неизвестно, но сам процесс просмотра повторяется из раза в раз совершенно одинаковым образом. - - Для выполнения повторяющихся действий как раз и нужны циклы. Каждый такой повтор называется **итерацией**. - - Допустим, мы хотим написать метод. Он должен выводить на экран все числа от 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); - ``` - -
-  1
-  2
-  3
-  finished!
-  
- - - В коде метода использован цикл `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) { - // Что-то делаем - } - ``` - - Подведем итог. Когда все же нужны циклы, а когда можно обойтись без них? Невозможно обойтись без циклов тогда, когда алгоритм решения задачи требует повторения каких-то действий, при этом количество этих операций заранее неизвестно. Так и было в примере с книгой, который мы рассматривали в начале урока. - -instructions: | - - Модифицируйте метод `printNumbers()` так, чтобы она выводила числа в обратном порядке. Для этого нужно идти от верхней границы к нижней. То есть счётчик должен быть инициализирован максимальным значением, а в теле цикла его нужно уменьшать до нижней границы. - - Пример вызова и вывода: - - ```java - printNumbers(4); - ``` - -
-    4
3
2
1
finished! -
- -# tips: -# - | -# [Цикл while](https://developer.mozilla.org/ru/docs/Web/java/Reference/Statements/while) - -definitions: - - name: Цикл While - description: инструкция для повторения кода, пока удовлетворяется какое-то условие. diff --git a/drafts/90-loops/150-aggregation-numbers/description.en.yml b/drafts/90-loops/150-aggregation-numbers/description.en.yml deleted file mode 100644 index 9e5924f..0000000 --- a/drafts/90-loops/150-aggregation-numbers/description.en.yml +++ /dev/null @@ -1,104 +0,0 @@ ---- - -name: Агрегация данных (Числа) - -theory: | - В программировании есть отдельный класс задач, который не может обойтись без циклов — он называется **агрегированием данных**. - - К таким задачам относятся поиска: - - * Максимального значения - * Минимального значения - * Суммы - * Среднего арифметического - - Их главная особенность в том, что результат зависит от всего набора данных. Для расчета суммы нужно сложить **все** числа, для вычисления максимального нужно сравнить **все** числа. - - С этой темой хорошо знакомы все, кто занимаются числами. Например, с такими задачами часто работают бухгалтеры или маркетологи в таблицах наподобие 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"` - -instructions: | - - Реализуйте метод `multiplyNumbersFromRange()`, который перемножает числа в указанном диапазоне включая границы диапазона. Пример вызова: - - ```java - App.multiplyNumbersFromRange(1, 5); // 1 * 2 * 3 * 4 * 5 = 120 - App.multiplyNumbersFromRange(2, 3); // 2 * 3 = 6 - App.multiplyNumbersFromRange(6, 6); // 6 - ``` - -tips: [] diff --git a/drafts/90-loops/200-aggregation-strings/description.en.yml b/drafts/90-loops/200-aggregation-strings/description.en.yml deleted file mode 100644 index 1566819..0000000 --- a/drafts/90-loops/200-aggregation-strings/description.en.yml +++ /dev/null @@ -1,52 +0,0 @@ ---- - -name: Агрегация данных (Строки) - -theory: | - Агрегация применяется не только к числам, но и к строкам. - - При агрегации строка формируется динамически, то есть заранее неизвестно, какого она размера и что будет содержать. Представьте себе метод, который умеет умножать строку — то есть он повторяет ее указанное количество раз: - - ```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" - ``` - -instructions: | - - Реализуйте метод `joinNumbersFromRange()`, который объединяет все числа из диапазона в строку: - - ```java - App.joinNumbersFromRange(1, 1); // "1" - App.joinNumbersFromRange(2, 3); // "23" - App.joinNumbersFromRange(5, 10); // "5678910" - ``` - -tips: [] diff --git a/drafts/90-loops/250-iteration-over-strings/description.en.yml b/drafts/90-loops/250-iteration-over-strings/description.en.yml deleted file mode 100644 index 9796357..0000000 --- a/drafts/90-loops/250-iteration-over-strings/description.en.yml +++ /dev/null @@ -1,48 +0,0 @@ ---- - -name: Обход строк - -theory: | - Циклы подходят не только для обработки чисел, но и при работе со строками. В первую очередь благодаря возможности получить конкретный символ по его индексу. Ниже пример кода, который распечатывает буквы каждого слова на отдельной строке: - - ```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` - - Оба способа приводят к одному результату. - -instructions: | - - Реализуйте статический метод `App.printReversedNameBySymbol()`, который печатает переданное слово посимвольно, как в примере из теории, но делает это в обратном порядке. - - ```java - var name = "Arya"; - App.printReversedNameBySymbol(name); - // 'a' - // 'y' - // 'r' - // 'A' - ``` - -tips: [] diff --git a/drafts/90-loops/300-conditions-inside-loops/description.en.yml b/drafts/90-loops/300-conditions-inside-loops/description.en.yml deleted file mode 100644 index 9dbb357..0000000 --- a/drafts/90-loops/300-conditions-inside-loops/description.en.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- - -name: Условия внутри тела цикла - -theory: | - Тело цикла, как и тело метода — это место выполнения инструкций. Значит, мы можем использовать внутри него все изученное ранее — в том числе условные конструкции. - - Рассмотрим метод, который считает, сколько раз входит буква в предложение: - - ```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` увеличивается только в том случае, когда текущий рассматриваемый символ совпадает с ожидаемым. В остальном — это типичный агрегатный метод, который возвращает количество нужных символов вызываемому коду. - -instructions: | - - Метод из теории учитывает регистр букв. То есть `A` и `a` с его точки зрения разные символы. Реализуйте вариант этого же метода, так чтобы регистр букв был не важен: - - ```java - App.countChars("HexlEt", 'e'); // 2 - App.countChars("HexlEt", 'E'); // 2 - ``` - - * `Character.toLowerCase()` – переводит символ в нижний регистр - -tips: [] diff --git a/drafts/90-loops/350-build-strings/description.en.yml b/drafts/90-loops/350-build-strings/description.en.yml deleted file mode 100644 index 4f5eee0..0000000 --- a/drafts/90-loops/350-build-strings/description.en.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- - -name: Формирование строк в циклах - -theory: | - Еще одно использование циклов — **формирование строк**. Подобная задача нередко встречается в программировании. Она сводится к обычной агрегации через конкатенацию. - - Есть одна задача, которая популярна на собеседованиях — это **переворот строки**. Ее можно решить множеством разных способов, но именно посимвольный перебор считается базовым: - - ```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 - - Важно прочувствовать, как собирается сама строка — каждый следующий символ прикрепляется к результирующей строке слева, и в итоге строка оказывается перевернута. - -instructions: | - - Реализуйте такой же метод `reverse()`, но выполняющий обход строки не с первого элемента по последний, а наоборот, от последнего к первому. Общая структура функции при этом останется такой же. Изменится начальный индекс, условие окончания цикла, сборка новой строки и формирование нового индекса в цикле. - -tips: [] diff --git a/drafts/90-loops/400-syntax-sugar/description.en.yml b/drafts/90-loops/400-syntax-sugar/description.en.yml deleted file mode 100644 index 103846e..0000000 --- a/drafts/90-loops/400-syntax-sugar/description.en.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- - -name: Синтаксический сахар - -theory: | - Подобные конструкции `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"` - -instructions: | - - Реализуйте статический метод `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" - ``` - -tips: [] diff --git a/drafts/90-loops/450-mutators/description.en.yml b/drafts/90-loops/450-mutators/description.en.yml deleted file mode 100644 index 40551e3..0000000 --- a/drafts/90-loops/450-mutators/description.en.yml +++ /dev/null @@ -1,72 +0,0 @@ ---- - -name: Инкремент и декремент - -theory: | - Из языка Си в 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`. Понять такой код почти невозможно. - - Рекомендации по использованию: - - * Никогда не смешайте операции без побочных эффектов и операциями с побочными эффектами. То же самое касается и методов - * Используйте инкремент и декремент только там, где нет разницы между префиксным и постфиксным вариантом — отдельно от всего, на отдельной строчке кода - -instructions: | - - Реализуйте статический метод `App.makeItFunny()`, который принимает на вход строку и возвращает её копию, у которой каждый n-ный элемент переведен в верхний регистр. n – задается на входе в функцию. Для определения каждого n-ного элемента понадобится остаток от деления `%`. Подумайте, как его можно использовать. - - ```java - var text = "I never look back"; - // Каждый третий элемент - App.makeItFunny(text, 3); // "I NevEr LooK bAck" - ``` - -tips: - - | - [Остаток от деления (%)](https://ru.wikipedia.org/wiki/Деление_с_остатком) diff --git a/drafts/90-loops/500-return-from-loops/description.en.yml b/drafts/90-loops/500-return-from-loops/description.en.yml deleted file mode 100644 index e10e9e1..0000000 --- a/drafts/90-loops/500-return-from-loops/description.en.yml +++ /dev/null @@ -1,62 +0,0 @@ ---- - -name: Возврат из циклов -theory: | - - Работа с циклами обычно сводится к двум сценариям: - - 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`. - - И только если цикл отработал целиком, можно сделать вывод, что число — простое, так как не было найдено ни одного числа, которое делит число без остатка. - -instructions: | - - Реализуйте статический метод `App.hasChar()`, который проверяет (с учётом регистра), содержит ли строка указанную букву. Метод принимает два параметра: - - * Строка - * Буква для поиска - - ```java - App.hasChar("Renly", 'R'); // true - App.hasChar("Renly", 'r'); // false - App.hasChar("Tommy", 'm'); // true - App.hasChar("Tommy", 'd'); // false - ``` - -tips: - - | - [Список простых чисел](https://ru.wikipedia.org/wiki/Список_простых_чисел) diff --git a/drafts/90-loops/550-for/description.en.yml b/drafts/90-loops/550-for/description.en.yml deleted file mode 100644 index 111ae07..0000000 --- a/drafts/90-loops/550-for/description.en.yml +++ /dev/null @@ -1,50 +0,0 @@ ---- - -name: Цикл For - -theory: | - Цикл `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; - } - ``` - - - Этот код можно описать так: - - > Цикл с индексом `i` повторяется, пока `i < str.length()`, а также после каждого шага увеличивает `i` на 1 - - В определении цикла `for` есть: - - 1. Начальное значение счетчика. Этот код выполняется ровно один раз перед первой итерацией - 2. Предикат — условие повторения циклов. Выполняется на каждой итерации. Точно так же как и в `while` - 3. Описание изменения счетчика. Этот код выполняется в конце каждой итерации - - В остальном принцип работы точно такой же, как у цикла `while`. - -instructions: | - - Сэмвелл обнаружил, что его сообщения перехватываются в замке «Близнецы» и там читаются. Из-за этого их атаки перестали быть внезапными. Немного подумав, он разработал программу, которая бы шифровала сообщения по следующему алгоритму. Она бы брала текст и переставляла в нем каждые два подряд идущих символа. - - ```java - App.encrypt("move"); // "omev" - App.encrypt("attack"); // "taatkc" - // Если число символов нечётное - // то последний символ остается на своем месте - App.encrypt("go!"); // "og!" - ``` - - Реализуйте статический метод `App.encrypt()`, который принимает на вход исходное сообщение и возвращает зашифрованное. - -tips: [] diff --git a/drafts/90-loops/description.en.yml b/drafts/90-loops/description.en.yml deleted file mode 100644 index b9adeff..0000000 --- a/drafts/90-loops/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Циклы -description: | - Любой код может повторяться десятки, тысячи, миллионы раз. В комбинации с другими известными нам инструментами — переменными и условиями — это открывает множество возможностей по построению программ и сложных систем. Приведем простой пример. Вам нужно найти конкретную фразу в учебнике из 500 страниц. Фразу вы помните, а вот номер страницы нет. Самый простой (и долгий) способ — последовательно просматривать страницы до тех пор, пока не найдете нужную. Для выполнения таких повторяющихся действий и нужны циклы. diff --git a/drafts/description.en.yml b/drafts/description.en.yml deleted file mode 100644 index 57bc21d..0000000 --- a/drafts/description.en.yml +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: | - Курс Java: обучение программированию на ява с нуля - -header: | - Курс Java: обучение для начинающих - -description: | - Изучение программирования — непростой и длительный процесс. Изучение синтаксиса языка — самая простая и короткая часть в пути, но без неё невозможно начать. Этот курс посвящен азам написания программ на Java. Он готовит плацдарм для написания осмысленных программ - -seo_description: | - Курс программирования на Java для начинающих от сообщества Хекслет. Обучение джава программированию: синтаксис языка, типы данных, азы написания программ на Java diff --git a/modules/10-basics/10-hello-world/Test.java b/modules/10-basics/10-hello-world/Test.java index bfc97be..0d23c54 100644 --- a/modules/10-basics/10-hello-world/Test.java +++ b/modules/10-basics/10-hello-world/Test.java @@ -1,14 +1,14 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; -import org.assertj.core.api.Assertions; +import static org.assertj.core.api.Assertions.assertThat; class Test { public static void main(final String[] args) { final var expected = "Hello, World!"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(final String[] args) { final var actual = out.toString().trim(); - Assertions.assertThat(actual).isEqualTo(expected); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/10-basics/10-hello-world/description.ru.yml b/modules/10-basics/10-hello-world/description.ru.yml deleted file mode 100644 index 5dc6d6b..0000000 --- a/modules/10-basics/10-hello-world/description.ru.yml +++ /dev/null @@ -1,64 +0,0 @@ ---- - -name: Привет, Мир! -theory: | - Изучать язык программирования по традиции начинают с программы "Hello, World!", которая выводит этот текст на экран. - -
-    Hello, World!
-  
- - На языке Java эта программа будет выглядеть так: - - ```java - class App { - public static void main(String[] args) { - System.out.println("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); - ``` - -instructions: | - Наберите в редакторе код из задания символ в символ и нажмите «Проверить». - - ```java - class App { - public static void main(String[] args) { - System.out.println("Hello, World!"); - } - } - ``` - - Если вы напишете *heLLo, woRld!* вместо *Hello, World!*, то это будет считаться другим текстом, потому что заглавные и строчные буквы — это разные символы. Размер буквы называют *регистром*, и говорят: **регистр — важен!** Это касается почти всего в коде, поэтому привыкайте всегда обращать внимание на регистр. - -tips: - - | - Если в редакторе есть запись `// BEGIN` и `// END`, то код нужно писать между этими строчками. - - | - [Что такое компилятор?](https://guides.hexlet.io/compiler/) diff --git a/modules/10-basics/10-hello-world/ru/README.md b/modules/10-basics/10-hello-world/ru/README.md index bb55cc0..18eb1b1 100644 --- a/modules/10-basics/10-hello-world/ru/README.md +++ b/modules/10-basics/10-hello-world/ru/README.md @@ -14,7 +14,6 @@ class App { } ``` - Текст *Hello, World!* появится на экране благодаря команде `System.out.println()`, где `println()` — это сокращение от английского *print line*. Она выводит на экран значение, указанное в скобках `("Hello, World!")` — в данном случае строку. Сама строка обрамляется двойными кавычками `""`. Если этого не сделать, то компилятор укажет на синтаксическую ошибку: ```bash diff --git a/modules/10-basics/10-hello-world/ru/data.yml b/modules/10-basics/10-hello-world/ru/data.yml index 37698a4..b3a3908 100644 --- a/modules/10-basics/10-hello-world/ru/data.yml +++ b/modules/10-basics/10-hello-world/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Привет, Мир! tips: - > diff --git a/modules/10-basics/20-comments/description.ru.yml b/modules/10-basics/20-comments/description.ru.yml deleted file mode 100644 index 47b7165..0000000 --- a/modules/10-basics/20-comments/description.ru.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- - -name: Комментарии -theory: | - Практически все языки программирования позволяют оставлять в коде комментарии. Они никак не используются кодом и нужны исключительно для людей: чтобы программист оставлял пометки для себя и для других программистов. - - Комментарии в 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 и выдать в качестве документации к вашему коду. Мы поговорим о них позже – когда разберем классы и методы. - -instructions: | - Создайте однострочный комментарий с текстом: *You know nothing, Jon Snow!*. diff --git a/modules/10-basics/20-comments/ru/data.yml b/modules/10-basics/20-comments/ru/data.yml index abc4274..17b084f 100644 --- a/modules/10-basics/20-comments/ru/data.yml +++ b/modules/10-basics/20-comments/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Комментарии diff --git a/modules/10-basics/30-statements/description.ru.yml b/modules/10-basics/30-statements/description.ru.yml deleted file mode 100644 index 68a8fe4..0000000 --- a/modules/10-basics/30-statements/description.ru.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- - -name: Инструкции (Statements) -theory: | - Инструкция — это команда для компьютера. Код на 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!"); - ``` - - Результат на экране будет таким же, но на практике такой подход считается плохим. - -instructions: | - Выведите на экран друг за другом три имени: *Robert*, *Stannis*, *Renly*. В результате на экране должно отобразиться: - -
-  Robert
-  Stannis
-  Renly
-  
- - Для каждого имени используйте свой собственный вызов `System.out.println()`. diff --git a/modules/10-basics/30-statements/ru/data.yml b/modules/10-basics/30-statements/ru/data.yml index 252cf88..6220090 100644 --- a/modules/10-basics/30-statements/ru/data.yml +++ b/modules/10-basics/30-statements/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Инструкции (Statements) diff --git a/modules/10-basics/40-testing/Test.java b/modules/10-basics/40-testing/Test.java index 192ea26..a2eff62 100644 --- a/modules/10-basics/40-testing/Test.java +++ b/modules/10-basics/40-testing/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -8,8 +10,6 @@ class Test { public static void main(String[] args) { final var expected = "420262531"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -17,8 +17,10 @@ public static void main(String[] args) { final var actual = out.toString().trim(); - assertThat(actual).isEqualTo(expected); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/10-basics/40-testing/description.ru.yml b/modules/10-basics/40-testing/description.ru.yml deleted file mode 100644 index d9e7d66..0000000 --- a/modules/10-basics/40-testing/description.ru.yml +++ /dev/null @@ -1,46 +0,0 @@ ---- - -name: Как мы проверяем ваши решения -theory: | - Наш сайт автоматически проверяет ваши решения. Как это работает? - - В самом простом случае система просто запускает ваш код и смотрит на то, что вывелось на экран. А потом сверяет с тем, что мы «ожидали» по заданию. - - В следующих, более сложных уроках вы будете писать методы — некие мини-программы, принимающие информацию из внешнего мира и производящие какие-то операции. Проверка ваших решений в таких случаях выглядит немного сложнее: система запускает ваше решение и передаёт какую-то информацию. Система также знает — «ожидает» — какой именно ответ должен вернуть правильный метод при таких входных данных. - - Например, если ваша задача — написать код для сложения двух чисел, то проверочная система будет передавать ему разные комбинации чисел и сверять ответ вашего кода с реальными суммами. Если во всех случаях ответы совпадут, то решение считается верным. - - Вот простой пример: в одном из будущих уроков вам нужно будет написать код, который производит вычисления и выдаёт ответ. Допустим, вы допустили небольшую ошибку, и метод выдал неправильное число. Система ответит примерно так: - -
expected: "35" but was: "10"
- - Самое главное начинается после двоеточия: «ожидалось: "35", но было "10"». То есть правильный код должен был выдать 35, но текущее решение работает неправильно и выдаёт 10. - - Кроме наших тестов, будет крайне полезно использовать сервис [repl.it](https://repl.it/languages/java). - - --- - - Иногда в процессе решения будет казаться, что вы сделали все правильно, но система "капризничает" и не принимает решение. Подобное поведение практически исключено. Нерабочие тесты просто не могут попасть на сайт, они автоматически запускаются после каждого изменения. В подавляющем большинстве таких случаев, (а все наши проекты в сумме провели миллионы проверок за много лет), ошибка содержится в коде решения. Она может быть очень незаметной, вместо английской буквы случайно ввели русскую, вместо верхнего регистра использовали нижний или забыли вывести запятую. Другие случаи сложнее. Возможно ваше решение работает для одного набора входных данных, но не работает для другого. Поэтому всегда внимательно читайте условие задачи и вывод тестов. Там почти наверняка есть указание на ошибку. - - Однако, если вы уверены в ошибке или нашли какую-то неточность, то вы всегда можете указать на нее. В конце каждой теории есть ссылка на содержимое урока на гитхабе (этот проект полностью открытый!). Перейдя туда, вы можете написать issue, посмотреть содержимое тестов (там видно, как вызывается ваш код) и даже отправить pullrequest. Если для вас это пока темный лес, то подключитесь в наше сообщество [Сообщество Хекслета в Telegram](https://t.me/hexletcommunity/12), там в канале Волонтеры мы всегда поможем. - - -instructions: | - Просто тренировка. Выведите на экран число 420262531. - -
-  420262531
-  
- - Поэкспериментируйте с выводом. Передайте туда другое число или строку. Посмотрите на ответ системы, попробуйте его перевести и понять. - -definitions: - - name: Тесты - description: | - специальный код, проверяющий программы на корректность, сверяя правильный результат с реальным. - -tips: - - | - [TDD](https://ru.wikipedia.org/wiki/Разработка_через_тестирование) - - | - [Сообщество Хекслета в Telegram](https://t.me/hexletcommunity/12) diff --git a/modules/10-basics/40-testing/ru/README.md b/modules/10-basics/40-testing/ru/README.md index c835717..b7934a6 100644 --- a/modules/10-basics/40-testing/ru/README.md +++ b/modules/10-basics/40-testing/ru/README.md @@ -12,8 +12,6 @@ Самое главное начинается после двоеточия: «ожидалось: "35", но было "10"». То есть правильный код должен был выдать 35, но текущее решение работает неправильно и выдаёт 10. -Кроме наших тестов, будет крайне полезно использовать сервис [repl.it](https://repl.it/languages/java). - --- Иногда в процессе решения будет казаться, что вы сделали все правильно, но система "капризничает" и не принимает решение. Подобное поведение практически исключено. Нерабочие тесты просто не могут попасть на сайт, они автоматически запускаются после каждого изменения. В подавляющем большинстве таких случаев, (а все наши проекты в сумме провели миллионы проверок за много лет), ошибка содержится в коде решения. Она может быть очень незаметной, вместо английской буквы случайно ввели русскую, вместо верхнего регистра использовали нижний или забыли вывести запятую. Другие случаи сложнее. Возможно ваше решение работает для одного набора входных данных, но не работает для другого. Поэтому всегда внимательно читайте условие задачи и вывод тестов. Там почти наверняка есть указание на ошибку. diff --git a/modules/10-basics/40-testing/ru/data.yml b/modules/10-basics/40-testing/ru/data.yml index faeaccb..1be2248 100644 --- a/modules/10-basics/40-testing/ru/data.yml +++ b/modules/10-basics/40-testing/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Как мы проверяем ваши решения definitions: - name: Тесты diff --git a/modules/10-basics/50-syntax-error/Test.java b/modules/10-basics/50-syntax-error/Test.java index adfbe03..edcf84c 100644 --- a/modules/10-basics/50-syntax-error/Test.java +++ b/modules/10-basics/50-syntax-error/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(final String[] args) { final var expected = "What Is Dead May Never Die"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(final String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/10-basics/50-syntax-error/description.ru.yml b/modules/10-basics/50-syntax-error/description.ru.yml deleted file mode 100644 index 083a7b9..0000000 --- a/modules/10-basics/50-syntax-error/description.ru.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- - -name: Ошибки оформления (синтаксиса) -theory: | - В человеческих языках грамматика важна, но текст с ошибками чаще всего можно понять и прочитать. В программировании все строго. Любое мельчайшее нарушение, и программа не запустится. - - Примером может быть забытая `;`, неправильно расставленные скобки и другие детали. Подобные ошибки называются **синтаксическими**, потому что они нарушают правила синтаксиса языка. - - Если программа на Java написана синтаксически некорректно, то компилятор выводит на экран: - - * Сообщение об ошибке - * Указание на файл - * Строчка в файле, где по его мнению произошла ошибка - - Ниже пример кода с синтаксической ошибкой: - - ```java - System.out.println("alala - ``` - - Если запустить код выше, то мы увидим следующее сообщение: - -
-  |  Error:
-  |  unclosed string literal
-  |  System.out.println("alala
-  
- - С одной стороны, ошибки синтаксиса — самые простые, потому что они связаны исключительно с грамматическими правилами написания кода, а не с самим смыслом кода. Их легко исправить — нужно лишь найти нарушение в записи. - - С другой стороны, компилятор не всегда может четко указать на это нарушение. Поэтому бывает, что забытую скобку нужно поставить не туда, куда указывает сообщение об ошибке. - -instructions: | - - Это задание не связано с уроком напрямую. Но будет полезным потренироваться с выводом на экран. Выведите на экран *What Is Dead May Never Die* - -# tips: [] - -definitions: - - name: Компилятор - description: Программа выполняющая преобразование исходного кода в низкоуровневый язык подходящий для выполнения - - - name: Синтаксическая ошибка - description: Нарушение грамматических правил языка программирования diff --git a/modules/10-basics/50-syntax-error/ru/data.yml b/modules/10-basics/50-syntax-error/ru/data.yml index 4ca88a2..10b42ac 100644 --- a/modules/10-basics/50-syntax-error/ru/data.yml +++ b/modules/10-basics/50-syntax-error/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Ошибки оформления (синтаксиса) definitions: - name: Компилятор diff --git a/modules/20-arithmetics/10-basics/Test.java b/modules/20-arithmetics/10-basics/Test.java index 4b9f24a..57b6077 100644 --- a/modules/20-arithmetics/10-basics/Test.java +++ b/modules/20-arithmetics/10-basics/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "9"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/20-arithmetics/10-basics/description.ru.yml b/modules/20-arithmetics/10-basics/description.ru.yml deleted file mode 100644 index c110f11..0000000 --- a/modules/20-arithmetics/10-basics/description.ru.yml +++ /dev/null @@ -1,55 +0,0 @@ ---- - -name: Арифметические операции -theory: | - На базовом уровне компьютеры оперируют только числами. Даже в прикладных программах на высокоуровневых языках внутри много чисел и операций над ними. - - К счастью, для старта достаточно знать обычную арифметику — с нее и начнем. - - Для сложения двух чисел в математике мы пишем, например, *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
-  
- -instructions: | - - Выведите на экран результат деления числа *81* на *9*. - -tips: - - Деление на ноль приводит к ошибке. Чтобы его не допустить, нужно знать про условные конструкции (о них вы узнаете в следующих уроках). diff --git a/modules/20-arithmetics/10-basics/ru/data.yml b/modules/20-arithmetics/10-basics/ru/data.yml index 6f03c81..01fa145 100644 --- a/modules/20-arithmetics/10-basics/ru/data.yml +++ b/modules/20-arithmetics/10-basics/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Арифметические операции tips: - >- diff --git a/modules/20-arithmetics/20-operators/Test.java b/modules/20-arithmetics/20-operators/Test.java index 536cb22..00e23f8 100644 --- a/modules/20-arithmetics/20-operators/Test.java +++ b/modules/20-arithmetics/20-operators/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -8,8 +10,6 @@ class Test { public static void main(String[] args) { final var expected = "87"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -17,8 +17,10 @@ public static void main(String[] args) { final var actual = out.toString().trim(); - assertThat(actual).isEqualTo(expected); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/20-arithmetics/20-operators/description.ru.yml b/modules/20-arithmetics/20-operators/description.ru.yml deleted file mode 100644 index 919750c..0000000 --- a/modules/20-arithmetics/20-operators/description.ru.yml +++ /dev/null @@ -1,54 +0,0 @@ ---- - -name: Операторы -theory: | - Перед тем, как двигаться дальше, разберем базовую терминологию. Знак операции, такой как `+`, называют оператором. **Оператор** — просто символ, который выполняет операцию, например, сложение: - - ```java - System.out.println(8 + 2); // => 10 - ``` - - В этом примере `+` — это оператор, а числа *8* и *2* — это **операнды**. - - В случае сложения у нас есть два операнда: - - * Один слева - * Другой справа от знака *+* - - Операции, которые требуют наличия двух операндов, называются **бинарными**. Если пропустить хотя бы один операнд, то программа завершится с синтаксической ошибкой. Например: - - ``` - `3 + ;` - ``` - - Операции бывают не только бинарными. Бывают еще: - - * Унарные — с одним операндом - * Тернарные — с тремя операндами - - Причем операторы могут выглядеть одинаково, но обозначать разные операции: - - ```java - System.out.println(-3); // => -3 - ``` - - Выше пример применения унарной операции к числу *3*. Оператор «минус» перед тройкой говорит интерпретатору — возьми число *3* и найди противоположное, то есть *-3*. - - Это немного может сбить с толку, потому что *-3* — это одновременно и число само по себе, и оператор с операндом, но у языков программирования такая структура. - -instructions: | - - Напишите программу, которая посчитает разность между числами `6` и `-81` и выведет ответ на экран. - - -definitions: - - name: "Арифметическая операция" - description: "сложение, вычитание, умножение и деление." - - name: "Оператор" - description: "специальный символ, создающий операцию. Например, `+` создает операцию сложения." - - name: "Операнд" - description: "объект, который участвует в операции. `3 * 6`: здесь 3 и 6 — операнды." - - name: "Унарная операция" - description: "операция с одним операндом. Например, `-3` — унарная операция для получения числа, противоположного числу три." - - name: "Бинарная операция" - description: "операция с двумя операндами. Например, `3 + 9`." diff --git a/modules/20-arithmetics/20-operators/ru/data.yml b/modules/20-arithmetics/20-operators/ru/data.yml index c8e68e5..6521cbd 100644 --- a/modules/20-arithmetics/20-operators/ru/data.yml +++ b/modules/20-arithmetics/20-operators/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Операторы definitions: - name: Арифметическая операция diff --git a/modules/20-arithmetics/30-commutative/description.ru.yml b/modules/20-arithmetics/30-commutative/description.ru.yml deleted file mode 100644 index c43bdd7..0000000 --- a/modules/20-arithmetics/30-commutative/description.ru.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- - -name: Коммутативная операция -theory: | - Мы все помним со школы: «от перемены мест слагаемых сумма не меняется». Это один из базовых и интуитивно понятных принципов арифметики — **коммутативный закон**. - - Бинарная операция считается коммутативной, если, вы получаете тот же самый результат, поменяв местами операнды. Очевидно, что сложение — коммутативная операция: - - ``` - 3 + 2 = 2 + 3 - ``` - - А вот вычитание — это не коммутативная операция: - - ``` - 2 - 3 ≠ 3 - 2 - ``` - - В программировании этот закон работает точно так же, как в арифметике. Более того, большинство операций не являются коммутативными. Отсюда вывод: всегда обращайте внимание на порядок того, с чем работаете. - -instructions: | - - Это задание напрямую не связано с темой урока. Но будет полезным попрактиковаться с арифметическими операциями и выводом на экран. - - Напишите программу, которая считает и последовательно выводит на экран значения следующих математических выражений: «3 умножить на 5» и «-8 разделить на -4». - -
-  15
-  2
-  
- -# tips: [] - -definitions: - - name: "Коммутативность" - description: "свойство операции, когда изменения порядка операндов не влияет на результат. Например, сложение — коммутативная операция: от перемены мест слагаемых сумма не меняется." diff --git a/modules/20-arithmetics/30-commutative/ru/data.yml b/modules/20-arithmetics/30-commutative/ru/data.yml index 1ab02e1..669d02f 100644 --- a/modules/20-arithmetics/30-commutative/ru/data.yml +++ b/modules/20-arithmetics/30-commutative/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Коммутативная операция definitions: - name: Коммутативность diff --git a/modules/20-arithmetics/40-composition/Test.java b/modules/20-arithmetics/40-composition/Test.java index a886ea2..2f5d7e1 100644 --- a/modules/20-arithmetics/40-composition/Test.java +++ b/modules/20-arithmetics/40-composition/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "10"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/20-arithmetics/40-composition/description.ru.yml b/modules/20-arithmetics/40-composition/description.ru.yml deleted file mode 100644 index 483a673..0000000 --- a/modules/20-arithmetics/40-composition/description.ru.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- - -name: Композиция операций -theory: | - А что, если понадобится вычислить такое выражение: *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* - -instructions: | - - Реализуйте программу, которая вычисляет значение выражения `8 / 2 + 5 - -3 / 2` и выводит результат на экран. Не вычисляйте ничего самостоятельно, ваша программа должна производить все вычисления сама. -
-  10
-  
- Обратите внимание, что интерпретатор производит арифметические вычисления в правильном порядке: сначала деление и умножение, потом сложение и вычитание. Иногда этот порядок нужно изменить — об этом следующий урок. - - Также обратите внимание на то, что в java по умолчанию используется целочисленное деление, `3 / 2` будет `1`. - - -# tips: [] diff --git a/modules/20-arithmetics/40-composition/ru/data.yml b/modules/20-arithmetics/40-composition/ru/data.yml index 3fa4e0b..f721c13 100644 --- a/modules/20-arithmetics/40-composition/ru/data.yml +++ b/modules/20-arithmetics/40-composition/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Композиция операций diff --git a/modules/20-arithmetics/50-priority/Test.java b/modules/20-arithmetics/50-priority/Test.java index f8bc3cf..5fafc04 100644 --- a/modules/20-arithmetics/50-priority/Test.java +++ b/modules/20-arithmetics/50-priority/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "49"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/20-arithmetics/50-priority/description.en.yml b/modules/20-arithmetics/50-priority/description.en.yml deleted file mode 100644 index 3a55ed3..0000000 --- a/modules/20-arithmetics/50-priority/description.en.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- - -name: Priority -theory: | - 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". - - -instructions: | - - 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. - -# tips: [] diff --git a/modules/20-arithmetics/50-priority/description.ru.yml b/modules/20-arithmetics/50-priority/description.ru.yml deleted file mode 100644 index 46fde30..0000000 --- a/modules/20-arithmetics/50-priority/description.ru.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- - -name: Приоритет операций -theory: | - Посмотрите внимательно на выражение *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 - ``` - - Запомните: код пишется для людей, потому что код будут читать люди, а машины будут только исполнять его. Для машин нет «более» понятного или «менее» понятного кода, независимо от того, является ли код корректным или нет. - - -instructions: | - - Дано выражение `70 * 3 + 4 / 8 + 2`. - - Расставьте скобки так, чтобы оба сложения (`3 + 4` и `8 + 2`) высчитывались в первую очередь. Выведите результат на экран. - -# tips: [] diff --git a/modules/20-arithmetics/50-priority/en/EXERCISE.md b/modules/20-arithmetics/50-priority/en/EXERCISE.md deleted file mode 100644 index 6cd0475..0000000 --- a/modules/20-arithmetics/50-priority/en/EXERCISE.md +++ /dev/null @@ -1,4 +0,0 @@ - -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 deleted file mode 100644 index 1995770..0000000 --- a/modules/20-arithmetics/50-priority/en/README.md +++ /dev/null @@ -1,33 +0,0 @@ -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". - diff --git a/modules/20-arithmetics/50-priority/en/data.yml b/modules/20-arithmetics/50-priority/en/data.yml deleted file mode 100644 index 8bff0d7..0000000 --- a/modules/20-arithmetics/50-priority/en/data.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -name: Priority diff --git a/modules/20-arithmetics/50-priority/ru/README.md b/modules/20-arithmetics/50-priority/ru/README.md index 470d061..ab197fc 100644 --- a/modules/20-arithmetics/50-priority/ru/README.md +++ b/modules/20-arithmetics/50-priority/ru/README.md @@ -34,4 +34,3 @@ System.out.println(((8 / 2) + 5) - (-4 / 2)); // => 11 ``` Запомните: код пишется для людей, потому что код будут читать люди, а машины будут только исполнять его. Для машин нет «более» понятного или «менее» понятного кода, независимо от того, является ли код корректным или нет. - diff --git a/modules/20-arithmetics/50-priority/ru/data.yml b/modules/20-arithmetics/50-priority/ru/data.yml index 11f848b..da15a1d 100644 --- a/modules/20-arithmetics/50-priority/ru/data.yml +++ b/modules/20-arithmetics/50-priority/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Приоритет операций diff --git a/modules/20-arithmetics/60-float/Test.java b/modules/20-arithmetics/60-float/Test.java index fee6cab..33a18ae 100644 --- a/modules/20-arithmetics/60-float/Test.java +++ b/modules/20-arithmetics/60-float/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "0.0858"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/20-arithmetics/60-float/description.ru.yml b/modules/20-arithmetics/60-float/description.ru.yml deleted file mode 100644 index e8ea6fa..0000000 --- a/modules/20-arithmetics/60-float/description.ru.yml +++ /dev/null @@ -1,47 +0,0 @@ ---- - -name: Числа с плавающей точкой - -theory: | - - В математике существуют разные виды чисел, например: - - * **Натуральные** — это целые числа от 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* лежит бесконечное множество чисел. - - А как тогда хранить рациональные числа? Подавляющее число языков программирования в этом случае опирается на единый стандарт, который описывает как организовывать память в таких случаях. - - Разработчикам важно понимать, что операции с плавающими числами неточны, но эту точность можно регулировать. Это значит, что при решении задач с подобными числами необходимо прибегать к специальным трюкам, которые позволяют добиться необходимой точности. - -instructions: | - - Вычислите и выведите на экран произведение двух чисел: *0.39* и *0.22* - -tips: - - | - [Что нужно знать про арифметику с плавающей запятой](https://habr.com/post/112953/) diff --git a/modules/20-arithmetics/60-float/ru/data.yml b/modules/20-arithmetics/60-float/ru/data.yml index 0e54583..32f20fc 100644 --- a/modules/20-arithmetics/60-float/ru/data.yml +++ b/modules/20-arithmetics/60-float/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Числа с плавающей точкой tips: - > diff --git a/modules/20-arithmetics/80-linting/Test.java b/modules/20-arithmetics/80-linting/Test.java index 0ba95cf..6848de0 100644 --- a/modules/20-arithmetics/80-linting/Test.java +++ b/modules/20-arithmetics/80-linting/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "-14"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/20-arithmetics/80-linting/description.ru.yml b/modules/20-arithmetics/80-linting/description.ru.yml deleted file mode 100644 index 2e0cbac..0000000 --- a/modules/20-arithmetics/80-linting/description.ru.yml +++ /dev/null @@ -1,47 +0,0 @@ ---- - -name: Линтер -theory: | - Теперь, когда мы уже научились писать простые программы, можно немного поговорить о том, как их писать. - - Код программы следует оформлять определенным образом, чтобы он был достаточно понятным и простым в поддержке. - - Специальные наборы правил — **стандарты** — описывают различные аспекты написания кода. Конкретно в 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/?utm_source=code-basics&utm_medium=referral&utm_campaign=programs&utm_content=lesson) и в реальной разработке линтер будет работать и сообщать вам о нарушениях. - -instructions: | - - Выведите на экран результат следующего вычисления: «разница между суммой пяти и двух и произведением трёх и семи». Сравните получившийся результат с решением учителя с точки зрения оформления кода. - -tips: [] diff --git a/modules/20-arithmetics/80-linting/ru/README.md b/modules/20-arithmetics/80-linting/ru/README.md index 4091f3a..a62886f 100644 --- a/modules/20-arithmetics/80-linting/ru/README.md +++ b/modules/20-arithmetics/80-linting/ru/README.md @@ -19,9 +19,9 @@ System.out.println( "Hello, World!" ); System.out.println("I'm a developer!") ; Проанализируем данные ошибки: -* Правило **ParenPad** требует отсутствия пробелов после открывающейся и перед закрывающейся круглыми скобками +* Правило **ParenPad**, указанное в квадратных скобках, требует отсутствия пробелов после открывающейся и перед закрывающейся круглыми скобками * Правило **NoWhitespaceBefore** указывает, что перед точкой с запятой не нужно устанавливать лишний пробел -* Каждую новую инструкцию принято записывать с новой строки. На это указывает правило **OneStatementPerLine** +* Каждую новую инструкцию принято записывать с новой строки. На это указывает правило *OneStatementPerLine* Соблюдение данных правил не влияет на результат, но помогает писать код понятнее и проще для восприятия. diff --git a/modules/20-arithmetics/80-linting/ru/data.yml b/modules/20-arithmetics/80-linting/ru/data.yml index 10274ee..2dd0d71 100644 --- a/modules/20-arithmetics/80-linting/ru/data.yml +++ b/modules/20-arithmetics/80-linting/ru/data.yml @@ -1,4 +1,3 @@ --- - name: Линтер tips: [] diff --git a/modules/25-strings/10-quotes/Test.java b/modules/25-strings/10-quotes/Test.java index 5b785eb..c73d1c1 100644 --- a/modules/25-strings/10-quotes/Test.java +++ b/modules/25-strings/10-quotes/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "\"Khal Drogo's favorite word is \"athjahakar\"\""; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/25-strings/10-quotes/description.en.yml b/modules/25-strings/10-quotes/description.en.yml deleted file mode 100644 index c891f06..0000000 --- a/modules/25-strings/10-quotes/description.en.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- - -name: quotes -theory: | - - ```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\""); - ``` - -instructions: | - - 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. - -# tips: [] diff --git a/modules/25-strings/10-quotes/description.ru.yml b/modules/25-strings/10-quotes/description.ru.yml deleted file mode 100644 index e11b10e..0000000 --- a/modules/25-strings/10-quotes/description.ru.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- - -name: Кавычки -theory: | - ```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\""); - ``` - -instructions: | - - Напишите программу, которая выведет на экран: - -
-  "Khal Drogo's favorite word is "athjahakar""
-  
- - Программа должна вывести на экран эту фразу в точности. Обратите внимание на кавычки в начале и в конце фразы. - -# tips: [] diff --git a/modules/25-strings/10-quotes/en/EXERCISE.md b/modules/25-strings/10-quotes/en/EXERCISE.md deleted file mode 100644 index ee5b34c..0000000 --- a/modules/25-strings/10-quotes/en/EXERCISE.md +++ /dev/null @@ -1,8 +0,0 @@ - -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 deleted file mode 100644 index 41305b2..0000000 --- a/modules/25-strings/10-quotes/en/README.md +++ /dev/null @@ -1,37 +0,0 @@ - -```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 deleted file mode 100644 index 4c397b4..0000000 --- a/modules/25-strings/10-quotes/en/data.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -name: quotes diff --git a/modules/25-strings/10-quotes/ru/data.yml b/modules/25-strings/10-quotes/ru/data.yml index ae39fc5..455b101 100644 --- a/modules/25-strings/10-quotes/ru/data.yml +++ b/modules/25-strings/10-quotes/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Кавычки diff --git a/modules/25-strings/15-escape-characters/description.en.yml b/modules/25-strings/15-escape-characters/description.en.yml deleted file mode 100644 index 3ae8260..0000000 --- a/modules/25-strings/15-escape-characters/description.en.yml +++ /dev/null @@ -1,132 +0,0 @@ ---- - -name: Escaping sequences -theory: | - - 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`. - -instructions: | - - 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. - -tips: - - | - [String History](https://en.wikipedia.org/wiki/Newline#History)j - -# definitions: -# - name: "Escape sequence" -# description: "a special combination of characters in the text. For example, _\\n_ is a line break." diff --git a/modules/25-strings/15-escape-characters/description.ru.yml b/modules/25-strings/15-escape-characters/description.ru.yml deleted file mode 100644 index 26775f1..0000000 --- a/modules/25-strings/15-escape-characters/description.ru.yml +++ /dev/null @@ -1,161 +0,0 @@ ---- - -name: Экранирующие последовательности -theory: | - Мы хотим показать диалог Матери Драконов со своим ребенком: - - ```text - - Are you hungry? - - Aaaarrrgh! - ``` - - Если вывести на экран строку с таким текстом: - - ```java - System.out.println("- Are you hungry?- Aaaarrrgh!"); - ``` - - Получится так: - -
-  - 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 -
- - Почему перед строкой *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`. - -instructions: | - - Напишите программу, которая выводит на экран: - - - Did Joffrey agree? - - He did. He also said "I love using \n". - - При этом программа использует только один `System.out.println()`, но результат на экране должен выглядеть в точности как показано выше. - -tips: - - | - [История перевода строки](https://ru.wikipedia.org/wiki/Перевод_строки#История) - -# definitions: -# - name: "Экранирующая последовательность" -# description: "специальная комбинация символов в тексте. Например, \n — это перевод строки." diff --git a/modules/25-strings/15-escape-characters/en/EXERCISE.md b/modules/25-strings/15-escape-characters/en/EXERCISE.md deleted file mode 100644 index 3d39a20..0000000 --- a/modules/25-strings/15-escape-characters/en/EXERCISE.md +++ /dev/null @@ -1,7 +0,0 @@ - -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 deleted file mode 100644 index 792dc03..0000000 --- a/modules/25-strings/15-escape-characters/en/README.md +++ /dev/null @@ -1,111 +0,0 @@ - -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 deleted file mode 100644 index fd9819f..0000000 --- a/modules/25-strings/15-escape-characters/en/data.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- - -name: Escaping sequences -tips: - - | - [String History](https://en.wikipedia.org/wiki/Newline#History)j diff --git a/modules/25-strings/15-escape-characters/ru/data.yml b/modules/25-strings/15-escape-characters/ru/data.yml index b9a4fcc..5c8613d 100644 --- a/modules/25-strings/15-escape-characters/ru/data.yml +++ b/modules/25-strings/15-escape-characters/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Экранирующие последовательности tips: - > diff --git a/modules/25-strings/20-strings-concatenation/Test.java b/modules/25-strings/20-strings-concatenation/Test.java index a71b960..a76ad85 100644 --- a/modules/25-strings/20-strings-concatenation/Test.java +++ b/modules/25-strings/20-strings-concatenation/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "Winter " + "came " + "for " + "the " + "House " + "of " + "Frey."; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/25-strings/20-strings-concatenation/description.en.yml b/modules/25-strings/20-strings-concatenation/description.en.yml deleted file mode 100644 index 7293036..0000000 --- a/modules/25-strings/20-strings-concatenation/description.en.yml +++ /dev/null @@ -1,68 +0,0 @@ ---- - -name: Concatenation -theory: | - - 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 - ``` - - -instructions: | - - 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. - -# definitions: -# - name: "Concatenation" -# description: | -# the operation of joining two strings. For example, `System.out.print("King's " + " Landing");` diff --git a/modules/25-strings/20-strings-concatenation/description.ru.yml b/modules/25-strings/20-strings-concatenation/description.ru.yml deleted file mode 100644 index 426d83c..0000000 --- a/modules/25-strings/20-strings-concatenation/description.ru.yml +++ /dev/null @@ -1,59 +0,0 @@ ---- - -name: Конкатенация -theory: | - Программы постоянно оперируют строками. Все, что мы видим на сайтах или в мобильных приложениях, так или иначе представлено в виде текста. Этот текст чаще всего **динамический** — полученный из разных частей, которые соединяются вместе. Операция соединения строк в программировании называется **конкатенацией** и выглядит так: - - ```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 - -instructions: | - - Используя `System.out.println()`, выполните конкатенацию слов и выведите на экран фразу: - -
-  Winter came for the House of Frey.
-  
- - Каждое слово должно быть записано отдельно и взято в кавычки, например "Winter ". Не забудьте о пробелах после каждого слова. - -# definitions: -# - name: Конкатенация -# description: | -# операция соединения двух строк. Например, `System.out.println("King's " + " Landing");` diff --git a/modules/25-strings/20-strings-concatenation/en/EXERCISE.md b/modules/25-strings/20-strings-concatenation/en/EXERCISE.md deleted file mode 100644 index 15c66a6..0000000 --- a/modules/25-strings/20-strings-concatenation/en/EXERCISE.md +++ /dev/null @@ -1,8 +0,0 @@ - -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 deleted file mode 100644 index 0e2e6e4..0000000 --- a/modules/25-strings/20-strings-concatenation/en/README.md +++ /dev/null @@ -1,49 +0,0 @@ - -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 -``` - diff --git a/modules/25-strings/20-strings-concatenation/en/data.yml b/modules/25-strings/20-strings-concatenation/en/data.yml deleted file mode 100644 index 5342e08..0000000 --- a/modules/25-strings/20-strings-concatenation/en/data.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -name: Concatenation diff --git a/modules/25-strings/20-strings-concatenation/ru/README.md b/modules/25-strings/20-strings-concatenation/ru/README.md index 6994511..ff8430c 100644 --- a/modules/25-strings/20-strings-concatenation/ru/README.md +++ b/modules/25-strings/20-strings-concatenation/ru/README.md @@ -36,4 +36,3 @@ 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 ``` - diff --git a/modules/25-strings/20-strings-concatenation/ru/data.yml b/modules/25-strings/20-strings-concatenation/ru/data.yml index edbc6c5..e91a817 100644 --- a/modules/25-strings/20-strings-concatenation/ru/data.yml +++ b/modules/25-strings/20-strings-concatenation/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Конкатенация diff --git a/modules/25-strings/description.en.yml b/modules/25-strings/description.en.yml deleted file mode 100644 index 9fa187a..0000000 --- a/modules/25-strings/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Strings -description: | - The text in programming is called "strings", and this topic is not as simple as it may seem. Escaping, control characters and other aspects often start up novice developers. diff --git a/modules/30-variables/10-definition/Test.java b/modules/30-variables/10-definition/Test.java index 38f7bf0..b52d238 100644 --- a/modules/30-variables/10-definition/Test.java +++ b/modules/30-variables/10-definition/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "What Is Dead May Never Die!"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/30-variables/10-definition/description.en.yml b/modules/30-variables/10-definition/description.en.yml deleted file mode 100644 index c635361..0000000 --- a/modules/30-variables/10-definition/description.en.yml +++ /dev/null @@ -1,55 +0,0 @@ ---- - -name: What is a variable -theory: | - 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!
-  
- - - For the name of the variable, any set of valid characters is used, which include letters of the English alphabet, numbers and the characters `-`, `_`. 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. - -instructions: | -   Create a variable with the name `motto` and the contents of `What is Dead May Never Die!`. Print the contents of the variable. - -tips: - - | - [Naming in programming](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) - -# definitions: -#   - name: variable -#     description: "a way to save information and give it a name for later use in the code." diff --git a/modules/30-variables/10-definition/description.ru.yml b/modules/30-variables/10-definition/description.ru.yml deleted file mode 100644 index c12c137..0000000 --- a/modules/30-variables/10-definition/description.ru.yml +++ /dev/null @@ -1,66 +0,0 @@ ---- - -name: Что такое переменная - -theory: | - Представьте себе задачу — нужно напечатать на экран фразу *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 - - Для удобства анализа программы переменные принято создавать как можно ближе к тому месту, где они используются. - -instructions: | - Создайте переменную с именем `motto` и содержимым `What Is Dead May Never Die!`. Распечатайте содержимое переменной. -
-  What Is Dead May Never Die!
-  
- -tips: - - | - [Именование в программировании](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) - -# definitions: -# - name: Переменная -# description: "способ сохранить информацию и дать ей имя для последующего использования в коде." diff --git a/modules/30-variables/10-definition/en/EXERCISE.md b/modules/30-variables/10-definition/en/EXERCISE.md deleted file mode 100644 index adcbe3f..0000000 --- a/modules/30-variables/10-definition/en/EXERCISE.md +++ /dev/null @@ -1 +0,0 @@ -  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 deleted file mode 100644 index 3895679..0000000 --- a/modules/30-variables/10-definition/en/README.md +++ /dev/null @@ -1,40 +0,0 @@ -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!
-
- - -For the name of the variable, any set of valid characters is used, which include letters of the English alphabet, numbers and the characters `-`, `_`. 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 deleted file mode 100644 index 17c1704..0000000 --- a/modules/30-variables/10-definition/en/data.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- - -name: What is a variable -tips: - - > - [Naming in - programming](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) diff --git a/modules/30-variables/10-definition/ru/README.md b/modules/30-variables/10-definition/ru/README.md index 050ad5e..de59d9e 100644 --- a/modules/30-variables/10-definition/ru/README.md +++ b/modules/30-variables/10-definition/ru/README.md @@ -24,7 +24,7 @@ Father! Father! -Для имени переменной используется любой набор допустимых символов, к которым относятся буквы английского алфавита, цифры, знаки `-` и `_`. При этом цифру нельзя ставить в начале. Имена переменных регистрозависимы, то есть имя `hello` и имя `heLLo` - это два разных имени и две переменные. Ниже пример с двумя разными переменными: +Для имени переменной используется любой набор допустимых символов, к которым относятся буквы английского алфавита, цифры, символ нижнего подчеркивания `_`. При этом цифру нельзя ставить в начале. Имена переменных регистрозависимы, то есть имя `hello` и имя `heLLo` - это два разных имени и две переменные. Ниже пример с двумя разными переменными: ```java var greeting1 = "Father!"; @@ -42,6 +42,4 @@ 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 index ae90a58..713f5d8 100644 --- a/modules/30-variables/10-definition/ru/data.yml +++ b/modules/30-variables/10-definition/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Что такое переменная tips: - > diff --git a/modules/30-variables/12-change/Test.java b/modules/30-variables/12-change/Test.java index 6438035..5d840ca 100644 --- a/modules/30-variables/12-change/Test.java +++ b/modules/30-variables/12-change/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "anneirB"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/30-variables/12-change/description.en.yml b/modules/30-variables/12-change/description.en.yml deleted file mode 100644 index fdd0d6b..0000000 --- a/modules/30-variables/12-change/description.en.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- - -name: Variable change - -theory: | - - 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); - ``` - - - 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. - -instructions: | - The code defines a variable with the value `'Brienna'`. Redefine the value of this variable and assign it the same line, but upside down. - -# tips: [] - -# definitions: -# - name: variable -#    description: A way to save information and give it a name for later use in code. diff --git a/modules/30-variables/12-change/description.ru.yml b/modules/30-variables/12-change/description.ru.yml deleted file mode 100644 index d4b17b7..0000000 --- a/modules/30-variables/12-change/description.ru.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- - -name: Изменение переменной - -theory: | - Само слово «переменная» говорит, что ее можно менять. И действительно, с течением времени внутри программы, значения переменных могут изменяться: - - ```java - var greeting = "Father!"; - System.out.println(greeting); - System.out.println(greeting); - // var уже не используется, так как переменная была определена выше - greeting = "Mother!"; - System.out.println(greeting); - System.out.println(greeting); - ``` - - - Java — статически типизированный язык. Это значит, что тип переменной задается при определении и больше не меняется. - - В примере выше мы присвоили строку при создании переменной. Компилятор запоминает тип и проверяет все последующие изменения переменной. Если попробовать этой же переменной присвоить число, то мы получим следующую ошибку: - - ```java - greeting = 5; - # Error: - # incompatible types: int cannot be converted to java.lang.String - # несовместимые типы: число не может быть превращено в строку - ``` - - Компилятор делает такую проверку без запуска кода на выполнение, именно поэтому такой вид типизации называют **статическим**. В JavaScript, Ruby, PHP, Python и других динамических языках подобное поведение не является ошибкой, переменная может легко изменить свой тип в процессе работы. - -instructions: | - - В коде определена переменная со значением `"Brienna"`. Переопределите значение этой переменной и присвойте ей такую же, но в перевернутом виде. - -
-  anneirB
-  
- -# tips: [] - -# definitions: -# - name: Переменная -# description: Способ сохранить информацию и дать ей имя для последующего использования в коде. diff --git a/modules/30-variables/12-change/en/EXERCISE.md b/modules/30-variables/12-change/en/EXERCISE.md deleted file mode 100644 index 8c081d6..0000000 --- a/modules/30-variables/12-change/en/EXERCISE.md +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 21c8189..0000000 --- a/modules/30-variables/12-change/en/README.md +++ /dev/null @@ -1,17 +0,0 @@ - -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); -``` - - -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 deleted file mode 100644 index 700b81a..0000000 --- a/modules/30-variables/12-change/en/data.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -name: Variable change diff --git a/modules/30-variables/12-change/ru/README.md b/modules/30-variables/12-change/ru/README.md index 734d057..4690d4e 100644 --- a/modules/30-variables/12-change/ru/README.md +++ b/modules/30-variables/12-change/ru/README.md @@ -10,7 +10,6 @@ System.out.println(greeting); System.out.println(greeting); ``` - Java — статически типизированный язык. Это значит, что тип переменной задается при определении и больше не меняется. В примере выше мы присвоили строку при создании переменной. Компилятор запоминает тип и проверяет все последующие изменения переменной. Если попробовать этой же переменной присвоить число, то мы получим следующую ошибку: diff --git a/modules/30-variables/12-change/ru/data.yml b/modules/30-variables/12-change/ru/data.yml index c6c52d0..87e50d6 100644 --- a/modules/30-variables/12-change/ru/data.yml +++ b/modules/30-variables/12-change/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Изменение переменной diff --git a/modules/30-variables/13-variables-naming/Test.java b/modules/30-variables/13-variables-naming/Test.java index 625f34d..512f317 100644 --- a/modules/30-variables/13-variables-naming/Test.java +++ b/modules/30-variables/13-variables-naming/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "-110.00000000000001"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/30-variables/13-variables-naming/description.en.yml b/modules/30-variables/13-variables-naming/description.en.yml deleted file mode 100644 index 8476085..0000000 --- a/modules/30-variables/13-variables-naming/description.en.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- - -name: Variable naming -theory: | - - 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. - - -instructions: | - - 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. - -# tips: [] - -# definitions: -#   - name: Coding Standard -#     description: "a set of syntax and stylistic rules for writing code." diff --git a/modules/30-variables/13-variables-naming/description.ru.yml b/modules/30-variables/13-variables-naming/description.ru.yml deleted file mode 100644 index 73a1f09..0000000 --- a/modules/30-variables/13-variables-naming/description.ru.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- - -name: Выбор имени переменной - -theory: | - Представим себе, что программа из прошлого урока выглядит так: - - ```java - var x = "Father!"; - System.out.println(x); - System.out.println(x); - ``` - - Она по-прежнему работает, но в ней изменилось имя переменной на `x`. Компьютеру без разницы, как мы называем переменные. Названия важны для программистов, ведь мы гораздо чаще читаем код, чем пишем. Причем не свой, а написанный другими людьми. От качества и понятности имен переменных зависит половина успеха в анализе кода. - - Лучше посидеть и придумать название, которое описывает суть переменной, чем назвать ее как попало, а в будущем переделывать. Постарайтесь давать им такие имена, чтобы они были максимально понятны без контекста, без изучения окружающего кода. - - Существует общепринятое правило: не используйте транслит для имен, только английский язык. Если вы испытываете сложности с английским, то пользуйтесь переводчиком. Со временем, копаясь в чужом коде, вы сформируете правильные понятия для именования. - - Среди разработчиков есть шутка: «самое сложное в программировании — названия переменных и инвалидация кеша». Придумывать названия и правда сложно. Как бы вы назвали переменную, в которой хранится «количество неоплаченных заказов от клиентов, имеющих задолженность в предыдущем квартале»? - -instructions: | - - Создайте две переменные с именами «первое число» и «второе число» на английском языке, используя lowerCamelCase. Запишите в первую переменную число `1.10`, во вторую — `-100`. Выведите на экран произведение чисел, записанных в получившиеся переменные. - -
-  -110.00000000000001
-  
- - Код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. - -# tips: [] - -# definitions: -# - name: Стандарт кодирования -# description: "набор синтаксических и стилистических правил написания кода." diff --git a/modules/30-variables/13-variables-naming/en/EXERCISE.md b/modules/30-variables/13-variables-naming/en/EXERCISE.md deleted file mode 100644 index 92e86a2..0000000 --- a/modules/30-variables/13-variables-naming/en/EXERCISE.md +++ /dev/null @@ -1,4 +0,0 @@ - -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 deleted file mode 100644 index 1700d73..0000000 --- a/modules/30-variables/13-variables-naming/en/README.md +++ /dev/null @@ -1,12 +0,0 @@ - -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 deleted file mode 100644 index d700ead..0000000 --- a/modules/30-variables/13-variables-naming/en/data.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -name: Variable naming diff --git a/modules/30-variables/13-variables-naming/ru/data.yml b/modules/30-variables/13-variables-naming/ru/data.yml index 986b5cb..99148c5 100644 --- a/modules/30-variables/13-variables-naming/ru/data.yml +++ b/modules/30-variables/13-variables-naming/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Выбор имени переменной diff --git a/modules/30-variables/14-errors/Test.java b/modules/30-variables/14-errors/Test.java index ba84ccd..602a83c 100644 --- a/modules/30-variables/14-errors/Test.java +++ b/modules/30-variables/14-errors/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "Targaryen and Dragon"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/30-variables/14-errors/description.en.yml b/modules/30-variables/14-errors/description.en.yml deleted file mode 100644 index 98b39dd..0000000 --- a/modules/30-variables/14-errors/description.en.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- - -name: Errors when working with variables - -theory: | - - 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. - -instructions: | - Find an undeclared variable in the program and declare it assigning to it the value of `"Dragon"`; - -# tips: [] - -# definitions: -#   - name: variable -#     description: A way to save information and give it a name for later use in code. diff --git a/modules/30-variables/14-errors/description.ru.yml b/modules/30-variables/14-errors/description.ru.yml deleted file mode 100644 index b27ee46..0000000 --- a/modules/30-variables/14-errors/description.ru.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- - -name: Ошибки при работе с переменными - -theory: | - Порядок инструкций в коде с переменными имеет огромное значение. Переменная должна быть определена до того, как будет использована. Ниже пример ошибки, которую очень часто допускают новички: - - ```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!"; - ``` - - Так делать нельзя. Придется создать новую переменную. - - Количество подобных ошибок уменьшается за счет использования правильно настроенного редактора. Такой редактор подсвечивает имена, которые используются без объявления, и предупреждает о возможных проблемах. - -instructions: | - Найдите в программе необъявленную переменную и объявите ее, присвоив ей значение `"Dragon"`; -
-  Targaryen and Dragon
-  
- -# tips: [] - -# definitions: -# - name: Переменная -# description: Способ сохранить информацию и дать ей имя для последующего использования в коде. diff --git a/modules/30-variables/14-errors/en/EXERCISE.md b/modules/30-variables/14-errors/en/EXERCISE.md deleted file mode 100644 index b49139e..0000000 --- a/modules/30-variables/14-errors/en/EXERCISE.md +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index ad8e770..0000000 --- a/modules/30-variables/14-errors/en/README.md +++ /dev/null @@ -1,16 +0,0 @@ - -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 deleted file mode 100644 index 5c73c9b..0000000 --- a/modules/30-variables/14-errors/en/data.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -name: Errors when working with variables diff --git a/modules/30-variables/14-errors/ru/data.yml b/modules/30-variables/14-errors/ru/data.yml index b2f973e..5ef08c7 100644 --- a/modules/30-variables/14-errors/ru/data.yml +++ b/modules/30-variables/14-errors/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Ошибки при работе с переменными diff --git a/modules/30-variables/15-variable-expressions/description.en.yml b/modules/30-variables/15-variable-expressions/description.en.yml deleted file mode 100644 index 4eb2514..0000000 --- a/modules/30-variables/15-variable-expressions/description.en.yml +++ /dev/null @@ -1,77 +0,0 @@ ---- - -name: Expressions in definitions -theory: | - - 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"); - ``` - - - 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. - -instructions: | - - 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 - -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/description.ru.yml b/modules/30-variables/15-variable-expressions/description.ru.yml deleted file mode 100644 index 47dea6a..0000000 --- a/modules/30-variables/15-variable-expressions/description.ru.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- - -name: Выражения в определениях - -theory: | - Переменные полезны не только для хранения и переиспользования информации, но и для упрощения сложных вычислений. - - Давайте рассмотрим пример: нужно перевести евро в рубли через доллары. Подобные конвертации через промежуточную валюту часто делают банки при покупках за рубежом. - - Для начала переведем 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 знает значение, потому что уже вычислил его. - -instructions: | - - Напишите программу, которая берет исходное количество евро, записанное в переменную `eurosCount`, переводит евро в доллары и выводит на экран. Затем полученное значение переводит в рубли и выводит на новой строчке. - - Пример вывода для 100 евро: - -
-  125.0
-  7500.0
-  
- - Считаем, что: - - - 1 евро = 1.25 долларов - - 1 доллар = 60 рублей - -tips: - - | - Для перевода строчки можно использовать `\n` между выводом долларов и рублей, либо нужное количество раз использовать метод `println()`. diff --git a/modules/30-variables/15-variable-expressions/en/EXERCISE.md b/modules/30-variables/15-variable-expressions/en/EXERCISE.md deleted file mode 100644 index 5b56208..0000000 --- a/modules/30-variables/15-variable-expressions/en/EXERCISE.md +++ /dev/null @@ -1,13 +0,0 @@ - -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 deleted file mode 100644 index 398df30..0000000 --- a/modules/30-variables/15-variable-expressions/en/README.md +++ /dev/null @@ -1,54 +0,0 @@ - -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"); -``` - - -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 deleted file mode 100644 index ce76abf..0000000 --- a/modules/30-variables/15-variable-expressions/en/data.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- - -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/ru/README.md b/modules/30-variables/15-variable-expressions/ru/README.md index fffa4b6..3d5d354 100644 --- a/modules/30-variables/15-variable-expressions/ru/README.md +++ b/modules/30-variables/15-variable-expressions/ru/README.md @@ -52,6 +52,4 @@ 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 index 53a9c15..22901e1 100644 --- a/modules/30-variables/15-variable-expressions/ru/data.yml +++ b/modules/30-variables/15-variable-expressions/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Выражения в определениях tips: - > diff --git a/modules/30-variables/18-variables-concatenation/description.en.yml b/modules/30-variables/18-variables-concatenation/description.en.yml deleted file mode 100644 index 14c88d6..0000000 --- a/modules/30-variables/18-variables-concatenation/description.en.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- - -name: Variables and Concatenation -theory: | - - 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" - ``` - - -instructions: | - - 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`. - -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/description.ru.yml b/modules/30-variables/18-variables-concatenation/description.ru.yml deleted file mode 100644 index 52c7a19..0000000 --- a/modules/30-variables/18-variables-concatenation/description.ru.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- - -name: Переменные и конкатенация - -theory: | - Переменные и конкатенацию можно объединять. Синтаксически ничего не меняется, ведь мы умеем конкатенировать — то есть склеивать две строки: - - ```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 - -instructions: | - - Сайты постоянно посылают письма своим пользователям. Типичная задача — сделать автоматическую отправку персонального письма, где в заголовке будет имя пользователя. Если где-то в базе сайта хранится имя человека в виде строки, то задача генерации заголовка сводится к конкатенации: например, нужно склеить строку *Здравствуйте* со строкой, где записано имя. - - Напишите программу, которая будет генерировать заголовок и тело письма, используя уже готовые переменные, и выводить получившиеся строки на экран. - - Для заголовка используйте переменные `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()`. - -tips: - - | - Подумайте, с какой строкой и в каком порядке нужно склеивать переменные, чтобы получить такой двухстрочный вывод тела письма. - - | - Помните, что можно создать строку, которая содержит только управляющую последовательность `\n`. diff --git a/modules/30-variables/18-variables-concatenation/en/EXERCISE.md b/modules/30-variables/18-variables-concatenation/en/EXERCISE.md deleted file mode 100644 index 2baef31..0000000 --- a/modules/30-variables/18-variables-concatenation/en/EXERCISE.md +++ /dev/null @@ -1,18 +0,0 @@ - -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 deleted file mode 100644 index eb87263..0000000 --- a/modules/30-variables/18-variables-concatenation/en/README.md +++ /dev/null @@ -1,30 +0,0 @@ - -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/18-variables-concatenation/en/data.yml b/modules/30-variables/18-variables-concatenation/en/data.yml deleted file mode 100644 index 9de80a9..0000000 --- a/modules/30-variables/18-variables-concatenation/en/data.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- - -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/ru/README.md b/modules/30-variables/18-variables-concatenation/ru/README.md index 403a29d..e646cdb 100644 --- a/modules/30-variables/18-variables-concatenation/ru/README.md +++ b/modules/30-variables/18-variables-concatenation/ru/README.md @@ -21,4 +21,3 @@ var last = "road"; var what = first + last; System.out.println(what); //=> Kingsroad ``` - diff --git a/modules/30-variables/18-variables-concatenation/ru/data.yml b/modules/30-variables/18-variables-concatenation/ru/data.yml index da1dfdd..53c1018 100644 --- a/modules/30-variables/18-variables-concatenation/ru/data.yml +++ b/modules/30-variables/18-variables-concatenation/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Переменные и конкатенация tips: - > diff --git a/modules/30-variables/19-naming-style/Test.java b/modules/30-variables/19-naming-style/Test.java index 28fcd6b..b3bad13 100644 --- a/modules/30-variables/19-naming-style/Test.java +++ b/modules/30-variables/19-naming-style/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "-1100"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/30-variables/19-naming-style/description.en.yml b/modules/30-variables/19-naming-style/description.en.yml deleted file mode 100644 index 22d7e87..0000000 --- a/modules/30-variables/19-naming-style/description.en.yml +++ /dev/null @@ -1,59 +0,0 @@ ---- - -name: Variables and Concatenation -theory: | - - 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" - ``` - -instructions: | - - 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`. - -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/description.ru.yml b/modules/30-variables/19-naming-style/description.ru.yml deleted file mode 100644 index c325061..0000000 --- a/modules/30-variables/19-naming-style/description.ru.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- - -name: Именование переменных - -theory: | - - `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 - ``` - -instructions: | - - Создайте две переменные с именами «первое число» и «второе число» на английском языке, используя lowerCamelCase. Запишите в первую переменную число `11`, во вторую — `-100`. Выведите на экран произведение чисел, записанных в получившихся переменных. - - Код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. - -tips: [] - -definitions: - - name: Стандарт кодирования - description: Набор синтаксических и стилистических правил написания кода. diff --git a/modules/30-variables/19-naming-style/en/EXERCISE.md b/modules/30-variables/19-naming-style/en/EXERCISE.md deleted file mode 100644 index 2baef31..0000000 --- a/modules/30-variables/19-naming-style/en/EXERCISE.md +++ /dev/null @@ -1,18 +0,0 @@ - -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 deleted file mode 100644 index 0b34320..0000000 --- a/modules/30-variables/19-naming-style/en/README.md +++ /dev/null @@ -1,29 +0,0 @@ - -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 deleted file mode 100644 index 9de80a9..0000000 --- a/modules/30-variables/19-naming-style/en/data.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- - -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/ru/EXERCISE.md b/modules/30-variables/19-naming-style/ru/EXERCISE.md index 1ba3540..4959e11 100644 --- a/modules/30-variables/19-naming-style/ru/EXERCISE.md +++ b/modules/30-variables/19-naming-style/ru/EXERCISE.md @@ -1,4 +1,8 @@ Создайте две переменные с именами «первое число» и «второе число» на английском языке, используя lowerCamelCase. Запишите в первую переменную число `11`, во вторую — `-100`. Выведите на экран произведение чисел, записанных в получившихся переменных. +
+-1100
+
+ Код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. diff --git a/modules/30-variables/19-naming-style/ru/data.yml b/modules/30-variables/19-naming-style/ru/data.yml index c2eda77..c8364ef 100644 --- a/modules/30-variables/19-naming-style/ru/data.yml +++ b/modules/30-variables/19-naming-style/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Именование переменных tips: [] definitions: diff --git a/modules/30-variables/20-magic-numbers/Test.java b/modules/30-variables/20-magic-numbers/Test.java index 178c10c..6d0d440 100644 --- a/modules/30-variables/20-magic-numbers/Test.java +++ b/modules/30-variables/20-magic-numbers/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "King Balon the 6th has 102 rooms."; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/30-variables/20-magic-numbers/description.en.yml b/modules/30-variables/20-magic-numbers/description.en.yml deleted file mode 100644 index e44d1d4..0000000 --- a/modules/30-variables/20-magic-numbers/description.en.yml +++ /dev/null @@ -1,66 +0,0 @@ ---- - -name: Magic Numbers -theory: | - - 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. - -instructions: | - - 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. - -# tips: [] diff --git a/modules/30-variables/20-magic-numbers/description.ru.yml b/modules/30-variables/20-magic-numbers/description.ru.yml deleted file mode 100644 index d44e7c5..0000000 --- a/modules/30-variables/20-magic-numbers/description.ru.yml +++ /dev/null @@ -1,64 +0,0 @@ ---- - -name: Магические числа - -theory: | - Вспомним один из прошлых уроков: - - ```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* - * Две новые переменные отделены от последующих вычислений пустой строчкой. Эти переменные имеют смысл и без вычислений, поэтому такое отделение уместно, оно повышает читаемость - * Получился хорошо именованный и структурированный код, но он длиннее прошлой версии. Так часто бывает, и это нормально, потому что код должен быть читабельным - -instructions: | - - Вы столкнулись с таким кодом, который выводит на экран общее количество комнат во владении нынешнего короля: - - ```java - var king = "King Balon the 6th"; - System.out.println(king + " has " + (6 * 17) + " rooms."); - ``` - - Как видите, это магические числа: непонятно, что такое _6_ и что такое _17_. Можно догадаться, если знать историю королевской семьи: каждый новый король получает в наследство все замки от предков и строит новый замок — точную копию родительского. - - Эта странная династия просто плодит одинаковые замки… - - Избавьтесь от магических чисел, создав новые переменные, а затем выведите текст на экран. - - Получится так: -
-  King Balon the 6th has 102 rooms.
-  
- - Названия переменных должны передавать смысл чисел, но должны при этом оставаться достаточно короткими и ёмкими для комфортного чтения. - - Помните: код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. - -# tips: [] diff --git a/modules/30-variables/20-magic-numbers/en/EXERCISE.md b/modules/30-variables/20-magic-numbers/en/EXERCISE.md deleted file mode 100644 index fd3d611..0000000 --- a/modules/30-variables/20-magic-numbers/en/EXERCISE.md +++ /dev/null @@ -1,23 +0,0 @@ - -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 deleted file mode 100644 index 2ab4a1a..0000000 --- a/modules/30-variables/20-magic-numbers/en/README.md +++ /dev/null @@ -1,35 +0,0 @@ - -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 deleted file mode 100644 index e801c25..0000000 --- a/modules/30-variables/20-magic-numbers/en/data.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -name: Magic Numbers diff --git a/modules/30-variables/20-magic-numbers/ru/data.yml b/modules/30-variables/20-magic-numbers/ru/data.yml index abd70c8..21fd015 100644 --- a/modules/30-variables/20-magic-numbers/ru/data.yml +++ b/modules/30-variables/20-magic-numbers/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Магические числа diff --git a/modules/30-variables/23-constants/description.en.yml b/modules/30-variables/23-constants/description.en.yml deleted file mode 100644 index b24a861..0000000 --- a/modules/30-variables/23-constants/description.en.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- - -name: Constants -theory: | - - 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 - ``` - - - 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. - -instructions: | - - Create the constant `dragonsBornCount` and write the number 3 in it - the number of dragons born to Dayenerys. - - -# tips: [] - -# definitions: -#   - name: "Constant" -#     description: "a way to save information and give it a name for later use in code; constants cannot be changed, unlike modules.variables" diff --git a/modules/30-variables/23-constants/description.ru.yml b/modules/30-variables/23-constants/description.ru.yml deleted file mode 100644 index 9c83770..0000000 --- a/modules/30-variables/23-constants/description.ru.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- - -name: Константы - -theory: | - Некоторые данные никогда не меняются — например, математические постоянные. Возьмем число *π*. Приближенно оно всегда равно *3.14* и не может измениться. - - Для обращения к подобным данным в Java принято использовать константы: - - ```java - final var pi = 3.14; - System.out.println(pi); // 3.14 - ``` - - https://replit.com/@hexlet/java-basics-variables-5 - - В отличие от переменных, в начале определения константы используют ключевое слово `final`. Оно сообщает компилятору запрет на изменение. Любая попытка поменять константу приведет к ошибке. - - Константа, как и переменная, может использоваться в любом выражении. Единственное ограничение — константу нельзя изменить, что звучит довольно логично. - -instructions: | - - Создайте константу `dragonsBornCount` и запишите в неё число 3 — это количество драконов, родившихся у Дайенерис. Выводить значение на экран не требуется. - - -# tips: [] - -# definitions: -# - name: "Константа" -# description: "способ сохранить информацию и дать ей имя для последующего использования в коде; константы нельзя изменять, в отличие от переменных" diff --git a/modules/30-variables/23-constants/en/EXERCISE.md b/modules/30-variables/23-constants/en/EXERCISE.md deleted file mode 100644 index 671a4e0..0000000 --- a/modules/30-variables/23-constants/en/EXERCISE.md +++ /dev/null @@ -1,2 +0,0 @@ - -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 deleted file mode 100644 index 85ebdb0..0000000 --- a/modules/30-variables/23-constants/en/README.md +++ /dev/null @@ -1,12 +0,0 @@ - -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 -``` - - -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 deleted file mode 100644 index 46e9495..0000000 --- a/modules/30-variables/23-constants/en/data.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -name: Constants diff --git a/modules/30-variables/23-constants/ru/README.md b/modules/30-variables/23-constants/ru/README.md index 051eed5..ceffe88 100644 --- a/modules/30-variables/23-constants/ru/README.md +++ b/modules/30-variables/23-constants/ru/README.md @@ -7,8 +7,6 @@ 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 index 2aa758e..1786fc2 100644 --- a/modules/30-variables/23-constants/ru/data.yml +++ b/modules/30-variables/23-constants/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Константы diff --git a/modules/30-variables/description.en.yml b/modules/30-variables/description.en.yml deleted file mode 100644 index 6d06b5a..0000000 --- a/modules/30-variables/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Variables -description: | -  Information can be placed in special "storage", and then use as many times as necessary. These storages are called modules.variables, and they help simplify the code and reduce unnecessary repetitions. diff --git a/modules/33-data-types/41-data-types-basics/Test.java b/modules/33-data-types/41-data-types-basics/Test.java index 9b1078b..acb3586 100644 --- a/modules/33-data-types/41-data-types-basics/Test.java +++ b/modules/33-data-types/41-data-types-basics/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "1"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/33-data-types/41-data-types-basics/description.en.yml b/modules/33-data-types/41-data-types-basics/description.en.yml deleted file mode 100644 index 3ddee85..0000000 --- a/modules/33-data-types/41-data-types-basics/description.en.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- - -name: Data Types -theory: | - - 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. - -instructions: | - Display the number `-0.304`. - -tips: - - | - [Article on fractional numbers](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Data Type" -# description: "a set of data in the code (a kind of information). The type determines what can be done with the elements of a particular set. For example, integers, rational numbers, strings are different data types." -# - name: "Primitive data types" -# description: "simple types built into the programming language itself." -# - name: "String" -# description: | -# data type describing the character set (in other words, text); for example, `"text"` diff --git a/modules/33-data-types/41-data-types-basics/description.ru.yml b/modules/33-data-types/41-data-types-basics/description.ru.yml deleted file mode 100644 index 5afc31e..0000000 --- a/modules/33-data-types/41-data-types-basics/description.ru.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- - -name: Зачем нужны типы данных - -theory: | - Внутри высокоуровневых языков программирования данные разделяются по типам. Например, строки относятся к типу *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 много, плюс можно создавать свои. Постепенно мы познакомимся со всеми необходимыми и научимся их правильно использовать. - -instructions: | - Выведите на экран результат деления целых чисел 3 на 2. Подумайте почему получился такой ответ? - -tips: - - | - [Статья о дробных числах](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Тип данных" -# description: "множество данных в коде (разновидность информации). Тип определяет, что можно делать с элементами конкретного множества. Например, целые числа, рациональные числа, строки — это разные типы данных." -# - name: "Примитивные типы данных" -# description: "простые типы, встроенные в сам язык программирования." -# - name: "Строка (String)" -# description: | -# тип данных, описывающий набор символов (иными словами — текст); например, `"text"` 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 deleted file mode 100644 index a4eaba0..0000000 --- a/modules/33-data-types/41-data-types-basics/en/EXERCISE.md +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 32b8c7a..0000000 --- a/modules/33-data-types/41-data-types-basics/en/README.md +++ /dev/null @@ -1,62 +0,0 @@ - -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 deleted file mode 100644 index 37eeffe..0000000 --- a/modules/33-data-types/41-data-types-basics/en/data.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- - -name: Data Types -tips: - - | - [Article on fractional numbers](https://habrahabr.ru/post/112953/) 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 index 34ee95f..a17ccbb 100644 --- a/modules/33-data-types/41-data-types-basics/ru/data.yml +++ b/modules/33-data-types/41-data-types-basics/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Зачем нужны типы данных tips: - | diff --git a/modules/33-data-types/45-explicit-types/Test.java b/modules/33-data-types/45-explicit-types/Test.java index 61c825d..d66e4f5 100644 --- a/modules/33-data-types/45-explicit-types/Test.java +++ b/modules/33-data-types/45-explicit-types/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -14,7 +16,8 @@ public static void main(String[] args) { final var actual = out.toString().trim(); - App.main(null); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); assertThat(actual).isEqualTo(expected); } diff --git a/modules/33-data-types/45-explicit-types/description.en.yml b/modules/33-data-types/45-explicit-types/description.en.yml deleted file mode 100644 index 3ddee85..0000000 --- a/modules/33-data-types/45-explicit-types/description.en.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- - -name: Data Types -theory: | - - 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. - -instructions: | - Display the number `-0.304`. - -tips: - - | - [Article on fractional numbers](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Data Type" -# description: "a set of data in the code (a kind of information). The type determines what can be done with the elements of a particular set. For example, integers, rational numbers, strings are different data types." -# - name: "Primitive data types" -# description: "simple types built into the programming language itself." -# - name: "String" -# description: | -# data type describing the character set (in other words, text); for example, `"text"` diff --git a/modules/33-data-types/45-explicit-types/description.ru.yml b/modules/33-data-types/45-explicit-types/description.ru.yml deleted file mode 100644 index 76c3a06..0000000 --- a/modules/33-data-types/45-explicit-types/description.ru.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- - -name: Явная типизация - -theory: | - До сих пор при определении переменных мы использовали ключевое слово `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 и множество других языков. - - Вывод типов и предпочтителен в большинстве ситуаций, однако бывает такое, что выводимый тип нас не устраивает. Тогда мы можем указать тип явно. Подробнее об этом в следующем уроке. - -instructions: | - Создайте строку *One more time* с явным указанием типа и выведите ее на экран - -tips: - - | - [Статья о дробных числах](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Тип данных" -# description: "множество данных в коде (разновидность информации). Тип определяет, что можно делать с элементами конкретного множества. Например, целые числа, рациональные числа, строки — это разные типы данных." -# - name: "Примитивные типы данных" -# description: "простые типы, встроенные в сам язык программирования." -# - name: "Строка (String)" -# description: | -# тип данных, описывающий набор символов (иными словами — текст); например, `"text"` diff --git a/modules/33-data-types/45-explicit-types/en/EXERCISE.md b/modules/33-data-types/45-explicit-types/en/EXERCISE.md deleted file mode 100644 index a4eaba0..0000000 --- a/modules/33-data-types/45-explicit-types/en/EXERCISE.md +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 32b8c7a..0000000 --- a/modules/33-data-types/45-explicit-types/en/README.md +++ /dev/null @@ -1,62 +0,0 @@ - -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 deleted file mode 100644 index 37eeffe..0000000 --- a/modules/33-data-types/45-explicit-types/en/data.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- - -name: Data Types -tips: - - | - [Article on fractional numbers](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/45-explicit-types/ru/data.yml b/modules/33-data-types/45-explicit-types/ru/data.yml index 7c63ca3..01a828b 100644 --- a/modules/33-data-types/45-explicit-types/ru/data.yml +++ b/modules/33-data-types/45-explicit-types/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Явная типизация tips: - | diff --git a/modules/33-data-types/47-data-types-list/Test.java b/modules/33-data-types/47-data-types-list/Test.java index 666d60e..f5d6858 100644 --- a/modules/33-data-types/47-data-types-list/Test.java +++ b/modules/33-data-types/47-data-types-list/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "hexlet-7"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/33-data-types/47-data-types-list/description. b/modules/33-data-types/47-data-types-list/description. deleted file mode 100644 index e69de29..0000000 diff --git a/modules/33-data-types/47-data-types-list/description.en.yml b/modules/33-data-types/47-data-types-list/description.en.yml deleted file mode 100644 index 3ddee85..0000000 --- a/modules/33-data-types/47-data-types-list/description.en.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- - -name: Data Types -theory: | - - 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. - -instructions: | - Display the number `-0.304`. - -tips: - - | - [Article on fractional numbers](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Data Type" -# description: "a set of data in the code (a kind of information). The type determines what can be done with the elements of a particular set. For example, integers, rational numbers, strings are different data types." -# - name: "Primitive data types" -# description: "simple types built into the programming language itself." -# - name: "String" -# description: | -# data type describing the character set (in other words, text); for example, `"text"` diff --git a/modules/33-data-types/47-data-types-list/description.ru.yml b/modules/33-data-types/47-data-types-list/description.ru.yml deleted file mode 100644 index e255a6b..0000000 --- a/modules/33-data-types/47-data-types-list/description.ru.yml +++ /dev/null @@ -1,93 +0,0 @@ ---- - -name: Какие бывают типы - -theory: | - В этом уроке мы рассмотрим систему типов в 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* — строка? Дело в том, что она не является примитивным типом. Внутри она представляет собой массив символов. Несмотря на это техническое различие, строки используются наравне с примитивными типами без особых отличий. - -instructions: | - Выведите на экран результат конкатенации слова *hexlet*, символа *-* и числа 7 - -tips: - - | - Попробуйте поиграть с конкатенированием строк и символов в jshell - - | - [Статья о дробных числах](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Тип данных" -# description: "множество данных в коде (разновидность информации). Тип определяет, что можно делать с элементами конкретного множества. Например, целые числа, рациональные числа, строки — это разные типы данных." -# - name: "Примитивные типы данных" -# description: "простые типы, встроенные в сам язык программирования." -# - name: "Строка (String)" -# description: | -# тип данных, описывающий набор символов (иными словами — текст); например, `"text"` 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 deleted file mode 100644 index a4eaba0..0000000 --- a/modules/33-data-types/47-data-types-list/en/EXERCISE.md +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 32b8c7a..0000000 --- a/modules/33-data-types/47-data-types-list/en/README.md +++ /dev/null @@ -1,62 +0,0 @@ - -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 deleted file mode 100644 index 37eeffe..0000000 --- a/modules/33-data-types/47-data-types-list/en/data.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- - -name: Data Types -tips: - - | - [Article on fractional numbers](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 index 1439df3..0756315 100644 --- a/modules/33-data-types/47-data-types-list/ru/EXERCISE.md +++ b/modules/33-data-types/47-data-types-list/ru/EXERCISE.md @@ -1 +1 @@ -Выведите на экран результат конкатенации слова *hexlet*, символа *-* (*дефис*, точнее *минус*) и числа 7 +Выведите на экран результат конкатенации слова *hexlet*, символа *-* и числа 7 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 index 3323891..44ddeaa 100644 --- a/modules/33-data-types/47-data-types-list/ru/data.yml +++ b/modules/33-data-types/47-data-types-list/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Какие бывают типы tips: - | diff --git a/modules/33-data-types/50-null/Test.java b/modules/33-data-types/50-null/Test.java index daca321..8a9dd7f 100644 --- a/modules/33-data-types/50-null/Test.java +++ b/modules/33-data-types/50-null/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "Hello Hexlet!"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/33-data-types/50-null/description.en.yml b/modules/33-data-types/50-null/description.en.yml deleted file mode 100644 index 3ddee85..0000000 --- a/modules/33-data-types/50-null/description.en.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- - -name: Data Types -theory: | - - 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. - -instructions: | - Display the number `-0.304`. - -tips: - - | - [Article on fractional numbers](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Data Type" -# description: "a set of data in the code (a kind of information). The type determines what can be done with the elements of a particular set. For example, integers, rational numbers, strings are different data types." -# - name: "Primitive data types" -# description: "simple types built into the programming language itself." -# - name: "String" -# description: | -# data type describing the character set (in other words, text); for example, `"text"` diff --git a/modules/33-data-types/50-null/description.ru.yml b/modules/33-data-types/50-null/description.ru.yml deleted file mode 100644 index 7043f4a..0000000 --- a/modules/33-data-types/50-null/description.ru.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- - -name: Значение null - -theory: | - Особняком в Java стоит значение `null`. В Java оно не является типом. Это просто конкретное значение со специальным смыслом и логикой работы. Начнем с примера: - - ```java - // Определение переменной без инициализации значением - // С var такое не сработает, так как невозможно вывести тип - String a; - ``` - - Что находится внутри переменной `a`? Если мы ее распечатаем, то увидим `null`. Значение `null` используется для ссылочных типов, когда значение не определено. - - Как такое возможно? Представьте, что мы хотим извлечь из базы данных пользователя, а его там нет. Что вернет нам запрос в базу? Вот именно для таких ситуаций и нужен `null`. - - Их гораздо больше, чем может показаться на первый взгляд. Чем дальше мы будем двигаться, тем чаще он начнет встречаться: - - ```java - var user = // тут делаем запрос в базу - // Если данных нет, то user станет null - // Запись выше равносильна - var user = null; - ``` - - Из вышесказанного следует важный вывод. Любой ссылочный тип данных может принимать значение `null`. То есть, `null` является значением любого ссылочного типа. А вот примитивные типы и `null` не совместимы. Примитивное значение всегда должно быть определено: - - ```java - // Error: incompatible types: cannot be converted to int - int x = null; - ``` - -instructions: | - - Определите переменную с именем `greeting`, но не инициализируйте ее - -tips: - - | - [Статья о дробных числах](https://habrahabr.ru/post/112953/) - -# definitions: -# - name: "Тип данных" -# description: "множество данных в коде (разновидность информации). Тип определяет, что можно делать с элементами конкретного множества. Например, целые числа, рациональные числа, строки — это разные типы данных." -# - name: "Примитивные типы данных" -# description: "простые типы, встроенные в сам язык программирования." -# - name: "Строка (String)" -# description: | -# тип данных, описывающий набор символов (иными словами — текст); например, `"text"` diff --git a/modules/33-data-types/50-null/en/EXERCISE.md b/modules/33-data-types/50-null/en/EXERCISE.md deleted file mode 100644 index a4eaba0..0000000 --- a/modules/33-data-types/50-null/en/EXERCISE.md +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 32b8c7a..0000000 --- a/modules/33-data-types/50-null/en/README.md +++ /dev/null @@ -1,62 +0,0 @@ - -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 deleted file mode 100644 index 37eeffe..0000000 --- a/modules/33-data-types/50-null/en/data.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- - -name: Data Types -tips: - - | - [Article on fractional numbers](https://habrahabr.ru/post/112953/) diff --git a/modules/33-data-types/50-null/ru/data.yml b/modules/33-data-types/50-null/ru/data.yml index 889ebe5..39f96f6 100644 --- a/modules/33-data-types/50-null/ru/data.yml +++ b/modules/33-data-types/50-null/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Значение null tips: - | diff --git a/modules/33-data-types/55-type-casting/description.en.yml b/modules/33-data-types/55-type-casting/description.en.yml deleted file mode 100644 index 2e51e56..0000000 --- a/modules/33-data-types/55-type-casting/description.en.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- - -name: Explicit type conversion -theory: | - - Java is a strongly typed programming language. Using special syntax we can change type of variables: - - ```java - System.out.print(Integer.parseInt("345")); - ``` - - Type conversion works like this: before the value, the desired type is indicated in parentheses. As a result, the value on the right is converted to a value of another type indicated on the left in parentheses. At the moment we are familiar with only two types, but the transformation in Java works not only for the primitive types. - - Type conversion can be used inside compound expressions: - - ```java - //Additional brackets help to visually separate parts of the expression from each other - System.out.print("It's" + ((int) 5.1)); - ``` - - It's 5 - - In case above, in spite of the fact, that 5.1 is the number, it has double type not int. Expression above bring this number type to int type, reject fraction part, because int type doesn't keep fraction part. - - -instructions: | - Display the string `2 times`, obtained from the number 2.9 and the string `times`, using type conversions and concatenation. - -# definitions: [] - -# tips: [] diff --git a/modules/33-data-types/55-type-casting/description.ru.yml b/modules/33-data-types/55-type-casting/description.ru.yml deleted file mode 100644 index 3b5b5e0..0000000 --- a/modules/33-data-types/55-type-casting/description.ru.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- - -name: Явное преобразование типов - -theory: | - В программировании регулярно встречаются задачи, когда один тип данных нужно преобразовать в другой. Простейший пример – работа с формами на сайтах. - - Данные формы всегда приходят в текстовом виде, даже если значение число. Вот как его можно преобразовать: - - ```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 - -instructions: | - - Выведите на экран строку `2 times`, полученную из числа 2.9 и строки `times`, используя преобразования типов и конкатенацию. -
-  2 times
-  
- -# definitions: [] - -# tips: [] diff --git a/modules/33-data-types/55-type-casting/en/EXERCISE.md b/modules/33-data-types/55-type-casting/en/EXERCISE.md deleted file mode 100644 index a9b8ea5..0000000 --- a/modules/33-data-types/55-type-casting/en/EXERCISE.md +++ /dev/null @@ -1 +0,0 @@ -Display the string `2 times`, obtained from the number 2.9 and the string `times`, using type conversions and concatenation. diff --git a/modules/33-data-types/55-type-casting/en/README.md b/modules/33-data-types/55-type-casting/en/README.md deleted file mode 100644 index 55878d1..0000000 --- a/modules/33-data-types/55-type-casting/en/README.md +++ /dev/null @@ -1,20 +0,0 @@ - -Java is a strongly typed programming language. Using special syntax we can change type of variables: - -```java -System.out.print(Integer.parseInt("345")); -``` - -Type conversion works like this: before the value, the desired type is indicated in parentheses. As a result, the value on the right is converted to a value of another type indicated on the left in parentheses. At the moment we are familiar with only two types, but the transformation in Java works not only for the primitive types. - -Type conversion can be used inside compound expressions: - -```java -//Additional brackets help to visually separate parts of the expression from each other -System.out.print("It's" + ((int) 5.1)); -``` - -It's 5 - -In case above, in spite of the fact, that 5.1 is the number, it has double type not int. Expression above bring this number type to int type, reject fraction part, because int type doesn't keep fraction part. - diff --git a/modules/33-data-types/55-type-casting/en/data.yml b/modules/33-data-types/55-type-casting/en/data.yml deleted file mode 100644 index e485e05..0000000 --- a/modules/33-data-types/55-type-casting/en/data.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -name: Explicit type conversion diff --git a/modules/33-data-types/55-type-casting/ru/README.md b/modules/33-data-types/55-type-casting/ru/README.md index 6f2b1d1..7240a33 100644 --- a/modules/33-data-types/55-type-casting/ru/README.md +++ b/modules/33-data-types/55-type-casting/ru/README.md @@ -22,4 +22,3 @@ System.out.println(result); // => 5 var result = 10 + ((int) 5.1); System.out.println(result); // => 15 ``` - diff --git a/modules/33-data-types/55-type-casting/ru/data.yml b/modules/33-data-types/55-type-casting/ru/data.yml index 0d3bf21..ba95a7f 100644 --- a/modules/33-data-types/55-type-casting/ru/data.yml +++ b/modules/33-data-types/55-type-casting/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Явное преобразование типов diff --git a/modules/33-data-types/description.en.yml b/modules/33-data-types/description.en.yml deleted file mode 100644 index e3139af..0000000 --- a/modules/33-data-types/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Data Types -description: | -  Java is a strongly typed language with different data types. You will find out what this means in the current module. diff --git a/modules/35-methods-using/100-methods/Test.java b/modules/35-methods-using/100-methods/Test.java index d07b111..b1b5fca 100644 --- a/modules/35-methods-using/100-methods/Test.java +++ b/modules/35-methods-using/100-methods/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "12"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/35-methods-using/100-methods/description.ru.yml b/modules/35-methods-using/100-methods/description.ru.yml deleted file mode 100644 index 8655be6..0000000 --- a/modules/35-methods-using/100-methods/description.ru.yml +++ /dev/null @@ -1,64 +0,0 @@ ---- - -name: Методы и их вызов - -theory: | - Сложение, конкатенация, нахождение остатка от деления и остальные ранее рассмотренные операции – все это довольно базовые возможности языков программирования. - - Математика не ограничена арифметикой, кроме нее есть и множество других разделов со своими операциями — например, геометрия. То же самое касается и строк: их можно переворачивать, менять регистр букв, удалять лишние символы — и это только самое простое. На более высоком уровне есть прикладная логика конкретного приложения. - - Программы списывают деньги, считают налоги, формируют отчеты. Количество подобных операций бесконечно и индивидуально для каждой программы. И все они должны быть как-то выражены в коде. - - ## Как выражаются операции - - Для выражения любой произвольной операции в программировании существует понятие **функция**. Функции бывают как встроенные в язык, так и добавленные программистом. С одной встроенной функцией мы уже знакомы — это `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. Программисты постоянно сидят в документации разбираясь с тем, как что работает. - -instructions: | - - В коде программы определены две переменные, содержащие имена компаний. Посчитайте их общую длину в символах и выведите ее на экран. - -# tips: [] - -# definitions: -# - name: Метод -# description: "операция, способная принимать данные и возвращать результат; Метод вызывается так: `foo()`." -# - name: Аргумент -# description: "информация, которую метод получает при вызове. Например, `foo(42)` — передача аргумента `42` методу `foo`" diff --git a/modules/35-methods-using/100-methods/ru/README.md b/modules/35-methods-using/100-methods/ru/README.md index 9734dce..28d48d2 100644 --- a/modules/35-methods-using/100-methods/ru/README.md +++ b/modules/35-methods-using/100-methods/ru/README.md @@ -31,8 +31,6 @@ System.out.println(companyLength); // => 6 company.toUpperCase(); // "HEXLET" ``` -https://replit.com/@hexlet/java-basics-methods-calling - Основное в работе с методами – понять принцип возврата значения. Методы почти никогда не выводят данные на экран, они их возвращают. Благодаря этому свойству, мы можем разбить нашу программу на кусочки, из которых потом составляется что-то сложное. В примерах выше результат вызова каждого метода записывается в переменные. Но это не обязательно, мы можем использовать методы напрямую: diff --git a/modules/35-methods-using/100-methods/ru/data.yml b/modules/35-methods-using/100-methods/ru/data.yml index 8370df3..03d90c7 100644 --- a/modules/35-methods-using/100-methods/ru/data.yml +++ b/modules/35-methods-using/100-methods/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Методы и их вызов diff --git a/modules/35-methods-using/105-methods-parameters/Test.java b/modules/35-methods-using/105-methods-parameters/Test.java index 07e9d0b..280db67 100644 --- a/modules/35-methods-using/105-methods-parameters/Test.java +++ b/modules/35-methods-using/105-methods-parameters/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "h o d o r"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/35-methods-using/105-methods-parameters/description.ru.yml b/modules/35-methods-using/105-methods-parameters/description.ru.yml deleted file mode 100644 index 2145bef..0000000 --- a/modules/35-methods-using/105-methods-parameters/description.ru.yml +++ /dev/null @@ -1,77 +0,0 @@ ---- - -name: Параметры методов - -theory: | - - Метод `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" - ``` - - -instructions: | - - Вам даны три переменные с фамилиями разных людей. Составьте и выведите на экран слово из символов в таком порядке: - - 1. третий символ из первой строки; - 2. второй символ из второй строки; - 3. четвертый символ из третьей строки; - 4. пятый символ из второй строки; - 5. третий символ из второй строки. - - Символы в слове должны быть разделены пробелами. Вывод результата должен быть примерно в таком виде: - -
-  a b c d e
-  
- -# tips: [] - -# definitions: -# - name: Метод -# description: "операция, способная принимать данные и возвращать результат; Метод вызывается так: `foo()`." -# - name: Аргумент -# description: "информация, которую метод получает при вызове. Например, `foo(42)` — передача аргумента `42` методу `foo`" diff --git a/modules/35-methods-using/105-methods-parameters/ru/README.md b/modules/35-methods-using/105-methods-parameters/ru/README.md index 456ed2a..fea309f 100644 --- a/modules/35-methods-using/105-methods-parameters/ru/README.md +++ b/modules/35-methods-using/105-methods-parameters/ru/README.md @@ -11,7 +11,7 @@ searchEngine.charAt(0); // 'g' Почему символ первый, а указан 0? В программировании отсчет начинается с нуля. Поэтому первый символ находится на нулевой позиции — «индекс 0». -Соответственно, у последнего символа индекс равен длине строки - 1: +Соответственно, у последнего символа индекс равен длине строки минус 1: ```java // google length => 6 @@ -45,4 +45,3 @@ searchEngine.replace("go", "mo"); // "moogle" "hexlet".substring(1, 3); // "ex" "hexlet".substring(3, 6); // "let" ``` - diff --git a/modules/35-methods-using/105-methods-parameters/ru/data.yml b/modules/35-methods-using/105-methods-parameters/ru/data.yml index 33163c5..db60e1a 100644 --- a/modules/35-methods-using/105-methods-parameters/ru/data.yml +++ b/modules/35-methods-using/105-methods-parameters/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Параметры методов diff --git a/modules/35-methods-using/110-methods-as-expressions/description.ru.yml b/modules/35-methods-using/110-methods-as-expressions/description.ru.yml deleted file mode 100644 index e6bffa7..0000000 --- a/modules/35-methods-using/110-methods-as-expressions/description.ru.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- - -name: Вызов метода — выражение - -theory: | - В программировании выражение — нечто возвращающее результат, который можно использовать. - - Мы уже знаем достаточно много о выражениях и о принципах их построения. Сложение, вычитание, конкатенация, а также другие математические и строковые операции — все это выражения: - - ```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 - ``` - -instructions: | - - Выведите на экран первую и последнюю буквы предложения, записанного в переменную `text`, в следующем формате: - -
-  First: N
-  Last: t
-  
- - Постарайтесь создать только одну переменную, в которую сразу запишется нужный текст перед печатью на экран. В этом уроке мы отрабатываем умение собирать составное выражение. - -# tips: [] 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 index 42696a1..e1ff3aa 100644 --- a/modules/35-methods-using/110-methods-as-expressions/ru/data.yml +++ b/modules/35-methods-using/110-methods-as-expressions/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Вызов метода — выражение diff --git a/modules/35-methods-using/115-string-immutability/Test.java b/modules/35-methods-using/115-string-immutability/Test.java index 285a34b..f875d6a 100644 --- a/modules/35-methods-using/115-string-immutability/Test.java +++ b/modules/35-methods-using/115-string-immutability/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "support@hexlet.io"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/35-methods-using/115-string-immutability/description.ru.yml b/modules/35-methods-using/115-string-immutability/description.ru.yml deleted file mode 100644 index 0913155..0000000 --- a/modules/35-methods-using/115-string-immutability/description.ru.yml +++ /dev/null @@ -1,51 +0,0 @@ ---- - -name: Неизменяемость строк - -theory: | - Подумаем, что выведет на экран следующий код: - - ```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 - - Такой подход нередко предпочтительнее по соображениям читаемости. Переменные, которые постоянно меняются, сложнее анализировать. В итоге все зависит от задачи. С опытом придет понимание, какой подход лучше. - -instructions: | - - Данные, вводимые пользователями в формах, часто содержат лишние пробельные символы в конце или начале строки. Кроме того, пользователи могут вводить одно и то же в разном регистре, что потом мешает работе с данными. Поэтому перед тем как добавлять их, данные обрабатывают (говорят нормализуют). В базовую обработку входят два действия: - - * Удаление концевых пробельных символов с помощью метода `.trim()`, например, было: `" hexlet\n "`, стало: `"hexlet"` - * Приведение к нижнему регистру с помощью метода `toLowerCase()`. Было: `"SUPPORT@hexlet.io"`, стало: `"support@hexlet.io"`. - - Обновите переменную `email` записав в неё то же самое значение, но обработанное по схеме указанной выше. Распечатайте то, что получилось, на экран. - -# tips: [] diff --git a/modules/35-methods-using/115-string-immutability/ru/README.md b/modules/35-methods-using/115-string-immutability/ru/README.md index 05f726c..2bb2ff9 100644 --- a/modules/35-methods-using/115-string-immutability/ru/README.md +++ b/modules/35-methods-using/115-string-immutability/ru/README.md @@ -30,6 +30,4 @@ 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 index 6e002e9..5557336 100644 --- a/modules/35-methods-using/115-string-immutability/ru/data.yml +++ b/modules/35-methods-using/115-string-immutability/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Неизменяемость строк diff --git a/modules/35-methods-using/120-methods-chain/description.ru.yml b/modules/35-methods-using/120-methods-chain/description.ru.yml deleted file mode 100644 index bfa6bbf..0000000 --- a/modules/35-methods-using/120-methods-chain/description.ru.yml +++ /dev/null @@ -1,75 +0,0 @@ ---- - -name: Цепочки вызовов методов - -theory: | - Обработка данных может состоять из достаточно большого количества шагов, которые нужно выполнить. - - Возьмем для примера такую задачу: сформировать адрес страницы в интернете на основе введенного пользователем названия статьи. Такая задача часто возникает при публикации статей в блогах. Подобные адреса выглядят так: - - ``` - 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(); - ``` - - - Несмотря на удобство этого механизма, им не стоит злоупотреблять. Промежуточные переменные могут упростить понимание кода. - -instructions: | - - Напишите код, который берет данные из переменной `name` и выполняет капитализацию. В программировании так называют операцию, которая делает заглавной первую букву в слове, а все остальные переводит в нижний регистр. Например: *heXlet => Hexlet*. Программа должна выводить результат на экран. - - Для извлечения частей слова, воспользуйтесь методом [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java?utm_source=code-basics&utm_medium=referral&utm_campaign=qna&utm_content=lesson): - - ```java - // 1 параметр – начальный индекс, 2 – конечный индекс (не включая) - "hexlet".substring(0, 1); // "h" - // По умолчанию до конца строки - "hexlet".substring(1); // "exlet" - ``` - -# tips: [] diff --git a/modules/35-methods-using/120-methods-chain/ru/README.md b/modules/35-methods-using/120-methods-chain/ru/README.md index 1cce7e1..b5f53a1 100644 --- a/modules/35-methods-using/120-methods-chain/ru/README.md +++ b/modules/35-methods-using/120-methods-chain/ru/README.md @@ -8,7 +8,7 @@ https://ru.hexlet.io/blog/posts/iz-vahtovika-v-programmirovanie Последняя часть здесь *iz-vahtovika-v-programmirovanie* создана автоматически кодом, который мы написали на Хекслете. Кстати, у нее есть специальное название – это [**слаг**](https://en.wikipedia.org/wiki/Clean_URL#Slug). -Какие шаги нужно выполнить? чтобы получить подобную строку? Вот лишь некоторые из них: +Какие шаги нужно выполнить, чтобы получить подобную строку? Вот лишь некоторые из них: * Перевести все в нижний регистр, чтобы случайно не создавались дубли одинаковых страниц в поисковых системах * Очистить название от пробельных символов на концах. Там они могут случайно появиться при вводе названия @@ -51,5 +51,4 @@ name = name.trim() .toLowerCase(); ``` - Несмотря на удобство этого механизма, им не стоит злоупотреблять. Промежуточные переменные могут упростить понимание кода. diff --git a/modules/35-methods-using/120-methods-chain/ru/data.yml b/modules/35-methods-using/120-methods-chain/ru/data.yml index 5723b1c..bb6bf53 100644 --- a/modules/35-methods-using/120-methods-chain/ru/data.yml +++ b/modules/35-methods-using/120-methods-chain/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Цепочки вызовов методов diff --git a/modules/35-methods-using/200-methods-deterministic/App.java b/modules/35-methods-using/200-methods-deterministic/App.java index bdd1527..9dcd873 100644 --- a/modules/35-methods-using/200-methods-deterministic/App.java +++ b/modules/35-methods-using/200-methods-deterministic/App.java @@ -1,7 +1,7 @@ public class App { public static void main(String[] args) { // BEGIN - System.out.println((int) (Math.random() * 10) + 1); + System.out.println((int) (Math.random() * 10)); // END } } diff --git a/modules/35-methods-using/200-methods-deterministic/Test.java b/modules/35-methods-using/200-methods-deterministic/Test.java index 8e564e1..848b816 100644 --- a/modules/35-methods-using/200-methods-deterministic/Test.java +++ b/modules/35-methods-using/200-methods-deterministic/Test.java @@ -6,7 +6,7 @@ class Test { public static void main(String[] args) { - IntStream.range(1, 10).forEach(i -> { + IntStream.range(0, 10).forEach(i -> { App.main(null); ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -14,7 +14,7 @@ public static void main(String[] args) { App.main(null); var actual = Integer.parseInt(out.toString().trim()); System.out.println(actual); - assertThat(actual).isBetween(1, 10); + assertThat(actual).isBetween(0, 10); }); } } diff --git a/modules/35-methods-using/200-methods-deterministic/description.ru.yml b/modules/35-methods-using/200-methods-deterministic/description.ru.yml deleted file mode 100644 index 5af94ae..0000000 --- a/modules/35-methods-using/200-methods-deterministic/description.ru.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- - -name: Детерминированность - -theory: | - Независимо от того, какой язык программирования используется, методы внутри него обладают некоторыми фундаментальными свойствами. Зная эти свойства, легче прогнозировать поведение методов, способы их тестирования и место их использования. К таким свойствам относится детерминированность. Метод называется детерминированным тогда, когда для одних и тех же входных параметров он возвращает один и тот же результат. Например, метод, извлекающий символ из строки — детерминированный. - - ```java - "wow".charAt(1); // 'o' - "wow".charAt(1); // 'o' - ``` - - Сколько бы раз мы не вызывали этот метод, передавая туда значение `1`, он всегда вернет `'o'`. В свою очередь метод, возвращающий случайное число, не является детерминированным, так как у одного и того же входа (даже если он пустой, то есть параметры не принимаются) мы получим всегда разный результат. Насколько он разный - не важно, даже если хотя бы один из миллиона вызовов вернет что-то другое, этот метод автоматически считается недетерминированным. - - ```java - // Метод, возвращающий случайное число - Math.random(); // 0.09856613113197676 - Math.random(); // 0.8839904367241888 - ``` - - - Зачем это нужно знать? Детерминированность серьезно влияет на многие аспекты. Детерминированные функции удобны в работе, их легко оптимизировать, легко тестировать. Если есть возможность сделать функцию детерминированной, то лучше ее такой и сделать. - -instructions: | - - Метод `Math.random()` возвращает случайное число от 0 до 1 с большим количеством знаков после запятой. Но в реальных задачах бывает нужно получать случайные целые числа. Реализуйте код, который печатает на экран случайное целое число от 1 до 10 включительно. Чтобы получить такое число, нужно умножить результат вызова `Math.random()` на 10 и преобразовать тип полученного числа из *double* в *int*. К полученному результату нужно прибавить 1. - - ```java - // Преобразование в int - (int) 0.932342; // 0 - (int) 8.123412; // 8 - ``` - - Попробуйте решить это задание в одну строчку - -tips: - - | - [Детерминированные функции](https://ru.wikipedia.org/wiki/Чистота_функции#Детерминированность_функции) - -# definitions: -# - name: Побочный эффект -# description: "действие, которое изменяет внешнее окружение (среду выполнения). Например, вывод на экран или отправка письма." diff --git a/modules/35-methods-using/200-methods-deterministic/ru/EXERCISE.md b/modules/35-methods-using/200-methods-deterministic/ru/EXERCISE.md index e7afeef..f4d13e4 100644 --- a/modules/35-methods-using/200-methods-deterministic/ru/EXERCISE.md +++ b/modules/35-methods-using/200-methods-deterministic/ru/EXERCISE.md @@ -1,5 +1,5 @@ -Метод `Math.random()` возвращает случайное число от 0 до 1 с большим количеством знаков после запятой. Но в реальных задачах бывает нужно получать случайные целые числа. Реализуйте код, который печатает на экран случайное целое число от 1 до 10. Чтобы получить такое число, нужно умножить результат вызова `Math.random()` на 10 и преобразовать тип полученного числа из *double* в *int*. К полученному результату нужно прибавить 1. +Метод `Math.random()` возвращает случайное число от 0 до 1 с большим количеством знаков после запятой. Но в реальных задачах бывает нужно получать случайные целые числа. Реализуйте код, который печатает на экран случайное целое число от 0 до 10. Чтобы получить такое число, нужно умножить результат вызова `Math.random()` на 10 и преобразовать тип полученного числа из *double* в *int*. ```java // Преобразование в int @@ -7,4 +7,4 @@ (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 index 073ce04..ccd57be 100644 --- a/modules/35-methods-using/200-methods-deterministic/ru/README.md +++ b/modules/35-methods-using/200-methods-deterministic/ru/README.md @@ -13,5 +13,4 @@ Math.random(); // 0.09856613113197676 Math.random(); // 0.8839904367241888 ``` - Зачем это нужно знать? Детерминированность серьезно влияет на многие аспекты. Детерминированные функции удобны в работе, их легко оптимизировать, легко тестировать. Если есть возможность сделать функцию детерминированной, то лучше ее такой и сделать. diff --git a/modules/35-methods-using/200-methods-deterministic/ru/data.yml b/modules/35-methods-using/200-methods-deterministic/ru/data.yml index 517e770..3f4b91c 100644 --- a/modules/35-methods-using/200-methods-deterministic/ru/data.yml +++ b/modules/35-methods-using/200-methods-deterministic/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Детерминированность tips: - > diff --git a/modules/35-methods-using/400-stdlib/description.ru.yml b/modules/35-methods-using/400-stdlib/description.ru.yml deleted file mode 100644 index 244c7bc..0000000 --- a/modules/35-methods-using/400-stdlib/description.ru.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- - -name: Стандартная библиотека - -theory: | - Java, как и любой другой язык, поставляется с набором полезных методов. Все вместе они составляют так называемую **стандартную библиотеку**. В нее обычно входят тысячи методов, которые невозможно выучить — этого и не нужно делать. Подразумевается, что любой программист знает, где искать документацию по ним и примерно представляет себе, чего он хочет достичь. А дальше — дело техники. Если отнять у программистов интернет, то большинство не сможет ничего запрограммировать. - - Для новичков эта информация часто выглядит так: «Сходи туда, не знаю куда, принеси то, не знаю что». То есть непонятно, как узнавать про эти методы, когда ты ничего не знаешь вообще. Как ни странно, не существует способа раз и навсегда познать все, что нужно познать. Любой разработчик в процессе своего профессионального взросления знакомится со все более интересными методами, решающими его задачи более элегантно, и таким образом пополняет свой арсенал. - - Вот некоторые советы, как узнавать о новых методах: - - * Всегда четко отслеживайте, с каким типом данных вы сейчас работаете. Почти всегда вы найдете необходимый метод в соответствующем разделе документации — например, для работы со строками нужно изучать строковые методы - * Периодически открывайте раздел со стандартными методами по изучаемой тематике и просто пробегайтесь по ним, изучая сигнатуры и способы использования - * Чаще читайте чужой код, особенно код библиотек, которые вы используете. Он весь доступен на GitHub - -instructions: | - - Напишем код в стиле "повтори за учителем". Рассчитаем количество дней между двумя датами используя встроенные возможности 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); - ``` - -tips: - - | - [Как искать техническую информацию](https://guides.hexlet.io/how-to-search/) - -# definitions: -# - name: Побочный эффект -# description: "действие, которое изменяет внешнее окружение (среду выполнения). Например, вывод на экран или отправка письма." diff --git a/modules/35-methods-using/400-stdlib/ru/data.yml b/modules/35-methods-using/400-stdlib/ru/data.yml index c4239d2..1bb88dd 100644 --- a/modules/35-methods-using/400-stdlib/ru/data.yml +++ b/modules/35-methods-using/400-stdlib/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Стандартная библиотека tips: - | diff --git a/modules/35-methods-using/500-methods-variants/description.ru.yml b/modules/35-methods-using/500-methods-variants/description.ru.yml deleted file mode 100644 index 3e74d62..0000000 --- a/modules/35-methods-using/500-methods-variants/description.ru.yml +++ /dev/null @@ -1,95 +0,0 @@ ---- - -name: Какие бывают методы - -theory: | - Одна из базовых тем в 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(); - ``` - - ## Выводы - - * Статические методы не связаны с конкретными объектами и вызываются из класса напрямую - * Нестатические методы строят свою логику относительно данных самого объекта и вызываются у конкретных объектов - - Все это плавно подводит нас к возможности самостоятельно создавать классы, объекты и методы, без чего невозможно себе представить ни одну программу, даже небольшую. - -instructions: | - - В переменной `emoji` находится текстовый грустный смайлик *-(*. Ваша задача — сделать этот смайлик веселым с помощью двух преобразований: - - * Добавить слева глаза *:* - * Заменить *(* на *)* (с помощью метода строки `replace()`) - - Должно получиться: *:-)*. Выведите его на экран. - -# tips: -# - | -# [Как искать техническую информацию](https://guides.hexlet.io/how-to-search/) - -# definitions: -# - name: Побочный эффект -# description: "действие, которое изменяет внешнее окружение (среду выполнения). Например, вывод на экран или отправка письма." diff --git a/modules/35-methods-using/500-methods-variants/ru/data.yml b/modules/35-methods-using/500-methods-variants/ru/data.yml index 8a2c62f..a5d017b 100644 --- a/modules/35-methods-using/500-methods-variants/ru/data.yml +++ b/modules/35-methods-using/500-methods-variants/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Какие бывают методы diff --git a/modules/40-methods-definition/100-method-definition-static/Test.java b/modules/40-methods-definition/100-method-definition-static/Test.java index 4f4931c..9f9ad50 100644 --- a/modules/40-methods-definition/100-method-definition-static/Test.java +++ b/modules/40-methods-definition/100-method-definition-static/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "Winter is coming"; - App.printMotto(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/40-methods-definition/100-method-definition-static/description.ru.yml b/modules/40-methods-definition/100-method-definition-static/description.ru.yml deleted file mode 100644 index 8eed1d6..0000000 --- a/modules/40-methods-definition/100-method-definition-static/description.ru.yml +++ /dev/null @@ -1,105 +0,0 @@ ---- - -name: Создание (определение) метода - -theory: | - Определение собственных методов значительно упрощает написание и поддержку программ. Например, методы позволяют объединять составные операции в одну. - - К примеру, отправка письма на сайте — это достаточно сложный процесс, включающий в себя взаимодействие с интернетом. Можно определить метод и скрыть всю сложность за одной простой конструкцией: - - ```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/programs/java?utm_source=code-basics&utm_medium=referral&utm_campaign=programs&utm_content=lesson). - - За работу метода отвечают: - - * *static* — отвязывает метод от объекта и делает возможным его вызов напрямую из класса - * *void* используется, если метод ничего не возвращает. Например, такое определение у метода `System.out.println()`. Если метод возвращает какие-то данные, то вместо *void* указывается тип возвращаемых данных - - В отличие от обычных данных, методы выполняют действия, поэтому их имена практически всегда должны быть глаголами: «построить что-то», «нарисовать что-то», «открыть что-то». - - Все, что описывается внутри фигурных скобок `{}`, называется **телом метода**. Внутри тела можно описывать любой код. Считайте, что это маленькая самостоятельная программа, набор произвольных инструкций. - - Тело выполняется ровно в тот момент, когда запускается метод. Причем каждый вызов метода запускает тело независимо от других вызовов. Кстати, тело может быть пустым: - - ```java - // Минимальное определение метода - public class App { - public static void noop() { - // Тут мог бы быть код, но его нет - // Обратите внимание на отступы - // Для читаемости, любой код внутри тела сдвигается вправо на 4 пробела - } - } - App.noop(); - ``` - - Понятие «создать метод» имеет много синонимов: «реализовать», «определить» и даже «заимплементить». Все эти термины встречаются в повседневной практике на работе. - - -instructions: | - - Реализуйте статический метод с именем `printMotto()`, который выведет на экран фразу *Winter is coming*. - - ```java - // Класс App уже определен - App.printMotto(); // => Winter is coming - ``` - - Чтобы мы могли вызвать этот метод снаружи, нужно его пометить не только ключевым словом `static`, но еще и `public`. - - В задачах, в которых нужно реализовать метод, этот метод вызывать не нужно. Вызывать метод будут автоматизированные тесты, которые проверяют его работоспособность. Пример с вызовом выше показан только для того, чтобы вы понимали, как ваш метод будет использоваться. - -tips: - - | - [Именование в программировании](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) 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 index e404b2b..a0235b4 100644 --- a/modules/40-methods-definition/100-method-definition-static/ru/README.md +++ b/modules/40-methods-definition/100-method-definition-static/ru/README.md @@ -45,8 +45,6 @@ public class App { App.showCurrentDate(); // => Today is: 2021-10-25 ``` -https://replit.com/@hexlet/java-basics-methods-definition - Определение метода в Java включает в себя много действий, которые мы постепенно разберем. Их можно разделить на две группы: 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 index a7f1bb6..b2e23c4 100644 --- a/modules/40-methods-definition/100-method-definition-static/ru/data.yml +++ b/modules/40-methods-definition/100-method-definition-static/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Создание (определение) метода tips: - > diff --git a/modules/40-methods-definition/150-method-main/Test.java b/modules/40-methods-definition/150-method-main/Test.java index fa83817..b86e413 100644 --- a/modules/40-methods-definition/150-method-main/Test.java +++ b/modules/40-methods-definition/150-method-main/Test.java @@ -1,4 +1,6 @@ import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +9,6 @@ class Test { public static void main(String[] args) { final var expected = "It works!"; - App.main(null); - ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); @@ -16,6 +16,9 @@ public static void main(String[] args) { final var actual = out.toString().trim(); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + System.out.println(actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/modules/40-methods-definition/150-method-main/description.ru.yml b/modules/40-methods-definition/150-method-main/description.ru.yml deleted file mode 100644 index 4382509..0000000 --- a/modules/40-methods-definition/150-method-main/description.ru.yml +++ /dev/null @@ -1,118 +0,0 @@ ---- - -name: Метод main - -theory: | - Возможно вы удивитесь, но на протяжении всех предыдущих уроков, мы создавали свой собственный метод. Каркас метода был заранее написан, а от вас требовалось добавить его тело. Практика выглядела так: - - ```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](utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson). - - Главное, что нужно сейчас запомнить — любые статические методы вызываются через точку после имени класса, а сами вызовы происходят внутри других методов: - - ```java - // Просто пример вызовов методов друг из друга - class MySuperClassName { - public static void oneMethod() { - MySuperClassName.twoMethod(); - } - - public static void twoMethod() { - MySuperClassName.threeMethod(); - } - - public static void threeMethod() { - } - } - ``` - -instructions: | - - Реализуйте класс с именем `App` и двумя методами: - - 1. Метод `gogo()`, который печатает на экран строку `It works!` - 2. `main()`, как в определении выше, который вызывает метод `gogo()` - - Результат вызова `main()` в таком случае будет таким: - - ```java - // => "It works!" - ``` - -# tips: -# - | -# [Именование в программировании](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) diff --git a/modules/40-methods-definition/150-method-main/ru/data.yml b/modules/40-methods-definition/150-method-main/ru/data.yml index 127ebc6..36a52e0 100644 --- a/modules/40-methods-definition/150-method-main/ru/data.yml +++ b/modules/40-methods-definition/150-method-main/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Метод main diff --git a/modules/40-methods-definition/200-method-definition-return/description.ru.yml b/modules/40-methods-definition/200-method-definition-return/description.ru.yml deleted file mode 100644 index efab5da..0000000 --- a/modules/40-methods-definition/200-method-definition-return/description.ru.yml +++ /dev/null @@ -1,154 +0,0 @@ ---- - -name: Возврат значений - -theory: | - Методы, которые мы определяли в предыдущих уроках, заканчивали свою работу тем, что печатали на экран какие-то данные: - - ```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; - } - } - ``` - - - В этом примере в определении метода использовался `long`, так как возвращается целое число. - - Чтобы проверить знания из этого урока, попробуйте ответить на вопрос. Как думаете, что выведет этот код? - - ```java - // Определение - class App { - public static int run() { - return 5; - return 10; - } - } - - // Использование - App.run(); // => ? - ``` - -instructions: | - - Реализуйте статический метод `sayHurrayThreeTimes()`, которая возвращает строку 'hurray! hurray! hurray!'. - - ```java - var hurray = App.sayHurrayThreeTimes(); - System.out.println(hurray); // => hurray! hurray! hurray! - ``` - -# tips: [] 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 index f9c18b3..4cf468e 100644 --- a/modules/40-methods-definition/200-method-definition-return/ru/EXERCISE.md +++ b/modules/40-methods-definition/200-method-definition-return/ru/EXERCISE.md @@ -1,5 +1,5 @@ -Реализуйте статический метод `sayHurrayThreeTimes()`, который возвращает строку 'hurray! hurray! hurray!'. +Реализуйте статический метод `sayHurrayThreeTimes()`, которая возвращает строку 'hurray! hurray! hurray!'. ```java var hurray = App.sayHurrayThreeTimes(); 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 index 4914572..f68d91d 100644 --- a/modules/40-methods-definition/200-method-definition-return/ru/README.md +++ b/modules/40-methods-definition/200-method-definition-return/ru/README.md @@ -119,7 +119,6 @@ class App { } ``` - В этом примере в определении метода использовался `long`, так как возвращается целое число. Чтобы проверить знания из этого урока, попробуйте ответить на вопрос. Как думаете, что выведет этот код? 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 index 4c6a392..0f8f6aa 100644 --- a/modules/40-methods-definition/200-method-definition-return/ru/data.yml +++ b/modules/40-methods-definition/200-method-definition-return/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Возврат значений diff --git a/modules/40-methods-definition/300-method-definition-parameters/description.ru.yml b/modules/40-methods-definition/300-method-definition-parameters/description.ru.yml deleted file mode 100644 index 5249082..0000000 --- a/modules/40-methods-definition/300-method-definition-parameters/description.ru.yml +++ /dev/null @@ -1,147 +0,0 @@ ---- - -name: Определение методов - -theory: | - Методы могут не только возвращать значения, но и принимать их в виде параметров. С параметрами методов мы уже сталкивались много раз: - - ```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); - } - } - ``` - - - Разберем этот код подробнее. `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 - ``` - - - Методы могут требовать на вход любое количество параметров, которое им нужно для работы: - - ```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 - ``` - -instructions: | - - Реализуйте статический метод `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?utm_source=code-basics&utm_medium=referral&utm_campaign=qna&utm_content=lesson). Подумайте, исходя из задания, с какого индекса и по какой вам надо извлечь подстроку? - - ```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 index 7679634..af4339b 100644 --- a/modules/40-methods-definition/300-method-definition-parameters/ru/README.md +++ b/modules/40-methods-definition/300-method-definition-parameters/ru/README.md @@ -47,8 +47,6 @@ class App { } ``` -https://replit.com/@hexlet/java-basics-methods-parameters-1 - Разберем этот код подробнее. `char` говорит нам о типе возвращаемого значения. Далее в скобках указывается тип параметра `String` и его имя `str`. Внутри метода мы не знаем, с каким конкретно значением идет работа, поэтому параметры всегда описываются как переменные. @@ -81,8 +79,6 @@ App.average(1, 5); // 3.0 App.average(1, 2); // 1.5 ``` -https://replit.com/@hexlet/java-basics-methods-parameters-2 - Методы могут требовать на вход любое количество параметров, которое им нужно для работы: ```java 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 index 62674da..0dd161f 100644 --- a/modules/40-methods-definition/300-method-definition-parameters/ru/data.yml +++ b/modules/40-methods-definition/300-method-definition-parameters/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Определение методов diff --git a/modules/40-methods-definition/400-method-definition-default-parameters/description.ru.yml b/modules/40-methods-definition/400-method-definition-default-parameters/description.ru.yml deleted file mode 100644 index f6241b6..0000000 --- a/modules/40-methods-definition/400-method-definition-default-parameters/description.ru.yml +++ /dev/null @@ -1,118 +0,0 @@ ---- - -name: Необязательные параметры методов - -theory: | - - - В программировании большое количество функций и методов имеют параметры, которые редко меняются. - - В таких случаях этим параметрам задают **значения по умолчанию**, которые можно поменять по необходимости. Этим немного сокращается количество одинакового кода. - - Это наглядно видно на таком примере: - - ```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 - - В этом примере мы не сократили код, но он наглядно показывает принцип, описанный выше. - -instructions: | - - Реализуйте метод `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" - ``` - -# tips: [] 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 index e754b2e..326d1e5 100644 --- 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 @@ -87,5 +87,4 @@ class App { } ``` - В этом примере мы не сократили код, но он наглядно показывает принцип, описанный выше. 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 index 557de49..aee3ae8 100644 --- 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 @@ -1,3 +1,2 @@ --- - name: Необязательные параметры методов diff --git a/modules/45-logic/10-bool-type/description.ru.yml b/modules/45-logic/10-bool-type/description.ru.yml deleted file mode 100644 index d5de3eb..0000000 --- a/modules/45-logic/10-bool-type/description.ru.yml +++ /dev/null @@ -1,84 +0,0 @@ ---- - -name: Логический тип - -theory: | - Кроме арифметических операций, из школьной математики нам известны еще и операции сравнения, например: - - ``` - 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 - ``` - -instructions: | - - Реализуйте метод `isPensioner()`, который принимает один параметр — возраст человека, и проверяет, является ли он пенсионным. Пенсионером считается человек, достигший возраста 60 лет и больше. - - Примеры вызова: - - ```java - App.isPensioner(75); // true - App.isPensioner(18); // false - ``` - -definitions: - - name: "Логический тип (boolean)" - description: "тип данных с двумя возможными значениями: true (истина) и false (ложь)." diff --git a/modules/45-logic/10-bool-type/ru/data.yml b/modules/45-logic/10-bool-type/ru/data.yml index b4d33e2..c193be4 100644 --- a/modules/45-logic/10-bool-type/ru/data.yml +++ b/modules/45-logic/10-bool-type/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Логический тип definitions: - name: Логический тип (boolean) diff --git a/modules/45-logic/12-string-comparasion/description.ru.yml b/modules/45-logic/12-string-comparasion/description.ru.yml deleted file mode 100644 index 188ef9a..0000000 --- a/modules/45-logic/12-string-comparasion/description.ru.yml +++ /dev/null @@ -1,151 +0,0 @@ ---- - -# Переписать на человеческий - -name: Сравнение строк - -theory: | - Посмотрите на код и попытайтесь ответить, чему равны значения этих выражений: - - ```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 - ``` - - - Помимо `equals()`, в строки встроен метод `equalsIgnoreCase()`, который выполняет проверку по значению без учета регистра: - - ```java - var name1 = "java".toUpperCase(); // "JAVA" - var name2 = "java".toLowerCase(); // "java" - name1.equalsIgnoreCase(name2); // true - ``` - - Иногда сравнение строк в Java ведет себя как сравнение значений, но никогда не делайте ставку на это. При изменении кода легко забыть поправить проверку и получить ошибку. Всегда используйте методы, когда нужно сравнивать по значению. - -instructions: | - - Реализуйте метод `isPalindrome()`, который определяет, является ли слово палиндромом или нет. Палиндром это слово, которое читается одинаково в обоих направлениях. - - ```java - App.isPalindrome("шалаш"); // true - App.isPalindrome("ага"); // true - App.isPalindrome("хекслет"); // false - - // Слова в метод могут быть переданы в любом регистре - App.isPalindrome("Ага"); // true - ``` - - Для определения палиндрома, необходимо перевернуть строку и сравнить ее с исходной. Для этого воспользуйтесь методом `StringUtils.reverse()` - - ```java - StringUtils.reverse("мама"); // "амам" - ``` - -# tips: [] diff --git a/modules/45-logic/12-string-comparasion/ru/README.md b/modules/45-logic/12-string-comparasion/ru/README.md index 4f65415..4650154 100644 --- a/modules/45-logic/12-string-comparasion/ru/README.md +++ b/modules/45-logic/12-string-comparasion/ru/README.md @@ -111,7 +111,6 @@ var name2 = "java".toUpperCase(); // "JAVA" name1.equals(name2); // true ``` - Помимо `equals()`, в строки встроен метод `equalsIgnoreCase()`, который выполняет проверку по значению без учета регистра: ```java diff --git a/modules/45-logic/12-string-comparasion/ru/data.yml b/modules/45-logic/12-string-comparasion/ru/data.yml index bd06840..b0cd3d1 100644 --- a/modules/45-logic/12-string-comparasion/ru/data.yml +++ b/modules/45-logic/12-string-comparasion/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Сравнение строк diff --git a/modules/45-logic/20-combine-expressions/description.ru.yml b/modules/45-logic/20-combine-expressions/description.ru.yml deleted file mode 100644 index cc46ae8..0000000 --- a/modules/45-logic/20-combine-expressions/description.ru.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- - -name: Комбинирование операций и методов -theory: | - - Логические операции — это выражения. Значит, **логические операции можно комбинировать с другими выражениями**. Разберем на примере. Допустим, мы хотим проверить четность числа. В программировании четность проверяется через остаток от деления на 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 - ``` - - - В одном выражении мы скомбинировали два логических оператора: - - * `==` — проверка равенства - * `%` — арифметический оператор остатка от деления - - **Приоритет арифметических операций выше логических.** Значит, сначала вычисляется арифметическое выражение `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 - ``` - -instructions: | - - Реализуйте метод `isInternationalPhone()`, который проверяет формат указанного телефона. Если телефон начинается с *+*, значит это международный формат. - - ```java - App.isInternationalPhone("89602223423"); // false - App.isInternationalPhone("+79602223423"); // true - ``` - -# tips: -# - | -# Подробнее изучить метод `startsWith()` можно на странице [java.lang.String](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#startsWith(java.lang.String)) diff --git a/modules/45-logic/20-combine-expressions/ru/README.md b/modules/45-logic/20-combine-expressions/ru/README.md index d8e0c1f..6cf520d 100644 --- a/modules/45-logic/20-combine-expressions/ru/README.md +++ b/modules/45-logic/20-combine-expressions/ru/README.md @@ -30,7 +30,6 @@ App.isEven(10); // true App.isEven(3); // false ``` - В одном выражении мы скомбинировали два логических оператора: * `==` — проверка равенства diff --git a/modules/45-logic/20-combine-expressions/ru/data.yml b/modules/45-logic/20-combine-expressions/ru/data.yml index 52ca427..63a7ac2 100644 --- a/modules/45-logic/20-combine-expressions/ru/data.yml +++ b/modules/45-logic/20-combine-expressions/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Комбинирование операций и методов diff --git a/modules/45-logic/25-logical-operators/description.ru.yml b/modules/45-logic/25-logical-operators/description.ru.yml deleted file mode 100644 index afd7e6e..0000000 --- a/modules/45-logic/25-logical-operators/description.ru.yml +++ /dev/null @@ -1,108 +0,0 @@ ---- - -name: Логические операторы -theory: | - - Мы уже умеем писать методы, которые проверяют одиночные условия. В этом уроке мы продолжим работу с методами и научимся строить составные условия. - - Такие навыки пригождаются в довольно распространенных задачах — например, при проверке пароля. Как вы знаете, некоторые сайты при регистрации просят придумать пароль от 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)); - } - ``` - - - Область математики, в которой изучаются логические операторы, называется **булевой алгеброй**. Ниже показаны «таблицы истинности» — по ним можно определить, каким будет результат применения оператора: - - ### Оператор И `&&` - - | 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 | - -instructions: | - - Реализуйте метод `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 - ``` - -tips: - - | - [Булева алгебра](https://ru.wikipedia.org/wiki/Булева_алгебра) - - | - [Конъюнкция](https://ru.wikipedia.org/wiki/Конъюнкция) - - | - [Дизъюнкция](https://ru.wikipedia.org/wiki/Дизъюнкция) - -# definitions: -# - name: "Логические операторы" -# description: "операторы «И» (&&), ИЛИ (||), позволяющие создавать составные логические условия." diff --git a/modules/45-logic/25-logical-operators/ru/README.md b/modules/45-logic/25-logical-operators/ru/README.md index 532d6c0..f9b1144 100644 --- a/modules/45-logic/25-logical-operators/ru/README.md +++ b/modules/45-logic/25-logical-operators/ru/README.md @@ -49,7 +49,6 @@ public static boolean isGoodApartment(int area, String street) { } ``` - Область математики, в которой изучаются логические операторы, называется **булевой алгеброй**. Ниже показаны «таблицы истинности» — по ним можно определить, каким будет результат применения оператора: ### Оператор И `&&` diff --git a/modules/45-logic/25-logical-operators/ru/data.yml b/modules/45-logic/25-logical-operators/ru/data.yml index f2f2bcb..90a94f2 100644 --- a/modules/45-logic/25-logical-operators/ru/data.yml +++ b/modules/45-logic/25-logical-operators/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Логические операторы tips: - | diff --git a/modules/45-logic/28-logical-negation/description.ru.yml b/modules/45-logic/28-logical-negation/description.ru.yml deleted file mode 100644 index 5579451..0000000 --- a/modules/45-logic/28-logical-negation/description.ru.yml +++ /dev/null @@ -1,46 +0,0 @@ ---- - -name: Отрицание - -theory: | - Наряду с конъюнкцией (**И**) и дизъюнкцией (**ИЛИ**), часто используется операция «**отрицание**». - - Отрицание меняет логическое значение на противоположное. В программировании ему соответствует оператор `!`. Если есть метод, проверяющий четность числа, то с помощью отрицания можно выполнить проверку нечетности: - - ```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 - ``` - - Отрицание — мощный инструмент, который позволяет лаконично выражать задуманные правила в коде без необходимости писать новые методы. - -instructions: | - - Реализуйте метод `notToday()`, который проверяет что переданная дата это не сегодняшнее число: - - ```java - // предположим сегодня 2012-11-25 - notToday("2012-11-25"); // false - notToday("2013-11-25"); // true - notToday("2013-09-01"); // true - ``` - - Для получения текущей даты в виде строки: `LocalDate.now().toString()`. - -tips: - - | - [Законы Де Моргана](https://ru.wikipedia.org/wiki/Законы_де_Моргана) diff --git a/modules/45-logic/28-logical-negation/ru/data.yml b/modules/45-logic/28-logical-negation/ru/data.yml index 11a6206..dd24f7f 100644 --- a/modules/45-logic/28-logical-negation/ru/data.yml +++ b/modules/45-logic/28-logical-negation/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Отрицание tips: - | diff --git a/modules/80-conditionals/30-if/description.ru.yml b/modules/80-conditionals/30-if/description.ru.yml deleted file mode 100644 index 4d4eaa4..0000000 --- a/modules/80-conditionals/30-if/description.ru.yml +++ /dev/null @@ -1,51 +0,0 @@ ---- - -name: Условная конструкция (if) - -theory: | - Условные конструкции позволяют выполнять разный код, основываясь на логических проверках. Посмотрим на таком типичном примере: - - * Человек хочет оплатить покупку с карты - * Если на счету есть деньги, то нужная сумма спишется автоматически - * Если денег нет, то операция будет отклонена - - Для примера напишем метод, который определяет тип переданного предложения. Для начала он будет отличать обычные предложения от вопросительных: - - ```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";` — заставит метод вернуть строку и завершиться. - -instructions: | - - Реализуйте метод `getSentenceTone()`, который принимает строку и определяет тон предложения. Если все символы в верхнем регистре, то это вопль — `scream`. В ином случае — нормальное предложение — `normal`. - - Примеры вызова: - - ```java - App.getSentenceTone("Hello"); // "normal" - App.getSentenceTone("WOW"); // "scream" - ``` - - Алгоритм: - - 1. Сгенерируйте строку в верхнем регистре на основе строки-аргумента с помощью `toUpperCase()`. - 2. Сравните её с исходной строкой: - * Если строки равны, значит, строка-аргумент в верхнем регистре - * В ином случае — строка-аргумент не в верхнем регистре - -tips: [] - -definitions: [] diff --git a/modules/80-conditionals/30-if/ru/data.yml b/modules/80-conditionals/30-if/ru/data.yml index b3f2859..11d5777 100644 --- a/modules/80-conditionals/30-if/ru/data.yml +++ b/modules/80-conditionals/30-if/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Условная конструкция (if) tips: [] definitions: [] diff --git a/modules/80-conditionals/40-if-else/description.ru.yml b/modules/80-conditionals/40-if-else/description.ru.yml deleted file mode 100644 index b265a51..0000000 --- a/modules/80-conditionals/40-if-else/description.ru.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- - -name: Конструкция if-else - -theory: | - Условная конструкция `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 не нужен - ``` - -instructions: | - - Реализуйте метод `normalizeUrl()`, который выполняет так называемую нормализацию данных. Он принимает адрес сайта и возвращает его с *https://* в начале. - - Метод принимает адреса в виде *АДРЕС* или *https://АДРЕС*, но всегда возвращает адрес в виде *https://АДРЕС* - - Можно использовать метод `startsWith()` чтобы проверить начинается ли строка с префикса *https://*. А потом на основе этого добавлять или не добавлять *https://*. - - ```java - App.normalizeUrl("google.com"); // "https://google.com" - App.normalizeUrl("https://ai.fi"); // "https://ai.fi" - ``` - -# tips: [] - -# definitions: -# - name: "else" -# description: "способ задать блок кода, который будет выполнен, если условие с `if` не удовлетворено" diff --git a/modules/80-conditionals/40-if-else/ru/data.yml b/modules/80-conditionals/40-if-else/ru/data.yml index 55ce3a4..42973c7 100644 --- a/modules/80-conditionals/40-if-else/ru/data.yml +++ b/modules/80-conditionals/40-if-else/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Конструкция if-else diff --git a/modules/80-conditionals/50-else-if/description.ru.yml b/modules/80-conditionals/50-else-if/description.ru.yml deleted file mode 100644 index 9650431..0000000 --- a/modules/80-conditionals/50-else-if/description.ru.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- - -name: Конструкция else if - -theory: | - В самой полной версии конструкция `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; - } - ``` - - - Теперь все условия выстроены в единую конструкцию. Оператор `else if` — это «если не выполнено предыдущее условие, но выполнено текущее». Получается такая схема: - - - Если последний символ `?`, то "question" - - Иначе, если последний символ `!`, то "exclamation" - - Иначе "general" - - В итоге выполнится только один из блоков кода, относящихся ко всей конструкции `if`. - -instructions: | - - На электронной карте Вестероса, которую реализовал Сэм, союзники Старков отображены зеленым кружком, враги — красным, а нейтральные семьи — серым. - - Напишите для Сэма метод `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" - ``` - -# tips: [] - -# definitions: -# - name: "else if" -# description: "способ задать несколько альтернативных условий" diff --git a/modules/80-conditionals/50-else-if/ru/README.md b/modules/80-conditionals/50-else-if/ru/README.md index 1cb4191..83df36b 100644 --- a/modules/80-conditionals/50-else-if/ru/README.md +++ b/modules/80-conditionals/50-else-if/ru/README.md @@ -40,7 +40,6 @@ public static String getTypeOfSentence(String sentence) } ``` - Теперь все условия выстроены в единую конструкцию. Оператор `else if` — это «если не выполнено предыдущее условие, но выполнено текущее». Получается такая схема: - Если последний символ `?`, то "question" diff --git a/modules/80-conditionals/50-else-if/ru/data.yml b/modules/80-conditionals/50-else-if/ru/data.yml index bbca5e0..79f1f2a 100644 --- a/modules/80-conditionals/50-else-if/ru/data.yml +++ b/modules/80-conditionals/50-else-if/ru/data.yml @@ -1,3 +1,2 @@ --- - name: Конструкция else if diff --git a/modules/80-conditionals/60-ternary-operator/description.ru.yml b/modules/80-conditionals/60-ternary-operator/description.ru.yml deleted file mode 100644 index c7b20c9..0000000 --- a/modules/80-conditionals/60-ternary-operator/description.ru.yml +++ /dev/null @@ -1,65 +0,0 @@ ---- - -name: Тернарный оператор - -theory: | - Посмотрите на определение метода, который возвращает модуль переданного числа: - - ```java - // Если больше нуля, то выдаем само число. Если меньше, то убираем знак - public static int abs(int number) { - if (number >= 0) { - return number; - } - - return -number; - } - - App.abs(10); // 10 - App.abs(-10); // 10 - ``` - - В Java существует конструкция, которая по своему действию аналогична конструкции *if-else*, но при этом является выражением. Она называется **тернарный оператор**. - - Тернарный оператор — единственный в своем роде оператор, требующий три операнда. Он помогает писать меньше кода для простых условных выражений. Наш пример выше с тернарным оператором превращается в три строки кода: - - ```java - public static int abs(int number) { - return number >= 0 ? number : -number; - } - ``` - - Общий шаблон выглядит так: - - ```java - ? : - ``` - - То есть сначала мы записываем логическое выражение, а дальше два разных варианта поведения: - - 1. Если условие истинно, выполняет вариант до двоеточия - 2. Если условие ложно, выполняет вариант после двоеточия - -instructions: | - - Реализуйте метод `convertString()`, который принимает на вход строку и, если первая буква не заглавная, возвращает перевернутый вариант исходной строки. Если первая буква заглавная, то строка возвращается без изменений. Если на вход передана пустая строка, метод должен вернуть пустую строку. - - ```java - App.convertString("Hello"); // "Hello" - App.convertString("hello"); // "olleh" - - // Не забудьте учесть пустую строку! - App.convertString(""); // "" - ``` - - * `StringUtils.reverse()` – переворот строки - * `Character.isUpperCase()` – проверка символа на верхний регистр - - Попробуйте написать два варианта функции: с обычным if-else, и с тернарным оператором. - -tips: [] - -definitions: - - name: Тернарный оператор - description: | - Способ превратить простую условную инструкцию в выражение, например, `number >= 0 ? number : -number`. diff --git a/modules/80-conditionals/60-ternary-operator/ru/data.yml b/modules/80-conditionals/60-ternary-operator/ru/data.yml index 8f1a792..22decf9 100644 --- a/modules/80-conditionals/60-ternary-operator/ru/data.yml +++ b/modules/80-conditionals/60-ternary-operator/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Тернарный оператор tips: [] definitions: diff --git a/modules/80-conditionals/80-switch/description.ru.yml b/modules/80-conditionals/80-switch/description.ru.yml deleted file mode 100644 index 16c6e71..0000000 --- a/modules/80-conditionals/80-switch/description.ru.yml +++ /dev/null @@ -1,136 +0,0 @@ ---- - -name: Конструкция Switch - -theory: | - Многие языки используют не только условную конструкцию `if`, но и `switch` в дополнение к ней. Конструкция `switch` — это специализированная версия `if`, созданная для некоторых особых ситуаций. - - Например, ее стоит использовать там, где есть цепочка `if else` с проверками на равенство: - - ```java - if (status.equals("processing")) { - // Делаем раз - } else if (status.equals("paid")) { - // Делаем два - } else if (status.equals("new")) { - // Делаем три - } else { - // Делаем четыре - } - ``` - - Эта составная проверка обладает одной отличительной чертой: каждая ветка здесь — это проверка значения переменной `status`. Конструкция `switch` позволяет записать этот код короче и выразительнее: - - ```java - switch (status) { - case "processing": - // Делаем раз - break; - case "paid": - // Делаем два - break; - case "new": - // Делаем три - break; - default: // else - // Делаем четыре - } - ``` - - С точки зрения количества элементов, `switch` — довольно сложная конструкция. В нее входят: - - * Внешнее описание с ключевым словом `switch`. В нем два элемента: - - Переменная, по значениям которой `switch` будет выбирать поведение - - Фигурные скобки для вариантов выбора - * Конструкции `case` и `default`, внутри которых описывается поведение для разных значений рассматриваемой переменной. Каждый `case` соответствует `if`, как в примере выше. Здесь `default` — это особая ситуация, соответствующая ветке `else` в условных конструкциях. Как и в случае с `else`, указывать `default` необязательно - * Конструкция `break`, которая предотвращает «проваливание». Если ее не указать, то после выполнения нужного `case`, выполнение перейдет к следующему `case`. Этот цикл будет повторяться до ближайшего `break` или до конца `switch` - - Фигурные скобки в `switch` не определяют блок кода, как это было в других местах. Внутри допускается только тот синтаксис, который показан выше — там можно использовать `case` или `default`. А вот внутри каждого `case` (и `default`) ситуация другая. Здесь можно выполнять любой произвольный код: - - ```java - switch (count) { - case 1: - // Делаем что-то полезное - break; - case 2: - // Делаем что-то полезное - break; - default: - // Что-то делаем - } - ``` - - Иногда результат, полученный внутри `case` — это конец выполнения метода, содержащего `switch`. В таком случае его нужно как-то вернуть наружу. Для решения этой задачи есть два способа. - - Первый способ — можно создать переменную перед `switch`, заполнить ее в `case` и затем вернуть значение этой переменной наружу: - - ```java - class App { - public static String getExplanation(int count) { - // Объявляем переменную - String result; - - // Заполняем - switch(count) { - case 1: - result = "one"; - break; - case 2: - result = "two"; - break; - default: - result = null; - } - - // Возвращаем - return result; - } - } - ``` - - Второй способ проще и короче. Вместо создания переменной можно использовать `case`, внутри которого можно делать обычный возврат из метода. После `return` никакой код не выполняется, так что мы можем избавиться от `break`: - - ```java - class App { - public static String getExplanation(int count) { - - switch(count) { - case 1: - return "one"; - case 2: - return "two"; - default: - return null; - } - } - } - ``` - - https://replit.com/@hexlet/java-basics-switch - - `Switch` хоть и встречается в коде, но технически всегда можно обойтись без него. - - Польза этой конструкции в том, что она лучше выражает намерение программиста, когда нужно проверять конкретные значения переменной. В отличие от блоков `else if`, код со `switch` становится немного длиннее, но читать его гораздо проще. - -instructions: | - - Реализуйте метод `getNumberExplanation()`, который принимает на вход число и возвращает объяснение этого числа. Если для числа нет объяснения, то возвращается `just a number`. Объяснения есть только для следующих чисел: - - * 666 - devil number - * 42 - answer for everything - * 7 - prime number - - Примеры вызова функции: - - ```java - App.getNumberExplanation(8); // just a number - App.getNumberExplanation(666); // devil number - App.getNumberExplanation(42); // answer for everything - App.getNumberExplanation(7); // prime number - ``` - -# tips: -# - | -# [switch](https://developer.mozilla.org/ru/docs/Web/java/Reference/Statements/switch) - -definitions: [] diff --git a/modules/80-conditionals/80-switch/ru/README.md b/modules/80-conditionals/80-switch/ru/README.md index 7b2f35f..197db89 100644 --- a/modules/80-conditionals/80-switch/ru/README.md +++ b/modules/80-conditionals/80-switch/ru/README.md @@ -101,8 +101,6 @@ class App { } ``` -https://replit.com/@hexlet/java-basics-switch - `Switch` хоть и встречается в коде, но технически всегда можно обойтись без него. Польза этой конструкции в том, что она лучше выражает намерение программиста, когда нужно проверять конкретные значения переменной. В отличие от блоков `else if`, код со `switch` становится немного длиннее, но читать его гораздо проще. diff --git a/modules/80-conditionals/80-switch/ru/data.yml b/modules/80-conditionals/80-switch/ru/data.yml index 2215dcc..eac6851 100644 --- a/modules/80-conditionals/80-switch/ru/data.yml +++ b/modules/80-conditionals/80-switch/ru/data.yml @@ -1,4 +1,3 @@ --- - name: Конструкция Switch definitions: [] diff --git a/modules/90-loops/100-while/description.ru.yml b/modules/90-loops/100-while/description.ru.yml deleted file mode 100644 index 666cc1c..0000000 --- a/modules/90-loops/100-while/description.ru.yml +++ /dev/null @@ -1,147 +0,0 @@ ---- - -name: Цикл While - -theory: | - Программы, которые мы пишем во время обучения, становятся все сложнее и объемнее. Они все еще очень далеки от реальных программ, где количество строк кода измеряется десятками и сотнями тысяч, но текущая сложность уже способна заставить напрячься людей без опыта. - - Начиная с этого урока, мы переходим к одной из самых сложных базовых тем в программировании – **циклам**. - - Любые прикладные программы служат очень прагматичным целям. Они помогают управлять сотрудниками, финансами, развлекают в конце концов. Несмотря на различия, все эти программы выполняют заложенные в них алгоритмы, которые очень похожи между собой. - - **Алгоритм** — это последовательность действий или инструкций, которая приводит нас к какому-то ожидаемому результату. Это описание подходит под любую программу, но под алгоритмами обычно понимается что-то более специфичное. - - Представьте себе, что у нас есть книга и мы хотим найти внутри нее какую-то конкретную фразу. Саму фразу мы помним, но не знаем, на какой она странице. Как найти нужную страницу? - - Самый простой и долгий способ — последовательно просматривать книгу до тех пор, пока мы не найдем нужную страницу. В худшем случае придется просмотреть все страницы, но результат мы все равно получим. - - Именно этот процесс и называется **алгоритмом**. Он включает в себя перебор страниц и логические проверки, нашли мы фразу или нет. Количество страниц, которое придется посмотреть, заранее неизвестно, но сам процесс просмотра повторяется из раза в раз совершенно одинаковым образом. - - Для выполнения повторяющихся действий как раз и нужны циклы. Каждый такой повтор называется **итерацией**. - - Допустим, мы хотим написать метод. Он должен выводить на экран все числа от 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); - ``` - -
-  1
-  2
-  3
-  finished!
-  
- - - В коде метода использован цикл `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) { - // Что-то делаем - } - ``` - - Подведем итог. Когда все же нужны циклы, а когда можно обойтись без них? Невозможно обойтись без циклов тогда, когда алгоритм решения задачи требует повторения каких-то действий, при этом количество этих операций заранее неизвестно. Так и было в примере с книгой, который мы рассматривали в начале урока. - -instructions: | - - Модифицируйте метод `printNumbers()` так, чтобы он выводил числа в обратном порядке. Для этого нужно идти от верхней границы к нижней. То есть счётчик должен быть инициализирован максимальным значением, а в теле цикла его нужно уменьшать до нижней границы. - - Пример вызова и вывода: - - ```java - printNumbers(4); - ``` - -
-    4
3
2
1
finished! -
- -# tips: -# - | -# [Цикл while](https://developer.mozilla.org/ru/docs/Web/java/Reference/Statements/while) - -definitions: - - name: Цикл While - description: инструкция для повторения кода, пока удовлетворяется какое-то условие. diff --git a/modules/90-loops/100-while/ru/README.md b/modules/90-loops/100-while/ru/README.md index 9194243..38796e4 100644 --- a/modules/90-loops/100-while/ru/README.md +++ b/modules/90-loops/100-while/ru/README.md @@ -48,7 +48,6 @@ App.printNumbers(3); finished! - В коде метода использован цикл `while`. Он состоит из трех элементов: * **Ключевое слово** `while`. Несмотря на схожесть с вызовом методов, это не вызов метода diff --git a/modules/90-loops/100-while/ru/data.yml b/modules/90-loops/100-while/ru/data.yml index bb1f837..9f57887 100644 --- a/modules/90-loops/100-while/ru/data.yml +++ b/modules/90-loops/100-while/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Цикл While definitions: - name: Цикл While diff --git a/modules/90-loops/150-aggregation-numbers/description.ru.yml b/modules/90-loops/150-aggregation-numbers/description.ru.yml deleted file mode 100644 index ddb3d67..0000000 --- a/modules/90-loops/150-aggregation-numbers/description.ru.yml +++ /dev/null @@ -1,104 +0,0 @@ ---- - -name: Агрегация данных (Числа) - -theory: | - В программировании есть отдельный класс задач, который не может обойтись без циклов — он называется **агрегированием данных**. - - К таким задачам относятся поиск: - - * Максимального значения - * Минимального значения - * Суммы - * Среднего арифметического - - Их главная особенность в том, что результат зависит от всего набора данных. Для расчета суммы нужно сложить **все** числа, для вычисления максимального нужно сравнить **все** числа. - - С этой темой хорошо знакомы все, кто занимаются числами. Например, с такими задачами часто работают бухгалтеры или маркетологи в таблицах наподобие 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"` - -instructions: | - - Реализуйте метод `multiplyNumbersFromRange()`, который перемножает числа в указанном диапазоне включая границы диапазона. Пример вызова: - - ```java - App.multiplyNumbersFromRange(1, 5); // 1 * 2 * 3 * 4 * 5 = 120 - App.multiplyNumbersFromRange(2, 3); // 2 * 3 = 6 - App.multiplyNumbersFromRange(6, 6); // 6 - ``` - -tips: [] diff --git a/modules/90-loops/150-aggregation-numbers/ru/README.md b/modules/90-loops/150-aggregation-numbers/ru/README.md index 0fe39f3..20f5c4c 100644 --- a/modules/90-loops/150-aggregation-numbers/ru/README.md +++ b/modules/90-loops/150-aggregation-numbers/ru/README.md @@ -52,8 +52,6 @@ public static int sumNumbersFromRange(int start, int finish) { } ``` -https://replit.com/@hexlet/java-basics-loops-using-1 - Общая структура цикла здесь стандартна: * Счетчик, который инициализируется начальным значением диапазона diff --git a/modules/90-loops/150-aggregation-numbers/ru/data.yml b/modules/90-loops/150-aggregation-numbers/ru/data.yml index a7b6be7..f4a7d9c 100644 --- a/modules/90-loops/150-aggregation-numbers/ru/data.yml +++ b/modules/90-loops/150-aggregation-numbers/ru/data.yml @@ -1,4 +1,3 @@ --- - name: Агрегация данных (Числа) tips: [] diff --git a/modules/90-loops/200-aggregation-strings/description.ru.yml b/modules/90-loops/200-aggregation-strings/description.ru.yml deleted file mode 100644 index 1566819..0000000 --- a/modules/90-loops/200-aggregation-strings/description.ru.yml +++ /dev/null @@ -1,52 +0,0 @@ ---- - -name: Агрегация данных (Строки) - -theory: | - Агрегация применяется не только к числам, но и к строкам. - - При агрегации строка формируется динамически, то есть заранее неизвестно, какого она размера и что будет содержать. Представьте себе метод, который умеет умножать строку — то есть он повторяет ее указанное количество раз: - - ```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" - ``` - -instructions: | - - Реализуйте метод `joinNumbersFromRange()`, который объединяет все числа из диапазона в строку: - - ```java - App.joinNumbersFromRange(1, 1); // "1" - App.joinNumbersFromRange(2, 3); // "23" - App.joinNumbersFromRange(5, 10); // "5678910" - ``` - -tips: [] diff --git a/modules/90-loops/200-aggregation-strings/ru/data.yml b/modules/90-loops/200-aggregation-strings/ru/data.yml index 5c02db1..4ed1fe3 100644 --- a/modules/90-loops/200-aggregation-strings/ru/data.yml +++ b/modules/90-loops/200-aggregation-strings/ru/data.yml @@ -1,4 +1,3 @@ --- - name: Агрегация данных (Строки) tips: [] diff --git a/modules/90-loops/250-iteration-over-strings/description.ru.yml b/modules/90-loops/250-iteration-over-strings/description.ru.yml deleted file mode 100644 index 9796357..0000000 --- a/modules/90-loops/250-iteration-over-strings/description.ru.yml +++ /dev/null @@ -1,48 +0,0 @@ ---- - -name: Обход строк - -theory: | - Циклы подходят не только для обработки чисел, но и при работе со строками. В первую очередь благодаря возможности получить конкретный символ по его индексу. Ниже пример кода, который распечатывает буквы каждого слова на отдельной строке: - - ```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` - - Оба способа приводят к одному результату. - -instructions: | - - Реализуйте статический метод `App.printReversedNameBySymbol()`, который печатает переданное слово посимвольно, как в примере из теории, но делает это в обратном порядке. - - ```java - var name = "Arya"; - App.printReversedNameBySymbol(name); - // 'a' - // 'y' - // 'r' - // 'A' - ``` - -tips: [] diff --git a/modules/90-loops/250-iteration-over-strings/ru/data.yml b/modules/90-loops/250-iteration-over-strings/ru/data.yml index c43b73d..8f2c0f7 100644 --- a/modules/90-loops/250-iteration-over-strings/ru/data.yml +++ b/modules/90-loops/250-iteration-over-strings/ru/data.yml @@ -1,4 +1,3 @@ --- - name: Обход строк tips: [] diff --git a/modules/90-loops/300-conditions-inside-loops/description.ru.yml b/modules/90-loops/300-conditions-inside-loops/description.ru.yml deleted file mode 100644 index 9dbb357..0000000 --- a/modules/90-loops/300-conditions-inside-loops/description.ru.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- - -name: Условия внутри тела цикла - -theory: | - Тело цикла, как и тело метода — это место выполнения инструкций. Значит, мы можем использовать внутри него все изученное ранее — в том числе условные конструкции. - - Рассмотрим метод, который считает, сколько раз входит буква в предложение: - - ```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` увеличивается только в том случае, когда текущий рассматриваемый символ совпадает с ожидаемым. В остальном — это типичный агрегатный метод, который возвращает количество нужных символов вызываемому коду. - -instructions: | - - Метод из теории учитывает регистр букв. То есть `A` и `a` с его точки зрения разные символы. Реализуйте вариант этого же метода, так чтобы регистр букв был не важен: - - ```java - App.countChars("HexlEt", 'e'); // 2 - App.countChars("HexlEt", 'E'); // 2 - ``` - - * `Character.toLowerCase()` – переводит символ в нижний регистр - -tips: [] diff --git a/modules/90-loops/300-conditions-inside-loops/ru/README.md b/modules/90-loops/300-conditions-inside-loops/ru/README.md index 221ebaf..050f308 100644 --- a/modules/90-loops/300-conditions-inside-loops/ru/README.md +++ b/modules/90-loops/300-conditions-inside-loops/ru/README.md @@ -32,8 +32,6 @@ public static int countChars(String str, char ch) { } ``` -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 index caa103c..bfc9409 100644 --- a/modules/90-loops/300-conditions-inside-loops/ru/data.yml +++ b/modules/90-loops/300-conditions-inside-loops/ru/data.yml @@ -1,4 +1,3 @@ --- - name: Условия внутри тела цикла tips: [] diff --git a/modules/90-loops/350-build-strings/description.ru.yml b/modules/90-loops/350-build-strings/description.ru.yml deleted file mode 100644 index 4f5eee0..0000000 --- a/modules/90-loops/350-build-strings/description.ru.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- - -name: Формирование строк в циклах - -theory: | - Еще одно использование циклов — **формирование строк**. Подобная задача нередко встречается в программировании. Она сводится к обычной агрегации через конкатенацию. - - Есть одна задача, которая популярна на собеседованиях — это **переворот строки**. Ее можно решить множеством разных способов, но именно посимвольный перебор считается базовым: - - ```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 - - Важно прочувствовать, как собирается сама строка — каждый следующий символ прикрепляется к результирующей строке слева, и в итоге строка оказывается перевернута. - -instructions: | - - Реализуйте такой же метод `reverse()`, но выполняющий обход строки не с первого элемента по последний, а наоборот, от последнего к первому. Общая структура функции при этом останется такой же. Изменится начальный индекс, условие окончания цикла, сборка новой строки и формирование нового индекса в цикле. - -tips: [] diff --git a/modules/90-loops/350-build-strings/ru/README.md b/modules/90-loops/350-build-strings/ru/README.md index ffcd3e6..df4f1da 100644 --- a/modules/90-loops/350-build-strings/ru/README.md +++ b/modules/90-loops/350-build-strings/ru/README.md @@ -28,5 +28,4 @@ App.reverse(name); // "narB" App.reverse(""); // "" ``` - Важно прочувствовать, как собирается сама строка — каждый следующий символ прикрепляется к результирующей строке слева, и в итоге строка оказывается перевернута. diff --git a/modules/90-loops/350-build-strings/ru/data.yml b/modules/90-loops/350-build-strings/ru/data.yml index ceb034f..db622ea 100644 --- a/modules/90-loops/350-build-strings/ru/data.yml +++ b/modules/90-loops/350-build-strings/ru/data.yml @@ -1,4 +1,3 @@ --- - name: Формирование строк в циклах tips: [] diff --git a/modules/90-loops/400-syntax-sugar/description.ru.yml b/modules/90-loops/400-syntax-sugar/description.ru.yml deleted file mode 100644 index 103846e..0000000 --- a/modules/90-loops/400-syntax-sugar/description.ru.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- - -name: Синтаксический сахар - -theory: | - Подобные конструкции `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"` - -instructions: | - - Реализуйте статический метод `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" - ``` - -tips: [] diff --git a/modules/90-loops/400-syntax-sugar/ru/data.yml b/modules/90-loops/400-syntax-sugar/ru/data.yml index 879b105..84ecd90 100644 --- a/modules/90-loops/400-syntax-sugar/ru/data.yml +++ b/modules/90-loops/400-syntax-sugar/ru/data.yml @@ -1,4 +1,3 @@ --- - name: Синтаксический сахар tips: [] diff --git a/modules/90-loops/450-mutators/App.java b/modules/90-loops/450-mutators/App.java index 1618fed..eb0a0c7 100644 --- a/modules/90-loops/450-mutators/App.java +++ b/modules/90-loops/450-mutators/App.java @@ -10,10 +10,10 @@ public static String makeItFunny(String str, int n) { } else { result = result + current; } - i++; - } + i++; + } - return result; - // END -} + return result; + // END + } } diff --git a/modules/90-loops/450-mutators/description.ru.yml b/modules/90-loops/450-mutators/description.ru.yml deleted file mode 100644 index 40551e3..0000000 --- a/modules/90-loops/450-mutators/description.ru.yml +++ /dev/null @@ -1,72 +0,0 @@ ---- - -name: Инкремент и декремент - -theory: | - Из языка Си в 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`. Понять такой код почти невозможно. - - Рекомендации по использованию: - - * Никогда не смешайте операции без побочных эффектов и операциями с побочными эффектами. То же самое касается и методов - * Используйте инкремент и декремент только там, где нет разницы между префиксным и постфиксным вариантом — отдельно от всего, на отдельной строчке кода - -instructions: | - - Реализуйте статический метод `App.makeItFunny()`, который принимает на вход строку и возвращает её копию, у которой каждый n-ный элемент переведен в верхний регистр. n – задается на входе в функцию. Для определения каждого n-ного элемента понадобится остаток от деления `%`. Подумайте, как его можно использовать. - - ```java - var text = "I never look back"; - // Каждый третий элемент - App.makeItFunny(text, 3); // "I NevEr LooK bAck" - ``` - -tips: - - | - [Остаток от деления (%)](https://ru.wikipedia.org/wiki/Деление_с_остатком) diff --git a/modules/90-loops/450-mutators/ru/EXERCISE.md b/modules/90-loops/450-mutators/ru/EXERCISE.md index 8c66865..d1f3121 100644 --- a/modules/90-loops/450-mutators/ru/EXERCISE.md +++ b/modules/90-loops/450-mutators/ru/EXERCISE.md @@ -1,5 +1,5 @@ -Реализуйте статический метод `App.makeItFunny()`, который принимает на вход строку и возвращает её копию, у которой каждый n-ный элемент переведен в верхний регистр. n – задается на входе в метод. Для определения каждого n-ного элемента понадобится остаток от деления `%`. Подумайте, как его можно использовать. +Реализуйте статический метод `App.makeItFunny()`, который принимает на вход строку и возвращает её копию, у которой каждый n-ный элемент переведен в верхний регистр. n – задается на входе в функцию. Для определения каждого n-ного элемента понадобится остаток от деления `%`. Подумайте, как его можно использовать. ```java var text = "I never look back"; diff --git a/modules/90-loops/450-mutators/ru/data.yml b/modules/90-loops/450-mutators/ru/data.yml index 2b12370..f16c95a 100644 --- a/modules/90-loops/450-mutators/ru/data.yml +++ b/modules/90-loops/450-mutators/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Инкремент и декремент tips: - | diff --git a/modules/90-loops/500-return-from-loops/description.ru.yml b/modules/90-loops/500-return-from-loops/description.ru.yml deleted file mode 100644 index e10e9e1..0000000 --- a/modules/90-loops/500-return-from-loops/description.ru.yml +++ /dev/null @@ -1,62 +0,0 @@ ---- - -name: Возврат из циклов -theory: | - - Работа с циклами обычно сводится к двум сценариям: - - 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`. - - И только если цикл отработал целиком, можно сделать вывод, что число — простое, так как не было найдено ни одного числа, которое делит число без остатка. - -instructions: | - - Реализуйте статический метод `App.hasChar()`, который проверяет (с учётом регистра), содержит ли строка указанную букву. Метод принимает два параметра: - - * Строка - * Буква для поиска - - ```java - App.hasChar("Renly", 'R'); // true - App.hasChar("Renly", 'r'); // false - App.hasChar("Tommy", 'm'); // true - App.hasChar("Tommy", 'd'); // false - ``` - -tips: - - | - [Список простых чисел](https://ru.wikipedia.org/wiki/Список_простых_чисел) diff --git a/modules/90-loops/500-return-from-loops/ru/data.yml b/modules/90-loops/500-return-from-loops/ru/data.yml index a36f907..7abc7ba 100644 --- a/modules/90-loops/500-return-from-loops/ru/data.yml +++ b/modules/90-loops/500-return-from-loops/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Возврат из циклов tips: - | diff --git a/modules/90-loops/550-for/description.ru.yml b/modules/90-loops/550-for/description.ru.yml deleted file mode 100644 index 111ae07..0000000 --- a/modules/90-loops/550-for/description.ru.yml +++ /dev/null @@ -1,50 +0,0 @@ ---- - -name: Цикл For - -theory: | - Цикл `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; - } - ``` - - - Этот код можно описать так: - - > Цикл с индексом `i` повторяется, пока `i < str.length()`, а также после каждого шага увеличивает `i` на 1 - - В определении цикла `for` есть: - - 1. Начальное значение счетчика. Этот код выполняется ровно один раз перед первой итерацией - 2. Предикат — условие повторения циклов. Выполняется на каждой итерации. Точно так же как и в `while` - 3. Описание изменения счетчика. Этот код выполняется в конце каждой итерации - - В остальном принцип работы точно такой же, как у цикла `while`. - -instructions: | - - Сэмвелл обнаружил, что его сообщения перехватываются в замке «Близнецы» и там читаются. Из-за этого их атаки перестали быть внезапными. Немного подумав, он разработал программу, которая бы шифровала сообщения по следующему алгоритму. Она бы брала текст и переставляла в нем каждые два подряд идущих символа. - - ```java - App.encrypt("move"); // "omev" - App.encrypt("attack"); // "taatkc" - // Если число символов нечётное - // то последний символ остается на своем месте - App.encrypt("go!"); // "og!" - ``` - - Реализуйте статический метод `App.encrypt()`, который принимает на вход исходное сообщение и возвращает зашифрованное. - -tips: [] diff --git a/modules/90-loops/550-for/ru/README.md b/modules/90-loops/550-for/ru/README.md index 8d97bc1..ec71522 100644 --- a/modules/90-loops/550-for/ru/README.md +++ b/modules/90-loops/550-for/ru/README.md @@ -15,7 +15,6 @@ public static String reverseString(String str) { } ``` - Этот код можно описать так: > Цикл с индексом `i` повторяется, пока `i < str.length()`, а также после каждого шага увеличивает `i` на 1 diff --git a/modules/90-loops/550-for/ru/data.yml b/modules/90-loops/550-for/ru/data.yml index 606151c..1985e4a 100644 --- a/modules/90-loops/550-for/ru/data.yml +++ b/modules/90-loops/550-for/ru/data.yml @@ -1,4 +1,3 @@ --- - name: Цикл For tips: [] diff --git a/modules/90-loops/description.en.yml b/modules/90-loops/description.en.yml deleted file mode 100644 index bed8737..0000000 --- a/modules/90-loops/description.en.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -name: Loops -description: | -  Any code can be repeated tens, thousands, millions of times. And in combination with other tools we know — variables and conditions — this opens up many possibilities for building programs and complex systems.