До списку уроків
9 клас · Урок 3 з 16

Таблиця як база даних: типи, формули, CSV

виконано0%
Крок 1

Що робимо сьогодні

Модуль I · Тема 2 · Дані опитування · урок 1 з 2 · 120 хвилин

Уяви: ти зібрав із класу відповіді про те, хто скільки спить. Тридцять рядків у таблиці. І тепер хочеш дізнатися, хто недосипає.

Якщо колонку з годинами таблиця вважає текстом, вона не порахує ні суми, ні середнього. Виглядатиме все однаково — а працювати не буде.

Сьогодні ти розберешся, чому так, і навчишся готувати таблицю заздалегідь. Заразом побачиш, як ті самі дані виглядають усередині файлу, коли переходять з однієї програми в іншу.

Наприкінці уроку в тебе буде паспорт майбутнього опитування. Це два файли: fields.json з описом полів і README.md з поясненням. На наступному уроці з них виросте HTML-форма, яку заповнить увесь клас.

Після уроку ти вмієш

Слова CSV, BOM і fields.json поки нічого не означають — розберемо їх по черзі.

Хід уроку

ЕтапХвЩо робимо
Вступ і задача теми10Що ми хочемо дізнатися про клас — три дослідницькі питання
Запис, поле, ключ10Та сама таблиця очима людини і очима бази
Типи і дати20П'ять типів, пастка 01.02.2026, ISO 8601
Нормалізація10Три написання одного міста — три різні значення
Перерва10
CSV зсередини15Роздільник, лапки, екранування, кодування, BOM
Парсер наживо10Лагодимо поламані рядки просто на сторінці
Формули15SUM, COUNTIF, IF, пошук, $
Практика: свої поля15Таблиця в Grist, fields.json, README.md
Здача і ДЗ5Автоперевірка, показ таблиці вчителю
Разом120з перервою всередині
Де живе таблиця Ніякого Google Sheets. Таблиці ведемо в Grist (або NocoDB) — це вільні системи, які стоять на нашому власному сервері, поруч із твоїм сайтом. Дані класу не їдуть у чужу хмару. Якщо Grist недоступний — запасний варіант LibreOffice Calc на твоїй машині.
Що сьогодні їде на сервер Тільки два легкі текстові файли: ~/www/form/fields.json і ~/www/form/README.md. Жодних .xlsx, жодних експортів на мегабайти. Сама таблиця лишається в Grist, а зібрані відповіді з'являться на наступному уроці — і ляжуть у приватну теку ~/data/, а не в публічну ~/www/.
Як рахується оцінка Внизу сторінки — шкала виконання: кроки практики, автоперевірка на сервері, відповіді на питання й очна перевірка. Відсоток видно в шапці постійно.
Крок 2

Запис, поле, ключ

Таблиця — це не картинка з лініями. Це база даних, у якої просто зручний вигляд

Три слова, якими далі говоритиме весь модуль:

СловоЩо це в таблиціПриклад
Запис (рядок)одна річ, про яку ми зібрали даніодна заповнена анкета
Поле (колонка)одна характеристика, однакова для всіх записівгодини_сну
Значення (клітинка)перетин: це поле в цьому записі7
Ключполе, яке відрізняє запис від усіх іншихid, номер анкети
Схемаперелік полів і їхніх типів — «паспорт» таблицітвій fields.json

Головне правило: усі значення в колонці — одного типу. Уяви колонку «години сну». Серед чисел трапилося слово «вісім» — і колонка вже не числова. Середнє по ній не порахується. Одна клітинка ламає всю колонку.

Що бачить людина і що бачить база

