\documentclass[11pt,a4paper,oneside]{report}
\usepackage{fithesis}
\usepackage[czech]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{url}
\usepackage{graphicx}
\usepackage{pdfpages}
\usepackage{fancyvrb}
\DefineVerbatimEnvironment{code}{Verbatim}{fontsize=\small}
\DefineVerbatimEnvironment{example}{Verbatim}{fontsize=\small}

\setlength{\hoffset}{-1.65cm}
\setlength{\voffset}{-1.75cm}
\setlength{\textheight}{25.0cm}
\setlength{\textwidth}{16cm}

\makeatletter
\renewcommand\l@figure{\@tocline{0}{3pt plus2pt}{0pt}{2.2pc}{}}
\renewcommand\l@table{\@tocline{0}{3pt plus2pt}{0pt}{2.2pc}{}}

\renewcommand{\@tocrmarg}{4em}
\def\@tocline#1#2#3#4#5#6#7{\relax
  \ifnum #1>\c@tocdepth % then omit
  \else
    \par \addpenalty\@secpenalty\addvspace{#2}%
    \begingroup \hyphenpenalty\@M
    \@ifempty{#4}{%
      \@tempdima\csname r@tocindent\number#1\endcsname\relax
    }{%
      \@tempdima#4\relax
    }%
    \parindent\z@ \leftskip#3\relax \advance\leftskip\@tempdima\relax
    \rightskip\@pnumwidth plus4em \parfillskip-\@pnumwidth
    #5\leavevmode\hskip-\@tempdima #6\nobreak\relax
    \ifnum#1<0\hfill\else\dotfill\fi\hbox to\@pnumwidth{\@tocpagenum{#7}}\par
    \nobreak
    \endgroup
  \fi}
\makeatother

\thesislang{cs}
\thesistitle{Knihovna pro tvorbu pluginů pro PyMOL}
\thesissubtitle{Bakalářská práce}
\thesisstudent{Matěj Škrabánek}
\thesiswoman{false} \thesisfaculty{fi} \thesisyear{2012}
\thesisadvisor{Mgr. David Sehnal}


\begin{document}
\sloppy

\FrontMatter \ThesisTitlePage

\begin{ThesisThanks}
Chtěl bych na tomto místě poděkovat především vedoucímu mé bakalářské práce Mgr. Davidu Sehnalovi, za ochotu, trpělivost~a cenné rady při psaní této práce. Také bych chtěl poděkovat mé rodině~a přátelům za podporu během studia.
\end{ThesisThanks}

\begin{ThesisDeclaration}
\DeclarationText
\AdvisorName
\end{ThesisDeclaration}

\begin{ThesisAbstract}
V dnešní době existuje škála programů zabývající se analýzou makromolekulárních struktur a~nové jsou denně vyvíjeny. Cílem této práce je vytvoření nástrojů, které umožní těmto programům přístup k~vizualizační aplikaci PyMOL, a~to způsobem vytvářejícím jak možnosti překladu výstupních dat analytických programů do dat, které je aplikace PyMOL schopna zobrazit, tak možností tvorby uživatelského rozhraní vlastního programu jako rozšíření aplikace PyMOL. Ve snaze naplnění tohoto cíle byly vytvořeny nástroje v~podobě knihovny \textbf{PyMOLBuilder} a~aplikace \textbf{PyMOLPluginCompiler} umožnující překlad programů napsaných v~jazyce C\# do jazyka Python. Tyto nástroje jsou pak vybudovány na teoretickém základu analytické části dnešních kompilátorů a~praktickém využití metod projektu Roslyn, možností vytváření rozšíření programů napsaných v~jazyce Python a~metod návrhu a~tvorby rozšiřitelných a~snadno použitelných knihoven.
\end{ThesisAbstract}

\begin{ThesisKeyWords}
PyMOL, Python, C\#, Roslyn, plugin, kompilátor.
\end{ThesisKeyWords}

\setcounter{tocdepth}{1}
\tableofcontents

\MainMatter

\part{Úvod}

\setcounter{chapter}{0}
\chapter{Úvod}
Rozvoj informačních technologií přinesl pozitivní výstupy v~mnoha oblastech. V~dnešní době je dostupné větší množství dat o~molekulách než kdy dříve. A~stále více struktur je zkoumáno, díky pokrokům v~experimentálních technikách a~jejich zvyšující se dostupnosti. Tato data jsou volně dostupná v~internetových databázích jako Protein Data Bank~\cite{berman2002protein} (aktuálně obsahující 77000 proteinových struktur), Pubchem~\cite{wang2009pubchem} (obsahující přes 5 milionů záznamů organických molekul) a~dalších. Toto množství informací nabízí možnost analýzy velkých množin motivů proteinových struktur, jako jsou jejich vazebná místa, druhotné elementy struktur či kanály. Tyto analýzy nám mohou pomoci s~odpověďmi na mnoho důležitých chemických a~biologických otázek. Například pochopit vztah mezi strukturou proteinu a~její funkcí, nebo dokonce tuto funkci předpovídat~\cite{Thornton00}, identifikovat evoluční vztahy mezi proteiny~\cite{Gherardini07}, poskytovat znaky pro klasifikaci~\cite{Eidhammer00}, identifikovat hlavní charakteristiky důležitých proteinových motivů~\cite{Nayal06} a~podobně. Tyto znalosti přináší nové možnosti jak v~základních chemických a~biologických výzkumech tak i~ve farmacii, medicíně a~dalších oblastech.

\paragraph{}
Odborníci, kteří ke svému výzkumu potřebují pracovat s~grafickými modely molekul, mají dnes k~dispozici celou škálu aplikací, které jim tuto možnost nabízí. Tyto programy je možné pořídit placené či zdarma. Komerčními programy jsou např.: Sybyl, Spartan nebo Insightll. Mezi volně dostupný software patří například: Rasmol, VMD, Chimera, Jmol a~PyMOL~\cite{Uvod01}. Mezi nejvyužívanější vizualizační nástroje pak patří poslední jmenovaný. Je udáváno, že zhruba 30\% vizualizací proteinových struktur je vytvořeno v~aplikaci PyMOL~\cite{Uvod02}.

\paragraph{}
PyMOL je vytvořen v~jazyce Python. Python je interpretovaný, dynamický, objektově orientovaný, skriptovací programovací jazyk~\cite{Uvod03}. Mezi jeho přednosti patří jak produktivita z~hlediska rychlosti psaní programů a~rozsáhlá škála knihovních modulů, tak přenositelnost programů v~něm napsaných. Python, v~závislosti na svém interpretu, běží na Windows, Linux / Unix, Mac OS X, a~na virtuálních strojích platforem Java a~.NET~\cite{Uvod04}.

\paragraph{}
Samostatné využití aplikace ovšem často předpokládá nestandardní funkcionalitu, například výpočet dutin a~tunelů v~proteinech. Ke zpracování takových případů jsou využívány speciální zásuvné moduly - pluginy, které po zavedení do základní aplikace PyMOL, požadovaný efekt umožní. Současný proces pak představuje postup od požadavku, vyhledání a~instalace pluginu po jeho spuštění nebo, pokud požadovaný plugin neexistuje, musí následovat jeho tvorba, což může představovat jisté snížení efektivity ve vztahu k~počátečnímu požadavku. V~souladu s~efektivním využitím otevřené vizualizační aplikace je cílem práce vytvoření knihovny v~jazyku C\# pro usnadnění tvorby zásuvných modulů do aplikace využívané k~vizualizaci molekul PyMOL.

\paragraph{}
Práce je členěna do tří základních okruhů. Prvním z~nich je analýza a~návrh zahrnující vyhodnocení požadavků na aplikaci, zjištění možností využití standardních funkcí programu PyMOL či knihovních modulů Pythonu tak, aby bylo snadné navrhovanou aplikaci rozšířit a~tak aby byla zachována její flexibilita a~robustnost z~pohledu změn v~programu PyMOL či jazyka Python. Další část představuje implementace návrhu. Zabývá se prací na vlastní aplikaci. Třetí část se pak zabývá využitím implementace k~tvorbě dvou rozšíření programu PyMOL, na kterých je demonstrována funkcionalita řešení.

\paragraph{}
Knihovna bude sloužit pro usnadnění tvorby rozšíření programu PyMOL. Výsledný produkt umožní vývojářům nových programů, které poskytují výpočetní funkcionalitu, to jest možnosti automatického zkoumání makromolekulárních struktur, využití vizualizačních schopností programu PyMOL tím, že dovolí implementaci pluginu souběžně s~vytvářením programu. Usnadnění spočívá i~v rychlejším a~efektivnějším převodu funkcionality poskytované jinými programy založenými na jazycích .NET platformy právě pomocí knihovny pro reprezentaci a~kompilaci programových celků v~jazyce Python.

\paragraph{}
Práce se skládá z~tří kapitol, toto rozložení reflektuje použitou metodologii a~postup tvorby aplikace. První kapitolou je teoretická příprava a~zkoumání možností transformace programu v~jazyce C\# do programu v~jazyce Python. Druhou kapitolou je analýza, která zahrnuje zkoumání používaných programů a~jazyků, či možnosti efektivní implementace knihoven. Třetí kapitolou je návrh a~implementace knihovny opírající se především o~návrh reprezentace kódu v~jazyce C\# do Python kódu rozšíření programu PyMOL. Čtvrtá kapitola se zabývá vytvářením demonstračních rozšíření a~nezbytnými úpravami knihovny na základě požadavků vzniklých implementací pluginů.

\part{Teorie}

\setcounter{chapter}{0}
\chapter{Kompilátor}
Nejběžnější formou nástroje umožňujícího překlad programu v~jistém jazyce do jazyka jiného jsou kompilátory, proto je logickým postupem při vytváření efektivního nástroje s~podobnou funkcionalitou nejprve analyzovat právě kompilátory, jejich strukturu a~funkce. Obecně je kompilátor chápán jako takzvaná \uv{černá krabička}, totiž jako komplexní systém s~výše zmíněnou funkcionalitou, tato je členěna do dvou částí, \textbf{analýzy} a~\textbf{syntézy}. Analýza vytváří representaci vstupního kódu a~provede jeho syntaktickou a~sémantickou analýzu. Získávají se data o~programu a~zapisují se do struktury nazývané \textbf{tabulka symbolů}, která je pak společně s~representací kódu předána syntéze, jejímž úkolem je převod do cílového jazyka~\cite{DragonBook01}.
\begin{figure}[h!]
\centering
\includegraphics[width=0.7\textwidth]{Compiler}
\caption{Detailní struktura kompilátoru}
\end{figure}

\paragraph{}
Při detailnějším rozdělení funkcionality kompilátoru podle rolí je viditelné, že jeho součásti jsou na sobě v~kaskádovitém pořadí závislé, kdy každá část jistým způsobem transformuje vstup na výstup, jenž je používán částí následující. Díky tomu je teoreticky možné jednotlivé části používat zvlášť jako služby a~nikoliv vždy pouze jako součást celkového program kompilátoru. Prakticky je tato možnost v~jazyce C\# umožněna aktuálně pomocí projektu firmy Microsoft \textbf{Roslyn}, momentálně označeném jako \uv{Community Technology Preview}, čili ve fázi veřejného testování~\cite{Msdn04}. Funkce tohoto projektu jsou pak prakticky použity ve vlastí implementaci knihovny, především pak funkce poskytující lexikální, syntaktickou a~sémantickou analýzu.

\section{Lexikální Analýza}
Jak specifikovat strukturální pravidla programovacího jazyka a~jak kompilátor identifikuje strukturu vstupního programu, jsou úzce související otázky. Zatímco první z~nich, tedy jak napsat program je předmětem zájmu uživatelů jazyka (programátorů), druhá jak napsaný program zkontrolovat je náplní práce kompilátorů. K~definici validního programu lze použít regulární výrazy a~bezkontextové gramatiky, k~validaci programů pak lze využít jejich jazykové ekvivalence s~deterministickými konečnými automaty a~deterministickými zásobníkovými automaty, které představují implementaci lexikálních a~syntaktických analyzátorů. Navíc je možné tyto analyzátory automaticky generovat na základě zadaných gramatik pomocí množství nástrojů jako Flex či Yacc~\cite{Pragmatics01}.

\paragraph{}
Hlavním úkolem lexikální analýzy, či \uv{scanovaní} je zjednodušení práce analýze syntaktické (\uv{parser}), redukováním vstupních dat (tok znaků). Výstupem je pak tok tokenů, kdy token chápeme jako dvojici skládající se z~názvu tokenu (typ tokenu) a~odkazu na příslušný řádek v~tabulce symbolů~\cite{DragonBook01}. Typicky se stará o~odstranění nedůležitých součástí vstupu jako komentáře zdrojového kódu, a~rozpoznání typu tokenů skládajících se z~jisté posloupnosti znaků. Každý takovýto rozpoznaný token je napojen na tabulku symbolů, kde jsou uchovány dodatečné informace~\cite{DragonBook01}.

