Przejdź do treści

Temat 14 · 3 × 45 minINF.03

Wzorzec egzaminacyjny „kalkulator”: kontrolki → obliczenie → akapit

Blisko połowa zadań z JavaScriptem w części praktycznej INF.03 to ten sam schemat: użytkownik wpisuje lub zaznacza dane, klika przycisk, a skrypt liczy coś i wypisuje wynik w akapicie pod przyciskiem. Ten schemat nazywamy kalkulatorem. Umiesz już wszystkie jego klocki – odczyt kontrolek (lekcja 13), konwersję (lekcja 3), warunki (lekcja 5), funkcje (lekcja 7) i zmianę treści (lekcja 11). W tej lekcji złożysz je w jedną, powtarzalną procedurę, która zdobywa wszystkie kryteria zasad oceniania – i przećwiczysz ją na trzech zadaniach na czas.

Jak wygląda zadanie „kalkulator”

Arkusz opisuje stronę (np. cena.html) z kilkoma kontrolkami i przyciskiem, a na końcu opisu skryptu podaje format wyniku. Oto oryginalne zadanie w stylu CKE, na którym będziemy pracować w całej lekcji:

Zasady oceniania dla takiego zadania (rezultat 5 „Skrypt”) wyglądałyby tak – każde kryterium za 0 lub 1:

NrKryterium (styl „Zasad oceniania”)Gdzie sprawdzane
5.1Skrypt napisany w JavaScript, zawiera co najmniej jedną poprawną składniowo instrukcję; funkcja wywoływana przyciskiem „Oblicz”kod źródłowy
5.2Skrypt pobiera dane z co najmniej jednej kontrolki, np. document.getElementByIdkod źródłowy
5.3Koszt liczony jako cena za godzinę × liczba godzin, cena zależna od zaznaczonego rodzaju rowerukod + wynik
5.4Dopłata 5 zł dodawana tylko przy zaznaczonym polu „Kask”kod + wynik
5.5Wynik w akapicie pod przyciskiem w formacie Koszt wypożyczenia: <koszt> zł – sprawdzany dla dwóch różnych zestawów danychprzeglądarka
5.6Co najmniej jedna zmienna lub funkcja o znaczącej nazwie (PL/EN)kod źródłowy
Pięć pól połączonych strzałkami: kontrolki (value, checked), konwersja (parseFloat), obliczenie (if/else, Math.ceil), napis wyniku, akapit (innerHTML). Pod spodem: wszystko w jednej funkcji uruchamianej przyciskiem.
Rys. 1. Przepływ danych w zadaniu typu „kalkulator” – pięć kroków w jednej funkcji.

Krok 0: czytaj kryterium po kryterium

Zanim napiszesz linię kodu, rozbij polecenie na czynności. Każde zdanie z arkusza to zwykle jedno kryterium, a każde kryterium to jedna–trzy linie kodu. Zrób sobie taką tabelę w głowie (albo na kartce brudnopisu, którą masz na egzaminie):

Fragment poleceniaCo muszę zrobićLinia kodu
„uruchamiany po kliknięciu przycisku”funkcja + podpięcie do przyciskufunction obliczKoszt() {…} + onclick="obliczKoszt()"
„pobiera liczbę godzin”odczyt + konwersjaconst godziny = parseFloat(document.getElementById('godziny').value);
„wybrany rodzaj roweru”zaznaczony radiodocument.querySelector('input[name="rower"]:checked').value
„stan pola Kask”checkboxdocument.getElementById('kask').checked
„cena za godzinę razy liczba godzin”mnożenielet koszt = cenaZaGodzine * godziny;
„plus 5 zł, jeśli zaznaczono”ifif (kask) koszt += 5;
„wypisuje w pustym akapicie: Koszt wypożyczenia: … zł”napis + innerHTMLwynik.innerHTML = 'Koszt wypożyczenia: ' + koszt + ' zł';
„znaczące nazewnictwo”nazwyobliczKoszt, cenaZaGodzine, nie f1, x

Z tej tabeli wynika kolejność pisania kodu. Przejdziemy ją krok po kroku.

Krok 1: HTML – przycisk i pusty akapit pod nim

Arkusz mówi „w pustym akapicie pod przyciskiem”. To znaczy dosłownie: <p> bez treści, z id, umieszczony za przyciskiem. Nie <div>, nie <span>, nie alert – egzaminator sprawdza miejsce wyświetlenia (w styczniu 2024 było to osobne kryterium: „komunikat wyświetlony w bloku głównym w akapicie”).

cennik.html (fragment)
<label for="godziny">Liczba godzin:</label>
<input type="number" id="godziny" min="1" value="1">
<br>
<input type="radio" name="rower" value="8" id="miejski" checked>
<label for="miejski">Rower miejski – 8 zł/h</label>
<input type="radio" name="rower" value="20" id="elektryczny">
<label for="elektryczny">Rower elektryczny – 20 zł/h</label>
<br>
<input type="checkbox" id="kask">
<label for="kask">Kask (+5 zł)</label>
<br>
<button type="button" onclick="obliczKoszt()">Oblicz</button>
<p id="wynik"></p>