ЩО БАЧИТЬ ЛЮДИНА — ВИГЛЯД УченьДата Години снуСпорт Шевченко Т.01.02.2026 7так Ковальчук І.1 лютого 8Так Леся У.2026-02-01 вісім+ та сама таблиця, але тепер питаємо: якого типу кожна колонка? ЩО БАЧИТЬ БАЗА — ДАНІ studentsurvey_date sleep_hoursdoes_sport текст дата (ISO) число логічний Шевченко Т. Ковальчук І. 01.02.2026 ✕ 1 лютого ✕ 7 вісім ✕ true + ?

Зверху й знизу — одні й ті самі дані. Різниця в питанні. Людина питає «як воно виглядає». База питає «якого воно типу». Людина спокійно читає «1 лютого» і «вісім», а база ставить хрестик. За таким полем не відсортуєш і середнє не порахуєш.

Ключ — це не «перша колонка» Ключ має бути унікальним і незмінним. Прізвище ключем бути не може: у класі бувають два Ковальчуки, а прізвище ще й змінюють. Тому в анкетах ключ — це id або код учасника, а не ім'я. Заразом це захищає приватність: у публічному файлі стоїть 09-14, а не «Ковальчук Іван».
Питання

У колонці «години сну» 29 чисел і одна клітинка зі словом «вісім». Ти просиш порахувати середнє — і воно виходить не таким, як очікував. Що сталося?

Питання

Однокласник зробив ключем таблиці колонку «Прізвище». Через тиждень у класі з'явився другий Мельник. Що зламається першим?

Крок 3

П'ять типів і головна пастка

Тип важливіший за вигляд: вигляд можна перемкнути, тип — це те, що програма реально вміє з даними робити

ТипЩо вмієПрикладЧого не можна
Текстзберігати будь-що, шукати підрядок, групуватиШевченко Т.рахувати середнє
Числосума, середнє, мінімум, максимум, сортування за величиною7, -3.5зберігати телефон — зникне перший нуль
Датасортування в часі, різниця в днях, групування за місяцем2026-02-01писати «1 лютого» словами
Логічнийлише два значення: так / ніtrue, falseтретій варіант «іноді»
Список (вибір)значення тільки з наперед відомого наборупішки, автобус, метровписати щось своє

Тип — це обіцянка, яку таблиця дає формулам. Колонка числова — отже, AVERAGE може розраховувати на числа. Порушив обіцянку хоч в одній клітинці — ламається вся колонка, а не клітинка.

Вигляд — це маска поверх типу. Одне й те саме число 0.75 показують як 0,75, 75% або 75,0%. Усередині лежить те саме.

Тому «поміняти формат» і «поміняти тип» — різні дії. Формат міняє зовнішність. Тип міняє зміст.

Пастка 01.02.2026

Це найдорожча помилка в роботі з даними. І вона не про програми, а про людей. Половина світу читає це як 1 лютого. Друга половина — як 2 січня. Сам запис не підказує, у якому порядку його склали.

01.02.2026 Україна, Європа: ДД.ММ.РРРР 1 лютого 2026 так прочитає твій клас США: ММ.ДД.РРРР 2 січня 2026 так прочитає англійський Excel імпорт у базу не дата, а текст формат не впізнано І ОСЬ ЩО БУДЕ ПРИ СОРТУВАННІ дати як текст, сортування за абеткою 01.02.2026 02.12.2025 10.01.2026 1 лютого 2026 2 грудня 2025 10 січня 2026 ✕ грудень 2025 опинився в середині ISO 8601, те саме сортування за абеткою 2025-12-02 2026-01-10 2026-02-01 2 грудня 2025 10 січня 2026 1 лютого 2026 ✓ порядок за абеткою = порядок у часі

Рятує міжнародний стандарт ISO 8601: дату пишуть як РРРР-ММ-ДД. Найбільша одиниця стоїть першою, і кожна має фіксовану довжину. Тому звичайне сортування за абеткою дає правильний порядок у часі.

І ніяких «а в нас інакше». Запис 2026-02-01 у будь-якій країні означає одне й те саме.