\subsection{Specifikace Tokenu}
Ke specifikaci, nalezení tokenu a~přiřazení jeho správného jména jsou analyzátorem používány regulární výrazy. Tyto jsou popsány pomocí pojmů abeceda, řetězec a~jazyk.

\subsubsection{Řetězce a~jazyky}
\textit{Abeceda} je konečná množina symbolů. Typickým příkladem jsou písmena nebo čísla. Množina \{0,1\} je tedy binární abecedou. Jiným příkladem abecedy může být Unicode, který obsahuje okolo 100 000 znaků. \textit{Řetězec} je pak konečná sekvence znaků určité \textit{abecedy}. Délka řetězce $s$, značená jako: $|s|$ je rovna počtu symbolů obsažených v~řetězci. Prázdný řetězec $\epsilon$ je řetězec neobsahující žádné symboly a~jeho délka $|\epsilon|$ je rovna 0. \textit{Jazyk} je množina slov (řetězců) skládajících se z~jedné abecedy, tato množina pak může být prázdná, může obsahovat pouze prázdný řetězec či naopak všechna slova existující nad danou abecedou~\cite{DragonBook01}.

\subsubsection{Operace nad jazyky}
Nejdůležitějšími operacemi z~pohledu lexikální analýzy jsou operace sjednocení, sřetězení a~iterace. Formálně definovány jako:
\begin{itemize}
\item \textit{Sjednocení jazyků L~a M: } $L \cup M~= \{s | s~\in L$ nebo $s\in M\}$
\item \textit{Sřetězení jazyků L~a M: } $L . M~= \{st | s~\in L$ a~$t\in M\}$
\item \textit{Iterace jazyka L: } $L^* = \cup^{\infty}_{i=0}L^i$
\item \textit{Pozitivní iterace jazyka L: } $L^+ = \cup^{\infty}_{i=1}L^i$
\end{itemize}

\subsubsection{Regulární výrazy}
Regulární výrazy jsou schopny popsat všechny jazyky, které mohou být vytvořeny pomocí použití výše zmíněných operací na symbolech nějaké abecedy. Výrazy jsou budovány rekurzivně z~menších regulárních výrazů, použitím následujících pravidel. Každý regulární výraz $r$ označuje jazyk $L(r)$, který je také definován rekurzivně podvýrazy výrazu $r$~\cite{DragonBook01}. Pravidla pro skládání regulárních výrazů nad abecedou $C$ a~jazyky, které jsou jimi označeny:

\paragraph{}
\textbf{Báze:} Dvě základní pravidla formující bázi.
\begin{enumerate}
\item $\epsilon$ je regulární výraz a~jazyk $L(\epsilon)$ je $\{\epsilon\}$, tudíž jazyk obsahující pouze prázdný řetězec.
\item Pokud $a$ je symbolem abecedy $C$, pak $s$ je regulární výraz a~$L(a)=a$, tedy jazyk s~jedním řetězcem délky jedna se symbolem $a$ na prvním místě.
\end{enumerate}

\textbf{Indukce:} Čtyři pravidla, kterými jsou stavěny větší regulární výrazy. $r$ a~$s$ jsou regulární výrazy označující jazyky $L(r)$ a~$L(s)$.
\begin{enumerate}
\item $(r)|(s)$ je regulární výraz označující jazyk: $L(r) \cup L(s)$.
\item $(r)(s)$ je regulární výraz označující jazyk: $L(r).L(s)$.
\item $(r)*$ je regulární výraz označující jazyk: $(L(r))^*$.
\item $(r)$ je regulární výraz označující jazyk: $L(r)$. To znamená, že přidání závorek, kolem regulárního výrazu nemění jazyk, který označuje~\cite{DragonBook01}.
\end{enumerate}

Jazyk, který může být definován regulárním výrazem, se nazývá regulární množinou. Pokud dva regulární výrazy $r$ a~$s$ popisují stejnou regulární množinu, říkáme, že jsou ekvivalentní, tudíž: $s=r$~\cite{DragonBook01}.
Regulární výrazy mohou být dále rozšířeny následujícími operacemi:
\begin{enumerate}
\item \textit{Jedna nebo více instancí.} Je unární operací shodnou s~pozitivní iterací $r^+$
\item \textit{Nula až jedna instance.} $r? = r|\epsilon$.
\item \textit{Třídy symbolů.} Umožňuje rozlišovat symboly podle tříd, do které spadají. $[a-z] = a|b| ... |z$
\end{enumerate}

\subsection{Rozpoznání tokenu}
Regulární výrazy jsou schopny popisovat regulární jazyky, tedy jazyky rozpoznatelné deterministickými i~nedeterministickými konečnými automaty.

\paragraph{}
Nedeterministický konečný automat (NFA) je pětice:
\begin{enumerate}
\item Konečná množina stavů S.
\item Množina vstupních symbolů C~neboli vstupní abeceda. Předpokládáme, že $\epsilon$ není součástí této množiny.
\item Přechodová funkce, která určuje každému stavu a~symbolu množinu jejich příštích stavů.
\item Počáteční stav (prvek S).
\item Množina koncových stavů (podmnožina S)~\cite{DragonBook01}.
\end{enumerate}

\paragraph{}
Deterministický konečný automat (DFA) je pak automat, jehož přechodová funkce určuje každému stavu a~symbolu přesně jeden následující stav. NFA i~DFA akceptuje vstupní řetězec $x$ pouze pokud existuje cesta z~jeho počátečního stavu do nějakého koncového stavu, taková která bude obsahovat přesně ty symboly ve stejném pořadí jako ve vstupním řetězci~\cite{DragonBook01}.

\subsubsection{McNaughton-Yamada-Thompson algoritmus}
Ke konverzi mezi regulárními výrazy popisující tokeny na nedeterministický konečný automat je možné použít McNaughton-Yamada-Thompson algoritmus~\cite{Pragmatics01}.\\
\textbf{Vstup:} Regulární výraz $r$ nad abecedou $C$.\\
\textbf{Vystup:} NFA $N$ akceptující jazyk $L(r)$.\\
\textbf{Metoda:} Rozděl výraz $r$ na jeho tvořící podvýrazy. Pravidla pro vytvoření NFA se pak skládají ze základních pravidel pro převod podvýrazů bez operátorů a~induktivních pravidel pro konstrukci rozšíření NFA pomocí bezprostředního podvýrazu vstupního výrazu $r$~\cite{DragonBook01}.

\subsubsection{Identifikátory a~rezervovaná slova}
Rozpoznání klíčových slov a~identifikátorů může působit problém. Běžně jsou klíčová slova velmi podobná identifikátorům, například \textbf{if} nebo \textbf{else}. Určit rozdíl mezi klíčovým slovem a~identifikátorem je možné dvojím způsobem:
\begin{itemize}
\item Použití tabulky symbolů k~odhalení typu tokenu. Při odhalení řetězce, který odpovídá regulárnímu výrazu popisující identifikátor je proveden náhled do tabulky symbolů, zda není daný řetězec shodný s~některým z~vyčleněných klíčových slov a~podle výsledku tohoto dotazu je tokenu přiřazeno jméno.
\item Vytvoření vlastních regulárních výrazů pro každé klíčové slovo.
\end{itemize}

\section{Syntaktická Analýza}
Druhá fáze kompilátoru se nazývá syntaktickou analýzou či \uv{parsování}. Vstupem této části jsou první části tokenů produkované lexikálním analyzátorem. Vstup je transformován na stromové objekty jako průběžná representace syntaxe, která popisuje gramatickou strukturu tokenů ve vstupním toku. Typickou representací je syntaktický strom, ve kterém každý vnitřní uzel představuje operaci a~potomci uzlu pak argumenty této operace. Kombinování uzlů je pak potenciálně rekurzivní a~je popsáno sadou bezkontextových gramatik nebo použitím notace Backus-Naurovy formy~\cite{DragonBook01}. Rozšířená notace Backus-Naurovy formy je popsána ve standardu ISO/IEC 14977:1996. Syntaktická analýza je pak problémem analýzy derivačních stromů daných bezkontextových gramatik.

\subsection{Bezkontextové gramatiky}
Bezkontextové gramatiky se skládají z~terminálů, neterminálů, počátečního neterminálu a~pravidel.
\begin{enumerate}
\item Terminály představují symboly, ze kterých jsou tvořeny řetězce. V~kontextu kompilátoru je terminál synonymem pro jméno tokenu. Při vytvoření bezkontextové gramatiky pro účel syntaktické analýzy je tedy definice jmen tokenů společná s~lexikální analýzou.
\item Neterminály jsou syntaktické proměnné, které popisují množiny řetězců a~představují hierarchickou strukturu jazyka.
\item Počáteční symbol je jeden neterminál, který je určen jako počáteční pro každý řetězec generovaný gramatikou.
\item Pravidla určují způsoby kombinace neterminálů a~terminálů, které je možno využít pro tvorbu řetězce. Pravidla jsou tvaru: Jeden neterminál $N$ na levé straně pravidla přepiš $\rightarrow$ na nula nebo více terminálů nebo neterminálů~\cite{DragonBook01}. 
\end{enumerate}

\subsubsection{Derivační strom a~derivace}
Derivace je pohled na gramatiku, kdy její pravidla jsou chápána jako přepisovací pravidla, z~hlediska přepisování jednotlivých neterminálů chápeme dva hraniční přístupy:
\begin{enumerate}
\item Levá derivace, kdy je přepsán v~každém kroku vždy neterminál na nejlevějším místě. Pokud $\alpha \Rightarrow \beta$ je krokem levé derivace, pak je přepsán užitím pravidla gramatiky první neterminál zleva obsažený v~$\alpha$.
\item Pravá derivace, kdy je přepsán v~každém kroku vždy neterminál nejvíce vpravo~\cite{Pragmatics01}.
\end{enumerate}

\paragraph{}
Derivační strom je grafická representace derivace, která zobrazuje postup, v~jakém jsou aplikována pravidla při přepisu neterminálů. Každý vnitřní uzel derivačního stromu je aplikací pravidla a~je označen přepisovaným neterminálem. Potomci uzlu jsou pak označeni symboly z~těla pravé strany použitého pravidla, podle pořadí udaném pravidlem. Gramatika je označena za \textbf{neurčitou} pokud umožňuje produkci více levých nebo pravých derivací při generování stejného řetězce~\cite{DragonBook01}.

\subsubsection{Odstranění levé rekurze}
Gramatika je levorekurzivní, pokud má neterminál $N$ takový, že existuje derivace $N \Rightarrow^+ N\alpha$ pro libovolný řetězec $\alpha$. Metoda syntaktické analýzy shora dolů však není schopna používat levorekurzivní gramatiky. K~odstranění levé rekurze je možné použít následující algoritmus:\\
\textbf{Vstup:} Gramatika $G$ bez cyklů nebo $\epsilon$ pravidel.\\
\textbf{Výstup:} Jazykově ekvivalentní gramatika bez levé rekurze.\\
\textbf{Metoda:}
\begin{enumerate}
\item uspořádej neterminály $A_1, A_2, ... A_n$.
\item pro každé i~z 1 až n:
\item \indent pro každé j~z 1 až i-1:
\item nahraď každé pravidlo tvaru $A_i \rightarrow A_{j\gamma}$ pravidly $A_i \rightarrow \delta_1\gamma | \delta_2\gamma ... | \delta_k\gamma$, kde pravidla $A_i \rightarrow \delta_1 | \delta_2 ... | \delta_k$ jsou aktuální $A_j$ pravidla
\item odstraň bezprostřední levou rekurzi v~pravidlech $A_i$~\cite{DragonBook01}.
\end{enumerate}

\subsection{Analýza shora dolů}
Na analýzu shora dolů může být nahlíženo jako na problém konstrukce derivačního stromu pro vstupní řetězec, neboli jako hledání levé derivace pro řetězec. Při každém kroku analýzy shora dolů je klíčovým problémem rozhodnutí, které pravidlo gramatiky pro daný neterminál aplikovat. Ve chvíli zvolení pravidla přepisu je zbytek procesu analýzy přiřazováním terminálních symbolů. Metodami analýzy shora dolů jsou rekurzivní sestup a~prediktivní analýza. Lišící se využitím predikce, kdy metoda rekurzivního sestupu nepoužívá predikci a~je tedy potřeba implementovat možnost \uv{couvání}. Prediktivní analýza využívá náhledu na budoucí vstup, typicky s~velikostí jednoho symbolu předem~\cite{DragonBook01}.

\subsubsection{FIRST a~FOLLOW}
Konstrukce obou přístupů analýzy, shora dolů i~zdola nahoru je doprovázeno využitím pomocných funkcí \textbf{FIRST} a~\textbf{FOLLOW} společně s~gramatikou $G$. V~průběhu analýzy shora dolů nám tyto funkce umožňují rozhodnutí, jaké pravidlo vybrat na základě příštího vstupního symbolu.