Trzy zasady:

  1. Każda kontrolka ma id (radio – wspólne name i własne value). Bez tego nie ma czego czytać.
  2. Przycisk ma type="button" albo nie jest w <form> – inaczej kliknięcie przeładuje stronę i wynik zniknie po ułamku sekundy.
  3. Akapit jest pusty i ma id – <p id="wynik"></p>. Możesz go nazwać inaczej (komunikat, koszt), byle konsekwentnie w JS.

Krok 2: funkcja i jej uruchomienie – dwa style

Arkusze CKE „myślą” w dialekcie egzaminacyjnym: atrybut onclick, var, getElementById, innerHTML. Tabela pomocnicza dołączona do każdego arkusza wymienia właśnie onclick i innerHTML. Ty możesz pisać tak samo albo nowocześnie. Porównaj dwa równoważne rozwiązania tego samego zadania:

Styl egzaminacyjny: onclick + getElementById + innerHTML
<label for="godziny">Liczba godzin:</label>
<input type="number" id="godziny" min="1" value="1"><br>
<input type="radio" name="rower" value="8" id="miejski" checked> <label for="miejski">Rower miejski – 8 zł/h</label>
<input type="radio" name="rower" value="20" id="elektryczny"> <label for="elektryczny">Rower elektryczny – 20 zł/h</label><br>
<input type="checkbox" id="kask"> <label for="kask">Kask (+5 zł)</label><br>
<button type="button" onclick="obliczKoszt()">Oblicz</button>
<p id="wynik"></p>
Podgląd

Ten sam efekt w stylu nowoczesnym – przycisk ma id, a funkcję podpina skrypt umieszczony pod przyciskiem:

Styl nowoczesny: addEventListener + querySelector + textContent
const przyciskOblicz = document.querySelector('#oblicz');
const akapitWyniku = document.querySelector('#wynik');

function obliczKoszt() {
  const godziny = parseFloat(document.querySelector('#godziny').value);
  const cenaZaGodzine = parseFloat(document.querySelector('input[name="rower"]:checked').value);
  const kask = document.querySelector('#kask').checked;
  let koszt = cenaZaGodzine * godziny;
  if (kask) koszt += 5;
  akapitWyniku.textContent = `Koszt wypożyczenia: ${koszt} zł`;
}

przyciskOblicz.addEventListener('click', obliczKoszt);
Podgląd

Kiedy który styl jest w porządku na egzaminie?

Styl egzaminacyjnyStyl nowoczesny
Podpięcieonclick="obliczKoszt()" w HTML – widoczne od razu, nie zależy od miejsca <script>addEventListener('click', obliczKoszt) – skrypt musi być po przycisku (koniec <body>) albo z defer
OdczytgetElementById('x')querySelector('#x') – to samo; querySelector dodatkowo obsługuje :checked
WynikinnerHTML – akceptuje <br>, gdy wynik ma kilka liniitextContent – bezpieczniejszy, ale <br> wypisze dosłownie
Zmiennevarconst/let
Ryzykoliterówka w nazwie funkcji w atrybucie widoczna dopiero po kliknięciufunkcja wywołana zamiast przekazana: addEventListener('click', obliczKoszt())
Ocenapełne punktypełne punkty – przeglądarka na stanowisku jest aktualna, a arkusz nie określa wersji języka

Oba podejścia są poprawne. Jeśli masz choć cień wątpliwości, pisz styl egzaminacyjny – jest odporny na kolejność ładowania i wygląda jak przykłady CKE. Jeśli piszesz nowocześnie, pamiętaj o jednym: <script> na końcu <body>.

Krok 3: pobranie i konwersja

Kontrolki zwracają napisy. Zanim policzysz, zamień na liczby – inaczej "5" + 5 da "55", a mnożenie przypadkiem zadziała, więc błąd zauważysz dopiero przy dodawaniu dopłaty.

Sprawdź się

Użytkownik wpisał 3 godziny i zaznaczył kask. Co wypisze ten (błędny) skrypt?

var godziny = document.getElementById('godziny').value;
var koszt = 8 * godziny;
koszt = koszt + 5;
document.getElementById('wynik').innerHTML = 'Koszt: ' + koszt + ' zł';
pobranie.js
const godziny = parseFloat(document.getElementById('godziny').value);   // "3" → 3
const liczbaRat = parseInt(document.getElementById('raty').value);        // "12" → 12
const kask = document.getElementById('kask').checked;                      // true / false (bez konwersji)
const miasto = document.getElementById('miasto').value;                    // napis – zostaje napisem