Правило зберігання Зберігай в ISO, показуй як завгодно. У файлі, у базі, в fields.json — тільки 2026-02-01. А на екрані форма чи звіт можуть намалювати «1 лютого 2026», якщо так зрозуміліше людині. Формат показу — справа інтерфейсу, формат зберігання — справа даних.
Це не теорія: у 2020 році через це перейменували гени Excel сам «здогадується» про типи. Символ гена SEPT1 він перетворював на дату, MARCH1 — теж. Виправити це не змогли, тому міжнародний комітет HGNC пішов іншим шляхом: перейменував 27 генів, щоб таблиці припинили їх псувати. Тепер це SEPTIN1 і MARCHF1.
Питання

Клас з іншої школи прислав таблицю, де в колонці дат стоїть 04.03.2026 і 03.04.2026. Як точно дізнатися, який це день і який місяць?

Питання

Ти вносиш у таблицю номер телефону 0501234567, а в клітинці після Enter лишається 501234567. Що зробити?

Крок 4

«Київ», «київ» і «КИЇВ» — це три значення

Комп'ютер порівнює не сенс, а послідовність символів

Для тебе це одне місто. Для таблиці — три різні рядки символів: коди літер у них не збігаються. Додай сюди зайвий пробіл у кінці, латинське Kyiv і «м. Київ». У колонці на 30 записів раптом стане шість «різних» міст.

КОЛОНКА «МІСТО», 7 ЗАПИСІВ Київ київ КИЇВ Київ␣ Kyiv Київ м. Київ пробіл латиниця зведена таблиця 6 різних міст групування порівнює точно COUNTIF(…;"Київ") 4, а не 7 регістр пробачає, пробіл — ні після нормалізації Київ — 7 одне значення нормалізація = обрізати пробіли + звести регістр + звірити зі словником TRIM(…) → LOWER(…) → «Kyiv», «м. Київ» → «Київ»

Зверни увагу на середню плашку. COUNTIF в Excel і Google Sheets не розрізняє великі й малі літери. Тому «київ» і «КИЇВ» він порахує разом. А от зайвий пробіл і латинське Kyiv для нього — вже інші значення.

Зведена таблиця й групування в Grist порівнюють точно. Там вилізуть усі шість варіантів. Виходить, одна колонка дає різні числа в різних програмах. Саме тому чистять дані, а не результати.

Найпростіший спосіб не мати цієї проблеми

Не давай людині набирати текст там, де можна дати вибір. У полі-списку (select, radio) варіанти задані наперед. Написати «київ» з малої там просто нема як. Тому вільний текст лишають для того, що справді неможливо передбачити.

Правило для сьогоднішньої практики Кожне поле, у якого відповідей менше ніж 8 і вони відомі наперед, роби "type": "select" з масивом options. Вільний текст — максимум одне-два поля на всю анкету.
Питання

У зведеній таблиці замість очікуваних 5 гуртків вийшло 11 рядків: «Футбол», «футбол», «Футбол » і так далі. Що ти зміниш в анкеті, щоб наступного разу цього не сталося взагалі?

Крок 5

CSV зсередини

Формат, у якому дані переходять із будь-якої програми в будь-яку — і в якому найлегше все зламати

CSV — це звичайний текстовий файл, який можна відкрити Блокнотом. Один рядок файлу — один запис таблиці. Кома — межа між полями. Перший рядок зазвичай заголовок.

Назва так і читається: comma-separated values, значення, розділені комами. Файл важить копійки, і його вміє читати кожна мова програмування.

Правила описані в RFC 4180 (2005). Їх усього чотири, але за кожним стоїть чиясь зіпсована таблиця:

ПравилоЩо воно рятує
Поле можна взяти в подвійні лапкиусе всередині лапок — одне поле, хай там хоч десять ком
Поле з комою, лапками або переносом рядка треба взяти в лапки"Ковальчук, Іван" лишається одним полем
Лапки всередині поля подвоюють"" означає одну літеральну лапку у значенні
В усіх рядках однакова кількість полівтаблиця лишається прямокутною

