{"id":"informatyka-2019-maj-matura-rozszerzona/zad/6.3","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"6.3","points":3,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 6.1.\n\nUtwórz uporządkowaną alfabetycznie listę wszystkich nazw marek, które nie zawierają w swoich perfumach żadnego składnika mającego w nazwie słowo „paczula”.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Marki bez \"paczuli\" wśród składników (alfabetycznie):**\nAison Eranciro\nArthbey\nEmbert Lucas\nEnmith\nNnick a Kieffo\n\n## Sposób 1 - SQL z NOT EXISTS\n\n```sql\nSELECT m.nazwa_m\nFROM marki m\nWHERE NOT EXISTS (\nSELECT 1\nFROM perfumy p\nINNER JOIN sklad s ON p.id_perfum = s.id_perfum\nWHERE p.id_marki = m.id_marki\nAND s.nazwa_skladnika LIKE '%paczula%'\n)\nORDER BY m.nazwa_m;\n\n**Wyjaśnienie:**\n- Główne zapytanie: marki.\n- Podzapytanie: czy marka ma jakiś składnik z \"paczula\" w nazwie?\n- `NOT EXISTS`: zwróć marki, które **nie mają** takiego składnika.\n- `LIKE '%paczula%'`: \"paczula\" gdziekolwiek w nazwie (np. \"paczula indonezyjska\", \"olejek z paczuli\").\n- `ORDER BY`: sortowanie alfabetyczne.\n\n## Sposób 2 - SQL alternatywne (LEFT JOIN + WHERE NULL)\n\n```sql\nSELECT DISTINCT m.nazwa_m\nFROM marki m\nWHERE m.id_marki NOT IN (\nSELECT DISTINCT p.id_marki\nFROM perfumy p\nINNER JOIN sklad s ON p.id_perfum = s.id_perfum\nWHERE s.nazwa_skladnika LIKE '%paczula%'\n)\nORDER BY m.nazwa_m;\n\n## Sposób 3 - Python\n\n```python\n# Wczytaj marki: id -> nazwa\nmarki = {}\nwith open('marki.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\nid_m, nazwa = linia.strip().split('\\t')\nmarki[id_m] = nazwa\n\n# Wczytaj perfumy: id_perfum -> id_marki\nperf_marka = {}\nwith open('perfumy.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\npola = linia.strip().split('\\t')\nperf_marka[pola[0]] = pola[2]\n\n# Znajdź marki, które mają składnik z \"paczula\"\nmarki_z_paczula = set()\nwith open('sklad.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\nid_p, nazwa_skl = linia.strip().split('\\t')\nif 'paczula' in nazwa_skl.lower():\nid_m = perf_marka.get(id_p)\nif id_m:\nmarki_z_paczula.add(id_m)\n\n# Marki BEZ paczuli\nwynik = sorted([marki[id_m] for id_m in marki if id_m not in marki_z_paczula])\nfor m in wynik:\nprint(m)\n\n## Sposób 4 - arkusz kalkulacyjny\n\n**Krok 1:** w sklad.txt - kolumna pomocnicza C: `=JEŻELI(ISNUMBER(SZUKAJ.TEKST(\"paczula\"; B2)); A2; \"\")`. To daje id_perfum jeśli składnik zawiera paczulę.\n\n**Krok 2:** zbierz unikalne id_perfum (zaawansowany filtr lub UNIQUE).\n\n**Krok 3:** dopasuj id_perfum → id_marki (VLOOKUP w perfumy.txt).\n\n**Krok 4:** lista wszystkich marek minus te z paczulą - formuła `IF(COUNTIF(zlepaczula; id_marki) = 0; nazwa; \"\")`.\n\n**Krok 5:** sortuj alfabetycznie.\n\n## Reference informatyczny - NOT EXISTS vs NOT IN\n\n> Reference - Subqueries z negacją:\n> - `NOT EXISTS (SELECT WHERE )`: efektywne, działa poprawnie z NULL.\n> - `NOT IN (SELECT )`: prostsze, ale ma pułapkę - jeśli podzapytanie zwróci NULL, cały warunek staje się UNKNOWN (faktycznie FALSE)!\n> - **Preferowane: `NOT EXISTS`** - bezpieczniejsze.\n>\n> Reference - LIKE z wildcardami:\n> - `%paczula%` - \"paczula\" gdziekolwiek (start, środek, koniec).\n> - `paczula%` - zaczyna od \"paczula\".\n> - `%paczula` - kończy na \"paczula\".\n> - `_paczula_` - z dokładnie jednym znakiem przed i po.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 6.3, max 3 pkt):\n> - **2 pkt** - zastosowanie filtra `*paczula*` (= `%paczula%`)\n> - **1 pkt** - filtr `paczula*` lub samo `paczula` (zamiast `*paczula*`) - niepełne\n> - **1 pkt** - sortowanie alfabetyczne\n> - **0 pkt** - błędna lub brak\n\n## Typowe pułapki\n\n- **`= 'paczula'`** zamiast `LIKE '%paczula%'` - pominie składniki typu \"olejek paczuli\".\n- **`paczula%`** - pominie składniki typu \"olejek paczuli\" (nie zaczyna się od paczula).\n- **Pomylenie polskich znaków** - \"paczula\" (litera 'l') vs \"paczuli\" (l, ale forma deklinacyjna).\n- **Brak sortowania** - utrata 1 punktu.\n- **`NOT IN` z NULL** - może spowodować błędy. Lepiej `NOT EXISTS`.\n- **Pomylenie kierunku** - listujemy marki BEZ paczuli, NIE marki Z paczulą.\n\n## Złożoność obliczeniowa\n\n- SQL z indeksami: O(n log n) sortowanie + O(n + m) join.\n- Python: O(n + m) - dwa przejścia przez pliki.\n- Pamięć: O(liczba marek + liczba składników z paczulą).","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura","text_html":"<p>Kontekst - patrz zadanie 6.1.</p>\n<p>Utwórz uporządkowaną alfabetycznie listę wszystkich nazw marek, które nie zawierają w swoich perfumach żadnego składnika mającego w nazwie słowo „paczula”.</p>","solutions":[{"source":"maturazai","label":"maturazai.pl (AI)","kind":"text","html":"<h4>Poprawna odpowiedź</h4>\n<p><strong>Marki bez &quot;paczuli&quot; wśród składników (alfabetycznie):</strong><br>Aison Eranciro<br>Arthbey<br>Embert Lucas<br>Enmith<br>Nnick a Kieffo</p>\n<h4>Sposób 1 - SQL z NOT EXISTS</h4>\n<p>```sql<br>SELECT m.nazwa_m<br>FROM marki m<br>WHERE NOT EXISTS (<br>SELECT 1<br>FROM perfumy p<br>INNER JOIN sklad s ON p.id_perfum = s.id_perfum<br>WHERE p.id_marki = m.id_marki<br>AND s.nazwa_skladnika LIKE &#x27;%paczula%&#x27;<br>)<br>ORDER BY m.nazwa_m;</p>\n<p><strong>Wyjaśnienie:</strong></p>\n<ul><li>Główne zapytanie: marki.</li><li>Podzapytanie: czy marka ma jakiś składnik z &quot;paczula&quot; w nazwie?</li><li><code>NOT EXISTS</code>: zwróć marki, które <strong>nie mają</strong> takiego składnika.</li><li><code>LIKE &#x27;%paczula%&#x27;</code>: &quot;paczula&quot; gdziekolwiek w nazwie (np. &quot;paczula indonezyjska&quot;, &quot;olejek z paczuli&quot;).</li><li><code>ORDER BY</code>: sortowanie alfabetyczne.</li></ul>\n<h4>Sposób 2 - SQL alternatywne (LEFT JOIN + WHERE NULL)</h4>\n<p>```sql<br>SELECT DISTINCT m.nazwa_m<br>FROM marki m<br>WHERE m.id_marki NOT IN (<br>SELECT DISTINCT p.id_marki<br>FROM perfumy p<br>INNER JOIN sklad s ON p.id_perfum = s.id_perfum<br>WHERE s.nazwa_skladnika LIKE &#x27;%paczula%&#x27;<br>)<br>ORDER BY m.nazwa_m;</p>\n<h4>Sposób 3 - Python</h4>\n<p>```python</p>\n<h3>Wczytaj marki: id -&gt; nazwa</h3>\n<p>marki = {}<br>with open(&#x27;marki.txt&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>f.readline()<br>for linia in f:<br>id_m, nazwa = linia.strip().split(&#x27;\\t&#x27;)<br>marki[id_m] = nazwa</p>\n<h3>Wczytaj perfumy: id_perfum -&gt; id_marki</h3>\n<p>perf_marka = {}<br>with open(&#x27;perfumy.txt&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>f.readline()<br>for linia in f:<br>pola = linia.strip().split(&#x27;\\t&#x27;)<br>perf_marka[pola[0]] = pola[2]</p>\n<h3>Znajdź marki, które mają składnik z &quot;paczula&quot;</h3>\n<p>marki_z_paczula = set()<br>with open(&#x27;sklad.txt&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>f.readline()<br>for linia in f:<br>id_p, nazwa_skl = linia.strip().split(&#x27;\\t&#x27;)<br>if &#x27;paczula&#x27; in nazwa_skl.lower():<br>id_m = perf_marka.get(id_p)<br>if id_m:<br>marki_z_paczula.add(id_m)</p>\n<h3>Marki BEZ paczuli</h3>\n<p>wynik = sorted([marki[id_m] for id_m in marki if id_m not in marki_z_paczula])<br>for m in wynik:<br>print(m)</p>\n<h4>Sposób 4 - arkusz kalkulacyjny</h4>\n<p><strong>Krok 1:</strong> w sklad.txt - kolumna pomocnicza C: <code>=JEŻELI(ISNUMBER(SZUKAJ.TEKST(&quot;paczula&quot;; B2)); A2; &quot;&quot;)</code>. To daje id_perfum jeśli składnik zawiera paczulę.</p>\n<p><strong>Krok 2:</strong> zbierz unikalne id_perfum (zaawansowany filtr lub UNIQUE).</p>\n<p><strong>Krok 3:</strong> dopasuj id_perfum → id_marki (VLOOKUP w perfumy.txt).</p>\n<p><strong>Krok 4:</strong> lista wszystkich marek minus te z paczulą - formuła <code>IF(COUNTIF(zlepaczula; id_marki) = 0; nazwa; &quot;&quot;)</code>.</p>\n<p><strong>Krok 5:</strong> sortuj alfabetycznie.</p>\n<h4>Reference informatyczny - NOT EXISTS vs NOT IN</h4>\n<blockquote>Reference - Subqueries z negacją:<br>- <code>NOT EXISTS (SELECT WHERE )</code>: efektywne, działa poprawnie z NULL.<br>- <code>NOT IN (SELECT )</code>: prostsze, ale ma pułapkę - jeśli podzapytanie zwróci NULL, cały warunek staje się UNKNOWN (faktycznie FALSE)!<br>- <strong>Preferowane: <code>NOT EXISTS</code></strong> - bezpieczniejsze.<br><br>Reference - LIKE z wildcardami:<br>- <code>%paczula%</code> - &quot;paczula&quot; gdziekolwiek (start, środek, koniec).<br>- <code>paczula%</code> - zaczyna od &quot;paczula&quot;.<br>- <code>%paczula</code> - kończy na &quot;paczula&quot;.<br>- <code><em>paczula</em></code> - z dokładnie jednym znakiem przed i po.</blockquote>\n<h4>Schemat oceniania CKE</h4>\n<blockquote>Klucz CKE (zadanie 6.3, max 3 pkt):<br>- <strong>2 pkt</strong> - zastosowanie filtra <code><em>paczula</em></code> (= <code>%paczula%</code>)<br>- <strong>1 pkt</strong> - filtr <code>paczula<em></code> lub samo <code>paczula</code> (zamiast <code></em>paczula*</code>) - niepełne<br>- <strong>1 pkt</strong> - sortowanie alfabetyczne<br>- <strong>0 pkt</strong> - błędna lub brak</blockquote>\n<h4>Typowe pułapki</h4>\n<ul><li><strong><code>= &#x27;paczula&#x27;</code></strong> zamiast <code>LIKE &#x27;%paczula%&#x27;</code> - pominie składniki typu &quot;olejek paczuli&quot;.</li><li><strong><code>paczula%</code></strong> - pominie składniki typu &quot;olejek paczuli&quot; (nie zaczyna się od paczula).</li><li><strong>Pomylenie polskich znaków</strong> - &quot;paczula&quot; (litera &#x27;l&#x27;) vs &quot;paczuli&quot; (l, ale forma deklinacyjna).</li><li><strong>Brak sortowania</strong> - utrata 1 punktu.</li><li><strong><code>NOT IN</code> z NULL</strong> - może spowodować błędy. Lepiej <code>NOT EXISTS</code>.</li><li><strong>Pomylenie kierunku</strong> - listujemy marki BEZ paczuli, NIE marki Z paczulą.</li></ul>\n<h4>Złożoność obliczeniowa</h4>\n<ul><li>SQL z indeksami: O(n log n) sortowanie + O(n + m) join.</li><li>Python: O(n + m) - dwa przejścia przez pliki.</li><li>Pamięć: O(liczba marek + liczba składników z paczulą).</li></ul>"}]}