← Zpět na obsah

Kapitola 10: Rozdělení problému na části

Dekompozice - rozdělení velkého problému na menší části
Dekompozice - rozdělení velkého problému na menší části

1. Úvod: Jak sníst slona?

Představ si, že máš za úkol sníst obrovského slona. To zní nemožně, že? Ale co kdyby sis ho rozdělil na malé kousky a každý den snědl jen jeden? Najednou se úkol zdá mnohem jednodušší. V životě i v informatice je to stejné. Když stojíme před velkým a složitým problémem, nejlepší způsob, jak ho vyřešit, je rozdělit si ho na menší, zvládnutelné části.

2. Co znamená "rozdělit problém na části"?

Rozdělení problému na části znamená, že velký a složitý úkol si rozkouskujeme na několik menších a jednodušších úkolů. Každý z těchto malých úkolů pak můžeme vyřešit samostatně.

Definice: Dekompozice

Dekompozice je odborný název pro rozdělení složitého problému na menší, jednodušší a lépe zvládnutelné části.

Proč je to důležité?

Rozdělení problému nám pomáhá:

Příklad: Uklidit si pokoj
Velký problém: "Uklidit pokoj."
Rozdělení na menší části:
  1. Ustlat postel.
  2. Uklidit oblečení do skříně.
  3. Uklidit knížky do knihovny.
  4. Uklidit hračky do krabice.
  5. Vyluxovat.
Každý z těchto úkolů je mnohem jednodušší a když je všechny splníš, máš uklizený celý pokoj!

3. Hledání opakujících se vzorů

Když si problém rozdělíme na části, často si všimneme, že některé kroky se opakují. Tomu říkáme opakující se vzory.

Příklad: Prostírání stolu pro 4 lidi
Místo toho, abychom si řekli: "Prostři pro Petra, pak pro Janu, pak pro Tomáše, pak pro Evu", můžeme si všimnout, že se postup opakuje.

Opakující se vzor:
  1. Polož talíř.
  2. Polož příbor.
  3. Polož skleničku.
Tento postup pak jen 4x zopakujeme pro každou osobu. Je to mnohem efektivnější!

4. Místa pro rozhodování

Někdy náš postup není úplně přímý. Musíme se rozhodnout, co udělat dál, na základě nějaké podmínky. Tomu říkáme místo pro rozhodování nebo větvení.

Příklad: Jít ven
Chceš jít ven. Tvůj postup (algoritmus) může vypadat takto:
  1. Podívej se z okna.
  2. Pokud prší, vezmi si deštník.
  3. Jinak (pokud neprší), vezmi si sluneční brýle.
  4. Jdi ven.
Krok 2 a 3 je místo pro rozhodování. Tvůj další postup se mění podle toho, jaké je počasí.
Hierarchie úkolů - od velkého k malým
Hierarchie úkolů - od velkého k malým

5. Jak to všechno použít v praxi?

Pojďme si to ukázat na příkladu z tvého oboru.

Úkol: Připravit svačinu pro celou třídu
Flowgorithm - tvorba vývojových diagramů
Flowgorithm - tvorba vývojových diagramů

6. Rozdělení problému při programování

Právě jsi se naučil důležitou dovednost, kterou používají všichni programátoři! Když chceme vytvořit počítačový program nebo hru, musíme velký problém rozdělit na malé části.

Příklad: Vytvoření jednoduché hry ve Scratchi

Velký problém: Vytvořit hru, kde hráč ovládá postavu, sbírá předměty a získává body.

Rozdělení na menší části:

  1. Část 1: Vytvořit scénu a postavy
    • Vybrat nebo nakreslit pozadí
    • Přidat hlavní postavu (sprite)
    • Přidat předměty ke sbírání
  2. Část 2: Naprogramovat ovládání
    • Postava se pohybuje doleva (šipka vlevo)
    • Postava se pohybuje doprava (šipka vpravo)
  3. Část 3: Naprogramovat sbírání předmětů
    • Když se postava dotkne předmětu...
    • ...předmět zmizí
    • ...přičte se bod
  4. Část 4: Přidat počítadlo bodů
    • Vytvořit proměnnou "body"
    • Na začátku nastavit body na 0
    • Zobrazit body na obrazovce

Výhoda tohoto přístupu:

Praktický tip pro Scratch:
Když programuješ ve Scratchi, můžeš vytvářet vlastní bloky pro opakující se části programu. Například můžeš vytvořit blok nazvaný "Zkontroluj_sbírání", který obsahuje všechny příkazy pro kontrolu, zda postava narazila na předmět. Pak tento blok můžeš používat vícekrát v programu. Je to jako si vytvořit vlastní LEGO kostku!

Člověk a digitální svět

Schopnost rozdělit velký problém na menší části je jednou z nejdůležitějších dovedností v digitálním světě. Pomáhá nám nejen při programování, ale i při řešení každodenních úkolů. Učí nás přemýšlet systematicky, plánovat a nenechat se odradit složitostí. Tato dovednost je klíčová pro efektivní práci s digitálními nástroji a pro úspěšné řešení problémů v jakémkoli oboru.

Otázky k zamyšlení

Úkoly pro praxi

  1. Plánování oslavy: Představ si, že máš za úkol naplánovat malou narozeninovou oslavu pro kamaráda. Rozděl tento velký úkol na co nejvíce malých, jednoduchých kroků.
  2. Recept s rozhodováním: Vymysli jednoduchý recept (např. na přípravu nápoje), který bude obsahovat alespoň jedno místo pro rozhodování (např. "Pokud chceš nápoj sladší, přidej lžičku medu.").
  3. Úklid dílny: Představ si, že jsi v dílně a máš za úkol uklidit nářadí. Popiš postup. Najdeš v něm nějaké opakující se vzory? (Např. pro každý druh šroubků: 1. Najdi správnou krabičku. 2. Nasyp šroubky do krabičky. 3. Zavři krabičku. 4. Dej krabičku na poličku.)

* Rozšíření pro pokročilé

Dekompozice v software inženýrství

V profesionální praxi se dekompozice používá na mnoha úrovních:

Principy dobrého návrhu

Abstrakce

Abstrakce je proces skrytí složitosti za jednoduché rozhraní. Například: tlačítko "Odeslat" skrývá složitý proces přenosu dat.

Modulární programování - hlavní program a moduly
Modulární programování - hlavní program a moduly

* Úkoly pro pokročilé

  1. Word – Dekompozice projektu: Vyber si větší projekt (např. vytvoření webové stránky). Rozděl ho hierarchicky: Projekt → Fáze → Úkoly → Podúkoly. Napiš to jako strukturovaný seznam ve Wordu.
  2. Excel – WBS (Work Breakdown Structure): Vytvoř v Excelu tabulku WBS: sloupce ID, Název úkolu, Nadřazený úkol, Odhadovaný čas, Odpovědná osoba. Vyplň pro fiktivní projekt "Školní akademie".
  3. Scratch – Vlastní bloky: Vytvoř ve Scratchi program s alespoň 3 vlastními bloky. Např. blok "NakresliČtverec(velikost)", "NakresliTrojúhelník(velikost)", "NakresliDomeček()" který volá předchozí dva.
  4. Scratch – Modulární hra: Vytvoř jednoduchou hru, kde máš oddělené části: pohyb hráče (jeden sprite), nepřátelé (jiný sprite), skóre (proměnná). Každá část má svůj vlastní kód.

** Rozšíření pro maturitní obory

Podrobně: Princip Divide and Conquer

Divide and Conquer (Rozděl a panuj) je algoritmická strategie:

  1. Rozděl: Rozlož problém na menší podproblémy.
  2. Panuj: Vyřeš podproblémy (rekurzivně).
  3. Spoj: Zkombinuj řešení podproblémů do celkového řešení.

Příklady: Merge Sort, Quick Sort, binární vyhledávání.

Funkce a procedury