\paragraph{}
Definujme funkci FIRST($\alpha$), kde $\alpha$ je řetězec gramatických symbolů, jako množinu terminálů derivovaných z~$\alpha$. Pokud $\alpha \Rightarrow^* \epsilon$ pak i~$\epsilon$ je součástí FIRST($\alpha$). Funkce FIRST pak může být použita v~rámci prediktivní analýzy, mějme dvě pravidla: $A \rightarrow \alpha | \beta$, kde FIRST($\alpha$) a~FIRST($\beta$) jsou disjunktní množiny. Se znalostí příštího vstupního symbolu můžeme určit nanejvýš jedno z~těchto pravidel, protože příští symbol se bude nacházet pouze v~jedné z~těchto množin~\cite{DragonBook01}.

\paragraph{}
Definujme funkci FOLLOW(A) pro neterminál A~jako množinu terminálů, které se mohou nacházet bezprostředně vpravo od neterminálu v~nějaké množině gramatických symbolů na pravé straně nějakého pravidla gramatiky. Tedy množina terminálů a~taková pokud existuje pravidlo tvaru $S \Rightarrow^* \alpha A~a \beta$ pro libovolné $\alpha, \beta$~\cite{DragonBook01}.

\subsubsection{LL(1) gramatiky}
Prediktivní analyzátory mohou být konstruovány pomocí třídy gramatik nazývaných LL(1). Kde první \uv{L} procházení vstupního toku symbolů zleva, druhé \uv{L} pak produkci levé derivace a~\uv{1} udává počet vstupních symbolů na které je nahlíženo v~předstihu při každém kroku akce analyzátoru.

\paragraph{}
Gramatika $G$ je LL(1) tehdy, a~jen tehdy pokud pravidla $A \rightarrow \alpha | \beta$ jsou různými pravidly gramatiky a~platí:
\begin{enumerate}
\item Pro žádný terminál $a$ nederivují pravidla $\alpha$ a~$\beta$ řetězec začínající $a$.
\item Pouze jedno z~pravidel $\alpha$ a~$\beta$ smí derivovat prázdný řetězec $\epsilon$.
\item Pokud $\beta \Rightarrow^* \epsilon$ pak $\alpha$ nesmí derivovat řetězec začínající terminálem z~množiny FOLLOW(A). Stejně tak pokud $\alpha \Rightarrow^* \epsilon$ pak $\beta$ nesmí derivovat řetězec začínající terminálem z~množiny FOLLOW(A)~\cite{DragonBook01}.
\end{enumerate}

\subsection{Analýza zdola nahoru}
Analýza zdola nahoru koresponduje s~konstrukcí derivačního stromu ze vstupního řetězce, začínající v~listech stromu a~postupně vytvářející strom směrem ke kořeni.

\subsubsection{Redukce}
Analýzu zdola nahoru můžeme považovat za proces redukce řetězce $r$ na počáteční neterminál gramatiky. Definicí redukce je pak opačný krok během derivace. Při každém redukčním kroku je specifický podřetězec odpovídající levé straně některého pravidla gramatiky nahrazen neterminálem pravé strany pravidla. Klíčovým rozhodnutím během analýzy zdola nahoru je pak otázka kdy redukovat a~které pravidlo aplikovat~\cite{DragonBook01}.

\subsubsection{Shift-reduce parsing}
Shift-reduce parsing je formou analýzy zdola nahoru, která využívá zásobník, který uchovává symboly gramatiky ke zpracování. V~průběhu procházení vstupního řetězce, analyzátor přesouvá nula nebo více vstupních symbolů na zásobník, dokud není schopen redukovat řetězec $\beta$ na vrcholu zásobníku pomocí pravidel gramatiky. Poté tento řetězec $\beta$ redukuje na neterminál odpovídajícího pravidla. Tento cyklus je opakován, dokud není detekována chyba nebo dokud není vstupní řetězec redukován na počáteční neterminál gramatiky~\cite{DragonBook01}.

\paragraph{}
Čtyři základní operace Shift-reduce parsing metody:
\begin{enumerate}
\item Posun. Přesouvá následující symbol ze vstupního řetězce na vrchol zásobníku.
\item Redukce. Redukuje podřetězec na zásobníku na neterminál.
\item Potvrzení. Ohlašuje úspěšné ukončení analýzy.
\item Chyba. Nalezení syntaktické chyby v~analyzovaném řetězci~\cite{DragonBook01}.
\end{enumerate}

\section{Sémantická Analýza}
Sémantický analyzátor používá syntaktické stromy a~příslušné záznamy z~tabulky symbolů ke kontrole sémantické konzistence zdrojového programu s~ohledem na definici použitého zdrojového jazyka. Stromy předávané syntaktickým analyzátorem jsou často označovány jako konkrétní syntaktické stromy, protože ukazují kompletní a~konkrétní způsob jakým může být skupina tokenů derivována pravidly bezkontextové gramatiky, ve chvíli kdy již víme, že konkrétní sekvence tokenů je validní, není již značná část konkrétního syntaktického stromu potřebná pro další zpracování kompilátorem. V~procesu kontroly statických sémantických pravidel je tudíž tento syntaktický strom transformován na takzvaný \textbf{abstraktní syntaktický strom}, odstraněním zbytečných uzlů a~označením zbylých uzlů souvisejícími informacemi z~tabulky symbolů~\cite{Pragmatics01}.

\paragraph{}
Mezi dalšími informacemi drží tabulka symbolů kompilátoru informace o~interní struktuře identifikátoru, jeho typu, či rozsahu programu, ve kterém je jeho výskyt validní. Současně analyzátor sbírá informace o~typech proměnných a~ukládá je do syntaktických stromů nebo do tabulky symbolů, pro fázi generování cílového kódu. Proces typové kontroly sémantického analyzátoru je velmi důležitý, kdy kompilátor kontroluje každou operaci a~její operandy. Například mnoho programovacích jazyků požaduje, aby byla pole indexována celými čísly, pokud tomu tak není, analyzátor musí nahlásit chybu, která musí být nutně opravena~\cite{Pragmatics01}.

\paragraph{}
Specifikace jazyka také může povolit donucovací operace, kdy například v~jazyce může být povolena binární operace aplikovatelná na buď dvojici celých čísel, nebo dvojici čísel desetinných, v~takovém případě kdy je operace aplikovaná na dvojici celé číslo a~desetinné číslo, může být kompilátoru umožněno donutit přetypování jednoho operandu na shodný typ. Veškeré tyto informace jsou využívány sémantickým analyzátorem k~dosažení účinné kontroly pravidel zdrojového jazyka, které nejsou postižitelná bezkontextovými gramatikami a~konkrétními syntaktickými stromy. Různá sémantická pravidla lze členit podle toho, kdy je možné odhalit jejich splnění.\\ \\ \textbf{Dynamická pravidla} jsou ta, která nelze vyhodnotit během kompilace programu, například:  
\begin{itemize}
\item Proměnné nejsou nikdy použity ve výrazu, pokud neobsahují nějakou hodnotu.
\item Program se nesnaží zasáhnout na index pole, který je mimo jeho hranice.
\item Aritmetické operace nepřetékají mimo hranice možných hodnot výsledků.
\end{itemize}
Mezi \textbf{pravidla statická}, která jsou kontrolovatelná během kompilace, pak patří:
\begin{itemize}
\item Kontrola deklarace identifikátoru před tím, než je užit.
\item Identifikátor není použit mimo svůj rozsah.
\item Volání metod má správný počet argumentů správného typu.
\end{itemize}

\subsection{Atributové gramatiky}
Atributové gramatiky poskytují formální rámec pro dekoraci syntaktických stromů sémantickými informacemi, rozšiřují tak schopnost bezkontextových gramatik umožňující validaci formy zápisu o~spojení s~významem zápisu~\cite{Pragmatics01}. Atributové gramatiky nabízejí rozšíření symbolů gramatiky o~vlastnosti (typicky založených na základě informací o~tokenu získaných v~průběhu lexikální analýzy) a~přidání sémantických pravidel nějakým způsobem ovlivňujícím tyto vlastnosti. Tato sémantická pravidla mohou být jak jedinečná každému pravidlu gramatiky, tak společná pro více pravidel. Zároveň je nutné, aby tato sémantická pravidla byla napsána v~nějaké již existující notaci, protože pravidla sama o~sobě neposkytují sémantiku, ale pouze spojení s~něčím co již význam má. Striktní atributové gramatiky povolují pouze pravidla kopírovací (přiřazení jednoho atributu jinému) a~volání jednoduchých sémantických funkcí.

\subsubsection{Hodnocení atributů}
Proces hodnocení atributů je nazýván anotace nebo dekorace syntaktického stromu. Atributy mohou být více druhů:
\begin{enumerate}
\item \textbf{Syntetizované atributy} jsou atributy, jejichž hodnoty jsou počítány v~pravidlech gramatiky, ve kterých se symbol atributu nachází na levé straně. Atributová gramatika, jejíž všechny atributy jsou syntetizované, je nazývána \textbf{S-atributová}. Argumenty sémantických funkcí v~těchto gramatikách jsou vždy atributy symbolů na pravé straně aktuálního pravidla a~jejich návratová hodnota je vždy umístěna do atributu na levé straně tohoto pravidla~\cite{Pragmatics01}.
\item \textbf{Zděděné atributy}. Obecně uvažujme atributy, jejichž hodnoty jsou počítány, když jejich symbol je na pravé straně aktuálního pravidla gramatiky. Takové atributy jsou nazývány zděděné. Umožňují kontextovým informacím přesun do vyšších symbolů nebo symbolů z~druhé strany pravidla tak, aby jeho syntaktická pravidla byla závislá na jiných prosazovacích cestách. Informace z~tabulky symbolů jsou častými hodnotami zděděných atributů~\cite{Pragmatics01}.
\end{enumerate}

\paragraph{}
Tak jako bezkontextové gramatiky nespecifikují, jakým způsobem mají být derivovány, atributové gramatiky nespecifikují pořadí, v~jakém by jejich syntaktická pravidla měla být vyvolána. Obě zmíněné notace jsou deklarativní, popisují množinu validních stromů, ale nepopisují, jakým způsobem jsou budovány. Mezi dalšími to také znamená, že pořadí, ve kterém jsou atributy sestaveny pro dané pravidlo gramatiky, je irelevantní. \textbf{Tok atributů} však může vynutit spuštění sémantických pravidel v~určitém pořadí. Algoritmus, který dekoruje syntaktické stromy voláním sémantických pravidel atributových gramatik, se nazývá \textbf{translační schéma}~\cite{Pragmatics01}.

\paragraph{}
Atributové gramatiky jsou kategorizovány podle komplexity jejich vzorců toku atributů. S-atributové gramatiky, ve kterých jsou všechny atributy syntetizované, mohou být přirozeně hodnoceny v~jednom průchodu stromem směrem zdola nahoru~\cite{Pragmatics01}.

\part{Metody}

\setcounter{chapter}{0}
\chapter{Projekt Roslyn}
Projekt Roslyn, zmíněný v~kapitole kompilátor je snahou o~přepsání kompilátorů jazyků C\# a~Visual Basic (VB), jedná se o~přechod od pojetí kompilátoru jako jednolitého programu k~náhledu na části kompilátoru jako na služby, toto drasticky snižuje bariéru pro vytváření nástrojů pro práci s~kódem a~vytváří možnosti pro inovaci v~oblastech generace a~transformace či interaktivního užití jazyků C\# a~VB. Součástí knihoven projektu jsou objektové modely nabízející nástroje pro lexikální, syntaktickou a~sémantickou analýzu kódu jazyka C\#. Nástroje tohoto projektu představují praktickou aplikaci teoretické části práce.

\section{Práce se syntaxí}
Důsledkem těsné spolupráce lexikální a~syntaktické analýzy kompilátoru jazyka C\# jsou jejich výsledky předány uživateli formou syntaktických stromů (typ \textbf{SyntaxTree}) skládajících se z~uzlů (\textbf{SyntaxNode}), ve kterých jsou výsledky analýz pohromadě, namísto striktního oddělení získaných informací.

\subsection{SyntaxTree}
Tyto syntaktické stromy mají tři klíčové vlastnosti. První z~nich je jejich neměnnost a~vláknová bezpečnost, každý syntaktický strom je vytvořen jako pohled na aktuální stav a~není možné jej tedy měnit. Druhým atributem je fakt, že objekty typu \textbf{SyntaxTree} obsahují veškeré informace o~zdrojovém kódu, to znamená, že obsahuje plné znění zdrojového textu včetně všech gramatických konstrukcí, lexikálních tokenů, komentářů i~direktiv preprocesoru. To umožnuje třetí vlastnost syntaktického stromu a~tou je možnost zpětného získání plného textu zdrojového kódu, je tedy i~možné získat text libovolného podstromu či uzlu stromu, což dělá z~typu \textbf{SyntaxTree} dobrý nástroj pro editaci zdrojového textu~\cite{Roslyn}.