Przypomnienie z lekcji 13: parseFloat do kwot i wymiarów, parseInt do liczby sztuk i rat, Number gdy chcesz, by puste pole dało 0, valueAsNumber gdy wolisz pominąć value. Checkbox i radio czytasz przez checked – to już wartość logiczna.

Krok 4: obliczenie

Obliczenie to zwykle 2–4 linie: mnożenie, suma zaznaczonych, warunek na dopłatę lub cenę zależną od wyboru, czasem zaokrąglenie. Zasady:

  • Każdy checkbox osobno – kryterium „testując zaznaczenie każdego pola wyboru” (styczeń 2025). Cztery checkboxy = cztery if.
  • Cena zależna od wyboru – if/else if/else po wartości radio lub pola numerycznego, albo bezpośrednio parseFloat(radio.value), jeśli w value wpisałeś cenę.
  • „Zaokrąglona w górę do liczby całkowitej” = Math.ceil. „W dół” = Math.floor. „Do najbliższej” = Math.round. W styczniu 2023 (INF.03-01-23.01) brak zaokrąglenia w górę kosztował osobne kryterium.
  • Dzielenie przez liczbę rat – uważaj na 0: dzielenie przez zero daje Infinity. Zabezpiecz min="1" w HTML, a najlepiej jeszcze if.
  • Grosze – toFixed(2) daje napis z dwiema cyframi po przecinku ("12.50"). Użyj, gdy arkusz pokazuje kwotę z groszami; w innym wypadku zostaw liczbę.
obliczenie.js
// cena zależna od numeru (jak w arkuszu „stacja paliw” z czerwca 2022)
function cenaPaliwa(rodzaj) {
  if (rodzaj === 1) return 4;
  else if (rodzaj === 2) return 3.5;
  else return 0;
}
console.log(cenaPaliwa(2) * 30);         // 105

// zaokrąglenie w górę (jak w arkuszu „malarz” ze stycznia 2023)
const powierzchnia = 37;
console.log(Math.ceil(powierzchnia / 4)); // 10 – nie 9.25 i nie 9

// rata z groszami
const koszt = 8000;
const raty = 12;
console.log((koszt / raty).toFixed(2));   // "666.67" – uwaga: to napis
Konsola
Kliknij „Uruchom”, aby zobaczyć wynik

Krok 5: dokładny format napisu

To tu ucieka najwięcej punktów. Kryterium brzmi: „pod przyciskiem wyświetla się napis Liczba potrzebnych puszek: <wynik>”. Egzaminator porównuje z arkuszem – drobne literówki i wielkość liter są tolerowane, ale brakujące słowo, dwukropek, jednostka albo zła kolejność mogą kosztować punkt. Przy formacie „Kurs odbędzie się w X. Koszt całkowity: Y zł. Płacisz N rat po Z zł” sprawdzane są trzy osobne kryteria: miasto, koszt, raty.

Arkusz żądaStudent wypisałProblem
Koszt wypożyczenia: 29 zł29brak etykiety i jednostki
Koszt wypożyczenia: 29 złKoszt wypożyczenia 29złbrak dwukropka i spacji – egzaminator może uznać to za drobną literówkę, ale nie musi; po co ryzykować
Koszt wypożyczenia: 29 złKoszt wypożyczenia: 29 zł w alert()złe miejsce – kryterium „w akapicie” przepada
Koszt wypożyczenia: 29 złKoszt wypożyczenia: 29.000000001 złbłąd zmiennoprzecinkowy – toFixed(2) lub Math.round
Koszt wypożyczenia: 29 złKoszt wypożyczenia: NaN złpuste pole lub brak konwersji – walidacja

Dwa równoważne zapisy – wybierz ten, w którym robisz mniej literówek:

napis.js
const koszt = 29;
const miasto = 'Gdańsk';
const raty = 3;

// konkatenacja (dialekt egzaminacyjny) – pilnuj spacji w cudzysłowach
console.log('Koszt wypożyczenia: ' + koszt + ' zł');

// template string – tekst wygląda jak w arkuszu, wartości w ${}
console.log(`Kurs odbędzie się w ${miasto}. Koszt całkowity: ${koszt} zł. Płacisz ${raty} rat po ${(koszt / raty).toFixed(2)} zł`);
Konsola
Kliknij „Uruchom”, aby zobaczyć wynik

Jeśli wynik ma kilka linii („w pierwszej linii imię i nazwisko, poniżej treść zgłoszenia” – styczeń 2024), użyj innerHTML z <br>:

wiele-linii.js
wynik.innerHTML = imie.toUpperCase() + ' ' + nazwisko.toUpperCase() + '<br>' +
  'Treść Twojej sprawy:<br>' + tresc;

textContent wypisałby <br> jako zwykły tekst. Z kolei innerHTML traktuje treść jak HTML – jeśli użytkownik wpisze <b>, zostanie to zinterpretowane. Na egzaminie to bez znaczenia, w prawdziwej aplikacji wybieraj textContent, gdy nie potrzebujesz znaczników.

