Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 42 additions & 28 deletions modules/45-logic/10-bool-type/ru/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
Кроме арифметических операций, из школьной математики нам известны еще и операции сравнения, например:
Кроме арифметических операций, из школьной математики нам известны еще и операции сравнения, например `5 > 4` или `3 < 1`. Они есть и в программировании. Сравнения часто применяются в реальных задачах, связанных с числами. Когда мы оформляем покупку в интернет-магазине, система проверяет, хватает ли у пользователя денег на счете. Если сумма на счете больше или равна цене товара, заказ подтверждается. При нехватке средств появляется сообщение об ошибке.

```text
5 > 4
```
## Сравнение в программировании

Это звучит как вопрос: «Пять больше четырех?». В данном случае, ответ «да». В других случаях, ответом может быть «нет», например, для такого выражения:
Начнем с примера, в котором сравниваются два числа. Результат сравнения выводим на экран:

```text
3 < 1
```java
System.out.println(5 > 4); // => true
System.out.println(4 > 4); // => false
```

Операции сравнения не имеют привязки к числам. Сравнивать можно практически что угодно — например, строки. Когда мы входим на какой-то сайт, внутри происходит сравнение введенного логина и пароля с теми, какие есть в базе. Если совпадение есть, то происходит авторизация.
Результат сравнения — это значение типа `boolean`. У этого типа всего два возможных варианта, `true` и `false`. Это специальные значения языка, их можно выводить напрямую:

Языки программирования адаптировали все математические операции сравнения практически в неизменном виде. Единственное серьезное отличие – **операторы равенства и неравенства**.
```java
System.out.println(true); // => true
System.out.println(false); // => false
```

В математике для этого используется обычное равно `=`, но в программировании такое встречается нечасто. Во многих языках символ `=` используется для присваивания значений переменным, поэтому для сравнения взяли `==`.
На практике их редко используют так напрямую, но на их основе строится логика поведения программы. Мы сталкиваемся с этим каждый день, когда вводим пинкоды и пароли, когда выполняем действия с разными возможными исходами. Все эти варианты прописаны внутри программы в виде условных выражений. Программа рассуждает примерно так: *если так, делай раз, если по-другому, делай два*.

Список операций сравнения в Java:
В Java доступны следующие операции сравнения:

* `<` — меньше
* `<=` — меньше или равно
Expand All @@ -25,40 +27,52 @@
* `==` — равно
* `!=` — не равно

Посмотрим на пару примеров логических операций:
Языки программирования адаптировали все математические операции сравнения в неизменном виде, кроме операторов равенства и неравенства. В математике для равенства используется обычное `=`, но в программировании символ `=` присваивает переменным значения. Поэтому в Java сравнивают с помощью `==`. Несколько примеров с выводом результата на экран:

```text
5 > 4
password == text
```java
System.out.println(5 >= 3); // => true
System.out.println(7 < 0); // => false
System.out.println(5 > 5); // => false
System.out.println(5 >= 5); // => true
System.out.println(2 == 5); // => false
System.out.println(2 != 5); // => true
```

Оба примера — это выражения. Результат вычисления этих выражений — это одно из двух специальных значений

* `true` — «истина»
* `false`— «ложь»

Это новый для нас тип данных — **boolean**. Он содержит всего лишь два этих значения. Так выглядит пример кода с ним:
Любую операцию сравнения можно сохранить в переменную типа `boolean`, а потом вывести:

```java
var result = 5 > 4;
boolean 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` вернет этот результат:
Единственной строкой метода мы пишем "вернуть то значение, которое получится в результате сравнения `age < 1`". В зависимости от пришедшего аргумента сравнение будет либо истинным (`true`), либо ложным (`false`). Метод вернет этот результат:

```java
System.out.println(App.isInfant(3)); // => false
System.out.println(App.isInfant(1)); // => false
System.out.println(App.isInfant(0)); // => true
```

## Предикаты

Когда методы возвращают результат сравнения, они отвечают на вопрос "да" или "нет". Такие методы называют **предикатами**. Их узнают по тому, что они возвращают логическое значение `true` или `false`. Часто в названии предиката стоит вопрос или утверждение, которое можно проверить (`is`, `has`, `can`, `was`). Вот метод, проверяющий, отрицательное ли число:

```java
public static boolean isNegative(int number) {
// Проверяем, меньше ли число нуля
return number < 0;
}

System.out.println(App.isNegative(-5)); // => true
System.out.println(App.isNegative(7)); // => false
```

Метод `isNegative` собирает условие внутри, а наружу отдает короткий ответ. Так вычисление прячется за понятным именем.
4 changes: 4 additions & 0 deletions modules/45-logic/10-bool-type/ru/data.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
---
name: Логический тип
tips:
- >
[Тип boolean в
Java](https://docs.oracle.com/javase/specs/jls/se21/html/jls-4.html#jls-4.2.5)
definitions:
- name: Логический тип (boolean)
description: 'тип данных с двумя возможными значениями: true (истина) и false (ложь).'
80 changes: 48 additions & 32 deletions modules/45-logic/25-logical-operators/ru/README.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,86 @@

Мы уже умеем писать методы, которые проверяют одиночные условия. В этом уроке мы продолжим работу с методами и научимся строить составные условия.

Такие навыки пригождаются в довольно распространенных задачахнапример, при проверке пароля. Как вы знаете, некоторые сайты при регистрации просят придумать пароль от 8 до 20 символов в длину.
Такие навыки пригождаются в распространенных задачах, например при проверке пароля. Некоторые сайты при регистрации просят придумать пароль от 8 до 20 символов в длину.

В математике мы бы написали `8 <= x <= 20`, но в Java такой трюк не пройдет. Нам придется сделать два отдельных логических выражения и соединить их специальным оператором «И».
В математике мы записали бы это как `8 <= x <= 20`, но в Java такой трюк не пройдет. Нам придется сделать два отдельных логических выражения и соединить их специальным оператором "И".

Напишем метод, который принимает пароль и говорит, соответствует ли он условиям:
Напишем метод, который принимает пароль и говорит, соответствует ли он условиям. Результат выводим на экран:

```java
// Пароль длиннее 8 символов **И** пароль короче 20 символов
// Пароль длиннее 8 символов И пароль короче 20 символов
public static boolean isCorrectPassword(String password) {
var length = password.length();
return length > 8 && length < 20;
}

isCorrectPassword("qwerty"); // false
isCorrectPassword("qwerty1234"); // true
System.out.println(App.isCorrectPassword("qwerty")); // => false
System.out.println(App.isCorrectPassword("qwerty1234")); // => true
```

Оператор `&&` означает «И». В этом случае выражение считается истинным, только если истинен каждый *операнд*каждое из составных выражений. Другими словами, `&&` означает «и то, и другое».
Оператор `&&` означает "И". В математической логике это называют конъюнкцией. Все выражение считается истинным, только когда истинен каждый **операнд**, то есть каждое из составных выражений. Другими словами, `&&` означает "и то, и другое". Приоритет этого оператора ниже, чем приоритет операторов сравнения, поэтому выражение `length > 8 && length < 20` отрабатывает правильно без скобок.

Приоритет этого оператора ниже, чем приоритет операторов сравнения, поэтому выражение отрабатывает правильно без скобок.
Кроме `&&` часто используется оператор `||`, который означает "ИЛИ" (дизъюнкция). Он читается как "или то, или другое, или оба". Выражение `a || b` считается истинным, когда истинен хотя бы один из операндов или когда истинны оба. В остальных случаях выражение ложное.

Кроме `&&` часто используется оператор `||` — «ИЛИ». Он означает «или то, или другое, или оба». Операторы можно комбинировать в любом количестве и любой последовательности. Единственное исключение — когда одновременно встречаются `&&` и `||`, то приоритет лучше задавать скобками:
Посмотрим на метод, который определяет, положена ли человеку скидка. Скидку дают тем, кто младше 18 лет, или студентам:

```java
a && b || c; // Без скобок сложно понять приоритет
a && (b || c) // Приоритет очевиден
public static boolean hasDiscount(int age, boolean isStudent) {
return age < 18 || isStudent;
}

System.out.println(App.hasDiscount(15, false)); // => true (младше 18)
System.out.println(App.hasDiscount(25, true)); // => true (студент)
System.out.println(App.hasDiscount(15, true)); // => true (оба условия)
System.out.println(App.hasDiscount(25, false)); // => false
```

Рассмотрим еще один пример. Представим, что мы хотим купить квартиру, которая удовлетворяет таким условиям:
Операторы можно комбинировать в любом количестве и любой последовательности. Когда в коде одновременно встречаются `&&` и `||`, приоритет лучше задавать скобками:

> Больше 100 м^2 на любой улице **ИЛИ** больше 80 м^2 на центральной улице *Main Street*
```java
a && b || c; // Без скобок сложно понять приоритет
a && (b || c); // Со скобками понятно, что к чему относится
```

Напишем метод, проверяющий квартиру. Он принимает два параметра: площадь и название улицы:
Рассмотрим еще один пример. Представим, что мы хотим купить квартиру, которая удовлетворяет таким условиям:

```java
isGoodApartment(91, "Queens Street"); // false
isGoodApartment(78, "Queens Street"); // false
isGoodApartment(70, "Main Street"); // false
> Больше 100 м² на любой улице **ИЛИ** больше 80 м² на центральной улице *Main Street*

isGoodApartment(120, "Queens Street"); // true
isGoodApartment(120, "Main Street"); // true
isGoodApartment(80, "Main Street"); // true
Напишем метод, проверяющий квартиру. Он принимает два параметра, площадь и название улицы. Строки сравниваем через `.equals(...)`, потому что для строк это правильный способ проверки на равенство:

```java
public static boolean isGoodApartment(int area, String street) {
return area >= 100 || (area >= 80 && "Main Street".equals(street));
return area >= 100 || (area >= 80 && "Main Street".equals(street));
}

System.out.println(App.isGoodApartment(91, "Queens Street")); // => false
System.out.println(App.isGoodApartment(78, "Queens Street")); // => false
System.out.println(App.isGoodApartment(70, "Main Street")); // => false

System.out.println(App.isGoodApartment(120, "Queens Street")); // => true
System.out.println(App.isGoodApartment(120, "Main Street")); // => true
System.out.println(App.isGoodApartment(80, "Main Street")); // => true
```

Область математики, в которой изучаются логические операторы, называется **булевой алгеброй**. Ниже показаны «таблицы истинности» — по ним можно определить, каким будет результат применения оператора:
Скобки вокруг `area >= 80 && "Main Street".equals(street)` задают приоритет. Без них правило прочиталось бы иначе, а так сразу видно, какая часть относится к какому оператору.

## Таблицы истинности

Область математики, в которой изучаются логические операторы, называется булевой алгеброй. **Таблицы истинности** показывают, каким будет результат при применении каждого оператора.

### Оператор И `&&`

| A | B | A && B |
| ----- | ----- | ------- |
| TRUE | TRUE | **TRUE** |
| TRUE | FALSE | FALSE |
| FALSE | TRUE | FALSE |
| FALSE | FALSE | FALSE |
| true | true | **true** |
| true | false | false |
| false | true | false |
| false | false | false |

### Оператор ИЛИ `||`

| A | B | A &VerticalSeparator;&VerticalSeparator; B |
| ----- | ----- | -------- |
| TRUE | TRUE | **TRUE** |
| TRUE | FALSE | **TRUE** |
| FALSE | TRUE | **TRUE** |
| FALSE | FALSE | FALSE |
| true | true | **true** |
| true | false | **true** |
| false | true | **true** |
| false | false | false |
5 changes: 5 additions & 0 deletions modules/45-logic/25-logical-operators/ru/data.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ tips:
[Конъюнкция](https://ru.wikipedia.org/wiki/Конъюнкция)
- |
[Дизъюнкция](https://ru.wikipedia.org/wiki/Дизъюнкция)
definitions:
- name: Логические операторы
description: >-
операторы "И" (`&&`) и "ИЛИ" (`||`), позволяющие создавать составные
логические условия.
Loading
Loading