Анатомія одного рядка

ОДИН РЯДОК ФАЙЛУ 3 , " Ковальчук, Іван " , " сказав "" ок "" " , 2026-02-01 поле 1 поле 2 поле 3 поле 4 число текст текст дата ЩО ОЗНАЧАЮТЬ ПІДСВІТКИ роздільник полів — кома поза лапками лапки-обгортка — межі поля, у значення вони не входять кома й подвоєні лапки всередині поля — частина тексту що з цього рядка прочитає програма: 3 · Ковальчук, Іван · сказав "ок" · 2026-02-01

Найважливіше в цій схемі — подвоєні лапки. Поле взяте в лапки, а всередині стоїть "". Це означає одну лапку у значенні. Іншого способу екранування в CSV немає — зворотних слешів, як у JSON, тут не буває.

Перенос рядка всередині клітинки

Так, це дозволено. Але тільки якщо поле взяте в лапки. Тоді один запис займає в файлі кілька рядків. І розбір «читаємо файл порядково» на ньому розвалюється.

Саме тому CSV читають посимвольно. Програма тримає один прапорець: «я зараз усередині лапок чи ні».

коректний CSV із «важкими» полями
id,учень,коментар 1,Шевченко Т.,норм 2,"Ковальчук, Іван","сказав ""ок"" і пішов" 3,Леся У.,"перший рядок другий рядок"

Тут 4 фізичні рядки файлу, але лише 3 записи плюс заголовок: третій запис займає два рядки, бо в його полі є перенос.

Питання

Однокласник надіслав таблицю, у якій прізвище «Ковальчук, Іван» з'їхало у два стовпці, а всі дані праворуч зсунулися на одну колонку. Що сталося?

Питання

Тобі треба записати в CSV коментар він сказав "ок". Як виглядатиме це поле у файлі?

Крок 6

Чому Excel псує CSV з українським текстом

Файл із самих байтів не знає, якою мовою його читати

Ось у чому річ: у CSV немає заголовка з назвою кодування. HTML має <meta charset="utf-8">, XML має декларацію. CSV не має нічого. Тож програма, яка відкриває файл, мусить здогадатися. Excel на Windows здогадується за мовою системи, а не за вмістом.

Українська літера в UTF-8 займає два байти. Windows-1251 — однобайтове кодування. Читаючи ним, програма робить із кожного байта окремий символ. Тому з чотирьох літер виходить вісім значків:

Що записалиБайти в UTF-8Що показав Excel
КиївD0 9A D0 B8 D1 97 D0 B2РљРёС—РІ
ЛьвівD0 9B D1 8C D0 B2 D1 96 D0 B2Львів

BOM — три байти, які все вирішують

На самому початку файлу можуть стояти три службові байти EF BB BF. Це позначка BOM, byte order mark. Для UTF-8 вона технічно не потрібна, і стандарт Unicode її не радить.

Але саме за нею Excel на Windows упізнає UTF-8. З нею він перестає малювати «кракозябри». Тому в реальному житті ця позначка живе й далі.

Дзеркальна пастка BOM рятує Excel і водночас ламає чимало інших інструментів: для скрипта на Python чи для парсера JSON перші три байти — це «сміття» на початку першого поля, і заголовок id раптом перестає збігатися з id. Тому питай себе не «як правильно», а «хто читатиме цей файл». Для Excel — з BOM. Для сервера, скрипта, чекера — без BOM.

Друга половина проблеми: роздільник

Українською, німецькою чи французькою дробову частину відділяють комою: 7,5. Кома вже зайнята. Тому в цих мовах Excel розділяє поля CSV крапкою з комою. Файл, збережений в українському Excel, часто виглядає так:

CSV з українського Excel
id;учень;години_сну 1;Шевченко Т.;7,5 2;Ковальчук І.;8

