Níže uvedený text pochází z prvního vydání. Nad tímto textem se nachází aktuální stav po revizi směřující k druhému vydání.
Tato část není součástí originálního textu. Obsahuje poznámky, uspořádané po jednotlivých kapitolách. Text poznámek vychází z mých studijních, praktických a pedagogických zkušeností, které jsem nasbíral v době svého působení na Ústavu informatiky a výpočetní techniky FEI VUT v Brně (od roku 2002 samostatná Fakulta informačních technologií).
Motivačních faktorů pro vznik překladu bylo více — viz dále. Původně soukromá aktivita našla kladnou odezvu a podporu ze strany výše zmíněné Fakulty informačních technologií při VUT v Brně. Elektronická podoba překladu je zahrnuta do portfolia studijní literatury pro programátorské kurzy ve vyšších studijních ročnících, kde se o jazyku Python uvažuje jako o výukovém jazyce, na kterém se demonstrují některé principy objektového návrhu a výstavby složitých softwarových systémů a prvky metodologie vývoje takových systémů. (Jazyk Python zde není cílem výuky, ale vyjadřovacím prostředkem.)
Původně jsem své poznámky, které upravují souvislost a srozumitelnost a které jsou za tímto účelem vkládány přímo do vět, uzavíral do hranatých závorek a odlišoval barevným podkladem. Při revizi v listopadu roku 2003 jsem dospěl k názoru, že hranaté závorky v těchto případech zhoršují čitelnost textu a ponechal jsem pouze ne příliš výrazné barevné odlišení podkladu textu spolu s textem v bublině (tool tip), pokud nad text najedete myší. Pokud poznámka v textu tvoří samostatný odstavec, pak je obvykle uvozena textem Poznámka překladatele.
Pokud v textu naleznete takto označený text (výrazný, bílý na červeném podkladu), pak se jedná většinou o místo, ve kterém má být něco doplněno, upraveno, zkontrolováno a podobně. Čím víc se překlad bude blížit k finální podobě, tím méně byste měli těchto proklatě čevených značek v dokumentech najít.
Na konci každé stránky naleznete odkaz s e-mailovou adresou, na kterou můžete posílat připomínky k překladu dané kapitoly. Rád přivítám podnětné návrhy a postupně je budu zapracovávat do odpovídajících dokumentů. Než ale nějakou připomínku či požadavky zašlete, uvědomte si, prosím, že vše dělám ve svém volném čase.
Úvod
- Informace o druhém výtisku knihy
- Pojem framework
- Pojem Web
- Pojem Internet
- Pojem syntaxe
- Skupina uživatelů jazyka Python
- Pojem Rapid Prototyping
Co potřebuji?
- Překlad byte versus bajt
Co je programování?
- Proč se v MS Windows již málo setkáváme s dávkovými soubory
- Anglický pojem object code
- Scheduler utility
Začínáme
- Poznámka k úplné příručce IDLE
- Nová verze překladače Python může uvádět přesnější význam chyby
Data, datové typy a proměnné
- Jak chápat význam proměnné v jazyce Python
- Instance její identifikace
- Statická typová kontrola
- Jsou to tedy reálná nebo racionální čísla?
- Hash table = vyhledávací tabulka
- Potravina s anglickým jménem Spam
- Řetězec nebývá považován za jednoduchý datový typ
Další posloupnosti a jiné věci
- The joy of being IDLE
Styl zápisu kódu
- Poznámka k systémům pro správu verzí
Konverzace s uživatelem
- Poznámka k zápisu českých řetězců s diakritikou
Větvení, aneb nechť padne rozhodnutí
- Je vytváření boolovských proměnných skutečně řídkým jevem?
- Takže píše se true a false s malým nebo s velkým počátečním písmenem?
Modulární programování (Funkce a moduly)
- Poznámka k #include
v C a C++
Práce se soubory a s textem
- Proč se log-souboru říká log-soubor?
- Poznámka k pojmu stream
Objektově orientované programování
- Co to je widget?
- Pohled na objekty a instance přes pohádku o Popelce
Programování uživatelského rozhraní
- Pojem pixel
Případová studie
- Pojem refaktorizace (refactoring)
Programovací jazyky, které jsem používal
- Co se vlatně rozumí pojmem skriptování ve velkém?
Ačkoliv autor originálu, Alan Gauld, na některých místech tvrdí, že nechce vyzvedávat žádný konkrétní programovací jazyk, z jiných míst je zřejmé, že v tomto textu hraje prim jazyk Python. Je to jazyk jednoduchý, krásný, v rámci nutných kompromisů čistý, mocný co do vyjadřovacích prostředků. To z něj činí dobrého kandidáta na programovací jazyk pro výuku programování. Na druhou stranu to není jazyk, který by byl vhodný jen na hraní. Jde o jazyk velmi praktický. Svým pojetím a vlastnostmi je dokonce dokonce natolik výjimečný, že jeho autor — Guido van Rossum — obdržel od Free Software Foundation ocenění Award for the Advancement of Free Software (Cena za pokrok v rámci Free Software) za rok 2001. Jde o čtvrté ocenění tohoto druhu — viz přehled ocenění.
Pokud se Python naučíte, určitě budete jeho znalost moci využít pro efektivní řešení řady problémů. Prvním motivačním faktorem byl tedy samotný jazyk Python.
Podle mého názoru je Python mnohem vhodnější pro výuku programování, než například BASIC v jakékoliv podobě (zde biji do osnov řady středních škol). Při zachování jednoduchosti a pragmatičnosti vyjadřování při výuce i při praktickém používání předčí řadu složitějších jazyků. I když má překladač jazyka Python z hlediska uživatele spíše vlastnosti interpretu, přesto dobře podporuje koncept objektově orientovaného programování v tom smyslu, že umožní pochopit principy OOP a nezakrývá je různými podivnostmi (viz jazyk Perl). Python vám neumožní tvořit co do efektivnosti kódu na tak detailních úrovních, jako například C++, ale poskytuje moderní datové abstrakce (například kontejnery typu seznam, tabulka) a podporuje moderní způsoby práce s nimi (iterátory), což při výuce programování považuji za mnohem přínosnější, než například schopnost manipulovat s jednotlivými bity. Při hlubším studiu zjistíte, že Python definuje i mechanismus, který umožní převedení každého objektu na sekvenci bajtů, kterou můžeme například uložit do souboru nebo poslat někam po síti. Na jiném místě nebo v jiném čase pak můžeme objekt znovu zrekonstruovat. Zmíněné vlastnosti a možnost jejich použití v tak čisté podobě a jejich zamýšlený účel nezná dokonce ani mnoho programátorů z povolání — pokud je vůbec znají. (Nijak se tím nechci dotknout VŠ absolventů fakult, které mají počítače a informatiku přímo v názvu. Ale ruku na srdce — i z těchto fakult vycházejí někdy absolventi, kteří s těmito koncepty mají problémy. Podle mé zkušenosti navíc řada programátorů v praxi má jen středoškolské vzdělání. Jakkoliv mohou být šikovní, troufám si tvrdit, že ani získávání programátorských certifikátů firmy Microsoft je k podobným znalostem nepřivede.) Druhým motivačním faktorem tedy bylo poskytnout text, který podle mého názoru lze použít i pro výuku začínajících programátorů — třeba i na středních školách —, kdy stupeň znalosti anglického jazyka může být překážkou k osvojení si podobné látky z originálního textu.
Původně zamýšleným cílem byla revize překladu autorky Soni Reisnerové, kterou naleznete na stránkách firmy dataPartner, s.r.o.. Firma dataPartner dala stránkám grafickou podobu, kterou ocenil i autor Alan Gauld. Při pokusech o revizi překladu se ovšem ukázalo, že pro mne bude jednodušší přeložit originál znovu. Jedním z důvodů je i skutečnost, že originální text prošel po původním překladu dalším vývojem a velmi odlišné značkování HTML stránek originálu a překladu ztěžovalo porovnávání.
Vznikl tedy tento (alternativní) překlad. Kromě zachycení inovovaného obsahu originálu jsem si vytkl za cíl i vyšší shodu překladu s originálním zněním textu. Tam, kde by přesný překlad nebyl v souladu s používanou českou terminologií nebo kde by díky překladu mohlo dojít k jeho nejednoznačnému výkladu, dávám přednost přesnému vyjádření myšlenky autora po stránce věcné, nikoliv po stránce čistě jazykové. Třetím motivačním faktorem tedy bylo zvýšení užitné hodnoty původního překladu.
V neposlední řadě jsem se rozhodl pro návrat k jednoduššímu stylu značkování HTML dokumentů, který se více blíží originálu. Současně vznikly CSS soubory, které definují styl zobrazování. Ten připomíná vzhled stránek původního překladu. Přesun informací o stylu do CSS souborů umožnil další zjednodušení značkování vlastních HTML dokumentů a odstranění některých technických problémů, které byly pozorovány při prohlížení původního překladu v alternativních HTML prohlížečích. Styly jsou navrženy tak, aby je mohl použít i autor originálního textu a autoři překladů do jiných jazyků, aniž by museli příliš zasahovat do způsobu značkování svých HTML dokumentů. To umožní případné sjednocení vzhledu originálu i překladů. Vyřešení této technické stránky bylo čtvrtým motivačním faktorem.
A nyní již následují poznámky uspořádané po jednotlivých kapitolách. Číslo v hranatých závorkách tvoří zpětný odkaz do místa, ke kterému se poznámka vztahuje.
Tato informace se týká druhého výtisku prvního vydání knihy v anglickém jazyce. V květnu 2002, kdy byla napsána tato poznámka, neexistoval český překlad a ani jsem neměl informace o tom, že by na českém překladu někdo pracoval.
Originální text používá obrat OO games framework, ve kterém slovo framework vyjadřuje pojem, pro který nemáme dobře použitelný jednoslovný český ekvivalent. Z jazykového hlediska bychom jej mohli přeložit jako rámec, ale v technických textech s programátorskou tématikou se takto obvykle nepřekládá. Vyjadřuje se jím existence předem připravené architektury vyvíjeného programu nebo jeho typických částí. Takové vývojové nebo programátorské prostředí může mít charakter obecný, ale velmi často se tento pojem používá v souvislosti s řešením speciální kategorie problémů. Účelem je dosažení co nejlepších vyjadřovacích prostředků z hlediska řešeného problému. Jinými slovy, zápis řešeného problému s využitím takových předem připravených prostředků je obvykle mnohem stručnější, přehlednější a tedy i efektivnější, než jakého bychom dosáhli bez jejich využití. Vývoj aplikace probíhá s využitím abstrakcí vyšší úrovně.
Games framework tedy můžeme přeložit jako prostředí pro psaní her. Zkratka OO (Object Oriented ...) se jednoznačně překládá jako objektově orientované.... Dohromady s pojmem framework naznačuje, že se zde setkáme s objektově orientovaným prostředím pro psaní specializovných aplikací (zde her). Typicky to znamená, že se s objekty setkáváme jako s prvky vytvářené aplikace, což podstatné z hlediska programátora, který tyto prostředky využívá. Může to také znamenat, že byl objektově orientovaný přístup použit pro vytvoření pracovního prostředí (framework), což může být pro koncového programátora méně důležité. V současné době to často znamená obojí, protože objektově orientovaný přístup se jeví jako vhodný přístup pro řešení široké škály problémů.
Pojem Web se používá jako kratší varianta celého názvu World-Wide Web, pro který se používá velmi známá zkratka WWW. Lze jej doslova přeložit jako celosvětová síť. Samotné anglické slovo web lze přeložit také jako pavučina (tj. síť upletená pavoukem). Pojem Web tedy zvýrazňuje trošku jiný smysl sítě, než pouhé propojení více počítačů dráty. Nese v sobě o něco abstraktnější příchuť. Chápejte jej spíše ve smyslu celosvětová informační síť.
Web je tvořen takzvanými webovými servery, což jsou speciální aplikační programy, které obvykle běží na vyhrazených počítačích — serverech v hardwarovém smyslu. (Pojem server se používá jak pro obslužné programy určitého typu, tak pro hardware se speciálním určením — jde o dvě odlišné věci.)
Webové servery spolu nejsou z abstraktního pohledu nijak propojeny. Definují svůj vlastní obsah, který je uložen v jejich lokálním diskovém prostoru v podobě dokumentů. Nejtypičtější formát dokumentů je znám pod pojmem HTML dokumenty, ale podoba dokumentů může být i jiná. Pro webový server je typické hlavně to, že že poskytuje služby (proto se mu říká server) klientským aplikacím, které se označují jako webovské prohlížeče, nebo prostě prohlížeče (například Mozilla, Netscape Navigator, Microsoft Internet Explorer a další). Od jiných serverů se liší tím, že pro komunikaci s prohlížečem používá takzvaný http protokol. (Pojem protokol obecně představuje předpis pro korektní chování — ať už pro státnické jednání nebo pro komunikaci ve světě počítačů.)
Vytvoření zmíněné celosvětové informační sítě se tedy nevytváří propojením serverů. Vytváří se vzájemným propojením dokumentů takzvanými hypertextovými odkazy. Odtud také pochází název formátu HTML — HyperText Markup Language.
Protikladem izolovaných webových serverů jsou například poštovní servery (používají protokoly SMTP, POP3, …) nebo news servery (používají komunikační protokol NNTP). Ty, narozdíl od webových serverů, vystupují navzájem aktivně a zasílají si vzájemně zprávy pro konkrétního adresáta (poštovní servery) nebo rozesílají příspěvky do zadaných diskusních skupin po celém světě (news servery).
Nejznámější celosvětové komunikační síti se říká Internet (viz dále). Ta umožňuje používání všech výše zmíněných komunikačních protokolů a tím umožňuje existenci jak webové sítě, tak systému poštovních serverů, systému news serverů a dalších, o kterých se zde nezmiňuji.
Závěr: Nezaměňujte pojmy Web a Internet (alespoň ne v situacích, kdy by to mohlo mást).
Česky hovořící běžní uživatelé často používají pojem Internet nepřesně, spíše ve významu Web (viz výše). Pokud jsme ale u pojmu web zdůraznili spíše abstraktnější význam ve smyslu celosvětová informační síť, pak u pojmu Internet můžeme zdůraznit spíše význam ve smyslu celosvětová komunikační síť.
Pro veškerou komunikaci mezi jinak fyzicky oddělenými počítači potřebujeme síť v technickém smyslu (vulgárně řečeno se jedná o dráty, optické kabely, radiová spojení, po kterých ty bity a bajty běhají). Nad nimi se budují logické komunikační sítě, které zakrývají technickou realizaci spojení (jestli je to drát nebo optické spojení nebo radiové spojení) a zvýrazňují jejich schopnost přenášet informace z jednoho určeného místa na druhé. Jednou z takových sítí je i Internet. Cílem Internetu tedy není poskytnout jen nějakou konkrétní službu — například v podobě webových stránek. Cílem Internetu je poskytnout obecné prostředí pro přenos dat různého charakteru.
Výše zmíněná schopnost tvořit komunikační síť vyžaduje především dvě vlastnosti: schopnost určit místo (existence adres) a zajistit správné chování při přenosu dat mezi dvěma místy. Děje se tak na různých úrovních abstrakce. Tomu odpovídají komunikační protokoly, u kterých rovněž existují úrovně od jejprimitivnějších po nejabstraktnější.
Závěr: Nezaměňujte pojmy Web a Internet. Web potřebuje pro svou existenci komunikační prostředí. Ale i poštovní servery potřebují komunikační prostředí. A platí to pro mnoho dalších aplikací. Internet takové komunikační prostředí realizuje.
S pojmy syntaxe a sémantika jste se možná setkali poprvé při studiu lidského (tedy nikoliv programovacího) jazyka. Pojem syntaxe bychom mohli zjednodušeně opsat jako "jak se to zapisuje". Související pojem sémantika naopak vyjadřuje "co to znamená" nebo "co se tím myslí".
V souvislosti s programovacími jazyky je nutné velmi přesně dodržovat syntaxi — tedy způsob zápisu —, protože na základě tohoto zápisu výsledná aplikace provádí konkrétní akce. Jinými slovy, syntaktickým konstrukcím (kouskům zdrojového textu) jsou přiřazeny operace, odpovídající významu těchto konstrukcí (sémantice). Počítač ve spolupráci s překladačem programovacího jazyka udělá přesně to, co je předepsáno. Nic si nedomyslí, nic si sám neopraví. Proto musíme pečlivě dodržovat, zda má někde být napsána třeba dvojtečka. Proto u jazyka Python musíme dodržovat odsazení řádků zdrojového textu a podobně.
Moderní, vhodně navržené programovací jazyky počítají s tím, že se člověk (programátor) může dopustit překlepu. Syntaktické konstrukce jsou proto navrhovány tak, aby byly nechtěné překlepy odhaleny jako chyba při zápisu a nikoliv jako předpis pro původně nechtěnou operaci. Takže okem špatně postřehnutelný překlep by již neměl způsobit například havárii kosmického nosiče, jak se to skutečně dříve stalo. Pro zápis řídicího programu rakety byl tehdy využit jazyk Fortran.
cz.comp.lang.python [doplnit]
PyCZ je portál zabývající se programovacím jazykem Python. Záběr toho portálu se týká všech činností, které mají alespoň něco společného s Pythonem:
[doplnit]
Když jsem byl ještě student — hrdý na pokrokový obor, který jsem studoval (ačkoliv samotnou účastí na studiu těžko můžete získat nárok na jakési zásluhy, tím méně nárok na posuzování a odsuzování terminologie oboru, který studujete) — pobuřovalo mne, když jsem v populárně vědeckých textech nacházel pojmy jako bajt nebo displej. "Jak někdo může prznit naše svaté pojmy!"
Jazyk se vyvíjí. I cizí pojmy jsou jen slova, která by měla dobře zapadat do rodného jazyka. Někdy to není snadné. Fonetický přepis pojmů je jedním z osvědčených způsobů. Extrémním příkladem používání takového přístupu může být ostatně jiný, typicky slovanský jazyk — jazyk ruský.
Můj názor na překlad tohoto pojmu by tedy měl být v tomto okamžiku zřejmý. Nesouhlasíte s ním? Pobuřuje vás to? Zkuste prosadit, aby se používal opět zápis tramway! A víte vůbec, jak toto slovo vzniklo?
Podle mého názoru je to dáno především tím, že se uživatelé systému MS Windows postupně vzdalují od stylu práce, kdy bylo nutné o programování alespoň něco málo vědět. Z hlediska programování se přibližují k laikům, které zajímá především dosažení cíle, daného charakterem jejich práce. Mnozí opravdoví programátoři jimi pohrdají, ale musíme si uvědomit, že počítače jsou tu především proto, abychom je používali. Cílem není to, aby se staly centrem našeho zájmu. Programování bychom proto neměli vnímat jako l'art pour l'art (umění pro umění).
Druhým důvodem, který může maskovat používání dávkových souborů v MS Windows, je existence grafického uživatelského rozhraní, kde se provádění akcí aktivuje poklepáním na zvolenou ikonu. Některé z ikon mohou aktivovat i dávkové soubory, ale uživatel to takto nevnímá. Proto si nemusí být existence BAT souborů vůbec vědom.
A je tu ještě jeden důvod. Uživatelé, kteří vědí, kde mají ručník… (viz Douglas Adams: Stopařův průvodce po Galaxii), používají výkonnější a výhodnější náhrady v podobě jiných skriptovacích jazyků. Jedním z velmi vhodných jazyků je právě Python.
V originálním textu a na různých místech v anglicky psané literatuře se hovoří o překladu do podoby "object code". Ačkoliv to svádí k překladu "… do objektového kódu", dopustili bychom se zde významové nepřesnosti. Výsledek nemá nic společného s objektem ve smyslu objektově orientovaného programování. Tento pojem se také používal mnohem dříve, než se v programování začalo o objektově orientovaném přístupu hovořit. V angličtině může být slovem object vyjádřeno jednak něco hmatatelného, něco, co se dá vyjádřit samostatnou existencí. Ale slovo object může mít i význam cíle, jako výsledku určitého záměru nebo snažení. Do českého jazyka se proto překládá object code jako cílový kód.
Anglický pojem object code dal také vznik příponě souborů obj
, které se používají pro jména souborů s výsledkem překladu v binární podobě. Tyto soubory ještě nejsou spustitelné. K vytvoření spustitelného souboru musí ještě proběhnout minimálně jedna fáze překladu — sestavení (link). Ještě jednou — neexistuje zde žádná logická spojitost s objektově orientovaným programováním.
Pojem scheduler utility lze v této souvislosti přeložit jako plánovací program. Konkrétně se tím myslí program, který je obvykle součástí operačního systému a který umožňuje například naplánování spuštění zvoleného programu ve zvolenou hodinu v každém pracovním dnu v týdnu. Obecně se dá říci, že je to pomocný program, který hlídá, zda nastala stanovená podmínka a pokud ano, provede stanovenou akci — jako je například spuštění dávkového programu.
Úplná příručka IDLE je poněkud zastaralá. V době revize překladu (červenec 2004) existovala verze IDLE 1.0.3, ale záhlaví příručky uvádělo verzi 0.5.
Verze překladače Python 2.2.1, která se na začátku hlásí takto…
Python 2.2.1 (#34, Apr 9 2002, 19:34:33) [MSC 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>>
… uvádí pro stejný případ jinou podobu chybového hlášení:
>>> print 'fred' + 7 Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: cannot concatenate 'str' and 'int' objects
V této kapitole nejsou uvedeny žádné poznámky formou odkazu.
Pokud se s pojmem proměnná setkáváme v matematice, pak jej chápeme jako název symbolu, místo kterého se může dosadit hodnota příslušného typu. Při úpravách matematických výrazů pracujeme pouze s tímto jménem. Konkrétní hodnotu obvykle dosazujeme až v okamžiku, kdy chceme abstraktní výraz zredukovat na speciální případ. Dosazení hodnoty za jméno symbolu se provede prostou textovou náhradou. Při lidském zpracování žádné další vysvětlování není potřeba (zjednodušeně řečeno).
V programech se musí s proměnnými pracovat bez rozhodovacích schopností člověka, bez vnějších zásahů. Proto musí být vyjádření proměnné mnohem konkrétnější. Proměnná si v programech ponechává tu vlastnost, že pojmenovává konkrétní hodnotu, která ovšem může být — jak již název napovídá — proměnná. Různé jazyky vytvářejí vazbu mezi jménem a mezi odpovídající hodnotou (přesněji instancí datového typu — viz dále) různým způsobem. Při používání proměnných v programu proto musíme znát některé detaily, které s existencí proměnných a odpovídajících hodnot souvisejí.
U kompilovaných jazyků se ve výsledném kódu jméno proměnné postupně transformovalo až na konkrétní hodnotu adresy v paměti. Také údaj o konkrétním datovém typu je přetaven do podoby konkrétních posloupností instrukcí. Z výsledného kódu již například zpětně nemůžeme určit, jak se konkrétní proměnná jmenovala. Pokud to není zajištěno speciálním způsobem, nemůžeme za běhu ani určit typ. Vše již bylo zkontrolováno a rozhodnuto během překladu. U takových systémů můžeme o jménu proměnné ve zdrojovém textu uvažovat jako o abstraktním vyjádření adresy, která bude známa až po dokončení všech fází generování výsledného spustitelného kódu. Pokud se jméno proměnné objeví v místě, kde se očekává hodnota, pak je použit obsah, který proměnná pojmenovává. Pokud potřebujeme z nějakých důvodů uložit přímo adresu instance datového typu, pak pro ni použijeme takzvanou ukazatelovou proměnnou. Pro vyjádření nepřímého odkazu na instanci datového typu prostřednictvím ukazatelové proměnné používáme odlišný zápis, než při přímém odkazu s použitím jména proměnné.
Jazyk Python má blíže k interpretačním jazykům. To mimo jiné znamená, že za běhu programu existují struktury, které udržují informaci o jménech proměnných, o jejich typech a odkazy na konkrétní instance datových typů. V jazyce Python se vytvářejí vnitřní vazby mezi jménem proměnné a identifikací instance. Takový pár se vlastně podobá ukazatelové proměnné v kompilovaných jazycích. Nepřímost odkazu je ale skrytá. Při použití jména proměnné se k instanci přistupuje vždy nepřímo, s využitím identifikace instance. Děje se tak ve všech myslitelných případech. Neexistuje jiný způsob přístupu k instancím.
Závěr: Pokud jste zvyklí na pojem proměnné, jak je používán u kompilovaných jazyků, pak o proměnných v jazyce Python uvažujte jako o odkazech přes ukazatel. Způsob zápisu přitom odpovídá přímému použití odpovídajícího objektu (instance datového typu). O přiřazování čehokoliv do proměnné uvažujte tak, že se vytváří vazba mezi jménem a instancí datového typu.
Instancí datového typu rozumíme konkrétní výskyt hodnoty daného datového typu. S tím je spojena skutečnost, že v paměti počítače musí být na určitém místě vyhrazen prostor o potřebné velikosti. Pokud v jazyce Python použijeme například číselnou konstantu 7, pak je vytvořena instance typu celé číslo (jinými slovy objekt typu celé číslo).
Každá vytvořená instance datového typu dostane přidělenu vnitřní identifikaci. Můžeme ji zjistit voláním zabudované funkce id()
. V současné implementaci jazyka Python je identifikace totožná s adresou místa, na kterém je objekt umístěn. Ale mohla by být i jiná. Důležitá je její jednoznačnost.
Pokud říkáme, že do proměnné přiřazujeme instanci určitého typu, pak vlastně provádíme navázání jména proměnné na identifikaci instance. Pokud ovšem jméno proměnné použijeme v místě, kde se má použít hodnota odkazované instance (například u typu celé číslo) nebo kde se má volat metoda instance (objektu), pak dojde k automatickému zpřístupnění instance, aniž bychom onu nepřímost odkazu museli nějakým zvláštním způsobem vyjádřit.
Slovo statická vyjadřuje skutečnost, že se typová kontrola provádí při zpracování zdrojového textu programu (v době překladu). Výsledný kód programu je vygenerován pouze v případě, kdy při není při typových kontrolách nalezen žádný problém. Tehdy je současně zajištěno, že se při běhu programu nevyskytne například přiřazení hodnoty do proměnné neodpovídajícího typu. To jinými slovy znamená, že si z pohledu práce s typy můžeme být jisti tím, že je program správný.
Opakem statické typové kontroly je kontrola až za běhu programu. Můžeme si sice být jistí tím, že případná nekorektní práce s typy bude odhalena, ale dokud tato chyba nenastane, nevíme, zda náš program někde chybu tohoto typu neobsahuje.
Pro uložení hodnot máme v počítači vždy omezený prostor. U základních datových typů máme velmi často dánu dokonce přesnou velikost tohoto prostoru v bajtech. Současně máme dán způsob kódování čísla — obvykle ve dvojkové soustavě. To ale znamená, že veškeré hodnoty reálných čísel můžeme vyjádřit pouze přibližně — jako hodnotově nejbližší zlomek. Ve skutečnosti tedy v počítačích nepracujeme s reálnými čísly, ale s racionálními čísly, což jsou čísla, která lze vyjádřit zlomkem s celočíselným čitatelem i jmenovatelem.
V jazyce Python a v některých dalších novějších jazycích se pro tento typ datové struktury začal používat pojem slovník, protože je tím vystižen způsob jejího používání. Pojem je navíc jednoslovný a snadno pochopitelný. Snadno pochopitelná je i skutečnost, že o systému hesel (klíčů) a odpovídajích popisů můžeme uvažovat jako o tabulce s dvěma sloupci. Pochopitelné je i to, že bychom v takové tabulce rádi něco dokázali vyhledat. Souvislost mezi pojmem slovník a klasickým pojmem pro tuto datovou strukturu — vyhledávací tabulka — by tedy měla být zřejmá. Zbývá vysvětlit pojem hash.
V českých kuchařských knihách se můžete setkat s jídlem zvaným hašé. (Jde o počeštěnou formu slova hash nebo nějakého jejich společného základu.) Je to více typů surovin rozsekaných na kousky a smíchaných dohromady. Dejme tomu, že je tam nějaký druh masa, nějaké druhy zeleniny a další přísady. (Nechtějte po mě detaily — nejsem v tomto směru odborník.) Proveďme následující (raději jen myšlenkový) experiment. Považujme onu hromádku surovin za klíč a recept na přípravu odpovídajícího jídla za hledanou hodnotu. Vezměme to tak, že prošmejdíme naše zásoby, dáme je na hromadu a chtěli bychom vědět, co se z toho dá uvařit. Nejpracnější způsob spočívá v postupném prohledávání kuchařské knihy a porovnávání našich surovin (klíče) se vstupními požadavky jednotlivých receptů. Asi to bude trvat dost dlouho.
Vezměme si nyní jen speciální případy, kdy hromádku surovin můžeme rozsekat na malé kousky — třeba v masovém mlýnku. Ve vzniklé hmotě už nemusíme být schopni rozeznat, jaké konkrétní suroviny byly rozsekány. Ale když z ní odebereme malou lžičku (vzorek), přidáme k ní popis zúčastněných surovin i s poměry jejich mísení a nakonec i celý text receptu, dostaneme jakýsi vzorník několika vhodných receptů, kterým tento postup neublíží. Pokud vám teď někdo přinese lžičku hmoty připravené podle stejného postupu a pokud budete schopni porovnat její podobnost s vaším vzorníkem, můžete mu říci, o jaké suroviny se jednalo a co má s takovou hmotou dál dělat, aby se to dalo jíst (pokud možno). Na základě podivného vzorku tedy můžete něco říci o klíči a o hodnotě. Při vhodném uspořádání našeho vzorníku můžete k této informaci dospět rychleji, než při postupném pročítání všech receptů. Na tomto principu jsou založeny vyhledávací tabulky s trochu slangově znějícím polovičním překladem — hešovací tabulky.
Princip uvedených tabulek je založen na schopnosti pomixovat vyhledávané heslo (klíč) do podoby, která nám sice sama o sobě nic neřekne, ale která nás rychle dovede k požadované hodnotě ve slovníku. V případě našich kulinářských vzorků bychom náš vzorník asi prostě přelétli očima a nějak vyhledali příslušný záznam. Pokud místo potravinářských surovin zpracováváme data, bude náš masový mlýnek mít matematickou podobu. Důležité je, aby pro různé vstupní suroviny vypadl z matematického masového mlýnku různý výsledek. Vyhledávání dále vylepšíme takovým způsobem, že vzorek pomocí jednoduchých matematických operací převedeme na číslo v předem určeném intervalu a dostaneme tak index do pole, které je jádrem hešovací tabulky. Z určeného místa v poli získáme informace ve tvaru dvojice (klíč, hodnota)
. Pokud se klíč na tomto místě shoduje se vstupním klíčem, pak jsme našli i hodnotu, kterou jsme hledali. Pokud ne, musíme dále dohledávat. Způsobů organizace hešovacích tabulek a odpovídajících technik dohledání výsledku je několik. Aby celý postup neztratil na účinnosti, musí být náš matematický mlýnek dostatečně rychlý.
Zmíněnému matematickému mlýnku se říká hešovací funkce (hash function). Říká se jí také rozptylovací funkce, protože se vlastně používá pokud možno k rovnoměrnému rozptýlení vstupních klíčů do celého prostoru hešovací tabulky. Snažíme se o minimalizaci množství konfliktů, kdy různé klíče vedou ke stejnému indexu v hešovacím poli. Takovým položkám se pak říká synonyma. Ta musí být prozkoumávána podrobnějším způsobem (provádíme výše zmíněné dohledání), abychom zjistili, které ze synonym odpovídá hledanému klíči. Dohledávání samozřejmě vede ke zdržením při hledání výsledku. Správná volba hešovací funkce proto nemusí být úplně jednoduchá a často závisí na konkrétním typu řešeného problému.
Pokud používáte elektronickou poštu, mohli jste se s anglickým pojmem spam setkat jako s označením pro nevyžádanou, hromadně šířenou zprávu, která obvykle plní úlohu reklamy. Ve slovnících pod heslem spam naleznete vysvětlení, že se jedná o masovou konzervu, jejíž obsah se obvykle jí studený. Nevím jak vy, ale dokud jsem se nedostal k překládání tohoto kurzu, nedovedl jsem si pod pojmem Spam představit žádnou potravinu. Po chvíli pátrání se ukázalo, že je to pravděpodobně způsobeno mým věkem v kombinaci s existencí bývalého režimu a s mou malou zcestovalostí.
Pravděpodobně nejzapamatovatelnější adresou serveru, na které se o jídle jménem Spam můžete dozvědět podrobnosti je www.spam.com. Zjistíte, že jde o registrovanou značku potravinového produktu, jehož plné jméno zní Spam® luncheon meat. (Aha!) Zjistíte také, že se pod tímto jménem vyrábí už velmi dlouho, že tyto konzervy významně zasáhly i do průběhu Druhé světové války, že nedávno bylo dokonce otevřeno tomuto jídlu věnované muzeum a že existuje něco jako celosvětový fan klub, který je svou bizarností srovnatelný nejspíš s fan klubem automobilu Trabant.
Obchodní název se zjevně povedl v tom smyslu, že je velmi stručný a díky historickému úspěchu je každý pokus o jiný popis tohoto jídla příliš zdlouhavý. I z těchto důvodů jsem se rozhodl název jídla, které je v příkladu použito jako identifikátor třídy objektu, nepřekládat. Protože se tento příklad navíc používá i na dalších místech kurzu, rozhodl jsem se ponechat anglické názvy modulu (meat = maso), třídy (spam = tedy luncheon meat) i operace (slice = krájet, ukrojit, řez ve smyslu uřezaného plátku). Protože nejsem příznivcem kombinování anglických a českých slov do jednoho identifikátoru (například názvu proměnné), rozhodl jsem se ponechat kód příkladu v původním tvaru a upravit pouze komentáře.
Znakové řetězce se řadí spíše mezi složené datové typy. Mezi jednoduché datové typy řadí spíše typ znak. Podpůrným argumentem pro tento pohled je skutečnost, že u jednoduchých datových typů předpokládáme možnost uložení v paměťovém prostoru o předem vyhrazené velikosti. S tím souvisí i to, že základní operace nad jednoduchými datovými typy můžeme provést v čase omezeném shora nějakou konstantní hodnotou. Teorie v této souvislosti hovoří o konstantní časové složitosti odpovídajícího algoritmu operace — označuje se O(1). U řetězců, které nemají omezenu maximální délku řetězce, nelze podobným způsobem uvažovat. Tak například doba trvání operace kopírování řetězce bude závislá na aktuální délce řetězce. Časová složitost takové operace je označována jako lineární a označuje se O(n).
Slovo IDLE je akronym odvozený z anglického Integrated DeveLopment Environment — česky integrované vývojové prostředí. Tento pojem se používá velmi často, v souvislosti s různými programovacími jazyky a jejich vývojovým prostředím. Obecně jde o aplikační program, který v sobě zahrnuje textový editor pro psaní zdrojových textů, vazbu na překladač jazyka, ladicí systém (debugger), případně další podpůrné nástroje (například nástroje pro zobrazení hierarchie tříd a jeho využití pro rychlý přechod na příslušná místa ve zdrojových textech, nástroje pro tvorbu dokumentace a podobně). V ostatních případech se obvykle označuje zkratkou IDE. Kde se tedy vzalo to L?
Autor jazyka, Guido van Rossum, dává neustále a veřejně najevo, že jazyk Python nebyl pojmenován podle nějakého "odporného plaza", ale podle britské komediální skupiny Monty Python's Flying Circus (tj. Monty Pythonův létající cirkus — epizody byly k vidění i u nás). Humorně kultovní vztah k jejich produkci vede k preferenci názvů, pro které lze v jejich komediích najít nějakou oporu. Pokud jsou mé informace správné, pak Idle je také příjmení (možná umělecké, nevím) jednoho z komiků.
Jenže idle je také běžné anglické slovo, které lze přeložit jako zahálející, nečinný, planý, nepotřebný… V tomto smyslu lze nadpis podkapitoly přeložit jako: Radost z nicnedělání nebo Je to fajn se jen tak poflakovat.
Ale je tu i další souvislost! Výslovnost tohoto slova je aidl. Stejnou výslovnost má i jiné anglické slovo — idol (něco hodné zbožňování). Pokud budeme trochu anglicky huhňat, pak by se dalo uvažovat i o slovu idyl (čti aidil), znamenající idylku, selanku.
Toto je tedy vysvětlení, proč jsem nechal nadpis nepřeložený (jako — podle mého názoru — velmi cenný příspěvek Alana Gaulda v duchu kultu Monty Python's Flying Circus). Vyberte si vysvětlení, které se vám líbí nejvíc. Případně zvažte, zda neplatí všechna dohromady. Případně žádné z nich. Nebo je to snad zcela jinak?
V této kapitole nejsou uvedeny žádné poznámky formou odkazu.
Pokud to myslíte s programováním vážně a chcete se pustit do projektu, který bude mít víc než jen pár řádků zdrojového textu, poohlédněte se po některém ze systémů pro správu verzí — myslí se tím obvykle verze jednotlivých zdrojových textů. Odpadnou vám tím starosti třeba právě s údržbou údajů, které se uvádějí ve zmíněném komentáři v hlavičce souboru. Systém pro správu verzí zajistí automatickou aktualizaci těchto údajů. To ale není vše. Tyto systémy udržují databázi změn a umožní vám vrátit se k verzi označené značkou nebo určené datem a časem. Umožní vám zjistit, jaké změny byly ve zdrojovém souboru provedeny mezi libovolně zvolenými časovými okamžiky nebo označkovanými verzemi.
Možná si teď říkáte, že to není nic pro vás. Ale ujišťuji vás, že kdo se jednou naučil takový systém používat, již nemá chuť dělat něco bez něj. Samozřejmě to od vás bude vyžadovat trochu úsilí navíc — jako každá nová věc. Ale zvládnutí takového systému není složité a výhody bohatě vyváží počáteční duševní úsilí. A možná si říkáte, že zase tak moc programovat nebudete, že se vás to asi netýká. Ale pozor! Tyto systémy se ideálně hodí pro správu libovolných souborů, které mají textovou podobu a vyvíjejí se v čase (některé výhody již nejsou tak zřetelné při správě binárních souborů). Možná něco intenzívně píšete — knihu, HTML stránky, dokumentaci v textovém formátu a podobně. Pak právě pro vás bude použití systému pro správu verzí velkým přínosem — i když nemusíte mít s programováním mnoho společného.
Momentálně je mezi volně dostupnými a oblíbenými systémy pro správu verzí nekorunovaným králem systém známý pod zkratkou CVS — Concurent Versions System. Vychází z historicky staršího systému RCS (Revision Control System) a doplňuje k němu mechanismy, které umožňují současnou (concurent) práci více programátorů najednou. Bezproblémový provoz je zaručen na systémech typu Unix, ale pokud hodláte CVS používat pouze na lokálním počítači, pak vám i pod Windows vyhoví CVSNT, případně i některou nadstavbu v podobě grafického uživatelského rozhraní, jako je WinCvs nebo TortoiseCVS. Systém CVSNT sice původně vznikl jako CVS pro Windows, ale evolučně se vyvinul do podoby dokonalejší, než originál. V současnosti již jej můžete provozovat i pod systémem Linux.
K základním operacím se systémem CVS patří vytvoření databáze souborů (takzvané repository) přidání adresáře nebo souboru do evidence (add), zaznamenání změn k současnému stavu (commit), získání souborů v aktuální podobě nebo v podobě určené značkou nebo datem (checkout), aktualizace souborů podle nejnovějšího stavu v evidenci (update), zjištění rozdílů pro aktuální verzi nebo mezi určenými verzemi (diff), a další. Systém CVS ze systému RCS mimo jiné přebírá takzvané RCS identifikátory, které do zdrojového textu zapisujeme ve tvaru $identifikátor$
. V okamžiku, kdy systému určíme, že má zaznamenat nové úpravy do databáze, rozgeneruje příslušné identifikátory do tvaru, který kromě identifikátoru samotného obsahuje i jeho hodnotu. Identifikátor můžeme zapsat jak do komentáře, tak i na libovolné místo v textu (například do řetězce, který přiřadíme nějaké řetězcové proměnné). Následující příklad ukazuje nejpoužívanější RCS identifikátory v akci. Původní zápis identifikátorů již byl rozgenerován, takže za identifikátorem následuje dvojtečka a poté obsah až po $
:
#############################
# $Source: e:/cvsrootPython/LearningToProgram/cz/czech2/cztuttrn.html,v $
# $Author: prikryl $
# $Date: 2004/07/02 08:12:10 $
# $Revision: 1.4 $
#
# Často se používá i identifikátor Id
, který
# rozgeneruje hned na několik údajů najednou.
#
# $Id: cztuttrn.html,v 1.4 2004/07/02 08:12:10 prikryl Exp $
#
# Pokud při zaznamenávání změn doplňujeme smysl dávající poznámky
# o tom, co se skutečně měnilo, můžeme přímo využít i identifikátor
# Log
, který ke specifické kombinaci údajů přidává i znění
# poznámky k poslední revizi. Jak je patrné z níže uvedeného
# obsahu, nejnovější údaje se připisují hned pod zápis identifikátoru
# Log
a vygenerované poznámky se stávají součástí normálního textu.
# Postupně se tak hromadí seznam poznámek, z nichž nejnovější je uvedena
# nahoře. Z níže uvedeného seznamu je patrné, že proměnná Log
byla
# ve zdrojovém souboru poprvé rozgenerována v okamžiku revize 1.21
# (tedy v okamžiku 21. zachycené úpravy — checkin). Aby se
# ukázka záznamů neprodlužovala s každou další úpravou tohoto souboru, byl
# znak $
později v tomto HTML souboru nahrazen sekvencí, která
# se zobrazuje jako $
, ale cvs již RCS identifikátor Log
# v tomto místě nenajde:
#
# $Log: cztuttrn.html,v $
# Revision 1.24 2002/08/24 14:43:22 Petr
# - Další poznámky. Upraveny CSS styly.
#
# Revision 1.23 2002/08/24 14:31:27 Petr
# - Doplněna patička souboru.
#
# Revision 1.22 2002/08/24 14:20:14 Petr
# - Připsán další kousek -- demonstrujeme budování seznamu
# na základě RCS identifikátoru Log
.
#
# Revision 1.21 2002/08/24 14:09:12 Petr
# - Dokončena poznámka k CVS.
#
################################
Ve výše uvedeném příkladu jsem sice použil komentářovou značku # pro Python, ale rozgenerované identifikátory ve skutečnosti patří k HTML souboru, jehož naformátovanou podobu právě čtete. Systému CVS je jedno, kde RCS identifikátor nalezne — prostě jej rozgeneruje. Takže už víte, odkud se vzaly ty podivné údaje na konci každé HTML stránky českého překladu kurzu?
U jednoduše zapsaných řetězců v jazyce Python mohou být použity i znaky s jedničkovým osmým bitem, tedy i znaky naší abecedy s diakritickými znaménky. Pokud interpret jazyka Python přečte takto zapsaný řetězec ze souboru, nic se znaky nedělá. Jednoduše je načte jako 8bitové hodnoty (bajty). Pokud chceme takový řetězec vytisknout příkazem print
, Python tyto 8bitové znaky pošle na výstup. Pracujete-li v systému typu Unix (pravděpodobně Linux), nemělo by to činit žádný problém. V celém systému se používá jediné kódování iso-8859-2
.
V systému MS Windows to ovšem s českým kódováním není tak jasné. Pro češtinu v DOSovém okně se standardně používá znaková sada 852
, zatímco pro čestinu v jiných oknech se používá kódování windows-1250
. Z toho vyplývají problémy spojené s psaním konzolových aplikací, mají zobrazovat korektní výstup v DOSovém okně a pro jiné windowsovské aplikace mají například generovat texty do souborů v kódování 1250
. A jak je to s texty v přímo zobrazovanými v neDOSových oknech?
U objektů uživatelského rozhraní z modulu Tkinter lze 8bitové řetězce sice použít přímo, ale předpokládá se, že se používá kódování znaků pro západní abecedy (tedy iso-8859-1
, známé také jako Latin 1
). Některé české znaky se sice zobrazí správně (jako například á
nebo í
), ale řada z nich se zobrazí chybně.
Python naštěstí podporuje i takzvané kódování Unicode, které umožňuje vyjádřit existenci znaků většiny používaných jazyků. Platíme za to větším prostorem, který je pro uložení znaku vyhrazen. Modul Tkinter umí s takto kódovanými řetězci pracovat. Pro české texty tedy nebudeme v tomto případě využívat jednoduše zapsané řetězce, ale převedeme je do jednoznačného kódování Unicode. Python pro tento převod poskytuje zabudovanou funkci unicode()
. Jako první parametr jí dáváme prostý řetězec v uvozovkách, na který se Python bude dívat jako na posloupnost bajtů. Současně ovšem musíme druhým parametrem říci, v jakém kódování jsme bajty uvedli. Na základě těchto údajů Python převede řetězec v zadaném 8bitovém kódování do kódování Unicode (16bitové). Tohoto obratu se užívá v příkladech kapitoly o grafickém uživatelském rozhraní.
Řetězcové objekty v kódování Unicode poskytují inverzní metodu encode()
, kterou můžeme řetězec převést z kódování Unicode do některého z podporovaných 8bitových kódů. Toho lze v Microsoft Windows využít pro převod českých řetězců, které jsou v programu zachyceny v kódování 1250
(psali jsme je například editorem Notepad, čili Poznámkový blok), na kódování 852
. Výsledek se pak při posílání výstupu do DOSového okna zobrazí správně.
[problém se vstupem >127 v editoru IDLE]
[Univezální řešení? (Jak rozpoznat, v jakém okně vypisujeme?)]
Pro ty, kdo mají rádi stručnost… Osobně si myslím, že to neodpovídá skutečnosti.
Pravděpodobně je to věc programátorského stylu. Řada jazyků — a patří k nim i Python — provádí v místech, kde se očekává boolovská hodnota, automatickou konverzi. Takže například prázdný pythonovský řetězec se například při použití v podmínce cyklu chápe jako hodnota false a neprázdný jako true. Podobně prázdný seznam se v boolovském kontextu chápe jako false a neprázdný jako true. Vhodné využívání těchto vlastností může zvýšit čitelnos a přehlednost zdrojového kódu. Ale osobně považuji za vhodnější, když se pro uložení logického příznaku používá raději boolovská proměnná, než celočíselná proměnná s hodnotami nula a jedna.
V době vzniku této učebnice neměl Alan Gauld navybranou. Typ bool
byl do jazyka Python zaveden až ve vyšší verzi, spolu s hodnotami True
a False
.
V novějších verzích jazyka Python byl zaveden typ bool
s konstantami True
a False
. Protože Python patří mezi jazyky, ve kterých záleží na velikosti písmen, musíme tyto konstanty psát s velkým počátečním písmenem.
Naproti tomu true (pravda) a false (nepravda) představují (anglické) matematické pojmy pro vyjádření pravdivostní hodnoty. V tomto abstraktním smyslu není důležité, zda v nich píšeme malá nebo velká počáteční písmena.
Pokud tedy někde uvidíte zápis True
nebo False
, pak je tím vyjádřena skutečnost, že se hovoří o konkrétních konstantách jazyka Python. Pokud někde budeme hovořit velmi obecně nebo pokud budeme chtít konkrétní případ odlišit od případu existence konstant jazyka Python, pak budeme zapisovat true a false. Chápejte to ovšem jako drobný detail. Na druhou stranu, konstantu True
nikdy neuvidíte použitou ve významu false a konstantu False
nebudeme používat ve významu true.
#include
v C a C++:Autor zjevně naráží na příkaz #include
, který byl do jazyka C++ převzat z jeho předchůdce, jazyka C. Tento příkaz skutečně zajišťuje, že se (při překladu) obsahem určeného textového souboru nahradí právě příslušný příkaz include. Jde o příkaz preprocesoru, který se o podobné textové náhrady stará. Ale tvrzení, že jím do zdrojového textu programu načítáme moduly, je problematické. Typicky se jím načítají takzvané hlavičkové soubory, které popisují například prototypy funkcí.
Prototypem funkce se myslí ta část definice funkce, která určuje jméno funkce, počet a typy parametrů, typ návratové funkční hodnoty a některé další detaily. Prototyp funkce neobsahuje tělo funkce. Překladač informací z prototypu funkce využívá pro kontrolu toho, zda v našem kódu voláme dostupnou funkci, zda ji předáváme správné parametry a podobně. Na základě toho vygeneruje podsloupnost instrukcí, které volání funkce zajistí a které zajistí převzetí vracené funkční hodnoty — to vše bez znalosti těla funkce. Těla takto volaných funkcí jsou typicky umístěna buď v cílových souborech (.obj
), nebo v knihovních souborech (.lib
).
Pojem modul není v jazycích C a C++ ostře vymezen. Pokud přijmeme autorův postoj, že funkce je jakýmsi druhem modulu, pak bychom příkaz #import
mohli v C/C++ považovat za způsob zpřístupnění modulu. Modulem se však obvykle chápe něco na jiné úrovni abstrakce, než je prostá funkce. Pro modul bývá typické to, že existuje veřejné rozhraní k implementované funkčnosti a může existovat i kód modulu, který není veřejně přístupný. Modul také zapouzdřuje datové struktury, které se používají jen pro vnitřní účely modulu.
Zatímco existenci funkcí, procedur a datových struktur spojujeme s pojmem strukturované programování, moduly a s nimi spojené modulární programování jde o krůček dál. Proti strukturovanému programování se navíc zabývá ukrýváním dat a veřejně nepřístupných funkcí na jedné straně a zpřístupněním veřejného rozhraní na straně druhé. O další krok dál jde objektově orientované programování, ve kterém se na požádání jakoby vytváří více kopií toho, co bylo u modulárního programování představováno modulem, jehož vnitřní datové struktury mohly být během používání naplněny konkrétními daty.
Doufám, že se svým soukromým odhadem přiblížím ke skutečnému původu slova log-soubor (anglicky log file). Pokud znáte správnější nebo přesnější vysvětlení, rád je zde uvedu.
Slovo log se v lodní terminologii používá pro lodní deník, do kterého se zapisují důležité údaje o plavbě. Je to pravděpodobně nejdůležitější doklad o provozu lodi na dané plavbě a považuje se za nedotknutelný v tom smyslu, že se nemění předchozí zápisy. Vždy se do něj pouze připisuje na konec. Odtud pravděpodobně pochází počítačová analogie v podobě takzvaných log-souborů, do kterých se zapisují například význačné události, které se v systému udály. Log-soubory ale obvykle bývají specializované — v systému bývá více než jeden. Samostatné soubory s takovým charakterem si často vytvářejí i různé aplikace. Jejich společným rysem je kromě připisování záznamů na konec i to, že nejsou určeny k ukládání nějakých mezivýsledků nebo údajů, které by se dále programem zpracovávaly. Slouží spíše správci aplikace nebo systému k tomu, aby mohl v případě potřeby dohledat historii určitých událostí a odhalit například, kde se v systému stala chyba a co k ní mohlo vést — tak jako například pojišťovací společnost zkoumá obsah lodního deníku havarované lodi, tak jako tým inspektorů zkoumá obsah černé skříňky havarovaného letadla.
Tolik tedy k účelu. A kde se vzal samotný název log? Jedním z velmi důležitých údajů, které se při navigaci lodi používají je její rychlost. A k jejímu měření se dříve používalo zařízení, které mělo podobu dřevěné desky zavěšené na lanku tak, aby po vhození do vody brzdila pohyb konce lanka vůči okolní vodě (jako padák ve vzduchu). Námořník pak po měřenou dobu (např. přesýpacími hodinami) nechával šňůru proklouzávat rukou a počítal uzly, které na šňůře byly navázány v odměřených vzdálenostech. Proto se rychlost lodi uvádí v uzlech.
Ale proč se tomuto zařízení říká log?! V angličtině se slovem log označuje také poleno, kus dřeva. Primitivní log pro měření rychlosti lodi asi byl jen kusem dřeva na šňůře. Plochá deska, zavěšená napříč směru pohybu, je ale výhodnější v tom, že lépe brzdí. Aby se na konci měření nemusela namáhavě přitahovat, jednoduše se sklopí do směru pohybu. Jak se to dá udělat? Pokud to nevíte, zkuste to vymyslet! Hledání řešení logických a technických problémů je dobrou průpravou k programování ;-)
Anglické slovo stream se překládá jako proud (ve smyslu "hlavní proud", "hlavní směr" a podobně, ale nikoliv "elektrický proud"). Tímto slovem se také pojmenovává potok či stružka. To už jsme se sice od jeho abstraktní podoby a od počítačů trochu vzdálili, ale může nám to pomoci pochopit, co má v počítačové terminologii vyjadřovat. V souvislosti s programováním se stream často nepřekládá, protože tento pojem popisuje specifickou abstrakci, kterou bychom mohli přeložit jako proud dat nebo datový kanál — podle situace. Oba pojmy spolu souvisejí.
Proud dat vyjadřuje skutečnost, že data neustále protékají — jedním směrem. Program může předepisovat získávání a zpracování jednoho datového prvku za druhým (nebo naopak generování nového datového prvku), ale nemůže zpracovat libovolný prvek, aniž by zpracoval prvky jemu předcházející. K jednou zpracovanému prvku se již nemůžeme vrátit — pokud si ho ovšem někde neuložíme. Pojem datový kanál vyjadřuje spíše existenci přenosového média, kterým zmíněná data proudí. Z tohoto pohledu pojem proud dat vyjadřuje spíše abstraktní podstatu jevu, zatímco datový kanál vyjadřuje spíše technickou realizaci cesty, kterou data proudí. V souvislosti s pojmem stream, jak jej používá BASIC v souvislosti se soubory, můžeme použít spíše překlad datový kanál.
Význam pojmu stream spočívá ve vyjádření jevu předem neomezeného množství dat. Neříká nic o tom, kdy data začala proudit a kdy proud dat skončí. Vyjadřuje však to, že jeden datový prvek následuje za druhým. To je velmi důležité, protože algoritmy, které z tohoto pojmu vycházejí, v sobě mají něco typického, obecného. V jazyce BASIC a v jiných jazycích a systémech se k souborům z abstraktního pohledu přistupuje jako k proudu dat, ale je to vlastně jen speciální případ. Soubor se tímto způsobem chová jen od okamžiku svého otevření, do okamžiku svého uzavření. Mimo tento interval pojem stream ztrácí ve vazbě na soubory svůj smysl.
Jste-li začátečníci a není vám to pořád naprosto jasné, nestyďte se za to. V programování, které je založené na přesném logickém uvažování, je využívání nejasných pojmů a nástrojů, které tak docela nechápeme, spolehlivou cestou k budoucím problémům. Pokud své neznalosti či pochybnosti dovedně ukryjete před svým učitelem, možná se vyhnete špatné známce. Pokud ani sami sobě nepřiznáte, že něčemu přesně nerozumíte (Stream? To je přece jasné, ne?), vyhnete se tím pochopení celé řady souvisejících problémů. Jak tedy z abstraktního pojmu stream udělat něco lépe pochopitelného i pro začátečníka?
Každý počítačový začátečník — dokonce i takový, který nechce mít s programováním nic společného — se setkává se zařízením tak dobře zvládnutelným, že už o něm prakticky vůbec neuvažuje. Máte je před sebou. Je to klávesnice počítače — dokonalý příklad pojmu stream v praxi.
Představme si, že klávesnice vyšle při stisku libovolné klávesy do počítače jeden symbol. Pro zjednodušení můžeme uvažovat, že klávesnice obsahuje pouze klávesy se zobrazitelnými znaky (vynecháme Shift, Ctrl, Enter, F1, a další podobné). Odpovězte si teď na tyto jednoduché otázky:
Klávesnice tedy reprezentuje zdroj dat — stream, ze kterého data proudí. Elektronická podoba symbolu zde vzniká. Podobně bychom o tiskárně mohli uvažovat jako o konzumentovi dat — zde údaje mění svou formu z elektronické na tištěnou. Elektronická podoba symbolu v tiskárně ukončí svou existenci.
Pokud si stejné otázky položíte v souvislosti se souborem, pak snadno pochopíte, v čem se pojmy soubor a stream liší. Zkuste si teď odpovědět na otázky:
readline()
napasovat na práci se stream?readlines()
, která má zajistit získání všech řádků?K této kapitole nejsou žádné poznámky formou odkazu. Zde uvedený příklad v dřívější verzi tohoto dokumentu byl autorem zohledněn v originálu.
S pojmem widget [čti vidžet] (případně i gadget [čti gedžit]) se hojně setkáte zejména v souvislosti s programováním grafického uživatelského roshraní, a to předeším u systému typu Unix a jeho součásti zvané X Window. Pojem widget se zde užívá pro abstraktní označení obvykle viditelných prvků uživatelského rozhraní, jako jsou různá tlačítka, přepínací prvky a podobně.
Zdá se, že původ slova widget je poněkud neformální. Dvojité w na začátku má možná připomínat, že s těmito prvky uživatelského rozhraní bývá spojeno okno (anglicky window). Ve výkladových slovnících můžete najít vysvětlení, že jde o obdobu pojmu gadget (a dalších synonym) a to zejména v případě, kdy má pojem vyjadřovat abstraktní podobu. Pojem gadget se přitom vysvětluje jako neformální označení nějakého mechanického zařízení, zařízeníčka, udělátka, čumexu a podobně, mající spíše nádech kutilství, než něčeho seriózního. Pokud to tedy spojíme s abstrakním charakterem a s použitím pro prvky uživatelského rozhraní, mohli bychom pojem widget překládat třeba jako čudlík ;-)
Poznámka: Čumex je obvykle nějaká zajímavá součástka z nějakého kuriózního zařízení, kterou si vystavíte na odiv na pracovním stole nebo někam na zřetelné místo ve vaší pracovně. Pokud možno se nějak hýbe nebo se s ní dá dělat něco zajímavého, ale přitom nepochopitelného. Pokud obsahuje leštěné mosazné části a vypadá, že jste si ji přinesli z ponorky kapitána Nema, tím lépe. Může to být také něco naprosto uměle zkonstruovaného pro tento účel. (Matně si pamatuji, že jsem tento pojem poprvé slyšel v souvislosti s historkou o jednom pracovišti, kde měli v kusu leštěného dřeva umným způsobem zabudován kus kolejnice, nebo něco takového.) Je žádoucí, aby toto zařízení bylo perfektně řemeslně zpracované. Mělo by vzbuzovat dojem, že k něčemu užitečnému skutečně slouží. Návštěva vaší pracovny se marně snaží přijít na jeho smysl. Obvykle to nevydrží a zeptá se: K čemu je to vlastně dobré?. A v tom okamžiku čumex splnil svůj jediný účel ;-)
Pojmy třída a instance bývají při nedostatečném vysvětlení pro začátečníky v oblasti objektového programování trochu záhadné a obtížně pochopitelné. O něco lépe jsou na tom ti, kteří se setkali s vyšší matematikou, která s pojmem třídy běžně pracuje. Jakmile ale jednou pochopíte, o co jde (ahááá), pak už se vám to zdá natolik jasné, že vám přestane být jasné, jak to někdo nemůže chápat — v tom asi bude zakopaný pes (pro lingvisty zděs sabáka zarýta). Ti kdo to vysvětlují, už to chápou, takže někdy nechápou… ;-)
Třeba vám k pochopení pomůže příklad, se kterým jste se setkali už v předškolním věku. Zlomyslná macecha jela se svou dcerou na královský ples a Popelce smíchala hrách a popel dohromady. Popelka je měla tuto směs zase oddělit od sebe. Z matematického a fyzikálního pohledu tedy Popelka oddělovala pevné částice popela od pevných částic hrachu. Rozhodovala se na základě jejich typických charakteristik — například barvy a jiných zjevných vlastností, které jaksi určují, co je popel a co je hrách. Z matematického hlediska její znalost rozdílů mezi hrachem a popelem indukovala rozklad množiny objektů na třídy. Z kupeckého hlediska třídila hrách a popel. Rozhodovala se právě podle obecných vlastností, které definují třídu popela a třídu hrachu. Nemusíte mít dokonce ani jedno zrnko hrachu, a přitom můžete chápat, co to je hrách. Právě souhrn určitých vlastností a způsob chování hrachu (třeba, že se kutálí) určuje jeho třídu. Třída je tedy definována jako souhrn těchto vlastností a má abstraktní charakter. Právě proto můžete definovat třídu hrachu aniž byste měli jediné zrnko hrachu.
Třída objektů je tedy popisem charakteristických vlastností objektů, které dosud nemusí ani existovat. Hovoříme-li o objektu, pak máme naopak na mysli něco existujícího, co má určité vlastnosti. A může toho existovat více výskytů — instancí třídy. Tyto výskyty, neboli instance nebo také objekty třídy nebo jednoduše objekty mohou být vnitřně naprosto totožné (lišící se pouze tím, že každý má svou vlastní existenci) nebo se mohou lišit v rámci dovolených variací. Pokud se na Popelčiny objekty obecně (tj. pevné částice) budeme dívat s přimhouřenýma očima, budou se nám objekty třídy hrachu (jinými slovy také instance třídy hrachu) zdát všechny stejné, ale můžeme je například spočítat. Když oči otevřeme pořádně, vidíme, že je každý hrášek trochu jiný — může se trochu lišit barva, velikost, kulatost a podobně. Dokud ale odpovídají popisu (třídě) hrachu, pak jsou to pořád instance hrachu.
Třída má tedy určitý statický charakter. Teoreticky by mohla existovat od nepaměti libovolně dlouho do budoucnosti. Můžeme ji chápat jako popis. Naproti tomu objekt (instance třídy) má dynamický charakter. Někdy musel vzniknout, nějakou dobu existuje a někdy zanikne.
V programátorském smyslu nemůže existovat objekt bez existence odpovídající třídy. Nejdříve musí existovat třída a potom můžeme vytvořit její instanci.
Z hlediska přírodních věd je to naopak. Nejprve existovaly objekty hrachu a teprve mnohem později se objevil někdo, kdo je začal třídit (viz holoubci: jedlé/nejedlé). A mnohem později se našel někdo, kdo vlastnosti hrachu popsal slovy a později i písmem.
Pojem hrách existuje mnohem déle, než kolik vydrží jedno zrnko hrachu. Má abstraktní charakter. Nedá se nahmatat. Pojem odpovídá třídě. Pojmu hrách se prostě nenajíte, protože uspokojení z jídla souvisí se zánikem objektů hrachu — tedy pokud máte hrách rádi.
Pojem instance se tedy velmi podobá pojmu objekt. Rozdíl je velmi jemný. U instance vyzvedáváme spíše stránku výskytu, zatímco pojmem objekt zdůrazňujeme stránku hmatatelnosti existence. Jsou to spíše jazykové a filosofické otázky. Pokud vám to věc s objekty nepomáhá vyjasnit, nelámejte si s tím hlavu.
Holoubci-pomocníčci nejspíš v praxi třídili podle kritéria jedlé/nejedlé. Nenalhávejme si, že by hrášek skládali do ošatky. Nejspíš Popelce pomohli tím, že pak hrách mezi popelem nebyl vidět, takže to vypadalo, že došlo k jejich roztřídění. Instance třídy hrachu se pak od instancí třídy popela lišily i svým umístěním — v holubích žaludcích.
Poznámky pro hloubavé, otrlé, nebo zvědavé čtenáře: K objektům a třídám můžeme zaujmout i jiný postoj. Dejme tomu, že vás napadne otázka: A jak vlastně ten hrách dosáhl své hrachovitosti? Není jeho třída definována tvarem jeho DNA?. (Tady bychom od hrachu mohli pro zjednodušení přejít k nějakým jednobuněčným organismům.) Nový objekt musí mít svou DNA. Aby tedy mohl vzniknout nový objekt, musí se DNA rozdělit! Někdy se v souvislosti s objektově orientovaným programováním (v některých programovacích jazycích) třída objektů definuje takzvaným prototypem. Je to vlastně jedna instance, ze které se vytvářejí nové instance okopírováním. To by nejspíše odpovídalo případu množení jednobuněčného organismu.
Existuje ještě jeden výrazný způsob vytvoření třídy objektů, kdy je třída definována opět jako objekt, ale na jiné logické úrovni — jako meta objekt (…, který může mít svou meta třídu… Ale z praktického hlediska bychom neměli zacházet příliš daleko. Mohlo by to skončit Nobelovou cenou nebo pobytem na psychiatrickém oddělení). A existuje vůbec odpovídající meta objekt pro náš objekt hrášku? Ví Bůh, případně matka Příroda — vyberte si. ;-)
A teď si podkapitolu Definice tříd přečtěte znovu. Pochopení pojmů třída a instance (nebo objekt) a rozdílů mezi nimi je pro studium dalšího textu důležité.
Vysvětlení pojmu pixel je poměrně jednoznačné. Jedná se o zkratkové slovo, které vzniklo z anglického picture element, tedy obrazový element. V technické praxi se obraz rozkládá do pravoúhlé mřížky, takže obrazový element má tvar čtverečku nebo obdélníčku. Udáváním souřadnic v pixelech se rozumí určení polohy obrazového elementu jako pořadí ve směru osy x a osy y.
Souřadnice v pixelech (nebo rozměry obrázku v pixelech) samy o sobě neurčují fyzické rozměry. Navíc musíme použít údaj, který určuje počet bodů na rozměrovou jednotku. Typicky se setkáváme se zkratkou DPI, což je akronym anglického Dots per Inch — bodů na palec (jeden palec odpovídá 25,4 mm). Při práci s monitorem se typicky setkáváme s údajem 96 DPI. Starší laserové tiskárny měly rozlišení 300 DPI. Běžné levné laserové tiskárny mají nyní rozlišení 600 DPI. Standardem se stávají tiskárny s rozlišením 1200 DPI. Výjimečné už nejsou tiskárny s rozlišením 2400 DPI. S podobnými údaji se setkáte u skenerů z papírové předlohy (scanner).
Poznámka: Pokud se pracuje s trojrozměrným rastrovým rozkladem třírozměrného prostoru, pak se můžete setkat s pojmem voxel, což je zkratkové slovo vytvořené obdobným způsobem ze spojení slov volume element, tedy objemový element.
Slovo refactoring se v programování používá jako specifický pojem pro činnost, kdy revidujeme a přepracováváme kód s tím, že chceme dosáhnout jeho vyšší kvality a použitelnosti. Objevuje se zejména v souvislosti s objektově orientovaným programováním, kdy se například snažíme v rámci používaných tříd najít lepší umístění kódu, který realizuje určitou funkčnost. Mohli bychom říci, že přehodnocujeme pohled na to, jaká třída (jaký objekt) je odpovědná za určitou činnost a zvažujeme možnosti zefektivnění komunikace mezi objekty.
Samotná refaktorizace obvykle nemění funkčnost kódu. Můžeme říci, že pouze využíváme dosavadní zkušenost, kterou jsme při psaní tohoto kódu získali, upřesňujeme svůj pohled na řešený problém a snažíme se řešení upravit tak, aby se zvýšila jeho průhlednost a jasnost. Snažíme se lepším způsobem dosáhnout stejné funkčnosti. Při tom si často ujasňujeme přesnou roli zúčastněných tříd a to i s ohledem na další vývoj. Pokud se nám podaří vše vyjádřit jednodušším a jasnějším způsobem, bude i další vývoj jednodušší a snadnější.
Při refaktorizaci tak může dojít například k rozdělení jedné třídy na víc tříd, nebo naopak k slučování tříd. U některých tříd může být vypozorován společný základ a může vzniknout společná bázová třída, ze které jsou nové verze původních tříd odvozeny, a podobně.
Refaktorizace patří ke klíčovým postupům jedné z nových metodik vývoje softwarových systémů, která je známa jako eXtreme Programming (dále XP). A protože každá změna — jakkoliv dobře míněná — může do programu vnést chyby, patří ke klíčovým postupům v XP i psaní testů známých jako unit tests (izolované testy funkčnosti pokud možno všech částí kódu) a acceptance tests (tedy testy přijatelnosti, které testují požadovanou funkčnost z pohledu uživatele). Testy se píší před implementací vlastního kódu, během ní i dodatečně. Pokud kód projde testy i po refaktorizaci, pak při ní s vysokou pravděpodobností nebyly do kódu zavlečeny nechtěné chyby. I v testech může být skrytá chyba, ale styl jejich psaní se obvykle liší od psaní kódu, který testují. V tom je skrytá jistá záruka, že chyby v testech budou odhaleny dobře implementovaným kódem a chybně implementovaný kód bude naopak odhalen testy. Pokud je přesto zjištěna chyba v aplikaci, postupuje se tak, že se nejdříve doplní test, který tuto chybu odhaluje. Na základě tohoto testu pak můžeme poznat, zda se nám chybu v implementaci podařilo opravit. Důležité je, že pro budoucí refaktorizace takto postupně budujeme záchrannou síť testů, která je stále spolehlivější. Důvěryhodnost kódu roste a současně odpadají obavy o to, že zásahy do fungujícího kódu způsobí jeho nefunkčnost.
Python ve své standardní distribuci obsahuje modul unittest
, který poskytuje prostředky pro psaní testů a implementuje mechanismus jejich automatizovaného spouštění a vyhodnocování.
Podle mého názoru už samotná existence tohoto pojmu — pokud přijmete názor, že dává smysl — potvrzuje, že Python tvoří jakýsi spojovací článek mezi skriptovacími jazyky a robustnějšími, kompilovanými programovacími jazyky.
Obvykle se setkáváme pouze s pojmy skriptovací jazyk nebo skriptování, jako výraz pro používání tohoto jazyka pro zápis skriptů. Skriptem se myslí spíše jednoduchý program, který se používá často jednoúčelově, v podobě konzolové aplikace. Typickou vlastností skriptu je to, že se spouští z příkazové řádky a nepoužívá grafické uživatelské rozhraní. K provedení úkolu často využívá konzolové příkazy operačního systému a jiné jednoúčelové programy, které mají užší vazbu na operační systém (zejména v systémech s unixovým jádrem) a kterým se často říká utility [čti jutility]. Původním smyslem skriptovacího jazyka je právě rychlé a snadné kombinování existujících utilit a to i za cenu méně efektivního běhu kódu, který jejich funkčnost spojuje. Uvedené vlastnosti vedou k tomu, že skriptovací jazyky prakticky vždy interpretují textový zápis programu.
Pojem programování ve velkém se naopak téměř výlučně používá ve spojení s kompilovanými jazyky. Pokud o nějakém jazyce řekneme, že je vhodný pro programování ve velkém, pak to znamená, že jazyk samotný nezavádí s nárůstem velikosti řešeného problému neočekávané komplikace. Dá se říci, že při jeho vhodném používání není velikost řešeného problému z hlediska jeho programování omezována. Příkladem takového jazyka je C++. Jazyky tohoto typu musí například podporovat dobrou práci s knihovnami, které připravil někdo jiný, případně — z opačného pohledu — dobré možnosti pro tvorbu takových knihoven. To mimo jiné znamená, že jazyk například musí být schopen oddělit prostory jmen, používané v rámci těchto knihoven, od prostorů jmen, které chceme využívat v naší aplikaci. Jinými slovy, musí podporovat mechanismy, které nám například umožní zvolit pojmenování naší funkce, aniž bychom museli zjišťovat nebo zkoušet, zda nedochází ke kolizi s jmény používanými v knihovnách. Podobných požadavků na vlastnosti, které při psaní malých programů nemusíme ani využít, je více. Další z důležitých vlastností, bez které si dnes programování ve velkém stěží dokážeme představit, je schopnost pracovat na úrovní objektů. Jazyk by tedy měl být objektově orientovaný, nebo alespoň object based. Volně s tím souvisí i možnost práce s hotovými binárními komponentami.
Skriptovací jazyky si obvykle cíle typu podporovat programování ve velkém nekladou. Výkon interpretace zdrojového textu u jednoduchých skriptovacích jazyků je prakticky nevhodný pro zápis složitější funkčnosti. Průlom v tomto směru udělal jazyk Perl (z těch známých), a také jazyk Python. S nárůstem výkonu, který je dán jiným přístupem k interpretaci zdrojového textu, lze budovat přímo v daném jazyce rozsáhlejší aplikace. Zavedení modulů, které umožňují jednoduchou vazbu na funkce systému, pomáhá splnit původní cíl skriptovacích jazyků — tvořit lepidlo pro spojování funkčnosti utilit. Vhodný způsob zavedení modulů umožňuje jak vytváření dalších, standardně dodávaných modulů, tak modulů vlastních. Vhodná definice zobecněného rozhraní modulů umožňuje vytvářet moduly v jiných, kompilovaných jazycích, které výsledné aplikaci mohou v dané aplikační oblasti dodávat potřebný výkon. Ten by v původním skriptovacím jazyce nemusel být v mnoha případech dosažitelný. Mimo jiné to umožňuje přidat mezi standardně dodávané moduly i ty, které realizují grafické uživatelské rozhraní, jako je například využití Tk. Všechny uvedené vlastnosti splňují jak Perl, tak Python.
Python ovšem navíc poskytuje výbornou vyjadřovací čistotu a stručnost. Třídy lze tvořit jednoduchým způsobem. Jednoduchým způsobem můžeme vytvářet i třídy odvozené, specializované (mechanismus dědičnosti). Při růstu velikosti řešeného problému nenarážíme na principiální omezení velikosti objektů nebo na omezení jejich funčnosti. Máme k dispozici kvalitní a výkonné zabudované datové abstrakce. V neposlední řadě Python používá jednoduchou, jednoznačnou a průhlednou syntaxi. To jsou ony vlastnosti, které z Pythonu činí mnohem lepšího kandidáta na tvorbu ve velkém, než je tomu například u jazyka Perl.
Pokud vás napadne, co by se mělo mezi tyto poznámky k některé kapitole doplnit, zašlete mi e-mail odklepnutím . Tím bude do subjektu dopisu automaticky vložena informace o jméně a verzi tohoto HTML dokumentu.
$Id: cztuttrn.html,v 1.4 2004/07/02 08:12:10 prikryl Exp $