Sprawdź się

Arkusz wymaga napisu Liczba puszek: <wynik> w akapicie pod przyciskiem. Które kryterium NIE zostanie spełnione przez ten kod?

function policz() {
var powierzchnia = parseFloat(document.getElementById('pow').value);
var puszki = Math.ceil(powierzchnia / 4);
alert('Liczba puszek: ' + puszki);
}

Krok 6: walidacja – „Wprowadź poprawne dane.”

Niektóre arkusze (styczeń 2025, INF.03-02-25.01) wymagają: „gdy oba pola są wypełnione – wynik; w przeciwnym razie komunikat Wprowadź poprawne dane.”. Inne zwalniają z walidacji wprost („dla uproszczenia wszelką walidację należy pominąć”). Jeśli arkusz nic nie mówi – prosta walidacja nie zaszkodzi, ale nie trać na nią czasu.

Wzorzec: sprawdź na początku funkcji, wypisz komunikat i zakończ return, żeby nie liczyć dalej:

Walidacja pustych pól
function obliczPole() {
  const szerokosc = parseFloat(document.getElementById('szerokosc').value);
  const dlugosc = parseFloat(document.getElementById('dlugosc').value);
  const wynik = document.getElementById('wynik');

  if (isNaN(szerokosc) || isNaN(dlugosc)) {   // puste pole → parseFloat daje NaN
    wynik.innerHTML = 'Wprowadź poprawne dane.';
    return;                                    // koniec – nie liczymy dalej
  }

  const pole = szerokosc * dlugosc;
  wynik.innerHTML = 'Pole powierzchni pomieszczenia: ' + pole + ' m², koszt montażu ' + pole * 12 + ' zł';
}
Podgląd

isNaN(x) zwraca true, gdy x nie jest liczbą – łapie puste pole i błędny tekst. Jeśli chcesz dodatkowo odrzucić wartości ujemne lub zero: if (isNaN(szerokosc) || szerokosc <= 0 || …). Pełną walidację (HTML5 required, min, pattern) poznasz w lekcji 18.

Krok 7: test na dwóch zestawach danych

Zasady oceniania mówią wprost: „sprawdzane dla dwóch różnych miast”, „dla dwóch różnych wartości rat”. Egzaminator kliknie co najmniej dwa razy z innymi danymi. Ty zrób to pierwszy – i policz oczekiwany wynik na kartce, zanim klikniesz:

ZestawGodzinyRowerKaskOczekiwaneSkrypt wypisał
A3miejski (8)nie24Koszt wypożyczenia: 24 zł
B2elektryczny (20)tak45Koszt wypożyczenia: 45 zł

Zestawy dobieraj tak, by każda gałąź kodu zadziałała: inny radio, zaznaczony i niezaznaczony checkbox, inna pozycja listy. Jeśli zadanie ma walidację – trzeci test z pustym polem. Jeżeli wynik jest zły, nie zgaduj: otwórz konsolę (F12), dodaj console.log(godziny, cenaZaGodzine) i zobacz, która wartość jest nie taka.

Gdy skrypt nie działa – co sprawdzi egzaminator

Najgorszy scenariusz: błąd składni (brakujący nawias, literówka w getElementById) i skrypt w ogóle nie startuje. Zasady oceniania mają na to regułę: „jeśli skrypt się nie uruchamia, kryteria X sprawdza się w kodzie źródłowym” – w styczniu 2023 były to kryteria 5.1–5.4 (język, pobranie, dzielenie, zaokrąglenie), w styczniu 2025 – 5.1–5.4 i 5.8 (nazewnictwo). Kryteria wyjściowe (napis w akapicie, poprawny wynik dla dwóch zestawów) przepadają.

Wniosek: nawet niedziałający skrypt może zdobyć 4–5 z 8 kryteriów, jeśli w kodzie widać właściwe konstrukcje. Zadbaj, by w pliku było:

  • <script> z funkcją (kryterium języka),
  • document.getElementById(...).value lub .checked (pobranie danych),
  • linia z działaniem z arkusza: / 4, Math.ceil(...), * liczbaGodzin (obliczenia),
  • znaczące nazwy.

A żeby skrypt jednak działał – lista najczęstszych przyczyn „nic się nie dzieje”:

ObjawPrzyczynaJak znaleźć
kliknięcie nic nie robi, konsola: obliczKoszt is not definedliterówka w nazwie funkcji w onclick lub funkcja w innym bloku, który ma błąd składnikonsola F12 pokazuje też SyntaxError z numerem linii
Cannot read properties of null (reading 'value')id w HTML inne niż w getElementById (np. godziny vs godzina) albo <script> w <head> bez defer przy addEventListenersprawdź id, przenieś <script> na koniec <body>
wynik znika po ułamku sekundyprzycisk w <form> wysyła formularztype="button" lub usuń <form>
NaN złbrak konwersji przy pustym polu, literówka w value, parseFloat na checkboxieconsole.log każdej zmiennej
Koszt: 85 zł zamiast 13 złsklejanie napisów zamiast dodawaniaparseFloat przy odczycie
Infinitydzielenie przez 0 ratmin="1" + walidacja

