Zápis řetězců

Teď se podíváme na zoubek řetězcům. Už s nimi trochu umíš, tak začneme rekapitulací.

Textový řetězec (angl. string) je datový typ (druh hodnot), který obsahuje text – třeba slovo nebo větu.

Když řetězec zadáváš do programu, musíš ho označit – uzavřít do uvozovek, buď jednoduchých nebo dvojitých:

'tohle je řetězec'
"tohle taky"

Je velký rozdíl mezi print('cislo') – vypiš slovo „cislo“ – a print(cislo) – vypiš hodnotu výrazu cislo. Jednou je cislo pět konkrétních písmen; podruhé instrukce k použití proměnné. Počítač, na rozdíl od lidí, rozdíl mezi textem a instrukcí nepozná z kontextu, a tak je uvozovky potřeba používat důsledně.

(Ilustrační komiks. Člověk říká robotovi: "Řekni Pavlovi, ať mi zavolá!". Robot odpoví: "PAVLOVI AŤ MI ZAVOLÁ!")

Znaky

Texty sestávají z jednotlivých písmenek. Řetězce víceméně taky, ale aby bylo jasné, co přesně tím písmenkem myslíme, říkáme, že řetězce sestávají ze znaků (angl. characters).

Takový znak může být písmenko (např. A) nebo číslice (3), ale i jiný symbol (!).

Každý řetězec má určitý počet znaků. Kolik, to nám umí říct funkce len(). Třeba řetězec Ahoj! má znaků pět:

>>> len('Ahoj!')
5

Jeden ze zajímavějších znaků je mezera. Je to taky znak. V řetězci se tedy chová stejně jako písmenko:

>>> len(' ')
1
>>> len('K ní')
4
>>> len('3 + 2')
5

Mimochodem, řetězec může být i prázdný – pak má nula znaků:

>>> len('')
0
>>> len("")
0

Uvozovky

K uvození řetězce můžeš použít jednoduché nebo dvojité rovné uvozovky. Není mezi nimi rozdíl. Podobně 4.0 a 4.000 jsou dva zápisy téhož čísla, tak 'slovo' a "slovo" pro Python označuje stejnou hodnotu, skládající se ze stejných pěti písmen.

Použité uvozovky nejsou součástí hodnoty – python si „nepamatuje“, jakým způsobem byl řetězec uvozen. Když má nějaký řetězec vypsat, jedny si k tomu vybere – většinou ty jednoduché:

>>> "python"
'python'
>>> 'slovo'
'slovo'

Předchozí příklad je z interaktivního režimu Pythonu, který ukazuje hodnoty výrazů „programátorsky“ – pokud možno tak, jak se zapisují v Pythonu. Funkce print() vypisuje hodnoty „hezky“, „pro uživatele“ – v případě řetězců tedy bez uvozovek.

Uvozovky v uvozovkách

Proč si při zadávání textu můžeš vybrat mezi dvěma druhy uvozovek?

Občas se stane, že v rámci textu potřebuješ použít samotnou uvozovku (nebo apostrof). Pak musíš „kolem“ řetězce použít tu druhou:

>>> len('Zpívala si: "Tralala!"')
22
>>> len("Byl to Goa'uld, parazit z planety P3X-888")
41

Když v rámci textu použiješ stejnou uvozovku jako „kolem něj“, tak bude Python naprosto zmatený.

>>> len("Zpívala si: "Tralala"")
Traceback (most recent call last)
  File "<>", line 1
    len("Zpívala si: "Tralala"")
                      ^
SyntaxError: invalid syntax

Pokud používáš chytrý editor, doporučuju si zvyknout na to, jakou barvou máš řetězce zvýrazněné. Často to pomáhá odhalit chybky.

Sekvence se zpětným lomítkem

Co dělat, když v řetězci potřebuješ oba druhy uvozovek, jako ve větě Vtom vnuk křik': "Hleď!"?

Můžeš si pomoci tím, že spojíš dva řetězce:

>>> print("Vtom vnuk křik': " + '"Hleď!"')
Vtom vnuk křik': "Hleď!"

Ale lepší způsob je použít speciální zápis se zpětným lomítkem. Kdykoli se v řetězci objeví sekvence \' nebo \", Python dá do řetězce danou uvozovku.

>>> print("Vtom vnuk křik': \"Hleď!\"")
Vtom vnuk křik': "Hleď!"
>>> print('"Jen ho nech," řek\' děd. "Kdo zná líp kraj?"')
"Jen ho nech," řek' děd. "Kdo zná líp kraj?"

Ve výsledném řetězci pak ovšem žádné zpětné lomítko není. Sekvence \' je jen způsob, jak v Pythonu zadat ' – jediný znak. Tomu je celkem důležité porozumět. Zkus si, jestli předpovědět výsledek těchto příkazů:

print(".\".")
len(".\".")
".\"."  # (v interaktivním režimu)

Řešení

Znaků, které se zadávají sekvencí se zpětným lomítkem je více. Jedna ze zajímavějších je \t, představující tabulátor – jediný znak, který se, když ho vypíšeš, „roztáhne“ na víc mezer.

>>> print("a\tb")   # Výpis "pro lidi"
a       b
>>> "a\tb"          # Výpis "pro programátory"
'a\tb'
>>> len("a\tb")     # Počet znaků v řetězci
3