Формально це вже не «comma-separated». Але так роблять усі, і програми це вміють читати — треба лише вказати роздільник явно. Гірше інше. Віддай такий файл програмі, яка чекає кому, — і вона прочитає весь рядок як одну колонку.

Мовних звичок у програми ціла купа. Чим відділяти дробову частину, чим розділяти колонки, у якому порядку писати число дати, як звуться місяці. Усе це разом називають локаллю — набором налаштувань під конкретну країну й мову. Тому «той самий Excel» на двох комп'ютерах поводиться по-різному.

СимптомПричинаЩо робити
Замість тексту «РљРёС—РІ»UTF-8 прочитали як Windows-1251імпортувати, вказавши UTF-8; або зберегти з BOM
Уся таблиця в одному стовпціроздільник ;, а чекали ,вказати роздільник у діалозі імпорту
0501234567 стало 501234567колонку визначено як числовуу діалозі імпорту дати колонці тип «текст»
1,23E+11 замість довгого номеравелике число показано в науковому форматіте саме: колонка має бути текстовою
SEPT1 стало 1 веравтовизначення типу «дата»тип «текст» при імпорті
Золоте правило Не відкривай CSV подвійним кліком. Заходь через «Дані → Отримати дані → З тексту/CSV» (Excel) — там можна вказати і кодування, і роздільник, і тип кожної колонки. LibreOffice Calc показує цей діалог завжди, тому в класі він надійніший. У Grist і NocoDB кодування й роздільник теж задають при імпорті.
Історія на 15 841 випадок У жовтні 2020 року Public Health England втратила 15 841 підтверджений випадок COVID-19 за тиждень із 25 вересня по 2 жовтня. Причина: результати тестів зводили у старому форматі .xls, у якому аркуш вміщає 65 536 рядків. Коли аркуш заповнився, нові рядки просто мовчки не додавалися. Помилки не було — було переповнення, про яке ніхто не дізнався. Формат даних — це не дрібниця.
Питання

Ти вивантажив із Grist файл responses.csv, відкрив його подвійним кліком в Excel — і замість прізвищ бачиш «РљРёС—РІ». Файл зіпсований?

Питання

Твій скрипт-чекер на сервері читає CSV і скаржиться, що не знаходить колонку id, хоча в першому рядку файлу вона є. Що найімовірніше сталося?

Крок 7

Парсер CSV наживо

Встав будь-який CSV — сторінка розбере його так само, як це зробить сервер, і покаже, де він ламається

Парсер працює посимвольно за правилами RFC 4180. Він тримає той самий прапорець: «я всередині лапок». Тип колонки він визначає за її вмістом. А клітинки, які цьому типу суперечать, підсвічує.

Домовленість. Колонка, чия назва в заголовку закінчується на *, вважається обов'язковою. Порожня клітинка в ній — помилка.

Типи рахуються тільки за рядками з правильною кількістю колонок. Зламаний рядок не має права зіпсувати статистику.

Спробуй полагодити «приклад із помилками» просто в полі: візьми Ковальчук, Іван у лапки, перепиши дату в ISO, заповни порожній id* — і дивись, як зникають червоні плашки.

Питання

Парсер каже: «запис 5 — 7 полів замість 6». Ти дивишся на рядок і бачиш там прізвище з комою. Скільки записів у файлі зіпсовано?

Крок 8

Формули: питання до даних

П'ять функцій, яких вистачить на весь модуль

Формула — це не «підрахувати». Формула — це питання до таблиці. Питання поставлене так, щоб таблиця могла відповісти сама. І щоб відповідь оновилася, щойно з'явиться новий рядок.

