{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Ukážeme si, jak vytvořit kompletní projekt v Pythonu. Navrhneme vhodnou adresářovou strukturu. Ukážeme si některé nástroje, které je možné použít, včetně verzovacího systému Git. A řekneme si něco málo o distribuci ve světě Pythonu.\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Vhodná adresářová struktura\n", "Python nevyžaduje žádnou speciální strukturu adresářů, existují pouze zvyklosti. Přehled takových zvyklostí najdeme např. v https://realpython.com/python-application-layouts/.\n", "\n", "Úplně jednoduchý projekt (script):\n", "\n", " helloworld/\n", " │\n", " ├── .gitignore\n", " ├── helloworld.py\n", " ├── LICENSE\n", " ├── README.md\n", " ├── requirements.txt\n", " ├── setup.py\n", " └── tests.py\n", "\n", "Typický projekt - instalovatelná knihovna:\n", "\n", " helloworld/\n", " │\n", " ├── helloworld/\n", " │ ├── __init__.py\n", " │ ├── helloworld.py\n", " │ └── helpers.py\n", " │\n", " ├── tests/\n", " │ ├── helloworld_tests.py\n", " │ └── helpers_tests.py\n", " │\n", " ├── .gitignore\n", " ├── LICENSE\n", " ├── README.md\n", " ├── requirements.txt\n", " └── setup.py\n", " \n", "V první řadě vytvoříme adresář, kam dáváme *všechny* soubory týkající se projektu. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## PEP 8\n", "O [PEP 8](http://www.python.org/dev/peps/pep-0008/) jsme se již zmínili. Tento dokument ovšem obsahuje natolik důležité konvence, že je dobré ho znovu připomenout. Jeho znalost a dodržování výrazně zlepšuje čitelnost kódů od ostatních / ostatními programátory. Vhodné je, aby přímo editor kontroloval PEP 8, případně alespoň použít samostatný pep8 příkaz.\n", "\n", "Několik důležitých bodů:\n", "\n", "* Use 4 spaces per indentation level. Spaces are the preferred indentation method.\n", "* Limit all lines to a maximum of 79 characters. The preferred way of wrapping long lines is by using Python's implied line continuation inside parentheses, brackets and braces. \n", "* Avoid extraneous whitespace in the following situations:\n", " * Immediately inside parentheses, brackets or braces.\n", " * Immediately before a comma, semicolon, or colon:\n", " * Immediately before the open parenthesis that starts the argument list of a function call:\n", " * Immediately before the open parenthesis that starts an indexing or slicing:\n", " * More than one space around an assignment (or other) operator to align it with another.\n", "* Modules should have short, all-lowercase names.\n", "* Almost without exception, class names use the CapWords convention.\n", "* Function names should be lowercase, with words separated by underscores as necessary to improve readability." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Cvičný projekt: načítání csv souboru\n", "Na ukázku si zkusíme načíst csv soubor. To není příliš složité, navíc si specifikaci ještě trochu zjednodušíme. Co budeme od projektu chtít:\n", "\n", "1. Načíst csv (specifikace např. na [wikipedii](http://en.wikipedia.org/wiki/CSV_file) (pro jednoduchost nebudeme uvažovat uvozovky) soubor do seznamu řádků.\n", "1. Zvolit si oddělovač řádků\n", "2. Každý řádek bude reprezentován seznamem.\n", "3. Každá položka bude převedena na int, float nebo str podle obsahu.\n", "4. Napíšeme unit testy pro nose.\n", "5. Vytvoříme dokumentaci pomocí Sphinx.\n", "\n", "### Co se může hodit\n", "\n", "* Práce se soubory (open + iterace)\n", "* str metody split, strip\n", "* Převod na float a int\n", "* Generátorova notace" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Verzovací systém Git\n", "Vhodné je používat nějaký nástroj na správu verzí. V současnosti je nejrozšířenější [Git](https://git-scm.com/).\n", "Základní kroky jsou:\n", "\n", "1. Vytvořit adresář projektu.\n", "2. Inicializovat pomocí `git init`.\n", "3. Přidat nebo změnit soubory.\n", "4. Změněné / nové soubory přidat pomocí `git add `.\n", "5. Vytvořit revizi pomocí `git commit`.\n", "6. ... zpět na 3." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Testování pomocí `pytest`\n", "`pytest` umožňuje jednoduše spravovat a spouštět unit testy.\n", "\n", "1. V adresáři `tests` vytvoříme soubor(y)s testy, např. `tests_main.py`.\n", "2. V tomto souboru implementujeme funkce, které začínají `test_` (např. `test_int`). Typicky v těchto funkcích používáme pro testování `assert`.\n", "3. Testy spustíme pomocí `python -m pytest`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dokumentace pomocí Sphinx\n", "[Sphinx](http://sphinx-doc.org/) je nástroj pro vytváření přehledné a vizuálně atraktivní dokumentace. Sphinx převádí [reStructuredText](http://en.wikipedia.org/wiki/ReStructuredText) na HTML, LaTeX aj. Navíc dokáže z dokumentace (docstrings) ve zdrojového kódu vytvořit přehlednou dokumentaci v reStructuredText. Výsledkem je např. vlastní [dokumentace Pythonu](http://docs.python.org/) a [mnoho dalších](http://sphinx-doc.org/examples.html).\n", "\n", "### Základní postup\n", "\n", "1. V adresáři doc spustíme `sphinx-quickstart`. Odpovíme na otázky, z rozšíření budeme potřebovat `autodoc`, případně `viewcode`.\n", "2. Podíváme se, co Sphinx vytvořil. Především to jsou soubory `conf.py` a `index.rst`.\n", "3. V `conf.py` téměř na začátku odkomentujeme `sys.path.insert` řádek a přidáme adresář `'..'`.\n", "4. Vytvoříme API dokumentaci pomocí `sphinx-apidoc -f -o . ../project` (project nahradíme vlastním názvem).\n", "1. Vytvoříme html pomocí `make html`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Jak software publikovat\n", "\n", "Publikace softwaru je spíše pokročilejší téma a nebudeme se mu příliš věnovat. Základní postup je popsán např. na https://packaging.python.org/tutorials/packaging-projects/. \n", "\n", "Základem je vytvořit soubor `setup.py` (pro [setuptools](https://packaging.python.org/key_projects/#setuptools), který může vypadat zhruba takto:\n", "```python\n", "import setuptools\n", "\n", "with open(\"README.md\", \"r\") as fh:\n", " long_description = fh.read()\n", "\n", "setuptools.setup(\n", " name=\"example-pkg-YOUR-USERNAME-HERE\", # Replace with your own username\n", " version=\"0.0.1\",\n", " author=\"Example Author\",\n", " author_email=\"author@example.com\",\n", " description=\"A small example package\",\n", " long_description=long_description,\n", " long_description_content_type=\"text/markdown\",\n", " url=\"https://github.com/pypa/sampleproject\",\n", " packages=setuptools.find_packages(),\n", " classifiers=[\n", " \"Programming Language :: Python :: 3\",\n", " \"License :: OSI Approved :: MIT License\",\n", " \"Operating System :: OS Independent\",\n", " ],\n", " python_requires='>=3.6',\n", ")\n", "```\n", "\n", "Pokud to s produkcí a distribucí Python knihoven a aplikací myslíte vážně, podívejte se na https://poetry.eustace.io/." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.4" } }, "nbformat": 4, "nbformat_minor": 4 }