Вход и изход
Проблем
Програмата знае само едно име
Програмата поздравява клиента по име:
const name = "Мария";console.log("Здравей, " + name + "!");Здравей, Мария!Работи, но поздравява всички като Мария. Името е записано в кода. За всеки нов клиент трябва да промениш програмата и да я пуснеш наново. Искаш програмата сама да попита.
Идеята
Четене от клавиатурата
Когато програмата чете, тя спира и чака. Човекът пише и натиска Enter. Написаното е входът на програмата.
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();1230Общо: 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();1230Общо: 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();Стъпка по стъпка, с думи
- Човекът пише 12 и Enter. await ask("") връща текста "12", не число.
- Number превръща текста в числото 12. То отива във first.
- 30 минава по същия път: текст, парсване, число в second.
- Сега + събира числа: 12 + 30 = 42.
- Отпечатва се „Общо: 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);123.5NaNNaN0NaNNumberиска винаги точка, каквито и да са настройките на компютъра:Number("3,5")еNaN.
Пробвай
Колко билета?
Програмата чете колко са възрастните и колко са децата.
23Какво ще отпечата програмата?
const adults = Number(await ask(""));const children = Number(await ask(""));console.log("Билети: " + adults + children);rl.close();"Билети: " + adults вече е текстът „Билети: 2“, а текст + 3 слепва 3 накрая. Със скоби първо се смята сумата: "Билети: " + (adults + children) дава „Билети: 5“.Идеята
Числата, както ги искаш
В миналия урок цената 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.00toLocaleString("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.} €`);toFixed(2): дробно число с точно два знака след точката.
Пробвай
Намери грешката
Вече са запазени 12 билета, а програмата добавя още, колкото въведеш. При вход 4 тя печата „Запазени: 124“. На кой ред е грешката?
Избери реда с грешката.
ask връща текст, "4". 12 + "4" в JavaScript не е грешка: числото се превръща в текст и двете се слепват в „124“. Затова такъв пропуск се хваща по изхода. Поправката е const tickets = Number(await ask("Брой билети: "));.Упражнение
Програми, които питат
Реши задачите в редактора си. Входът е по един ред за всяка стойност. Не печатай въпроси като „Въведи име:“, за да съвпадне изходът ти с примерния: пиши ask("").
1. Поздрав по име. Прочети име и поздрави.
МарияЗдравей, Мария!2. Сума на две числа. Прочети две цели числа и отпечатай сметката.
172517 + 25 = 423. Два текста в един. Прочети два текста и ги отпечатай заедно, с интервал между тях.
ВеликоТърновоВелико Търново4. π с два знака. Запиши π в променлива като 3.14159265358979 и го отпечатай с два знака след точката. Готовата стойност Math.PI идва в следващия урок.
3.14Още задачи
- Възраст. Прочети име и възраст (цяло число) и отпечатай „Мария е на 19 години.“
- Визитка от клавиатурата. Прочети име, професия и телефон и отпечатай визитката от урока „Първата програма“ с тях.
- Цена с два знака. Прочети цена като дробно число и я отпечатай с два знака и знак за евро: при вход
7.5изходът еЦена: 7.50 €. - Сума на две цени. Прочети две дробни цени и отпечатай сумата им с два знака: при вход
12.4и3.15изходът еОбщо: 15.55 €.
Тест