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

Вход и изход

Проблем

Програмата знае само едно име

Програмата поздравява клиента по име:

const name = "Мария";
console.log("Здравей, " + name + "!");
Изход
Здравей, Мария!

Работи, но поздравява всички като Мария. Името е записано в кода. За всеки нов клиент трябва да промениш програмата и да я пуснеш наново. Искаш програмата сама да попита.

Идеята

Четене от клавиатурата

Когато програмата чете, тя спира и чака. Човекът пише и натиска Enter. Написаното е входът на програмата.

greet.js
import { createInterface } from "node:readline";
const rl = createInterface({ input: process.stdin });
const lines = rl[Symbol.asyncIterator]();
async function ask(question) {
process.stdout.write(question);
return (await lines.next()).value;
}
const name = await ask("Как се казваш? ");
console.log("Здравей, " + name + "!");
rl.close();
Вход
Мария
Изход
Как се казваш? Здравей, Мария!

В JavaScript няма кратка готова команда за четене от клавиатурата. Затова най-горе стоят няколко реда, които правят помощник: ask. ask("Как се казваш? ") печата въпроса, чака човекът да напише ред и Enter и дава написаното. await пред него значи „изчакай отговора“. rl.close(); в края затваря четенето, когато програмата вече няма да чете.

Какво значат import, async, function и await, ще разберем по-нататък. Функциите са в модул „Функции“. Засега копирай тези редове най-горе във всяка програма, която чете. По-нататък в уроците не ги показваме, а само редовете след тях.

Входът и изходът тук са показани поотделно. В конзолата името ще се появи там, където го пишеш: след „Как се казваш? “. ask печата въпроса с process.stdout.write, без нов ред: отговорът е на същия ред.

По-точно, за любопитните
  • ask("") с празни кавички само чете, без въпрос.
  • Ако входът е свършил (няма повече редове), ask дава undefined, „няма стойност“.
  • readline има и rl.question(), който ще срещнеш в примери в интернет. Когато входът идва от файл, той губи редове, затова тук не го ползваме.

Проблем

12 + 30 = 1230

Касиерът въвежда две плащания, 12 € и 30 €. Програмата трябва да покаже общата сума:

const first = await ask("");
const second = await ask("");
const total = first + second;
console.log("Общо: " + total + " €");
rl.close();
Вход
12
30
Изход
Общо: 1230 €

Вместо 42 излезе 1230. Програмата не е сбъркала сметката. Тя изобщо не е смятала.

Тук въпрос няма: ask("") само чете ред.

Идеята

От текст към число

Каквото и да напише човекът, ask() връща текст. „12“ и „30“ са два текста, а + между текстове ги слепва. За да смяташ, превърни текста в число:

const first = Number(await ask(""));
const second = Number(await ask(""));
const total = first + second;
console.log("Общо: " + total + " €");
rl.close();
Вход
12
30
Изход
Общо: 42 €

Превръщането на текст в стойност от друг тип се казва парсване (parse).

  • Number(...) дава число, цяло или дробно: в JavaScript те са един тип.
  • Има и parseInt(...) и parseFloat(...). Те четат цифрите от началото на текста и спират при първия друг знак: parseInt("12 €") е 12.

Сумата тук е първата сметка в курса. Изваждане, умножение и деление идват в следващия урок.

const first = Number(await ask(""));
const second = Number(await ask(""));
const total = first + second;
console.log("Общо: " + total + " €");
rl.close();
Стъпка по стъпка, с думи
  1. Човекът пише 12 и Enter. await ask("") връща текста "12", не число.
  2. Number превръща текста в числото 12. То отива във first.
  3. 30 минава по същия път: текст, парсване, число в second.
  4. Сега + събира числа: 12 + 30 = 42.
  5. Отпечатва се „Общо: 42 €“.
По-точно, за любопитните
  • Ако текстът не е число (например „дванайсет“), JavaScript не спира. Number дава NaN (Not a Number, „не е число“), а сметка с NaN пак дава NaN. Празен ред дава 0. Интервалите отстрани не пречат: Number(" 12 ") е 12.
console.log(Number(" 12 "));
console.log(Number("3.5"));
console.log(Number("дванайсет"));
console.log(Number("3,5"));
console.log(Number(""));
console.log(Number("дванайсет") + 1);
Изход
12
3.5
NaN
NaN
0
NaN
  • Number иска винаги точка, каквито и да са настройките на компютъра: Number("3,5") е NaN.