Princip DRY (Don't Repeat Yourself)

Opakující se kód by měl být extrahován do funkce. Výhody:

Struktura projektu - organizace souborů a složek
Struktura projektu - organizace souborů a složek

** Úkoly pro maturitní obory

  1. Flowgorithm – Funkce Maximum: Vytvoř funkci NajdiMaximum(a, b), která vrátí větší ze dvou čísel. Pak ji použij v hlavním programu pro nalezení maxima ze tří čísel.
  2. Flowgorithm – Binární vyhledávání: Vytvoř algoritmus binárního vyhledávání v seřazeném poli. Vysvětli, proč je efektivnější než lineární.
  3. Flowgorithm – Faktoriál funkcí: Vytvoř funkci Faktorial(n), která rekurzivně počítá faktoriál. Nakresli strom volání pro n=4.
  4. PowerPoint – DRY princip: Vytvoř prezentaci "Princip DRY v programování" (8-10 snímků). Ukaž příklad kódu PŘED a PO aplikaci DRY.
  5. Word – Návrh modulů: Navrhni strukturu modulů pro aplikaci "Školní jídelna". Hlavní moduly: Jídelníček, Objednávky, Platby, Uživatelé. Pro každý napiš funkce.
  6. Canva – Infografika: Vytvoř infografiku "Divide and Conquer" vysvětlující strategii na příkladu třídění karet.

*** Rozšíření pro IT obory

Jako IT specialista budeš navrhovat software pomocí modulů a tříd. Naučíš se principy objektově orientovaného programování.

Moduly v Pythonu

# matematika.py - vlastní modul
def secti(a, b):
    return a + b

def odecti(a, b):
    return a - b

def faktorial(n):
    if n <= 1:
        return 1
    return n * faktorial(n - 1)

PI = 3.14159

# hlavni.py - použití modulu
import matematika
from matematika import faktorial, PI

print(matematika.secti(5, 3))
print(faktorial(5))
print(PI)
        

Třídy a objekty (OOP)

class Student:
    """Třída reprezentující studenta."""

    def __init__(self, jmeno, vek):
        """Konstruktor - inicializace objektu."""
        self.jmeno = jmeno
        self.vek = vek
        self.znamky = []

    def pridej_znamku(self, znamka):
        """Přidá známku studentovi."""
        if 1 <= znamka <= 5:
            self.znamky.append(znamka)

    def prumer(self):
        """Vypočítá průměr známek."""
        if not self.znamky:
            return 0
        return sum(self.znamky) / len(self.znamky)

    def __str__(self):
        """Reprezentace objektu jako text."""
        return f"{self.jmeno} ({self.vek} let), průměr: {self.prumer():.2f}"

# Použití
jan = Student("Jan Novák", 15)
jan.pridej_znamku(1)
jan.pridej_znamku(2)
jan.pridej_znamku(1)
print(jan)  # Jan Novák (15 let), průměr: 1.33
        

Dědičnost

class Osoba:
    """Základní třída pro osoby."""
    def __init__(self, jmeno, vek):
        self.jmeno = jmeno
        self.vek = vek

    def predstav_se(self):
        return f"Jmenuji se {self.jmeno}"

class Student(Osoba):
    """Student dědí od Osoba."""
    def __init__(self, jmeno, vek, trida):
        super().__init__(jmeno, vek)  # Zavolej konstruktor rodiče
        self.trida = trida

    def predstav_se(self):
        return f"{super().predstav_se()}, chodím do {self.trida}"

class Ucitel(Osoba):
    """Učitel dědí od Osoba."""
    def __init__(self, jmeno, vek, predmet):
        super().__init__(jmeno, vek)
        self.predmet = predmet

    def predstav_se(self):
        return f"{super().predstav_se()}, učím {self.predmet}"

# Použití
student = Student("Jan", 15, "9.A")
ucitel = Ucitel("Mgr. Nováková", 35, "matematiku")

print(student.predstav_se())  # Jmenuji se Jan, chodím do 9.A
print(ucitel.predstav_se())   # Jmenuji se Mgr. Nováková, učím matematiku
        

Struktura projektu

muj_projekt/
├── main.py              # Hlavní soubor
├── requirements.txt     # Závislosti
├── README.md           # Dokumentace
├── models/             # Datové modely
│   ├── __init__.py
│   ├── student.py
│   └── ucitel.py
├── utils/              # Pomocné funkce
│   ├── __init__.py
│   └── validators.py
├── tests/              # Testy
│   ├── test_student.py
│   └── test_ucitel.py
└── data/               # Data
    └── studenti.csv
        

*** Praktické úkoly pro IT obory

  1. Modul kalkulačka: Vytvoř modul s funkcemi pro základní matematické operace. Importuj ho v hlavním programu.
  2. Třída Bankovní účet: Vytvoř třídu s atributy (číslo účtu, zůstatek) a metodami (vklad, výběr, výpis).
  3. Dědičnost - Tvary: Vytvoř třídu Tvar s metodou obsah(). Odvoď třídy Ctverec, Obdelnik, Kruh s vlastními implementacemi.
  4. Projekt: Vytvoř strukturovaný projekt (složky, moduly, main.py) pro jednoduchou aplikaci (TODO list, správce kontaktů).

*** Projekt pro IT obory: Správce kontaktů (část 1/4)

V kapitolách 10-13 vytvoříš kompletní aplikaci Správce kontaktů. Naučíš se správnou strukturu projektu, verzování v Gitu a psaní dokumentace.

Popis projektu

Aplikace umožní:

Krok 1: Vytvoření repozitáře

# 1. Vytvoř složku projektu
mkdir spravce-kontaktu
cd spravce-kontaktu

# 2. Inicializuj Git
git init

# 3. Vytvoř základní strukturu
mkdir models
mkdir utils
mkdir tests

# 4. Vytvoř prázdné __init__.py (označí složky jako Python moduly)
echo. > models/__init__.py
echo. > utils/__init__.py
echo. > tests/__init__.py
        

Krok 2: Vytvoření základních souborů

README.md

# Správce kontaktů

Jednoduchá CLI aplikace pro správu kontaktů.

## Funkce
- Přidání nového kontaktu
- Zobrazení všech kontaktů
- Vyhledávání podle jména
- Mazání kontaktů
- Ukládání do souboru

## Instalace
```
git clone https://github.com/tvoje-jmeno/spravce-kontaktu.git
cd spravce-kontaktu
python main.py
```

## Použití
Spusť `python main.py` a následuj instrukce v menu.

## Autor
Tvoje Jméno

## Licence
MIT
        

.gitignore

# Python
__pycache__/
*.pyc
*.pyo
.env
venv/

# IDE
.vscode/
.idea/
*.swp

# Data (volitelně - pokud nechceš verzovat uživatelská data)
# data/*.json

# OS
.DS_Store
Thumbs.db
        

Krok 3: Model kontaktu (models/kontakt.py)

# models/kontakt.py
"""Modul obsahující třídu Kontakt."""

class Kontakt:
    """Třída reprezentující jeden kontakt."""

    def __init__(self, jmeno, telefon, email=""):
        """
        Inicializace kontaktu.

        Args:
            jmeno: Jméno kontaktu
            telefon: Telefonní číslo
            email: E-mailová adresa (volitelné)
        """
        self.jmeno = jmeno
        self.telefon = telefon
        self.email = email

    def __str__(self):
        """Textová reprezentace kontaktu."""
        info = f"{self.jmeno} | Tel: {self.telefon}"
        if self.email:
            info += f" | Email: {self.email}"
        return info

    def to_dict(self):
        """Převede kontakt na slovník (pro ukládání do JSON)."""
        return {
            "jmeno": self.jmeno,
            "telefon": self.telefon,
            "email": self.email
        }

    @classmethod
    def from_dict(cls, data):
        """Vytvoří kontakt ze slovníku (načítání z JSON)."""
        return cls(
            jmeno=data["jmeno"],
            telefon=data["telefon"],
            email=data.get("email", "")
        )
        

Krok 4: První commit

# Přidej všechny soubory
git add .

# Vytvoř první commit
git commit -m "Počáteční struktura projektu

- Přidána základní struktura složek
- Vytvořen README.md s popisem projektu
- Přidán .gitignore pro Python
- Implementována třída Kontakt"

# (Volitelné) Propoj s GitHubem
git remote add origin https://github.com/tvoje-jmeno/spravce-kontaktu.git
git branch -M main
git push -u origin main
        

Aktuální struktura projektu

spravce-kontaktu/
├── .git/                  # Git repozitář
├── .gitignore             # Ignorované soubory
├── README.md              # Dokumentace
├── models/
│   ├── __init__.py
│   └── kontakt.py         # Třída Kontakt
├── utils/
│   └── __init__.py
└── tests/
    └── __init__.py
        

*** Úkol pro tuto kapitolu

  1. Vytvoř projekt podle kroků výše.
  2. Nahraj na GitHub a zkontroluj, že soubory jsou viditelné.
  3. Přidej do třídy Kontakt metodu aktualizuj() pro změnu údajů.
  4. Vytvoř commit s popisem změny.

V další kapitole: Přidáme správce kontaktů a ukládání do souboru.

← Zpět na obsah