ПитанняФормулаЩо робить
Скільки всього годин?=SUM(C2:C31)додає числа в діапазоні, текст ігнорує
Скільки в середньому?=AVERAGE(C2:C31)сума ділиться на кількість непорожніх числових клітинок
Скільки їздять метро?=COUNTIF(E2:E31;"метро")рахує клітинки, що збігаються з умовою
Хто недосипає?=IF(C2<7;"мало";"норма")перевіряє умову і повертає одне з двох значень
Як розшифрувати код?=XLOOKUP(A2;Довідник!A:A;Довідник!B:B;"немає")шукає ключ в одному стовпці, повертає значення з іншого

Тепер розберемо кожну на своїй таблиці. Уяви, що анкету заповнили 30 однокласників. Їхні відповіді лежать у рядках з 2-го по 31-й. У колонці C — години сну, у колонці E — як людина дістається до школи.

Скільки годин клас спить разом

=SUM(C2:C31) складає всі числа з колонки C. Саме число «разом» тобі навряд чи знадобиться. Зате воно одразу показує, чи всю колонку таблиця бачить як числа. Хтось написав «сім» словами — і сума мовчки стане меншою.

Скільки в середньому

=AVERAGE(C2:C31) ділить суму на кількість заповнених клітинок. Ключове слово — заповнених. Троє не відповіли, порожні клітинки в лік не йдуть, і середнє рахується по 27 людях, а не по 30.

А от нуль — це відповідь. Якщо хтось написав 0, він потрапить у розрахунок і потягне середнє вниз.

Скільки їздять метро

=COUNTIF(E2:E31;"метро") проходить колонку E й рахує, скільки разів там стоїть слово «метро». Це і є твоя перша діаграма: та сама формула зі словом «автобус», потім із «пішки».

Ось де мститься неохайність із попереднього кроку. «Метро» з великої літери ця формула теж порахує, а от «метро » із пробілом у кінці — уже ні.

Хто недосипає

=IF(C2<7;"мало";"норма") дивиться на години одного учня й пише поруч одне з двох слів. Формулу ставлять у сусідню колонку й протягують на всі 30 рядків.

Виходить нова колонка, яку далі можна порахувати тим самим COUNTIF — і дізнатися, скільки в класі тих, кому «мало».

Як розшифрувати код

У відповідях зручно тримати короткі коди: 9A, 9B. Але в звіті мають стояти нормальні назви. Тоді поруч заводять другий аркуш-довідник: у першій колонці код, у другій — розшифровка.

=XLOOKUP(A2;Довідник!A:A;Довідник!B:B;"немає") бере код із клітинки A2, шукає його в першій колонці довідника й повертає те, що стоїть навпроти в другій. Останній аргумент — слово, яке з'явиться, якщо такого коду в довіднику немає.

Кома чи крапка з комою в аргументах Це та сама локаль, а не різні функції. В англійській — COUNTIF(E2:E31,"метро"), в українській — COUNTIF(E2:E31;"метро"). Обидва записи правильні; неправильно лише сліпо копіювати з інтернету. Скопіював чужий запис — і в клітинці з'явиться #NAME?. Це відповідь програми «я не впізнала того, що ти написав»: або ім'я функції з друкарською помилкою, або зайвий знак у списку аргументів.

VLOOKUP проти XLOOKUP

Обидві функції роблять одне: «маю ключ — дай мені рядок — візьми з нього потрібне значення». Різниця в зручності й у кількості способів помилитися.

VLOOKUPXLOOKUP
Як задають результатномером колонки: 2, 3прямо діапазоном результату
Вставили колонку в довідникномер «з'їхав», формула тихо брешенічого не ламається
Шукати ліворуч від ключане вмієвміє
Якщо не знайдено#N/A — «такого ключа немає»; щоб замість помилки стояв твій текст, формулу обгортають у IFERRORчетвертий аргумент: що повернути
Де доступнаскрізь, зокрема в старих файлахExcel 365 / 2021+, Google Sheets, LibreOffice 24.8+