Пробвай

Колко билета?

Програмата чете колко са възрастните и колко са децата.

Вход
2
3

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

const adults = Number(await ask(""));
const children = Number(await ask(""));
console.log("Билети: " + adults + children);
rl.close();
Отговор

Идеята

Числата, както ги искаш

В миналия урок цената 49.90 излезе като 49.9. За цена искаш винаги два знака след десетичната точка. Това е форматиран изход:

const product = "Слушалки";
const price = 49.9;
const qty = 2;
console.log(`${product}: ${price.toFixed(2)} €`);
console.log(`${qty} бр. в количката`);
const label = `Цена: ${price.toFixed(2)} €`;
console.log(label);
Изход
Слушалки: 49.90 €
2 бр. в количката
Цена: 49.90 €

Текстът в обратни кавички, `, е шаблонен низ: стойностите се пишат направо в него, в ${…}. Това се казва интерполация на низове.

price.toFixed(2) дава числото като текст с точно 2 знака след точката. toFixed(0) е без знаци след точката, toFixed(3) е с три.

Стойността в променливата не се променя. Форматът решава само как да изглежда, когато се печата.

По-точно, за любопитните
  • Хилядите и подравняването в колони:
const total = 1234.5;
console.log("Общо: " + total.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + " €");
console.log("Кафе".padEnd(10) + "|" + (2.5).toFixed(2).padStart(8));
console.log("Лаптоп".padEnd(10) + "|" + (1299.0).toFixed(2).padStart(8));
Изход
Общо: 1,234.50 €
Кафе | 2.50
Лаптоп | 1299.00

toLocaleString("en-US", …) пише числото по правилата на английския, с разделител за хилядите. padEnd(10) допълва текста с интервали отдясно до 10 знака, а padStart(8) отляво до 8.

  • toFixed не следва регионалните настройки: точката си е точка на всеки компютър. Ако искаш десетична запетая, както се пише у нас, сложи я изрично:
const price = 49.9;
console.log("Цена: " + price.toFixed(2).replace(".", ",") + " €");
Изход
Цена: 49,90 €

Пробвай

Два знака

Нощувката струва 65.5 €. Искаш да излезе „Нощувка: 65.50 €“. Какво трябва да пише на празното място?

console.log(`Нощувка: ${price.} €`);

Пробвай

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

Вече са запазени 12 билета, а програмата добавя още, колкото въведеш. При вход 4 тя печата „Запазени: 124“. На кой ред е грешката?

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

Упражнение

Програми, които питат

Реши задачите в редактора си. Входът е по един ред за всяка стойност. Не печатай въпроси като „Въведи име:“, за да съвпадне изходът ти с примерния: пиши ask("").

1. Поздрав по име. Прочети име и поздрави.

Вход
Мария
Изход
Здравей, Мария!

2. Сума на две числа. Прочети две цели числа и отпечатай сметката.

Вход
17
25
Изход
17 + 25 = 42

3. Два текста в един. Прочети два текста и ги отпечатай заедно, с интервал между тях.

Вход
Велико
Търново
Изход
Велико Търново

4. π с два знака. Запиши π в променлива като 3.14159265358979 и го отпечатай с два знака след точката. Готовата стойност Math.PI идва в следващия урок.

Изход
3.14

Още задачи

  • Възраст. Прочети име и възраст (цяло число) и отпечатай „Мария е на 19 години.“
  • Визитка от клавиатурата. Прочети име, професия и телефон и отпечатай визитката от урока „Първата програма“ с тях.
  • Цена с два знака. Прочети цена като дробно число и я отпечатай с два знака и знак за евро: при вход 7.5 изходът е Цена: 7.50 €.
  • Сума на две цени. Прочети две дробни цени и отпечатай сумата им с два знака: при вход 12.4 и 3.15 изходът е Общо: 15.55 €.

Тест

Провери се

1. Какво връща await ask("")?
2. Прочетени са текстовете "12" и "30". Какво дава first + second?
3. Какво прави Number("25")?
4. const a = 2; const b = 3; Какво отпечатва "Сума: " + a + b?
5. Как се отпечатва 7.5 като 7.50?

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