Nazewnictwo – osobne kryterium od 2024

Od stycznia 2024 każdy arkusz zawiera zdanie „należy stosować znaczące nazewnictwo zmiennych i funkcji w języku polskim lub angielskim”, a zasady oceniania mają osobny punkt: „skrypt używa co najmniej jednej zmiennej lub funkcji, nazwy odzwierciedlają cel”. To najtańszy punkt na egzaminie – pod warunkiem, że piszesz cenaZaGodzine, a nie c.

Źle (punkt stracony)Dobrze (PL)Dobrze (EN)
function f1()function obliczKoszt()function calculateCost()
var a, b, x1let godziny, cenaZaGodzine, kosztlet hours, pricePerHour, cost
var zm = ...const liczbaRat = ...const installments = ...
function funkcja()function pokazWynik()function showResult()

Nazwy bez polskich znaków (dlugosc, nie długość) – polskie litery w identyfikatorach są technicznie dozwolone, ale proszą się o literówkę. Styl camelCase (cenaZaGodzine) lub z podkreśleniem (cena_za_godzine) – oba akceptowane, byle konsekwentnie.

Pełny przykład: od polecenia do rozwiązania

Zbierzmy wszystko w jedno rozwiązanie zadania przewodniego – z komentarzami, który fragment zdobywa które kryterium. Ten plik możesz traktować jako szablon, który na egzaminie przerabiasz pod konkretne polecenie.

Wypożyczalnia rowerów – rozwiązanie wzorcowe
// 5.1: JavaScript, funkcja wywoływana przyciskiem (onclick="obliczKoszt()")
// 5.6: znaczące nazwy – obliczKoszt, liczbaGodzin, cenaZaGodzine, koszt
function obliczKoszt() {
  // 5.2: pobranie danych z kontrolek + konwersja
  const liczbaGodzin = parseFloat(document.getElementById('godziny').value);
  const wybranyRower = document.querySelector('input[name="rower"]:checked');
  const cenaZaGodzine = parseFloat(wybranyRower.value);
  const zKaskiem = document.getElementById('kask').checked;

  // walidacja (arkusz jej nie wymaga, ale chroni przed NaN)
  if (isNaN(liczbaGodzin) || liczbaGodzin <= 0) {
    document.getElementById('wynik').innerHTML = 'Wprowadź poprawne dane.';
    return;
  }

  // 5.3: cena za godzinę × liczba godzin
  let koszt = cenaZaGodzine * liczbaGodzin;
  // 5.4: dopłata tylko przy zaznaczonym kasku
  if (zKaskiem) {
    koszt += 5;
  }

  // 5.5: dokładny format napisu w akapicie pod przyciskiem
  document.getElementById('wynik').innerHTML = 'Koszt wypożyczenia: ' + koszt + ' zł';
}
Podgląd

Testy: (3 h, miejski, bez kasku) → Koszt wypożyczenia: 24 zł; (2 h, elektryczny, kask) → Koszt wypożyczenia: 45 zł; (puste pole) → Wprowadź poprawne dane.

Sprawdź się

W którym miejscu kod poniżej ma błąd, przez który skrypt wyświetli Koszt: NaN zł dla każdego zestawu danych?

function obliczKoszt() {
var godziny = parseFloat(document.getElementById('godziny').value);
var cena = parseFloat(document.getElementById('kask').checked);
var koszt = godziny * 8 + cena;
document.getElementById('wynik').innerHTML = 'Koszt: ' + koszt + ' zł';
}

Na egzaminie

Ściąga

KrokSkładniaPrzykład
Przycisk + akapit<button type="button" onclick="f()"> + <p id="wynik"></p>akapit pod przyciskiem, pusty
Funkcja (egz.)function obliczKoszt() { … } + onclick="obliczKoszt()"nawiasy w atrybucie!
Funkcja (nowocz.)btn.addEventListener('click', obliczKoszt)bez nawiasów; <script> na końcu body
Odczyt liczbyparseFloat(document.getElementById('x').value)parseInt dla sztuk/rat
Odczyt checkboxadocument.getElementById('x').checkedtrue/false, bez konwersji
Odczyt radiodocument.querySelector('input[name="g"]:checked').valuejedno checked w HTML
Odczyt listydocument.getElementById('lista').valuetekst opcji, gdy brak value
Każdy checkboxif (a.checked) suma += 60; if (b.checked) suma += 150;osobne if
Cena wg wyboruif (rodzaj === 1) cena = 4; else if (rodzaj === 2) cena = 3.5; else cena = 0;lub parseFloat(radio.value)
W górę / w dółMath.ceil(x) / Math.floor(x) / Math.round(x)Math.ceil(37 / 4) → 10
Groszekwota.toFixed(2)zwraca napis "12.50"
Walidacjaif (isNaN(a) || isNaN(b)) { wynik.innerHTML = 'Wprowadź poprawne dane.'; return; }na początku funkcji
Napis'Koszt: ' + koszt + ' zł' lub `Koszt: ${koszt} zł`przepisz format z arkusza
Wynikdocument.getElementById('wynik').innerHTML = napis;<br> dla kilku linii
DebugF12 → konsola; console.log(zmienna)po każdej zmianie