Висновок простий: якщо XLOOKUP є — бери його. Якщо працюєш із чужим старим файлом, читати VLOOKUP усе одно доведеться вміти.

Знак $: що фіксуємо, а що ні

Коли формулу тягнуть униз, посилання в ній їдуть разом із рядком. Це зручно. Але буває клітинка, на яку мають дивитися всі рядки — підсумок або норма. Ось тоді й потрібен знак долара.

ЗаписЩо зафіксованоПісля протягування з рядка 2 у рядок 7
B2нічогоB7
$B2колонка$B7
B$2рядокB$2
$B$2і колонка, і рядок$B$2
частка кожного учня в загальній сумі
=C2/$C$33

C2 має їхати за рядком — це «мої години». А $C$33 — клітинка з підсумком, вона одна для всіх. Прибереш $ — і в сьомому рядку формула стане C7/C38. Клітинка C38 порожня, а порожнеча для формули дорівнює нулю.

Ділити на нуль не можна, тому в клітинці з'явиться #DIV/0!. Це скорочення від англійського division by zero — «ділення на нуль».

А як це в Grist

Grist — не Excel. Формули там пишуть мовою Python. І на колонки посилаються не літерами, а іменами: $sleep_hours.

Знак $ тут означає не «зафіксувати», а «поле цього запису». Протягувати теж нічого не треба: формула колонки одразу діє на всі рядки.

формула колонки в Grist
IF($sleep_hours < 7, "мало", "норма")

Звичні SUM, AVERAGE, IF у Grist теж є — просто в пітонівському записі. А от підсумок по всій колонці формулою внизу там не пишуть.

Замість цього Grist робить окрему таблицю з підсумками. У ній один рядок на кожну групу: скільки людей їздять метро, скільки автобусом, скільки ходять пішки. І середні години сну для кожної групи окремо.

Від звичайної таблиці вона відрізняється тим, що її ніхто не заповнює руками. З'явився новий рядок відповіді — підсумки перерахувалися самі. Англійською таку таблицю звуть summary table, українською — зведеною таблицею.

Питання

Формулу =B2*$D$1 протягнули з рядка 2 у рядок 7. Якою вона стала?

Питання

Ти написав =AVERAGE(C2:C31), але заповнено лише 18 анкет, решта рядків порожні. Середнє вийшло «занадто хороше». У чому річ?

Крок 9

Що виросте з fields.json на наступних уроках

Сьогоднішній fields.json — це креслення, за яким наступного уроку зросте справжня форма

fields.json опис полів і типів сьогодні index.html форма з валідацією урок 4 POST сервер /api/collect перевіряє ще раз ~/data/ responses.csv приватно, права 750 формули і зведення SUM · AVERAGE · COUNTIF у Grist або в Calc stats.json лише підсумки, без імен публічно, ~/www/ діаграми Chart.js, тема 3 уроки 5–6 ШЛЯХ ОДНІЄЇ ВІДПОВІДІ жовтим — те, що ніколи не потрапляє в публічну теку; зеленим — те, що можна показувати всьому світу

Тобто помилка в типі поля, зроблена сьогодні, дійде аж до діаграми на уроці 6. Зробиш «години сну» текстовими — Chart.js не намалює по них нічого. Лишиш «місто» вільним текстом — на кругову діаграму піде одинадцять секторів замість п'яти.

Як виглядає fields.json

