Към съдържанието
wannacode

Условия

Проблем

Доставката, която не трябваше да я има

Онлайн магазин обещава безплатна доставка за поръчки от 50 € нагоре. Под 50 € доставката е 4,99 €. Поръчката е 62 €, а програмата пак добавя доставка:

double total = 62.0;
double shipping = 4.99;
System.out.println("За плащане: " + (total + shipping) + " €");
Изход
За плащане: 66.99 €

Програмата изпълнява всеки ред, един след друг. Тук трябва да избере: един ред при едно положение, друг при друго.

Идеята

Сравнението отговаря с да или не

Първо програмата трябва да попита: сумата 50 € или повече ли е? За това има оператори за сравнение. Отговорът им не е число, а true (вярно) или false (невярно): стойност от тип boolean.

double total = 62.0;
System.out.println(total >= 50);
System.out.println(total == 50);
System.out.println(total != 50);
Изход
true
false
true
Пишеш Пита
a > b, a < b по-голямо, по-малко
a >= b, a <= b по-голямо или равно, по-малко или равно
a == b равни ли са
a != b различни ли са

Внимавай: == сравнява, а = записва стойност. total == 50 пита дали сумата е 50, а total = 50 я прави 50.

Текст в Java не се сравнява с ==, а с .equals:

String answer = "да";
boolean yes = answer.equals("да");
System.out.println(yes);
Изход
true

== при текст понякога работи, понякога не. Защо, ще разберем в урока за текста. Дотогава: текст винаги с .equals.

По-точно, за любопитните

Дробни числа рядко са точно равни. Компютърът пази 0.1 и 0.2 приблизително, затова сумата им не е точно 0.3:

System.out.println(0.1 + 0.2 == 0.3);
System.out.println(0.1 + 0.2);
Изход
false
0.30000000000000004

За дробни числа питай дали са достатъчно близо: Math.abs(a - b) < 0.000001. Сравнения с > и < нямат този проблем.

Идеята

if и else: единият от двата пътя

Сега програмата може да избира. if проверява условието в скобите. Ако е вярно, изпълнява блока след него. Ако не е, изпълнява блока след else:

double total = 62.0;
double shipping;
if (total >= 50) {
shipping = 0;
} else {
shipping = 4.99;
}
System.out.println("Доставка: " + shipping + " €");
Изход
Доставка: 0.0 €

При поръчка от 18,50 € същата програма печата Доставка: 4.99 €. Изпълнява се само единият блок, никога и двата.

else не е задължителен. Без него, ако условието не е вярно, блокът просто се прескача и програмата продължава след него.

По-точно, за любопитните
  • Ако блокът е един ред, скобите { } могат да се изпуснат. Не го прави: щом добавиш втори ред, той ще е извън if, а отстъпът ще те лъже, че е вътре.
  • Условието трябва да е boolean. Затова if (total) не се компилира, а if (total = 50) също: = записва и дава число, не да или не.

Пробвай

Поръчка над наличното

В склада има 3 бройки, а клиентът поръчва 5.

Какво ще отпечата програмата?

int stock = 3;
int ordered = 5;
if (ordered > stock) {
System.out.println("Няма достатъчно");
ordered = stock;
}
System.out.println("Изпращаме " + ordered + " бр.");
Отговор

Идеята

else if: повече от два пътя

Учителят превръща точките от теста в оценка. Възможностите са четири. Слагаш if след else:

int points = 76;
if (points >= 90) {
System.out.println("Отличен");
} else if (points >= 75) {
System.out.println("Много добър");
} else if (points >= 50) {
System.out.println("Добър");
} else {
System.out.println("Слаб");
}
Изход
Много добър

Проверките вървят отгоре надолу. Изпълнява се първият клон с вярно условие, а останалите се прескачат. 76 не е >= 90, но е >= 75, затова е „Много добър“. До >= 50 не се стига, макар и то да е вярно.

Затова редът има значение: най-строгото условие е първо. Ако points >= 50 беше най-отгоре, всеки с 50 и повече точки щеше да е „Добър“.

int points = 76;
if (points >= 90) {
System.out.println("Отличен");
} else if (points >= 75) {
System.out.println("Много добър");
} else if (points >= 50) {
System.out.println("Добър");
} else {
System.out.println("Слаб");
}
Стъпка по стъпка, с думи
  1. points е 76.
  2. 76 >= 90? Не. Клонът „Отличен“ се прескача.
  3. 76 >= 75? Да. Влизаме в клона „Много добър“.
  4. Отпечатва се „Много добър“.
  5. И 76 >= 50 е вярно, но не се проверява: веригата спира при първия верен клон.