\subsection{SyntaxNode}
Uzly syntaktického stromu jsou representovány typem \textbf{SyntaxNode}, tyto uzly představují syntaktické konstrukty jako deklarace, tvrzení a~výrazy. Každá kategorie uzlů je rozlišena třídou derivovanou z~třídy \textbf{SyntaxNode} a~tato množina tříd není rozšiřitelná. Určení typu každého uzlu je (na základě syntaktické analýzy) závislé na syntaktických tokenech (\textbf{SyntaxToken}), což jsou terminály jazykových gramatik. Roslyn dále dělí tyto tokeny na klíčová slova, identifikátory a~literály. Syntaktické tokeny jsou CLR hodnotovými typy a~je tedy možné získat jejich hodnotu v~jejich vlastnosti \textit{Value}~\cite{Roslyn}.

\subsection{Procházení syntaktických stromů}
Projekt Roslyn dodává i~možnost konktrétního způsobu procházení syntaktického stromu pomocí tříd \textbf{SyntaxWalker} a~\textbf{SyntaxVisitor<T>}. Typ \textbf{SyntaxWalker} je schopen procházet konkrétní syntaktický strom, nalézt v~něm uzly specifikovaného typu a~při jejich průchodu provést akci definovanou uživatelem. Třída \textbf{SyntaxVisitor<T>} pak neprochází celý strom, ale navštěvuje vždy jen jeden uživatelem zadaný uzel. Typickým způsobem a~způsobem použitým i~tvořeným programem v~rámci této práce je jejich kombinace~\cite{Roslyn}.

\section{Práce se sémantikou}
Jak je patrné z~popisu analytické části kompilátoru v~předcházející kapitole tabulka symbolů, hrající podstatnou roli v~sémantické analýze je produktem (a zároveň je jimi i~využívána) všech tří částí analýzy. Proto je i~pro Roslyn při pokusu o~zisk sémantických informací potřeba více informací než jen vlastní text kódu.

\subsection{Compilation}
Třída \textbf{Compilation} je representací všeho co je potřeba ke kompilaci programu napsaném v~jazyce C\#, to znamená odkazy na všechny použité sestavy, možnosti kompilátoru a~zdrojové soubory. Díky přístupu ke všem těmto informacím mohou být všechny elementy, které jsou obsaženy ve zdrojovém kódu popsány detailněji. Stejně jako syntaktické stromy i~kompilace jsou neměnné. Kompilace representuje každý deklarovaný typ, člen či proměnou jako symbol~\cite{Roslyn}.

\subsubsection{Symbol}
Typ \textbf{Symbol} representuje odlišné elementy deklarované ve zdrojovém kódu, nebo importované z~různých sestav jako metadata. Každý jmenný prostor, typ, metoda, vlastnost, pole, parametr nebo logická proměnná je representována symbolem.  Každý typ symbolu je odlišen vlastní třídou derivovanou od třídy \textbf{Symbol}. Symbol také obsahuje dodatečné informace jako reference na další symboly~\cite{Roslyn}. Tato vlastnost je pak použitá implementovaným programem pro vytvoření možnosti využívání metod a~jiných programových celků s~uživatelsky definovanou representací v~jazyce Python~\cite{Roslyn}.


\chapter{Python}
Pro navržení dobré funkční knihovny usnadňující rozšiřování takového programu je třeba analyzovat stávající možnosti jazyka programu, ale i~možnosti jakými zajistit fungování knihovny i~po změnách jazyka. U~jazyka Python je pak třeba vzít v~potaz jak jeho nové verze, tak i~různé implementace jeho interpretů. Pro účel této práce je především důležitý mechanismus operace importování Python modulů. Rozšiřování programů v~jazyce Python hraje v~rámci implementace vlastní práce velmi klíčovou roli, za prvé je třeba pochopit, jakým způsobem jsou spuštěny vlastní pluginy programu PyMOL, ale také je třeba zjistit možnosti spouštění skriptů, jež takový plugin může generovat coby svůj výstup.

\section{Python 2 a~Python 3}
V této části se pojednává o~aktuálních verzích jazyka Python 2.7.2 a~Python 3.2 Zejména z~důvodu zpětné kompatibility vytvářené knihovny. Pro pochopení hlavních rozdílů těchto dvou verzí jsou zde nejprve uvedeny základní rysy jazyku a~pak i~možnosti jak vytvořit programy u~kterých budou minimální obtíže s~úpravami pro danou verzi interpretu.

\subsection{Základní rysy jazyka Python}
V úvodu práce je jazyk Python definován slovy: interpretovaný, dynamický objektově orientovaný a~skriptovací. Proberme nyní tyto pojmy.

\subsubsection{Interprety}
V dnešní době existují tři základní interprety jazyka Python, lišící se především tím v~jakém jazyce jsou napsány. Jsou to:
\begin{itemize}
\item \textbf{CPython}. Jedná se o~původní implementaci napsanou v~jazyce ANSI C.
\item \textbf{Jython}. Implementace pomocí jazyku Java. Jedná se o~Java třídy, které převádějí Python kód do Java byte kódu, který je následně spuštěn pomocí Java Virtual Machine.
\item \textbf{IronPython}. Je nejnovější implementací, která je navržena pro umožnění Python programům interagovat s~aplikacemi napsanými pro platformy .NET či Mono.
\end{itemize}

\subsubsection{Datový model}
V jazyku Python je objekt abstrakcí dat. Všechna data jsou representována objekty či jejich relacemi. Každý takový objekt má pak svou identitu, typ a~hodnotu. Přičemž identita a~typ nemohou být změněny~\cite{PyDoc04}. Uživatelské typy jsou tvořeny pomocí klíčového slova \textbf{class}. Tyto třídy pak mohou dědit z~více rodičovských tříd. Důležitým znakem jazyku Python je jeho dynamičnost, vyplývající ze způsobu zpracování jeho instrukcí a~toho, že tento jazyk je slabě typovaný. Díky tomu je možné vytvořit i~prázdný nespecifikovaný typ, jehož atributy a~metody budou určeny až za běhu programu~\cite{LearningPython01}.

\paragraph{}
Na rozdíl od jazyků jako C++, Java nebo C\# kde jsou kolekce přidány jazyku pomocí knihoven. Python integruje kolekce přímo do svého jádra. Tudíž seznamy, pole i~slovníky jsou základními datovými typy se svou vlastní syntaxí. Navíc výraz \textbf{for} přímo iteruje skrze seznam hodnot než pouze posloupností čísel.

\subsection{Python 3}
3. prosince 2008 byla vydána nová verze jazyka Python 3.0. Verze této nové řady nejsou zpětně kompatibilní s~verzemi jazyka řady 2.x. Mezi hlavní změny patří práce s~celými čísly, kódováním textových dat, práce se seznamy a~změny ve standardních knihovnách~\cite{PyDoc05}.

\subsubsection{Celá čísla}
V Pythonu verze 2.x existují dva datové typy reprezentující celá čísla, \textbf{int} a~\textbf{long}. Rozdíl mezi nimi je v~jejich rozsahu, zatímco typ \textbf{int} je omezen hodnotou konstanty \textbf{sys.maxint}, která je závislá na platformě, hodnoty typy \textbf{long} nejsou takto omezeny. Od verze jazyka 3.0 již existuje pouze jeden typ pro representaci celých čísel, který je shodný s~dřívějším typem textbf{long}, representace tudíž již není na platformě závislá~\cite{PyDoc05}.

\subsubsection{Text}
Python 3.0 používá koncept textových a~binárních dat na rozdíl od unikódových a~osmi bitových řetězců. Nově je veškerý text kódován Unicode kódováním. Datový typ ukládající text je \textbf{str} a~typ pro binární data je \textbf{bytes}. Největší rozdíl mezi verzemi 2.x a~verzemi řady 3 je situace při pokusu o~smíchání textových dat s~daty binárními, která je od nové řady ošetřena výjimkou, kdežto u~řady 2.x bylo možné tyto dva datové typy \uv{míchat}, pokud náhodou bitová data obsahovala sedmi bitová ASCII byty~\cite{PyDoc05}.

\subsubsection{Seznamy}
Hlavní změnou při práci se seznamy a~slovníky je nahrazení návratových hodnot některých jejich známých metod. Například metody slovníků \textbf{dict.keys(), dict.items(), dict.values()} nyní vracejí pouze pohled na dotazované seznamy, jejich editací pak nedochází ke změnám v~původním slovníku~\cite{PyDoc05}.

\subsection{2to3}
\textbf{2to3} je název nástroje, který je dodáván s~novými verzemi Python interpretu a~umožňuje automatický přepis programů napsaných pomocí syntaxe starších 2.x verzí jazyka do syntaxe aktuální. Je také dodávána standardní knihovna \textbf{lib2to3}, která umožňuje vytvoření vlastních přepisovacích pravidel. Avšak tato knihovna je označena za vysoce nestabilní a~v budoucnosti je možné očekávat její značné změny~\cite{PyDoc06}. Standardně je tento nástroj schopen poznat a~opravit jednoduché změny jako například nové volání výrazu \textbf{print}, použití starého datového typu \textbf{long} či nalézt hledanou knihovní funkci při referenci na jistou změněnou standardní knihovnu. Ovšem tento překladač není schopen opravit reference na staré a~v nové verzi jazyka již neexistující vestavěné či knihovní funkce. Pro zamezení těmto chybám je třeba konzultovat dokumentaci jazyka, ve které lze dohledat, zda je daná funkce i~nadále podporována či je nahrazena. 