~/www/form/fields.json
[ { "name": "student_code", "type": "text", "required": true, "hint": "твій номер у списку класу, без прізвища" }, { "name": "survey_date", "type": "date", "required": true, "hint": "дата заповнення у форматі РРРР-ММ-ДД" }, { "name": "sleep_hours", "type": "number", "required": true, "min": 3, "max": 12, "hint": "скільки годин ти спав минулої ночі" }, { "name": "transport", "type": "select", "required": true, "options": ["пішки", "автобус", "тролейбус", "метро", "авто", "велосипед"], "hint": "як найчастіше дістаєшся школи" }, { "name": "does_sport", "type": "boolean", "required": false, "hint": "чи ходиш на спортивну секцію" }, { "name": "comment", "type": "text", "required": false, "hint": "одне речення: що б ти змінив у розкладі" } ]
КлючНавіщо
nameім'я колонки в CSV і атрибут name у формі. Латиниця, нижній регістр, _ замість пробілів
typetext, number, date, boolean, select
requiredчи стане поле required у формі й обов'язковим у перевірці
min, maxмежі для чисел і дат: відсіюють «120 годин сну»
optionsваріанти для select — той самий словник, що рятує від «Київ / київ»
hintпідказка під полем: половина помилок зникає, коли людині пояснили, чого від неї хочуть
Чому ім'я поля — латиницею Українське Години сну в заголовку CSV живе рівно доти, доки файл не пройде через програму з іншим кодуванням або через URL. Пробіл у імені ламає атрибут name у формі. Тому sleep_hours — і жодних пробілів, крапок і дужок. Людське пояснення живе в hint і в README.md, а не в назві колонки.
Приватність — не формальність В анкеті не має бути прізвища, номера телефону, адреси, посилань на соцмережі. Ключ — це номер у списку класу. Дані класу з іменами не мають потрапити в публічну теку взагалі ніколи; на уроці 4 сервер сам покладе відповіді в приватну ~/data/.
Питання

Ти хочеш спитати «скільки часу витрачаєш на дорогу до школи». Який тип поля обереш і що додаси, щоб дані потім можна було порахувати?

Крок 10

Практика: паспорт свого опитування

Виконуй по черзі. Галочки зберігаються — сторінку можна закрити.

Тека зветься form, а урок — третій Практика зветься за темою, а не за номером уроку: усе кладемо в ~/www/form/. Теку lesson-03 шукати не треба — її немає.
Крок 11

Автоперевірка check 03

Система прочитає твої два файли, звірить їх зі схемою й перевірить права на теки. Спроби не обмежені.

Демонстраційний режим: результат згенеровано для показу. На сервері ця кнопка викликає POST /api/check, який запускає чекер уроку від імені учня.

Що вчитель дивиться на екрані

Крок 12

Шкала виконання

Це те, що бачить учитель, коли виставляє оцінку.

СкладникВагаРезультат
Виконано
0%
Рекомендований бал за 12-бальною

Сім пасток цього уроку

СимптомПричина й лікування
Не рахується середнє по колонціколонка текстова або в ній є слово; дай колонці тип «число» і полагодь клітинку
Прізвище з'їхало у два стовпцікома в полі без лапок; загорни поле в "…"
Дати сортуються неправильновони текстові й у форматі ДД.ММ.РРРР; перепиши в ISO РРРР-ММ-ДД
Замість тексту «РљРёС—РІ»UTF-8 прочитали як Windows-1251; імпортуй із явним кодуванням
Скрипт не бачить першу колонкуBOM на початку файлу приклеївся до назви; збережи без BOM
Формула «з'їхала» при протягуваннізабув $ у посиланні на клітинку підсумку
У зведенні 11 гуртків замість 5вільний текст замість списку; зроби поле select з options

Домашнє завдання

Додай у fields.json ще одне поле. У README.md напиши про нього два-три речення. Який тип ти обрав, чому саме такий і яку формулу застосуєш, коли зберуться відповіді.

Якщо поле числове, постав min і max. І поясни, від якої дурниці вони захищають.

Довідка

Джерела

Звідки взяті правила й числа на цій сторінці

CSV і формат файлу

Кодування, BOM і Excel

Дати й типи

Формули

Grist і NocoDB

Дані в прикладах на цій сторінці вигадані для навчання: прізвища, години сну й дати не належать нікому з класу. Реальні дані з'являться на наступному уроці — і одразу поїдуть у приватну теку.