Zadania

Zadania 2–4 rób na czas: 20 minut każde, bez podglądania rozwiązania. Po skończeniu oceń się według listy kryteriów – uczciwie, 0 albo 1.

Zadanie 1
łatwe

Przelicznik walut – rozgrzewka

Pole liczbowe „Kwota w PLN”, lista rozwijana z walutami: EUR (kurs 4,30), USD (3,95), GBP (5,05) – kurs wpisz w atrybucie value opcji, nazwę jako tekst. Przycisk Przelicz. Pod przyciskiem: <kwota> PLN = <wynik> <waluta>, wynik z dwoma miejscami po przecinku, np. 100 PLN = 23.26 EUR.

Pokaż rozwiązanie
Rozwiązanie: Przelicznik walut
function przelicz() {
  const kwotaPln = parseFloat(document.getElementById('kwota').value);
  const lista = document.getElementById('waluta');
  const kurs = parseFloat(lista.value);                        // value opcji = kurs
  const nazwaWaluty = lista.options[lista.selectedIndex].text; // widoczny tekst = nazwa
  const wynik = (kwotaPln / kurs).toFixed(2);
  document.getElementById('wynik').innerHTML = kwotaPln + ' PLN = ' + wynik + ' ' + nazwaWaluty;
}
Podgląd
Zadanie 2
średniejak na INF.03

Szkoła jazdy – raty (20 min)

Strona raty.html zawiera: dwa pola wyboru „Kurs kategorii B – 3200 zł” i „Jazdy doszkalające – 600 zł”, pole numeryczne „Liczba rat” (wartości od 1 do 12, domyślnie 1), listę rozwijaną „Oddział” z pozycjami Poznań, Wrocław, Łódź, przycisk „Oblicz” i pusty akapit pod przyciskiem.

Skrypt w JavaScript, uruchamiany przyciskiem, sumuje ceny zaznaczonych szkoleń, dzieli sumę przez liczbę rat i wypisuje w akapicie: Szkolenie w oddziale <oddział>. Koszt całkowity: <koszt> zł. Płacisz <liczba> rat po <rata> zł. Stosuj znaczące nazwy zmiennych i funkcji.

Kryteria samooceny (0/1):

  1. Skrypt w JavaScript, co najmniej jedna poprawna instrukcja; funkcja wywoływana przyciskiem.
  2. Pobiera dane z co najmniej jednej kontrolki.
  3. Liczy koszt zaznaczonych szkoleń, testując zaznaczenie każdego z dwóch pól wyboru.
  4. Pobiera liczbę rat i dzieli przez nią koszt.
  5. Wynik zawiera nazwę oddziału z listy – poprawnie dla dwóch różnych oddziałów.
  6. Wynik zawiera koszt całkowity.
  7. Wynik zawiera liczbę rat i wysokość raty – poprawnie dla dwóch różnych liczb rat.
  8. Znaczące nazwy zmiennych i funkcji.

Testy: (oba kursy, 4 raty, Wrocław) → Szkolenie w oddziale Wrocław. Koszt całkowity: 3800 zł. Płacisz 4 rat po 950 zł; (tylko kat. B, 1 rata, Łódź) → koszt 3200, rata 3200.

Pokaż rozwiązanie
Rozwiązanie: Szkoła jazdy
function obliczRaty() {
  // kryterium 3: każde pole wyboru osobno
  let kosztCalkowity = 0;
  if (document.getElementById('kursB').checked) kosztCalkowity += 3200;
  if (document.getElementById('doszkalajace').checked) kosztCalkowity += 600;

  // kryterium 4: liczba rat i dzielenie
  const liczbaRat = parseInt(document.getElementById('raty').value);
  const rata = kosztCalkowity / liczbaRat;

  // kryterium 5: oddział z listy (tekst opcji)
  const oddzial = document.getElementById('oddzial').value;

  // kryteria 5–7: dokładny format
  document.getElementById('wynik').innerHTML =
    'Szkolenie w oddziale ' + oddzial + '. Koszt całkowity: ' + kosztCalkowity +
    ' zł. Płacisz ' + liczbaRat + ' rat po ' + rata + ' zł';
}
Podgląd

