Kurs JavaScript i TypeScript · Moduł 1: Podstawy JavaScript
Projekt końcowy: System rejestracji dinozaurów
W tej lekcji4
Gratulacje, młody paleontologu! Dotarłeś do końca pierwszego modułu i pora sprawdzić, czego się nauczyłeś. W tym projekcie końcowym połączysz wszystkie poznane koncepcje JavaScript w jeden spójny system - System Rejestracji Dinozaurów Parku Jurajskiego.
Wyobraź sobie, że laboratorium genetyczne właśnie sklonowało nową partię dinozaurów. Jako główny programista parku, Twoim zadaniem jest stworzenie systemu, który zarejestruje każdego nowego osobnika, przypisze mu odpowiednie parametry i wyświetli raport w konsoli. To jak tworzenie cyfrowego DNA każdego dinozaura w naszej bazie danych!
Zanim przejdziemy do kodu, przypomnijmy sobie narzędzia, które mamy do dyspozycji: zmienne (var, let, const), typy danych (string, number, boolean, null, undefined), operatory, instrukcje warunkowe, pętle, funkcje oraz konsolę do wyświetlania wyników.
Cel projektu
Zbudujesz kompletny system rejestracji dinozaurów, który:
- Przechowuje dane o dinozaurach w zmiennych odpowiednich typów
- Wykorzystuje operatory do obliczeń i porównań
- Stosuje instrukcje warunkowe do klasyfikacji gatunków
- Używa pętli do przetwarzania danych
- Organizuje logikę w funkcje
- Wyświetla czytelne raporty w konsoli
Wymagania funkcjonalne
1. Rejestracja osobnika - zmienne i typy danych
Pierwszym krokiem jest stworzenie zestawu zmiennych przechowujących dane o dinozaurze. Pamiętaj o doborze odpowiednich typów danych i sposobów deklaracji zmiennych.
1// Stałe dane gatunkowe (nie zmieniają się po rejestracji)
2const speciesName = "Tyrannosaurus Rex";
3const speciesCode = "TREX-001";
4const registrationDate = "2024-03-15";
5
6// Zmienne dane osobnika (mogą się zmieniać w czasie)
7let currentWeight = 8500; // w kilogramach
8let height = 5.2; // w metrach
9let isHealthy = true;
10let currentEnclosure = "Sektor A-7";
11
12// Dane jeszcze nieznane
13let lastFeedingTime = null;
14let veterinaryNotes = undefined;
15
16// Użycie var dla demonstracji (w praktyce unikamy var)
17var parkId = 42;
18
19// Wyświetlanie danych w konsoli
20console.log("=== REJESTRACJA DINOZAURA ===");
21console.log("Gatunek:", speciesName);
22console.log("Kod:", speciesCode);
23console.log("Waga:", currentWeight, "kg");
24console.log("Wzrost:", height, "m");
25console.log("Zdrowy:", isHealthy);
26console.log("Wybieg:", currentEnclosure);
27console.log("Ostatnie karmienie:", lastFeedingTime);
28console.log("Notatki weterynaryjne:", veterinaryNotes);Zwróć uwagę na dobór const vs let - dane gatunkowe się nie zmieniają, ale parametry osobnika mogą ulegać zmianom. Wartość null oznacza celowy brak danych (jeszcze nie karmiony), a undefined - dane jeszcze nie wprowadzone.
2. Klasyfikacja gatunku - instrukcje warunkowe i operatory
System musi automatycznie klasyfikować dinozaury na podstawie ich parametrów. Tu wykorzystasz operatory porównania, logiczne oraz instrukcje warunkowe.
1// Parametry dinozaura
2const weight = 8500;
3const diet = "carnivore"; // "carnivore", "herbivore", "omnivore"
4const aggressionLevel = 9; // skala 1-10
5
6// Klasyfikacja poziomu zagrożenia za pomocą if/else
7let threatLevel;
8let requiresDoubleBarrier;
9
10if (diet === "carnivore" && aggressionLevel > 7) {
11 threatLevel = "KRYTYCZNY";
12 requiresDoubleBarrier = true;
13} else if (diet === "carnivore" && aggressionLevel <= 7) {
14 threatLevel = "WYSOKI";
15 requiresDoubleBarrier = true;
16} else if (diet === "omnivore") {
17 threatLevel = "ŚREDNI";
18 requiresDoubleBarrier = false;
19} else {
20 threatLevel = "NISKI";
21 requiresDoubleBarrier = false;
22}
23
24// Klasyfikacja wielkości za pomocą switch
25let sizeCategory;
26switch (true) {
27 case weight > 5000:
28 sizeCategory = "kolosalny";
29 break;
30 case weight > 1000:
31 sizeCategory = "duży";
32 break;
33 case weight > 100:
34 sizeCategory = "średni";
35 break;
36 default:
37 sizeCategory = "mały";
38 break;
39}
40
41// Operatory logiczne do warunków specjalnych
42const needsReinforcement = weight > 5000 || aggressionLevel >= 9;
43const canCohabitate = diet !== "carnivore" && aggressionLevel < 5;
44const isDocile = !requiresDoubleBarrier && aggressionLevel <= 3;
45
46console.log("Poziom zagrożenia:", threatLevel);
47console.log("Kategoria wielkości:", sizeCategory);
48console.log("Wymaga podwójnej bariery:", requiresDoubleBarrier);
49console.log("Wymaga wzmocnień:", needsReinforcement);
50console.log("Może współżyć z innymi:", canCohabitate);
51console.log("Łagodny:", isDocile);3. Raport żywieniowy - pętle i operatory arytmetyczne
System musi obliczyć zapotrzebowanie żywieniowe na cały tydzień. Tu wykorzystasz pętle for i while oraz operatory arytmetyczne.
1const dinoName = "Rex";
2const baseFood = 150; // kg mięsa dziennie
3const growthRate = 1.02; // 2% wzrostu dziennie
4
5console.log("=== RAPORT ŻYWIENIOWY ===");
6console.log("Dinozaur:", dinoName);
7
8// Pętla for - obliczanie dziennego zapotrzebowania
9let totalFood = 0;
10
11for (let day = 1; day <= 7; day++) {
12 // Każdego dnia dinozaur potrzebuje więcej jedzenia
13 let dailyFood = baseFood * (growthRate ** (day - 1));
14 dailyFood = Math.round(dailyFood * 100) / 100;
15 totalFood += dailyFood;
16
17 console.log("Dzień " + day + ": " + dailyFood + " kg");
18}
19
20console.log("Suma tygodniowa:", Math.round(totalFood) + " kg");
21
22// Pętla while - sprawdzanie zapasów magazynu
23let stockKg = 2000; // zapas mięsa w magazynie
24let daysUntilEmpty = 0;
25let dailyConsumption = baseFood;
26
27while (stockKg > 0) {
28 stockKg -= dailyConsumption;
29 dailyConsumption *= growthRate; // rośnie z czasem
30 daysUntilEmpty++;
31}
32
33console.log("Zapasy wystarczą na:", daysUntilEmpty, "dni");
34
35// Operator reszty z dzielenia - harmonogram karmienia
36for (let hour = 0; hour < 24; hour++) {
37 if (hour % 8 === 0) {
38 console.log("Godzina " + hour + ":00 - PORA KARMIENIA!");
39 }
40}4. Funkcje systemowe - organizacja kodu
Każdy podsystem parku powinien być zamknięty w funkcji. To pozwala na wielokrotne użycie kodu i lepszą organizację.
1// Funkcja rejestrująca dinozaura
2function registerDinosaur(name, species, weight, diet) {
3 console.log("--- Rejestracja ---");
4 console.log("Imię:", name);
5 console.log("Gatunek:", species);
6 console.log("Waga:", weight, "kg");
7 console.log("Dieta:", diet);
8
9 // Zwracamy kod rejestracyjny
10 const code = species.substring(0, 3).toUpperCase() + "-" + parkId;
11 parkId++; // zwiększamy globalny licznik
12 return code;
13}
14
15// Zmienna globalna jako licznik
16var parkId = 1;
17
18// Funkcja obliczająca BMI dinozaura
19function calculateDinoBMI(weight, height) {
20 if (height <= 0) {
21 console.log("Błąd: wzrost musi być większy od 0!");
22 return null;
23 }
24 const bmi = weight / (height * height);
25 return Math.round(bmi * 100) / 100;
26}
27
28// Funkcja generująca alert bezpieczeństwa
29function securityAlert(name, threatLevel, isContained) {
30 if (!isContained) {
31 console.log("!!! ALARM !!! Dinozaur " + name + " wydostał się!");
32 console.log("Poziom zagrożenia: " + threatLevel);
33 return true; // ewakuacja wymagana
34 }
35 console.log(name + " - status: bezpieczny");
36 return false; // brak zagrożenia
37}
38
39// Komentarze wieloliniowe opisujące logikę systemu
40/*
41 System rejestracji dinozaurów:
42 1. Rejestrujemy nowego osobnika
43 2. Obliczamy jego BMI
44 3. Sprawdzamy status bezpieczeństwa
45 4. Generujemy raport końcowy
46*/
47
48// Użycie funkcji
49const rexCode = registerDinosaur("Rex", "Tyrannosaurus", 8500, "carnivore");
50const triCode = registerDinosaur("Tricia", "Triceratops", 6000, "herbivore");
51const veloCode = registerDinosaur("Blue", "Velociraptor", 75, "carnivore");
52
53console.log("Kody rejestracyjne:", rexCode, triCode, veloCode);
54
55const rexBMI = calculateDinoBMI(8500, 5.2);
56const triBMI = calculateDinoBMI(6000, 2.8);
57console.log("BMI Rexa:", rexBMI);
58console.log("BMI Tricii:", triBMI);
59
60// Konwersja typów w praktyce
61const userInput = "7500"; // dane z formularza jako string
62const numericWeight = Number(userInput);
63console.log("Typ przed konwersją:", typeof userInput);
64console.log("Typ po konwersji:", typeof numericWeight);
65console.log("Czy to liczba?", !isNaN(numericWeight));
66
67// Konkatenacja vs dodawanie
68console.log("500" + 100); // "500100" - konkatenacja stringów!
69console.log(Number("500") + 100); // 600 - prawidłowe dodawanie
70
71// Boolean w warunkach
72const isElectrified = true;
73const hasPower = false;
74const fenceActive = isElectrified && hasPower;
75console.log("Ogrodzenie aktywne:", fenceActive); // falseWskazówki implementacyjne
Przy tworzeniu własnego systemu rejestracji pamiętaj o kilku kluczowych zasadach:
- Dobierz odpowiedni typ deklaracji zmiennej -
constdla wartości stałych (gatunek, data rejestracji),letdla wartości zmiennych (waga, lokalizacja), unikajvar - Używaj komentarzy - zarówno jednoliniowych (
//) jak i wieloliniowych (/* */), aby dokumentować logikę systemu - Pamiętaj o średnikach - choć JavaScript pozwala je pomijać dzięki ASI, warto je stosować dla czytelności
- Konwertuj typy świadomie - używaj
Number(),String(),Boolean()zamiast polegać na niejawnej konwersji - Testuj w konsoli -
console.log(),console.table()iconsole.warn()to Twoi najlepsi przyjaciele przy debugowaniu - Organizuj kod w funkcje - każda logiczna operacja (rejestracja, klasyfikacja, raport) powinna być osobną funkcją
Powodzenia!
Stwórz swój własny System Rejestracji Dinozaurów w edytorze poniżej. Wykorzystaj wszystkie poznane koncepcje: zmienne, typy danych, operatory, instrukcje warunkowe, pętle i funkcje. Pamiętaj - w Parku Jurajskim nie ma miejsca na błędy, więc testuj swój kod dokładnie!
Jak powiedział dr Ian Malcolm: "Życie zawsze znajdzie sposób" - a Ty właśnie znalazłeś swój sposób na JavaScript!
Kod do tej lekcji: index.js
1// Projekt końcowy: System rejestracji dinozaurów
2// Połącz wszystkie poznane koncepcje: zmienne, typy, warunki, pętle, funkcje
3
4// === 1. BAZA DANYCH GATUNKÓW ===
5// TODO: Stwórz tablicę obiektów z danymi dinozaurów
6// Każdy dinozaur powinien mieć: name, species, weight, diet, isHealthy, enclosure
7const parkDinosaurs = [
8 // TODO: Dodaj co najmniej 5 dinozaurów
9];
10
11// === 2. FUNKCJA REJESTRACJI ===
12// TODO: Stwórz funkcję registerDinosaur(name, species, weight, diet)
13// Powinna zwracać obiekt z danymi + automatycznie wygenerowanym ID i datą rejestracji
14function registerDinosaur(name, species, weight, diet) {
15 // TODO: Zwróć obiekt dinozaura z polami:
16 // id mod -(np. "DINO-001"), name, species, weight, diet,
17 // isHealthy (domyślnie true), registrationDate
18}
19
20// === 3. KLASYFIKACJA GATUNKU ===
21// TODO: Stwórz funkcję classifyDinosaur(dino) która na podstawie diet i weight
22// zwraca level zagrożenia: "critical", "high", "medium", "low"
23function classifyDinosaur(dino) {
24 // TODO: Użyj if/else do klasyfikacji
25 // Mięsożerca > 5000kg = "critical"
26 // Mięsożerca <= 5000kg = "high"
27 // Roślinożerca > 3000kg = "medium"
28 // Pozostałe = "low"
29}
30
31// === 4. RAPORT PARKU ===
32// TODO: Użyj pętli do przejścia po tablicy dinozaurów
33// Wyświetl raport: nazwa, gatunek, level zagrożenia
34function generateParkReport(dinosaurs) {
35 console.log("=== RAPORT PARKU JURAJSKIEGO ===");
36 // TODO: Użyj for...of do iteracji
37 // Dla każdego dinozaura wyświetl dane i klasyfikacje
38}
39
40// === 5. STATYSTYKI ===
41// TODO: Oblicz i wyświetl statystyki parku
42// - Łączna liczba dinozaurów
43// - Średnia waga
44// - Liczba mięsożernych vs roślinożernych
45
46// Uruchom system:
47console.log("System rejestracji dinozaurów uruchomiony!");Widzisz błąd w tej lekcji?