diff --git a/.gitignore b/.gitignore index ea8c4bf..56ce728 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +*/target diff --git a/JR-priprava-na-skusku5/Cargo.toml b/JR-priprava-na-skusku5/Cargo.toml new file mode 100644 index 0000000..52ae4b0 --- /dev/null +++ b/JR-priprava-na-skusku5/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "JR-priprava-na-skusku5" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/JR-priprava-na-skusku5/src/main.rs b/JR-priprava-na-skusku5/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/JR-priprava-na-skusku5/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/JR-priprava-na-skusku5/zadanie/1.jpg b/JR-priprava-na-skusku5/zadanie/1.jpg new file mode 100644 index 0000000..49cbba9 Binary files /dev/null and b/JR-priprava-na-skusku5/zadanie/1.jpg differ diff --git a/JR-priprava-na-skusku5/zadanie/2.jpg b/JR-priprava-na-skusku5/zadanie/2.jpg new file mode 100644 index 0000000..9a3911e Binary files /dev/null and b/JR-priprava-na-skusku5/zadanie/2.jpg differ diff --git a/JR-priprava-na-skusku5/zadanie/3.jpg b/JR-priprava-na-skusku5/zadanie/3.jpg new file mode 100644 index 0000000..917309e Binary files /dev/null and b/JR-priprava-na-skusku5/zadanie/3.jpg differ diff --git a/JR-priprava-na-skusku5/zadanie/4.jpg b/JR-priprava-na-skusku5/zadanie/4.jpg new file mode 100644 index 0000000..fc33869 Binary files /dev/null and b/JR-priprava-na-skusku5/zadanie/4.jpg differ diff --git a/priprava/rust_skuska_priprava.md b/priprava/rust_skuska_priprava.md new file mode 100644 index 0000000..4628d2a --- /dev/null +++ b/priprava/rust_skuska_priprava.md @@ -0,0 +1,821 @@ +# Intenzívna príprava na skúšku z Rustu + +## Analýza vzoru skúšok + +Z troch skúšok (Knižnica, Obesenec, Milionár) vyplýva **vždy rovnaký vzor**: + +1. **Štruktúry** s derives (Serialize, Deserialize, Default, Clone, PartialEq) +2. **Enumy** s derives + Display +3. **Asociované funkcie** (konštruktory `::new`, `::nacitaj_zo_suboru`) +4. **Metódy** na štruktúrach (CRUD operácie, filtrovanie, štatistiky) +5. **JSON serializácia/deserializácia** cez serde +6. **File I/O** s PathBuf → Option alebo bool +7. **CLI aplikácia** s knižnicou `clap` (subcommands + argumenty) +8. **Trait definícia + implementácia** (IOManager, Display) +9. **Iterátory** (filter, find, map, collect) +10. **Option/Result** return typy všade + +### Povolené knižnice +- `clap` (derive), `serde` (derive), `serde_json`, `itertools`, `rand` +- `chrono` (serde), `futures`, `color-eyre`, `dotenvy` + +--- + +## BLOK 1: Štruktúry, Enumy, Derives (základ všetkého) + +### Cvičenie 1.1 — Filmová databáza +Implementuj nasledovné: + +``` +Enum Zaner: + - Hodnoty: Akcia, Komedia, Horor, Drama, SciFi, Dokumentarny + - Požadované traity: Default, Display, Serialize, Deserialize, PartialEq, Clone + - Default vráti hodnotu Drama + +Štruktúra Film: + - nazov: String + - reziser: String + - rok: u16 + - zaner: Zaner + - hodnotenie: f32 (0.0 - 10.0) + - Požadované traity: Default, Serialize, Deserialize, Clone + +Štruktúra Filmoteka: + - filmy: Vec + - Požadované traity: Default, Serialize, Deserialize +``` + +**Úlohy:** +1. Implementuj `Display` pre `Zaner` (výstup: slovenský názov žánru) +2. Implementuj `Display` pre `Film` (formát: `"Nazov (rok) - Reziser [Zaner] ★hodnotenie"`) +3. Implementuj `Default` pre `Zaner` + +### Cvičenie 1.2 — Enum s dátami +``` +Enum Stav: + - Aktivny + - Pozastaveny { dovod: String } + - Ukonceny { datum: String, hodnotenie: u8 } + - Požadované traity: Serialize, Deserialize, Clone, PartialEq +``` + +Implementuj `Display` pre `Stav`: +- Aktivny → "Aktívny" +- Pozastaveny → "Pozastavený: {dovod}" +- Ukonceny → "Ukončený dňa {datum} s hodnotením {hodnotenie}" + +--- + +## BLOK 2: Asociované funkcie a Konštruktory + +### Cvičenie 2.1 — ::new a ::nacitaj_zo_suboru + +Pre štruktúru `Filmoteka`: +```rust +// Asociovaná funkcia - načíta z JSON súboru +// Parameter: &std::path::PathBuf +// Návratová hodnota: Option +// Ak súbor neexistuje → None +// Ak sa nepodarí deserializovať → None +fn nacitaj_zo_suboru(cesta: &std::path::PathBuf) -> Option + +// Metóda - uloží do JSON súboru +// Parameter: &std::path::PathBuf +// Návratová hodnota: bool (true ak úspech) +fn uloz_do_suboru(&self, cesta: &std::path::PathBuf) -> bool +``` + +**Kľúčové vzory na zapamätanie:** +```rust +// Čítanie súboru +let obsah = std::fs::read_to_string(cesta).ok()?; +let data: T = serde_json::from_str(&obsah).ok()?; + +// Zápis do súboru +let json = serde_json::to_string_pretty(&self).ok()?; +std::fs::write(cesta, json).ok()?; +``` + +### Cvičenie 2.2 — Konštruktor s validáciou + +```rust +// Pre štruktúru Film: +// Funkcia ::new berie nazov: &str, reziser: &str, rok: u16, zaner: Zaner, hodnotenie: f32 +// Ak hodnotenie nie je v rozsahu 0.0..=10.0, vráti None +// Inak vráti Some(Film) +fn new(nazov: &str, reziser: &str, rok: u16, zaner: Zaner, hodnotenie: f32) -> Option +``` + +--- + +## BLOK 3: Metódy — CRUD + Filtrovanie + Štatistiky + +### Cvičenie 3.1 — CRUD operácie (vzor z Knižnica) + +Pre `Filmoteka`: +```rust +// Pridaj film. Ak film s rovnakým názvom už existuje → Err(()) +fn pridaj_film(&mut self, film: Film) -> Result<(), ()> + +// Odstráň film podľa názvu. Ak neexistuje → Err(()) +fn odstran_film(&mut self, nazov: &str) -> Result +``` + +### Cvičenie 3.2 — Filtrovanie (vzor z Knižnica) + +```rust +// Vráti film podľa názvu +fn daj_film_podla_nazvu(&self, nazov: &str) -> Option<&Film> + +// Vráti všetky filmy daného režiséra +fn daj_filmy_rezisera(&self, reziser: &str) -> Vec<&Film> + +// Vráti všetky filmy daného žánru +fn daj_filmy_podla_zanru(&self, zaner: &Zaner) -> Vec<&Film> + +// Vráti filmy s hodnotením vyšším ako zadané +fn daj_filmy_nad_hodnotenie(&self, min: f32) -> Vec<&Film> +``` + +### Cvičenie 3.3 — Štatistiky (vzor z Knižnica) + +```rust +// Pre každý žáner vypíše počet filmov +// Formát: "Žáner: počet filmov" +fn vypis_statistiky_zanrov(&self) + +// Priemerné hodnotenie filmov daného režiséra +fn priemerne_hodnotenie_rezisera(&self, reziser: &str) -> Option +``` + +**Tip:** Použi `itertools` alebo `HashMap` na zoskupenie: +```rust +use std::collections::HashMap; +let mut mapa: HashMap<&str, Vec<&Film>> = HashMap::new(); +for film in &self.filmy { + mapa.entry(&film.reziser).or_default().push(film); +} +``` + +--- + +## BLOK 4: Traity (vzor z Obesenec — IOManager) + +### Cvičenie 4.1 — Definícia a implementácia traitu + +```rust +// Trait pre vstup/výstup +trait IOManager { + fn ziskaj_vstup(&self) -> String; + fn zobraz_spravu(&self, sprava: &str); +} + +// Implementuj pre štruktúru ConsoleIO (prázdna štruktúra) +struct ConsoleIO; + +impl IOManager for ConsoleIO { + fn ziskaj_vstup(&self) -> String { + let mut vstup = String::new(); + std::io::stdin().read_line(&mut vstup).unwrap(); + vstup.trim().to_string() + } + fn zobraz_spravu(&self, sprava: &str) { + println!("{}", sprava); + } +} +``` + +### Cvičenie 4.2 — Trait s generickým parametrom + +```rust +// Trait pre validáciu +trait Validator { + fn je_platny(&self) -> bool; + fn chyby(&self) -> Vec; +} + +// Implementuj pre Film: +// - hodnotenie musí byť 0.0..=10.0 +// - nazov nesmie byť prázdny +// - rok musí byť 1888..=2026 +``` + +--- + +## BLOK 5: Hra — Game Loop Pattern (vzor z Obesenec + Milionár) + +### Cvičenie 5.1 — Kvízová hra + +Implementuj jednoduchú kvízovú hru: + +``` +Štruktúra Odpoved: + - text: String + - je_spravna: bool + - Traity: Serialize, Deserialize, Clone + +Štruktúra Otazka: + - text: String + - odpovede: Vec (presne 4) + - Traity: Serialize, Deserialize, Clone + +Štruktúra Kviz: + - otazky: Vec + - aktualne_skore: u32 + - Traity: Serialize, Deserialize, Default +``` + +**Metódy:** +```rust +impl Odpoved { + fn new(text: &str, je_spravna: bool) -> Odpoved +} + +impl Otazka { + // Vytvorí otázku. Ak odpovede.len() != 4, vráti None + // Ak žiadna odpoveď nie je správna, vráti None + fn new(text: &str, odpovede: Vec) -> Option + + // Pridá odpoveď. Ak je už 4, vráti false. + fn pridaj_odpoved(&mut self, odpoved: Odpoved) -> bool +} + +impl Kviz { + fn nacitaj_zo_suboru(cesta: &std::path::PathBuf) -> Option + fn uloz_do_suboru(&self, cesta: &std::path::PathBuf) -> bool + + // Vyberie náhodnú otázku + fn nahodna_otazka(&self) -> Option<&Otazka> + + // Vyhodnotí odpoveď (index 0-3), vráti bool + fn vyhodnot(&mut self, otazka: &Otazka, index: usize) -> bool + + // Game loop - používa IOManager trait + fn hraj(&mut self, io: &impl IOManager) +} +``` + +### Cvičenie 5.2 — Implementuj `hraj` metódu + +Vzor game loopu (toto sa opakuje na KAŽDEJ skúške): + +```rust +fn hraj(&mut self, io: &impl IOManager) { + loop { + // 1. Zobraz stav hry + io.zobraz_spravu(&format!("Skóre: {}", self.aktualne_skore)); + + // 2. Vyber otázku + let otazka = match self.nahodna_otazka() { + Some(o) => o.clone(), + None => { io.zobraz_spravu("Žiadne otázky!"); return; } + }; + + // 3. Zobraz otázku + odpovede + io.zobraz_spravu(&otazka.text); + for (i, odp) in otazka.odpovede.iter().enumerate() { + io.zobraz_spravu(&format!(" {}: {}", i + 1, odp.text)); + } + + // 4. Načítaj vstup + let vstup = io.ziskaj_vstup(); + + // 5. Spracuj vstup + match vstup.trim().parse::() { + Ok(n) if n >= 1 && n <= 4 => { + if self.vyhodnot(&otazka, n - 1) { + io.zobraz_spravu("Správne!"); + } else { + io.zobraz_spravu("Nesprávne!"); + } + } + _ => { + io.zobraz_spravu("Neplatný vstup!"); + continue; + } + } + + // 6. Kontrola konca + io.zobraz_spravu("Pokračovať? (a/n)"); + if io.ziskaj_vstup().trim() == "n" { + break; + } + } + io.zobraz_spravu(&format!("Konečné skóre: {}", self.aktualne_skore)); +} +``` + +--- + +## BLOK 6: CLI s Clap (toto je na KAŽDEJ skúške za 5-6 bodov!) + +### Cvičenie 6.1 — Základný clap vzor + +```rust +use clap::{Parser, Subcommand}; + +#[derive(Parser)] +#[command(name = "filmoteka")] +struct Cli { + #[command(subcommand)] + prikaz: Prikazy, +} + +#[derive(Subcommand)] +enum Prikazy { + /// Pridaj nový film + Pridaj { + /// Cesta k súboru s filmami + cesta: std::path::PathBuf, + /// Názov filmu + nazov: String, + /// Režisér + reziser: String, + /// Rok vydania + rok: u16, + }, + /// Odstráň film + Odstran { + cesta: std::path::PathBuf, + nazov: String, + }, + /// Zobraz filmy režiséra + FilmyRezisera { + cesta: std::path::PathBuf, + reziser: String, + }, + /// Štatistiky + Statistiky { + cesta: std::path::PathBuf, + }, +} + +fn main() { + let cli = Cli::parse(); + match cli.prikaz { + Prikazy::Pridaj { cesta, nazov, reziser, rok } => { + // 1. Načítaj filmotéku zo súboru (alebo vytvor novú) + let mut filmoteka = Filmoteka::nacitaj_zo_suboru(&cesta) + .unwrap_or_default(); + // 2. Vytvor film a pridaj + let film = Film { nazov, reziser, rok, ..Default::default() }; + match filmoteka.pridaj_film(film) { + Ok(()) => { + filmoteka.uloz_do_suboru(&cesta); + println!("Film pridaný."); + } + Err(()) => println!("Film už existuje."), + } + } + Prikazy::Odstran { cesta, nazov } => { + // podobne... + } + // ... ďalšie príkazy + } +} +``` + +### Cvičenie 6.2 — Clap s viacerými argumentmi + +Vzor príkazu s 3 argumentmi (ako v Milionár a Obesenec): +```rust +#[derive(Subcommand)] +enum Prikazy { + PridajOtazku { + /// Cesta k JSON súboru + cesta: std::path::PathBuf, + /// Text otázky + otazka: String, + }, + Hraj { + /// Cesta k JSON súboru + cesta: std::path::PathBuf, + /// Kategória + kategoria: String, + }, +} +``` + +--- + +## BLOK 7: HashSet + Iterátory (vzor z Obesenec) + +### Cvičenie 7.1 — Práca s HashSet + +```rust +use std::collections::HashSet; + +struct SlovnaHra { + hladane_slovo: String, + uhadnute_pismena: HashSet, + skusane_pismena: HashSet, + pocet_zivotov: u8, +} + +impl SlovnaHra { + fn new(slovo: &str) -> SlovnaHra { + SlovnaHra { + hladane_slovo: slovo.to_lowercase(), + uhadnute_pismena: HashSet::new(), + skusane_pismena: HashSet::new(), + pocet_zivotov: 6, + } + } + + // Vráti slovo s neuhádnutými písmenami nahradenými '_' + fn daj_slovo_skryto(&self) -> String { + self.hladane_slovo.chars().map(|c| { + if self.uhadnute_pismena.contains(&c) { c } else { '_' } + }).collect() + } + + // Tipni písmeno - vráti enum VysledokPokusu + fn tipni_pismeno(&mut self, pismeno: char) -> VysledokPokusu { + let p = pismeno.to_lowercase().next().unwrap(); + if self.skusane_pismena.contains(&p) { + return VysledokPokusu::Neplatne; + } + self.skusane_pismena.insert(p); + if self.hladane_slovo.contains(p) { + self.uhadnute_pismena.insert(p); + VysledokPokusu::Uhadnute + } else { + self.pocet_zivotov -= 1; + VysledokPokusu::Neuhadnute + } + } + + fn je_koniec_hry(&self) -> bool { + self.pocet_zivotov == 0 || self.je_vyhra() + } + + fn je_vyhra(&self) -> bool { + self.hladane_slovo.chars().all(|c| self.uhadnute_pismena.contains(&c)) + } +} +``` + +### Cvičenie 7.2 — Iterátory s impl Iterator + +```rust +// Vráti iterátor na uhádnuté písmená +fn daj_uhadnute_pismena(&self) -> impl Iterator { + self.uhadnute_pismena.iter() +} + +// Vráti iterátor na skúšané písmená +fn daj_skusane_pismena(&self) -> impl Iterator { + self.skusane_pismena.iter() +} +``` + +--- + +## BLOK 8: rand — Náhodné generovanie + +### Cvičenie 8.1 + +```rust +use rand::Rng; +use rand::seq::SliceRandom; + +// Vyber náhodné slovo z vektora +fn nahodne_slovo(slova: &[String]) -> Option<&String> { + let mut rng = rand::thread_rng(); + slova.choose(&mut rng) +} + +// Náhodné číslo v rozsahu +fn nahodne_cislo(min: u32, max: u32) -> u32 { + let mut rng = rand::thread_rng(); + rng.gen_range(min..=max) +} + +// Zamiešaj vektor +fn zamiesaj(vektor: &mut Vec) { + let mut rng = rand::thread_rng(); + vektor.shuffle(&mut rng); +} +``` + +--- + +## BLOK 9: Nové knižnice — chrono, color-eyre, futures + +### Cvičenie 9.1 — chrono (dátumy) + +```rust +use chrono::{NaiveDate, Local, Datelike}; +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Clone)] +struct Udalost { + nazov: String, + datum: NaiveDate, // chrono s serde feature +} + +impl Udalost { + fn new(nazov: &str, rok: i32, mesiac: u32, den: u32) -> Option { + let datum = NaiveDate::from_ymd_opt(rok, mesiac, den)?; + Some(Udalost { nazov: nazov.to_string(), datum }) + } + + fn je_dnes(&self) -> bool { + self.datum == Local::now().date_naive() + } + + fn dni_do_udalosti(&self) -> i64 { + let dnes = Local::now().date_naive(); + (self.datum - dnes).num_days() + } +} +``` + +### Cvičenie 9.2 — color-eyre (error handling) + +```rust +use color_eyre::eyre::{Result, eyre, WrapErr}; + +fn nacitaj_zo_suboru(cesta: &std::path::PathBuf) -> Result { + let obsah = std::fs::read_to_string(cesta) + .wrap_err_with(|| format!("Nepodarilo sa otvoriť súbor: {:?}", cesta))?; + let filmoteka: Filmoteka = serde_json::from_str(&obsah) + .wrap_err("Nepodarilo sa deserializovať JSON")?; + Ok(filmoteka) +} + +fn main() -> Result<()> { + color_eyre::install()?; + // ... zvyšok kódu s ? operátorom + Ok(()) +} +``` + +--- + +## BLOK 10: Kompletné cvičné zadanie — Správca úloh (TODO app) + +**Toto je simulácia skúšky. Skús to celé implementovať za 90 minút.** + +### Zadanie: Správca úloh + +Cieľom je implementovať aplikáciu na správu úloh s nasledovnými funkcionalitami: +- pridávanie úloh +- odstraňovanie úloh +- označovanie úloh ako dokončené +- filtrovanie úloh podľa rôznych kritérií +- štatistiky +- načítavanie a ukladanie do súboru vo formáte JSON + +#### Enum Priorita +- Nazov: Priorita +- Hodnoty: Nizka, Stredna, Vysoka, Kriticka +- Požadované traity: Default, Display, Serialize, Deserialize, PartialEq, Clone +- Default vráti hodnotu Stredna + +#### Enum StavUlohy +- Hodnoty: Nova, Rozpracovana, Dokoncena, Zrusena +- Požadované traity: Default, Display, Serialize, Deserialize, PartialEq, Clone +- Default vráti hodnotu Nova + +#### Štruktúra Uloha +- nazov: String +- popis: String +- priorita: Priorita +- stav: StavUlohy +- kategoria: String +- Požadované traity: Default, Serialize, Deserialize, Clone + +#### Štruktúra SpravcaUloh +- ulohy: Vec +- Požadované traity: Default, Serialize, Deserialize + +#### Funkcia SpravcaUloh::nacitaj_zo_suboru +- Parameter: &PathBuf → Option + +#### Metóda spravca_uloh.uloz_do_suboru +- Parameter: &PathBuf → bool + +#### Metóda spravca_uloh.pridaj_ulohu +- Parameter: Uloha → Result<(), ()> +- Err ak úloha s rovnakým názvom existuje + +#### Metóda spravca_uloh.odstran_ulohu +- Parameter: &str (názov) → Result + +#### Metóda spravca_uloh.oznac_dokoncenu +- Parameter: &str (názov) → Result<(), ()> +- Zmení stav úlohy na Dokoncena + +#### Metóda spravca_uloh.daj_ulohy_podla_priority +- Parameter: &Priorita → Vec<&Uloha> + +#### Metóda spravca_uloh.daj_ulohy_podla_stavu +- Parameter: &StavUlohy → Vec<&Uloha> + +#### Metóda spravca_uloh.daj_ulohy_podla_kategorie +- Parameter: &str → Vec<&Uloha> + +#### Metóda spravca_uloh.vypis_statistiky_kategorii +- Pre každú kategóriu vypíše počet úloh +- Formát: "Kategória: počet úloh" + +#### Metóda spravca_uloh.vypis_ulohy_podla_priority +- Vypíše všetky úlohy zoskupené podľa priority + +#### Ovládanie aplikácie (main.rs s clap) + +Príkazy: +- `pridaj` — 2 argumenty: cesta k súboru, názov úlohy. Interaktívne sa opýta na popis, prioritu a kategóriu. +- `odstran` — 2 argumenty: cesta k súboru, názov úlohy +- `dokonci` — 2 argumenty: cesta k súboru, názov úlohy +- `zoznam` — 2 argumenty: cesta k súboru, filter (vsetky/dokoncene/nedokoncene) +- `statistiky` — 1 argument: cesta k súboru + +--- + +## BLOK 11: Ďalšie simulácie skúšok + +### Simulácia 2 — Správca kontaktov + +``` +Enum TypKontaktu: Osobny, Pracovny, Rodina +Štruktúra Kontakt: meno, priezvisko, email, telefon, typ_kontaktu +Štruktúra Adresar: kontakty: Vec + +Metódy: +- nacitaj_zo_suboru, uloz_do_suboru +- pridaj_kontakt (duplicita podľa emailu → Err) +- odstran_kontakt (podľa emailu) +- najdi_podla_mena(&str) → Vec<&Kontakt> +- najdi_podla_typu(&TypKontaktu) → Vec<&Kontakt> +- vypis_kontakty_podla_typu() + +CLI: pridaj, odstran, hladaj-meno, hladaj-typ, statistiky +``` + +### Simulácia 3 — Hudobná knižnica (s chrono) + +``` +Enum Zaner: Rock, Pop, Jazz, Klasicka, HipHop, Elektronicka +Štruktúra Piesnicka: nazov, interpret, zaner, trvanie_sekundy: u32, datum_pridania: NaiveDate +Štruktúra Playlist: nazov, piesnicky: Vec +Štruktúra HudobnaKniznica: playlisty: Vec + +Metódy pre Playlist: +- pridaj_piesnicku, odstran_piesnicku +- celkove_trvanie() → u32 +- piesnicky_interpreta(&str) → Vec<&Piesnicka> + +Metódy pre HudobnaKniznica: +- nacitaj_zo_suboru, uloz_do_suboru +- vytvor_playlist, odstran_playlist +- najdi_piesnicku_v_kniznici(&str) → Vec<(&Playlist, &Piesnicka)> +- statistiky_zanrov() + +CLI: vytvor-playlist, pridaj-piesnicku (3 arg: cesta, playlist, piesnicka), + zoznam, statistiky +``` + +### Simulácia 4 — Hra s kartami (trait + rand) + +``` +Trait Hratelna { + fn tahaj_kartu(&mut self) -> Option; + fn je_koniec(&self) -> bool; + fn daj_skore(&self) -> u32; +} + +Enum Farba: Srdce, Karo, Piky, Krize (Display) +Enum Hodnota: Cislo(u8), Dolnik, Hornik, Kral, Eso (Display) +Štruktúra Karta: farba, hodnota +Štruktúra Balicek: karty: Vec +Štruktúra HraBlackjack: balicek, hrac_karty, dealer_karty, stav_hry + +impl Balicek: +- fn novy() → Balicek // vytvorí 32 kariet +- fn zamiesaj(&mut self) +- fn tahaj(&mut self) -> Option + +impl HraBlackjack: Hratelna +- fn hraj(&mut self, io: &impl IOManager) + +CLI: hraj (cesta k uloženej hre), nove-hry +``` + +--- + +## Kľúčové vzory na zapamätanie (cheat sheet) + +### 1. Serde JSON čítanie/zápis +```rust +// Čítanie +let obsah = std::fs::read_to_string(&cesta).ok()?; +let data: MojTyp = serde_json::from_str(&obsah).ok()?; +Some(data) + +// Zápis +let json = serde_json::to_string_pretty(&self).unwrap_or_default(); +std::fs::write(&cesta, json).is_ok() +``` + +### 2. Vec filtrovanie +```rust +// Referencia +self.polozky.iter().filter(|p| p.nazov == hladany).collect() + +// Hľadanie jedného +self.polozky.iter().find(|p| p.nazov == hladany) + +// Odstránenie +if let Some(pos) = self.polozky.iter().position(|p| p.nazov == hladany) { + Ok(self.polozky.remove(pos)) +} else { + Err(()) +} +``` + +### 3. Display implementácia +```rust +impl std::fmt::Display for MojEnum { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + MojEnum::Varianta1 => write!(f, "Text 1"), + MojEnum::Varianta2 => write!(f, "Text 2"), + } + } +} +``` + +### 4. Clap šablóna +```rust +use clap::{Parser, Subcommand}; + +#[derive(Parser)] +struct Cli { + #[command(subcommand)] + prikaz: Prikazy, +} + +#[derive(Subcommand)] +enum Prikazy { + NazovPrikazu { + cesta: std::path::PathBuf, + argument: String, + }, +} + +fn main() { + let cli = Cli::parse(); + match cli.prikaz { + Prikazy::NazovPrikazu { cesta, argument } => { /* ... */ } + } +} +``` + +### 5. HashMap štatistiky +```rust +use std::collections::HashMap; +let mut mapa: HashMap = HashMap::new(); +for polozka in &self.polozky { + *mapa.entry(polozka.kategoria.clone()).or_insert(0) += 1; +} +for (kluc, pocet) in &mapa { + println!("{}: {}", kluc, pocet); +} +``` + +### 6. rand +```rust +use rand::seq::SliceRandom; +let mut rng = rand::thread_rng(); +let nahodny = vektor.choose(&mut rng); +vektor.shuffle(&mut rng); +``` + +### 7. Čítanie vstupu z konzoly +```rust +let mut vstup = String::new(); +std::io::stdin().read_line(&mut vstup).unwrap(); +let vstup = vstup.trim(); +// Parsovanie na číslo: +let cislo: usize = vstup.parse().unwrap_or(0); +``` + +--- + +## Postup na skúške + +1. **Prečítaj celé zadanie** (2 min) +2. **Vytvor `Cargo.toml`** s potrebnými závislosťami (1 min) +3. **Implementuj enumy a štruktúry** s derives v `lib.rs` (10 min) +4. **Implementuj `Display`** pre enumy (5 min) +5. **Implementuj `nacitaj_zo_suboru` + `uloz_do_suboru`** (5 min) — toto je vždy rovnaké! +6. **Implementuj CRUD metódy** (15 min) +7. **Implementuj filtrovacie metódy** (10 min) +8. **Implementuj štatistiky/špeciálne metódy** (10 min) +9. **Implementuj game loop** ak je hra (15 min) +10. **Implementuj CLI v `main.rs`** (15 min) +11. **Testuj s `cargo test`** + manuálne (zvyšok) + +**CELKOM: ~90 minút** diff --git a/priprava_na_skusku2/Cargo.lock b/priprava_na_skusku2/Cargo.lock index 8f62509..3657995 100644 --- a/priprava_na_skusku2/Cargo.lock +++ b/priprava_na_skusku2/Cargo.lock @@ -2,6 +2,283 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" + +[[package]] +name = "cc" +version = "1.2.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.182" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + [[package]] name = "priprava_na_skusku2" version = "0.1.0" +dependencies = [ + "chrono", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e614ed320ac28113fa64972c4262d5dbc89deacdfd00c34a3e4cea073243c12" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" + +[[package]] +name = "wasm-bindgen" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] diff --git a/priprava_na_skusku2/Cargo.toml b/priprava_na_skusku2/Cargo.toml index bee9050..f1a94b5 100644 --- a/priprava_na_skusku2/Cargo.toml +++ b/priprava_na_skusku2/Cargo.toml @@ -4,3 +4,5 @@ version = "0.1.0" edition = "2024" [dependencies] +chrono = "0.4.43" + diff --git a/priprava_na_skusku2/src/main.rs b/priprava_na_skusku2/src/main.rs index 957b486..ef7533e 100644 --- a/priprava_na_skusku2/src/main.rs +++ b/priprava_na_skusku2/src/main.rs @@ -1,19 +1,10 @@ +use chrono::prelude::*; + + fn main() { - // 1. How to create it - let letter: char = 'a'; // Use SINGLE quotes for char - let emoji: char = '🦀'; // Even emojis are exactly ONE char - - // 2. Why it's useful - // You can ask it questions: - println!("{}", letter.is_alphabetic()); // Prints: true - println!("{}", letter.is_numeric()); // Prints: false - - // 3. Converting to a number (The "Address" of the letter) - // Every letter has a unique number in the world (Unicode). - let number = 'a' as u32; - println!("{}", number); // Prints: 65 - - // 4. Converting a number back to a letter - let back_to_char = std::char::from_u32(97); - println!("{:?}", back_to_char); // Prints: Some('A') + let utc: DateTime = Utc::now(); + let local: DateTime = Local::now(); + + println!("{utc}"); + println!("{local}"); }