Пробвай

Намери грешката

Отличен е всеки с 90 точки и повече. Ученик с точно 90 точки получава „Много добър“. На кой ред е грешката?

Избери реда с грешката.

Идеята

И, или, не

Киното дава билет с отстъпка на деца и на студенти. Условията са две, а стига едното. Свързваш ги с логически оператори:

int age = 16;
boolean student = false;
if (age < 18 || student) {
System.out.println("Билет с отстъпка: 6 €");
} else {
System.out.println("Билет: 10 €");
}
Изход
Билет с отстъпка: 6 €
  • a && b е вярно, когато и двете са верни („и“).
  • a || b е вярно, когато поне едното е вярно („или“).
  • !a е вярно, когато a не е вярно („не“): !student.

Безплатна доставка над 50 € и само в града е total >= 50 && inCity. Числото е между 1 и 12, ако month >= 1 && month <= 12. Записът 1 <= month <= 12 от математиката тук не работи.

По-точно, за любопитните
  • Ако левият операнд вече решава отговора, десният не се проверява: при false && … и при true || …. Това се казва кратко съединяване и понякога пази от грешка: count != 0 && total / count > 10 никога не дели на 0.
  • && е преди ||, като * преди +. При смесване слагай скоби, за да се чете ясно: (a && b) || c.
  • Условие може да е и вътре в друг if. Това е вложен if. Този код е същото като if (total >= 50 && inCity):
if (total >= 50) {
if (inCity) {
shipping = 0;
}
}

Пробвай

И на 5, и на 7

Какво трябва да пише на празното място, за да е вярно условието само за числа, които се делят и на 5, и на 7?

int number = 35;
if (number % 5 == 0  number % 7 == 0) {
    System.out.println("Дели се и на 5, и на 7");
}

Идеята

Тернарният оператор ? :

Понякога целият if е само за да избереш една от две стойности. За това има кратък запис, тернарният оператор (на три части):

int points = 76;
String message = points >= 50 ? "Издържал си!" : "Неуспешен опит.";
System.out.println(message);
Изход
Издържал си!

Чете се така: условие ? стойност, ако е вярно : стойност, ако не е. Същото с if и else е няколко реда, а тук е един.

Ползвай го за избор на стойност. Ако в двата случая програмата трябва да направи различни неща, пиши if.

По-точно, за любопитните
  • Двете стойности трябва да са от съвместим тип: не може едната да е текст, а другата число.
  • Тернарни оператори могат да се влагат един в друг, но такъв код се чете трудно. За три и повече възможности пиши else if.

Идеята

switch: избор по стойност

Магазинът работи от 9:00 до 18:00 през седмицата, в събота до 14:00, а в неделя е затворен. Ако денят е число (1 е понеделник, 7 е неделя), сравняваш го с няколко точни стойности. За това има switch:

int day = 6;
switch (day) {
case 6:
System.out.println("10:00–14:00");
break;
case 7:
System.out.println("Почивен ден");
break;
default:
System.out.println("9:00–18:00");
}
Изход
10:00–14:00
  • switch взима стойността в скобите и скача на case със същата стойност.
  • break приключва switch. Без него изпълнението продължава в следващия case.
  • default е за всички останали стойности, като последния else.
  • Няколко стойности с еднакво действие се пишат една под друга: case 6: и веднага case 7:.

switch работи с цели числа, символи и текст. За проверки от типа „от 50 нагоре“ пиши if.

По-точно, за любопитните
  • Ако забравиш break, изпълнението „пропада“ в следващия case, без проверка. При ден 6 се печатат два реда:
int day = 6;
switch (day) {
case 6:
System.out.println("10:00–14:00");
case 7:
System.out.println("Почивен ден");
break;
default:
System.out.println("9:00–18:00");
}
Изход
10:00–14:00
Почивен ден
  • От Java 14 има и запис със стрелка. При него няма пропадане и break не трябва. Освен това switch може да дава стойност, като тернарния оператор. Няколко стойности се пишат със запетая: case 6, 7 ->.
int day = 6;
String hours = switch (day) {
case 6 -> "10:00–14:00";
case 7 -> "Почивен ден";
default -> "9:00–18:00";
};
System.out.println(hours);
Изход
10:00–14:00

Упражнение

Програми, които избират

Реши задачите в редактора си. Всяко число на входа е на отделен ред. Пробвай всяко решение и с вход, който минава през другите клонове.

