Obsah
1. Zobrazení stromové struktury na ploše terminálu
2. Přidání uzlů do stromu metodou add, zobrazení celého stromu na terminálu
3. Přidání uzlů s poduzly do stromu
4. Specifikace barev textů v uzlech stromu
5. Volba, zda má být podstrom rozbalen či nikoli
6. Praktická ukázka použití stromu: zobrazení obsahu adresáře
7. Zobrazení průběhu výpočtu: progress bar
8. Progress bar vytvořený pro sekvenci
9. Výpočet prvočísel s vizualizací průběhu výpočtu
10. Využití instance třídy Progress ve funkci context manageru
12. Změna stylu (barvy) textu umístěných do jednotlivých panelů, víceřádkový text
13. Automatické rozmístění patnácti panelů v rámci plochy terminálu
14. Zobrazení jednoduché tabulky
15. Formát textu v buňkách tabulky
16. Použití značky [bold] a [/bold] v buňkách tabulky
18. Příloha: jména podporovaných barev
19. Repositář s demonstračními příklady
1. Zobrazení stromové struktury na ploše terminálu
V úvodní části dnešního článku o knihovně Rich se seznámíme se zobrazením stromové struktury na ploše terminálu. Jedná se o poměrně často využívanou operaci, protože například systém souborů tvoří stromovou strukturu; ovšem může se jednat například i o vizualizaci struktury nějaké organizace, o strukturované poznámky, vizualizaci rozhodovacího stromu atd. atd. Pro zobrazení stromové struktury se používá třída nazvaná tree, kterou nalezneme v modulu rich.tree:
Help on class Tree in module rich.tree: class Tree(rich.jupyter.JupyterMixin) | Tree(label: Union[rich.console.ConsoleRenderable, rich.console.RichCast, str], *, style: Union[str, ForwardRef('Style')] = 'tree', guide_style: Union[str, ForwardRef('Style')] = 'tree.line', expanded: bool = True, highlight: bool = False, hide_root: bool = False) -> None | | A renderable for a tree structure. | | Args: | label (RenderableType): The renderable or str for the tree label. | style (StyleType, optional): Style of this tree. Defaults to "tree". | guide_style (StyleType, optional): Style of the guide lines. Defaults to "tree.line". | expanded (bool, optional): Also display children. Defaults to True. | highlight (bool, optional): Highlight renderable (if str). Defaults to False. | | Method resolution order: | Tree | rich.jupyter.JupyterMixin | builtins.object
Samozřejmě můžeme pro zobrazení informací o třídě Tree využít i metodu inspect, kterou jsme si popsali minule:
from rich import inspect from rich.tree import Tree inspect(Tree, methods=True)
Výsledek zobrazený na textovém terminálu může vypadat následovně:
Obrázek 1: Základní informace o třídě Tree zobrazené funkcí inspect.
2. Přidání uzlů do stromu metodou add, zobrazení celého stromu na terminálu
Po konstrukci instance třídy Tree můžeme do takto vytvořeného uzlu přidávat uzly (a popř. celé podstromy) metodou add. V tom nejjednodušším případě postačuje této metodě předat pouze text, kterým je uzel stromu popsán. Pro ilustraci se pokusme o vytvoření stromu s pěti uzly (na stejné úrovni). Samotný kořen stromu je taktéž popsán textem. Strom lze vykreslit upravenou funkcí print:
from rich.tree import Tree from rich import print tree = Tree("Barvové modely") tree.add("RGB") tree.add("CMYK") tree.add("YUV") tree.add("HSL") tree.add("HSV") print(tree)
Výsledek bude vypadat takto:
Obrázek 2: Jednoúrovňový strom s kořenem a pěti uzly.
Zobrazme si navíc informace o samotné instanci třídy Tree. K tomuto účelu opět použijeme funkci inspect, kterou již dobře známe:
from rich import inspect from rich.tree import Tree tree = Tree("Barvové modely") tree.add("RGB") tree.add("CMYK") tree.add("YUV") tree.add("HSL") tree.add("HSV") inspect(tree, methods=True)
S výsledkem:
Obrázek 3: Informace o instanci třídy Tree zobrazené funkcí inspect.
3. Přidání uzlů s poduzly do stromu
Uzel, který je vložený do stromu (tedy do instance třídy Tree) metodou add, je opět instancí třídy Tree. O tom se přesvědčíme triviálním způsobem:
from rich import inspect from rich.tree import Tree tree = Tree("Strom") node = tree.add("Uzel") inspect(node)
S tímto výsledkem:
Obrázek 4: Informace o uzlu zobrazené funkcí inspect.
To tedy znamená, že můžeme vytvořit strom, jehož uzly budou obsahovat další poduzly. V případě jediného poduzlu lze použít tento trik:
from rich.tree import Tree from rich import print tree = Tree("Barvové modely") tree.add("RGB").add("Red Green Blue") tree.add("CMYK").add("Cyan Magenta Yellow blacK") tree.add("YUV").add("Luminance Chrominance") tree.add("HSL").add("Hue Saturation Lightness") tree.add("HSV").add("Hue Saturation Value") print(tree)
Výsledný strom bude vypadat takto:
Obrázek 5: Strom s pěti uzly, z nichž každý obsahuje jediný poduzel.
V případě, že má nějaký uzel stromu obsahovat větší množství poduzlů, vypomůžeme si použitím proměnných, z nichž každá bude obsahovat daný podstrom:
from rich.tree import Tree from rich import print tree = Tree("Barvové modely") rgb = tree.add("RGB") cmyk = tree.add("CMYK") yuv = tree.add("YUV") hsl = tree.add("HSL") hsv = tree.add("HSV") rgb.add("Red") rgb.add("Green") rgb.add("Blue") cmyk.add("Cyan") cmyk.add("Magenta") cmyk.add("Yellow") cmyk.add("blacK") hsl.add("Hue") hsl.add("Saturation") hsl.add("Lightness") hsv.add("Hue") hsv.add("Saturation") hsv.add("Value") print(tree)
Opět se podívejme na výsledek:
Obrázek 6: Strom s pěti uzly, které mohou obsahovat další poduzly.
4. Specifikace barev textů v uzlech stromu
Struktura resp. struktury zobrazené ve stromu nebyly zvoleny náhodně, neboť některé uzly obsahují jména barev. Uzly stromu totiž skutečně můžeme obarvit, a to takovým způsobem, že jméno barvy zapíšeme do hranatých závorek. Ostatně vše bude patrné z následujícího příkladu:
from rich.tree import Tree from rich import print tree = Tree("Barvové modely") rgb = tree.add("RGB") cmyk = tree.add("CMYK") yuv = tree.add("YUV") hsl = tree.add("HSL") hsv = tree.add("HSV") rgb.add("[red]Red") rgb.add("[green]Green") rgb.add("[blue]Blue") cmyk.add("[cyan]Cyan") cmyk.add("[magenta]Magenta") cmyk.add("[yellow]Yellow") cmyk.add("[black]blacK") hsl.add("Hue") hsl.add("Saturation") hsl.add("Lightness") hsv.add("Hue") hsv.add("Saturation") hsv.add("Value") print(tree)
Podívejme se na výsledek (včetně poněkud nešťastně zvolené černé barvy):
Obrázek 7: Strom s pěti uzly, které mohou obsahovat další poduzly. Některé poduzly jsou obarveny.
Obarveny však nejsou celé uzly, pouze text za jménem barvy. O tom se opět můžeme velmi snadno přesvědčit:
from rich.tree import Tree from rich import print tree = Tree("Barvové modely") rgb = tree.add("RGB") cmyk = tree.add("CMYK") yuv = tree.add("YUV") hsl = tree.add("HSL") hsv = tree.add("HSV") rgb.add("barva [red]Red") rgb.add("barva [green]Green") rgb.add("barva [blue]Blue") cmyk.add("barva [cyan]Cyan") cmyk.add("barva [magenta]Magenta") cmyk.add("barva [yellow]Yellow") cmyk.add("barva [black]blacK") hsl.add("Hue") hsl.add("Saturation") hsl.add("Lightness") hsv.add("Hue") hsv.add("Saturation") hsv.add("Value") print(tree)
Na terminál se v tomto případě vykreslí tento strom:
Obrázek 8: Strom s pěti uzly, které mohou obsahovat další poduzly. Některé poduzly jsou částečně obarveny.
5. Volba, zda má být podstrom rozbalen či nikoli
Nepovinným parametrem expanded nastaveným na pravdivostní hodnotu True či False je možné určit, jestli se má zvolený (právě vytvářený) podstrom daného uzlu zobrazit v rozbalené podobně či nikoli. V dalším demonstračním příkladu je tato volba použita u podstromu CMYK:
from rich.tree import Tree from rich import print tree = Tree("Barvové modely") rgb = tree.add("RGB") cmyk = tree.add("CMYK", expanded=False) yuv = tree.add("YUV") hsl = tree.add("HSL") hsv = tree.add("HSV") rgb.add("barva [red]Red") rgb.add("barva [green]Green") rgb.add("barva [blue]Blue") cmyk.add("barva [cyan]Cyan") cmyk.add("barva [magenta]Magenta") cmyk.add("barva [yellow]Yellow") cmyk.add("barva [black]blacK") hsl.add("Hue") hsl.add("Saturation") hsl.add("Lightness") hsv.add("Hue") hsv.add("Saturation") hsv.add("Value") print(tree)
S výsledkem:
Obrázek 9: Uzel CMYK sice obsahuje poduzly, ty však nejsou zobrazeny (podstrom je zabalený).
6. Praktická ukázka použití stromu: zobrazení obsahu adresáře
Na adrese https://github.com/Textualize/rich/blob/master/examples/tree.py naleznete skript, který po svém spuštění vytiskne strom s vizualizací obsahu zvoleného adresáře. Povšimněte si, že se zobrazují (přes Unicode) i ikony u známých typů souborů:
""" Demonstrates how to display a tree of files / directories with the Tree renderable. """ import os import pathlib import sys from rich import print from rich.filesize import decimal from rich.markup import escape from rich.text import Text from rich.tree import Tree def walk_directory(directory: pathlib.Path, tree: Tree) -> None: """Recursively build a Tree with directory contents.""" # Sort dirs first then by filename paths = sorted( pathlib.Path(directory).iterdir(), key=lambda path: (path.is_file(), path.name.lower()), ) for path in paths: # Remove hidden files if path.name.startswith("."): continue if path.is_dir(): style = "dim" if path.name.startswith("__") else "" branch = tree.add( f"[bold magenta]:open_file_folder: [link file://{path}]{escape(path.name)}", style=style, guide_style=style, ) walk_directory(path, branch) else: text_filename = Text(path.name, "green") text_filename.highlight_regex(r"\..*$", "bold red") text_filename.stylize(f"link file://{path}") file_size = path.stat().st_size text_filename.append(f" ({decimal(file_size)})", "blue") icon = "🐍 " if path.suffix == ".py" else "📄 " tree.add(Text(icon) + text_filename) try: directory = os.path.abspath(sys.argv[1]) except IndexError: print("[b]Usage:[/] python tree.py <DIRECTORY>") else: tree = Tree( f":open_file_folder: [link file://{directory}]{directory}", guide_style="bold bright_blue", ) walk_directory(pathlib.Path(directory), tree) print(tree)
Podívejme se nyní na ukázky výstupu:
Obrázek 10: Zobrazení obsahu adresáře (výřez výstupu).
Obrázek 11: Zobrazení obsahu adresáře (výřez výstupu).
7. Zobrazení průběhu výpočtu: progress bar
V případě, že se provádí nějaký zdlouhavý výpočet nebo zpracování dat a současně je alespoň zhruba známý počet kroků nutných k dokončení této činnosti, můžeme uživatele o průběhu výpočtu informovat s využitím klasického „teploměru“ (progress bar). Jedná se o objekt, který se vytváří (a současně i zobrazí) funkcí track:
Help on function track in module rich.progress: track(sequence: Union[Sequence[~ProgressType], Iterable[~ProgressType]], description: str = 'Working...', total: Union[float, NoneType] = None, auto_refresh: bool = True, console: Union[rich.console.Console, NoneType] = None, transient: bool = False, get_time: Union[Callable[[], float], NoneType] = None, refresh_per_second: float = 10, style: Union[str, ForwardRef('Style')] = 'bar.back', complete_style: Union[str, ForwardRef('Style')] = 'bar.complete', finished_style: Union[str, ForwardRef('Style')] = 'bar.finished', pulse_style: Union[str, ForwardRef('Style')] = 'bar.pulse', update_period: float = 0.1, disable: bool = False, show_speed: bool = True) -> Iterable[~ProgressType] Track progress by iterating over a sequence. Args: sequence (Iterable[ProgressType]): A sequence (must support "len") you wish to iterate over. description (str, optional): Description of task show next to progress bar. Defaults to "Working". total: (float, optional): Total number of steps. Default is len(sequence). auto_refresh (bool, optional): Automatic refresh, disable to force a refresh after each iteration. Default is True. transient: (bool, optional): Clear the progress on exit. Defaults to False. console (Console, optional): Console to write to. Default creates internal Console instance. refresh_per_second (float): Number of times per second to refresh the progress information. Defaults to 10. style (StyleType, optional): Style for the bar background. Defaults to "bar.back". complete_style (StyleType, optional): Style for the completed bar. Defaults to "bar.complete". finished_style (StyleType, optional): Style for a finished bar. Defaults to "bar.finished". pulse_style (StyleType, optional): Style for pulsing bars. Defaults to "bar.pulse". update_period (float, optional): Minimum time (in seconds) between calls to update(). Defaults to 0.1. disable (bool, optional): Disable display of progress. show_speed (bool, optional): Show speed if total isn't known. Defaults to True. Returns: Iterable[ProgressType]: An iterable of the values in the sequence.
8. Progress bar vytvořený pro sekvenci
Důležitý je především parametr sequence, kterým může být libovolná sekvence (například vytvořená pomocí range), přes níž se iteruje a z níž lze odvodit, jak dlouho bude výpočet prováděn. Ostatně si to ukažme na demonstračním příkladu získaném z originální dokumentace, který ukazuje, jak lze iterovat přes hodnoty 0 až 100 (vždy se zpožděním 0.02 sekundy)
from rich.progress import track from time import sleep def process_data(): sleep(0.02) for _ in track(range(100), description='[green]Processing data'): process_data()
Podívejme se na výsledky, konkrétně na terminál na začátku výpočtu a na konci výpočtu:
Obrázek 12: Zobrazení průběhu výpočtu: začátek výpočtu.
Obrázek 13: Zobrazení průběhu výpočtu: dokončení výpočtu.
9. Výpočet prvočísel s vizualizací průběhu výpočtu
Podívejme se nyní na poněkud praktičtější příklad. Bude se jednat o relativně pomalý algoritmus určený pro výpočet prvočísel. Vzhledem k tomu, že výpočet může být pro větší limit pomalý, budeme na terminál zobrazovat i průběh výpočtu s využitím progress baru. Jediná změna, kterou bylo nutné realizovat, je ve zdrojovém kódu zvýrazněna:
from rich.progress import track # originální kód lze nalézt na adrese: # http://www.rosettacode.org/wiki/Sieve_of_Eratosthenes#Using_array_lookup def primes2(limit): """Výpočet seznamu prvočísel až do zadaného limitu.""" is_prime = [False] * 2 + [True] * (limit - 1) for n in track(range(int(limit ** 0.5 + 1.5))): if is_prime[n]: for i in range(n * n, limit + 1, n): is_prime[i] = False return [i for i, prime in enumerate(is_prime) if prime] print(primes2(100))
Obrázek 14: Výpočet prvočísel s postupnou změnou progress baru.
10. Využití instance třídy Progress ve funkci context manageru
Třída Progress, resp. přesněji řečeno instance této třídy, lze využít i ve funkci context manageru, tedy (zjednodušeně řečeno) v programové konstrukci with. V následujícím příkladu nejdříve vytvoříme dva ukazatele průběhu s maximální hodnotou nastavenou na 100. Následně ve smyčce postupně zvyšujeme interní hodnotu každého ukazatele průběhu o 0,3 resp. 0,2, přičemž díky použití context manageru je zaručeno, že je smyčka ukončena až tehdy, když oba interní čítače dosáhnou či přesáhnou hodnoty 100:
from rich.progress import Progress import time with Progress() as progress_bars: task1 = progress_bars.add_task("[blue]Task #1...", total=100) task2 = progress_bars.add_task("[yellow]Task #2...", total=100) while not progress_bars.finished: progress_bars.update(task1, advance=0.3) progress_bars.update(task2, advance=0.2) time.sleep(0.01)
Obrázek 15: Dva paralelně běžící ukazatele průběhu.
Podívat se můžeme i na zpomalený „progress“ u většího množství úloh, zde konkrétně u čtveřice úloh:
from rich.progress import Progress import time with Progress() as progress_bars: task1 = progress_bars.add_task("[blue]Task #1...", total=100) task2 = progress_bars.add_task("[yellow]Task #2...", total=100) task3 = progress_bars.add_task("[red]Task #3...", total=100) task4 = progress_bars.add_task("[green]Task #4...", total=100) while not progress_bars.finished: progress_bars.update(task1, advance=0.3) progress_bars.update(task2, advance=0.2) progress_bars.update(task3, advance=0.1) progress_bars.update(task4, advance=0.05) time.sleep(0.01)
Obrázek 16: Čtyři paralelně běžící ukazatele průběhu.
11. Panely a sloupce
Poměrně často se setkáme s nutností zobrazit větší množství různých „kartiček“ (resp. panelů) na ploše terminálu, přičemž ovšem není dopředu zřejmé, jak široké tyto kartičky budou a především není jasné, jak široká je vlastně plocha terminálu (zde pochopitelně měřená ve znacích a nikoli v pixelech). Na druhou stranu ovšem nechceme, aby byly kartičky/panely na ploše terminálu rozmístěny zcela náhodně; ideální by bylo rozmístění do dynamicky vytvořených sloupců, přičemž dopředu neznáme počet sloupců ani jejich šířku. A přesně k tomuto účelu slouží v knihovně Rich třídy Panel a Columns, přičemž panely mohou obsahovat textové objekty a jsou umístěny do sloupců (nicméně sloupce se spíše podobají konceptu gridu a nikoli tabulkám, protože jejich počet se dynamicky mění). Podívejme se na jednoduchý demonstrační příklad se třemi panely:
from rich.console import Console from rich.columns import Columns from rich.panel import Panel console = Console() panel1 = Panel("První") panel2 = Panel("Druhý") panel3 = Panel("Třetí") columns = Columns([panel1, panel2, panel3]) console.print(columns)
Zajímavé bude otestovat si chování tohoto skriptu při změně šířky terminálu:
Obrázek 17: Zobrazení tří panelů na dostatečně širokém terminálu.
Obrázek 18: Zobrazení tří panelů na úzkém terminálu.
Obrázek 19: Zobrazení tří panelů na ještě užším terminálu.
12. Změna stylu (barvy) textu umístěných do jednotlivých panelů, víceřádkový text
Do panelů, které jsou rozmisťovány do automaticky vypočtených sloupců, lze umístit víceřádkový text – postačuje použít řídicí znak \n. Navíc je možné, aby byl tento text obarvený, přičemž barva (části) textu se zapisuje značkou [barva], což je styl, který jsme mohli vidět již při práci se stromy v úvodních kapitolách. Podívejme se tedy na způsob zápisu několika panelů s popisky barvových modelů (opět se tedy vracíme k již výše zmíněným demonstračním příkladům):
from rich.console import Console from rich.columns import Columns from rich.panel import Panel console = Console() panel1 = Panel("RGB\n\n[red]Red\n[green]Green\n[blue]Blue") panel2 = Panel("CMYK\n\n[cyan]Cyan\n[magenta]Magenta\n[yellow]Yellow\n[black]blacK") panel3 = Panel("YUV") panel4 = Panel("HSL\n\nHue\nSaturation\nLightness") panel5 = Panel("HSV\n\nHua\nSaturation\nValue") columns = Columns([panel1, panel2, panel3, panel4, panel5]) console.print(columns)
Nyní by měl výsledek (pochopitelně na dostatečně širokém terminálu) vypadat následovně:
Obrázek 20: Víceřádkový a obarvený text umístěný do jednotlivých panelů, které jsou rozmístěny do dynamicky spočtených sloupců.
13. Automatické rozmístění patnácti panelů v rámci plochy terminálu
Nepatrnou úpravou příkladu z předchozí kapitoly, konkrétně přidáním operace pro opakování seznamu (viz zvýrazněnou část), si můžeme otestovat, jak vlastně bude vypadat plocha terminálu po zobrazení patnácti panelů a nikoli pouze tří panelů:
from rich.console import Console from rich.columns import Columns from rich.panel import Panel console = Console() panel1 = Panel("RGB\n\n[red]Red\n[green]Green\n[blue]Blue") panel2 = Panel("CMYK\n\n[cyan]Cyan\n[magenta]Magenta\n[yellow]Yellow\n[black]blacK") panel3 = Panel("YUV") panel4 = Panel("HSL\n\nHue\nSaturation\nLightness") panel5 = Panel("HSV\n\nHua\nSaturation\nValue") columns = Columns([panel1, panel2, panel3, panel4, panel5]*5) console.print(columns)
Opět se podívejme na výsledky získané po spuštění tohoto demonstračního příkladu na dvou terminálech s rozdílnou velikostí plochy:
Obrázek 21: Zobrazení patnácti panelů na širokém terminálu.
Obrázek 22: Zobrazení patnácti panelů na užším terminálu.
14. Zobrazení jednoduché tabulky
Poslední užitečnou vlastností knihovny Rich, kterou si dnes alespoň ve stručnosti popíšeme, je podpora pro zobrazení tabulek. Samotná tabulka je reprezentována objektem typu Table (což asi není příliš překvapivé). Pro tabulku lze deklarovat titulky a popř. i styly sloupců, a to metodou Table.add_column. Dále lze do tabulky přidávat jednotlivé řádky metodou Table.add_row. Podívejme se nyní na velmi jednoduchý příklad s tabulkou, která bude mít dva sloupce a čtyři řádky:
from rich.console import Console from rich.table import Table table = Table(title="Barvové modely") table.add_column("Zkratka") table.add_column("Význam") table.add_row("RGB", "Red Green Blue") table.add_row("CMYK", "Cyan Magenta Yellow blacK") table.add_row("HSL", "Hue Saturation Lightness") table.add_row("HSV", "Hue Saturation Value") console = Console() console.print(table)
Výsledkem činnosti tohoto skriptu bude následující tabulka:
Obrázek 23: Zobrazení jednoduché tabulky se dvěma sloupci a čtyřmi řádky.
15. Formát textu v buňkách tabulky
Text, který je zapsán do buněk tabulky, je pochopitelně možné různým způsobem formátovat. Opět se podívejme na způsob použití značek pro specifikaci barev textu. Povšimněte si, že každá další zapsaná značka ruší (podle očekávání) význam značky předchozí (není tedy striktně nutné značky uzavírat):
from rich.console import Console from rich.table import Table table = Table(title="Barvové modely") table.add_column("Zkratka") table.add_column("Význam") table.add_column("Komponenty") table.add_row("RGB", "Red Green Blue", "[red]Red [green]Green [blue]Blue") table.add_row("CMYK", "Cyan Magenta Yellow blacK", "[cyan]Cyan [magenta]Magenta [yellow]Yellow [black]blacK") table.add_row("HSL", "Hue Saturation Lightness", "") table.add_row("HSV", "Hue Saturation Value", "") console = Console() console.print(table)
Podívejme se na výsledek:
Obrázek 24: Zobrazení jednoduché tabulky se třemi sloupci a čtyřmi řádky, přičemž část textu jsou zobrazeny barevně.
16. Použití značky [bold] a [/bold] v buňkách tabulky
Demonstrační příklad z předchozí kapitoly lze vylepšit takovým způsobem, že se zvýrazní ta písmena, ze kterých se skládá zkratka barvového modelu. Pro tento účel použijeme značku [bold] a vzhledem k tomu, že budeme chtít zvýraznit vždy jen jediný znak, budeme muset použít i uzavírací značku [/bold], tedy použije se prakticky totožný zápis, jaký je známý z HTML (až na odlišné znaky pro zápis samotných značek):
from rich.console import Console from rich.table import Table table = Table(title="Barvové modely") table.add_column("Zkratka") table.add_column("Význam") table.add_column("Komponenty") table.add_row("RGB", "[bold]R[/bold]ed [bold]G[/bold]reen [bold]B[/bold]lue", "[red]Red [green]Green [blue]Blue") table.add_row("CMYK", "[bold]C[/bold]yan [bold]M[/bold]agenta [bold]Y[/bold]ellow blac[bold]K[/bold]", "[cyan]Cyan [magenta]Magenta [yellow]Yellow [black]blacK") table.add_row("HSL", "[bold]H[/bold]ue [bold]S[/bold]aturation [bold]L[/bold]ightness", "") table.add_row("HSV", "[bold]H[/bold]ue [bold]S[/bold]aturation [bold]V[/bold]alue", "") console = Console() console.print(table)
Výsledek:
Obrázek 25: Zobrazení jednoduché tabulky se třemi sloupci a čtyřmi řádky, přičemž část textu jsou zobrazeny barevně. Tučně jsou navíc zvýrazněny ty znaky, z nichž se skládá zkratka názvu barvového modelu.
17. Zarovnání textu
V dnešním posledním demonstračním příkladu je ukázán způsob zobrazení dlouhého odstavce, jehož text se nevejde na jediný řádek. Takový odstavec může být zarovnán doleva, doprava, na střed (vycentrován) nebo zarovnán na oba okraje:
from rich.console import Console, Text paragraph = Text( """\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n""" ) console = Console() console.rule("justify='left'") console.print(paragraph, style="red") console.print() console.rule("justify='center'") console.print(paragraph, style="green", justify="center") console.print() console.rule("justify='right'") console.print(paragraph, style="blue", justify="right") console.print() console.rule("justify='full'") console.print(paragraph, style="magenta", justify="full") console.print()
S tímto výsledkem:
Obrázek 26: Odstavec, který je postupně zarovnán doleva, na střed, doprava a nakonec na oba okraje.
18. Příloha: jména podporovaných barev
V této příloze jsou vypsána jména všech barev, která je možné použít v hranatých závorkách pro ovlivnění barvy textu v terminálu (například uzlu stromu atd.):
black red green yellow blue magenta cyan white bright_black bright_red bright_green bright_yellow bright_blue bright_magenta bright_cyan bright_white grey0 gray0 navy_blue dark_blue blue3 blue1 dark_green deep_sky_blue4 dodger_blue3 dodger_blue2 green4 spring_green4 turquoise4 deep_sky_blue3 dodger_blue1 green3 spring_green3 dark_cyan light_sea_green deep_sky_blue2 deep_sky_blue1 spring_green2 cyan3 dark_turquoise turquoise2 green1 spring_green1 medium_spring_green cyan2 cyan1 dark_red deep_pink4 purple4 purple3 blue_violet orange4 grey37 gray37 medium_purple4 slate_blue3 royal_blue1 chartreuse4 dark_sea_green4 pale_turquoise4 steel_blue steel_blue3 cornflower_blue chartreuse3 cadet_blue sky_blue3 steel_blue1 pale_green3 sea_green3 aquamarine3 medium_turquoise chartreuse2 sea_green2 sea_green1 aquamarine1 dark_slate_gray2 dark_magenta dark_violet purple light_pink4 plum4 medium_purple3 slate_blue1 yellow4 wheat4 grey53 gray53 light_slate_grey light_slate_gray medium_purple light_slate_blue dark_olive_green3 dark_sea_green light_sky_blue3 sky_blue2 dark_sea_green3 dark_slate_gray3 sky_blue1 chartreuse1 light_green pale_green1 dark_slate_gray1 red3 medium_violet_red magenta3 dark_orange3 indian_red hot_pink3 medium_orchid3 medium_orchid medium_purple2 dark_goldenrod light_salmon3 rosy_brown grey63 gray63 medium_purple1 gold3 dark_khaki navajo_white3 grey69 gray69 light_steel_blue3 light_steel_blue yellow3 dark_sea_green2 light_cyan3 light_sky_blue1 green_yellow dark_olive_green2 dark_sea_green1 pale_turquoise1 deep_pink3 magenta2 hot_pink2 orchid medium_orchid1 orange3 light_pink3 pink3 plum3 violet light_goldenrod3 tan misty_rose3 thistle3 plum2 khaki3 light_goldenrod2 light_yellow3 grey84 gray84 light_steel_blue1 yellow2 dark_olive_green1 honeydew2 light_cyan1 red1 deep_pink2 deep_pink1 magenta1 orange_red1 indian_red1 hot_pink dark_orange salmon1 light_coral pale_violet_red1 orchid2 orchid1 orange1 sandy_brown light_salmon1 light_pink1 pink1 plum1 gold1 navajo_white1 misty_rose1 thistle1 yellow1 light_goldenrod1 khaki1 wheat1 cornsilk1 grey100 gray100 grey3 gray3 grey7 gray7 grey11 gray11 grey15 gray15 grey19 gray19 grey23 gray23 grey27 gray27 grey30 gray30 grey35 gray35 grey39 gray39 grey42 gray42 grey46 gray46 grey50 gray50 grey54 gray54 grey58 gray58 grey62 gray62 grey66 gray66 grey70 gray70 grey74 gray74 grey78 gray78 grey82 gray82 grey85 gray85 grey89 gray89 grey93 gray93
19. Repositář s demonstračními příklady
Zdrojové kódy všech minule i dnes popsaných demonstračních příkladů určených pro Python 3 byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/most-popular-python-libs. V případě, že nebudete chtít klonovat celý repositář (ten je ovšem stále velmi malý, dnes má velikost zhruba několik desítek kilobajtů), můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:
20. Odkazy na Internetu
- Repositář s knihovnou Rich
https://github.com/Textualize/rich - Knihovna Rich na PyPi
https://pypi.org/project/rich/ - How to Use the Rich Library with Python
https://www.freecodecamp.org/news/use-the-rich-library-in-python/ - Introduction (Rich, Readthedocs)
https://rich.readthedocs.io/en/stable/introduction.html - Awesome Python
https://awesome-python.com/ - Python Awesome
https://pythonawesome.com/about/ - Python Rich Library
https://vegibit.com/python-rich-library/ - Python’s rich library – a tutorial
https://softbranchdevelopers.com/pythons-rich-library-a-tutorial/ - blessed na PyPi
https://pypi.org/project/blessed/ - blessed na GitHubu
https://github.com/jquast/blessed - Blessed documentation!
https://blessed.readthedocs.io/en/latest/ - termbox-go na GitHubu
https://github.com/nsf/termbox-go - termui na GitHubu
https://github.com/gizak/termui - blessed na GitHubu
https://github.com/chjj/blessed - blessed-contrib na GitHubu
https://github.com/yaronn/blessed-contrib - tui-rs na GitHubu
https://github.com/fdehau/tui-rs - Tree structure
https://en.wikipedia.org/wiki/Tree_structure - Directory structure
https://en.wikipedia.org/wiki/Directory_structure - Decision tree
https://en.wikipedia.org/wiki/Decision_tree - Lightweight markup language
https://en.wikipedia.org/wiki/Lightweight_markup_language - Text box
https://en.wikipedia.org/wiki/Text_box