Jeśli rata wychodzi z długim ułamkiem (np. 3800 / 3), możesz użyć rata.toFixed(2) – jeśli arkusz nie precyzuje zaokrąglenia, oba warianty powinny być w porządku.

Zadanie 3
średniejak na INF.03

Ogrodzenie – z walidacją (20 min)

Strona koszt.html zawiera: dwa pola numeryczne „Długość ogrodzenia [m]” i „Wysokość [m]”, trzy przyciski opcji „Siatka – 45 zł/m²”, „Panel – 80 zł/m²”, „Drewno – 120 zł/m²” (siatka domyślnie zaznaczona), przycisk „Oblicz” i pusty akapit pod przyciskiem.

Skrypt w JavaScript po kliknięciu: jeśli oba pola liczbowe są wypełnione – oblicza powierzchnię (długość × wysokość) oraz koszt (powierzchnia × cena wybranego materiału) i wypisuje: Powierzchnia ogrodzenia: <powierzchnia> m², koszt: <koszt> zł. W przeciwnym razie wypisuje: Wprowadź poprawne dane. Stosuj znaczące nazwy.

Kryteria samooceny (0/1):

  1. JavaScript, co najmniej jedna poprawna instrukcja, funkcja wywoływana przyciskiem.
  2. Pobranie danych z co najmniej jednej kontrolki.
  3. Powierzchnia = długość × wysokość.
  4. Koszt zależny od zaznaczonego materiału – poprawny dla dwóch różnych materiałów.
  5. Przy pustym którymkolwiek polu – komunikat Wprowadź poprawne dane. zamiast wyniku.
  6. Wynik w podanym formacie w akapicie pod przyciskiem.
  7. Znaczące nazwy.

Testy: (20, 1.5, panel) → Powierzchnia ogrodzenia: 30 m², koszt: 2400 zł; (10, 2, drewno) → 20 m², 2400 zł; (puste, 2, siatka) → Wprowadź poprawne dane.

Pokaż rozwiązanie
Rozwiązanie: Ogrodzenie
function obliczKosztOgrodzenia() {
  const dlugosc = parseFloat(document.getElementById('dlugosc').value);
  const wysokosc = parseFloat(document.getElementById('wysokosc').value);
  const akapit = document.getElementById('wynik');

  // kryterium 5: walidacja – puste pole daje NaN
  if (isNaN(dlugosc) || isNaN(wysokosc)) {
    akapit.textContent = 'Wprowadź poprawne dane.';
    return;
  }

  // kryterium 3 i 4
  const powierzchnia = dlugosc * wysokosc;
  const cenaZaMetr = parseFloat(document.querySelector('input[name="material"]:checked').value);
  const koszt = powierzchnia * cenaZaMetr;

  // kryterium 6
  akapit.textContent = `Powierzchnia ogrodzenia: ${powierzchnia} m², koszt: ${koszt} zł`;
}

document.getElementById('oblicz').addEventListener('click', obliczKosztOgrodzenia);
Podgląd

Tu celowo styl nowoczesny (addEventListener, textContent, template string) – zwróć uwagę, że skrypt jest pod przyciskiem, więc getElementById('oblicz') go znajduje.

Zadanie 4
średniejak na INF.03

Nawóz do trawnika – zaokrąglanie (20 min)

Strona nawoz.html zawiera: pole numeryczne „Powierzchnia trawnika [m²]”, przycisk „Policz” i pusty akapit pod przyciskiem. Jeden worek nawozu wystarcza na 25 m², a kosztuje 39 zł.

Skrypt w JavaScript po kliknięciu pobiera powierzchnię, oblicza liczbę worków (powierzchnia / 25, zaokrąglona w górę do liczby całkowitej – nawóz sprzedaje się tylko w całych workach) i koszt (worki × 39 zł). W akapicie wypisuje, w dwóch liniach: Liczba worków: <worki> oraz Koszt: <koszt> zł. Stosuj znaczące nazwy.

Kryteria samooceny (0/1):

  1. JavaScript, co najmniej jedna poprawna instrukcja, funkcja wywoływana przyciskiem.
  2. Pobranie powierzchni z pola.
  3. Dzielenie powierzchni przez 25.
  4. Wynik zaokrąglony w górę do liczby całkowitej (dowolną metodą).
  5. Koszt = liczba worków × 39.
  6. Dwie linie w podanym formacie w akapicie pod przyciskiem – poprawne dla dwóch różnych powierzchni.
  7. Znaczące nazwy.

Testy: 100 m² → 4 worki, 156 zł; 101 m² → 5 worków, 195 zł; 25 m² → 1 worek, 39 zł.