1. Билет за кино. Прочети възрастта. До 6 години се влиза безплатно, до 17 билетът е 6 €, до 64 е 10 €, от 65 нагоре е 5 €. Отрицателна възраст е грешка.

Вход
15
Изход
Билетът е 6 €

2. Мини калкулатор. Прочети число, операция (+, -, * или /) и второ число. Избери действието с switch по текста на операцията. На 0 не се дели.

Вход
12
/
5
Изход
Резултат: 2.4

3. Квадратно уравнение. Прочети a, b и c от ax² + bx + c = 0. Дискриминантата е D = b² − 4ac. Ако D е положително, корените са два: (−b ± √D) / 2a. Ако D е 0, коренът е един: −b / 2a. Ако D е отрицателно, реални корени няма. Ако a = 0, уравнението не е квадратно.

Вход
1
-3
2
Изход
x1 = 2.00, x2 = 1.00

4. Валидна дата. Прочети ден, месец и година и кажи дали датата съществува. Броя на дните в месеца намери с switch. Февруари има 29 дни във високосна година: делима на 4, но не на 100, или делима на 400.

Вход
29
2
2023
Изход
Невалидна дата

За 29, 2, 2024 изходът е Валидна дата.

Още задачи

  • Четно или нечетно. За 7: Нечетно.
  • Положително, отрицателно или нула. За −5: Отрицателно.
  • По-голямо от 10. За 15: По-голямо от 10.
  • Равни ли са. Прочети две числа. За 5 и 5: Равни.
  • По-голямото от две. Прочети две числа и отпечатай по-голямото. Направи го веднъж с if и веднъж с ? :.
  • Абсолютна стойност. Без Math.abs: ако числото е отрицателно, смени му знака.
  • Да или не. Прочети текст. Отпечатай true за „да“, false за „не“ и Неразбран отговор за всичко друго.
  • На 5 и на 7. Кажи дали числото се дели и на 5, и на 7. За 35: да, за 10: не.
  • Три числа във възходящ ред. Прочети три числа и ги отпечатай от най-малкото към най-голямото. За 7, 2, 5: 2 5 7.
  • Най-малко и най-голямо от пет. Прочети пет числа в пет променливи. Запомни първото като най-малко и най-голямо, после сравни с него всяко следващо.
  • Ден от седмицата. Прочети число от 1 до 7 и отпечатай деня: 1 е Понеделник. За друго число: Няма такъв ден. Пробвай с switch.
  • Възрастова категория. До 12 години е дете, до 19 тийнейджър, иначе възрастен.
  • Сезон по месец. Декември, януари и февруари са зима, март до май пролет и т.н. За 4: Пролет. Със switch сложи няколко case един под друг.
  • Триъгълник ли е. Три страни правят триъгълник, ако сумата на всеки две е по-голяма от третата. За 3, 4, 5: да, за 1, 2, 3: не.
  • Оценка с думи. Прочети оценка от 2 до 6 и отпечатай Слаб, Среден, Добър, Много добър или Отличен.
  • Познай животното. Програмата задава въпроси с отговор „да“ или „не“ и познава какво животно си намислил. Започни с поздрав и кратко обяснение на играта. Можеш да зададеш всички въпроси и после да решиш с else if, или да питаш само нужното с вложени if. Въпросникът:
Въпрос Ако „да“ Ако „не“
Лети ли? птица или насекомо продължи
Има ли пера? птица ако лети, насекомо
Плува ли? ако не лети: риба или водно бозайниче продължи
Мяука ли? котка не е котка
Има ли косми? куче, котка или друг бозайник гущер или друго влечуго
Зелено ли е? ако не лети и не плува: жаба или гущер продължи
Реве ли? крава или лъв продължи
Има ли хобот? слон продължи

Пример (входът е отговорът на всеки въпрос, по ред):

Вход
не
не
не
да
да
не
не
не
Изход
Намисли животно. Ще ти задам 8 въпроса, отговаряй с да или не.
Лети ли?
Има ли пера?
Плува ли?
Мяука ли?
Има ли косми?
Зелено ли е?
Реве ли?
Има ли хобот?
Мисля, че е котка.

Тест

Провери се

1. Какво дава 62.0 >= 50?
2. Каква е разликата между = и ==?
3. Веригата if / else if проверява първо points >= 50, после points >= 75. Какво става при 95 точки?
4. Отстъпка има, ако age < 18 || age >= 65. Получава ли отстъпка човек на 70?
5. Какво става в switch, ако в края на един case няма break?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·