Se zpětným lomítkem zadat jakýkoli znak – včetně emoji – podle jména (\N{…}) nebo identifikačního čísla (\x.., \u...., \U........) standardu Unicode. Délka všech následujících řetězců je 3:

>>> print('-\N{GREEK CAPITAL LETTER DELTA}-')
-Δ-
>>> print('-\N{SECTION SIGN}-')
-§-
>>> print('-\N{GRINNING CAT FACE WITH SMILING EYES}-')
-😸-
>>> print('-\x60-')
-`-
>>> print('-\u30C4-')
-ツ-
>>> print('-\U0001F0BD-')
-🂽-

Zpětné lomítko

Zpětné lomítko tedy začíná speciální sekvenci (známou pod anglickým termínem escape sequence), kterou zadáš jediný znak.

Tahle vychytávka má jeden, někdy nepříjemný, důsledek: pokud chceš mít jako součást řetězce zpětné lomítko (třeba ve jménech souborů na Windows), nemůžeš použít přímo \. Musíš použít speciální sekvenci \\ – tedy lomítko zdvojit:

print('C:\\PyLadies\\Nový adresář')

Podobně jako \" je zápis pro uvozovku a \' pro apostrof, sekvence \\ je zápis pro znak \.

Nový řádek

Někdy potřebuješ řetězce, které obsahují více řádků. Pythonní řetězce ale můžeš normálně napsat jen na jeden řádek. (Python se tak snaží ulehčit hledání chyby, kdybys koncovou uvozovku zapoměla: kdyby mohla být kdekoli ve zbytku souboru, špatně by se hledala.)

Můžeš ale do řetězce znak pro nový řádek vložit pomocí sekvence \n:

>>> print('Haló haló!\nCo se stalo?')
Haló haló!
Co se stalo?

Ono \n do řetězce vloží znak nového řádku. Ten při výpisu ukončí stávající řádek a přede na nový – ale jinak se chová jako jakýkoli jiný znak:

>>> print('-\n-')
-
-
>>> len('-\n-')
3

Trojité uvozovky

Kromě \n je i druhý způsob, jak zadat řetězec se znakem nového řádku: ohraničit ho třemi uvozovkami (jednoduchými nebo dvojitými) na každé straně. Dají se tak zadávat delší víceřádkové řetězce:

basen = '''Haló haló!
Co se stalo?
Prase kozu potrkalo!'''

Víceřádkové řetězce se často používají jako dokumentační řetězce funkcí. U nich nevadí, že jsou na začátku řádků mezery.

def vynasob(a, b):
    """Vynásobí argumenty a vrátí výsledek.

    Oba argumenty by měly být čísla.
    """

    return a * b

Pozor na to, že pokud je tenhle řetězec v odsazeném kódu, každý jeho řádek bude začínat několika mezerami. (V dokumentačních řetězcích tohle nevadí, tam se s odsazením počítá.)

Formátovací řetězce

A ještě přidám jednu vychtytávku: šablony, kterými můžeš do řetězce vložit hodnotu.

Řekněme, že chceš vypsat určitou hodnotu uživatelovi s nějakou „omáčkou“ okolo. Dá se na to použít print(), kterému můžeš předat „mix“ řetězců a čísel:

>>> soucet = 3 + 4
>>> print('Součet je', soucet)

Co ale když chceš celý tento výpis uložit do proměnné – jako jeden řetězec? Čárka tu fungovat nebude, ta odděluje argumenty ve volání funkce. Je potřeba soucet převést na řetězec a ten pak připojit k „omáčce“:

>>> hlaska = 'Součet je ' + str(soucet)

To ale není tak přehledné, jak by mohlo. Lze to zpřehlednit použitím šablony – formátovacího řetězce (angl. format string nebo f-string).

Takovou šablonu si představ jako formulář s vynechanými místy:

Mil[ý/á] _______,
Váš výsledek je __________.

S pozdravem,
_________

Aby Python věděl, kam co doplnit, jednotlivá vynechaná místa označíš jmény v „kudrnatých“ závorkách:

Mil{y_a} {osloveni},
Váš výsledek je {soucet}.

S pozdravem,
{podpis}.

A nakonec, aby Python věděl že jde o šablonu, před první uvozovku dej písmenko f. Pro náš první případ bude šablona f'Součet je {soucet}':

>>> soucet = 3 + 4
>>> hlaska = f'Součet je {soucet}'
>>> print(hlaska)

Program s dlouhou šablonou může vypadat jako:

y_a = 'á'
osloveni = 'Anežko'
soucet = 3 + 4
podpis = 'Váš Program'

print(f"""Mil{y_a} {osloveni},
Váš výsledek je {soucet}.

S pozdravem,
{podpis}""")

A nakonec – v šabloně můžeš použít nejen jména proměnných, ale jakékoli výrazy.

>>> hlaska = f'Součet je {3 + 4}'

Ale nepřežeň to! Většinou je program přehlednější, když si každou vypisovanou hodnotu zvlášť pojmenuješ.

Cvičení

Jaká je délka těchto řetězců?

Výsledek zjistíš snadno, zkus se ale zamyslet a Python použít jen pro ověření.


print(len('ahoj'))
print(len("""Ahoj!"""))
print(len(' a b '))
print(len('\N{SNOWMAN}ové'))
print(len('a\nb'))
print(len('a\tb'))
print(len('"\'"'))


print(len("""
abc"""))


if True:
    print(len("""a
    b"""))


print(len('C:\new_dir'))

print(len(f'{print}'))
{
  "data": {
    "sessionMaterial": {
      "id": "session-material:2019/brno-jaro-2019-pondeli:turtle:1",
      "title": "Zápis řetězců",
      "html": "\n          \n    \n\n    <h1>Z&#xE1;pis &#x159;et&#x11B;zc&#x16F;</h1>\n<p>Te&#x10F; se pod&#xED;v&#xE1;me na zoubek &#x159;et&#x11B;zc&#x16F;m.\nU&#x17E; s&#xA0;nimi trochu um&#xED;&#x161;, tak za&#x10D;neme rekapitulac&#xED;.</p>\n<p>Textov&#xFD; <em>&#x159;et&#x11B;zec</em> (angl. <em>string</em>) je datov&#xFD; typ (druh <em>hodnot</em>),\nkter&#xFD; obsahuje text &#x2013; t&#x159;eba slovo nebo v&#x11B;tu.</p>\n<p>Kdy&#x17E; &#x159;et&#x11B;zec zad&#xE1;v&#xE1;&#x161; do programu, mus&#xED;&#x161; ho ozna&#x10D;it &#x2013; uzav&#x159;&#xED;t do\n<em>uvozovek</em>, bu&#x10F; jednoduch&#xFD;ch nebo dvojit&#xFD;ch:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"s1\">&apos;tohle je &#x159;et&#x11B;zec&apos;</span>\n<span class=\"s2\">&quot;tohle taky&quot;</span>\n</pre></div><p>Je velk&#xFD; rozd&#xED;l mezi <code>print(&apos;cislo&apos;)</code> &#x2013; vypi&#x161; slovo &#x201E;cislo&#x201C; &#x2013;\na <code>print(cislo)</code> &#x2013; vypi&#x161; hodnotu v&#xFD;razu <code>cislo</code>.\nJednou je <code>cislo</code> p&#x11B;t konkr&#xE9;tn&#xED;ch p&#xED;smen; podruh&#xE9; <em>instrukce</em> k&#xA0;pou&#x17E;it&#xED;\nprom&#x11B;nn&#xE9;.\nPo&#x10D;&#xED;ta&#x10D;, na rozd&#xED;l od lid&#xED;, rozd&#xED;l mezi textem a instrukc&#xED; nepozn&#xE1; z&#xA0;kontextu,\na tak je uvozovky pot&#x159;eba pou&#x17E;&#xED;vat d&#x16F;sledn&#x11B;.</p>\n<p><span class=\"figure\"><a href=\"/2019/brno-jaro-2019-pondeli/beginners/str/static/quote-comic.svg\"><img src=\"/2019/brno-jaro-2019-pondeli/beginners/str/static/quote-comic.svg\" alt=\"(Ilustra&#x10D;n&#xED; komiks. &#x10C;lov&#x11B;k &#x159;&#xED;k&#xE1; robotovi: &quot;&#x158;ekni Pavlovi, a&#x165; mi zavol&#xE1;!&quot;. Robot odpov&#xED;: &quot;PAVLOVI A&#x164; MI ZAVOL&#xC1;!&quot;)\"></a></span></p>\n<h2>Znaky</h2>\n<p>Texty sest&#xE1;vaj&#xED; z&#xA0;jednotliv&#xFD;ch p&#xED;smenek.\n&#x158;et&#x11B;zce v&#xED;cem&#xE9;n&#x11B; taky, ale aby bylo jasn&#xE9;, co p&#x159;esn&#x11B; t&#xED;m <em>p&#xED;smenkem</em>\nmysl&#xED;me, &#x159;&#xED;k&#xE1;me, &#x17E;e &#x159;et&#x11B;zce sest&#xE1;vaj&#xED; ze <em>znak&#x16F;</em> (angl. <em>characters</em>).</p>\n<p>Takov&#xFD; znak m&#x16F;&#x17E;e b&#xFD;t p&#xED;smenko (nap&#x159;. <code>A</code>) nebo &#x10D;&#xED;slice (<code>3</code>),\nale i jin&#xFD; symbol (<code>!</code>).</p>\n<p>Ka&#x17E;d&#xFD; &#x159;et&#x11B;zec m&#xE1; ur&#x10D;it&#xFD; po&#x10D;et znak&#x16F;.\nKolik, to n&#xE1;m um&#xED; &#x159;&#xED;ct funkce <code>len()</code>.\nT&#x159;eba &#x159;et&#x11B;zec <code>Ahoj!</code> m&#xE1; znak&#x16F; p&#x11B;t:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s1\">&apos;Ahoj!&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">5</span>\n</pre></div><p>Jeden ze zaj&#xED;mav&#x11B;j&#x161;&#xED;ch znak&#x16F; je <em>mezera</em>.\nJe to taky znak. V&#xA0;&#x159;et&#x11B;zci se tedy chov&#xE1; stejn&#x11B; jako p&#xED;smenko:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s1\">&apos; &apos;</span><span class=\"p\">)</span>\n<span class=\"go\">1</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s1\">&apos;K n&#xED;&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">4</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s1\">&apos;3 + 2&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">5</span>\n</pre></div><p>Mimochodem, &#x159;et&#x11B;zec m&#x16F;&#x17E;e b&#xFD;t i pr&#xE1;zdn&#xFD; &#x2013; pak m&#xE1; nula znak&#x16F;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s1\">&apos;&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">0</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s2\">&quot;&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">0</span>\n</pre></div><h2>Uvozovky</h2>\n<p>K&#xA0;uvozen&#xED; &#x159;et&#x11B;zce m&#x16F;&#x17E;e&#x161; pou&#x17E;&#xED;t jednoduch&#xE9; nebo dvojit&#xE9; rovn&#xE9; uvozovky.\nNen&#xED; mezi nimi rozd&#xED;l.\nPodobn&#x11B; <code>4.0</code> a <code>4.000</code> jsou dva z&#xE1;pisy t&#xE9;ho&#x17E; &#x10D;&#xED;sla,\ntak <code>&apos;slovo&apos;</code> a <code>&quot;slovo&quot;</code> pro Python ozna&#x10D;uje stejnou\nhodnotu, skl&#xE1;daj&#xED;c&#xED; se ze stejn&#xFD;ch p&#x11B;ti p&#xED;smen.</p>\n<p>Pou&#x17E;it&#xE9; uvozovky nejsou sou&#x10D;&#xE1;st&#xED; hodnoty &#x2013; python si &#x201E;nepamatuje&#x201C;, jak&#xFD;m\nzp&#x16F;sobem byl &#x159;et&#x11B;zec uvozen.\nKdy&#x17E; m&#xE1; n&#x11B;jak&#xFD; &#x159;et&#x11B;zec vypsat, jedny si k&#xA0;tomu vybere &#x2013; v&#x11B;t&#x161;inou ty jednoduch&#xE9;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"s2\">&quot;python&quot;</span>\n<span class=\"go\">&apos;python&apos;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"s1\">&apos;slovo&apos;</span>\n<span class=\"go\">&apos;slovo&apos;</span>\n</pre></div><div class=\"admonition note\"><p>P&#x159;edchoz&#xED; p&#x159;&#xED;klad je z&#xA0;interaktivn&#xED;ho re&#x17E;imu Pythonu, kter&#xFD; ukazuje hodnoty \nv&#xFD;raz&#x16F; &#x201E;program&#xE1;torsky&#x201C; &#x2013; pokud mo&#x17E;no tak, jak se zapisuj&#xED; v&#xA0;Pythonu.\nFunkce <code>print()</code> vypisuje hodnoty &#x201E;hezky&#x201C;, &#x201E;pro u&#x17E;ivatele&#x201C; &#x2013; v&#xA0;p&#x159;&#xED;pad&#x11B;\n&#x159;et&#x11B;zc&#x16F; tedy bez uvozovek.</p>\n</div><h3>Uvozovky v&#xA0;uvozovk&#xE1;ch</h3>\n<p>Pro&#x10D; si p&#x159;i zad&#xE1;v&#xE1;n&#xED; textu m&#x16F;&#x17E;e&#x161; vybrat mezi dv&#x11B;ma druhy uvozovek?</p>\n<p>Ob&#x10D;as se stane, &#x17E;e v r&#xE1;mci textu pot&#x159;ebuje&#x161; pou&#x17E;&#xED;t samotnou uvozovku (nebo\napostrof).\nPak mus&#xED;&#x161; &#x201E;kolem&#x201C; &#x159;et&#x11B;zce pou&#x17E;&#xED;t tu druhou:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s1\">&apos;Zp&#xED;vala si: &quot;Tralala!&quot;&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">22</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s2\">&quot;Byl to Goa&apos;uld, parazit z planety P3X-888&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">41</span>\n</pre></div><p>Kdy&#x17E; v&#xA0;r&#xE1;mci textu pou&#x17E;ije&#x161; stejnou uvozovku jako &#x201E;kolem n&#x11B;j&#x201C;, tak bude Python\nnaprosto zmaten&#xFD;.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s2\">&quot;Zp&#xED;vala si: &quot;</span><span class=\"n\">Tralala</span><span class=\"s2\">&quot;&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">Traceback (most recent call last)</span>\n  File <span class=\"nb\">&quot;&lt;&gt;&quot;</span>, line <span class=\"m\">1</span>\n    <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s2\">&quot;Zp&#xED;vala si: &quot;</span><span class=\"n\">Tralala</span><span class=\"s2\">&quot;&quot;</span><span class=\"p\">)</span>\n                      <span class=\"o\">^</span>\n<span class=\"gr\">SyntaxError</span>: <span class=\"n\">invalid syntax</span>\n</pre></div><p>Pokud pou&#x17E;&#xED;v&#xE1;&#x161; chytr&#xFD; editor, doporu&#x10D;uju si zvyknout na to, jakou barvou\nm&#xE1;&#x161; &#x159;et&#x11B;zce zv&#xFD;razn&#x11B;n&#xE9;.\n&#x10C;asto to pom&#xE1;h&#xE1; odhalit chybky.</p>\n<h2>Sekvence se zp&#x11B;tn&#xFD;m lom&#xED;tkem</h2>\n<p>Co d&#x11B;lat, kdy&#x17E; v &#x159;et&#x11B;zci pot&#x159;ebuje&#x161; <em>oba</em> druhy uvozovek,\njako ve v&#x11B;t&#x11B; <code>Vtom vnuk k&#x159;ik&apos;: &quot;Hle&#x10F;!&quot;</code>?</p>\n<p>M&#x16F;&#x17E;e&#x161; si pomoci t&#xED;m, &#x17E;e spoj&#xED;&#x161; dva &#x159;et&#x11B;zce:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;Vtom vnuk k&#x159;ik&apos;: &quot;</span> <span class=\"o\">+</span> <span class=\"s1\">&apos;&quot;Hle&#x10F;!&quot;&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">Vtom vnuk k&#x159;ik&apos;: &quot;Hle&#x10F;!&quot;</span>\n</pre></div><p>Ale lep&#x161;&#xED; zp&#x16F;sob je pou&#x17E;&#xED;t speci&#xE1;ln&#xED; z&#xE1;pis se <em>zp&#x11B;tn&#xFD;m lom&#xED;tkem</em>.\nKdykoli se v&#xA0;&#x159;et&#x11B;zci objev&#xED; sekvence <code>\\&apos;</code> nebo <code>\\&quot;</code>, Python d&#xE1; do &#x159;et&#x11B;zce danou\nuvozovku.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;Vtom vnuk k&#x159;ik&apos;: </span><span class=\"se\">\\&quot;</span><span class=\"s2\">Hle&#x10F;!</span><span class=\"se\">\\&quot;</span><span class=\"s2\">&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">Vtom vnuk k&#x159;ik&apos;: &quot;Hle&#x10F;!&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;&quot;Jen ho nech,&quot; &#x159;ek</span><span class=\"se\">\\&apos;</span><span class=\"s1\"> d&#x11B;d. &quot;Kdo zn&#xE1; l&#xED;p kraj?&quot;&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">&quot;Jen ho nech,&quot; &#x159;ek&apos; d&#x11B;d. &quot;Kdo zn&#xE1; l&#xED;p kraj?&quot;</span>\n</pre></div><p>Ve v&#xFD;sledn&#xE9;m &#x159;et&#x11B;zci pak ov&#x161;em &#x17E;&#xE1;dn&#xE9; zp&#x11B;tn&#xE9; lom&#xED;tko <em>nen&#xED;</em>.\nSekvence <code>\\&apos;</code> je jen zp&#x16F;sob, jak v&#xA0;Pythonu zadat <code>&apos;</code> &#x2013; jedin&#xFD; znak.\nTomu je celkem d&#x16F;le&#x17E;it&#xE9; porozum&#x11B;t.\nZkus si, jestli p&#x159;edpov&#x11B;d&#x11B;t v&#xFD;sledek t&#x11B;chto p&#x159;&#xED;kaz&#x16F;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;.</span><span class=\"se\">\\&quot;</span><span class=\"s2\">.&quot;</span><span class=\"p\">)</span>\n<span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s2\">&quot;.</span><span class=\"se\">\\&quot;</span><span class=\"s2\">.&quot;</span><span class=\"p\">)</span>\n<span class=\"s2\">&quot;.</span><span class=\"se\">\\&quot;</span><span class=\"s2\">.&quot;</span>  <span class=\"c1\"># (v interaktivn&#xED;m re&#x17E;imu)</span>\n</pre></div><div class=\"solution\" id=\"solution-0\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2019/brno-jaro-2019-pondeli/beginners/str/index/solutions/0/\"><span class=\"link-text\">Uk&#xE1;zat &#x159;e&#x161;en&#xED;</span></a>\n    </div>\n    <div class=\"solution-body\" aria-hidden=\"true\">\n        <div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;.</span><span class=\"se\">\\&quot;</span><span class=\"s2\">.&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">.&quot;.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s2\">&quot;.</span><span class=\"se\">\\&quot;</span><span class=\"s2\">.&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">3</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"s2\">&quot;.</span><span class=\"se\">\\&quot;</span><span class=\"s2\">.&quot;</span>\n<span class=\"go\">&apos;.&quot;.&apos;</span>\n</pre></div>\n    </div>\n</div><p>Znak&#x16F;, kter&#xE9; se zad&#xE1;vaj&#xED; sekvenc&#xED; se zp&#x11B;tn&#xFD;m lom&#xED;tkem je v&#xED;ce.\nJedna ze zaj&#xED;mav&#x11B;j&#x161;&#xED;ch je <code>\\t</code>, p&#x159;edstavuj&#xED;c&#xED; tabul&#xE1;tor &#x2013; jedin&#xFD; znak, kter&#xFD;\nse, kdy&#x17E; ho vyp&#xED;&#x161;e&#x161;, &#x201E;rozt&#xE1;hne&#x201C; na v&#xED;c mezer.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;a</span><span class=\"se\">\\t</span><span class=\"s2\">b&quot;</span><span class=\"p\">)</span>   <span class=\"c1\"># V&#xFD;pis &quot;pro lidi&quot;</span>\n<span class=\"go\">a       b</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"s2\">&quot;a</span><span class=\"se\">\\t</span><span class=\"s2\">b&quot;</span>          <span class=\"c1\"># V&#xFD;pis &quot;pro program&#xE1;tory&quot;</span>\n<span class=\"go\">&apos;a\\tb&apos;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s2\">&quot;a</span><span class=\"se\">\\t</span><span class=\"s2\">b&quot;</span><span class=\"p\">)</span>     <span class=\"c1\"># Po&#x10D;et znak&#x16F; v&#xA0;&#x159;et&#x11B;zci</span>\n<span class=\"go\">3</span>\n</pre></div><p>Se zp&#x11B;tn&#xFD;m lom&#xED;tkem zadat jak&#xFD;koli znak &#x2013; v&#x10D;etn&#x11B; <em>emoji</em> &#x2013; podle jm&#xE9;na\n(<code>\\N{&#x2026;}</code>) nebo identifika&#x10D;n&#xED;ho &#x10D;&#xED;sla (<code>\\x..</code>, <code>\\u....</code>, <code>\\U........</code>)\nstandardu Unicode.\nD&#xE9;lka v&#x161;ech n&#xE1;sleduj&#xED;c&#xED;ch &#x159;et&#x11B;zc&#x16F; je 3:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;-</span><span class=\"se\">\\N{GREEK CAPITAL LETTER DELTA}</span><span class=\"s1\">-&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">-&#x394;-</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;-</span><span class=\"se\">\\N{SECTION SIGN}</span><span class=\"s1\">-&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">-&#xA7;-</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;-</span><span class=\"se\">\\N{GRINNING CAT FACE WITH SMILING EYES}</span><span class=\"s1\">-&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">-&#x1F638;-</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;-</span><span class=\"se\">\\x60</span><span class=\"s1\">-&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">-`-</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;-</span><span class=\"se\">\\u30C4</span><span class=\"s1\">-&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">-&#x30C4;-</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;-</span><span class=\"se\">\\U0001F0BD</span><span class=\"s1\">-&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">-&#x1F0BD;-</span>\n</pre></div><h3>Zp&#x11B;tn&#xE9; lom&#xED;tko</h3>\n<p>Zp&#x11B;tn&#xE9; lom&#xED;tko tedy za&#x10D;&#xED;n&#xE1; speci&#xE1;ln&#xED; sekvenci (zn&#xE1;mou pod anglick&#xFD;m\nterm&#xED;nem <em>escape sequence</em>), kterou zad&#xE1;&#x161; <em>jedin&#xFD; znak</em>.</p>\n<p>Tahle vychyt&#xE1;vka m&#xE1; jeden, n&#x11B;kdy nep&#x159;&#xED;jemn&#xFD;, d&#x16F;sledek: pokud chce&#x161; m&#xED;t jako\nsou&#x10D;&#xE1;st &#x159;et&#x11B;zce zp&#x11B;tn&#xE9; lom&#xED;tko (t&#x159;eba ve jm&#xE9;nech soubor&#x16F; na Windows),\nnem&#x16F;&#x17E;e&#x161; pou&#x17E;&#xED;t p&#x159;&#xED;mo <code>\\</code>.\nMus&#xED;&#x161; pou&#x17E;&#xED;t speci&#xE1;ln&#xED; sekvenci <code>\\\\</code> &#x2013; tedy lom&#xED;tko zdvojit:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;C:</span><span class=\"se\">\\\\</span><span class=\"s1\">PyLadies</span><span class=\"se\">\\\\</span><span class=\"s1\">Nov&#xFD; adres&#xE1;&#x159;&apos;</span><span class=\"p\">)</span>\n</pre></div><p>Podobn&#x11B; jako <code>\\&quot;</code> je z&#xE1;pis pro uvozovku a <code>\\&apos;</code> pro apostrof, sekvence <code>\\\\</code>\nje z&#xE1;pis pro znak <code>\\</code>.</p>\n<h3>Nov&#xFD; &#x159;&#xE1;dek</h3>\n<p>N&#x11B;kdy pot&#x159;ebuje&#x161; &#x159;et&#x11B;zce, kter&#xE9; obsahuj&#xED; v&#xED;ce &#x159;&#xE1;dk&#x16F;.\nPythonn&#xED; &#x159;et&#x11B;zce ale m&#x16F;&#x17E;e&#x161; norm&#xE1;ln&#x11B; napsat jen na <em>jeden</em> &#x159;&#xE1;dek.\n(Python se tak sna&#x17E;&#xED; uleh&#x10D;it hled&#xE1;n&#xED; chyby, kdybys koncovou uvozovku\nzapom&#x11B;la: kdyby mohla b&#xFD;t kdekoli ve zbytku souboru, &#x161;patn&#x11B; by se hledala.)</p>\n<p>M&#x16F;&#x17E;e&#x161; ale do &#x159;et&#x11B;zce znak pro nov&#xFD; &#x159;&#xE1;dek vlo&#x17E;it pomoc&#xED; sekvence <code>\\n</code>:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Hal&#xF3; hal&#xF3;!</span><span class=\"se\">\\n</span><span class=\"s1\">Co se stalo?&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">Hal&#xF3; hal&#xF3;!</span>\n<span class=\"go\">Co se stalo?</span>\n</pre></div><p>Ono <code>\\n</code> do &#x159;et&#x11B;zce vlo&#x17E;&#xED; znak nov&#xE9;ho &#x159;&#xE1;dku.\nTen p&#x159;i v&#xFD;pisu ukon&#x10D;&#xED; st&#xE1;vaj&#xED;c&#xED; &#x159;&#xE1;dek a p&#x159;ede na nov&#xFD; &#x2013; ale jinak se chov&#xE1;\njako jak&#xFD;koli jin&#xFD; znak:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;-</span><span class=\"se\">\\n</span><span class=\"s1\">-&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">-</span>\n<span class=\"go\">-</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s1\">&apos;-</span><span class=\"se\">\\n</span><span class=\"s1\">-&apos;</span><span class=\"p\">)</span>\n<span class=\"go\">3</span>\n</pre></div><h2>Trojit&#xE9; uvozovky</h2>\n<p>Krom&#x11B; <code>\\n</code> je i druh&#xFD; zp&#x16F;sob, jak zadat &#x159;et&#x11B;zec se znakem nov&#xE9;ho &#x159;&#xE1;dku:\nohrani&#x10D;it ho <em>t&#x159;emi</em> uvozovkami (jednoduch&#xFD;mi nebo dvojit&#xFD;mi)\nna ka&#x17E;d&#xE9; stran&#x11B;.\nDaj&#xED; se tak zad&#xE1;vat del&#x161;&#xED; v&#xED;ce&#x159;&#xE1;dkov&#xE9; &#x159;et&#x11B;zce:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">basen</span> <span class=\"o\">=</span> <span class=\"s1\">&apos;&apos;&apos;Hal&#xF3; hal&#xF3;!</span>\n<span class=\"s1\">Co se stalo?</span>\n<span class=\"s1\">Prase kozu potrkalo!&apos;&apos;&apos;</span>\n</pre></div><p>V&#xED;ce&#x159;&#xE1;dkov&#xE9; &#x159;et&#x11B;zce se &#x10D;asto pou&#x17E;&#xED;vaj&#xED; jako dokumenta&#x10D;n&#xED; &#x159;et&#x11B;zce funkc&#xED;.\nU nich nevad&#xED;, &#x17E;e jsou na za&#x10D;&#xE1;tku &#x159;&#xE1;dk&#x16F; mezery.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">vynasob</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Vyn&#xE1;sob&#xED; argumenty a vr&#xE1;t&#xED; v&#xFD;sledek.</span>\n\n<span class=\"sd\">    Oba argumenty by m&#x11B;ly b&#xFD;t &#x10D;&#xED;sla.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">b</span>\n</pre></div><p>Pozor na to, &#x17E;e pokud je tenhle &#x159;et&#x11B;zec\nv&#xA0;odsazen&#xE9;m k&#xF3;du, ka&#x17E;d&#xFD; jeho &#x159;&#xE1;dek bude za&#x10D;&#xED;nat\nn&#x11B;kolika mezerami.\n(V dokumenta&#x10D;n&#xED;ch &#x159;et&#x11B;zc&#xED;ch tohle nevad&#xED;, tam se s odsazen&#xED;m po&#x10D;&#xED;t&#xE1;.)</p>\n<h2>Form&#xE1;tovac&#xED; &#x159;et&#x11B;zce</h2>\n<p>A je&#x161;t&#x11B; p&#x159;id&#xE1;m jednu vychtyt&#xE1;vku: <em>&#x161;ablony</em>, kter&#xFD;mi m&#x16F;&#x17E;e&#x161; do &#x159;et&#x11B;zce vlo&#x17E;it\nhodnotu.</p>\n<p>&#x158;ekn&#x11B;me, &#x17E;e chce&#x161; vypsat ur&#x10D;itou hodnotu u&#x17E;ivatelovi s&#xA0;n&#x11B;jakou &#x201E;om&#xE1;&#x10D;kou&#x201C; okolo.\nD&#xE1; se na to pou&#x17E;&#xED;t <code>print()</code>, kter&#xE9;mu m&#x16F;&#x17E;e&#x161; p&#x159;edat &#x201E;mix&#x201C; &#x159;et&#x11B;zc&#x16F; a &#x10D;&#xED;sel:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">soucet</span> <span class=\"o\">=</span> <span class=\"mi\">3</span> <span class=\"o\">+</span> <span class=\"mi\">4</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Sou&#x10D;et je&apos;</span><span class=\"p\">,</span> <span class=\"n\">soucet</span><span class=\"p\">)</span>\n</pre></div><p>Co ale kdy&#x17E; chce&#x161; cel&#xFD; tento v&#xFD;pis ulo&#x17E;it do prom&#x11B;nn&#xE9; &#x2013; jako jeden &#x159;et&#x11B;zec?\n&#x10C;&#xE1;rka tu fungovat nebude, ta odd&#x11B;luje argumenty ve vol&#xE1;n&#xED; funkce.\nJe pot&#x159;eba <code>soucet</code> p&#x159;ev&#xE9;st na &#x159;et&#x11B;zec a ten pak p&#x159;ipojit k&#xA0;&#x201E;om&#xE1;&#x10D;ce&#x201C;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">hlaska</span> <span class=\"o\">=</span> <span class=\"s1\">&apos;Sou&#x10D;et je &apos;</span> <span class=\"o\">+</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">soucet</span><span class=\"p\">)</span>\n</pre></div><p>To ale nen&#xED; tak p&#x159;ehledn&#xE9;, jak by mohlo.\nLze to zp&#x159;ehlednit pou&#x17E;it&#xED;m &#x161;ablony &#x2013; <em>form&#xE1;tovac&#xED;ho &#x159;et&#x11B;zce</em>\n(angl. <em>format string</em> nebo <em>f-string</em>).</p>\n<p>Takovou &#x161;ablonu si p&#x159;edstav jako formul&#xE1;&#x159; s&#xA0;vynechan&#xFD;mi m&#xED;sty:</p>\n<div class=\"highlight\"><pre><code>Mil[&#xFD;/&#xE1;] _______,\nV&#xE1;&#x161; v&#xFD;sledek je __________.\n\nS pozdravem,\n_________</code></pre></div><p>Aby Python v&#x11B;d&#x11B;l, kam co doplnit, jednotliv&#xE1; vynechan&#xE1; m&#xED;sta ozna&#x10D;&#xED;&#x161; jm&#xE9;ny\nv&#xA0;&#x201E;kudrnat&#xFD;ch&#x201C; z&#xE1;vork&#xE1;ch:</p>\n<div class=\"highlight\"><pre><code>Mil{y_a} {osloveni},\nV&#xE1;&#x161; v&#xFD;sledek je {soucet}.\n\nS pozdravem,\n{podpis}.</code></pre></div><p>A nakonec, aby Python v&#x11B;d&#x11B;l &#x17E;e jde o &#x161;ablonu, p&#x159;ed prvn&#xED; uvozovku dej\np&#xED;smenko <code>f</code>.\nPro n&#xE1;&#x161; prvn&#xED; p&#x159;&#xED;pad bude &#x161;ablona <code>f&apos;Sou&#x10D;et je {soucet}&apos;</code>:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">soucet</span> <span class=\"o\">=</span> <span class=\"mi\">3</span> <span class=\"o\">+</span> <span class=\"mi\">4</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">hlaska</span> <span class=\"o\">=</span> <span class=\"n\">f</span><span class=\"s1\">&apos;Sou&#x10D;et je {soucet}&apos;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">hlaska</span><span class=\"p\">)</span>\n</pre></div><p>Program s&#xA0;dlouhou &#x161;ablonou m&#x16F;&#x17E;e vypadat jako:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">y_a</span> <span class=\"o\">=</span> <span class=\"s1\">&apos;&#xE1;&apos;</span>\n<span class=\"n\">osloveni</span> <span class=\"o\">=</span> <span class=\"s1\">&apos;Ane&#x17E;ko&apos;</span>\n<span class=\"n\">soucet</span> <span class=\"o\">=</span> <span class=\"mi\">3</span> <span class=\"o\">+</span> <span class=\"mi\">4</span>\n<span class=\"n\">podpis</span> <span class=\"o\">=</span> <span class=\"s1\">&apos;V&#xE1;&#x161; Program&apos;</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">f</span><span class=\"s2\">&quot;&quot;&quot;Mil{y_a} {osloveni},</span>\n<span class=\"s2\">V&#xE1;&#x161; v&#xFD;sledek je {soucet}.</span>\n\n<span class=\"s2\">S pozdravem,</span>\n<span class=\"s2\">{podpis}&quot;&quot;&quot;</span><span class=\"p\">)</span>\n</pre></div><p>A nakonec &#x2013; v&#xA0;&#x161;ablon&#x11B; m&#x16F;&#x17E;e&#x161; pou&#x17E;&#xED;t nejen jm&#xE9;na prom&#x11B;nn&#xFD;ch, ale jak&#xE9;koli v&#xFD;razy.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">hlaska</span> <span class=\"o\">=</span> <span class=\"n\">f</span><span class=\"s1\">&apos;Sou&#x10D;et je {3 + 4}&apos;</span>\n</pre></div><p>Ale nep&#x159;e&#x17E;e&#x148; to!\nV&#x11B;t&#x161;inou je program p&#x159;ehledn&#x11B;j&#x161;&#xED;, kdy&#x17E; si ka&#x17E;dou vypisovanou hodnotu zvl&#xE1;&#x161;&#x165;\npojmenuje&#x161;.</p>\n<h2>Cvi&#x10D;en&#xED;</h2>\n<p>Jak&#xE1; je d&#xE9;lka t&#x11B;chto &#x159;et&#x11B;zc&#x16F;?</p>\n<p>V&#xFD;sledek zjist&#xED;&#x161; snadno, zkus se ale zamyslet a Python pou&#x17E;&#xED;t jen pro ov&#x11B;&#x159;en&#xED;.</p>\n<div class=\"highlight\"><pre><code>\nprint(len(&apos;ahoj&apos;))\nprint(len(&quot;&quot;&quot;Ahoj!&quot;&quot;&quot;))\nprint(len(&apos; a b &apos;))\nprint(len(&apos;\\N{SNOWMAN}ov&#xE9;&apos;))\nprint(len(&apos;a\\nb&apos;))\nprint(len(&apos;a\\tb&apos;))\nprint(len(&apos;&quot;\\&apos;&quot;&apos;))\n\n\nprint(len(&quot;&quot;&quot;\nabc&quot;&quot;&quot;))\n\n\nif True:\n    print(len(&quot;&quot;&quot;a\n    b&quot;&quot;&quot;))\n\n\nprint(len(&apos;C:\\new_dir&apos;))\n\nprint(len(f&apos;{print}&apos;))</code></pre></div>\n\n\n        "
    }
  }
}