Pokaż rozwiązanie
Rozwiązanie: Nawóz do trawnika
function policzWorki() {
  const powierzchnia = parseFloat(document.getElementById('powierzchnia').value);
  const liczbaWorkow = Math.ceil(powierzchnia / 25);   // kryteria 3 i 4: dzielenie + w górę
  const koszt = liczbaWorkow * 39;                     // kryterium 5
  document.getElementById('wynik').innerHTML =
    'Liczba worków: ' + liczbaWorkow + '<br>Koszt: ' + koszt + ' zł';   // kryterium 6: dwie linie
}
Podgląd

Bez Math.ceil dla 101 m² wyszłoby 4.04 worka – kryterium 4 stracone. Math.round dałoby 4 – też źle. Tylko Math.ceil (lub parseInt(x) + 1 dla niecałkowitych – ale po co kombinować).

Zadanie 5
trudne

Znajdź pięć błędów

Uczeń oddał poniższy skrypt do zadania „Nawóz do trawnika”. Skrypt nie działa albo działa źle. Znajdź pięć błędów (składnia, logika, kryteria) i popraw kod tak, by zdobył wszystkie kryteria z zadania 4.

nawoz.html (z błędami)
<input type="number" id="powierzchnia">
<button onclick="policz">Policz</button>
<p id="wynik"></p>
<script>
  function policz() {
    var p = document.getElementById('powierzchnia').value;
    var w = Math.round(p / 25);
    var k = w + 39;
    alert('Liczba worków: ' + w + '<br>Koszt: ' + k + ' zł');
  }
</script>
Pokaż rozwiązanie

Błędy:

  1. onclick="policz" – brak nawiasów, funkcja nie zostanie wywołana. Poprawnie: onclick="policz()".
  2. var p = ....value bez konwersji – p to napis. Tu dzielenie akurat go skonwertuje, ale to przypadek: przy pierwszym dodawaniu (np. dopłacie) dostałbyś sklejanie napisów. Konwertuj zawsze – parseFloat.
  3. Math.round zamiast Math.ceil – 101 m² da 4 worki zamiast 5 (kryterium „w górę”).
  4. w + 39 zamiast w * 39 – koszt to liczba worków razy cena.
  5. alert(...) zamiast akapitu pod przyciskiem – kryterium miejsca; dodatkowo <br> w alercie wyświetli się dosłownie.
  6. (bonus) Nazwy p, w, k, policz – jednoliterowe zmienne kosztują kryterium nazewnictwa.
Rozwiązanie: poprawiony skrypt
function policzWorki() {
  var powierzchnia = parseFloat(document.getElementById('powierzchnia').value);   // 2: konwersja
  var liczbaWorkow = Math.ceil(powierzchnia / 25);                                 // 3: w górę
  var koszt = liczbaWorkow * 39;                                                   // 4: mnożenie
  document.getElementById('wynik').innerHTML =                                     // 5: akapit, nie alert
    'Liczba worków: ' + liczbaWorkow + '<br>Koszt: ' + koszt + ' zł';
}
// 1: w HTML onclick="policzWorki()" – z nawiasami; 6: znaczące nazwy
Podgląd

Test powtórkowy

Test powtórkowy

Format jak w części pisemnej INF.03 – 4 odpowiedzi, 1 poprawna.

0/0poprawnych
Sprawdź się

Który zapis w HTML poprawnie uruchomi funkcję oblicz po kliknięciu przycisku?

Sprawdź się

W polu wpisano 4. Co wypisze ten kod w dialekcie egzaminacyjnym?

var ilosc = document.getElementById('ilosc').value;
var cena = 10;
document.getElementById('wynik').innerHTML = 'Razem: ' + (ilosc + cena) + ' zł';
Sprawdź się

Arkusz: „liczba puszek zaokrąglona w górę do liczby całkowitej”. Powierzchnia 37 m², 1 puszka na 4 m². Które wyrażenie spełnia kryterium?

Sprawdź się

Która właściwość wpisze tekst wyniku do pustego akapitu <p id='wynik'></p>?

Sprawdź się

Skrypt ma działać przy <script> umieszczonym w <head> bez atrybutu defer. Które podpięcie zdarzenia zadziała na pewno?

Sprawdź się

Arkusz wymaga wyniku „dla dwóch różnych miast z listy”. Co to oznacza dla twojego kodu?

Sprawdź się

Skrypt nie uruchamia się z powodu błędu składni. Które kryterium egzaminator może mimo to zaliczyć na podstawie kodu źródłowego?

Sprawdź się

Które nazwy spełniają kryterium „znaczące nazewnictwo zmiennych i funkcji”?

Sprawdź się

Pole liczbowe jest puste. Który warunek wykryje to po var w = parseFloat(pole.value);?

Sprawdź się

Co wypisze kod, gdy użytkownik zaznaczył checkbox #rabat?

var cena = 200;
if (document.getElementById('rabat').checked == true) {
cena = cena * 0.9;
}
document.getElementById('wynik').innerHTML = 'Cena: ' + cena + ' zł';