\section{Rozšiřování Python programů}
Pomineme-li zjevnou možnost rozšíření existujícího programu napsaného v~jazyce Python, kterou představuje přímé doplnění zdrojového kódu svými vlastními příkazy, můžeme použít k~rozšíření výraz \textbf{import}. Avšak v~Pythonu tato možnost neznamená pouze sřetězení nového textu k~již existujícímu zdrojovému kódu, jako tomu je například u~jazyka C~a jeho výrazu \textbf{\#include}~\cite{LearningPython01}. Při importování modulu v~Pythonu (modulem rozumíme libovolný textový soubor obsahující Python příkazy~\cite{LearningPython01}) se provádějí následující tři operace:
\begin{itemize}
\item Vyhledání souboru modulu.
\item Zkompilování do \uv{byte kódu}.
\item Spuštění kódu modulu.
\end{itemize}

\subsection{Vyhledání modulu}
Python uchovává vyhledávací cesty v~proměnné \textbf{path} modulu \textbf{sys}. Tato proměnná se skládá ze čtyř částí:
\begin{enumerate}
\item Domovský adresář programu.
\item \textbf{PYTHONPATH} proměnné prostředí.
\item Adresáře standardních knihoven.
\item Adresáře specifikované v~.pth souborech.
\end{enumerate}

\paragraph{}
Domovský adresář může znamenat adresář, kde je program umístěn, případně v~interaktivním režimu je to momentální pracovní adresář.  Nastavení \textbf{PYTHONPATH} proměnné prostředí závisí na nastavení operačního systému. Při vykonávání příkazu import se postupně prohledávají adresáře obsažené v~\textbf{sys.path} a~první modul shodného názvu je použit. Toto přináší jisté nebezpečí spojené s~překrýváním například standardních knihoven s~moduly se stejným jménem nacházejícími se v~domovském adresáři~\cite{LearningPython01}.

\paragraph{}
Metody navigování Pythonu k~modulům, kterými chceme rozšířit program, lze rozdělit na dvě skupiny. Metody, které lze použít při běhu programu a~ty které je třeba použít před samotným spuštěním. Druhá skupina zahrnuje metody jako nastavení proměnné prostředí \textbf{PYTHONPATH} či zadání adresářů modulů do příslušných .pth souborů.  První skupina se skládá z~následujících tří metod:
\begin{enumerate}
\item Použití vestavěné funkce \textbf{\_\_import\_\_()}.
\item Editace proměnné \textbf{sys.path}
\item Použití metod \textbf{import} z~modulu \textbf{imp}
\end{enumerate}

\subsubsection{Proměnná \textbf{sys.path}}
Důležitým znakem proměnné \textbf{sys.path} je možnost její editace při běhu programu~\cite{PyDoc01}. Přidáním nějaké položky do této proměnné zaručíme vyhledávání modulu v~daném adresáři. Navíc jakoukoliv změnu provedeme, bude tato změna viditelná pouze v~daném běhu programu.

\subsubsection{Vestavěná funkce \_\_import\_\_()}
Funkce \textbf{\_\_import\_\_()} je volána pokaždé, když je v~programu použito slovo \textbf{import} a~umožňuje vyhledávat modul v~daném adresáři a~specifikovat jaké konkrétní objekty chceme z~modulu použít. Funkci má smysl volat v~případě kdy je známá lokace a~název modulu až za běhu programu~\cite{PyDoc02}.

\subsubsection{Modul imp}
Modul \textbf{imp} nám poskytuje rozhraní pro importování modulů~\cite{PyDoc03}. Na rozdíl od předchozích dvou metod získáváme kontrolu nad konkrétním souborem modulu a~je proto možné vyhnout se zmiňované chybě s~překrýváním modulů se stejným názvem. Tato metoda importování je tudíž vhodná pro spuštění scriptů vygenerovaných pluginem.

\subsection{Kompilace a~\uv{Python Virtual Machine}}
Po nalezení souboru se zdrojovým kódem modulu,  shodujícího se s~import dotazem, Python, v~případě, že není dostupná nejaktuálnější zkompilovaná verze, zkompiluje tento kód do byte kódu. K~této kompilaci však dochází vždy pouze při importování modulu, což mimo jiné znamená, že k~jakýmkoliv změnám v~kódu modulu dojde při běhu programu, nebudou tyto změny akceptovány. Python byte kód je závislý na implementaci jeho interpretu, protože po kompilaci je byte kód předán \uv{Python Virtual Machine} (PMV) kterou je spuštěn. V~případě standardní implementace v~jazyce C~je PMV smyčka procházející a~spouštějící příkazy v~souboru v~Java implementaci interpretu je pak PMV totožná s~Java Virtual Machine~\cite{LearningPython01}.
\begin{figure}[h!]
\centering
\includegraphics[width=0.7\textwidth]{PythonExecutionModel}
\caption{Zdrojový kód je přeložen do byte kódu, který je spuštěn pomocí Python Virtual Machine}
\end{figure}

\subsection{Spuštění modulu}
Posledním krokem operace importu je spuštění nalezeného a~případně nově zkompilovaného modulu. Všechny výrazy souboru jsou provedeny v~pořadí udaném rozvržením v~souboru a~novém jmenném prostoru. V~průběhu tohoto kroku jsou vygenerovány všechny atributy výsledného objektu, které jeho zdrojový kód definuje~\cite{LearningPython01}. Je důležité si uvědomit, že jakékoliv příkazy které jsou umístěny \uv{na povrchu} (to jest příkazy bez odsazení) jsou provedeny, což může způsobit nechtěné chování při importování modulu. Výsledný objekt je uložen do slovníku \textbf{sys.modules}~\cite{Effbot01}.

\chapter{Metody návrhu knihoven}
V této kapitole jsou probrány významné otázky problematiky správného návrhu knihoven a~frameworků v~rámci jazyků platformy .NET. Správně navržená knihovna by měla být co nejjednodušší což umožní rychlé pochopení jejích základních způsobů použití a~její struktura by měla navádět programátora k~možnostem řešení složitějších úkonů. Další znaky takové knihovny jsou její opětovná použitelnost a~snadná rozšiřitelnost,  konzistence a~výkonnost. V~případě jazyků platformy .NET je také dobrou vlastností použitelnost knihovny v~co možná nejvíce těchto jazycích.
 
\section{Případy použití}
Jedním z~možných přístupů k~návrhu knihoven je návrh pomocí případů použití. Tyto případy lze rozdělit do dvou skupin podle jejich obtížnosti. Velká část vývoje knihoven se zabývá vývojem poměrně malé části, která je ale zodpovědná za většinu základních použití, tyto případy označme za hlavní případy užití a~budeme se jimi dále zabývat. Druhou skupinu tvoří pokročilé případy, kdy knihovna poskytuje své specializované funkce, ke kterým je však potřeba hlubší znalost problematiky uživatelem knihovny~\cite{FrameworkDesign01}.

\paragraph{}
Prvním krokem pro návrh knihovny je tedy specifikace hlavních případů užití. Součástí této specifikace by měl být i~kód, který představuje použití knihovny k~řešení daného problému. S~ohledem na knihovny používané více jazyky je dobré použít pro specifikaci také více jazyků, protože konkrétní volání prostředků knihovny se může lišit, pak je třeba dbát na konvence daného jazyka a~použít je tak, aby byl náš kód srozumitelný. Dalším požadavkem na tento ukázkový kód je jeho jednoduchost a~snadná pochopitelnost, má totiž představovat pouze velmi základní užití knihovny a~spíše má ukázat konvenci používání knihovny~\cite{FrameworkDesign01}.

\subsection{Objektový návrh}
Ukázkové kódy hlavních případů užití lze použít pro definování základního objektového návrhu, který pak může být rozšířen dalšími specializovanými funkcemi, které jsou využívány při obtížnějších úkonech. Tento návrh musí respektovat jistou sémantickou strukturu, to lze docílit správným rozdělením objektů do jmenných prostorů podle významu problému, který je jejich pomocí knihovnou řešen. Logickou strukturu knihovny pak určíme pomocí hloubky, kdy specializovanější funkcionalita bude umístěna hlouběji a~naopak k~řešení hlavních problémů budou použity základní jmenné prostory~\cite{FrameworkDesign01}.

\section{Implementační pravidla}
Nesmíme zapomínat na původní záměry návrhu, což jsou opětovná použitelnost a~snadná rozšiřitelnost. Chtěného stavu dosáhneme dodržováním různých implementačních pravidel. Tato pravidla se týkají způsobu používání výjimek, událostí, datových typů, objektů a~jejich vlastností i~jmenných konvencí.

\paragraph{}
Důležitým faktorem těchto pravidel je snaha o~sebe dokumentaci knihoven. To jest jak uzpůsobení názvů tak i~způsob použití výjimek, událostí i~návratových hodnot různých metod tak, aby programátor měl možnost naučit se práci s~knihovnou pomocí experimentálního přístupu.

\subsection{Výjimky}
V kontextu knihoven a~frameworků jsou výjimky používány nejen k~oznámení chyb ve výpočtu, ale nabývá na významu jejich komunikační potenciál, jsou proto používaným prostředkem sebe dokumentace a~způsobem pro vedení dialogu s~uživatelem pokud je daný prvek knihovny nevhodně či špatně použit (například pokud se nějakým zásahem do hodnot objektu stane daný objekt nekonzistentní, což by mohlo vést k~nemožnosti dodat správný výsledek, je použita výjimka, která popíše, kde přesně došlo k~porušení konzistence objektu). Z~toho vyplývá, že výjimky musejí být pokud možno velmi specifické (svými vlastnostmi, popisem i~typem) tak, aby bylo snadno pochopitelné co je třeba udělat pro zbavení se problému~\cite{FrameworkDesign01}.

\paragraph{}
Výjimky by měly v~knihovně ošetřovat veškeré možné problémy, které mohou nastat v~jejích veřejných metodách, toto zajistí lepší lokalizovatelnost problému, ze stejného důvodu je pak třeba výjimky dobře dokumentovat. Pro specifické potíže knihovny je mnohdy vhodné vytvořit vlastní typ výjimky, kterým bude problém snadno identifikovatelný.

\subsubsection{Tester - Doer vzor}
V jistých případech může být výkon metody vyhazující výjimku zvýšen pomocí tohoto vzoru. Pokud se jedná o~metodu, potenciálně může být volána často. Jde o~rozdělení na dva členy, jeden z~nich obsahuje výkonnou část kódu, která vyvolává výjimky a~nazývá se \textbf{Doer} (muž činu) a~druhý z~nich \textbf{Tester} se stará o~připuštění k~muži činu jen pokud jsou splněny takové podmínky, při kterých k~vyvolání výjimky nedojde~\cite{FrameworkDesign01}.
 
\subsubsection{Try - Parse vzor}
Druhým vzorem pro výkonnostně citlivé části knihovny je takzvaný Try - Parse vzor, jedná se o~metodu, která na místo vyvolání výjimky vrací jakou svou návratovou hodnotu příznak (z pravidla typu \textbf{Boolean}), zda byl kód proveden úspěšně či ne~\cite{FrameworkDesign01}.

\subsection{Výčty}
Výčtový typ \textbf{enum} je speciálním hodnotovým typem, který representuje nějakou množinu hodnot. Z~pohledu vývojáře knihovny jsou výhodné především pro svou vypovídající funkci, lze jimi nahradit často nic neříkající konstanty či parametry volání funkcí tak, aby programátor mohl tušit, co daný parametr ovlivní, aniž by přečetl textovou dokumentaci funkce. Výčet tedy může pomoci se sebe dokumentací knihovny~\cite{FrameworkDesign01}.

\subsection{Třídy}
Třídy jsou základním stavebním kamenem jakéhokoliv objektového návrhu. Především pro svou schopnost modelovat skutečné objekty. Konstruktory, metody a~indexované vlastnosti tříd je možno přetížit. Přetížení je jednou ze základních možností jak zvýšit produktivitu a~použitelnost. Pro zvýšení srozumitelnosti přetížení je používat vhodná pojmenování a~konzistentní pořadí parametrů. Pokud chceme umožnit rozšíření daného člena třídy je nejlepší praktikou určit k~přepsání až nejdelší přetížení, na které se odvolávají přetížení kratší. Při psaní knihovny použitelné více jazyky je důležité dbát na typ parametrů, při přetěžování nemůžeme spoléhat na existenci rozdílnosti datových typů, protože knihovna může být volána například dynamicky typovaným jazykem, kde rozdíl nemusí existovat~\cite{FrameworkDesign01}.  

\subsubsection{Vlastnosti}
I když technicky jsou vlastnosti a~metody velmi podobné existuje poměrně silný rozdíl v~případech jejich užití. Zatímco metody představují jistou akci, která se má provést vlastnosti symbolizují data. V~otázce, zda zvolit metodu nebo vlastnost je třeba podívat se právě na tento rozdíl, jak jsou tyto odlišní členové třídy chápáni. Pokud je kladen velký důraz na metody, je potom jejich volání často velmi složité ve vztahu k~počtu parametrů, vlastnosti, které nastavují příslušný stav objektu pro provedení stejné akce, mohou zmenšit počet parametrů metody a~tím programátorovi zjednodušit přístup k~požadované funkcionalitě~\cite{FrameworkDesign01}.

\paragraph{}
Z výše zmíněných důvodů je důležité poskytovat jisté standardní hodnoty vlastností v~případě jejich nenastavení. Naopak však povolit změny hodnot vlastností, i~pokud vedou k~dočasnému nekonzistentnímu stavu objektu. Na takový nepřípustný stav je pak ovšem nutné upozornit uživatele knihovny vyvoláním výjimky.

\subsubsection{Konstruktory}
Konstruktory jsou nejčastějším způsobem vytvoření nového objektu, jelikož mohou být takto velmi často vyhledávány a~volány, je dobré pokusit se vytvářet pokud možno jednoduché konstruktory, jejichž parametry tvoří základní datové typy. Jejich přetížením můžeme poskytnout jednoduchou cestu k~iniciálnímu nastavení vlastností objektu, potom je pro lepší přehlednost však vhodné pojmenovat parametry konstruktoru podle vlastností, které nastavují~\cite{FrameworkDesign01}.

\paragraph{}
Jelikož se konstruktor objektu volá pokaždé, je-li vytvářen objekt, neměl by obsahovat žádnou další funkcionalitu, zvláště pokud chceme objekty daného typu rychle vytvářet ve velkém množství jak je tomu často u~struktur. Stejně tak by konstruktor neměl volat metody, které mohou být přepsány v~dceřiném objektu, kdy může dojít nechtěným následkům.

\subsubsection{Události}
Události jsou nejčastější formou poskytování zpětné vazby, událost je vlastnost typu delegát a~dvě obslužné metody. Uživatel se může přihlásit k~odběru, pokud dodá metodu, která obslouží danou událost. Každá událost si s~sebou nese své argumenty, což jsou typicky dceřiné objekty typu \textbf{EventArgs}. Pokud knihovna obsahuje třídu, která vytváří nějaké události, pak tyto by měly být volány pouze z~kontextu dané třídy případně tříd dceřiných~\cite{FrameworkDesign01}.

\subsubsection{Rozšiřující metody}
Rozšiřující metody jsou schopností programovacího jazyka volat statické metody pomocí \uv{tečkové} syntaxe volání metod. Tyto statické metody musejí být volány nejméně s~jedním parametrem označující \uv{sponzorskou} třídu. Pro použití rozšiřující metody pak musí programátor importovat jmenný prostor, kde je statická metoda definována. Rozšiřující metody by měly být užívány s~mírou, protože mohou existovat jazyky používající knihovnu nemající možnost volat tyto metody jinak než standardně jako všechny ostatní statické metody. Z~toho vyplývá, že statické metody by měly být umístěny pokud možno ve vlastním jmenném prostoru, který bude indikovat jaké funkcionalitu těchto metod. Rozšiřující metody jsou vhodné především pro implementaci pomocných metod ke skupině objektů definovaných náležitostí k~nějaké rodičovské třídě či rozhraní~\cite{FrameworkDesign01}.

\subsubsection{Třídy a~struktury}
Jedním z~problémů návrhu každého frameworku je rozhodnutí o~použití třídy (referenční typ) a~struktury (hodnotový typ) pro modelování dané situace. Důležitým faktorem při tomto rozhodnutí je právě jejich typ a~jeho zpracování. Referenční typy jsou skladovány na haldě. Jejich zahazování je řízeno garbage collectorem, kdežto hodnotové typy jsou typicky alokovány na zásobníku a~dealokovány jeho uvolněním. Tudíž alokace a~dealokace hodnotových typů je obecně levnější operace, než je tomu u~referenčních typů~\cite{FrameworkDesign01}. Dalším rozdílem je chování při operacích jako kopírování či přiřazení. U~hodnotových typů totiž dochází ke kopírování celé hodnoty v~paměti, kdežto u~referenčních typů dojde jenom k~předání odkazu na místo, kde je hodnota uložena. Z~toho vyplývá pravidlo, že struktury by měly být používány v~případě, že dané objekty jsou zpravidla součástí nějakého většího objektu či jsou často vytvářeny a~zahazovány.

\subsubsection{Třídy a~rozhraní}
K dalšímu obdobnému rozhodnutí zda použít třídu, může dojít v~případě modelování abstrakce. Zde je potom otázkou jestli vybrat třídu nebo rozhraní. Hlavním problémem využití rozhraní k~abstrakci je jejich malá flexibilita. Jednou vytvořené rozhraní již nelze změnit, aniž bychom museli udělat změny ve všech třídách, které dané rozhraní implementují. Jinou možností je pak vytvořit další rozšiřující rozhraní, což ale může vést naopak ke změnám v~částech kódu, které pracovaly s~původním rozhraním. Řešení tohoto problému přinášejí třídy, které jsou flexibilnější a~navíc hlavní výhoda rozhraní, což je oddělení kontraktu od implementace, je nahraditelná vhodným použitím abstraktních tříd. I~tak je však dobré rozhraní používat, zejména ve chvílích, kdy potřebujeme modelovat složitou dědičnost či vytvořit kontrakt nad hodnotovými typy, které již dědí své vlastnosti z~jiné třídy~\cite{FrameworkDesign01}.

\subsection{Kolekce}
.NET Framework 2.0 představil pojem generik. V~.NET Frameworku 1.x, většina tříd kolekcí ukládala reference na \textbf{System.Object}. To znamenalo, že při každém pokusu o~získání položky kolekce bylo třeba položku přetypovat na její originální typ. Toto mělo za následek zhoršení výkonnosti, například při ukládání hodnotových typů, které bylo třeba při vkládání do kolekce obalit referenčním typem a~při odebírání z~kolekce je opět rozbalovat. Používáním typů generických kolekcí je možno tyto nedostatky odstranit.

\subsubsection{Výkonnostní implikace}
Obsáhlé kolekce mohou mít vliv na výkon aplikace, je proto třeba dbát na volbu správného typu kolekce. Důležitým faktorem pro výběr kolekce je způsob jakým chceme s~kolekcí pracovat. Pokud je potřeba velmi rychle přidávat, odebírat a~vyhledávat položky a~zároveň není kladen důraz na pořadí položek v~kolekci je vhodnou volbou třída \textbf{System.Collections.Generic.Dictionary<TKey, TValue>}. Její tři základní operace vkládání, odebírání a~vyhledávání jsou velmi rychlé, i~pokud obsahuje velké množství položek.

\paragraph{}
Na druhé straně třídám \textbf{List<T>, ArrayList<T>}, mohou operace vkládání a~odebírání trvat rozdílnou dobu. Je to způsobeno udržováním pořadí položek těchto kolekcí, kdy například přidávání položky do středu seznamu znamená posunout Všechny položky za tímto místem, přidání položky na konec seznamu nebude vyžadovat posouvání jiných položek a~bude rychlejší.

\paragraph{}
Použití třídy \textbf{LinkedList<T>} může potenciálně pomoci, pokud je třeba udržovat pořadí elementů a~zároveň je nutné rychle vkládat a~vybírat položky. Na rozdíl od kolekce \textbf{List<T>} je Linkedist<T> implementován jako řetěz dynamicky alokovaných objektů. Pro srovnání s~\textbf{List<T>}, vložení objektu do středu kolekce způsobí změnu jen ve dvou sousedících položkách. Nevýhodou z~pohledu výkonu tohoto typu kolekce je zvýšení aktivity \textbf{garbage collectoru}, který nesmí objekty této kolekce smazat.

\subsubsection{Vlastní kolekce}
V některých situacích se může vyskytnout potřeba vytvoření vlastního typu kolekce, pokud typy .NET frameworku nedostačují potřebě. Jednou z~možností je pak odvození vlastní nové kolekce od třídy \textbf{System.Collections.ObjectModel.Collection}, to má však nevýhodu dědění nevlastní třídy, kdy může dojít ke změně implementace této třídy a~k následným nežádoucím efektům na naši kolekci. Druhou možností je použití rozšiřujících metod, toto je však aplikovatelné pouze pokud chceme přidávat metody k~existujícím objektům, nikoliv pro odebírání metod nebo redefinici metod objektu vlastních. Třetí možností a~pro knihovny pravděpodobně nejefektivnější metodou je implementace rozhraní \textbf{IEnumerable, ICollection, IList} či jejich generických protějšků \textbf{IEnumerable<T>, ICollection<T>, IList<T>}.

\paragraph{IEnumerable}
Toto rozhraní procházení kolekce, zavádí totiž jedinou metodu \textbf{GetEnumerator}, která vrací \textbf{IEnumerator} objekt. Každá kolekce implementující toto rozhraní může pak být procházena pomocí jazykové struktury \textbf{foreach} jazyka C\#.

\paragraph{ICollection} 
Rozšíření rozhraní \textbf{IEnumerable}. Navíc přidává vlastnosti a~jednu další metodu. \textbf{Count} je vlastnost udávající počet položek v~kolekci. \textbf{IsSynchronized} indikuje, zda je kolekce vláknově bezpečná dodáním objektu, který může tuto vlastnost zajistit. Metoda \textbf{CopyTo} dodává funkcionalitu zkopírování položek kolekce od určité pozice do pole. Pro své vlastnosti je toto rozhraní využito vytvořenými nástroji pro implementaci klíčových kolekcí.

\paragraph{IList} 
Rozšiřuje rozhraní \textbf{ICollection}. Ke všemu co dodává rozhraní \textbf{ICollection} má navíc metody \textbf{IndexOf, Insert, RemoveAt} a~indexer, který umožňuje přístup k~položkám \textbf{IListu} jako k~položkám pole. Rozhraní také dodává metody \textbf{Add, Remove, Clear, Contains}. \textbf{IList} je proto velmi vhodným rozhraním k~implementaci vlastích kolekcí, které umožňují přidávání a~odebírání položek jak podle jejich polohy tak bez ní~\cite{Msdn03}.

\section{Rozšiřitelnost}
Důležitým aspektem vývoje knihoven je jejich pozdější rozšiřitelnost. Dobře navržené knihovny dbající o~možnosti rozšíření a~zabývající se jeho cenou a~výhodami mohou nejen přispět k~vývoji ve chvíli, kdy vzniknou, ale i~později. Je tedy opodstatněné zabývat se hlouběji mechanismy jako dědičnost, virtuální metody, události a~zpětná volání. Tyto mechanismy mají většinou tu vlastnost, že je snadnější je přidávat, než později odebírat, protože často pak dochází k~problémům v~návazných systémech, které s~daným mechanismem pracovaly.

\subsection{Nezapečetěné třídy}
Každá třída může být zapečetěná (klíčové slovo \textbf{sealed}) či nezapečetěná. Zapečetěné třídy nemohou být děděny, naopak nezapečetěné třídy děděny být mohou a~jejich dceřiné třídy mohou přidávat novu funkcionalitu pomocí vlastností, metod, užíváním jejích chráněných (\textbf{protected}) členů či přepisováním členů virtuálních (klíčové slovo \textbf{virtual}). Chránění a~virtuální členové tříd jsou však často předmětem zájmu metod rodičovské třídy a~jejich změny, pokud nejsou dobře ošetřeny, mohou být problémové. Levným a~efektivním způsobem podpory rozšiřitelnosti jsou tedy nezapečetěné třídy bez virtuálních a~chráněných členů~\cite{FrameworkDesign01}.

\subsubsection{Chránění členové}
Chránění členové poskytují značnou podporu při dědění tříd, mohou poskytovat přístup k~méně triviálnímu nastavení třídy. Je však třeba dbát na ochranu, jelikož k~chráněným členům smí přistoupit všechny dceřiné třídy, je třeba přistupovat k~nim z~hlediska bezpečnosti i~dokumentace jako ke členům veřejným.

\subsubsection{Virtuální členové}
Virtuální členové umožňují pomocí dědění měnit chování třídy, tím jsou poměrně podobné událostem, ale s~rozdílem, že modifikace chování virtuálních členů je možná jen při kompilaci. Jejich výhodou je oproti událostem vyšší výkonnost. Virtuální členy je dobré používat v~případech, kdy se nám jedná a~možnosti rozšíření určitým směrem, je proto vhodné označit je za chráněné a~ne veřejné a~případné chtěné změny ve veřejných členech třídy zpřístupnit pomocí chráněného virtuálního člena~\cite{FrameworkDesign01}.

\subsection{Události a~zpětná volání}
Zpětná volání umožňují knihovnám volat delegáty funkcí uživatelského kódu skrze delegáty. Ve srovnání s~virtuálními členy poskytují zpětná volání možnost rozšiřování knihovny přímo při běhu, ne při kompilaci. Nevýhodou událostí je však jejich nižší výkonnost, kdy volání delegátu metody je náročnější akcí než volání virtuální metody~\cite{FrameworkDesign01}.

\section{Atributy sestavy}
Všechny datové typy jsou součástí sestav (\textbf{assembly}), které jsou běžně baleny do souborů typu \textbf{.dll} nebo spustitelných souborů (\textbf{.exe}). Tyto sestavy mohou mít různé atributy, jsou to například:

\subsection{CLSCompilant}
Sestavy, které obsahují nějaký veřejný typ, by měly mít tento atribut nastavený na true (\textbf{[assembly:CLSCompilant(true)]}), pokud tak chtějí deklarovat, že typy, které jsou v~nich obsaženy jsou použitelné všemi jazyky .NET platformy. Některé z~těchto jazyků (například jazyk C\#) jsou schopny pak takovéto sestavy porovnávat se standardy~\cite{FrameworkDesign01}.

\subsection{Identifikační atributy}
Mezi tyto atributy patří například: \textbf{AssemblyDescription, AssemblyTitle, AssemblyProduct}. Tyto atributy nějakým způsobem identifikují sestavu a~mohou programátorovi pomoci například při výběru verze sestavy~\cite{Msdn01}. Hodnota atributu \textbf{AssemblyVersion} je používána CLR (common language runetime) k~vazebným operacím v~silně pojmenovaných sestavách (sestavy s~globálně jedinečným identifikátorem~\cite{Msdn02}).

\part{Implementace}

\setcounter{chapter}{0}
\chapter{Budování PyMOL skriptů}
Řešení problému tvorby pluginů pro program PyMOL stojí na implementaci dvou datových toků, na kterých jsou tyto pluginy založeny. Směr prvního z~nich je od programu nabízejícího novou funkcionalitu (v případě prvního řešeného pluginu tedy spustitelný soubor MOLE pluginu), který vytváří data, k~programu PyMOL, který je využíván pro zobrazení těchto dat. Tento směr je tedy převážně založen na transformaci dat získaných výpočtem na uživateli srozumitelný výstup programu PyMOL. Řešení tohoto směru představuje knihovna \textbf{PyMOLBuilder}.

\section{Návrh}
Návrh knihovny PyMOLBuilder se opírá především o~hlavní scénáře jejího užití. Program vznikal jako knihovna poskytující možnosti transformace výstupních programu \textbf{TunnelsServer}, který je součástí implementovaného \textbf{MOLE 2.0} pluginu (MOLE 2.0 je univerzální nástroj pro rychlou a~plně automatizovanou lokalizaci kanálů, tunelů a~pórů v~makromolekulárních strukturách.) a~to právě reflektuje diagram užití, který tyto hlavní scénáře zachycuje. Nicméně cílem knihovny PyMOLBuilder není poskytovat podporu pro jeden program, ale pro škálu programů, pro podporu snadné tvorby rozšíření bylo tedy využito výše popsané techniky metod návrhu knihoven, kdy jsou jednotlivé případy užití doprovázeny názornými příklady použití nástrojů knihovny v~jazyce C\# a~na základě jejich implementace je pak vybudován objektový model. Kompletní znění dokumentu popisujícího hlavní případy užití knihovny PyMOLBuilder je možno nalézt v~přílohách k~této práci.
 
\begin{figure}[h!]
\centering
\includegraphics[width=0.5\textwidth]{MainScenariosPyMOLBuilder}
\caption{Hlavní scénáře užití programu PyMOLBuilder}
\end{figure}

Jak je patrné z~následujícího diagramu, objekty, jež byly přímo implikovány ve scénářích užití knihovny, jsou převážně obsaženy pouze v~jedné její podčásti (\textbf{PyMOLBuilder.Data}). Tyto objekty pokrývají potřebu representace dat pro plugin \textbf{MOLE 2}, ale i~obecnou potřebu získávání dat ze souborů, či definici způsobu transformace. V~obecnějších jmenných prostorech pak knihovna obsahuje nástroje, které umožňují vytváření vlastních representací dat dle potřeby konkrétního pluginu a~nástroje pro práci s~generovaným Python kódem.

\begin{figure}[h!]
\centering
\includegraphics[width=1.0\textwidth]{ObjectModel2}
\caption{Diagram tříd knihovny}
\end{figure}

\section{Implementace}
Knihovna je rozčleněna do tří jmenných prostorů, mimo již zmíněného \textbf{PyMOLBuilder.Data} lze pak na diagramu nalézt jmenný prostor \textbf{PyMOLBuilder.Components} a~v něm vnořený \textbf{PyMOLBuilder.Components.GUI}. Tyto dva prostory obsahují objektové typy, které popisují soubory obsahující kod v~jazyce Python, který je srozumitelný aplikaci PyMOL, kterou obecně využívá k~zobrazení dat.

\subsection{PyMOLRunnable}
Abstraktní třída \textbf{PyMOLRunnable} representuje jakýkoliv obecný soubor se zdrojovým kódem v~jazyce Python, jeho vlastnosti \textit{Dependencies} a~\textit{Representation} obsahují jednotlivé řádky tohoto kódu. Vlastnost \textit{Dependencies} obsahuje deklarace importování modulů užívaných programem, k~jasné přehlednosti je využit typ \textbf{HashSet<string>}, který zaručí jedinečnost objektů, jež obsahuje. Vlastnost \textit{Component} je typu \textbf{ComponentColelction} a~obsahuje pojmenované programové celky, s~vlastním jménem. Metody \textit{Compile} a~\textit{SaveToFile} jsou poté využity pro zajištění správného pojmenování jednotlivých komponent objektu a~následného uložení zdrojového kódu do souboru. 

\paragraph{}
Dceřiné typy této třídy jsou pak používány pro vytváření skriptů spustitelných programem PyMOL. Například typ \textbf{PyMOLScript} přidává na konec své representace volání všech objektů ve své vlastnosti \textit{Components}. Toto je výhodná vlastnost pro skripty mající za cíl čisté zobrazení dat (například tunelů uvnitř molekuly), naopak nevhodná pro skripty vytvářející uživatelská rozhraní.

\subsubsection{PythonVersion}
Výčet \textbf{PythonVersion} reflektuje možnost generování výstupního kódu dle verze cílové verze jazyka, objekty typu \textbf{PythonComponent} či \textbf{PyMOLRunnable} mají pak vlastnosti tohoto typu a~mohou se řídit jejich hodnotou a~poskytovat možnost vytvářet skripty reflektující požadovanou verzi.

\subsubsection{ComponentCollection}
Typ \textbf{ComponentCollection} implementuje rozhraní \textbf{ICollection<PythonComponent>}, a~nabízí možnost správy komponent do něj vložených. Každý objekt, který je přidán do této kolekce, je interně přejmenován tak, aby nedocházelo k~duplikaci identifikátorů. Toto zaručuje možnou koexistenci dvou uživatelem stejně pojmenovaných komponent přidaných do jednoho objektu typu \textbf{PyMOLRunnable} tak, aniž by se vzájemně ovlivňovali.

\subsection{PythonComponent}
Typ \textbf{PythonComponent} representuje programový celek v~jazyce Python (například funkci), který má identifikátor (\textit{Name}), v~jeho \textit{Representaci} se může vyskytnout použití nějakého modulu, který je nutno importovat (vlastnost \textit{Dependencies}) a~tuto representaci je možné zkompilovat (methoda \textit{Compile}) jako součást nějakého Python scriptu.

\subsection{PythonRepresentation}
Representaci nějakého objektu, dat či C\# kodu představuje právě tento typ. Typ \textbf{PythonRepresentation} je implementací rozhraní \textbf{ICollection<string>} a~umožnuje práci s~jednotlivými řádky Python kódu. Jelikož je kód v~jazyce Python syntakticky závislý na svém odsazení od levého okraje, umožnuje také tato kolekce přidávat řádky, které mají být v~konečném textu odsazeny. Její metoda \textit{AddIndentRange} pak nabízí možnost přidání celého odsazeného bloku textu. Tento typ je využíván jak knihovnou \textbf{PyMOLBuilder}, tak programem \textbf{PyMOLPluginCompiler} a~umožnuje tedy využití všech typů definovaných v~těchto dvou programech k~vytváření Python scriptů.

\chapter{Kompilátor PyMOL pluginů}
Směr druhého datového toku, na kterém je založeno řešení problému tvorby pluginů pro program PyMOL je od uživatele programu PyMOL, který předkládá své požadavky programu, k~programu skutečně poskytujícímu novou funkcionalitu. Zde je tedy předmětem vytvářet rozšíření uživatelského prostředí programu PyMOL, která jsou schopna transformovat uživatelské vstupy na informace, kterým rozumí rozšiřující program. Implementaci tohoto řešení pak představuje \textbf{PyMOLPluginCompiler}

\section{Návrh}
Návrh programu \textbf{PyMOLPluginCompiler} je opět vytvořen na základě hlavních scénářů užití programu. Ústředním pilířem je případ požadavku transformace vstupního C\# kódu na Python kód, další požadavky jsou pak s~pjaty s~psaním vlastního C\# kódu, kdy uživatel (v tomto případě programátor) chce použít již existující representaci nějakého kódu (například volání knihovní nějaké funkce obsažené v~existující Python knihovně), či vytvořit vlastní objekt s~representací, který bude moci použít. Kompletní znění dokumentu popisujícího hlavní případy užití nástroje PyMOLPluginCompiler je možno nalézt v~přílohách k~této práci.

\begin{figure}[h!]
\centering
\includegraphics[width=0.5\textwidth]{MainScenariosPythonCompiler}
\caption{Hlavní scénáře užití}
\end{figure}

Je zřejmé, že scénáře užití programu lze rozdělit na dva typy, první typ se vždy zabývá finálním překladem kódu, druhý pak tvorbou kódu, jenž má být přeložen. Tento rozdíl je viditelný v~diagramu tříd tvořících základní objektový model programu.

\begin{figure}[h!]
\centering
\includegraphics[width=1.1\textwidth]{ObjectModel}
\caption{Diagram tříd knihovny a~spustitelného souboru kompilátoru}
\end{figure}

\section{Implementace}
Řešení je rozděleno do dvou částí, spustitelný soubor kompilátoru, který provádí analýzu vstupního kodu a~jeho transformaci za využití projektu Roslyn. Druhou částí je pak knihovna podporující tvorbu programů v~jazyce C\# , které si kladou za cíl využívat prostředky knihoven jazyku Python či funkcí programu PyMOL.

\section{Program kompilátoru}
Vstupní metodou programu je metoda objektu \textbf{PluginBuilder}. Tato metoda provede vytvoření kompilace ze vstupního souboru a~zisk jejího sémantického modelu a~syntaktického stromu. Tyto struktury jsou následně předány objektu \textbf{PythonRewriter}, který provádí jejich transformaci na objekt typu \textbf{PythonRepresentation}, což je typ knihovny \textbf{PyMOLBuilder}. Na závěr je Python representace vstupního kódu zapsána do výstupního souboru.

\subsection{PythonRewriter}
Centrálním bodem implementace spustitelného programu je objekt \textbf{PythonReWriter}, tento objekt má pouze jednu metodu a~tou je metoda \textit{Visit}, jejím vstupem je pak sémantický model získaný z~kompilace vstupního souboru programu pomocí služby projektu Roslyn. Metoda prochází syntaktický strom asociovaný se vstupním modelem pomocí objektu typu \textbf{ClassWalker}, tento pak má za cíl nalézt všechny deklarace tříd ve vstupním souboru a~následně rozebrat podstromy reprezentující syntaktický obsah těchto tříd. Typ \textbf{ClassWalker} je odvozen od typu knihovny Roslyn \textbf{SyntaxWalker}, který prochází všechny uzly daného typu ve vstupním syntaktickém stromu. Potomci těchto uzlů (v našem případě uzlů s~deklarací tříd) mohou být následně procházeny objekty typu \textbf{SyntaxVisitor<T>}, které mohou provádět jejich transformaci. V~programu \textbf{PyMOLPluginCompiler} jsou pak tito \uv{návštěvníci} rozčleněni podle typu uzlů které mohou navštívit do typů: \textbf{MemberRewriter, StatementRewriter, ExpressionRewriter}.

\subsubsection{MemberRewriter}
Provádí analýzu uzlů, jež jsou potomky uzlu s~deklarací třídy, jedná se o~uzly typu: \textbf{MethodDeclaration, FieldDeclaration, ConstructorDeclaration}. Metody procházející syntaxi těchto uzlů transformují samotnou syntaxi deklarace těchto členů a~dále procházejí dceřiné uzly obsažené v~těle členů tříd pomocí objektu typu \textbf{StatementRewriter}.

\subsubsection{StatementRewriter}
Transformuje syntaxi tvrzení jazyka C\# do objektů typu \textbf{PythonRepresentation}, z~hlediska projektu Roslyn jsou procházeny následující uzly syntaktického stromu: \textbf{ExpressionStatementSyntax, ForEachStatementSyntax, IfStatementSyntax, WhileStatementSyntax, TryStatementSyntax} a~další. \textbf{StatementRewriter} provádí transformaci klíčových slov těchto tvrzení a~následně pomocí objektu typu \textbf{ExpressionRewriter} provádí transformaci obsažených výrazů.

\subsubsection{ExpressionRewriter}
Provádí finální transformaci uzlů stromu obsahující výrazy na sémantické ekvivalenty v~jazyce Python, jedná se o~uzly typu: \textbf{MemberAccessExpressionSyntax, InvocationExpressionSyntax, BinaryExpressionSyntax, LiteralExpressionSyntax, SimpleLambdaExpressionSyntax} a~další. Díky značné výrazové podobnosti jazyků C\# a~Python je tato transformace především kontrolou příslušnosti volaných metod k~objektům, transformace některých klíčových slov či změna znaků operací. Další vlastností těchto objektů je pak rozpoznání příslušnosti členů tříd a~možná odlišná reakce na volání metody různých typů.

\section{Knihovna modulů}
Knihovna \textbf{PyMOLPluginCompiler.Utils} nabízí možnost definice vlastní Python representace metodám, třídám, či jiným programovým strukturám a~zároveň používání takových struktur s~již definovanou representací ve vlastním C\# kódu. K~tomu využívá objekty, jež jsou potomky třídy \textbf{System.Attribute}, které jsou využívány k~přidávání vlastích atributů. PyMOLPluginCompiler je pak schopen rozpoznávat tyto vlastní atributy a~na místo, kde je programová struktura s~vlastním atributem umístit vlastní representaci danou atributem.

\paragraph{}
K umožnění vytváření vlastních \uv{knihoven} s~programovými strukturami je součástí knihovny \textbf{PyMOLPluginCompiler.Utils} typ \textbf{Store}, který představuje atribut používaný k~označení tříd obsahující nějaké struktury s~vlastní representací. Při spuštění transformace kódu programem PyMOLPluginCompiler je pak možno mu předat na vstup i~soubor se sestavou obsahující vlastní třídy označené atributem \textbf{Store}, program PyMOLPluginCompiler poté provede jejich analýzu a~pokud nalezne použití vlastní \uv{knihovny} použije i~její vlastní representaci. Knihovnu lze také využít ve spojení s~PyMOLPluginCompilerem pro vytváření Python modulů, které mohou programátorovi pluginů sloužit ke zjednodušení přístupu ke knihovním funkcím Pythonu, příkladem je typ \textbf{GUI}, který je definován jako sada statických metod, sloužících jako \textit{factory} metody pro vytváření grafického uživatelského rozhraní.

\part{Výsledky a~diskuse}

\setcounter{chapter}{0}
\chapter{Vytvořené pluginy a~možnosti rozšíření}
Schopnosti a~funkčnost výsledných nástrojů pro tvorbu pluginů rozšiřujících program PyMOL, \textbf{PyMOLBuilder} a~\textbf{PyMOLPluginCompiler} jsou demonstrovány na dvou konkrétních pluginech, těmito pluginy jsou \textbf{MOLE 2.0} a~\textbf{Motive Explorer}. Oba dva jsou typickým předmětem představujícím potřebu pro rozšíření funkcionality programu PyMOL, umožnují totiž vznášet nové dotazy na jistou makromolekulární strukturu, které nejsou podporovány standardní verzí programu PyMOL. Jejich dalším společným rysem je obalení výpočtové funkcionality externích programů, kterým plugin předá dotazy na molekulu zformulovány jako vstupní parametry pro výpočet pomocí souborů XML, a~následně čeká na jejich výstup, který má formu přijatelnou programem PyMOL a~může být zobrazen uživateli. Vzhledem ke značné komplexnosti demonstračních případů byl vytvořen dokument ukazující základní případy použití vytvořených nástrojů, tento dokument je dostupný coby příloha této práce.

\section{MOLE 2.0}
Aplikace MOLE 2.0 je univerzální nástroj pro rychlou a~plně automatizovanou lokalizaci a~charakterizaci kanálů, tunelů a~pórů v~makromolekulárních strukturách, je následovníkem programu MOLE~\cite{Mole}. Plugin MOLE 2.0 pak poskytuje rozhraní pro tuto aplikaci v~rámci programu PyMOL, jednak vytvořením grafického uživatelského rozhraní, ale také umožněním graficky representovat data získaná výpočtem aplikace MOLE 2.0 vizualizačními nástroji programu PyMOL.

\paragraph{}
Jeho implementaci lze rozdělit na čtyři okruhy:
\begin{enumerate}
\item Vytvoření uživatelského rozhraní, který je řešen využitím Python modulů \textbf{Tkinter} a~\textbf{Pmw}, které umožňují tvorbu grafických uživatelských rozhraní v~jazyce Python. Toto definované rozhraní pak musí kontrolovat uživatelský vstup, tak aby byl validní podle možností aplikace, a~zároveň musí umožnit plnou podporu všech jejích funkcí.
\item Vytvoření souboru XML s~parametry dotazů uživatele.
\item Spuštění aplikace MOLE 2.0. Tento problém v~sobě skýtá aspekt spuštění samostatného procesu aplikace a~monitorování jeho průběhu, tak aby bylo uživatelské rozhraní schopno reagovat na jeho dokončení.
\item Zisk výstupu aplikace MOLE 2.0 a~jeho zobrazení uživateli. Aplikace MOLE využívá k~vytváření výstupu knihovnu \textbf{PyMOLBuilder} a~zobrazení výstupu uživateli tedy znamená pouze import vygenerovaného Python scriptu. Samotný původní výstup aplikace je XML soubor obsahující definice tunelů v~molekule, zapsané jako sled bodů v~prostoru. Každý takový bod má pak určen poloměr udávající šířku dutiny tunelu. Pomocí knihovny PyMOLBuilder je pak tento XML soubor rozebrán a~body definovány jako centra atomu o~určitém poloměru vytvořením dceřiného typu třídy \textbf{Vertex}. Výsledný tunel je v~aplikaci PyMOL zobrazen jako isoplocha struktury vzniklé spojením těchto atomů.
\end{enumerate}

\begin{figure}[h!]
\centering
\includegraphics[width=1.0\textwidth]{Mole}
\caption{Tunely nalezené v~molekule bílkoviny 1TQN pomocí pluginu MOLE 2.}
\end{figure}

\section{Motive Explorer}
Aplikace MotiveExporer slouží k~prohledávání motivů v~proteinech, za pomocí výrazů specifikujících molekulární struktury. K~tvorbě těchto výrazů je použit jazyk \textit{Motive Query}. Stejně jako u~pluginu MOLE 2 lze jeho implementaci rozložit na stejné čtyři okruhy problémů a~struktura programu je tedy velmi podobná. Zkušenosti s~implementací předchozího pluginu rovněž vedly ke snaze opravit problém, jež představuje časté využívání Python modulů pro tvorbu pluginu pomocí jazyka C\#.

\begin{figure}[h!]
\centering
\includegraphics[width=1.0\textwidth]{MotiveExplorer}
\caption{Motivy nalezené v~bílkovině 1GZT.}
\end{figure}

\paragraph{}
První změnou byl převod vstupních a~výstupních parametrů vytvořených metod dovolujících využití Python modulů na typ \textit{dynamic}. Tento typ je sice statický, ale objekt tohoto typu dynamicky překonává statické typové kontroly. Při kompilaci se u~elementu, který je typem \textit{dynamic}, předpokládá podpora pro volání jakékoliv operace~\cite{Msdn05}. Z~hlediska programátora pluginu pak s~proměnnými typu \textit{dynamic}, k~jejímu vytvoření je třeba knihovního modulu, může pracovat stejným způsobem jako v~jazyce Python. Dalším příspěvkem spojeným s~typem dynamic je definice třídy \textbf{PluginBase}, která definuje dynamickou vlastnost \textit{Fields}. Použitím této vlastnosti je programátor nyní schopen emulovat dynamičnost definice objektů Pythonu, kdy nové vlastnosti objektů mohou být poprvé definovány až při průběhu nějaké metody a~nemusejí být definovány (tak jak v~jazyce C\#) mimo metody. S~minimalizací využívání Python modulů kódem pluginu se pojí snaha o~zapouzdření volání těchto metod, proto byl do \textbf{PyMOLPluginCompileru} přidán v~předcházející kapitole již zmiňovaný typ \textbf{GUI}.

\paragraph{}
Na následujícím příkladu jasně viditelný výsledný rozdíl, kterých se změnou v~reakci na získané zkušenosti s~tvorbou pluginů dosáhlo. První část ukazuje vytvoření okna pluginu MOLE 2, definici událostí a~tvorbu prvků okna. Druhá část pak vytvoření okna pluginu Motive Explorer, u~prvního příkladu jsou zcela zřejmé nevýhody původního postupu, kdy metodu konstruktoru předchází definice vlastností objektu a~také nepohodlná tvorba oken a~dalších komponent grafického rozhraní.

\begin{code}
[EntryPoint()]
public class MOLE2
{
	...
	object SelectCSAButton = null;
	object SelectExecutableButton = null;
	object GuidePage = null;
	object wd = null;
	object original_view = null;

	public MOLE2(object app)
	{
		Points = StoredMethods.NewPythonDictionary();
		pa = StoredMethods.NewPythonTuple();
		pars = StoredMethods.NewPythonTuple();
		Tk.SetTopLevelTitle(root,"MOLE");
		Parent = root;
		Mainframe = Tk.Frame(Parent);
		Tk.Pack(Mainframe, "both", 1, 0, 0);
		Tk.BindWidgetWithEvent(Mainframe, "<<ComputationDone>>", 
			e => WhenComputationDone());
		Tk.BindWidgetWithEvent(Mainframe,"<<WrongExecutable>>", 
			e => WhenError(e,
				"Your TunnelsServer executable was not found!"));
		object balloon = Pmw.Balloon(Mainframe);
		Notebook = Pmw.NoteBook(Mainframe);
		Tk.Pack(Notebook, "both", 1, 10, 10);

		MainPage = Pmw.AddNoteBookPage(Notebook, "Compute tunnels");
		Pmw.SetNoteBookPageFocus(MainPage);
		var o = Tk.IntVar();
		var w = Pmw.Group(MainPage, "Specify starting points",0,o);
		Tk.Pack(w, "both", 0, 0, 0);
		...
\end{code}

\begin{code}
[EntryPoint()]
public class MotiveExplorer:PluginBase
{
	public MotiveExplorer(dynamic app)
	{
		Fields.CONFIGFILE = "MotiveExplorer_settings.txt";
		dynamic root = GUI.CreateWindow(app.root);
		root.title("Motive Explorer");
		Fields.Parent = root;

		Fields.MainFrame = GUI.CreateFrame(Fields.Parent);
		GUI.Pack(Fields.MainFrame, "both", 1, 0, 0);
		Fields.MainFrame.bind("<<ComputationDone>>", 
			(Action<object>)(e => WhenComputationDone()));
		Fields.MainFrame.bind("<<WrongExecutable>>",
			(Action<object>)(e => WhenError(e,
				"Your Motive explorer executable was not found!")));
		dynamic balloon = GUI.CreateBalloon(Fields.MainFrame);

		Fields.NoteBook = GUI.CreateNotebook(Fields.MainFrame);
		GUI.Pack(Fields.NoteBook, "both", 1, 10, 10);

		Fields.MainPage = Fields.NoteBook.add("Explore Motives");
		Fields.MainPage.focus_set();
		dynamic w = GUI.CreateGroup(Fields.MainPage,"Settings");
		GUI.Pack(w, "both", 0, 0, 0);
		...
\end{code}

\section{Možnosti rozšíření}
Obě dvě vytvořené knihovny \textbf{PyMOLBuilder} a~\textbf{PyMOLPluginCompiler.utils} jsou založeny na možnosti jejich rozšiřování pomocí nových uživatelem vytvořených typů, takovým způsobem, aby byly znovu použitelné. U~\textbf{PyMOLBuilderu} se jedná především o~tvorbu nových typů odvozených od typu \textit{PythonComponent}, u~\textbf{PyMOLPluginCompileru} pak definice vlastních typů pomocí atributů \textit{Store} a~\textit{Representation}. Značnou možnost rozšíření nabízí typ \textit{PythonRepresentation}, jež je společný oběma knihovnám a~tak umožňuje použití typů vytvořených v~jedné knihovně v~rámci typů knihovny druhé.

\paragraph{}
Z hlediska použití knihoven pro tvorbu pluginu je výraznou nevýhodou vlastnost objektů vytvářených pomocí Python modulů a~to ponechání jejich metod a~funkcí pro práci s~nimi. Je sice pravdou, že je takto možno využít jejich již existující dokumentaci, nicméně toto je bariéra, podobná samotnému vytváření kódu pluginu přímo v~jazyce Python. Mým návrhem řešení této bariéry proti použití je pak vytvoření aliasů pro metody objektů vytvořených moduly Pythonu, takových, které budou blíže známým metodám podobných objektů knihoven jazyku C\# tak, aby byla minimalizována rozdílnost v~chování těchto objektů.

\part{Závěr}

\setcounter{chapter}{0}
\chapter{Závěr}
Ve snaze nalézt možnost jak umožnit snadný přístup ke schopnostem programu pro vizualizaci struktur PyMOL byly v~rámci práce vytvořeny nástroje \textbf{PyMOLBuilder} a~\textbf{PyMOLPluginCompiler}. Knihovna \textbf{PyMOLBuilder} zjednodušuje jak vytváření nových programů takových, jejichž výstup bude schopen zpracovat program PyMOL, tak i~transformaci výstupů programů již vytvořených. Přínosem této knihovny je tedy především rozšíření možností prezentace výsledků svých aplikací zabývajících se makromolekulárními strukturami o~publikum uživatelů programu PyMOL. 

\paragraph{}
Program \textbf{PyMOLPluginCompiler} dodává nástroj pro vytváření uživatelských rozhraní pro programy v~rámci programu PyMOL jako jeho rozšíření. Tento nástroj lze obecně použít nejen ve spolupráci s~programem PyMOL, ale je možné jej použít i~k transformaci účelově různorodých programů v~jazyce C\# do jazyka Python. V~tomto směru také vidím potenciální možnost vylepšení stávajícího stavu nástroje řešením problému transformace částí programů, které využívají knihovní funkce platformy .NET na sémanticky ekvivalentní program řešící problém pomocí prostředků jazyku Python.

\addcontentsline{toc}{chapter}{Bibliografie}
\bibliographystyle{unsrturl}
\small
\bibliography{literature}
\normalsize

\appendix
\chapter{Přehled elektronických příloh}

\begin{itemize}
\item \textbf{MOLE 2 plugin}
Složka MOLE2\_plugin obsahuje soubory MOLE2.cs s~kodem pluginu v~jazyce C\# a~soubor MOLE2\_plugin\_final.py s~pluginem v~jazyce Python.

\item \textbf{Motive Explorer plugin}
Složka MotiveExplorer\_plugin obsahuje soubory MotiveExplorer.cs s~kodem pluginu v~jazyce C\# a~soubor MotiveExplorer\_plugin\_final.py s~pluginem v~jazyce Python.

\item \textbf{Knihovna PyMOLBuilder}
Složka PyMOLBuilder obsahuje soubor knihovny a~její dokumentaci ve formátu XML.

\item \textbf{Program PyMOLPluginCompiler}
Složka PyMOLPluginCompiler.

\item \textbf{Knihovna PyMOLPluginCompiler.Utils}
Složka PyMOLPluginCompiler.Utils obsahuje soubor knihovny a~její dokumentaci ve formátu XML.

\item \textbf{Projekt PyMOLPluginTools}
Složka PyMOLPluginTools obsahuje projekt programu Visual Studio, ve kterém jsou dostupné zdrojové kódy nástrojů PyMOLBuilder, PyMOLPluginCompiler a~PyMOLPluginCompiler.Utils.

\item \textbf{Srojový kod práce} Složka thesis obsahuje zdrojový kod práce, rovněž s~obrázky a~dalšími textovými přílohami.
\end{itemize}

\chapter{Případy užití nástroje PyMOLBuilder}
\includepdf[pages={1,2,3,4,5,6,7}]{PyMOLBuilder_UseCase}
\chapter{Případy užití nástroje PyMOLPluginCompiler}
\includepdf[pages={1,2,3,4,5}]{PyMOLPluginCompiler_UseCase}
\chapter{Návod pro vytváření PyMOL pluginů}
\includepdf[pages={1,2,3,4,5,6}]{Examples}

\end{document}
