├── requirements.txt ├── Python теория.docx ├── images ├── image_1.png ├── image_10.png ├── image_11.png ├── image_12.png ├── image_13.png ├── image_14.png ├── image_15.png ├── image_16.png ├── image_17.png ├── image_18.png ├── image_19.png ├── image_2.png ├── image_20.png ├── image_21.png ├── image_22.png ├── image_23.png ├── image_3.png ├── image_4.png ├── image_5.png ├── image_6.png ├── image_7.png ├── image_8.png └── image_9.png ├── TODO ├── .github └── workflows │ └── commit.yml ├── .gitignore ├── docx-to-md.py └── README.md /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/requirements.txt -------------------------------------------------------------------------------- /Python теория.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/Python теория.docx -------------------------------------------------------------------------------- /images/image_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_1.png -------------------------------------------------------------------------------- /images/image_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_10.png -------------------------------------------------------------------------------- /images/image_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_11.png -------------------------------------------------------------------------------- /images/image_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_12.png -------------------------------------------------------------------------------- /images/image_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_13.png -------------------------------------------------------------------------------- /images/image_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_14.png -------------------------------------------------------------------------------- /images/image_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_15.png -------------------------------------------------------------------------------- /images/image_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_16.png -------------------------------------------------------------------------------- /images/image_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_17.png -------------------------------------------------------------------------------- /images/image_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_18.png -------------------------------------------------------------------------------- /images/image_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_19.png -------------------------------------------------------------------------------- /images/image_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_2.png -------------------------------------------------------------------------------- /images/image_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_20.png -------------------------------------------------------------------------------- /images/image_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_21.png -------------------------------------------------------------------------------- /images/image_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_22.png -------------------------------------------------------------------------------- /images/image_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_23.png -------------------------------------------------------------------------------- /images/image_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_3.png -------------------------------------------------------------------------------- /images/image_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_4.png -------------------------------------------------------------------------------- /images/image_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_5.png -------------------------------------------------------------------------------- /images/image_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_6.png -------------------------------------------------------------------------------- /images/image_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_7.png -------------------------------------------------------------------------------- /images/image_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_8.png -------------------------------------------------------------------------------- /images/image_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FerrumVega/Python/HEAD/images/image_9.png -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | yield from 2 | ['assert', 'async', 'await', 'class', 'raise'] 3 | битовые операции 4 | match/case 5 | фикс чисел в math в конспекте 6 | Python имеет и встроенную команду round(). функция а не команда 7 | функция генераторов и итераторов -------------------------------------------------------------------------------- /.github/workflows/commit.yml: -------------------------------------------------------------------------------- 1 | name: DOCX to Markdown 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | convert: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout repo 15 | uses: actions/checkout@v4 16 | 17 | - name: Set up Python 18 | uses: actions/setup-python@v5 19 | with: 20 | python-version: "3.11" 21 | 22 | - name: Install dependencies 23 | run: | 24 | python -m pip install --upgrade pip 25 | pip install python-docx 26 | 27 | - name: Run DOCX to Markdown converter 28 | run: python docx-to-md.py 29 | 30 | - name: Move converted files to repo root 31 | run: | 32 | shopt -s dotglob 33 | for f in MarkdownOutput/*; do 34 | mv "$f" . 35 | done 36 | 37 | - name: Commit and push changes 38 | env: 39 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 40 | run: | 41 | git config user.name "github-actions[bot]" 42 | git config user.email "github-actions[bot]@users.noreply.github.com" 43 | git add . 44 | git commit -m "Auto-update Markdown from DOCX" || echo "No changes" 45 | git push https://x-access-token:$GH_TOKEN@github.com/${{ github.repository }} HEAD:main 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[codz] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # UV 98 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | #uv.lock 102 | 103 | # poetry 104 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 105 | # This is especially recommended for binary packages to ensure reproducibility, and is more 106 | # commonly ignored for libraries. 107 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 108 | #poetry.lock 109 | #poetry.toml 110 | 111 | # pdm 112 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 113 | # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. 114 | # https://pdm-project.org/en/latest/usage/project/#working-with-version-control 115 | #pdm.lock 116 | #pdm.toml 117 | .pdm-python 118 | .pdm-build/ 119 | 120 | # pixi 121 | # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. 122 | #pixi.lock 123 | # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one 124 | # in the .venv directory. It is recommended not to include this directory in version control. 125 | .pixi 126 | 127 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 128 | __pypackages__/ 129 | 130 | # Celery stuff 131 | celerybeat-schedule 132 | celerybeat.pid 133 | 134 | # SageMath parsed files 135 | *.sage.py 136 | 137 | # Environments 138 | .env 139 | .envrc 140 | .venv 141 | env/ 142 | venv/ 143 | ENV/ 144 | env.bak/ 145 | venv.bak/ 146 | 147 | # Spyder project settings 148 | .spyderproject 149 | .spyproject 150 | 151 | # Rope project settings 152 | .ropeproject 153 | 154 | # mkdocs documentation 155 | /site 156 | 157 | # mypy 158 | .mypy_cache/ 159 | .dmypy.json 160 | dmypy.json 161 | 162 | # Pyre type checker 163 | .pyre/ 164 | 165 | # pytype static type analyzer 166 | .pytype/ 167 | 168 | # Cython debug symbols 169 | cython_debug/ 170 | 171 | # PyCharm 172 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 173 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 174 | # and can be added to the global gitignore or merged into this file. For a more nuclear 175 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 176 | #.idea/ 177 | 178 | # Abstra 179 | # Abstra is an AI-powered process automation framework. 180 | # Ignore directories containing user credentials, local state, and settings. 181 | # Learn more at https://abstra.io/docs 182 | .abstra/ 183 | 184 | # Visual Studio Code 185 | # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore 186 | # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore 187 | # and can be added to the global gitignore or merged into this file. However, if you prefer, 188 | # you could uncomment the following to ignore the entire vscode folder 189 | # .vscode/ 190 | 191 | # Ruff stuff: 192 | .ruff_cache/ 193 | 194 | # PyPI configuration file 195 | .pypirc 196 | 197 | # Cursor 198 | # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to 199 | # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data 200 | # refer to https://docs.cursor.com/context/ignore-files 201 | .cursorignore 202 | .cursorindexingignore 203 | 204 | # Marimo 205 | marimo/_static/ 206 | marimo/_lsp/ 207 | __marimo__/ 208 | -------------------------------------------------------------------------------- /docx-to-md.py: -------------------------------------------------------------------------------- 1 | import re 2 | import docx 3 | import os 4 | 5 | # === DOCX TO MARKDOWN === 6 | 7 | 8 | def sanitize_anchor(text): 9 | anchor = re.sub(r"[^\w\s-]", "", text.lower()) 10 | anchor = re.sub(r"[\s-]+", "-", anchor) 11 | return anchor.strip("-") 12 | 13 | 14 | def is_list_paragraph(paragraph): 15 | """Проверка, является ли параграф элементом списка в Word.""" 16 | p = paragraph._p 17 | numPr = p.find(".//w:numPr", p.nsmap) 18 | return numPr is not None 19 | 20 | 21 | def add_two_spaces(line): 22 | return line + " " 23 | 24 | 25 | def docx_to_markdown(docx_path, output_dir): 26 | os.makedirs(output_dir, exist_ok=True) 27 | images_dir = os.path.join(output_dir, "images") 28 | os.makedirs(images_dir, exist_ok=True) 29 | 30 | doc = docx.Document(docx_path) 31 | markdown_lines = [] 32 | current_code_block = [] 33 | in_code_block = False 34 | image_counter = 1 35 | 36 | # Собираем картинки 37 | image_parts = {} 38 | for rel in doc.part.rels.values(): 39 | if rel.target_ref and "image" in rel.target_ref: 40 | image_parts[rel.rId] = rel.target_part 41 | 42 | for element in doc.element.body: 43 | if element.tag.endswith("p"): 44 | paragraph = docx.text.paragraph.Paragraph(element, doc) 45 | 46 | # Изображения 47 | if paragraph._element.xpath(".//pic:pic"): 48 | for run in paragraph.runs: 49 | if run._element.xpath(".//pic:pic"): 50 | blip = run._element.xpath(".//a:blip/@r:embed")[0] 51 | if blip in image_parts: 52 | img_path = os.path.join( 53 | images_dir, f"image_{image_counter}.png" 54 | ) 55 | with open(img_path, "wb") as f: 56 | f.write(image_parts[blip].blob) 57 | markdown_lines.append( 58 | add_two_spaces( 59 | f"![Image {image_counter}](images/image_{image_counter}.png)" 60 | ) 61 | ) 62 | image_counter += 1 63 | continue 64 | 65 | is_code_font = all( 66 | run.font and run.font.name == "Cascadia Mono" for run in paragraph.runs 67 | ) 68 | has_content = bool(paragraph.text.strip()) 69 | 70 | if not has_content: 71 | if in_code_block and is_code_font: 72 | current_code_block.append("") 73 | else: 74 | markdown_lines.append("") 75 | continue 76 | 77 | if is_code_font: 78 | if not in_code_block and current_code_block: 79 | code_text = "\n".join(current_code_block) 80 | markdown_lines.append( 81 | add_two_spaces(f"```python\n{code_text}\n```") 82 | ) 83 | current_code_block = [] 84 | in_code_block = True 85 | current_code_block.append(add_two_spaces(paragraph.text)) 86 | else: 87 | if in_code_block and current_code_block: 88 | code_text = "\n".join(current_code_block) 89 | markdown_lines.append( 90 | add_two_spaces(f"```python\n{code_text}\n```") 91 | ) 92 | current_code_block = [] 93 | in_code_block = False 94 | 95 | paragraph_text = "" 96 | runs = paragraph.runs 97 | i = 0 98 | while i < len(runs): 99 | run = runs[i] 100 | if ( 101 | run.font 102 | and run.font.name == "Cascadia Mono" 103 | and run.text.strip() 104 | ): 105 | code_parts = [run.text] 106 | j = i + 1 107 | while j < len(runs): 108 | next_run = runs[j] 109 | if ( 110 | next_run.font and next_run.font.name == "Cascadia Mono" 111 | ) or ( 112 | next_run.text == " " 113 | and j + 1 < len(runs) 114 | and runs[j + 1].font 115 | and runs[j + 1].font.name == "Cascadia Mono" 116 | ): 117 | code_parts.append(next_run.text) 118 | j += 1 119 | else: 120 | break 121 | paragraph_text += f"`{''.join(code_parts)}`" 122 | i = j 123 | else: 124 | paragraph_text += run.text 125 | i += 1 126 | 127 | paragraph_text = add_two_spaces(paragraph_text.rstrip()) 128 | 129 | if paragraph.style.name.startswith("Heading"): 130 | level = int(paragraph.style.name.split()[-1]) 131 | clean_text = paragraph_text.strip() 132 | markdown_lines.append(add_two_spaces(f"{'#' * level} {clean_text}")) 133 | elif is_list_paragraph(paragraph): 134 | markdown_lines.append(add_two_spaces(f"- {paragraph_text.strip()}")) 135 | else: 136 | markdown_lines.append(add_two_spaces(paragraph_text)) 137 | 138 | elif element.tag.endswith("tbl"): 139 | table = docx.table.Table(element, doc) 140 | num_cols = len(table.columns) 141 | header = [add_two_spaces(cell.text.strip()) for cell in table.rows[0].cells] 142 | markdown_lines.append(add_two_spaces("| " + " | ".join(header) + " |")) 143 | markdown_lines.append( 144 | add_two_spaces("|" + "|".join(["---"] * num_cols) + "|") 145 | ) 146 | 147 | for row in table.rows[1:]: 148 | row_data = [ 149 | add_two_spaces(cell.text.strip().replace("\n", "
")) 150 | for cell in row.cells 151 | ] 152 | markdown_lines.append( 153 | add_two_spaces("| " + " | ".join(row_data) + " |") 154 | ) 155 | 156 | if current_code_block: 157 | code_text = "\n".join(current_code_block) 158 | markdown_lines.append(add_two_spaces(f"```python\n{code_text}\n```")) 159 | 160 | # Оглавление 161 | toc = [add_two_spaces("## Оглавление")] 162 | headers = [] 163 | for line in markdown_lines: 164 | if line.startswith("#") and not line.startswith("## Оглавление"): 165 | level = len(line.split()[0]) 166 | title = " ".join(line.split()[1:]) 167 | headers.append((level, title)) 168 | 169 | anchor_counts = {} 170 | for level, title in headers: 171 | anchor = sanitize_anchor(title) 172 | if anchor in anchor_counts: 173 | anchor_counts[anchor] += 1 174 | anchor = f"{anchor}-{anchor_counts[anchor]}" 175 | else: 176 | anchor_counts[anchor] = 1 177 | indent = " " * (level - 1) 178 | toc.append(add_two_spaces(f"{indent}- [{title}](#{anchor})")) 179 | 180 | output_path = os.path.join(output_dir, "README.md") 181 | with open(output_path, "w", encoding="utf-8") as f: 182 | f.write("\n".join(toc + ["\n"] + markdown_lines)) 183 | 184 | return output_path 185 | 186 | 187 | # === Использование === 188 | docx_path = "Python теория.docx" 189 | output_dir = "MarkdownOutput" 190 | result_path = docx_to_markdown(docx_path, output_dir) 191 | print(f"Markdown сохранен в: {result_path}") 192 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Оглавление 2 | - [Ввод-вывод](#ввод-вывод) 3 | - [Базовые команды](#базовые-команды) 4 | - [sep, end](#sep-end) 5 | - [Арифметика и её приоритеты](#арифметика-и-её-приоритеты) 6 | - [Логические операторы и их приоритеты](#логические-операторы-и-их-приоритеты) 7 | - [If-elif-else](#if-elif-else) 8 | - [Операторы сравнения](#операторы-сравнения) 9 | - [or, and, not](#or-and-not) 10 | - [Типы данных](#типы-данных) 11 | - [Числовые типы данных](#числовые-типы-данных) 12 | - [Строковый тип данных](#строковый-тип-данных) 13 | - [Модуль math](#модуль-math) 14 | - [Циклы](#циклы) 15 | - [For](#for) 16 | - [Частые сценарии](#частые-сценарии) 17 | - [While](#while) 18 | - [while: break, continue, else](#while-break-continue-else) 19 | - [Вложенные циклы](#вложенные-циклы) 20 | - [Строки](#строки) 21 | - [Индексация строк](#индексация-строк) 22 | - [Вывод символов строки](#вывод-символов-строки) 23 | - [Срезы строк](#срезы-строк) 24 | - [Методы строк](#методы-строк) 25 | - [partition()](#partition) 26 | - [format(); format_map()](#format-format_map) 27 | - [f-строки](#f-строки) 28 | - [Строки в памяти компьютера](#строки-в-памяти-компьютера) 29 | - [Сравнение строк](#сравнение-строк) 30 | - [Списки](#списки) 31 | - [Создание списка](#создание-списка) 32 | - [Основы (len, sum, min, max, in)](#основы-len-sum-min-max-in) 33 | - [Добавление элементов](#добавление-элементов) 34 | - [Объединение списков](#объединение-списков) 35 | - [Удаление элементов](#удаление-элементов) 36 | - [Вывод элементов списка](#вывод-элементов-списка) 37 | - [split(), join()](#split-join) 38 | - [Методы списков](#методы-списков) 39 | - [Сортировка списков](#сортировка-списков) 40 | - [Генераторы списков; списочные выражения](#генераторы-списков-списочные-выражения) 41 | - [Нахождение чисел палиндромов](#нахождение-чисел-палиндромов) 42 | - [Методы сортировки списков](#методы-сортировки-списков) 43 | - [Тип данных bool и NoneType](#тип-данных-bool-и-nonetype) 44 | - [bool](#bool) 45 | - [NoneType](#nonetype) 46 | - [Вложенные списки](#вложенные-списки) 47 | - [Основы](#основы) 48 | - [Матрицы, ljust(), rjust()](#матрицы-ljust-rjust) 49 | - [Кортежи](#кортежи) 50 | - [Введение](#введение) 51 | - [Основы](#основы-2) 52 | - [Сравнение кортежей](#сравнение-кортежей) 53 | - [Сортировка кортежей](#сортировка-кортежей) 54 | - [Распаковка кортежей; “хвосты”](#распаковка-кортежей-хвосты) 55 | - [Множества](#множества) 56 | - [Множества в математике](#множества-в-математике) 57 | - [Пустое множество](#пустое-множество) 58 | - [Числовые множества](#числовые-множества) 59 | - [Операции над множествами](#операции-над-множествами) 60 | - [Диаграммы Эйлера-Венна при решении задач](#диаграммы-эйлера-венна-при-решении-задач) 61 | - [Введение в множества в Python](#введение-в-множества-в-python) 62 | - [Создание множества](#создание-множества) 63 | - [Вывод множества](#вывод-множества) 64 | - [set()](#set) 65 | - [Основы работы с множествами](#основы-работы-с-множествами) 66 | - [Перебор элементов множества и распаковка](#перебор-элементов-множества-и-распаковка) 67 | - [Сравнение множеств](#сравнение-множеств) 68 | - [Методы множеств](#методы-множеств) 69 | - [Генераторы множеств](#генераторы-множеств) 70 | - [frozenset](#frozenset) 71 | - [Словари](#словари) 72 | - [Введение](#введение-2) 73 | - [Создание словаря](#создание-словаря) 74 | - [Создание пустого словаря](#создание-пустого-словаря) 75 | - [Важные детали](#важные-детали) 76 | - [Основы (len, sum, min, max, in)](#основы-len-sum-min-max-in-2) 77 | - [Сравнение словарей](#сравнение-словарей) 78 | - [Перебор элементов словаря](#перебор-элементов-словаря) 79 | - [Распаковка словарей](#распаковка-словарей) 80 | - [Методы keys(), values(), items()](#методы-keys-values-items) 81 | - [Сортировка словарей](#сортировка-словарей) 82 | - [Методы словарей](#методы-словарей) 83 | - [Генераторы словарей](#генераторы-словарей) 84 | - [Вложенные словари](#вложенные-словари) 85 | - [Модули random, string, Метод Монте-Карло, Bogosort](#модули-random-string-метод-монте-карло-bogosort) 86 | - [Модуль random](#модуль-random) 87 | - [Модуль string](#модуль-string) 88 | - [Метод Монте-Карло](#метод-монте-карло) 89 | - [Bogosort](#bogosort) 90 | - [Модули decimal, fractions и complex](#модули-decimal-fractions-и-complex) 91 | - [Модуль decimal: введение](#модуль-decimal-введение) 92 | - [Создание Decimal чисел](#создание-decimal-чисел) 93 | - [Арифметические операции над Decimal числами](#арифметические-операции-над-decimal-числами) 94 | - [Математические функции Decimal чисел](#математические-функции-decimal-чисел) 95 | - [Работа с контекстом Decimal чисел](#работа-с-контекстом-decimal-чисел) 96 | - [Точность Decimal чисел](#точность-decimal-чисел) 97 | - [Округление Decimal чисел](#округление-decimal-чисел) 98 | - [Сравнение float и Decimal чисел](#сравнение-float-и-decimal-чисел) 99 | - [Важные примечания для decimal](#важные-примечания-для-decimal) 100 | - [Модуль fractions: введение](#модуль-fractions-введение) 101 | - [Тип данных Fraction](#тип-данных-fraction) 102 | - [Создание Fraction чисел](#создание-fraction-чисел) 103 | - [Основы типа данных Fraction](#основы-типа-данных-fraction) 104 | - [Сравнение Fraction чисел](#сравнение-fraction-чисел) 105 | - [Арифметические операции над Fraction числами](#арифметические-операции-над-fraction-числами) 106 | - [Математические функции](#математические-функции) 107 | - [Свойства numerator и denominator, as_integer_ratio()](#свойства-numerator-и-denominator-as_integer_ratio) 108 | - [Метод limit_denominator()](#метод-limit_denominator) 109 | - [Комплексные числа: введение](#комплексные-числа-введение) 110 | - [Комплексные числа в математике](#комплексные-числа-в-математике) 111 | - [Комплексные числа в Python](#комплексные-числа-в-python) 112 | - [Создание комплексных чисел](#создание-комплексных-чисел) 113 | - [Арифметические операции над комплексными числами](#арифметические-операции-над-комплексными-числами) 114 | - [Методы и свойства комплексных чисел](#методы-и-свойства-комплексных-чисел) 115 | - [cmath](#cmath) 116 | - [Модуль turtle](#модуль-turtle) 117 | - [Введение в turtle](#введение-в-turtle) 118 | - [Рисование отрезков прямой](#рисование-отрезков-прямой) 119 | - [Поворот черепашки](#поворот-черепашки) 120 | - [Изменение внешнего вида черепашки](#изменение-внешнего-вида-черепашки) 121 | - [Поднятие и опускание пера](#поднятие-и-опускание-пера) 122 | - [Рисование кругов и точек](#рисование-кругов-и-точек) 123 | - [Изменение размера пера](#изменение-размера-пера) 124 | - [Изменение цвета рисунка](#изменение-цвета-рисунка) 125 | - [Изменение цвета фона](#изменение-цвета-фона) 126 | - [Создание штампа](#создание-штампа) 127 | - [Возвращение экрана в исходное состояние](#возвращение-экрана-в-исходное-состояние) 128 | - [Размер окна](#размер-окна) 129 | - [Перемещение черепашки в заданную позицию](#перемещение-черепашки-в-заданную-позицию) 130 | - [Получение текущей позиции черепашки](#получение-текущей-позиции-черепашки) 131 | - [Сокрытие черепашки](#сокрытие-черепашки) 132 | - [Управление скоростью анимации черепахи](#управление-скоростью-анимации-черепахи) 133 | - [Вывод текста в графическое окно](#вывод-текста-в-графическое-окно) 134 | - [Заполнение геометрических фигур](#заполнение-геометрических-фигур) 135 | - [Создание нескольких черепашек](#создание-нескольких-черепашек) 136 | - [Отслеживание нажатия клавиш](#отслеживание-нажатия-клавиш) 137 | - [Отслеживание нажатия мыши](#отслеживание-нажатия-мыши) 138 | - [Функции](#функции) 139 | - [Функции без параметров](#функции-без-параметров) 140 | - [Функции с параметрами](#функции-с-параметрами) 141 | - [Глобальные, нелокальные и локальные переменные](#глобальные-нелокальные-и-локальные-переменные) 142 | - [Функции с возвратом значения](#функции-с-возвратом-значения) 143 | - [Позиционные и именованные аргументы](#позиционные-и-именованные-аргументы) 144 | - [Необязательные аргументы](#необязательные-аргументы) 145 | - [Изменяемые типы в качестве значений по умолчанию](#изменяемые-типы-в-качестве-значений-по-умолчанию) 146 | - [Переменное количество аргументов (*args, **kwargs)](#переменное-количество-аргументов-args-kwargs) 147 | - [Передача аргументов в форме списка и кортежа](#передача-аргументов-в-форме-списка-и-кортежа) 148 | - [Получение именованных аргументов в виде словаря](#получение-именованных-аргументов-в-виде-словаря) 149 | - [Keyword-only и positional-only аргументы](#keyword-only-и-positional-only-аргументы) 150 | - [Функции как объекты](#функции-как-объекты) 151 | - [Функции в качестве аргументов других функций](#функции-в-качестве-аргументов-других-функций) 152 | - [key в min(), max(), sort(), sorted()](#key-в-min-max-sort-sorted) 153 | - [Функции в качестве возвращаемых значений других функций (вложенные функции)](#функции-в-качестве-возвращаемых-значений-других-функций-вложенные-функции) 154 | - [Функции высшего порядка](#функции-высшего-порядка) 155 | - [map()](#map) 156 | - [filter()](#filter) 157 | - [reduce()](#reduce) 158 | - [Модуль operator](#модуль-operator) 159 | - [Анонимные функции (lambda): введение](#анонимные-функции-lambda-введение) 160 | - [Анонимные функции (lambda): основы, тернарный оператор](#анонимные-функции-lambda-основы-тернарный-оператор) 161 | - [all(), any()](#all-any) 162 | - [enumerate()](#enumerate) 163 | - [zip()](#zip) 164 | - [Рекурсия](#рекурсия) 165 | - [Декораторы](#декораторы) 166 | - [Работа с файлами](#работа-с-файлами) 167 | - [Введение](#введение-3) 168 | - [languages.txt](#languagestxt) 169 | - [Открытие файлов](#открытие-файлов) 170 | - [Указание места расположения файла, сырые строки](#указание-места-расположения-файла-сырые-строки) 171 | - [Кодировка](#кодировка) 172 | - [Закрытие файлов](#закрытие-файлов) 173 | - [read(), readline(), readlines()](#read-readline-readlines) 174 | - [Бинарные файлы](#бинарные-файлы) 175 | - [Свойства файла](#свойства-файла) 176 | - [Позиция в файле (курсор)](#позиция-в-файле-курсор) 177 | - [seek(), tell()](#seek-tell) 178 | - [Менеджер контекста](#менеджер-контекста) 179 | - [write(), writelines(), запись в файл при помощи print()](#write-writelines-запись-в-файл-при-помощи-print) 180 | - [Интересные штуки](#интересные-штуки) 181 | - [Числовая угадайка](#числовая-угадайка) 182 | - [Магический шар 8](#магический-шар-8) 183 | - [Генератор безопасных паролей](#генератор-безопасных-паролей) 184 | - [Калькулятор систем счисления (bin(), oct(), hex())](#калькулятор-систем-счисления-bin-oct-hex) 185 | - [Угадайка слов](#угадайка-слов) 186 | - [Не вошедшее в конспект](#не-вошедшее-в-конспект) 187 | - [Исключения (try-except-else-finally)](#исключения-try-except-else-finally) 188 | - [Итераторы и генераторы](#итераторы-и-генераторы) 189 | - [Малоизвестные (или не мало) функции](#малоизвестные-или-не-мало-функции) 190 | - [Спецификаторы](#спецификаторы) 191 | - [Спецсимволы и экранирование](#спецсимволы-и-экранирование) 192 | - [Неявная конкатенация](#неявная-конкатенация) 193 | - [Моржовый оператор](#моржовый-оператор) 194 | - [Присвоение цепочкой](#присвоение-цепочкой) 195 | - [Константы](#константы) 196 | - [Docstrings (Докстринги)](#docstrings-докстринги) 197 | - [Многоточие (…) как объект](#многоточие-как-объект) 198 | - [Атрибуты функций](#атрибуты-функций) 199 | - [locals(), globals()](#locals-globals) 200 | - [maketrans(), translate()](#maketrans-translate) 201 | 202 | 203 | Copyright (c) 2025 FerrumVega 204 | В конспекте использованы примеры и картинки из курсов https://stepik.org/course/58852 и https://stepik.org/course/68343. 205 | # Ввод-вывод 206 | ## Базовые команды 207 | Для ввода используется команда `input()` 208 | Для вывода команда `print()` 209 | 210 | Для присвоения переменной значения используют знак `=` 211 | ```python 212 | a = 5 213 | print(a) 214 | >>> 5 215 | ``` 216 | ## sep, end 217 | С помощью `sep `и `end `можно установить знак между аргументами и конец строки в `print() ` 218 | Пример: 219 | ```python 220 | print("Hello", "World", sep="*", end="/") 221 | >>> Hello*World/ 222 | 223 | ``` 224 | ## Арифметика и её приоритеты 225 | ```python 226 | + # сложение 227 | - # вычитание 228 | / # деление 229 | * # умножение 230 | ** # возведение в степень 231 | % # остаток от деления 232 | // # целочисленное деление 233 | ``` 234 | Приоритеты (сверху самый высокий): 235 | ```python 236 | 1. () 237 | 2. ** 238 | 3. - (унарный минус) 239 | 4. *, /, //, % 240 | 5. +, - 241 | 242 | 243 | ``` 244 | # Логические операторы и их приоритеты 245 | ## If-elif-else 246 | ```python 247 | answer = input('Какой язык программирования мы изучаем?') 248 | 249 | if answer == 'Python': 250 | print('Верно! Мы ботаем Python =)') 251 | print('Python - отличный язык!') 252 | elif answer == "C++": 253 | print('C++ тоже уважаем :)') 254 | else: 255 | print('Не знаю такого :(') 256 | ``` 257 | ## Операторы сравнения 258 | | Выражение | Описание | 259 | |---|---| 260 | | if x > 7 | если x больше 7 | 261 | | if x < 7 | если x меньше 7 | 262 | | if x >= 7 | если x больше либо равен 7 | 263 | | if x <= 7 | если x меньше либо равен 7 | 264 | | if x == 7 | если x равен 7 | 265 | | if x != 7 | если x не равен 7 | 266 | 267 | Также можно использовать цепочки: `a == b == c` 268 | 269 | ## or, and, not 270 | ```python 271 | or # логическое сложение 272 | and # логическое умножение 273 | not # логическое отрицание 274 | ``` 275 | Приоритеты (сверху самый высокий): 276 | ```python 277 | 1. not 278 | 2. and 279 | 3. or 280 | 281 | ``` 282 | # Типы данных 283 | ## Числовые типы данных 284 | ```python 285 | int(n) # целочисленный тип данных (1) 286 | float(n) # число с плавающей точкой (0.1) 287 | max(a, b ... n) # максимальное число 288 | min(a, b ... n) # минимальное число 289 | abs(n) # абсолютная величина числа (модуль) 290 | 291 | ``` 292 | Существует функция `divmod()`, которая возвращает кортеж из целочисленного частного x и y, и остатка от целочисленного частного из x и y: 293 | ```python 294 | print(divmod(5, 2)) 295 | >>> (2, 1) 296 | ``` 297 | ## Строковый тип данных 298 | ```python 299 | str("string") # преобразование в строку 300 | len("string") # длина строки 301 | 302 | print("ab"+"bc") # конкатенация (сложение строк) 303 | >>> abbc 304 | 305 | print("Hi" * 4) # умножение строки 306 | >>> HiHiHiHi 307 | 308 | text = """ 309 | многострочный текст выделяется 310 | тройными кавычками 311 | """ 312 | 313 | print("ab" in "abc") 314 | >>> True 315 | print("ac" in "abc") 316 | >>> False 317 | print("AB" in "abc") 318 | >>> False # in чувствителен к регистру 319 | 320 | ``` 321 | ## Модуль math 322 | Существует 2 вида импорта модулей: 323 | ```python 324 | 1. import math 325 | 2. from math import * 326 | ``` 327 | При использовании первого нужно использовать команды так: 328 | ```python 329 | math.sqrt(25) 330 | ``` 331 | При использовании второго: 332 | ```python 333 | sqrt(25) 334 | ``` 335 | Второй метод проще, но при нём могут возникнуть конфликты из-за одинаковых команд в разных модулях 336 | Также можно импортировать всего несколько команд, а не все из модуля: 337 | ```python 338 | from math import sqrt 339 | sqrt(25) 340 | 341 | 342 | ``` 343 | Список функций модуля math 344 | | Функция | Описание | 345 | |---|---| 346 | | Округления | | 347 | | int() | Округляет число в сторону нуля | 348 | | round(x) | Округляет число x до ближайшего целого. Если дробная часть числа равна 0.50.5, то число округляется до ближайшего четного числа (банковское округление) | 349 | | round(x, n) | Округляет число x до n знаков после точки | 350 | | floor(x) | Округляет число x вниз («пол») | 351 | | ceil(x) | Округляет число x вверх («потолок») | 352 | | abs(x) | Модуль числа x (абсолютная величина) | 353 | | Корни, логарифмы, степени и факториал | | 354 | | sqrt(x) | Квадратный корень числа x | 355 | | pow(x, n) | Возведение числа x в степень n | 356 | | log(x) | Натуральный логарифм числа x. Основание натурального логарифма равно числу e | 357 | | log10(x) | Десятичный логарифм числа x. Основание десятичного логарифма равно числу 10 | 358 | | log(x, b) | Логарифм числа x по основанию b | 359 | | factorial(n) | Факториал натурального числа n | 360 | | Тригонометрия | | 361 | | degrees(x) | Преобразует угол x, заданный в радианах, в градусы | 362 | | radians(x) | Преобразует угол x, заданный в градусах, в радианы | 363 | | cos(x) | Косинус угла x, задаваемого в радианах | 364 | | sin(x) | Синус угла x, задаваемого в радианах | 365 | | tan(x) | Тангенс угла x, задаваемого в радианах | 366 | | acos(x) | Возвращает угол в радианах от 0 до π, cos которого равен x | 367 | | asin(x) | Возвращает угол в радианах от −π2−2π​ до π22π​, sin которого равен x | 368 | | atan(x) | Возвращает угол в радианах от −π2−2π​ до π22π​, tan которого равен x | 369 | | atan2(y, x) | Полярный угол (в радианах) точки с координатами (x, y) | 370 | 371 | Python имеет и встроенную команду `round().` 372 | # Циклы 373 | ## For 374 | for перебирает все значения из итератора и заполняет переменную текущим значением. 375 | С одним аргументом (от нуля до n-1): 376 | ```python 377 | for i in range(10): 378 | print(i) 379 | >>> 0 380 | >>> 1 381 | >>> 2 382 | >>> 3 383 | >>> 4 384 | >>> 5 385 | >>> 6 386 | >>> 7 387 | >>> 8 388 | >>> 9 389 | ``` 390 | С двумя аргументами (от m до n-1): 391 | ```python 392 | for i in range(1, 10): 393 | print(i) 394 | >>> 1 395 | >>> 2 396 | >>> 3 397 | >>> 4 398 | >>> 5 399 | >>> 6 400 | >>> 7 401 | >>> 8 402 | >>> 9 403 | ``` 404 | С тремя аргументами (от m до n-1 с шагом k): 405 | ```python 406 | for i in range(1, 10, 2): # третий аргумент - величина шага 407 | print(i) 408 | >>> 1 409 | >>> 3 410 | >>> 5 411 | >>> 7 412 | >>> 9 413 | 414 | ``` 415 | ## Частые сценарии 416 | - Подсчёт количества 417 | ```python 418 | counter = 0 419 | for _ in range(10): 420 | num = int(input()) 421 | if num > 10: 422 | counter = counter + 1 423 | 424 | print('Было введено', counter, 'чисел, больших 10.') 425 | 426 | ``` 427 | - Обмен значений переменных 428 | Вместо: 429 | ```python 430 | temp = x 431 | x = y 432 | y = temp 433 | ``` 434 | Можно использовать: 435 | ```python 436 | x, y = y, x 437 | 438 | ``` 439 | - Сигнальные метки 440 | ```python 441 | num = int(input()) 442 | flag = True 443 | 444 | for i in range(2, num): 445 | if num % i == 0: # если исходное число делится на какое-либо отличное от 1 и самого себя 446 | flag = False 447 | 448 | if num == 1: 449 | print('Это единица, она не простая и не составная') 450 | elif flag == True: 451 | print('Число простое') 452 | else: 453 | print('Число составное') 454 | 455 | ``` 456 | - Максимум и минимум 457 | ```python 458 | largest = 0 459 | for _ in range(10): 460 | num = int(input()) 461 | if num > largest: 462 | largest = num 463 | 464 | print('Наибольшее число равно', largest) 465 | 466 | ``` 467 | - Расширенные операторы присваивания 468 | | Оператор | Пример использования | Эквивалент | 469 | |---|---|---| 470 | | += | x += 5 | x = x + 5 | 471 | | -= | x -= 2 | x = x - 2 | 472 | | *= | x *= 10 | x = x * 10 | 473 | | /= | x /= 4 | x = x / 4 | 474 | | //= | x //= 4 | x = x // 4 | 475 | | %= | x %= 4 | x = x % 4 | 476 | 477 | ## While 478 | While выполняет команды внутри себя пока условие(-я) выполняется(-ются) 479 | - Обработка цифр числа: 480 | ```python 481 | n = int(input()) 482 | while n != 0: # пока в числе есть цифры 483 | last_digit = n % 10 # получить последнюю цифру 484 | # код обработки последней цифры 485 | n = n // 10 # удалить последнюю цифру из числа 486 | 487 | ``` 488 | - «До остановки»: 489 | ```python 490 | text = input() 491 | total = 0 492 | while text != "stop": 493 | total += int(text) 494 | text = input() 495 | print("Сумма чисел равна", total) 496 | 497 | ``` 498 | ## while: break, continue, else 499 | `break `завершает цикл 500 | Проверка числа на простоту: 501 | ```python 502 | num = int(input()) 503 | flag = True 504 | 505 | for i in range(2, num): 506 | if num % i == 0: # если исходное число делится на какое-либо отличное от 1 и самого себя 507 | flag = False 508 | break # останавливаем цикл если встретился делитель числа 509 | if flag: # эквивалентно if flag == True: 510 | print('Число простое') 511 | else: 512 | print('Число составное') 513 | 514 | ``` 515 | `continue `позволяет перейти к следующей итерации цикла `for `или `while `до завершения всех команд в теле цикла. 516 | Программа, которая выводит все числа от 1 до 100, кроме чисел 7, 17, 29 и 78: 517 | ```python 518 | for i in range(1, 101): 519 | if i == 7 or i == 17 or i == 29 or i == 78: 520 | continue # переходим на следующую итерацию 521 | print(i) 522 | 523 | ``` 524 | Python допускает необязательный блок `else `в конце циклов `while` и `for`. Это уникальная особенность Python, не встречающаяся в большинстве других языков программирования. `else `выполнится, если цикл завершился без `break`. Синтаксис такой конструкции следующий: 525 | ```python 526 | while условие: 527 | блок кода1 528 | else: 529 | блок кода2 530 | 531 | # или 532 | 533 | for i in range(10): 534 | блок кода1 535 | else: 536 | блок кода2 537 | ``` 538 | Пример: 539 | ```python 540 | n = 5 541 | while n > 0: 542 | n -= 1 543 | print(n) 544 | else: 545 | print("Цикл завершен.") 546 | 547 | ``` 548 | ## Вложенные циклы 549 | ```python 550 | for hours in range(24): 551 | for minutes in range(60): 552 | for seconds in range(60): 553 | print(hours, ':', minutes, ':', seconds) 554 | >>> 0 : 0 : 0 555 | >>> 0 : 0 : 1 556 | >>> 0 : 0 : 2 557 | ... 558 | >>> 23 : 59 : 58 559 | >>> 23 : 59 : 59 560 | ``` 561 | При помощи вложенных циклов можно решать уравнения: 562 | Уравнение 12x+13y=777. 563 | Решение: 564 | ```python 565 | for x in range(777): 566 | for y in range(777): 567 | if 12 * x + 13 * y == 777: 568 | print(x, y) 569 | 570 | ``` 571 | # Строки 572 | ## Индексация строк 573 | ![Image 1](images/image_1.png) 574 | Пример вывода символа из строки: 575 | ```python 576 | s = 'Python' 577 | print(s[1]) # выводит символ с индексом 1 (2 с начала) 578 | print(s[-3]) # выводит символ с индексом -3 (3 с конца) 579 | >>> y 580 | >>> h 581 | 582 | ``` 583 | ## Вывод символов строки 584 | Для вывода каждого символа на новой строке используют такую конструкцию: 585 | ```python 586 | s = 'abcdef' 587 | for i in range(len(s)): 588 | print(s[i]) 589 | >>> a 590 | >>> b 591 | >>> c 592 | >>> d 593 | >>> e 594 | >>> f 595 | 596 | ``` 597 | ## Срезы строк 598 | Срез выводит символы с x по y (правильнее будет сказать с x по y-1) 599 | ![Image 2](images/image_2.png) 600 | ```python 601 | s = 'abcdefghij' 602 | print(s[2:5]) 603 | >>> cde 604 | ``` 605 | Также можно опускать параметры в срезах 606 | ![Image 3](images/image_3.png) 607 | ![Image 4](images/image_4.png) 608 | ```python 609 | s = 'abcdefghij' 610 | print(s[2:]) 611 | print(s[:7]) 612 | >>> cdefghij 613 | >>> abcdefg 614 | ``` 615 | Также можно указать шаг среза, например, срез `s[1:7:2] `создаст строку bdf состоящую из каждого второго символа (индексы 1, 3, 5) 616 | ![Image 5](images/image_5.png) 617 | Можно указать отрицательный шаг среза: 618 | | s = 'abcdefghij' | s = 'abcdefghij' | s = 'abcdefghij' | 619 | |---|---|---| 620 | | Программный код | Результат | Пояснение | 621 | | s[2:5] | cde | строка состоящая из символов с индексами 2, 3, 4 | 622 | | s[:5] | abcde | первые пять символов строки | 623 | | s[5:] | fghij | строка состоящая из символов с индексами от 5 до конца | 624 | | s[-2:] | ij | последние два символа строки | 625 | | s[:] | abcdefghij | вся строка целиком | 626 | | s[1:7:2] | bdf | строка, состоящая из каждого второго символа с индексами от 1 до 6 | 627 | | s[::-1] | jihgfedcba | строка в обратном порядке, так как шаг отрицательный | 628 | ```python 629 | s = 'abcdefghij' 630 | print(s[::-1]) 631 | >>> jihgfedcba 632 | 633 | ``` 634 | Изменение символа строки по индексу 635 | Предположим, у нас есть строка `s = 'abcdefghij' `и мы хотим заменить символ с индексом 4 на 'X'. Можно попытаться написать код: 636 | ```python 637 | s[4] = 'X' 638 | ``` 639 | Однако такой код не работает. В Python строки являются неизменяемыми, то есть мы не можем менять их содержимое с помощью индексатора. 640 | Правильный код: 641 | ```python 642 | s = s[:4] + 'X' + s[5:] 643 | 644 | ``` 645 | Можно присваивать переменным срезы: 646 | ```python 647 | a = slice(1, -1, 3) 648 | print("ABCDEFGHI"[a]) 649 | >>> BEH 650 | 651 | ``` 652 | ## Методы строк 653 | Методы к строкам применяются так: строка.метод 654 | - Конвертация регистра 655 | ```python 656 | s = 'foO BaR BAZ quX' 657 | 658 | 659 | print(s.capitalize()) # Первое слово с большой буквы, остальные - с маленькой 660 | >>> Foo bar baz qux 661 | 662 | print(s.swapcase()) # Меняет регистр всех символов на противоположный 663 | >>> FOo bAr baz QUx 664 | 665 | print(s.title()) # Каждое слово начинается с заглавной буквы 666 | >>> Foo Bar Baz Qux 667 | 668 | print(s.lower()) # Все символы приводятся к нижнему регистру 669 | >>> foo bar baz qux 670 | 671 | print(s.upper()) # Все символы приводятся к верхнему регистру 672 | >>> FOO BAR BAZ QUX 673 | 674 | 675 | a = "ßßß" 676 | b = "SSSSSS" 677 | print(a.casefold() == b.casefold()) # Переводит все символы в нижний регистр (Полезно при работе с немецким языком) 678 | >>> True 679 | 680 | ``` 681 | - Поиск и замена 682 | ```python 683 | s = 'foo bar foo baz foo qux' 684 | 685 | # Метод count(, , ) - количество вхождений подстроки 686 | print(s.count('foo')) 687 | print(s.count('foo', 0, 10)) 688 | >>> 3 689 | >>> 1 690 | 691 | # Метод startswith(, , ) - проверка начала строки 692 | print(s.startswith('foo')) 693 | print(s.startswith('bar')) 694 | >>> True 695 | >>> False 696 | 697 | # Метод endswith(, , ) - проверка конца строки 698 | print(s.endswith('qux')) 699 | print(s.endswith('bar')) 700 | >>> True 701 | >>> False 702 | 703 | # Метод find(, , ) - индекс первого вхождения (или -1) 704 | print(s.find('foo')) 705 | print(s.find('python')) 706 | >>> 0 707 | >>> -1 708 | 709 | # Метод rfind(, , ) - поиск с конца строки 710 | print(s.rfind('foo')) 711 | print(s.rfind('python')) 712 | >>> 16 713 | >>> -1 714 | 715 | # Метод index(, , ) - как find(), но вызывает ошибку при отсутствии 716 | print(s.index('foo')) 717 | # print(s.index('python')) # Вызовет ValueError 718 | >>> 0 719 | 720 | # Метод rindex(, , ) - поиск с конца с ошибкой при отсутствии 721 | print(s.rindex('foo')) 722 | # print(s.rindex('python')) # Вызовет ValueError 723 | >>> 16 724 | 725 | s = ' foo bar foo baz foo qux ' 726 | 727 | # Метод strip() - удаляет пробелы с обоих концов 728 | print(s.strip()) 729 | >>> foo bar foo baz foo qux 730 | 731 | # Метод lstrip() - удаляет пробелы только слева 732 | print(s.lstrip()) 733 | >>> foo bar foo baz foo qux______ 734 | 735 | # Метод rstrip() - удаляет пробелы только справа 736 | print(s.rstrip()) 737 | >>> ______foo bar foo baz foo qux 738 | 739 | s = '-+-+abc+-+-' 740 | 741 | # Удаление указанных символов с обоих концов 742 | print(s.strip('+-')) 743 | >>> abc 744 | 745 | # Удаление указанных символов справа 746 | print(s.rstrip('+-')) 747 | >>> -+-+abc 748 | 749 | # Удаление указанных символов слева 750 | print(s.lstrip('+-')) 751 | >>> abc+-+- 752 | 753 | # Удаление указанного префикса (суффикса) 754 | print("-+-+abc+-+-".removeprefix("-+")) 755 | >>> -+abc+-+- 756 | print("-+-+abc+-+-".removesuffix("+-")) 757 | >>> -+-+abc+- 758 | 759 | s = 'foo bar foo baz foo qux' 760 | 761 | # Метод replace(, , ) - замена всех вхождений 762 | print(s.replace('foo', 'grault')) # Все вхождения 763 | >>> grault bar grault baz grault qux 764 | 765 | print(s.replace('foo', 'grault', 2)) # Только 2 первых замены 766 | >>> grault bar grault baz foo qux0 767 | 768 | # Разделение на строки 769 | text_with_lot_of_lines = """A 770 | B 771 | C 772 | D 773 | E""" 774 | print(text_with_lot_of_lines.splitlines()) 775 | >>> ['A', 'B', 'C', 'D', 'E'] 776 | 777 | # Дополнение строку нулями слева, чтобы её общая длина стала равна аргументу 778 | print("234".zfill(12)) 779 | >>> 000000000234 780 | 781 | ``` 782 | - Классификация символов 783 | ```python 784 | print('Python3'.isalnum()) # состоит ли строка только из букв и/или цифр 785 | >>> True 786 | 787 | print('Hello'.isalpha()) # состоит ли строка только из букв 788 | >>> True 789 | 790 | print('2023'.isdigit()) # состоит ли строка только из цифр 791 | >>> True 792 | 793 | print('python'.islower()) # все ли буквы в строке строчные 794 | >>> True 795 | 796 | print('PYTHON'.isupper()) # все ли буквы в строке заглавные 797 | >>> True 798 | 799 | print(' '.isspace()) # состоит ли строка только из пробелов 800 | >>> True 801 | 802 | ``` 803 | ## partition() 804 | Помимо метода `split() `строковый тип данных содержит метод `partition()`. Метод `partition()` принимает на вход один аргумент `sep`, разделяет строку при первом появлении `sep` и возвращает кортеж, состоящий из трех элементов: часть перед разделителем, сам разделитель и часть после разделителя. Если разделитель не найден, то кортеж содержит саму строку, за которой следуют две пустые строки. 805 | ```python 806 | s1 = 'abc-de'.partition('-') 807 | s2 = 'abc-de'.partition('.') 808 | s3 = 'abc-de-fgh'.partition('-') 809 | 810 | print(s1) 811 | print(s2) 812 | print(s3) 813 | >>> ('abc', '-', 'de') 814 | >>> ('abc-de', '', '') 815 | >>> ('abc', '-', 'de-fgh') 816 | 817 | ``` 818 | ## format(); format_map() 819 | В Python можно использовать заполнители: 820 | ```python 821 | birth_year = 1992 822 | name = 'Timur' 823 | profession = 'math teacher' 824 | text = 'My name is {}, I was born in {}, I work as a {}.'.format(name, birth_year, profession) 825 | 826 | print(text) 827 | >>> My name is Timur, I was born in 1992, I work as a math teacher. 828 | 829 | ``` 830 | Также можно несколько раз использовать один и тот же аргумент: 831 | ```python 832 | name = 'Timur' 833 | city = 'Moscow' 834 | text1 = 'My name is {0}-{0}-{0}!'.format(name, city) 835 | text2 = '{1} is my city and {0} is my name!'.format(name, city) 836 | 837 | print(text1) 838 | >>> My name is Timur-Timur-Timur! 839 | 840 | print(text2) 841 | >>> Moscow is my city and Timur is my name! 842 | 843 | ``` 844 | Также существует и функция `format():` 845 | Она применяет к первому аргументу форматирование (второй аргумент): 846 | ```python 847 | print(format(1.23456, ".2f")) # 2 цифры после запятой 848 | >>> 1.23 849 | 850 | ``` 851 | Есть и метод `format_map()`: 852 | ```python 853 | print("Привет, {name}".format_map({"name": "Никита"})) 854 | >>> Привет, Никита 855 | 856 | ``` 857 | ## f-строки 858 | Строки вида 859 | ```python 860 | name = 'Никита' 861 | print(name, "- мой друг") 862 | >>> Никита - мой друг 863 | ``` 864 | Можно изменить на: 865 | ```python 866 | name = 'Никита' 867 | print(f"{name} - мой друг") 868 | >>> Никита - мой друг 869 | ``` 870 | В f-строках переменные нужно указывать в {} скобках, а текст просто писать 871 | 872 | ## Строки в памяти компьютера 873 | Таблица ASCII: 874 | ![Image 6](images/image_6.png) 875 | Функция `ord() `позволяет определить код некоторого символа в таблице символов Unicode. 876 | ```python 877 | num1 = ord('A') 878 | num2 = ord('B') 879 | num3 = ord('a') 880 | print(num1, num2, num3) 881 | >>> 65 66 97 882 | ``` 883 | Функция `chr() `позволяет определить по коду символа сам символ. Аргументом данной функции является численный код. 884 | ```python 885 | chr1 = chr(65) 886 | chr2 = chr(75) 887 | chr3 = chr(110) 888 | print(chr1, chr2, chr3) 889 | >>> A K n 890 | 891 | ``` 892 | ## Сравнение строк 893 | Строки можно сравнивать, работает это по лексикографическому порядку (точнее, по ASCII) 894 | Строчные символы больше заглавных 895 | ```python 896 | print('d' > 'D') 897 | print('Ы' < 'ы') 898 | >>> True 899 | >>> True 900 | 901 | ``` 902 | # Списки 903 | ## Создание списка 904 | Списки могут содержать разные типы данных 905 | Список можно задать двумя способами: 906 | ```python 907 | a = [] 908 | a = list() 909 | 910 | ``` 911 | ## Основы (len, sum, min, max, in) 912 | ```python 913 | a = [1, 5, 3] 914 | 915 | print(len(a)) # длина списка (количество элементов) 916 | >>> 3 917 | 918 | print(sum(a)) # сумма элементов списка 919 | >>> 9 920 | 921 | print(min(a)) # минимум из списка 922 | >>> 1 923 | 924 | print(max(a)) # максимум из списка 925 | >>> 5 926 | 927 | print(1 in a) # есть ли элемент со значением 1 в списке a 928 | >>> True 929 | 930 | ``` 931 | В списках индексация, срезы, конкатенация и умножение аналогично строкам, только тут вместо символов строки элементы списка. 932 | 933 | Отличие списков от строк: 934 | Несмотря на всю схожесть списков и строк, есть одно очень важное отличие: строки — неизменяемые объекты, а списки – изменяемые. 935 | 936 | Список можно удобно заполнить порядковыми числами: 937 | ```python 938 | a = list(range(1, 10, 2)) 939 | print(a) 940 | >>> [1, 3, 5, 7, 9] 941 | 942 | ``` 943 | ## Добавление элементов 944 | `a.append()` - добавление элемента в конец списка 945 | ```python 946 | a = [1, 1, 2, 3, 5, 8, 13] 947 | a.append(21) # добавляем число 21 в конец списка 948 | a.append(34) # добавляем число 34 в конец списка 949 | print(a) 950 | >>> [1, 1, 2, 3, 5, 8, 13, 21, 34] 951 | 952 | ``` 953 | ## Объединение списков 954 | Чтобы объединить списки нужно использовать следующий метод: 955 | ```python 956 | a = [1, 2] 957 | b = [5, 7] 958 | a.extend(b) 959 | print(a) 960 | >>> [1, 2, 5, 7] 961 | 962 | ``` 963 | ## Удаление элементов 964 | Для удаления элементов используется инструкция `del` 965 | Эту инструкцию можно использовать и для удаления переменных 966 | ```python 967 | a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 968 | del a[5] # удаляем элемент, имеющий индекс 5 969 | print(a) 970 | >>> [1, 2, 3, 4, 5, 7, 8, 9] 971 | 972 | ``` 973 | ## Вывод элементов списка 974 | - Вывод через цикл 975 | ```python 976 | a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 977 | for i in range(len(a)): 978 | print(a[i]) 979 | >>> 0 980 | >>> 1 981 | >>> 2 982 | >>> 3 983 | >>> 4 984 | >>> 5 985 | >>> 6 986 | >>> 7 987 | >>> 8 988 | >>> 9 989 | >>> 10 990 | 991 | ``` 992 | - Распаковка списка 993 | ```python 994 | a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 995 | print(*a) 996 | >>> 0 1 2 3 4 5 6 7 8 9 10 997 | 998 | ``` 999 | - Распаковка списка и вывод каждого элемента на новой строке 1000 | ```python 1001 | a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 1002 | print(*a, sep="\n") 1003 | >>> 0 1004 | >>> 1 1005 | >>> 2 1006 | >>> 3 1007 | >>> 4 1008 | >>> 5 1009 | >>> 6 1010 | >>> 7 1011 | >>> 8 1012 | >>> 9 1013 | >>> 10 1014 | 1015 | ``` 1016 | ## split(), join() 1017 | Метод `split()` разбивает строку на слова, используя в качестве разделителя последовательность пробельных символов, и возвращает список из этих слов. 1018 | ```python 1019 | s = 'Python is the most powerful language' 1020 | words = s.split() 1021 | print(words) 1022 | >>> ['Python', 'is', 'the', 'most', 'powerful', 'language'] 1023 | ``` 1024 | Также можно указать аргумент, который будет разделителем: 1025 | ```python 1026 | ip = '192.168.1.24' 1027 | numbers = ip.split('.') # указываем явно разделитель 1028 | print(numbers) 1029 | >>> ['192', '168', '1', '24'] 1030 | 1031 | ``` 1032 | Метод `join()` собирает строку из элементов списка, используя в качестве разделителя строку, к которой применяется метод. 1033 | ```python 1034 | words = ['Python', 'is', 'the', 'most', 'powerful', 'language'] 1035 | s = ' '.join(words) 1036 | print(s) 1037 | >>> Python is the most powerful language 1038 | 1039 | ``` 1040 | Шпаргалки: 1041 | ![Image 7](images/image_7.png) 1042 | ![Image 8](images/image_8.png) 1043 | ![Image 9](images/image_9.png) 1044 | 1045 | ## Методы списков 1046 | ```python 1047 | s = [1, 3, 5] 1048 | s.insert(4, 2) # вставляет 2 в индекс 4 1049 | print(s) 1050 | >>> [1, 3, 5, 2] 1051 | 1052 | s = [1, 3, 5] 1053 | print(s.index(3)) # выводит индекс первого вхождения 3 список s 1054 | >>> 1 1055 | 1056 | s = [1, 3, 5] 1057 | s.remove(3) # удаляет первое вхождение элемента 3 1058 | print(s) 1059 | >>> [1, 5] 1060 | 1061 | s = [1, 3, 5] 1062 | s.pop(2) # удаляет элемент с индексом 2 1063 | print(s) 1064 | >>> [1, 3] 1065 | 1066 | s = [1, 3, 3, 3, 3, 5] 1067 | print(s.count(3)) # выводит количество элементов со значением 3 1068 | >>> 4 1069 | 1070 | s = [1, 3, 5] 1071 | s.reverse() # переворачивает список 1072 | print(s) 1073 | >>> [5, 3, 1] 1074 | 1075 | s = [1, 3, 5] 1076 | s.clear() # очищает список 1077 | print(s) 1078 | >>> [] 1079 | 1080 | s = [1, 3, 5] 1081 | g = s.copy() # делает копия списка, при изменении оригинала копия тоже изменяется 1082 | print(g) 1083 | >>> [1, 3, 5] 1084 | 1085 | ``` 1086 | ## Сортировка списков 1087 | В Python списки имеют встроенный метод `sort()`, который сортирует элементы списка по возрастанию или убыванию. 1088 | ```python 1089 | a = [1, 7, -3, 9, 0, -67, 34, 12, 45, 1000, 6, 8, -2, 99] 1090 | a.sort() 1091 | print('Отсортированный список:', a) 1092 | >>> Отсортированный список: [-67, -3, -2, 0, 1, 6, 7, 8, 9, 12, 34, 45, 99, 1000] 1093 | ``` 1094 | Также можно сортировать по убыванию. Если требуется отсортировать список по убыванию, необходимо явно указать параметр `reverse = True.` 1095 | ```python 1096 | a = [1, 7, -3, 9, 0, -67, 34, 12, 45, 1000, 6, 8, -2, 99] 1097 | a.sort(reverse=True) # сортируем по убыванию 1098 | print('Отсортированный список:', a) 1099 | >>> Отсортированный список: [1000, 99, 45, 34, 12, 9, 8, 7, 6, 1, 0, -2, -3, -67] 1100 | ``` 1101 | Функция `sorted() `возвращает отсортированный список, не изменяя оригинальный. 1102 | ```python 1103 | a = [1, 5, 3] 1104 | print(sorted(a)) 1105 | >>> [1, 3, 5] 1106 | ``` 1107 | ## Генераторы списков; списочные выражения 1108 | ```python 1109 | numbers = [i for i in range(10)] # числа от 0 до 9 1110 | print(numbers) 1111 | >>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 1112 | 1113 | numbers = [i**2 for i in range(10)] # квадраты чисел от 0 до 9 1114 | print(numbers) 1115 | >>> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 1116 | 1117 | numbers = [int(input()) for i in range(int(input()))] # ввод n чисел с клавиатуры 1118 | print(numbers) 1119 | <<< 5 1120 | <<< 1 1121 | <<< 2 1122 | <<< 3 1123 | <<< 4 1124 | <<< 5 1125 | >>> [1, 2, 3, 4, 5] 1126 | 1127 | numbers = [i * j for i in range(1, 5) for j in range(2)] # вложенные циклы 1128 | print(numbers) 1129 | >>> [0, 1, 0, 2, 0, 3, 0, 4] 1130 | 1131 | numbers = [i for i in range(21) if i % 2 == 0] # четные числа от 0 до 20 (условие в списочном выражении) 1132 | print(numbers) 1133 | >>> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20] 1134 | ``` 1135 | В списочных выражениях нельзя использовать `else` и несколько условий. 1136 | 1137 | ## Нахождение чисел палиндромов 1138 | Во-первых, вот что такое палиндром: 1139 | Числа-палиндромы — числа, которые в определённой позиционной системе исчисления (как правило — в десятичной) читаются одинаково как справа налево, так и слева направо. 1140 | Достаточно просто доказать, что чисел-палиндромов бесконечно много. Одним из способов доказательства является замена любой выбранной цифры в их написании двумя любыми другими цифрами, в результате чего получается новое число-палиндром. 1141 | ```python 1142 | palindromes = [i for i in range(100, 1001) if i == int(str(i)[::-1])] 1143 | print(palindromes) 1144 | 1145 | ``` 1146 | ## Методы сортировки списков 1147 | - Сортировка пузырьком 1148 | Алгоритм сортировки пузырьком состоит из повторяющихся проходов по сортируемому списку. За каждый проход элементы последовательно сравниваются попарно и, если порядок в паре неверный, выполняется обмен элементов. Проходы по списку повторяются n−1 раз, где n – длина списка. При каждом проходе алгоритма по внутреннему циклу, очередной наибольший элемент списка ставится на свое место в конце списка рядом с предыдущим «наибольшим элементом». 1149 | Наибольший элемент каждый раз «всплывает» до нужной позиции, как пузырёк в воде — отсюда и название алгоритма. 1150 | 1151 | Алгоритм пузырьковой сортировки считается учебным и практически не применяется вне учебной литературы, а на практике применяются более эффективные. 1152 | 1153 | Реализация: 1154 | ```python 1155 | a = [1, 7, -3, 9, 0, -67, 34, 12, 45, 1000, 6, 8, -2, 99] 1156 | n = len(a) 1157 | 1158 | for i in range(n - 1): 1159 | for j in range(n - 1 - i): 1160 | if a[j] > a[j + 1]: # если порядок элементов пары неправильный 1161 | a[j], a[j + 1] = a[j + 1], a[j] # меняем элементы пары местами 1162 | 1163 | print('Отсортированный список:', a) 1164 | 1165 | ``` 1166 | - Сортировка выбором 1167 | Сортировка выбором улучшает пузырьковую сортировку, совершая всего один обмен за каждый проход по списку. Для этого алгоритм ищет максимальный элемент и помещает его на соответствующую позицию. Как и для пузырьковой сортировки, после первого прохода самый большой элемент находится на правильном месте. После второго прохода на своё место становится следующий максимальный элемент. Проходы по списку повторяются n−1 раз, где n – длина списка, поскольку последний из них автоматически оказывается на своем месте. 1168 | 1169 | Алгоритм сортировки выбором также считается учебным и практически не применяется вне учебной литературы. На практике используют более эффективные алгоритмы. 1170 | 1171 | Реализация: 1172 | ```python 1173 | a = [78, -32, 5, 39, 58, -5, -63, 57, 72, 9, 53, -1, 63, -97, -21, -94, -47, 57, -8, 60, -23, -72, -22, -79, 90, 96, -41, -71, -48, 84, 89, -96, 41, -16, 94, -60, -64, -39, 60, -14, -62, -19, -3, 32, 98, 14, 43, 3, -56, 71, -71, -67, 80, 27, 92, 92, -64, 0, -77, 2, -26, 41, 3, -31, 48, 39, 20, -30, 35, 32, -58, 2, 63, 64, 66, 62, 82, -62, 9, -52, 35, -61, 87, 78, 93, -42, 87, -72, -10, -36, 61, -16, 59, 59, 22, -24, -67, 76, -94, 59] 1174 | 1175 | n = len(a) 1176 | 1177 | for i in range(n): 1178 | mx = max(a[:n - i]) 1179 | mx_ind = a.index(mx) 1180 | 1181 | a[n - 1 - i], a[mx_ind] = a[mx_ind], a[n - 1 - i] 1182 | 1183 | print('Отсортированный список:', a) 1184 | 1185 | ``` 1186 | - Сортировка простыми вставками 1187 | Алгоритм сортировки простыми вставками делит список на 2 части — отсортированную и неотсортированную. Из неотсортированной части извлекается очередной элемент и вставляется на нужную позицию в отсортированной части, в результате чего отсортированная часть списка увеличивается, а неотсортированная уменьшается. Так происходит, пока не исчерпан набор входных данных и не отсортированы все элементы. 1188 | 1189 | Сортировка простыми вставками наиболее эффективна, когда список уже частично отсортирован и элементов массива немного. Если элементов в списке меньше 10, то этот алгоритм - один из самых быстрых. 1190 | 1191 | Реализация: 1192 | ```python 1193 | a = [1, 7, -3, 9, 0, -67, 34, 12, 45, 1000, 6, 8, -2, 99] 1194 | n = len(a) 1195 | 1196 | for i in range(1, n): 1197 | elem = a[i] # берем первый элемент из неотсортированной части списка 1198 | j = i 1199 | 1200 | # пока элемент слева существует и больше нашего текущего элемента 1201 | while j >= 1 and a[j - 1] > elem: 1202 | # смещаем j-1-й элемент отсортированной части вправо 1203 | a[j] = a[j - 1] 1204 | # сами идём влево, дальше ищем место для нашего текущего элемента 1205 | j -= 1 1206 | 1207 | # нашли место для нащего текущего элемента из неотсортированной части 1208 | # и вставляем его на индекс j в отсортированной части 1209 | a[j] = elem 1210 | 1211 | print('Отсортированный список:', a) 1212 | 1213 | 1214 | ``` 1215 | # Тип данных bool и NoneType 1216 | ## bool 1217 | - bool может иметь значение `True `или `False`. 1218 | - `a and b `дает `True`, если оба операнда `True`, или `False`, если хотя бы один из них `False` 1219 | - `a or b `дает `False`, если оба операнда `False`, или `True`, если хотя бы один из них `Truef` 1220 | - `not a` дает `True`, если `a` имеет значение `False`, или `False`, если `a` имеет значение `True`. 1221 | 1222 | ```python 1223 | print(True == 1) 1224 | print(False == 0) 1225 | >>> True 1226 | >>> True 1227 | 1228 | print(True == 1) 1229 | print(False == 0) 1230 | >>> True 1231 | >>> True 1232 | ``` 1233 | Для приведения других типов данных к булеву существует функция `bool()`, работающая по следующим соглашениям: 1234 | - строки: пустая строка – ложь (`False`), непустая строка – истина (`True`) 1235 | - числа: нулевое число – ложь (`False`), ненулевое число (в том числе и меньшее нуля) – истина (`True`) 1236 | - списки: пустой список – ложь (`False`), непустой – истина (`True`). 1237 | 1238 | В языке Python имеется встроенная функция `isinstance()` для проверки соответствия типа объекта какому-либо типу данных. 1239 | ```python 1240 | print(isinstance(3, int)) 1241 | print(isinstance(3.5, float)) 1242 | print(isinstance('Beegeek', str)) 1243 | print(isinstance([1, 2, 3], list)) 1244 | print(isinstance(True, bool)) 1245 | >>> True 1246 | >>> True 1247 | >>> True 1248 | >>> True 1249 | >>> True 1250 | 1251 | ``` 1252 | В языке Python имеется встроенная функция `type()`, позволяющая получить тип указанного в качестве аргумента объекта. 1253 | ```python 1254 | print(type(3)) 1255 | print(type(3.5)) 1256 | print(type('Beegeek')) 1257 | print(type([1, 2, 3])) 1258 | print(type(True)) 1259 | >>> 1260 | >>> 1261 | >>> 1262 | >>> 1263 | >>> 1264 | 1265 | ``` 1266 | ## NoneType 1267 | ```python 1268 | var = None 1269 | print(type(var)) 1270 | >>> 1271 | ``` 1272 | Сравнение `None` с любым объектом, отличным от `None`, дает значение `False`. `None` возвращается если функция ничего не вернула. Рекомендуется сравнивать `None` через `is`: 1273 | ```python 1274 | a = None 1275 | print(a is None) 1276 | >>> True 1277 | 1278 | ``` 1279 | # Вложенные списки 1280 | ## Основы 1281 | Создание вложенного списка: 1282 | ```python 1283 | my_list = [[0], [1, 2], [3, 4, 5]] 1284 | ``` 1285 | Чтобы получить число 2 мы используем такую команду: 1286 | ```python 1287 | my_list = [[0], [1, 2], [3, 4, 5]] 1288 | print(my_list[1][1]) # сначала получаем список с индексом 1 ([1, 2]), а затем первый индекс (2) 1289 | >>> 2 1290 | 1291 | ``` 1292 | Функции `min()` и `max() `могут работать и со списками. Если этим функциям передается несколько списков, то целиком возвращается один из переданных списков. При этом сравнение происходит поэлементно: сначала сравниваются первые элементы списков. Если они не равны, то функция `min()` вернет тот список, первый элемент которого меньше, `max()` – наоборот. Если первые элементы равны, то будут сравниваться вторые и т. д. 1293 | Пример: 1294 | Задача: 1295 | На вход программе подается число n. Напишите программу, которая создает и выводит построчно вложенный список, состоящий из n списков [[1], [1, 2], [1, 2, 3], ..., [1, 2, ..., n]]. 1296 | Формат входных данных 1297 | На вход программе подается натуральное число n. 1298 | Формат выходных данных 1299 | Программа должна вывести построчно указанный вложенный список. 1300 | Решение: 1301 | ```python 1302 | print(*[[i for i in range(1, j+1)] for j in range(1, int(input())+1)], sep="\n") 1303 | 1304 | ``` 1305 | ## Матрицы, ljust(), rjust() 1306 | Матрицы - прямоугольные таблицы, заполненные какими-то значениями, обычно числами. 1307 | ![Image 10](images/image_10.png) 1308 | 1309 | Перебор элементов матрицы: 1310 | ```python 1311 | rows, cols = 3, 4 # rows - количество строк, cols - количество столбцов 1312 | 1313 | matrix = [[2, 3, 1, 0], 1314 | [9, 4, 6, 8], 1315 | [4, 7, 2, 7]] 1316 | 1317 | for r in range(rows): 1318 | for c in range(cols): 1319 | print(matrix[r][c], end=' ') 1320 | print() 1321 | >>> 2 3 1 0 1322 | >>> 9 4 6 8 1323 | >>> 4 7 2 7 1324 | ``` 1325 | Строковый метод `ljust(arg) `выравнивает текст по ширине, добавляя пробелы в конец текста: 1326 | Строковый метод `rjust(arg)` выравнивает текст по ширине, добавляя пробелы в начало текста: 1327 | ```python 1328 | matrix = [[1, 2, 3], 1329 | [4, 590, 6], 1330 | [70, 8, 9]] 1331 | 1332 | for i in range(3): 1333 | for j in range(3): 1334 | print(str(matrix[i][j]).ljust(5), end="") 1335 | print() 1336 | 1337 | print() 1338 | 1339 | for i in range(3): 1340 | for j in range(3): 1341 | print(str(matrix[i][j]).rjust(5), end="") 1342 | print() 1343 | >>> 1 2 3 1344 | >>> 4 590 6 1345 | >>> 70 8 9 1346 | 1347 | >>> 1 2 3 1348 | >>> 4 590 6 1349 | >>> 70 8 9 1350 | 1351 | ``` 1352 | Таблица умножения n на m: 1353 | ```python 1354 | n, m = int(input()), int(input()) 1355 | s = [[i * j for i in range(m)] for j in range(n)] 1356 | for i in s: 1357 | print(*i) 1358 | <<< 4 1359 | <<< 6 1360 | >>> 0 0 0 0 0 0 1361 | >>> 0 1 2 3 4 5 1362 | >>> 0 2 4 6 8 10 1363 | >>> 0 3 6 9 12 15 1364 | 1365 | ``` 1366 | # Кортежи 1367 | ## Введение 1368 | Кортежи по своей природе (задумке) – неизменяемые аналоги списков. Кортеж описывается следующим образом: 1369 | ```python 1370 | list = [] # список 1371 | tuple = () # кортеж 1372 | ``` 1373 | Для создания кортежа с единственным элементом после значения элемента ставят замыкающую запятую: 1374 | ```python 1375 | my_tuple = (1,) 1376 | print(type(my_tuple)) 1377 | >>> 1378 | ``` 1379 | Если её не поставить, то будет создан не кортеж, а просто переменная со значением 1 (типа `int`) 1380 | 1381 | В чём кортеж превосходит список? 1382 | - Скорость 1383 | - Безопасность 1384 | Где встречаются кортежи? Если функция возвращает несколько значений, она возвращает кортеж. 1385 | 1386 | Важно! Тот факт, что кортеж является неизменяемым вовсе не означает, что мы не можем поменять содержимое списка в кортеже. 1387 | 1388 | ## Основы 1389 | Кортеж можно превратить в список используя функцию `list(mytuple)`. 1390 | Список можно превратить в кортеж используя функцию `tuple(mylist)`. 1391 | Кортеж можно преобразовать в строку с помощью строкового метода `join(mytuple)`. 1392 | Строку можно преобразовать в кортеж с помощью функции `tuple(mystring)`. 1393 | 1394 | Кортежи поддерживают: 1395 | - доступ к элементу по индексу (только для получения значений элементов) 1396 | - методы, в частности `index()`, `count()` 1397 | - встроенные функции, в частности `len(), sum(), min(), max()` 1398 | - срезы 1399 | - оператор принадлежности `in` 1400 | - операторы конкатенации (+) и повторения (*). 1401 | Кортежи могут иметь вложенные кортежи и вложенные списки. 1402 | 1403 | ## Сравнение кортежей 1404 | ```python 1405 | print((1, 8) == (1, 8)) 1406 | print((1, 8) != (1, 10)) 1407 | print((1, 9) < (1, 2)) 1408 | print((2, 5) < (6,)) 1409 | print(('a', 'bc') > ('a', 'de')) 1410 | 1411 | >>> True 1412 | >>> True 1413 | >>> False 1414 | >>> True 1415 | >>> False 1416 | ``` 1417 | Обратите внимание: операции == и != применимы к любым кортежам, независимо от типов элементов. А вот операции <, >, <=, >= применимы только в том случае, когда соответствующие элементы кортежей имеют один тип. 1418 | 1419 | ## Сортировка кортежей 1420 | Так как кортежи неизменяемы, то и метода `sort()` у них нет. Но кортеж можно отсортировать при помощи функции `sorted()`. Данная функция возвращает отсортированный кортеж/список, а не сортирует его «на месте». 1421 | Примеры решения задач: 1422 | Условие: Напишите программу, которая выводит список хорошистов и отличников в классе. 1423 | Формат входных данных 1424 | На вход программе подается натуральное число 1425 | n, далее следует n строк с фамилией школьника и его оценкой на каждой из них. 1426 | Формат выходных данных 1427 | Программа должна вывести сначала все введённые строки с фамилиями и оценками учеников в том же порядке. Затем следует пустая строка, а затем выводятся строки с фамилиями и оценками хорошистов и отличников (в том же порядке). 1428 | Решение: 1429 | ```python 1430 | a = [tuple(input().split()) for _ in range(int(input()))] # создаем n кортежей, которые будут иметь 2 значения - фамилия и оценка 1431 | for i in a: 1432 | print(*i) 1433 | 1434 | print() 1435 | 1436 | for name, grade in a: # перебираем каждый кортеж 1437 | if int(grade) > 3: # если оценка выше 3, выводим имя и оценку 1438 | print(name, grade) 1439 | 1440 | ``` 1441 | ## Распаковка кортежей; “хвосты” 1442 | Кортежи можно распаковывать так: 1443 | ```python 1444 | print(*tuple) 1445 | ``` 1446 | Но мы также можем присвоить переменным значения элементов кортежа: 1447 | ```python 1448 | colors = ('red', 'green', 'blue', 'cyan') 1449 | 1450 | (a, b, c, d) = colors 1451 | 1452 | print(a) 1453 | print(b) 1454 | print(c) 1455 | print(d) 1456 | >>> red 1457 | >>> green 1458 | >>> blue 1459 | >>> cyan 1460 | ``` 1461 | При этом переменных должно быть ровно столько, сколько символов в кортеже. 1462 | Но что делать если нам нужны например только первые 2 переменные из кортежа/списка? Для этого используют такую конструкцию: 1463 | ```python 1464 | *names, surname = ('Стефани', 'Джоанн', 'Анджелина', 'Джерманотта') 1465 | 1466 | print(names) 1467 | print(surname) 1468 | >>> ['Стефани', 'Джоанн', 'Анджелина'] 1469 | >>> Джерманотта 1470 | ``` 1471 | Перед `names` мы поставили `*`, это означает что это список, который примет все значения, которые не приняли другие переменные. 1472 | Учтите, что `*tail` всегда будет списком, даже когда в него попадает лишь один элемент или даже ноль. 1473 | 1474 | # Множества 1475 | ## Множества в математике 1476 | В математике множество – совокупность объектов, понимаемых как единое целое. Обычно множества обозначают большими латинскими буквами. 1477 | Если два множества X и Y состоят из одних и тех же элементов, то они называются равными X=Y. Обратите внимание, порядок расположения элементов в записи множеств при их сравнении во внимание не принимается. 1478 | Если все элементы множества X принадлежат также и множеству Y, то говорят, что X является подмножеством Y, а записывается это так: X ⊂ Y. 1479 | Если множество X конечно, то через ∣X∣ обозначается количество элементов множества X. 1480 | Множество X, содержащее n элементов, имеет 2^n подмножеств, включая пустое. Например, X = {a, b, c} (3 элемента) имеет 8 подмножеств: ∅, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}. 1481 | Важно! Множества – неупорядоченные совокупности, то есть неважно, в каком порядке указаны элементы множества. 1482 | 1483 | ## Пустое множество 1484 | Пустое множество – множество, не содержащего ни одного элемента. Оно обозначается знаком ∅. 1485 | 1486 | ## Числовые множества 1487 | - Натуральные числа: 1488 | N={1,2,3,4,5,…} 1489 | - Целые числа: 1490 | Z={0,±1,±2,±3,±4,±5,…} 1491 | - Рациональные числа. Рациональным числом в математике называется любое число, представимое в виде частного двух целых чисел с отличным от нуля знаменателем. Множество рациональных чисел обозначается буквой Q и содержит следующие числа: 1492 | Q={, m∈Z, n∈N}. 1493 | - Иррациональные числа. Не все числа в математике можно представить в виде рационального числа. Примером служат числа: 1494 | ≈1.414213562… 1495 | π≈3.1415926535… 1496 | e≈2.71828182845… 1497 | Такие числа называются иррациональными и являются бесконечными непериодическими дробями. Иными словами, в «бесконечных хвостах» иррациональных чисел нет никакой закономерности. Иррациональные числа часто обозначают буквой I. 1498 | - Вещественные числа: 1499 | Объединение рациональных и иррациональных чисел образует множество вещественных чисел. Множество вещественных чисел R определяется так: R=Q∪I. Символ ∪ – означает объединение множеств. 1500 | - Комплексные числа: 1501 | Комплексные числа — это числа вида a + bi, где a и b — действительные числа, а i — мнимая единица (i^2 = −1). 1502 | Это множество обозначают буквой C. 1503 | 1504 | ## Операции над множествами 1505 | - Объединение множеств – множество, состоящее из элементов, принадлежащих хотя бы одному из объединяемых множеств. Для объединения множеств используется символ ∪. 1506 | ![Image 11](images/image_11.png) 1507 | 1508 | - Пересечение множеств – множество, состоящее из элементов, принадлежащих одновременно каждому из пересекающихся множеств. Для пересечения множеств используется символ ∩. 1509 | ![Image 12](images/image_12.png) 1510 | 1511 | - Разность множеств – множество, в которое входят только элементы первого множества, не входящие во второе множество. Для разности множеств используется символ ∖. 1512 | ![Image 13](images/image_13.png) 1513 | 1514 | - Симметрическая разность множеств – множество, включающее все элементы исходных множеств, не принадлежащие одновременно обоим исходным множествам. Для симметрической разности множеств используется символ △. 1515 | ![Image 14](images/image_14.png) 1516 | 1517 | - Дополнение множества – множество всех элементов, в нем не содержащихся. Для операции дополнения множества используется символ ¬. 1518 | ![Image 15](images/image_15.png) 1519 | 1520 | ## Диаграммы Эйлера-Венна при решении задач 1521 | Задача. Каждый ученик онлайн-школы BEEGEEK изучает или математику или информатику, или и то и другое одновременно. Всего 75 учеников изучает математику, а 27 – информатику и только 13 – оба предмета. Сколько учеников учится в онлайн-школе BEEGEEK? 1522 | Решение. Введем обозначения: множество учеников, изучающих математику – М, информатику – И. Изображаем множества на диаграмме Эйлера-Венна в наиболее общем случае. 1523 | ![Image 16](images/image_16.png) 1524 | Рассуждаем следующим образом: оба предмета изучают 13 учеников. Значит, только математику изучают 75 − 13 = 62 ученика, только информатику изучают 27 − 13 = 14 учеников. Таким образом, всего в школе учится 62 + 13 + 14 = 89 учеников. Ответ: 89. 1525 | 1526 | ## Введение в множества в Python 1527 | Важно знать: 1528 | - все элементы множества различны (уникальны), два элемента не могут иметь одинаковое значение 1529 | - множества неупорядочены, то есть элементы не хранятся в каком-то определенном порядке 1530 | - элементы множества должны относиться к неизменяемым типам данных 1531 | - хранящиеся в множестве элементы могут иметь разные типы данных. 1532 | - Множества изменяемы 1533 | Множество не может содержать список, множество, однако может содержать кортеж. 1534 | 1535 | ## Создание множества 1536 | Чтобы создать множество, нужно перечислить его элементы через запятую в фигурных скобках: 1537 | ```python 1538 | numbers = {2, 4, 6, 8, 10} 1539 | languages = {"Python", "C#", "C++", "Java"} 1540 | favorites = {"Nikita", 144, "My friend"} 1541 | 1542 | ``` 1543 | Создать пустое множество можно с помощью встроенной функции, которая называется `set()`: 1544 | ```python 1545 | myset = set() # пустое множество 1546 | ``` 1547 | Важно! Создать пустое множество с помощью пустых фигурных скобок нельзя: 1548 | ```python 1549 | myset = {} # создается словарь 1550 | 1551 | ``` 1552 | ## Вывод множества 1553 | Вывести множество можно через `print(myset)`. 1554 | Обратите внимание: при выводе множества порядок элементов может отличаться от существовавшего при его создании, поскольку множества — неупорядоченные коллекции данных. 1555 | 1556 | ## set() 1557 | Встроенная функция `set() `помимо создания пустого множества может преобразовывать некоторые типы объектов в множества. В функцию `set() `можно передать один аргумент. Передаваемый аргумент должен быть итерируемым объектом, таким как список, кортеж или строковое значение. Отдельные элементы объекта, передаваемого в качестве аргумента, становятся элементами множества: 1558 | ```python 1559 | myset1 = set(range(10)) # множество из элементов последовательности 1560 | myset2 = set([1, 2, 3, 4, 5]) # множество из элементов списка 1561 | myset3 = set('abcd') # множество из элементов строки 1562 | myset4 = set((10, 20, 30, 40)) # множество из элементов кортежа 1563 | ``` 1564 | Пустое множество также можно создать передав функции `set() `в качестве аргумента пустой список, строку или кортеж: 1565 | ```python 1566 | emptyset1 = set([]) # пустое множество из пустого списка 1567 | emptyset2 = set('') # пустое множество из пустой строки 1568 | emptyset3 = set(()) # пустое множество из пустого кортежа 1569 | 1570 | ``` 1571 | Множества не могут содержать повторяющиеся элементы. Если в функцию `set()` передать аргумент, содержащий повторяющиеся элементы, то в множестве появится только один из этих повторяющихся элементов. 1572 | ```python 1573 | myset1 = {2, 2, 4, 6, 6} 1574 | myset2 = set([1, 2, 2, 3, 3]) 1575 | myset3 = set("aaaaabbbbccccddd") 1576 | 1577 | print(myset1) 1578 | print(myset2) 1579 | print(myset3) 1580 | >>> {2, 4, 6} 1581 | >>> {1, 2, 3} 1582 | >>> {"b", "c", "d", "a"} 1583 | 1584 | ``` 1585 | Если требуется создать множество, в котором каждый элемент — строковое значение, содержащее более одного символа, то используем код: 1586 | ```python 1587 | myset = set(['aaa', 'bbbb', 'cc']) 1588 | 1589 | print(myset) 1590 | >>> {'bbbb', 'aaa', 'cc'} 1591 | ``` 1592 | Однако вот что будет, если аргумент будет строкой: 1593 | ```python 1594 | myset = set('aaa bbbb cc') 1595 | 1596 | print(myset) 1597 | >>> {' ', 'c', 'a', 'b'} 1598 | 1599 | ``` 1600 | ## Основы работы с множествами 1601 | - Функция `len() `возвращает длину множества (количество элементов). 1602 | - Оператор `in `позволяет проверить, содержит ли множество некоторый элемент. В множествах он работает намного быстрее чем в списках. 1603 | - Встроенная функция `sum()` принимает в качестве аргумента множество чисел и вычисляет сумму его элементов. 1604 | - Встроенные функции `min() `и `max()` принимают в качестве аргумента множество и находят минимальный и максимальный элементы соответственно. 1605 | Важно! Индексация и срезы недоступны для множеств. Операция конкатенации + и умножения на число * тоже недоступны для множеств. 1606 | 1607 | ## Перебор элементов множества и распаковка 1608 | Перебор элементов множества осуществляется точно так же, как и перебор элементов списка, то есть с помощью цикла `for`. 1609 | Для вывода элементов множества каждого на отдельной строке можно использовать следующий код: 1610 | ```python 1611 | numbers = {0, 1, 1, 2, 3, 3, 3, 5, 6, 7, 7} 1612 | 1613 | for num in numbers: 1614 | print(num) 1615 | >>> 0 1616 | >>> 1 1617 | >>> 2 1618 | >>> 3 1619 | >>> 5 1620 | >>> 6 1621 | >>> 7 1622 | ``` 1623 | Но также можно распаковать таким способом: 1624 | ```python 1625 | numbers = {0, 1, 1, 2, 3, 3, 3, 5, 6, 7, 7} 1626 | 1627 | print(*numbers) 1628 | >>> 0 1 2 3 5 6 7 1629 | ``` 1630 | Помните, что множества - неупорядоченные коллекции, а значит если вам нужно вывести элементы по возрастанию, используйте функцию `sorted()`, которая вернёт отсортированный список. Метода `sort()` у множеств нет. В функции можно указать необязательный параметр `reverse`. При `reverse=True` множество будет отсортировано по убыванию. 1631 | 1632 | ## Сравнение множеств 1633 | Множества можно сравнивать между собой. Равные множества имеют одинаковую длину и содержат равные элементы. Для сравнения множеств используются операторы == и !=. Других операторов сравнения у множеств нет. 1634 | 1635 | ## Методы множеств 1636 | Основные: 1637 | - Для добавления нового элемента в множество используется метод `add()`. 1638 | ```python 1639 | numbers = {1, 1, 2, 3, 5, 8, 3} # создаем множество 1640 | numbers.add(21) # добавляем число 21 в множество 1641 | numbers.add(34) # добавляем число 34 в множество 1642 | print(numbers) 1643 | >>> {1, 2, 3, 34, 5, 8, 21} 1644 | ``` 1645 | - Метод `remove()` удаляет элемент из множества с генерацией исключения (ошибки) в случае, если такого элемента нет. 1646 | ```python 1647 | numbers = {1, 2, 3, 4, 5} 1648 | numbers.remove(3) 1649 | print(numbers) 1650 | >>> {1, 2, 4, 5} 1651 | ``` 1652 | - Метод `discard()` удаляет элемент из множества без генерации исключения (ошибки), если элемент отсутствует. 1653 | ```python 1654 | numbers = {1, 2, 3, 4, 5} 1655 | numbers.discard(3) 1656 | print(numbers) 1657 | >>> {1, 2, 4, 5} 1658 | 1659 | numbers = {1, 2, 3, 4, 5} 1660 | numbers.discard(10) 1661 | print(numbers) 1662 | >>> {1, 2, 3, 4, 5} 1663 | ``` 1664 | - Метод `pop()` удаляет и возвращает первый элемент из множества с генерацией исключения (ошибки) при попытке удаления из пустого множества. Аргументы указать нельзя. 1665 | ```python 1666 | numbers = {1, 2, 3, 4, 5} 1667 | print('до удаления:', numbers) 1668 | num = numbers.pop() # удаляет первый элемент множества, возвращая его 1669 | print('удалённый элемент:', num) 1670 | print('после удаления:', numbers) 1671 | >>> до удаления: {1, 2, 3, 4, 5} 1672 | >>> удалённый элемент: 1 1673 | >>> после удаления: {2, 3, 4, 5} 1674 | ``` 1675 | - Метод `clear()` удаляет все элементы из множества. 1676 | ```python 1677 | numbers = {1, 2, 3, 4, 5} 1678 | numbers.clear() 1679 | print(numbers) 1680 | >>> set() 1681 | 1682 | ``` 1683 | Операции над множествами: 1684 | - Объединение множеств: `union() `возвращает новое множество со всеми элементами первого и второго. 1685 | Для объединения двух множеств можно также использовать оператор |. 1686 | Для изменения текущего множества используется метод `update()`. 1687 | Первый вариант: 1688 | ```python 1689 | myset1 = {1, 2, 3, 4, 5} 1690 | myset2 = {3, 4, 6, 7, 8} 1691 | myset3 = myset1.union(myset2) 1692 | print(myset3) 1693 | >>> {1, 2, 3, 4, 5, 6, 7, 8} 1694 | ``` 1695 | Второй вариант: 1696 | ```python 1697 | myset1 = {1, 2, 3, 4, 5} 1698 | myset2 = {3, 4, 6, 7, 8} 1699 | myset3 = myset1 | myset2 1700 | print(myset3) 1701 | >>> {1, 2, 3, 4, 5, 6, 7, 8} 1702 | ``` 1703 | Использование `update()`: 1704 | ```python 1705 | myset1 = {1, 2, 3, 4, 5} 1706 | myset2 = {3, 4, 6, 7, 8} 1707 | myset1.update(myset2) # изменяем множество myset1 1708 | print(myset1) 1709 | >>> {1, 2, 3, 4, 5, 6, 7, 8} 1710 | ``` 1711 | Еще один способ: 1712 | ```python 1713 | myset1 = {1, 2, 3, 4, 5} 1714 | myset2 = {3, 4, 6, 7, 8} 1715 | myset1 |= myset2 1716 | print(myset1) 1717 | >>> {1, 2, 3, 4, 5, 6, 7, 8} 1718 | 1719 | ``` 1720 | - Пересечение множеств: `intersection() `возвращает новое множество состоящее из элементов, принадлежащих одновременно каждому из пересекающихся множеств. 1721 | Для пересечения двух множеств можно также использовать оператор &. 1722 | Для изменения текущего множества используется метод `intersection_update()`. 1723 | Первый вариант: 1724 | ```python 1725 | myset1 = {1, 2, 3, 4, 5} 1726 | myset2 = {3, 4, 6, 7, 8} 1727 | myset3 = myset1.intersection(myset2) 1728 | print(myset3) 1729 | >>> {3, 4} 1730 | ``` 1731 | Второй вариант: 1732 | ```python 1733 | myset1 = {1, 2, 3, 4, 5} 1734 | myset2 = {3, 4, 6, 7, 8} 1735 | myset3 = myset1 & myset2 1736 | print(myset3) 1737 | >>> {3, 4} 1738 | ``` 1739 | Использование `intersection_update()`: 1740 | ```python 1741 | myset1 = {1, 2, 3, 4, 5} 1742 | myset2 = {3, 4, 6, 7, 8} 1743 | myset1.intersection_update(myset2) # изменяем множество myset1 1744 | print(myset1) 1745 | >>> {3, 4} 1746 | ``` 1747 | Еще один способ: 1748 | ```python 1749 | myset1 = {1, 2, 3, 4, 5} 1750 | myset2 = {3, 4, 6, 7, 8} 1751 | myset1 &= myset2 1752 | print(myset1) 1753 | >>> {3, 4} 1754 | ``` 1755 | - Разность множеств: `difference() `возвращает новое множество, в которое входят все элементы первого множества, не входящие во второе множество. 1756 | Для разности двух множеств можно также использовать оператор -. 1757 | Для изменения текущего множества используется метод `difference_update()`. 1758 | Первый вариант: 1759 | ```python 1760 | myset1 = {1, 2, 3, 4, 5} 1761 | myset2 = {3, 4, 6, 7, 8} 1762 | myset3 = myset1.difference(myset2) 1763 | print(myset3) 1764 | >>> {1, 2, 5} 1765 | ``` 1766 | Второй вариант: 1767 | ```python 1768 | myset1 = {1, 2, 3, 4, 5} 1769 | myset2 = {3, 4, 6, 7, 8} 1770 | myset3 = myset1 - myset2 1771 | print(myset3) 1772 | >>> {1, 2, 5} 1773 | ``` 1774 | Использование `difference_update()`: 1775 | ```python 1776 | myset1 = {1, 2, 3, 4, 5} 1777 | myset2 = {3, 4, 6, 7, 8} 1778 | myset1.difference_update(myset2) # изменяем множество myset1 1779 | print(myset1) 1780 | >>> {1, 2, 5} 1781 | ``` 1782 | Еще один способ: 1783 | ```python 1784 | myset1 = {1, 2, 3, 4, 5} 1785 | myset2 = {3, 4, 6, 7, 8} 1786 | myset1 -= myset2 1787 | print(myset1) 1788 | >>> {1, 2, 5} 1789 | ``` 1790 | - Симметричная разность множеств: `symmetric_difference() `возвращает новое множество, включающее все элементы исходных множеств, не принадлежащие одновременно обоим исходным множествам. 1791 | Для симметричной разности двух множеств можно также использовать оператор ^. 1792 | Для изменения текущего множества используется метод `symmetric_difference_update()`. 1793 | Первый вариант: 1794 | ```python 1795 | myset1 = {1, 2, 3, 4, 5} 1796 | myset2 = {3, 4, 6, 7, 8} 1797 | myset3 = myset1.symmetric_difference(myset2) 1798 | print(myset3) 1799 | >>> {1, 2, 5, 6, 7, 8} 1800 | ``` 1801 | Второй вариант: 1802 | ```python 1803 | myset1 = {1, 2, 3, 4, 5} 1804 | myset2 = {3, 4, 6, 7, 8} 1805 | myset3 = myset1 ^ myset2 1806 | print(myset3) 1807 | >>> {1, 2, 5, 6, 7, 8} 1808 | ``` 1809 | Использование `symmetric_difference_update()`: 1810 | ```python 1811 | myset1 = {1, 2, 3, 4, 5} 1812 | myset2 = {3, 4, 6, 7, 8} 1813 | myset1.symmetric_difference_update(myset2) # изменяем множество myset1 1814 | print(myset1) 1815 | >>> {1, 2, 5, 6, 7, 8} 1816 | ``` 1817 | Еще один способ: 1818 | ```python 1819 | myset1 = {1, 2, 3, 4, 5} 1820 | myset2 = {3, 4, 6, 7, 8} 1821 | myset1 ^= myset2 1822 | print(myset1) 1823 | >>> {1, 2, 5, 6, 7, 8} 1824 | 1825 | ``` 1826 | Подмножества и надмножества: 1827 | Любое множество – подмножество самого себя, про такое подмножество говорят "нестрогое подмножество". 1828 | Для определения, является ли одно из множеств подмножеством другого, используется метод `issubset(). `Данный метод возвращает значение `True`, если одно множество является подмножеством другого, и `False`, если не является 1829 | ```python 1830 | set1 = {2, 3} 1831 | set2 = {1, 2, 3, 4, 5, 6} 1832 | print(set1.issubset(set2)) 1833 | >>> True 1834 | 1835 | ``` 1836 | Для определения, является ли одно из множеств подмножеством другого, также применяются операторы <= (нестрогое подмножество) и < (строгое подмножество). 1837 | ```python 1838 | set1 = {2, 3} 1839 | set2 = {1, 2, 3, 4, 5, 6} 1840 | print(set1 <= set2) 1841 | >>> True 1842 | 1843 | ``` 1844 | Для определения, является ли одно из множеств надмножеством другого, используется метод `issuperset()`. Данный метод возвращает значение `True`, если одно множество является надмножеством другого, в противном случае он возвращает `False`. 1845 | ```python 1846 | set1 = {'a', 'b', 'c', 'd', 'e'} 1847 | set2 = {'c', 'e'} 1848 | print(set1.issuperset(set2)) 1849 | >>> True 1850 | ``` 1851 | Для определения, является ли одно из множеств надмножеством другого, также применяются операторы >= (нестрогое надмножество) и > (строгое надмножество). 1852 | ```python 1853 | set1 = {'a', 'b', 'c', 'd', 'e'} 1854 | set2 = {'c', 'e'} 1855 | print(set1 >= set2) 1856 | >>> True 1857 | ``` 1858 | Для определения отсутствия общих элементов в множествах используется метод `isdisjoint()`. Данный метод возвращает значение `True`, если множества не имеют общих элементов, и `False`, когда множества имеют общие элементы. 1859 | ```python 1860 | set1 = {1, 2, 3, 4, 5} 1861 | set2 = {5, 6, 7} 1862 | set3 = {7, 8, 9} 1863 | print(set1.isdisjoint(set2)) 1864 | print(set1.isdisjoint(set3)) 1865 | print(set2.isdisjoint(set3)) 1866 | >>> False 1867 | >>> True 1868 | >>> False 1869 | 1870 | ``` 1871 | ## Генераторы множеств 1872 | Чтобы заполнить множество всеми цифрами числа, можно использовать следующий код: 1873 | ```python 1874 | digits = {int(c) for c in input()} 1875 | ``` 1876 | В генераторах можно использовать условия: 1877 | ```python 1878 | digits = {int(d) for d in 'abcd12ef78ghj90' if d.isdigit()} 1879 | ``` 1880 | Данный код добавляет в `digits` только цифры. 1881 | 1882 | ## frozenset 1883 | frozenset – замороженный вариант множеств (set) 1884 | Синтаксис замороженных множеств полностью идентичен обычным. 1885 | Такие множества можно сравнивать с обычными. 1886 | 1887 | Зачем они нужны? Замороженные множества являются неизменяемыми, а значит могут быть элементами других множеств. 1888 | 1889 | # Словари 1890 | ## Введение 1891 | Словарь – изменяемый тип данных в Python. Левая часть – ключ, правая – значение. 1892 | Пример словаря: 1893 | ```python 1894 | languages = {'Python': 'Гвидо ван Россум', 1895 | 'C#': 'Андерс Хейлсберг', 1896 | 'Java': 'Джеймс Гослинг', 1897 | 'C++': 'Бьёрн Страуструп'} 1898 | ``` 1899 | Код создает словарь, в котором ключом служит строка — название языка программирования, а значением — имя создателя языка. Важно! В рамках одного словаря каждый ключ уникален. 1900 | 1901 | Для извлечения элемента словаря используют ключ: 1902 | ```python 1903 | languages = {'Python': 'Гвидо ван Россум', 1904 | 'C#': 'Андерс Хейлсберг', 1905 | 'Java': 'Джеймс Гослинг', 1906 | 'C++': 'Бьёрн Страуструп'} 1907 | 1908 | print('Создателем языка C# является', languages['C#']) 1909 | >>> Создателем языка C# является Андерс Хейлсберг 1910 | ``` 1911 | В отличие от списков, номеров позиций в словарях нет. 1912 | 1913 | Для вывода всего словаря можно использовать функцию `print()`: 1914 | ```python 1915 | info = {"name": "Nikita", "status": "Creator"} 1916 | print(info) 1917 | >>> {'name': 'Nikita', 'status': 'Creator'} 1918 | ``` 1919 | Начиная с версии Python 3.6, словари являются упорядоченными, то есть сохраняют порядок следования ключей в порядке их внесения в словарь. 1920 | 1921 | ## Создание словаря 1922 | Если ключи словаря — строки без каких-либо специальных символов, то для создания словаря можно использовать функцию `dict(). `Пример: 1923 | ```python 1924 | info = dict(name='Timur', age=28, job='Teacher') 1925 | 1926 | ``` 1927 | Создание на основе списка кортежей: 1928 | ```python 1929 | info_list = [('name', 'Timur'), ('age', 28), ('job', 'Teacher')] # список кортежей 1930 | info_dict = dict(info_list) # создаем словарь на основе списка кортежей 1931 | 1932 | ``` 1933 | Создание на основе кортежа списков: 1934 | ```python 1935 | info_tuple = (['name', 'Timur'], ['age', 28], ['job', 'Teacher']) # кортеж списков 1936 | info_dict = dict(info_tuple) # создаем словарь на основе кортежа списков 1937 | 1938 | ``` 1939 | Если необходимо создать словарь, каждому ключу которого соответствует одно и то же значение, можно воспользоваться методом `fromkeys()`. 1940 | ```python 1941 | dict1 = dict.fromkeys(['name', 'age', 'job'], 'Missed information') 1942 | ``` 1943 |  Если методу `fromkeys()` не передать второй параметр, то по умолчанию присваивается значение `None`. 1944 | 1945 | Создать словарь на основании двух списков (кортежей) можно с помощью встроенной функции-упаковщика `zip().` 1946 | ```python 1947 | keys = ['name', 'age', 'job'] 1948 | values = ['Timur', 28, 'Teacher'] 1949 | info = dict(zip(keys, values)) 1950 | print(info) 1951 | >>> {'name': 'Timur', 'age': 28, 'job': 'Teacher'} 1952 | ``` 1953 | В случае несовпадения длины списков функция самостоятельно отсечет лишние элементы. 1954 | 1955 | ## Создание пустого словаря 1956 | Создать пустой словарь можно двумя способами: 1957 | - с помощью пустых фигурных скобок 1958 | - с помощью функции `dict()` 1959 | 1960 | ## Важные детали 1961 | - Ключи должны быть уникальными 1962 | - Ключи должны быть неизменяемым типом данных 1963 | - Значения могут относиться к любому типу данных, их тип данных произволен 1964 | - Обращение по индексу и срезы недоступны для словарей 1965 | - Операция конкатенации + и умножения на число * недоступны для словарей 1966 | 1967 | 1968 | ## Основы (len, sum, min, max, in) 1969 | - Длиной словаря называется количество его элементов. Для определения длины словаря используют встроенную функцию `len()`. 1970 | ```python 1971 | fruits = {'Apple': 70, 'Grape': 100, 'Banana': 80} 1972 | print(len(fruits)) 1973 | >>> 3 1974 | ``` 1975 | - Встроенная функция `sum() `принимает в качестве аргумента словарь с числовыми ключами и вычисляет сумму его ключей. 1976 | ```python 1977 | my_dict = {10: 'Россия', 20: 'США', 30: 'Франция'} 1978 | print('Сумма всех ключей словаря =', sum(my_dict)) 1979 | >>> Сумма всех ключей словаря = 60 1980 | ``` 1981 | - Встроенные функции `min() `и `max() `принимают в качестве аргумента словарь и находят минимальный и максимальный ключ соответственно, при этом ключ может принадлежать к любому типу данных, для которого возможны операции порядка <, <=, >, >= (числа, строки, и т.д.). 1982 | ```python 1983 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'} 1984 | months = {1: 'Январь', 2: 'Февраль', 3: 'Март'} 1985 | print('Минимальный ключ =', min(capitals)) 1986 | print('Максимальный ключ =', max(months)) 1987 | >>> Минимальный ключ = Россия 1988 | >>> Максимальный ключ = 3 1989 | ``` 1990 | - Оператор `in` позволяет проверить, содержит ли словарь заданный ключ. 1991 | ```python 1992 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'} 1993 | if 'Франция' in capitals: 1994 | print('Столица Франции - это', capitals['Франция']) 1995 | >>> Столица Франции - это Париж 1996 | 1997 | ``` 1998 | ## Сравнение словарей 1999 | Словари можно сравнивать между собой. Равные словари имеют одинаковое количество элементов и содержат равные элементы (ключ: значение). Для сравнения словарей используются операторы == и !=. 2000 | 2001 | ## Перебор элементов словаря 2002 | Вывод ключей словаря: 2003 | ```python 2004 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'} 2005 | for key in capitals: 2006 | print(key) 2007 | >>> Россия 2008 | >>> Франция 2009 | >>> Чехия 2010 | ``` 2011 | Вывод значений словаря: 2012 | ```python 2013 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'} 2014 | for key in capitals: 2015 | print(capitals[key]) 2016 | >>> Москва 2017 | >>> Париж 2018 | >>> Прага 2019 | 2020 | ``` 2021 | ## Распаковка словарей 2022 | При распаковке словарей возвращаются только ключи: 2023 | ```python 2024 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'} 2025 | print(*capitals, sep='\n') 2026 | >>> Россия 2027 | >>> Франция 2028 | >>> Чехия 2029 | 2030 | ``` 2031 | ## Методы keys(), values(), items() 2032 | Словарный метод `keys()` возвращает список ключей всех элементов словаря. 2033 | ```python 2034 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'} 2035 | for key in capitals.keys(): # итерируем по списку ['Россия', 'Франция', 'Чехия'] 2036 | print(key) 2037 | >>> Россия 2038 | >>> Франция 2039 | >>> Чехия 2040 | 2041 | ``` 2042 | Словарный метод `values() `возвращает список значений всех элементов словаря. 2043 | ```python 2044 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'} 2045 | for value in capitals.values(): # итерируем по списку ['Москва', 'Париж', 'Прага'] 2046 | print(value) 2047 | >>> Москва 2048 | >>> Париж 2049 | >>> Прага 2050 | 2051 | ``` 2052 | Словарный метод `items() `возвращает список всех элементов словаря, состоящий из кортежей пар (ключ, значение). 2053 | ```python 2054 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'} 2055 | for item in capitals.items(): 2056 | print(item) 2057 | >>> ('Россия', 'Москва') 2058 | >>> ('Франция', 'Париж') 2059 | >>> ('Чехия', 'Прага') 2060 | ``` 2061 | Можно писать такой код: 2062 | ```python 2063 | capitals = {'Россия': 'Москва', 'Франция': 'Париж', 'Чехия': 'Прага'} 2064 | for key, value in capitals.items(): 2065 | print(key, '-', value) 2066 | >>> Россия - Москва 2067 | >>> Франция - Париж 2068 | >>> Чехия – Прага 2069 | 2070 | ``` 2071 | ## Сортировка словарей 2072 | Сортировка по ключам выполняется с использованием функции `sorted()`. 2073 | Важно: словари не содержат метода `sort()`. 2074 | ```python 2075 | capitals = {'Россия': 'Москва', 'Англия': 'Лондон', 'Чехия': 'Прага', 'Бразилия': 'Бразилиа'} 2076 | for key in sorted(capitals): 2077 | print(key) 2078 | >>> Англия 2079 | >>> Бразилия 2080 | >>> Россия 2081 | >>> Чехия 2082 | 2083 | ``` 2084 | ## Методы словарей 2085 | - Добавление и изменение элементов в словаре 2086 | Чтобы изменить значение по определенному ключу в словаре, достаточно использовать индексацию вместе с оператором присваивания. При этом если ключ уже присутствует в словаре, его значение заменяется новым, если же ключ отсутствует – то в словарь будет добавлен новый элемент. 2087 | ```python 2088 | info = {"name": "Sam", "age": 28, "job": "Teacher"} 2089 | info["name"] = "Timur" # изменяем значение по ключу name 2090 | info["email"] = "timyr-guev@yandex.ru" # добавляем в словарь элемент с ключом email 2091 | print(info) 2092 | >>> {'name': 'Timur', 'age': 28, 'job': 'Teacher', 'email': 'timyr-guev@yandex.ru'} 2093 | ``` 2094 | - Метод `get()` 2095 | Для того чтобы избежать возникновения ошибки в случае отсутствия ключа в словаре, можно использовать метод `get(),` способный кроме ключа принимать и второй аргумент — значение, которое вернется, если заданного ключа нет. Когда второй аргумент не указан, то метод в случае отсутствия ключа возвращает `None.` 2096 | ```python 2097 | info = {"name": "Bob", "age": 25, "job": "Dev"} 2098 | item1 = info.get("salary") 2099 | item2 = info.get("salary", "Информации о зарплате нет") 2100 | print(item1) 2101 | print(item2) 2102 | >>> None 2103 | >>> Информации о зарплате нет 2104 | ``` 2105 | - Метод `update()` 2106 | Метод `update()` реализует своеобразную операцию конкатенации для словарей. Он объединяет ключи и значения одного словаря с ключами и значениями другого. При совпадении ключей в итоге сохранится значение словаря, указанного в качестве аргумента метода `update()`. 2107 | ```python 2108 | info1 = {"name": "Bob", "age": 25, "job": "Dev"} 2109 | info2 = {"age": 30, "city": "New York", "email": "bob@web.com"} 2110 | info1.update(info2) 2111 | print(info1) 2112 | >>> {'name': 'Bob', 'age': 30, 'job': 'Dev', 'city': 'New York', 'email': 'bob@web.com'} 2113 | ``` 2114 | В Python 3.9 появились операторы | и |=, которые реализуют операцию конкатенации словарей. 2115 | ```python 2116 | info1 = {"name": "Bob", "age": 25, "job": "Dev"} 2117 | info2 = {"age": 30, "city": "New York", "email": "bob@web.com"} 2118 | info1 |= info2 2119 | print(info1) 2120 | >>> {'name': 'Bob', 'age': 30, 'job': 'Dev', 'city': 'New York', 'email': 'bob@web.com'} 2121 | ``` 2122 | - Метод `setdefault()` 2123 | Метод `setdefault()` позволяет получить значение из словаря по заданному ключу, автоматически добавляя элемент словаря, если он отсутствует. 2124 | ```python 2125 | info = {"name": "Bob", "age": 25, "job": "Dev"} 2126 | print(info.setdefault("name", "Tim")) 2127 | >>> Bob 2128 | 2129 | info = {"age": 25, "job": "Dev"} 2130 | print(info.setdefault("name", "Tim")) 2131 | >>> Tim 2132 | ``` 2133 | - Оператор `del` 2134 | ```python 2135 | info = {"name": "Sam", "age": 28, "job": "Teacher", "email": "timyr-guev@yandex.ru"} 2136 | del info["email"] # удаляем элемент имеющий ключ email 2137 | del info["job"] # удаляем элемент имеющий ключ job 2138 | print(info) 2139 | >>> {'name': 'Sam', 'age': 28} 2140 | ``` 2141 | - Метод `pop()` 2142 | ```python 2143 | info = {"name": "Sam", "age": 28, "job": "Teacher", "email": "timyr-guev@yandex.ru"} 2144 | email = info.pop('email') # удаляем элемент по ключу email, возвращая его значение 2145 | job = info.pop('job') # удаляем элемент по ключу job, возвращая его значение 2146 | print(email) 2147 | print(job) 2148 | print(info) 2149 | >>> timyr-guev@yandex.ru 2150 | >>> Teacher 2151 | >>> {'name': 'Sam', 'age': 28} 2152 | ``` 2153 | Также можно указать второй аргумент, он будет возвращен, если указанного ключа в словаре нет. Это позволяет реализовать безопасное удаление элемента из словаря: 2154 | ```python 2155 | surname = info.pop('surname', None) 2156 | ``` 2157 | - Метод `popitem() `удаляет из словаря последний добавленный элемент и возвращает удаляемый элемент в виде кортежа (ключ, значение). 2158 | ```python 2159 | info = {"name": "Bob", "age": 25, "job": "Dev"} 2160 | info["surname"] = "Sinclar" 2161 | item = info.popitem() 2162 | print(item) 2163 | print(info) 2164 | >>> ('surname', 'Sinclar') 2165 | >>> {'name': 'Bob', 'age': 25, 'job': 'Dev'} 2166 | ``` 2167 | - Метод `clear()` удаляет все элементы из словаря. 2168 | - Метод `copy() `создает поверхностную копию словаря. 2169 | 2170 | ## Генераторы словарей 2171 | Генераторы словарей имеют такой же синтаксис как и в генераторах списков. 2172 | ```python 2173 | squares = {i: i**2 for i in range(6)} # квадраты чисел от 0 до 5 2174 | print(squares) 2175 | >>> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25} 2176 | ``` 2177 | В генераторах словарей можно использовать условия: 2178 | ```python 2179 | squares = {i: i**2 for i in range(10) if i % 2 == 0} 2180 | print(squares) 2181 | >>> {0: 0, 2: 4, 4: 16, 6: 36, 8: 64} 2182 | 2183 | ``` 2184 | ## Вложенные словари 2185 | Вложенный словарь создается как обычный, только каждое значение в нем – другой словарь. 2186 | Пример: 2187 | ```python 2188 | info = {'emp1': {'name': 'Timur', 'job': 'Teacher'}, 2189 | 'emp2': {'name': 'Ruslan', 'job': 'Developer'}, 2190 | 'emp3': {'name': 'Rustam', 'job': 'Tester'}} 2191 | ``` 2192 | Или так: 2193 | ```python 2194 | info = dict(emp1 = {'name': 'Timur', 'job': 'Teacher'}, 2195 | emp2 = {'name': 'Ruslan', 'job': 'Developer'}, 2196 | emp3 = {'name': 'Rustam', 'job': 'Tester'}) 2197 | 2198 | ``` 2199 | Для обращения по индексу используют такой код: 2200 | ```python 2201 | info = {'emp1': {'name': 'Timur', 'job': 'Teacher'}, 2202 | 'emp2': {'name': 'Ruslan', 'job': 'Developer'}, 2203 | 'emp3': {'name': 'Rustam', 'job': 'Tester'}} 2204 | 2205 | print(info['emp1']['name']) 2206 | print(info['emp2']['job']) 2207 | >>> Timur 2208 | >>> Developer 2209 | 2210 | ``` 2211 | Изменение вложенных словарей: 2212 | ```python 2213 | info = {'emp1': {'name': 'Timur', 'job': 'Teacher'}, 2214 | 'emp2': {'name': 'Ruslan', 'job': 'Developer'}, 2215 | 'emp3': {'name': 'Rustam', 'job': 'Tester'}} 2216 | 2217 | info['emp1']['job'] = 'Manager' 2218 | print(info['emp1']) 2219 | >>> {'name': 'Timur', 'job': 'Manager'} 2220 | 2221 | ``` 2222 | Итерация по вложенным словарям: 2223 | ```python 2224 | info = {'emp1': {'name': 'Timur', 'job': 'Teacher'}, 2225 | 'emp2': {'name': 'Ruslan', 'job': 'Developer'}, 2226 | 'emp3': {'name': 'Rustam', 'job': 'Tester'}} 2227 | 2228 | for emp in info: 2229 | print('Employee ID:', emp) 2230 | for key in info[emp]: 2231 | print(key + ':', info[emp][key]) 2232 | print() 2233 | >>> Employee ID: emp1 2234 | >>> name: Timur 2235 | >>> job: Teacher 2236 | 2237 | >>> Employee ID: emp2 2238 | >>> name: Ruslan 2239 | >>> job: Developer 2240 | 2241 | >>> Employee ID: emp3 2242 | >>> name: Rustam 2243 | >>> job: Tester 2244 | 2245 | ``` 2246 | # Модули random, string, Метод Монте-Карло, Bogosort 2247 | ## Модуль random 2248 | ```python 2249 | import random 2250 | 2251 | num = random.randint(0, 17) # случайное целое число от 0 до 17 (включительно) 2252 | print(num) 2253 | >>> 14 2254 | 2255 | num1 = random.randrange(0, 100, 10) # возвращает случайное число от m до n с шагом k. синтаксис идентичен range() (не включительно) 2256 | num2 = random.randrange(0, 100, 10) # возвращает случайное число от m до n с шагом k. синтаксис идентичен range() (не включительно) 2257 | num3 = random.randrange(0, 100, 10) # возвращает случайное число от m до n с шагом k. синтаксис идентичен range() (не включительно) 2258 | print(num1, num2, num3) 2259 | >>> 80 30 50 2260 | 2261 | num = random.random() # случайное число с плавающей точкой от 0.0 до 1.0, аргументы не указываются (не включительно) 2262 | print(num) 2263 | >>> 0.34980886772220243 2264 | 2265 | num = random.uniform(3.6, 9.2) # случайное число с плавающей точкой от 3.6 до 9.2, аргументы обязательны (включительно) 2266 | print(num) 2267 | >>> 6.574427819432531 2268 | ``` 2269 | Методы строк и списков: 2270 | ```python 2271 | import random 2272 | 2273 | numbers = [1, 2, 3, 4, 5, 6, 7, 8] 2274 | random.shuffle(numbers) # перемешивает список 2275 | print(numbers) 2276 | >>> [3, 6, 7, 1, 5, 8, 2, 4] 2277 | 2278 | print(random.choice('Ваня, привет')) # случайный символ из строки или случайный элемент из списка 2279 | >>> я 2280 | 2281 | numbers = [12, 89, 27, 46] 2282 | print(random.sample(numbers, 3)) # выводит 3 случайных элемента из списка numbers 2283 | >>> [46, 89, 27] 2284 | 2285 | ``` 2286 | В модуле random можно задать сид (англ. seed - семя). При одинаковых сидах одинаковый код рандома выдаст одинаковых результат. По умолчанию, начальным значением генератора является системное время (текущая дата и время). Пример: 2287 | ```python 2288 | import random 2289 | random.seed(17) # явно устанавливаем начальное значение для генератора случайных чисел 2290 | for _ in range(10): 2291 | print(random.randint(1, 100)) 2292 | >>> 67 2293 | >>> 54 2294 | >>> 39 2295 | >>> 47 2296 | >>> 38 2297 | >>> 23 2298 | >>> 99 2299 | >>> 91 2300 | >>> 91 2301 | >>> 70 2302 | ``` 2303 | Попробуйте этот код, он выведет тоже самое что и в примере. 2304 | 2305 | ## Модуль string 2306 | В модуле string есть удобные константы: 2307 | ```python 2308 | import string 2309 | 2310 | print(string.ascii_letters) 2311 | print(string.ascii_uppercase) 2312 | print(string.ascii_lowercase) 2313 | print(string.digits) 2314 | print(string.hexdigits) 2315 | print(string.octdigits) 2316 | print(string.punctuation) 2317 | print(string.printable) 2318 | >>> abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 2319 | >>> ABCDEFGHIJKLMNOPQRSTUVWXYZ 2320 | >>> abcdefghijklmnopqrstuvwxyz 2321 | >>> 0123456789 2322 | >>> 0123456789abcdefABCDEF 2323 | >>> 01234567 2324 | >>> !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ 2325 | >>> 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ \t\n\r\x0b\x0c 2326 | 2327 | ``` 2328 | ## Метод Монте-Карло 2329 | При помощи метода Монте-Карло можно вычислить примерную площадь фигуры. 2330 | Фигура: 2331 | ![Image 17](images/image_17.png) 2332 | Формула: 2333 | ​−2 ≤ x ≤ 2 2334 | −2 ≤ y ≤ 2 2335 | x^3 + y^4 + 2 ≥ 0 2336 | 3x + y^2 ≤ 2​ 2337 | 2338 | Задача вычислить примерную площадь фигуры. 2339 | Решение: 2340 | ```python 2341 | from random import uniform 2342 | 2343 | n = 10**6 # количество испытаний 2344 | k = 0 # количество попавших точек 2345 | S = 16 # площадь квадрата, в который вписана фигура 2346 | 2347 | for _ in range(n): 2348 | x = uniform(-2, 2) # рандомное число от минимальной до максимальной возможной координаты 2349 | y = uniform(-2, 2) # рандомное число от минимальной до максимальной возможной координаты 2350 | if (x**3 + y**4 + 2 >= 0) and (3*x + y**2 <= 2): # если точка внутри фигуры 2351 | k += 1 # увеличиваем количество попавших точек 2352 | 2353 | print((k/n) * S) # (точек / метр) * площадь квадрата 2354 | 2355 | ``` 2356 | ## Bogosort 2357 | Болотная сортировка (Bogosort) — неэффективный алгоритм сортировки, используемый только в образовательных целях и противопоставляемый другим, более реалистичным алгоритмам. 2358 | Принцип работы алгоритма прост, как плесень. Перетряхиваем список случайным образом до тех пор пока он внезапно не отсортируется. Процесс может счастливо завершиться сразу, а может длиться до тепловой смерти Вселенной. Это уж как повезёт. 2359 | Реализация алгоритма: 2360 | 2361 | ```python 2362 | import random 2363 | 2364 | def is_sorted(nums): # отсортирован ли список? 2365 | for i in range(len(nums) - 1): 2366 | if nums[i] > nums[i + 1]: 2367 | return False 2368 | return True 2369 | 2370 | def bogosort(nums): # реализация алгоритма болотной сортировки 2371 | while not is_sorted(nums): 2372 | random.shuffle(nums) 2373 | return nums 2374 | 2375 | numbers = list(range(10)) 2376 | random.shuffle(numbers) # перемешиваем начальный список 2377 | print(numbers) # выводим начальный список 2378 | 2379 | sorted_numbers = bogosort(numbers) 2380 | 2381 | print(sorted_numbers) 2382 | 2383 | ``` 2384 | # Модули decimal, fractions и complex 2385 | ## Модуль decimal: введение 2386 | Тип данных float не стоит использовать в случаях, когда важна точность: 2387 | ```python 2388 | num = 0.1 + 0.1 + 0.1 2389 | 2390 | if num == 0.3: 2391 | print('YES') 2392 | else: 2393 | print('NO') 2394 | print(num) 2395 | >>> NO 2396 | >>> 0.30000000000000004 2397 | ``` 2398 | Для точных расчетов рекомендуется использовать модуль decimal и тип данных Decimal. 2399 | Тип данных Decimal неизменяемый, также он в разы медленнее float. 2400 | 2401 | ## Создание Decimal чисел 2402 | Создать Decimal число можно из строки (str) или из числа с плавающей точкой (float): 2403 | ```python 2404 | from decimal import * 2405 | 2406 | d1 = Decimal(1) 2407 | d2 = Decimal(567) 2408 | d3 = Decimal(-93) 2409 | d4 = Decimal('12345') 2410 | d5 = Decimal('52.198') 2411 | 2412 | print(d1, d2, d3, d4, d5, sep='\n') 2413 | >>> 1 2414 | >>> 567 2415 | >>> -93 2416 | >>> 12345 2417 | >>> 52.198 2418 | ``` 2419 | Не стоит создавать Decimal из float, в Decimal попадает уже “неправильное” число 2420 | ```python 2421 | from decimal import * 2422 | 2423 | num = Decimal(0.1) 2424 | print(num) 2425 | >>> 0.1000000000000000055511151231257827021181583404541015625 2426 | 2427 | ``` 2428 | ## Арифметические операции над Decimal числами 2429 | Тип данных Decimal отлично интегрирован в язык Python. С Decimal числами работают все привычные операции: сложение, вычитание, умножение, деление, возведение в степень. 2430 | ```python 2431 | from decimal import * 2432 | 2433 | num1 = Decimal('5.8') 2434 | num2 = Decimal('2.5') 2435 | 2436 | print(num1 + num2) 2437 | print(num1 - num2) 2438 | print(num1 * num2) 2439 | print(num1 / num2) 2440 | print(num1 // num2) 2441 | print(num1 ** num2) 2442 | >>> 8.3 2443 | >>> 3.3 2444 | >>> 14.50 2445 | >>> 2.32 2446 | >>> 2 2447 | >>> 81.01584832611456399030280565 2448 | 2449 | ``` 2450 | Можно совершать арифметические операции над Decimal и целыми числами (миксовать Decimal и int), но не рекомендуется смешивать их с float. 2451 | 2452 | ## Математические функции Decimal чисел 2453 | Decimal числа можно передавать как аргументы функциям, ожидающим float. Они будут преобразованы во float. К примеру, модуль math, оперирующий float числами, может работать и с Decimal числами. 2454 | ```python 2455 | from decimal import * 2456 | from math import * 2457 | 2458 | num1 = Decimal('1.44') 2459 | num2 = Decimal('0.523') 2460 | 2461 | print(sqrt(num1)) 2462 | print(sin(num2)) 2463 | print(log(num1 + num2)) 2464 | >>> 1.2 2465 | >>> 0.4994813555186418 2466 | >>> 0.6744739152943241 2467 | ``` 2468 | Важно понимать, что результатом работы функции модуля math являются float числа, а не Decimal. 2469 | У модуля decimal есть встроенные математические методы, которые возвращают число с типом данных Decimal: 2470 | | Функция | Описание | 2471 | |---|---| 2472 | | sqrt() | вычисляет квадратный корень из Decimal числа | 2473 | | exp() | возвращает e^x для Decimal числа | 2474 | | ln() | вычисляет натуральный логарифм (по основанию e) Decimal числа | 2475 | | log10() | вычисляет десятичный логарифм (по основанию 10) Decimal числа | 2476 | 2477 | ```python 2478 | from decimal import * 2479 | 2480 | num = Decimal('10.0') 2481 | 2482 | print(num.sqrt()) 2483 | print(num.exp()) 2484 | print(num.ln()) 2485 | print(num.log10()) 2486 | >>> 3.162277660168379331998893544 2487 | >>> 22026.46579480671651695790065 2488 | >>> 2.302585092994045684017991455 2489 | >>> 1 2490 | 2491 | ``` 2492 | Тип данных Decimal также содержит полезный метод `as_tuple()` который возвращает кортеж из 3 элементов: 2493 | - sign – знак числа (0 для положительного числа и 1 для отрицательного числа) 2494 | - digits – цифры числа 2495 | - exponent – значение экспоненты (количество цифр после точки, умноженное на -1) 2496 | 2497 | ```python 2498 | from decimal import * 2499 | 2500 | num1 = Decimal('-1.4568769017') 2501 | num2 = Decimal('0.523') 2502 | 2503 | print(num1.as_tuple()) 2504 | print(num2.as_tuple()) 2505 | >>> DecimalTuple(sign=1, digits=(1, 4, 5, 6, 8, 7, 6, 9, 0, 1, 7), exponent=-10) 2506 | >>> DecimalTuple(sign=0, digits=(5, 2, 3), exponent=-3) 2507 | 2508 | ``` 2509 | Удобно использовать следующий код: 2510 | ```python 2511 | from decimal import * 2512 | 2513 | num = Decimal('-1.4568769017') 2514 | num_tuple = num.as_tuple() 2515 | 2516 | print(num_tuple.sign) 2517 | print(num_tuple.digits) 2518 | print(num_tuple.exponent) 2519 | >>> 1 2520 | >>> (1, 4, 5, 6, 8, 7, 6, 9, 0, 1, 7) 2521 | >>> -10 2522 | 2523 | ``` 2524 | ## Работа с контекстом Decimal чисел 2525 | Базовые параметры Decimal можно посмотреть в его контексте, выполнив функцию `getcontext():` 2526 | ```python 2527 | from decimal import * 2528 | print(getcontext()) 2529 | >>> Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, 2530 | flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]) 2531 | ``` 2532 | Мы видим здесь, что точность 28 знаков, округление к ближайшему четному, пределы по экспоненте ± 999999, capitals – это про заглавную Е при печати, включенные ловушки – неправильная операция, деление на ноль, переполнение. 2533 | 2534 | ## Точность Decimal чисел 2535 | Контекстом в Decimal можно управлять, устанавливая свои значения. Например, чтобы управлять точностью Decimal, необходимо изменить параметр контекста prec (от англ. precision – точность). 2536 | ```python 2537 | from decimal import * 2538 | 2539 | getcontext().prec = 3 # устанавливаем точность в 3 знака 2540 | num = Decimal('3.1415') 2541 | 2542 | print(num) 2543 | print(num * 1) 2544 | print(num * 2) 2545 | print(num / 2) 2546 | >>> 3.1415 2547 | >>> 3.14 2548 | >>> 6.28 2549 | >>> 1.57 2550 | ``` 2551 | Обратите внимание на то, что точность вступает в силу только во время арифметических операций, а не при создании самих чисел. 2552 | 2553 | ## Округление Decimal чисел 2554 | Округляют числа Decimal с помощью метода `quantize()`. Этот метод в качестве первого аргумента принимает объект Decimal, указывающий на формат округления. 2555 | ```python 2556 | from decimal import * 2557 | 2558 | getcontext().prec = 4 # устанавливаем точность числа 2559 | num = Decimal('3.1415926535') 2560 | 2561 | print(num.quantize(Decimal('1.000'))) # округление до 3 цифр в дробной части 2562 | print(num.quantize(Decimal('1.00'))) # округление до 2 цифр в дробной части 2563 | print(num.quantize(Decimal('1.0'))) # округление до 1 цифр в дробной части 2564 | >>> 3.142 2565 | >>> 3.14 2566 | >>> 3.1 2567 | 2568 | ``` 2569 | Если точность округления установлена в 2, а формат округления `Decimal('1.00')`, то возникнет ошибка: 2570 | ```python 2571 | from decimal import * 2572 | 2573 | getcontext().prec = 2 # устанавливаем точность округления 2574 | num = Decimal('3.1415926535') 2575 | 2576 | print(num.quantize(Decimal('1.00'))) # округление до 2 цифр в дробной части 2577 | >>> decimal.InvalidOperation: [] 2578 | 2579 | ``` 2580 | Помимо первого параметра, метод `quantize()` принимает в качестве второго параметра стратегию округления: 2581 | - ROUND_CEILING – округление в направлении бесконечности (Infinity) 2582 | - ROUND_FLOOR – округляет в направлении минус бесконечности (- Infinity) 2583 | - ROUND_DOWN – округление в направлении нуля 2584 | - ROUND_HALF_EVEN – округление до ближайшего четного числа, число 6.5 округлится не до 7, а до 6 2585 | - ROUND_HALF_DOWN – округление до ближайшего нуля 2586 | - ROUND_UP – округление от нуля 2587 | - ROUND_05UP – округление от нуля (если последняя цифра после округления до нуля была бы 00 или 55, в противном случае – к нулю). 2588 | 2589 | ```python 2590 | from decimal import * 2591 | 2592 | num = Decimal('3.456') 2593 | 2594 | print(num.quantize(Decimal('1.00'), ROUND_CEILING)) 2595 | print(num.quantize(Decimal('1.00'), ROUND_FLOOR)) 2596 | >>> 3.46 2597 | >>> 3.45 2598 | 2599 | ``` 2600 | ## Сравнение float и Decimal чисел 2601 | | Характеристика / тип | float | Decimal | 2602 | |---|---|---| 2603 | | Реализация | аппаратная | программная | 2604 | | Размер | 64 бит | не ограничен | 2605 | | Основание экспоненты | 2 | 10 | 2606 | | Скорость | + | - | 2607 | | Настраиваемость | - | + | 2608 | | Для финансов и бизнеса | - | + | 2609 | | Для симуляций, визуализаций и игр | + | - | 2610 | | Для высокоточных вычислений | - | + | 2611 | 2612 | ## Важные примечания для decimal 2613 | - Decimal числа можно сравнивать между собой, как обычные числа, причем в отличие от float чисел допускается и точное равенство. 2614 | ```python 2615 | from decimal import * 2616 | 2617 | num = Decimal("0.1") 2618 | if num * 3 == Decimal("0.3"): 2619 | print("YES") 2620 | else: 2621 | print("NO") 2622 | >>> YES 2623 | 2624 | ``` 2625 | - Можно сортировать списки с Decimal числами и искать минимум и максимум среди них. 2626 | ```python 2627 | from decimal import * 2628 | 2629 | s = '1.34 3.45 1.00 0.03 9.25' 2630 | 2631 | numbers = [Decimal(i) for i in s.split()] 2632 | 2633 | maximum = max(numbers) 2634 | minimum = min(numbers) 2635 | 2636 | numbers.sort() 2637 | 2638 | print(maximum) 2639 | print(minimum) 2640 | print(numbers) 2641 | >>> 9.25 2642 | >>> 0.03 2643 | >>> [Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('3.45'), Decimal('9.25')] 2644 | 2645 | ``` 2646 | - Чтобы не писать каждый раз название типа, можно использовать приведенный ниже код: 2647 | ```python 2648 | from decimal import Decimal as D 2649 | 2650 | num1 = D("1.5") + D("3.2") 2651 | num2 = D("1.4") * D("2.5") 2652 | 2653 | print(num1) 2654 | print(num2) 2655 | >>> 4.7 2656 | >>> 3.50 2657 | ``` 2658 | ## Модуль fractions: введение 2659 | Рациональное число – это число, которое можно представить в виде дроби ​m/n, где m, n соответственно, числитель и знаменатель, которые имеют целочисленное значение, при этом знаменатель не равен нулю. 2660 | Например, в дроби 5/6​ числитель m=5, а знаменатель n=6. 2661 | Знаменатель дроби показывает количество равных частей, а числитель дроби показывает, сколько из них взято. 2662 | ![Image 18](images/image_18.png) 2663 | 2664 | ## Тип данных Fraction 2665 | Для работы с рациональными числами в Python используется тип данных Fraction. Тип данных Fraction как и Decimal реализован программно, поэтому он в разы медленнее встроенных числовых типов данных int и float. Тип данных Fraction неизменяемый. Операции над данными этого типа приводят к созданию новых объектов, при этом старые не меняются. 2666 | Чтобы использовать возможности типа данных Fraction, нужно предварительно подключить модуль fractions: 2667 | ```python 2668 | from fractions import Fraction 2669 | 2670 | ``` 2671 | ## Создание Fraction чисел 2672 | Создать Fraction число можно несколькими способами: 2673 | - из целых чисел, передав значения числителя и знаменателя дроби 2674 | - из строки на основании десятичного представления 2675 | - из строки на основании обыкновенной дроби 2676 | - из числа с плавающей точкой (не рекомендуется) 2677 | 2678 | ```python 2679 | from fractions import Fraction 2680 | 2681 | num1 = Fraction(7, 32) # 7 - числитель, 32 - знаменатель 2682 | num2 = Fraction('0.67') 2683 | num3 = Fraction('1/45') 2684 | 2685 | print(num1, num2, num3, sep='\n') 2686 | >>> 7/32 2687 | >>> 67/100 2688 | >>> 1/45 2689 | 2690 | ``` 2691 | Не стоит создавать Fraction из float: 2692 | ```python 2693 | from fractions import Fraction 2694 | 2695 | num = Fraction(0.34) 2696 | 2697 | print(num) # Вместо 17/50 код выведет: 2698 | >>> 6124895493223875/18014398509481984 2699 | 2700 | ``` 2701 | ## Основы типа данных Fraction 2702 | Обратите внимание на то, что при создании рационального числа Fraction, автоматически происходит сокращение числителя и знаменателя дроби: 2703 | ```python 2704 | from fractions import Fraction 2705 | 2706 | num = Fraction(4, 8) 2707 | 2708 | print(num) 2709 | >>> 1/2 2710 | 2711 | ``` 2712 | Вывод дробей, являющихся целыми числами: 2713 | ```python 2714 | from fractions import Fraction 2715 | 2716 | num = Fraction(5, 1) 2717 | 2718 | print(num) 2719 | >>> 5 2720 | 2721 | ``` 2722 | Для того чтобы каждый раз не писать название типа, можно использовать следующий код: 2723 | ```python 2724 | from fractions import Fraction as F 2725 | 2726 | num1 = F('1/5') + F('3/2') 2727 | num2 = F('1/4') * F('2/5') 2728 | 2729 | print(num1) 2730 | print(num2) 2731 | 2732 | ``` 2733 | ## Сравнение Fraction чисел 2734 | Fraction числа можно сравнивать между собой точно так же, как и любые другие числа. Доступны 6 основных операторов сравнения: 2735 | ``` 2736 | - >: больше 2737 | - <: меньше 2738 | - >=: больше либо равно 2739 | - <=: меньше либо равно 2740 | - ==: в точности равно 2741 | - !=: не равно 2742 | ``` 2743 | Обратите внимание на то, что мы можем сравнивать Fraction числа и целые числа (числа с плавающей точкой) без явного приведения типов. 2744 | 2745 | ## Арифметические операции над Fraction числами 2746 | Тип данных Fraction отлично интегрирован в язык Python. С Fraction числами работают все привычные операции: сложение, вычитание, умножение, деление, возведение в степень. 2747 | Мы также можем совершать арифметические операции над Fraction и целыми числами (миксовать Fraction и int), но не рекомендуется смешивать их с float. 2748 | Обратите внимание на то, что операция возведения в степень (**) для Fraction чисел может возвращать вещественный результат: 2749 | ```python 2750 | from fractions import Fraction 2751 | 2752 | num1 = Fraction('3/8') 2753 | num2 = Fraction('1/2') 2754 | 2755 | print(num1 ** num2) 2756 | >>> 0.6123724356957945 2757 | 2758 | ``` 2759 | ## Математические функции 2760 | Fraction числа можно передавать как аргументы функций, ожидающих float. Тогда они будут преобразованы во float. К примеру, модуль math, оперирующий float числами, может работать и с Fraction числами. 2761 | ```python 2762 | from fractions import Fraction 2763 | from math import * 2764 | 2765 | num1 = Fraction('1.44') 2766 | num2 = Fraction('0.523') 2767 | 2768 | print(sqrt(num1)) 2769 | print(sin(num2)) 2770 | print(log(num1 + num2)) 2771 | >>> 1.2 2772 | >>> 0.4994813555186418 2773 | >>> 0.6744739152943241 2774 | 2775 | ``` 2776 | ## Свойства numerator и denominator, as_integer_ratio() 2777 | ```python 2778 | from fractions import Fraction 2779 | 2780 | num = Fraction('5/16') 2781 | 2782 | print('Числитель дроби равен:', num.numerator) 2783 | print('Знаменатель дроби равен:', num.denominator) 2784 | >>> Числитель дроби равен: 5 2785 | >>> Знаменатель дроби равен: 16 2786 | 2787 | ``` 2788 | Метод `as_integer_ratio() `возвращает кортеж, состоящий из числителя и знаменателя данного Fraction числа: 2789 | ```python 2790 | from fractions import Fraction 2791 | 2792 | num = Fraction('-5/16') 2793 | 2794 | print(num.as_integer_ratio()) 2795 | >>> (-5, 16) 2796 | 2797 | ``` 2798 | ## Метод limit_denominator() 2799 | Метод `limit_denominator() `возвращает самую близкую к данному числу рациональную дробь, чей знаменатель не превосходит переданного аргумента: 2800 | ```python 2801 | from fractions import Fraction 2802 | 2803 | num = (Fraction("0.83485")) 2804 | 2805 | for d in [1, 5, 50, 90, 100, 500, 1000000]: 2806 | limited = num.limit_denominator(d) 2807 | print(limited) 2808 | >>> 1 2809 | >>> 4/5 2810 | >>> 5/6 2811 | >>> 71/85 2812 | >>> 81/97 2813 | >>> 369/442 2814 | >>> 16697/20000 2815 | 2816 | ``` 2817 | ## Комплексные числа: введение 2818 | ``` 2819 | Рассмотрим квадрат произвольного вещественного числа: 2820 | - 2*2=4 2821 | - (−2)*(−2)=4 2822 | - 0*0=0 2823 | - 0.1*0.1=0.01 2824 | Результат всегда неотрицательное число. Действительно, пусть a – произвольное вещественное число. Тогда a*a=a^2≥0. Таким образом, на множестве вещественных чисел, перемножая два одинаковых числа мы всегда получаем неотрицательное число (большее, либо равное нулю). 2825 | 2826 | Представим, что существует число i (не являющееся вещественным), такое, что i*i=i^2=−1. Будет ли такое обозначение полезным? Оказывается, да! Такие числа в математике называются мнимыми и обозначают их буквой i, от слова imaginary (мнимый, воображаемый). Итак, получаем: 2827 | i^2=-1, отсюда i = √(-1) 2828 | 2829 | Мнимая единица i обладает интересным свойством: каждый раз при умножении на i она "циклически" проходит через 4 различных значения: 2830 | 1*i=i 2831 | i*i=-1 2832 | -1*i=-1 2833 | -i*i=1 2834 | ``` 2835 | 2836 | ## Комплексные числа в математике 2837 | Комплексное число – комбинация вещественного и мнимого числа. Таким образом, число вида a+bi, где a, b – вещественные числа, называется комплексным числом. 2838 | 2839 | Модулем комплексного числа z=a+bi называется вещественное число, равное: 2840 | |z|=√(a^2+b^2) 2841 | 2842 | Число zˉ=a−bi называется сопряженным к числу z=a+bi. Произведение двух сопряженных чисел является вещественным числом. 2843 | 2844 | ## Комплексные числа в Python 2845 | Для работы с комплексными числами (тип complex) не нужно подключать какой-либо модуль в отличие от типов Decimal и Fraction. 2846 | В языке Python есть возможность работать с комплексными числами. Общая форма представления комплексного числа следующая: real + imag j, где: 2847 | - real – вещественная часть комплексного числа 2848 | - imag – мнимая часть комплексного числа, которая завершается символом j или J. 2849 | 2850 | ```python 2851 | z1 = 5 + 7j 2852 | z2 = 1j 2853 | z3 = -3 + 5J 2854 | z4 = 1.5 + 3.2j 2855 | 2856 | print(z1, z2, z3, z4, sep='\n') 2857 | print(type(z1)) 2858 | >>> (5+7j) 2859 | >>> 1j 2860 | >>> (-3+5j) 2861 | >>> (1.5+3.2j) 2862 | >>> 2863 | 2864 | ``` 2865 | ## Создание комплексных чисел 2866 | Комплексные числа можно создать с помощью литерала, как выше, а можно с помощью функции `complex()`, которая принимает два аргумента: вещественную и мнимую часть числа, либо строковое представление числа. 2867 | ```python 2868 | z1 = -3 + 2j # создание на основе литерала 2869 | z2 = complex(6, -8) # z2 = 6 - 8j 2870 | z3 = complex(0, 2.5) # z3 = 2.5j 2871 | z4 = complex(5, 0) # z4 = 5 + 0j 2872 | z5 = complex('3+4j') # создание на основе строки 2873 | 2874 | print(z1, z2, z3, z4, z5, sep='\n') 2875 | >>> (-3+2j) 2876 | >>> (6-8j) 2877 | >>> 2.5j 2878 | >>> (5+0j) 2879 | >>> (3+4j) 2880 | 2881 | ``` 2882 | ## Арифметические операции над комплексными числами 2883 | ```python 2884 | z1 = 1 + 3j 2885 | z2 = -3 + 2j 2886 | 2887 | print('z1 + z2 =', z1 + z2) 2888 | print('z1 - z2 =', z1 - z2) 2889 | print('z1 * z2 =', z1 * z2) 2890 | print('z1 / z2 =', z1 / z2) 2891 | print('z1^20 =', z1**20) 2892 | >>> z1 + z2 = (-2+5j) 2893 | >>> z1 - z2 = (4+1j) 2894 | >>> z1 * z2 = (-9-7j) 2895 | >>> z1 / z2 = (0.23076923076923078-0.8461538461538461j) 2896 | >>> z1^20 = (9884965888-1512431616j) 2897 | ``` 2898 | Мы также можем совершать арифметические операции над complex и целыми числами (миксовать complex, int, float). 2899 | 2900 | ## Методы и свойства комплексных чисел 2901 | ```python 2902 | z = 3+4j 2903 | 2904 | print('Действительная часть =', z.real) 2905 | print('Мнимая часть =', z.imag) 2906 | >>> Действительная часть = 3.0 2907 | >>> Мнимая часть = 4.0 2908 | 2909 | ``` 2910 | Для нахождения сопряженного комплексного числа можно использовать метод `conjugate()`: 2911 | ```python 2912 | z = 3+4j 2913 | print('Сопряженное число =', z.conjugate()) 2914 | >>> Сопряженное число = (3-4j) 2915 | 2916 | ``` 2917 | Для нахождения модуля комплексного числа используется встроенная функция `abs()`: 2918 | ```python 2919 | z = 3+4j 2920 | print('Модуль числа =', abs(z)) 2921 | >>> Модуль числа = 5.0 2922 | 2923 | ``` 2924 | ## cmath 2925 | Встроенный модуль math работает с вещественными числами. Для работы с комплексными числами есть модуль cmath. Модуль cmath включает дополнительные функции для использования комплексных чисел. 2926 | ```python 2927 | import cmath 2928 | 2929 | z = 2+3j 2930 | print(cmath.phase(z)) # полярный угол 2931 | print(cmath.polar(z)) # полярные координаты 2932 | >>> 0.982793723247329 2933 | >>> (3.605551275463989, 0.982793723247329) 2934 | ``` 2935 | Модуль cmath содержит следующие категории функций: 2936 | - Экспоненциальные и логарифмические функции 2937 | - Квадратные корни 2938 | - Тригонометрические функции и их обратные 2939 | - Гиперболические функции и их обратные 2940 | 2941 | # Модуль turtle 2942 | ## Введение в turtle 2943 | Подключение модуля: 2944 | ```python 2945 | import turtle 2946 | 2947 | ``` 2948 | В результате команды `turtle.showturtle()` появляется графическое окно с черепашкой. Черепашка первоначально расположена в центре графического окна, "холста". Выглядит она как стрелка с острием на месте головы. Если дать черепашке команду двигаться вперед, она переместится в направлении, указываемом стрелкой. По умолчанию на старте черепашка смотрит на восток. 2949 | 2950 | ## Рисование отрезков прямой 2951 | Для перемещения черепашки вперед на n пикселей применяется команда `turtle.forward(n)`. 2952 | Для перемещения черепашки назад на n пикселей применяется команда `turtle.backward(n)`. 2953 | 2954 | ## Поворот черепашки 2955 | Команда `turtle.right(angle) `поворачивает черепашку вправо на angle градусов. 2956 | Команда `turtle.left(angle)` поворачивает черепашку влево на angle градусов. 2957 | Команда `turtle.setheading(angle)` применяется для установки углового направления черепашки с заданным углом. В качестве аргумента нужно указать желаемый угол. 2958 | Чтобы получить текущее угловое направление черепашки используется команда `turtle.heading()`. 2959 | 2960 | ## Изменение внешнего вида черепашки 2961 | По умолчанию черепашка выглядит как стрелочка, но возможен и другой внешний вид. Для его изменения используют команду `turtle.shape(shape_name).` Команда принимает в качестве аргумента строковое название фигуры, определяющей форму черепашки. Доступные фигуры: 2962 | - square (квадрат) 2963 | - arrow (стрелка) 2964 | - circle (круг) 2965 | - turtle (черепашка) 2966 | - triangle (треугольник) 2967 | - classic (классическая стрелка) 2968 | 2969 | При необходимости можно использовать собственные рисунки для создания внешнего вида черепашки: 2970 | ```python 2971 | import turtle 2972 | 2973 | turtle.Screen().addshape('rocketship.gif') # регистрируем изображение 2974 | turtle.shape('rocketship.gif') # устанавливаем изображение 2975 | 2976 | 2977 | for _ in range(4): 2978 | turtle.forward(150) 2979 | turtle.left(90) 2980 | 2981 | ``` 2982 | ## Поднятие и опускание пера 2983 | Команда `turtle.penup() `поднимает перо, а команда `turtle.pendown()` - опускает. Когда перо поднято, черепашка перемещается не оставляя линии. Когда перо опущено, черепашка во время перемещения чертит линию. По умолчанию перо опущено. 2984 | 2985 | ## Рисование кругов и точек 2986 | Чтобы черепашка нарисовала круг, можно применить команду `turtle.circle(radius)`. Такая команда рисует круг заданного в виде аргумента в пикселях радиуса. 2987 | Команда `turtle.dot()` применяется, чтобы черепашка нарисовала точку. 2988 | ## Изменение размера пера 2989 | Для изменения ширины пера черепашки в пикселях можно применить команду `turtle.pensize(size)`. Аргумент команды – целое число, задает ширину пера. 2990 | 2991 | ## Изменение цвета рисунка 2992 | Для изменения цвета рисунка можно применить команду `turtle.pencolor(color)`. Аргумент команды – строковое представление названия цвета. 2993 | Пример: `turtle.pencolor('red')`. 2994 | Наиболее распространённые цвета: 2995 | - red (красный) 2996 | - green (зеленый) 2997 | - bluе (синий) 2998 | - yellow (желтый) 2999 | - cyan (сине-зелёный) 3000 | 3001 | Команда `turtle.pencolor(color)` позволяет работать не только с предопределенными названиями цветов, но и с цветами, заданными в формате RGB (Red Green Blue). В качестве аргумента команды `turtle.pencolor(r, g, b)` можно использовать либо кортеж из 3 чисел (r, g, b), либо просто три числа r, g, b. В Python 3 для того, чтобы использовать цвет в формате RGB, нужно предварительно установить значение colormode в 255, для этого нужно использовать команду `turtle.Screen().colormode(255).` 3002 | 3003 | ## Изменение цвета фона 3004 | Для изменения фонового цвета графического окна можно применить команду `turtle.Screen().bgcolor(color)`. В этом случае тоже можно использовать цвета с предопределенными названиями или задать цвет в RGB формате. 3005 | 3006 | Мы также можем установить фоновое изображение с помощью команды `turtle.Screen().bgpic('picture.png')`. 3007 | 3008 | ## Создание штампа 3009 | С помощью команды `turtle.stamp()` можно оставить штамп черепашки. Использование команды `turtle.stamp()` производит тот же эффект, что и команда `turtle.dot([radius])`, но оставляет отметку в форме черепашки. 3010 | 3011 | ## Возвращение экрана в исходное состояние 3012 | Команда `turtle.clear()` стирает все рисунки в графическом окне. Но не меняет положение черепашки, цвет рисунка и цвет фона графического окна. 3013 | Команда `turtle.reset()` стирает все рисунки, имеющиеся в графическом окне, задает черный цвет рисунка и возвращает черепашку в исходное положение в центре экрана. Эта команда не переустанавливает цвет фона графического окна. 3014 | Команда `turtle.clearscreen()` стирает все рисунки в графическом окне, меняет цвет рисунка на черный, а цвет фона на белый, и возвращает черепашку в исходное положение в центре графического окна. 3015 | 3016 | ## Размер окна 3017 | Для установления размера графического окна можно применить команду `turtle.Screen().setup(width, height)`. Аргументы команды – ширина и высота (в пикселях). 3018 | 3019 | ## Перемещение черепашки в заданную позицию 3020 | ![Image 19](images/image_19.png) 3021 | Для перемещения черепашки в конкретную позицию в графическом окне применяется команда `turtle.goto(x, y)`. Аргументами служат координаты целевой позиции. Если перо черепашки опущено вниз (по умолчанию оно опущено), то будет начерчена линия. 3022 | 3023 | Команды `turtle.setposition(x, y)` и `turtle.setpos(x, y)` аналогичны команде `turtle.goto(x, y)`. Все три команды перемещают черепашку в заданную позицию. 3024 | 3025 | ## Получение текущей позиции черепашки 3026 | Команда `turtle.pos()` возвращает кортеж с x и y координатами черепашки. Команда `turtle.position()` аналогична команде `turtle.pos()`. Обе эти команды возвращают кортеж с x и y координатами черепашки. 3027 | Для получения только координаты x черепашки служит команда `turtle.xcor()`, а для получения координаты y - команда `turtle.ycor()`. 3028 | 3029 | ## Сокрытие черепашки 3030 | Когда не нужно, чтобы черепашка отображалась на экране, применяется команда `turtle.hideturtle()`, которая ее прячет. Эта команда не изменяет процесс создания графического изображения, она просто скрывает значок черепашки. Когда требуется снова вывести черепашку на экран, применяется команда `turtle.showturtle()`. 3031 | 3032 | ## Управление скоростью анимации черепахи 3033 | Для изменения скорости движения черепашки можно применить команду `turtle.speed(speed)`. Аргумент команды скорость – число в диапазоне от 0 до 10. Если указать 0, то черепашка будет делать все свои перемещения мгновенно (анимация отключена). 3034 | 3035 | ## Вывод текста в графическое окно 3036 | Для вывода текста в графическое окно применяется команда `turtle.write(string)`. Аргумент этой команды — строка текста, которую требуется вывести на экран. Левый нижний угол первого символа выведенного текста будет расположен в точке с координатами черепашки. 3037 | 3038 | Аргументы команды `write(args)`: 3039 | - arg – текст, который нужно вывести 3040 | - move – указывает будет ли двигаться черепашка по мере рисования надписи (по умолчанию значение False) 3041 | - align – служит для выравнивания надписи относительно черепашки, может принимать три строковых значения right, center, left (по умолчанию значению right) 3042 | - font – кортеж из трех значений: (название шрифта, размер шрифта, тип начертания). В качестве начертания можно использовать строковые значения: normal — обычный, bold — полужирный, italic — курсив, или объединить два последних, тогда текст будет напечатан полужирным курсивом. 3043 | 3044 | Пример: 3045 | ```python 3046 | import turtle 3047 | turtle.write('Приветик)', move=True, align='left', font=('Times New Roman', 25, 'normal')) 3048 | ``` 3049 | Вывод: 3050 | ![Image 20](images/image_20.png) 3051 | 3052 | ## Заполнение геометрических фигур 3053 | Для заполнения геометрической фигуры цветом используется команда `turtle.begin_fill()`, причем она применяется до начертания фигуры, а после завершения начертания используется команда `turtle.end_fill()` и геометрическая фигура заполняется текущим цветом заливки. 3054 | 3055 | Пример: 3056 | ```python 3057 | import turtle 3058 | 3059 | turtle.hideturtle() 3060 | turtle.begin_fill() # включаем заливку 3061 | turtle.circle(80) 3062 | turtle.end_fill() # выключаем заливку 3063 | ``` 3064 | Вывод: 3065 | ![Image 21](images/image_21.png) 3066 | 3067 | Цвет заливки можно изменить при помощи команды `turtle.fillcolor(color / r, g, b)`. Аргумент команды — название цвета в виде строкового литерала, либо значения трех компонентов RGB. 3068 | 3069 | ## Создание нескольких черепашек 3070 | Можно работать сразу с несколькими черепашками. Для этого надо создать несколько переменных, содержащих экземпляры класса Turtle. 3071 | 3072 | Пример: 3073 | ```python 3074 | import turtle 3075 | from random import randrange 3076 | 3077 | def move_turtles(turtles, dist, angle): 3078 | for turtle in turtles: # все черепашки из списка делают одни и те же действия 3079 | turtle.forward(dist) 3080 | turtle.right(angle) 3081 | 3082 | 3083 | turtles = [] # список черепашек 3084 | head = 0 3085 | num_turtles = 10 # количество череашек 3086 | for i in range(num_turtles): 3087 | turt = turtle.Turtle() # создаем черепашку и устанавливаем ее свойства 3088 | turt.setheading(head) 3089 | turt.pensize(2) 3090 | turt.color(randrange(256), randrange(256), randrange(256)) 3091 | turt.speed(5) 3092 | turt.tracer(25, 0) 3093 | turtles.append(turt) # добавляем черепашку в список 3094 | head = head + 360/num_turtles 3095 | 3096 | for i in range(70): 3097 | move_turtles(turtles, 10, i) 3098 | 3099 | ``` 3100 | Вывод: 3101 | ![Image 22](images/image_22.png) 3102 | 3103 | Команда `turtle.tracer(n, delay)` включает/выключает анимацию черепашки и устанавливает задержку для обновления рисунков. Может использоваться для ускорения рисования сложной графики. 3104 | 3105 | ## Отслеживание нажатия клавиш 3106 | Черепашья графика позволяет отслеживать происходящие события, такие как нажатия клавиш клавиатуры, перемещение мышки или нажатие на мышку. Изначально программа никак не реагирует на эти события и чтобы это поведение изменить необходимо привязать функции обратного вызова к событиям. Для этого существуют специальные команды. Для отслеживания нажатия клавиш клавиатуры используется команда `turtle.Screen().onkey(fun, key)`, которая связывает функцию обратного вызова fun с событием нажатия клавиши key. 3107 | Для отслеживания событий также необходимо установить фокус на экран черепашки с помощью команды `turtle.Screen().listen()`. 3108 | Пример: 3109 | ```python 3110 | import turtle 3111 | 3112 | def move_up(): # функция обратного вызова 3113 | x, y = turtle.pos() 3114 | turtle.setposition(x, y + 5) 3115 | 3116 | def move_down(): # функция обратного вызова 3117 | x, y = turtle.pos() 3118 | turtle.setposition(x, y - 5) 3119 | 3120 | def move_left(): # функция обратного вызова 3121 | x, y = turtle.pos() 3122 | turtle.setposition(x - 5, y) 3123 | 3124 | def move_right(): # функция обратного вызова 3125 | x, y = turtle.pos() 3126 | turtle.setposition(x + 5, y) 3127 | 3128 | turtle.showturtle() # отображаем черепашку 3129 | turtle.pensize(3) # устанавливаем размер пера 3130 | turtle.shape('turtle') 3131 | turtle.Screen().listen() # устанавливаем фокус на экран черепашки 3132 | 3133 | turtle.Screen().onkey(move_up, 'Up') # регистрируем функцию на нажатие клавиши наверх 3134 | turtle.Screen().onkey(move_down, 'Down') # регистрируем функцию на нажатие клавиши вниз 3135 | turtle.Screen().onkey(move_left, 'Left') # регистрируем функцию на нажатие клавиши налево 3136 | turtle.Screen().onkey(move_right, 'Right') # регистрируем функцию на нажатие клавиши направо 3137 | 3138 | ``` 3139 | ## Отслеживание нажатия мыши 3140 | Аналогичным образом можно отслеживать нажатие на мышку. Для отслеживания нажатия мыши используется команда `turtle.Screen().onclick(fun)`, которая связывает функцию обратного вызова fun с событием нажатия левой кнопки мыши. 3141 | Пример: 3142 | ```python 3143 | import turtle 3144 | from random import randrange 3145 | 3146 | def random_color(): 3147 | return randrange(256), randrange(256), randrange(256) 3148 | 3149 | def draw_circle(x, y, r): 3150 | turtle.penup() 3151 | turtle.goto(x, y - r) 3152 | turtle.pendown() 3153 | color = random_color() 3154 | turtle.pencolor(color) 3155 | turtle.fillcolor(color) 3156 | turtle.begin_fill() 3157 | turtle.circle(r) 3158 | turtle.end_fill() 3159 | turtle.speed(0) 3160 | 3161 | def left_mouse_click(x, y): 3162 | draw_circle(x, y, 10) 3163 | 3164 | turtle.hideturtle() 3165 | 3166 | turtle.Screen().onclick(left_mouse_click) 3167 | turtle.Screen().listen() 3168 | 3169 | ``` 3170 | # Функции 3171 | ## Функции без параметров 3172 | Именование функций 3173 | Python и тут требует соблюдения тех же правил, что при именовании переменных: 3174 | - в имени функции используются только латинские буквы a-z, A-Z, цифры и символ нижнего подчеркивания (_) 3175 | - имя функции не может начинаться с цифры 3176 | - имя функции по возможности должно отражать ее назначение 3177 | - символы верхнего и нижнего регистра различаются. 3178 | Объявление функции: 3179 | ```python 3180 | def название_функции(): 3181 | блок кода 3182 | 3183 | pass # ничего не делает, используется как заглушка. 3184 | ``` 3185 | Вызов функции: 3186 | ```python 3187 | название_функции() 3188 | ``` 3189 | Объявление функции должно предшествовать ее вызову. 3190 | 3191 | ## Функции с параметрами 3192 | Объявление функции с параметрами: 3193 | ```python 3194 | def название_функции(параметры): 3195 | блок кода 3196 | ``` 3197 | При вызове функции мы обязаны использовать столько аргументов, сколько объявлено в функции. 3198 | Пример: 3199 | ```python 3200 | def draw(c): 3201 | for i in range(c): 3202 | print('*' * 10) 3203 | 3204 | draw(10) 3205 | >>> ********** 3206 | >>> ********** 3207 | >>> ********** 3208 | >>> ********** 3209 | >>> ********** 3210 | >>> ********** 3211 | >>> ********** 3212 | >>> ********** 3213 | >>> ********** 3214 | >>> ********** 3215 | 3216 | ``` 3217 | ## Глобальные, нелокальные и локальные переменные 3218 | Локальными называются переменные, объявленные внутри функции и доступные только ей самой. Программный код за пределами функции к ним доступа не имеет. 3219 | ```python 3220 | def print_paris(): 3221 | s = 'I love Paris' 3222 | print(s) 3223 | 3224 | def print_london(): 3225 | s = 'I love London' 3226 | print(s) 3227 | 3228 | s = 'I love Moscow' 3229 | print_paris() 3230 | print_london() 3231 | print(s) 3232 | >>> I love Paris 3233 | >>> I love London 3234 | >>> I love Moscow 3235 | 3236 | ``` 3237 | Глобальными называются переменные, объявленные в основной программе и доступные как программе, так и всем ее функциям. 3238 | Если нужно, чтобы инструкция внутри функции присваивала значение глобальной переменной, то требуется дополнительный шаг. В этом случае глобальная переменная должна быть объявлена внутри функции. Благодаря `global `можно изменять глобальную переменную в функции. 3239 | ```python 3240 | def print_texas(): 3241 | global birds 3242 | birds = 5000 3243 | print('В Техасе обитает', birds, 'птиц.') 3244 | 3245 | def print_california(): 3246 | print('В Калифорнии обитает', birds, 'птиц.') 3247 | 3248 | print_texas() 3249 | print_california() 3250 | >>> В Техасе обитает 5000 птиц. 3251 | >>> В Калифорнии обитает 5000 птиц. 3252 | ``` 3253 | В следующем коде мы работаем с глобальной переменной в функции: 3254 | ```python 3255 | x = 5 3256 | 3257 | def add(): 3258 | global x 3259 | x = 3 3260 | x = x + 5 3261 | print(x) 3262 | 3263 | add() 3264 | print(x) 3265 | ``` 3266 | Код выведет 8 8, так как мы использовали `global x`, а значит функция будет изменять глобальную переменную. 3267 | 3268 | Также есть `nonlocal` переменные, они видны внутри вложенной функции, но относятся к переменным из внешней функции (не глобальной). 3269 | Если во вложенной функции используется `nonlocal`, то переменной должно быть присвоено значение во внешней функции до этого — иначе будет ошибка: 3270 | ```python 3271 | def main(): 3272 | def print_number(): 3273 | nonlocal number # ошибка 3274 | number = 5 3275 | print(number) 3276 | 3277 | print_number() 3278 | 3279 | 3280 | main() 3281 | 3282 | ``` 3283 | ## Функции с возвратом значения 3284 | Некоторые команды в Python возвращают что-то, например, `len("Бургер") `вернёт 6. 3285 | Есть команды, которые ничего не возвращают, например, `del a[2] `просто удаляет элемент списка. 3286 | Для возврата значения используют `return значение `в конце тела функции. Все команды написанные после `return `в функции не будут выполнятся. 3287 | Пример: 3288 | ```python 3289 | def square(x): 3290 | return x**2 3291 | 3292 | print(square(2)) 3293 | >>> 4 3294 | ``` 3295 | Код выводит квадрат числа 2 3296 | 3297 | Также можно возвращать `True` или `False`. 3298 | Пример: 3299 | ```python 3300 | def divide(x): 3301 | if x % 2 == 0: 3302 | return True 3303 | 3304 | if divide(2): 3305 | print('Число делится на 2') 3306 | else: 3307 | print('Число не делится на 2') 3308 | 3309 | ``` 3310 | Также можно возвращать несколько значений: 3311 | ```python 3312 | def sqr(x, y): 3313 | return x**2, y**2 3314 | 3315 | print(sqr(2, 4)) 3316 | >>> (4, 16) 3317 | 3318 | ``` 3319 | ## Позиционные и именованные аргументы 3320 | Все ранее написанные нами функции имели позиционные аргументы. Такие аргументы передаются без указания имен. Они называются позиционными, потому что именно по позиции, расположению аргумента, функция понимает, какому параметру он соответствует. 3321 | ```python 3322 | def diff(x, y): 3323 | return x - y 3324 | 3325 | 3326 | res = diff(10, 3) # используем позиционные аргументы 3327 | print(res) 3328 | >>> 7 3329 | ``` 3330 | При вызове функции `diff()` первому параметру x будет соответствовать первый переданный аргумент, 10, а второму параметру y — второй аргумент, 3. 3331 | 3332 | Аргументы, передаваемые с именами, называются именованными. При вызове функции можно использовать имена параметров из ее определения. 3333 | ```python 3334 | def diff(x, y): 3335 | return x - y 3336 | 3337 | 3338 | res = diff(y=3, x=10) # используем именованные аргументы 3339 | print(res) 3340 | >>> 7 3341 | ``` 3342 | Такой код по-прежнему выведет число 7. При вызове функции `diff()` мы явно указываем, что параметру x соответствует аргумент 10, а параметру y - аргумент 3. 3343 | 3344 | Комбинировать позиционные и именованные аргументы можно, но позиционные значения должны быть указаны до любых именованных. 3345 | ```python 3346 | res = diff(10, y=3) # используем позиционный и именованный аргумент 3347 | ``` 3348 | Но: 3349 | ```python 3350 | res = diff(x=10, 3) # используем позиционный и именованный аргумент 3351 | ``` 3352 | Приводит к возникновению ошибки `SyntaxError: positional argument follows keyword argument.` 3353 | 3354 | ## Необязательные аргументы 3355 | Например, нам нужна функция которая рисует круг с радиусом radius при указании аргумента radius. Если его не указать, radius будет выставлено значение 10. Вот так это можно реализовать: 3356 | ```python 3357 | def draw_circle(radius=10): 3358 | print(f"Радиус круга: {radius}") 3359 | 3360 | 3361 | draw_circle() 3362 | draw_circle(100) 3363 | >>> Радиус круга: 10 3364 | >>> Радиус круга: 100 3365 | 3366 | ``` 3367 | ## Изменяемые типы в качестве значений по умолчанию 3368 | ```python 3369 | def append(element, seq=[]): 3370 | seq.append(element) 3371 | return seq 3372 | 3373 | 3374 | print(append(100, [])) 3375 | print(append(238, [])) 3376 | 3377 | print(append(100)) 3378 | print(append(238)) 3379 | >>> [100] 3380 | >>> [238] 3381 | >>> [100] 3382 | >>> [100, 238] 3383 | ``` 3384 | Почему `append(238)` выводит не `[238]`, а `[100, 238]`? Значение по умолчанию для параметра создается единожды при определении функции (обычно при загрузке модуля) и становится атрибутом (свойством) функции. Поэтому, если значение по умолчанию изменяемый объект, то его изменение повлияет на каждый следующий вызов функции. Вместо этого используйте такой код: 3385 | ```python 3386 | def append(element, seq=None): 3387 | if seq is None: 3388 | seq = [] 3389 | seq.append(element) 3390 | return seq 3391 | 3392 | ``` 3393 | Чтобы посмотреть значения по умолчанию, можно использовать атрибут `__defaults__`: 3394 | ```python 3395 | def append(element, seq=[]): 3396 | seq.append(element) 3397 | return seq 3398 | 3399 | print('Значение по умолчанию', append.__defaults__) 3400 | print(append(10)) 3401 | print('Значение по умолчанию', append.__defaults__) 3402 | print(append(5)) 3403 | print('Значение по умолчанию', append.__defaults__) 3404 | print(append(1)) 3405 | print('Значение по умолчанию', append.__defaults__) 3406 | >>> Значение по умолчанию ([],) 3407 | >>> [10] 3408 | >>> Значение по умолчанию ([10],) 3409 | >>> [10, 5] 3410 | >>> Значение по умолчанию ([10, 5],) 3411 | >>> [10, 5, 1] 3412 | >>> Значение по умолчанию ([10, 5, 1],) 3413 | 3414 | ``` 3415 | ## Переменное количество аргументов (*args, **kwargs) 3416 | Функция может принимать столько аргументов, сколько ей передали: 3417 | ```python 3418 | def my_func(*args): 3419 | print(type(args)) 3420 | print(args) 3421 | 3422 | 3423 | my_func() 3424 | my_func(1, 2, 3) 3425 | my_func('a', 'b') 3426 | >>> 3427 | >>> () 3428 | >>> 3429 | >>> (1, 2, 3) 3430 | >>> 3431 | >>> ('a', 'b') 3432 | ``` 3433 | Звездочка в определении функции означает, что переменная (параметр) args получит в виде кортежа все аргументы, переданные в функцию при ее вызове от текущей позиции и до конца. *args нужно указывать после всех аргументов: 3434 | ```python 3435 | def my_func(num, *args): 3436 | print(args) 3437 | print(num) 3438 | 3439 | 3440 | my_func(17, 'Python', 2, 'C#') 3441 | >>> ('Python', 2, 'C#') 3442 | >>> 17 3443 | ``` 3444 | Помеченный звездочкой параметр *args нормально переживает и отсутствие аргументов, в то время как позиционные параметры всегда обязательны. 3445 | 3446 | После *args можно передавать и другие аргументы, однако передать их можно только как keyword-only: 3447 | ```python 3448 | def string_multiplication(*args, times): 3449 | for i in args: 3450 | yield str(i) * times 3451 | 3452 | 3453 | print(*string_multiplication(1, 2, times=5)) 3454 | >>> 11111 22222 3455 | 3456 | ``` 3457 | ## Передача аргументов в форме списка и кортежа 3458 | (*args): 3459 | ```python 3460 | def my_sum(*args): 3461 | return sum(args) # args - это кортеж 3462 | 3463 | 3464 | print(my_sum(*[1, 2, 3, 4, 5])) # распаковка списка 3465 | print(my_sum(*(1, 2, 3))) # распаковка кортежа 3466 | >>> 15 3467 | >>> 6 3468 | 3469 | ``` 3470 | (**kwargs): 3471 | ```python 3472 | def my_func(**kwargs): 3473 | print(type(kwargs)) 3474 | print(kwargs) 3475 | 3476 | 3477 | info = {"name": "Timur", "age": "28", "job": "teacher"} 3478 | my_func(**info) 3479 | >>> 3480 | >>> {'name': 'Timur', 'age': '28', 'job': 'teacher'} 3481 | 3482 | ``` 3483 | ## Получение именованных аргументов в виде словаря 3484 | Позиционные аргументы можно получать в виде *args, причём произвольное их количество. Такая возможность существует и для именованных аргументов. Только именованные аргументы получаются в виде словаря, что позволяет сохранить имена аргументов в ключах. 3485 | ```python 3486 | def my_func(**kwargs): 3487 | print(type(kwargs)) 3488 | print(kwargs) 3489 | 3490 | 3491 | my_func(a=1, b=2) 3492 | my_func(name="Timur", job="Teacher") 3493 | >>> 3494 | >>> {'a': 1, 'b': 2} 3495 | >>> 3496 | >>> {'name': 'Timur', 'job': 'Teacher'} 3497 | 3498 | ``` 3499 | ## Keyword-only и positional-only аргументы 3500 | В Python 3 добавили возможность пометить именованные аргументы функции так, чтобы вызвать функцию можно было, только передав эти аргументы по именам. Такие аргументы называются keyword-only и их нельзя передать в функцию в виде позиционных. 3501 | ```python 3502 | def make_circle(x, y, radius, *, line_width=1, fill=True): 3503 | pass 3504 | 3505 | 3506 | make_circle(10, 20, 10, line_width=2, fill=False) 3507 | ``` 3508 | Здесь * выступает разделителем: отделяет обычные аргументы (их можно указывать по имени и позиционно) от строго именованных. Справа – строго именованные. 3509 | 3510 | Существуют и positional-only аргументы, слева от разделителя / - только позиционные аргументы: 3511 | ```python 3512 | def make_circle(x, y, radius, /, line_width, fill): 3513 | pass 3514 | 3515 | 3516 | make_circle(1, 1, 3, line_width=0.1, fill=False) 3517 | 3518 | ``` 3519 | Удобно комбинировать их: 3520 | ```python 3521 | def func(a, /, b, *, c): 3522 | pass 3523 | 3524 | 3525 | func(1, b=2, c=3) 3526 | func(1, 2, c=3) 3527 | 3528 | ``` 3529 | ## Функции как объекты 3530 | Встроенные функции или методы Python: 3531 | ```python 3532 | print(type(print)) 3533 | print(type(sum)) 3534 | print(type(abs)) 3535 | >>> 3536 | >>> 3537 | >>> 3538 | 3539 | ``` 3540 | Тип обычных функций: 3541 | ```python 3542 | def hello(): 3543 | print('Hello from function') 3544 | 3545 | 3546 | print(type(hello)) 3547 | >>> 3548 | 3549 | ``` 3550 | Мы можем назначить переменной функцию: 3551 | ```python 3552 | печать = print 3553 | печать("Hello World!") 3554 | >>> Hello World! 3555 | 3556 | ``` 3557 | Выполнение функции, введённой с клавиатуры: 3558 | ```python 3559 | def start(): 3560 | # тело функции start 3561 | pass 3562 | 3563 | 3564 | def stop(): 3565 | # тело функции stop 3566 | pass 3567 | 3568 | 3569 | def pause(): 3570 | # тело функции pause 3571 | pass 3572 | 3573 | 3574 | commands = {'start': start, 'stop': stop, 'pause': pause} # словарь соответствия команда → функция 3575 | command = input() # считываем название команды 3576 | commands[command]() # вызываем нужную функцию через словарь по ключу 3577 | 3578 | ``` 3579 | ## Функции в качестве аргументов других функций 3580 | ```python 3581 | def pick(f): 3582 | f() 3583 | 3584 | 3585 | def first(): 3586 | print("Первая функция") 3587 | 3588 | 3589 | def second(): 3590 | print("Вторая функция") 3591 | 3592 | 3593 | pick(first) 3594 | >>> Первая функция 3595 | 3596 | ``` 3597 | ## key в min(), max(), sort(), sorted() 3598 | Стандартно `min(), max(), sort(), sorted()` сравнивают сами элементы, однако можно указать key - ключ, по которому будут сравниваться аргументы. Важно, значением key должна быть функция, принимающая и возвращающая один аргумент. 3599 | Пример, сравнение по квадратам элементов: 3600 | ```python 3601 | def to_two(x): 3602 | return x**2 3603 | 3604 | 3605 | list = [-10, 0, 1] 3606 | list.sort(key=to_two) 3607 | print(list) 3608 | >>> [0, 1, -10] # так как [0, 1, 100] отсортирован по возрастанию (квадраты чисел) 3609 | ``` 3610 | Можно использовать и встроенные функции: 3611 | ```python 3612 | list = [-10, 0, 1] 3613 | list.sort(key=abs) 3614 | print(list) 3615 | >>> [0, 1, -10] # так как [0, 1, 10] отсортирован по возрастанию (модули чисел) 3616 | 3617 | ``` 3618 | ## Функции в качестве возвращаемых значений других функций (вложенные функции) 3619 | Можно использовать “вложенные” функции: 3620 | ```python 3621 | def main_function(a, b, c): 3622 | def function(x): 3623 | return a * b * c * x 3624 | 3625 | return function 3626 | 3627 | 3628 | print(main_function(1, 23, 12)(1)) 3629 | >>> 276 3630 | ``` 3631 | Пример использования: 3632 | ```python 3633 | def tracker(func_name): 3634 | def print_func_name(a): 3635 | print(func_name) 3636 | return a 3637 | 3638 | return print_func_name 3639 | 3640 | 3641 | print(max([1, 2, 3], key=tracker("max"))) 3642 | print(min([1, 2, 3], key=tracker("min"))) 3643 | ``` 3644 | (Сначала вызывается трекер с именем функции, а затем функция внутри, возвращающая само число.) 3645 | 3646 | Второй пример: 3647 | ```python 3648 | def func(x): 3649 | def inner(y): 3650 | return y 3651 | 3652 | return inner 3653 | 3654 | 3655 | first = func(12) # в переменной first лежит функция inner, так как func вернула функцию, а не вызвала. 3656 | print(first(33)) 3657 | >>> 33 3658 | 3659 | ``` 3660 | ## Функции высшего порядка 3661 | Функции, которые принимают или/и возвращают другие функции, называются функциями высшего порядка. 3662 | ```python 3663 | def high_order_function(func): # функция высшего порядка, так как принимает функцию 3664 | return func(3) 3665 | 3666 | 3667 | def double(x): # обычная функция = функция первого порядка 3668 | return 2*x 3669 | 3670 | 3671 | def add_one(x): # обычная функция = функция первого порядка 3672 | return x + 1 3673 | 3674 | ``` 3675 | ## map() 3676 | `map() `применяет функцию ко всем элементам последовательности: 3677 | ```python 3678 | def increase(num): 3679 | return num + 7 3680 | 3681 | 3682 | numbers = [1, 2, 3, 4, 5, 6] 3683 | new_numbers = map(increase, numbers) 3684 | 3685 | print(new_numbers) 3686 | >>> 3687 | ``` 3688 | Код выведет специальный объект, его можно итерировать, преобразовывать в список или кортеж, распаковывать при помощи *: 3689 | ```python 3690 | def increase(num): 3691 | return num + 7 3692 | 3693 | 3694 | numbers = [1, 2, 3, 4, 5, 6] 3695 | new_numbers = map(increase, numbers) 3696 | 3697 | for i in new_numbers: 3698 | print(i) 3699 | >>> 8 3700 | >>> 9 3701 | >>> 10 3702 | >>> 11 3703 | >>> 12 3704 | >>> 13 3705 | 3706 | ``` 3707 | Чтобы получить из итератора список, нужно воспользоваться функцией `list()`: 3708 | ```python 3709 | new_numbers = list(map(increase, numbers)) 3710 | 3711 | ``` 3712 | Функции `map()` можно передать несколько последовательностей. В этом случае в функцию обратного вызова func будут передаваться сразу несколько элементов, расположенных в последовательностях на одинаковых позициях: 3713 | ```python 3714 | def func(elem1, elem2, elem3): 3715 | return elem1 + elem2 + elem3 3716 | 3717 | 3718 | numbers1 = [1, 2, 3, 4, 5] 3719 | numbers2 = [10, 20, 30, 40, 50] 3720 | numbers3 = [100, 200, 300, 400, 500] 3721 | 3722 | new_numbers = list(map(func, numbers1, numbers2, numbers3)) 3723 | 3724 | print(new_numbers) 3725 | >>> [111, 222, 333, 444, 555] 3726 | 3727 | ``` 3728 | Важно! Если в последовательностях разное количество элементов, то последовательность с минимальным количеством элементов становится ограничителем: 3729 | ```python 3730 | def func(elem1, elem2, elem3): 3731 | return elem1 + elem2 + elem3 3732 | 3733 | 3734 | numbers1 = [1, 2, 3, 4] 3735 | numbers2 = [10, 20] 3736 | numbers3 = [100, 200, 300, 400, 500] 3737 | 3738 | new_numbers = list(map(func, numbers1, numbers2, numbers3)) 3739 | 3740 | print(new_numbers) 3741 | >>> [111, 222] 3742 | 3743 | ``` 3744 | ## filter() 3745 | `filter(): `в качестве параметра func указывается ссылка на функцию, которой будет передаваться текущий элемент последовательности. Внутри функции func необходимо вернуть значение `True` или `False`. Для примера, удалим все отрицательные значения из списка: 3746 | ```python 3747 | def func(elem): 3748 | return elem >= 0 3749 | 3750 | 3751 | numbers = [-1, 2, -3, 4, 0, -20, 10] 3752 | positive_numbers = list(filter(func, numbers)) 3753 | 3754 | print(positive_numbers) 3755 | >>> [2, 4, 0, 10] 3756 | ``` 3757 | Встроенной функции `filter()` можно в качестве первого параметра func передать значение `None`. В таком случае каждый элемент последовательности будет проверен на соответствие значению `True`. Если элемент в логическом контексте возвращает значение `False`, то он не будет добавлен в возвращаемый результат. 3758 | 3759 | `filter()` возвращает специальный объект, его можно итерировать, преобразовывать в список или кортеж, распаковывать при помощи *: 3760 | 3761 | Чтобы получить из итератора список, нужно воспользоваться функцией `list()`: 3762 | ```python 3763 | list(filter()) 3764 | 3765 | ``` 3766 | ## reduce() 3767 | `reduce(): `для использования функции `reduce()` необходимо подключить специальный модуль functools. 3768 | Пример: 3769 | ```python 3770 | from functools import reduce 3771 | 3772 | 3773 | def func(a, b): 3774 | return a + b 3775 | 3776 | 3777 | numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 3778 | total = reduce(func, numbers, 0) # в качестве начального значения 0 3779 | print(total) 3780 | >>> 55 3781 | ``` 3782 | Как работает функция: складывается 0 и 1, потом 0 + 1 складывается с 2 и т.д. 3783 | 3784 | ## Модуль operator 3785 | Чтобы не писать каждый раз функции, определяющие такие стандартные математические операции как сумма или произведение, можно использовать модуль operator. Неполный список функций из модуля operator выглядит так: 3786 | | Операция | Синтаксис | Функция | 3787 | |---|---|---| 3788 | | Addition | a + b | add(a, b) | 3789 | | Containment Test | obj in seq | contains(seq, obj) | 3790 | | Division | a / b | truediv(a, b) | 3791 | | Division | a // b | floordiv(a, b) | 3792 | | Exponentiation | a ** b | pow(a, b) | 3793 | | Modulo | a % b | mod(a, b) | 3794 | | Multiplication | a * b | mul(a, b) | 3795 | | Negation (Arithmetic) | -a | neg(a) | 3796 | | Subtraction | a - b | sub(a, b) | 3797 | | Ordering | a < b | lt(a, b) | 3798 | | Ordering | a <= b | le(a, b) | 3799 | | Equality | a == b | eq(a, b) | 3800 | | Difference | a != b | ne(a, b) | 3801 | | Ordering | a >= b | ge(a, b) | 3802 | | Ordering | a > b | gt(a, b) | 3803 | 3804 | Пример кода, который выводит сумму всех чисел от 0 до 9: 3805 | ```python 3806 | from operator import * 3807 | from functools import reduce 3808 | 3809 | print(reduce(add, range(10))) 3810 | >>> 45 3811 | 3812 | ``` 3813 | ## Анонимные функции (lambda): введение 3814 | Анонимные функции - функции с телом, но без имени. 3815 | Общий формат определения анонимной функции: `lambda список_параметров: выражение. `Параметры не нужно заключать в скобки. 3816 | Лямбда всегда будет возвращать выражение, написанное после “:”. 3817 | 3818 | ## Анонимные функции (lambda): основы, тернарный оператор 3819 | Лямбды удобно использовать как ключи в `min(), max(), sort(), sorted()`: 3820 | ```python 3821 | usernames = [ 3822 | "VulUyiD", 3823 | "YZGDxyurp", 3824 | "xjPaNUIX", 3825 | "OlKBzwein", 3826 | "InuXktD", 3827 | "xgfosAWaK", 3828 | "vMPNwVc", 3829 | "NJGPkmieKZ", 3830 | "whYrmcyNJD", 3831 | "zcQvPfe", 3832 | ] 3833 | 3834 | print(list(filter(lambda user: len(user) == 10, usernames))) 3835 | >>> ['NJGPkmieKZ', 'whYrmcyNJD'] 3836 | ``` 3837 | В коде выше `lambda user: len(user) == 10` возвращает `True` если длина имени пользователя равна десяти. 3838 | 3839 | В лямбдах можно использовать условия (их вид - `значение1 if условие else значение2`): 3840 | ```python 3841 | user = "bananchik2000" 3842 | print((lambda x: "Здравствуйте!" if len(x) > 5 else "Мы вас не знаем :(")(user)) 3843 | >>> Здравствуйте 3844 | ``` 3845 | Код выведет “Здравствуйте!”, так как длина строки user больше 5. 3846 | Важно! Лямбды не поддерживают `elif`. 3847 | 3848 | Лямбды как и обычные функции могут: 3849 | - позиционные аргументы 3850 | - именованные аргументы 3851 | - переменный список позиционных аргументов (*args) 3852 | - переменный список именованных аргументов (**kwargs) 3853 | - keyword-only аргументы (*) 3854 | 3855 | ```python 3856 | a = lambda num: num + 5 3857 | print(a(1)) 3858 | print(a(num=1)) 3859 | 3860 | 3861 | b = lambda *args: f"Аргументы: {args}" 3862 | print(b("Банан", "Лисичка")) 3863 | 3864 | c = lambda **kwargs: f"Аргументы: {kwargs}" 3865 | print(c(food="Банан", i_like="Лисичка")) 3866 | 3867 | d = lambda name, *, food: f"{name} любит {food}" 3868 | print(d("Никита", food="сыр")) 3869 | >>> 6 3870 | >>> 6 3871 | >>> Аргументы: ('Банан', 'Лисичка') 3872 | >>> Аргументы: {'food': 'Банан', 'i_like': 'Лисичка'} 3873 | >>> Никита любит сыр 3874 | 3875 | ``` 3876 | Тернарные условия можно использовать во многих местах, например, в генераторах списков: 3877 | ```python 3878 | print([a if a < 50 else a**2 for a in range(1, 101)]) 3879 | >>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409, 9604, 9801, 10000] 3880 | 3881 | ``` 3882 | Можно использовать несколько тернарных условий: 3883 | ```python 3884 | print([a if 10 % a == 0 else a**2 if 20 % a == 1 else a**3 for a in range(1, 101)]) 3885 | >>> [1, 2, 27, 64, 5, 216, 343, 512, 729, 10, 1331, 1728, 2197, 2744, 3375, 4096, 4913, 5832, 361, 8000, 9261, 10648, 12167, 13824, 15625, 17576, 19683, 21952, 24389, 27000, 29791, 32768, 35937, 39304, 42875, 46656, 50653, 54872, 59319, 64000, 68921, 74088, 79507, 85184, 91125, 97336, 103823, 110592, 117649, 125000, 132651, 140608, 148877, 157464, 166375, 175616, 185193, 195112, 205379, 216000, 226981, 238328, 250047, 262144, 274625, 287496, 300763, 314432, 328509, 343000, 357911, 373248, 389017, 405224, 421875, 438976, 456533, 474552, 493039, 512000, 531441, 551368, 571787, 592704, 614125, 636056, 658503, 681472, 704969, 729000, 753571, 778688, 804357, 830584, 857375, 884736, 912673, 941192, 970299, 1000000] 3886 | 3887 | ``` 3888 | ## all(), any() 3889 | Встроенная функция `all()` возвращает значение `True`, если все элементы переданной ей последовательности (итерируемого объекта) истинны (приводятся к значению `True`), или `False` в противном случае. 3890 | Встроенная функция `any()` возвращает значение `True`, если хотя бы один элемент переданной ей последовательности (итерируемого объекта) истинный (приводится к значению `True`), или `False` в противном случае. 3891 | 3892 | Сигнатура функций следующая: `all(iterable), any(iterable)`. В качестве iterable может выступать любой итерируемый объект: 3893 | - список 3894 | - кортеж 3895 | - строка 3896 | - множество 3897 | - словарь и т.д. 3898 | В Python все следующие значения приводятся к значению `False`: 3899 | - константы `None` и `False` 3900 | - нули всех числовых типов данных: `0, 0.0, 0j, Decimal(0), Fraction(0, 1)` 3901 | - пустые коллекции: `'', (), [], {}, set(), range(0)` 3902 | 3903 | При работе со словарями функции `all(), any()` проверяют на соответствие параметрам `True `ключи словаря, а не их значения. 3904 | 3905 | Обратите внимание: если переданный итерируемый объект пустой, то функция `all()` возвращает значение `True`: 3906 | ```python 3907 | print(all([])) # передаем пустой список 3908 | print(all(())) # передаем пустой кортеж 3909 | print(all('')) # передаем пустую строку 3910 | print(all([[], []])) # передаем список, содержащий пустые списки 3911 | >>> True 3912 | >>> True 3913 | >>> True 3914 | >>> False 3915 | ``` 3916 | Обратите внимание: если переданный объект пуст, то функция `any()` возвращает значение `False`: 3917 | ```python 3918 | print(any([])) # передаем пустой список 3919 | print(any(())) # передаем пустой кортеж 3920 | print(any('')) # передаем пустую строку 3921 | print(any([[], []])) # передаем список, содержащий пустые списки 3922 | >>> False 3923 | >>> False 3924 | >>> False 3925 | >>> False 3926 | 3927 | ``` 3928 | ## enumerate() 3929 | Встроенная функция `enumerate()` возвращает кортеж из индекса элемента и самого элемента переданной ей последовательности (итерируемого объекта). С помощью необязательного параметра `start` можно задать начальное значение индекса. По умолчанию значение параметра `start = 0`, то есть счет начинается с нуля. `enumerate() `возвращает не список, а специальный итерируемый объект. 3930 | ```python 3931 | colors = ['red', 'green', 'blue'] 3932 | 3933 | for pair in enumerate(colors): 3934 | print(pair) 3935 | >>> (0, 'red') 3936 | >>> (1, 'green') 3937 | >>> (2, 'blue') 3938 | ``` 3939 | С использованием `start`: 3940 | ```python 3941 | colors = ['red', 'green', 'blue'] 3942 | 3943 | for pair in enumerate(colors, 100): 3944 | print(pair) 3945 | >>> (100, 'red') 3946 | >>> (101, 'green') 3947 | >>> (102, 'blue') 3948 | 3949 | ``` 3950 | ## zip() 3951 | Встроенная функция `zip()` объединяет отдельные элементы из каждой переданной ей последовательности (итерируемого объекта) в кортежи. `zip() `возвращает не список, а специальный итерируемый объект: 3952 | ```python 3953 | numbers = [1, 2, 3] 3954 | words = ['one', 'two', 'three'] 3955 | 3956 | for pair in zip(numbers, words): 3957 | print(pair) 3958 | >>> (1, 'one') 3959 | >>> (2, 'two') 3960 | >>> (3, 'three') 3961 | 3962 | ``` 3963 | ## Рекурсия 3964 | Рекурсивная функция – функция, вызывающая себя же. 3965 | Пример: 3966 | ```python 3967 | def print_every_element(element): 3968 | if isinstance(element, list): 3969 | for i in element: 3970 | print_every_element(i) 3971 | else: 3972 | print(element, end=" ") 3973 | 3974 | 3975 | print_every_element([[[[[[1]], 2, 3]], 4], 5, [6, 7]]) 3976 | >>> 1 2 3 4 5 6 7 3977 | 3978 | ``` 3979 | ## Декораторы 3980 | ```python 3981 | import time 3982 | 3983 | 3984 | def how_much_time(func): 3985 | def wrapper(*args, **kwargs): # 4. выполняется wrapper 3986 | start = time.time() 3987 | func(*args, **kwargs) 3988 | return time.time() - start 3989 | 3990 | return wrapper # 3. возвращает функцию wrapper 3991 | 3992 | 3993 | @how_much_time # 2. декоратор принимает на вход функцию 3994 | def from_a_to_b(a, b): 3995 | for i in range(a, b + 1): 3996 | print(i) 3997 | 3998 | 3999 | print(from_a_to_b(1, 100)) # 1. вызываем функцию 4000 | 4001 | ``` 4002 | Также можно передавать декораторам свои аргументы: 4003 | ```python 4004 | import time 4005 | 4006 | 4007 | def how_much_time(name): 4008 | def timer(func): 4009 | def wrapper(*args, **kwargs): 4010 | print(f"Выполняется функция {name}") # 5. выводит имя функции 4011 | start = time.time() 4012 | func(*args, **kwargs) 4013 | return time.time() - start 4014 | 4015 | return wrapper # 4. выполняется wrapper 4016 | 4017 | return timer # 3. возвращает функцию timer 4018 | 4019 | 4020 | @how_much_time("from_a_to_b") # 2. декоратор принимает на вход название функции 4021 | def from_a_to_b(a, b): 4022 | for i in range(a, b + 1): 4023 | print(i) 4024 | 4025 | 4026 | print(from_a_to_b(1, 100)) # 1. вызываем функцию 4027 | 4028 | ``` 4029 | # Работа с файлами 4030 | ## Введение 4031 | Существует 2 типа файлов: текстовые и двоичные (бинарные). Текстовый файл содержит данные, которые были закодированы в виде текста при помощи такой схемы кодирования, как ASCII или Юникод. Разделение файлов на текстовые и бинарные искусственное, так как любой файл бинарен. 4032 | 4033 | Большинство языков программирования обеспечивает два способа получения доступа к данным в файле: 4034 | - последовательный, 4035 | - прямой или произвольный. 4036 | Последовательный выдает порции информации одну за другой. При работе с таким файлом не получится перескочить сразу к нужной части данных, сначала придется прочитать все предыдущие. 4037 | При работе с файлом с прямым или произвольным доступом можно перескочить непосредственно к любой порции данных, не читая предыдущие. 4038 | 4039 | Путь файла (или путь к файлу) — последовательное указание имен папок, через которые надо пройти, чтобы добраться до объекта. 4040 | Пути к файлу бывают двух типов: абсолютные и относительные. 4041 | Абсолютный путь – полный путь к файлу, показывающий точное место его расположения. Он всегда один и тот же, пока файл не перемещен. 4042 | Относительный путь – привязан к какой-либо "отправной точке" и указан по отношению к ней. 4043 | 4044 | ## languages.txt 4045 | В последующих примерах будет использоваться файл languages.txt. Он содержит: 4046 | ```python 4047 | Python 4048 | Java 4049 | Javascript 4050 | C# 4051 | C 4052 | C++ 4053 | PHP 4054 | R 4055 | Objective-C 4056 | 4057 | ``` 4058 | ## Открытие файлов 4059 | Для открытия файлов в Python существует функция `open()`. Она создает файловый объект и связывает его с файлом на диске. Общий формат применения функции `open()`: 4060 | ```python 4061 | файловая_переменная = open(имя_файла, режим_доступа) 4062 | ``` 4063 | Режимы доступа: 4064 | | Стр. литерал | Режим | Описание | 4065 | |---|---|---| 4066 | | 'r' | Read (чтение) | Открыть файл только для чтения. Такой файл не может быть изменен. | 4067 | | 'w' | Write (запись) | Открыть файл для записи. Если файл уже существует, стереть его содержимое.
Если файл не существует, он будет создан. | 4068 | | 'a' | Append (добавление) | Открыть файл для записи. Данные будут добавлены в конец файла. Если файл не существует, он будет создан. | 4069 | | 'r+' | Read + Write | Открыть файл для чтения и записи. В этом режиме происходит частичная перезапись содержимого файла. | 4070 | | 'x' | Create (создание) | Создать новый файл. Если файл существует, произойдет ошибка. | 4071 | 4072 | Пример: 4073 | ```python 4074 | student_file = open('students.txt', 'w') # открываем файл в режиме записи 4075 | student_file = open('students.txt') # открываем файл в режиме чтения (по умолчанию режиме записи 'r') 4076 | 4077 | ``` 4078 | ## Указание места расположения файла, сырые строки 4079 | `Для указания абсолютного пути нужно использовать \\, вместо \:` 4080 | ```python 4081 | test_file = open('C:\\Users\\temp\\test.txt', 'w') 4082 | ``` 4083 | Вместо этого можно использовать сырые строки, для этого перед строкой нужно указать префикс r: 4084 | ```python 4085 | test_file = open(r'C:\Users\temp\test.txt', 'w') 4086 | 4087 | ``` 4088 | ## Кодировка 4089 | При работе с текстом на русском языке нужно указать кодировку, для этого служит параметр `encoding`: 4090 | ```python 4091 | file = open('info.txt', 'r', encoding='utf-8') 4092 | ``` 4093 | Чтобы получить кодировку открытого файла, используют файловое свойство `encoding`: 4094 | ```python 4095 | file1 = open('students.txt', 'w') 4096 | file2 = open('customers.txt', 'w', encoding='utf-8') 4097 | 4098 | print(file1.encoding) 4099 | print(file2.encoding) 4100 | 4101 | file1.close() 4102 | file2.close() 4103 | >>> cp1252 4104 | >>> utf-8 4105 | 4106 | ``` 4107 | ## Закрытие файлов 4108 | После окончания работы с файлом его необходимо закрыть. 4109 | 4110 | Для закрытия файла используется файловый метод `close()`: 4111 | ```python 4112 | file = open('info.txt', 'r') # открываем файл с именем info.txt для чтения 4113 | 4114 | # работаем с содержимым файла info.txt 4115 | 4116 | file.close() # закрываем файл после окончания работы 4117 | 4118 | ``` 4119 | Чтобы проверить открыт файл или закрыт можно использовать файловое свойство (атрибут) `closed`: 4120 | ```python 4121 | file1 = open('students.txt', 'w') 4122 | file2 = open('customers.txt', 'w') 4123 | 4124 | file1.close() 4125 | 4126 | print(file1.closed) 4127 | print(file2.closed) 4128 | 4129 | file2.close() 4130 | >>> True 4131 | >>> False 4132 | 4133 | ``` 4134 | ## read(), readline(), readlines() 4135 | Файловый метод `read()` считывает все содержимое из файла и возвращает строку, которая может содержать символы перехода на новую строку '\n'. 4136 | Также методу `read()` можно передать целочисленный аргумент – столько символов считает метод. 4137 | ```python 4138 | file = open('languages.txt', 'r', encoding='utf-8') 4139 | print(file.read()) 4140 | file.close() 4141 | >>> Python\nJava\nJavascript\nC#\nC\nC++\nPHP\nR\nObjective-C 4142 | 4143 | ``` 4144 | Файловый метод `readline()` считывает одну строку из файла (до символа конца строки '\n'), при этом возвращается считанная строка вместе с символом '\n'. Если считать строку не удалось – достигнут конец файла и больше строк в нем нет, возвращается пустая строка. 4145 | ```python 4146 | file = open('languages.txt', 'r', encoding='utf-8') 4147 | print(file.readline()) 4148 | file.close() 4149 | >>> Python\n 4150 | ``` 4151 | Для удаления '\n' можно использовать `rstrip():` 4152 | ```python 4153 | print("Python\n".rstrip()) 4154 | >>> Python 4155 | 4156 | ``` 4157 | Файловый метод `readlines()` считывает все строки из файла и возвращает список из всех считанных строк (одна строка — один элемент списка). При этом, каждая строка в списке заканчивается символом переноса строки '\n'. 4158 | ```python 4159 | file = open('languages.txt', 'r', encoding='utf-8') 4160 | print(file.readlines()) 4161 | file.close() 4162 | >>> ['Python\n', 'Java\n', 'Javascript\n', 'C#\n', 'C\n', 'C++\n', 'PHP\n', 'R\n', 'Objective-C'] 4163 | 4164 | ``` 4165 | ## Бинарные файлы 4166 | Чтобы открыть бинарный файл нужно использовать литерал b: 4167 | ```python 4168 | file = open('file.dat', 'rb') # открываем бинарный файл в режиме чтения 4169 | file = open('file.dat', 'rt') # открываем текстовый файл в режиме чтения 4170 | file = open('file.dat', 'r') # открываем текстовый файл в режиме чтения 4171 | 4172 | ``` 4173 | ## Свойства файла 4174 | | Атрибут (свойство) | Описание | 4175 | |---|---| 4176 | | file.closed | возвращает истину (True), если файл закрыт, иначе возвращает ложь (False) | 4177 | | file.mode | возвращает режим доступа, с помощью которого был открыт файл | 4178 | | file.name | возвращает имя файла | 4179 | 4180 | ## Позиция в файле (курсор) 4181 | Вызов методов `read()`, `readlines()`, `readline()` перемещает текущую позицию туда, где завершилось чтение. Для методов `read()` и `readlines()` это конец файла, для метода `readline()` – следующая строка после прочитанной. 4182 | Для повторного чтения данных из файла, можно: 4183 | - переоткрыть файл, тогда курсор снова попадёт в начало 4184 | - переместить курсор с помощью файлового метода seek() 4185 | 4186 | ## seek(), tell() 4187 | Файловый метод `seek()` задаёт позицию курсора в байтах от начала файла. Чтобы перевести курсор в самое начало файла необходимо вызвать метод `seek()`, передав ему в качестве аргумента значение 0: 4188 | ```python 4189 | file = open('languages.txt', 'r', encoding='utf-8') 4190 | line1 = file.readline() 4191 | file.seek(0) # переводим курсор в самое начало 4192 | line2 = file.readline() 4193 | 4194 | print(line1, line2) 4195 | 4196 | file.close() 4197 | >>> Python 4198 | >>> Python 4199 | ``` 4200 | Будьте аккуратны с символами, использующими более 1 байта (кириллица в кодировке utf-8), обращение к "промежуточному" байту может вызвать ошибку. 4201 | 4202 | Метод `tell()` получает текущую позицию курсора: 4203 | ```python 4204 | file = open('languages.txt', 'r', encoding='utf-8') 4205 | print(file.tell()) 4206 | line1 = file.readline() 4207 | print(file.tell()) 4208 | 4209 | file.close() 4210 | >>> 0 4211 | >>> 8 4212 | 4213 | ``` 4214 | ## Менеджер контекста 4215 | Закрытие файлов вручную, а также отдача закрытия на откуп среде исполнения, обладают существенным недостатком: если между открытием файла и его закрытием произойдёт ошибка, в лучшем случае файл окажется открыт слишком долго, а в худшем случае часть данных не сохранится. 4216 | Менеджер контекста автоматически закрывает файл после выхода из него. Общий вид менеджера контекста: 4217 | ```python 4218 | with object as name: 4219 | # Здесь нам доступен ресурс name. 4220 | # Это тело with-блока. 4221 | # А здесь ресурс name уже освобождён, даже если в теле with-блока произошла ошибка. 4222 | ``` 4223 | Пример использования: 4224 | ```python 4225 | with open('languages.txt', 'r', encoding='utf-8') as file: 4226 | for line in file: 4227 | print(line) 4228 | # автоматическое закрытие файла 4229 | print('Файл закрыт') 4230 | 4231 | ``` 4232 | С помощью менеджера контекста можно работать с несколькими файлами: 4233 | ```python 4234 | with open('input.txt', 'r') as input_file, open('output.txt', 'w') as output_file: 4235 | # обработка файлов 4236 | 4237 | ``` 4238 | ## write(), writelines(), запись в файл при помощи print() 4239 | У нас есть файл myfile.txt, он содержит: 4240 | ```python 4241 | First line of the file. 4242 | Second line of the file. 4243 | Third line of the file. 4244 | 4245 | ``` 4246 | Чтобы использовать методы `write(), writelines()` файл должен быть открыт в режиме записи. 4247 | - При открытии файла в режиме записи (“w”): 4248 | ```python 4249 | with open('myfile.txt', 'w', encoding='utf-8') as file: 4250 | file.write('Python and beegeek forever\n') 4251 | file.write('We love stepik <3') 4252 | ``` 4253 | Файл будет содержать: 4254 | ```python 4255 | Python and beegeek forever 4256 | We love stepik <3 4257 | ``` 4258 | - При открытии файла в режиме добавления (“a”): 4259 | ```python 4260 | with open('myfile.txt', 'a', encoding='utf-8') as file: 4261 | file.write('Python and beegeek forever\n') 4262 | file.write('We love stepik <3') 4263 | ``` 4264 | Файл будет содержать: 4265 | ```python 4266 | First line of the file. 4267 | Second line of the file. 4268 | Third line of the file.Python and beegeek forever 4269 | We love stepik <3 4270 | ``` 4271 | - При открытии файла в режиме чтения + записи (частичной перезаписи) (“r+”): 4272 | ```python 4273 | with open('myfile.txt', 'r+', encoding='utf-8') as file: 4274 | file.write('Python and beegeek forever\n') 4275 | file.write('We love stepik.') 4276 | ``` 4277 | Файл будет содержать: 4278 | ```python 4279 | Python and beegeek forever 4280 | We love stepik. file. 4281 | Third line of the file. 4282 | 4283 | ``` 4284 | Метод `writelines()` записывает все элементы итерируемого объекта в файл: 4285 | ```python 4286 | philosophers = ['Джoн Локк\n', 'Дэвид Хьюм\n', 'Эдмyнд Берк\n'] 4287 | 4288 | with open('philosophers.txt', 'w', encoding='utf-8') as file: 4289 | file.writelines(philosophers) 4290 | ``` 4291 | Чтобы каждый элемент был на новой строке, нужно добавлять “\n” в конце каждого элемента. 4292 | 4293 | Для записи данных в файл можно также использовать встроенную функцию `print()`: 4294 | ```python 4295 | philosophers = ["Джoн Локк", "Дэвид Хьюм", "Эдмyнд Берк"] 4296 | 4297 | with open("philosophers.txt", "w", encoding="utf-8") as output: 4298 | for i in philosophers: 4299 | print(i, file=output) 4300 | ``` 4301 | `print()` сама добавит переходы на новые строки. 4302 | 4303 | # Интересные штуки 4304 | ## Числовая угадайка 4305 | ```python 4306 | import random 4307 | 4308 | while True: 4309 | counter = 0 4310 | to = int(input("Укажите число, до которого компьютер будет выбирать случайное: ")) 4311 | g = random.randint(1, to) 4312 | print("Добро пожаловать в числовую угадайку!") 4313 | print(f"Введите число от 1 до {to}") 4314 | 4315 | while True: 4316 | n = int(input()) 4317 | if n < g: 4318 | print("Ваше число меньше загаданного, попробуйте еще разок") 4319 | counter += 1 4320 | 4321 | elif n > g: 4322 | print("Ваше число больше загаданного, попробуйте еще разок") 4323 | counter += 1 4324 | 4325 | else: 4326 | counter += 1 4327 | print(f"Вы угадали число за {counter} попыток, поздравляем!") 4328 | break 4329 | 4330 | if ( 4331 | input( 4332 | "Спасибо, что играли в числовую угадайку. Хотите сыграть еще раз? (да/нет): " 4333 | ) 4334 | == "нет" 4335 | ): 4336 | break 4337 | 4338 | ``` 4339 | ## Магический шар 8 4340 | ```python 4341 | import random 4342 | 4343 | answers = [ 4344 | "Бесспорно", 4345 | "Мне кажется - да", 4346 | "Пока неясно, попробуй снова", 4347 | "Даже не думай", 4348 | "Предрешено", 4349 | "Вероятнее всего", 4350 | "Спроси позже", 4351 | "Мой ответ - нет", 4352 | "Никаких сомнений", 4353 | "Хорошие перспективы", 4354 | "Лучше не рассказывать", 4355 | "По моим данным - нет", 4356 | "Можешь быть уверен в этом", 4357 | "Да", 4358 | "Сконцентрируйся и спроси опять", 4359 | "Весьма сомнительно", 4360 | ] 4361 | 4362 | print("Привет Мир, я магический шар, и я знаю ответ на любой твой вопрос.") 4363 | name = input("Как тебя зовут? ") 4364 | print(f"Привет, {name}") 4365 | while True: 4366 | input("Напиши свой вопрос: ") 4367 | print(random.choice(answers)) 4368 | if input("Хочешь задать ещё один вопрос? (да/нет): ") == "нет": 4369 | break 4370 | 4371 | ``` 4372 | ## Генератор безопасных паролей 4373 | ```python 4374 | import random 4375 | 4376 | 4377 | digits = "0123456789" 4378 | lowercase_letters = "abcdefghijklmnopqrstuvwxyz" 4379 | uppercase_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 4380 | punctuation = "!#$%&*+-=?@^_" 4381 | 4382 | chars = "" 4383 | 4384 | count = int(input("Введите количество паролей: ")) 4385 | lenght = int(input("Введите длину одного пароля: ")) 4386 | contain_digits = input("Включать цифры? ") 4387 | contain_upper = input("Включать прописные буквы? ") 4388 | contain_lower = input("Включать строчные буквы? ") 4389 | contain_strange = input("Включать символы !#$%&*+-=?@^_? ") 4390 | stupid = input("Исключать неоднозначные символы il1Lo0O? ") 4391 | 4392 | if contain_digits == "да": 4393 | chars += digits 4394 | if contain_upper == "да": 4395 | chars += uppercase_letters 4396 | if contain_lower == "да": 4397 | chars += lowercase_letters 4398 | if contain_strange == "да": 4399 | chars += punctuation 4400 | if stupid == "да": 4401 | chars = "".join([i for i in chars if not i in "il1Lo0O"]) 4402 | 4403 | for i in range(count): 4404 | print("".join(random.sample(chars, lenght))) 4405 | 4406 | ``` 4407 | ## Калькулятор систем счисления (bin(), oct(), hex()) 4408 | ```python 4409 | a = int(input("Введите число в десятичной системе счисления: ")) 4410 | print(f"Число в двоичной системе: {bin(a)[2:]}") 4411 | print(f"Число в восьмеричной системе: {oct(a)[2:]}") 4412 | print(f"Число в шестнадцатеричной системе: {hex(a)[2:].upper()}") 4413 | 4414 | ``` 4415 | ## Угадайка слов 4416 | ```python 4417 | import random, os 4418 | 4419 | word_list = [ 4420 | "год", 4421 | "человек", 4422 | "время", 4423 | "дело", 4424 | "жизнь", 4425 | "день", 4426 | "рука", 4427 | "раз", 4428 | "работа", 4429 | "слово", 4430 | "место", 4431 | "лицо", 4432 | "друг", 4433 | "глаз", 4434 | "вопрос", 4435 | "дом", 4436 | "сторона", 4437 | "страна", 4438 | "мир", 4439 | "случай", 4440 | "голова", 4441 | "ребенок", 4442 | "сила", 4443 | "конец", 4444 | "вид", 4445 | "система", 4446 | "часть", 4447 | "город", 4448 | "отношение", 4449 | "женщина", 4450 | "деньги", 4451 | "земля", 4452 | "машина", 4453 | "вода", 4454 | "отец", 4455 | "проблема", 4456 | "час", 4457 | "право", 4458 | "нога", 4459 | "решение", 4460 | "дверь", 4461 | "образ", 4462 | "история", 4463 | "власть", 4464 | "закон", 4465 | "война", 4466 | "бог", 4467 | "голос", 4468 | "тысяча", 4469 | "книга", 4470 | "возможность", 4471 | "результат", 4472 | "ночь", 4473 | "стол", 4474 | "имя", 4475 | "область", 4476 | "статья", 4477 | "число", 4478 | "компания", 4479 | "народ", 4480 | "жена", 4481 | "группа", 4482 | "развитие", 4483 | "процесс", 4484 | "суд", 4485 | "условие", 4486 | "средство", 4487 | "начало", 4488 | "свет", 4489 | "пора", 4490 | "путь", 4491 | "душа", 4492 | "уровень", 4493 | "форма", 4494 | "связь", 4495 | "минута", 4496 | "улица", 4497 | "вечер", 4498 | "качество", 4499 | "мысль", 4500 | "дорога", 4501 | "мать", 4502 | "действие", 4503 | "месяц", 4504 | "государство", 4505 | "язык", 4506 | "любовь", 4507 | "взгляд", 4508 | "мама", 4509 | "век", 4510 | "школа", 4511 | "цель", 4512 | "общество", 4513 | "деятельность", 4514 | "организация", 4515 | "президент", 4516 | "комната", 4517 | "порядок", 4518 | "момент", 4519 | "театр", 4520 | ] 4521 | 4522 | 4523 | def get_word(): 4524 | return random.choice(word_list).upper() 4525 | 4526 | 4527 | # функция получения текущего состояния 4528 | def display_hangman(tries): 4529 | stages = [ # финальное состояние: голова, торс, обе руки, обе ноги 4530 | """ 4531 | -------- 4532 | | | 4533 | | O 4534 | | \\|/ 4535 | | | 4536 | | / \\ 4537 | - 4538 | """, 4539 | # голова, торс, обе руки, одна нога 4540 | """ 4541 | -------- 4542 | | | 4543 | | O 4544 | | \\|/ 4545 | | | 4546 | | / 4547 | - 4548 | """, 4549 | # голова, торс, обе руки 4550 | """ 4551 | -------- 4552 | | | 4553 | | O 4554 | | \\|/ 4555 | | | 4556 | | 4557 | - 4558 | """, 4559 | # голова, торс и одна рука 4560 | """ 4561 | -------- 4562 | | | 4563 | | O 4564 | | \\| 4565 | | | 4566 | | 4567 | - 4568 | """, 4569 | # голова и торс 4570 | """ 4571 | -------- 4572 | | | 4573 | | O 4574 | | | 4575 | | | 4576 | | 4577 | - 4578 | """, 4579 | # голова 4580 | """ 4581 | -------- 4582 | | | 4583 | | O 4584 | | 4585 | | 4586 | | 4587 | - 4588 | """, 4589 | # начальное состояние 4590 | """ 4591 | -------- 4592 | | | 4593 | | 4594 | | 4595 | | 4596 | | 4597 | - 4598 | """, 4599 | ] 4600 | os.system("cls") 4601 | return stages[tries] 4602 | 4603 | 4604 | def play(word): 4605 | word_completion = "_" * len( 4606 | word 4607 | ) # строка, содержащая символы _ на каждую букву задуманного слова 4608 | guessed_letters = [] # список уже названных букв 4609 | tries = 6 4610 | 4611 | while True: 4612 | print(display_hangman(tries)) 4613 | print(word_completion) 4614 | 4615 | symbol = input("Введите букву русского алфавита: ").upper() 4616 | 4617 | if symbol in guessed_letters: 4618 | while True: 4619 | symbol = input("Вы уже открыли эту букву, введите другую: ").upper() 4620 | if symbol not in guessed_letters: 4621 | break 4622 | 4623 | if symbol not in "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ" or len(symbol) != 1: 4624 | while True: 4625 | symbol = input("Введите букву русского алфавита: ").upper() 4626 | if symbol in "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ" and len(symbol) == 1: 4627 | break 4628 | 4629 | word_completion_before = word_completion 4630 | 4631 | for i in range(len(word)): 4632 | if word[i] == symbol: 4633 | word_completion = ( 4634 | word_completion[:i] + symbol + word_completion[i + 1 :] 4635 | ) 4636 | guessed_letters += symbol 4637 | 4638 | if word_completion_before == word_completion: 4639 | tries -= 1 4640 | 4641 | if tries == 0: 4642 | print(display_hangman(0)) 4643 | print(f"К сожалению, вы проиграли... Слово: {word}") 4644 | input("Нажмите Enter для повторной игры") 4645 | break 4646 | 4647 | if "_" not in word_completion: 4648 | print(f"Поздравляем! Вы угадали слово {word_completion}") 4649 | input("Нажмите Enter для повторной игры") 4650 | break 4651 | 4652 | 4653 | while True: 4654 | play(get_word()) 4655 | 4656 | ``` 4657 | # Не вошедшее в конспект 4658 | ## Исключения (try-except-else-finally) 4659 | ```python 4660 | def division(x, y): 4661 | try: 4662 | x / y 4663 | except ZeroDivisionError: 4664 | print("ERROR: Попытка деление на нуль") 4665 | else: 4666 | print("INFO: Операция прошла успешно") 4667 | finally: 4668 | print("INFO: Работа функции завершена") 4669 | 4670 | 4671 | division(1, 0) 4672 | division(4, 2) 4673 | >>> ERROR: Попытка деление на нуль 4674 | >>> INFO: Работа функции завершена 4675 | >>> INFO: Операция прошла успешно 4676 | >>> INFO: Работа функции завершена 4677 | ``` 4678 | `finally` будет выполнен в любом случае, даже если функция вернула значение! 4679 | ```python 4680 | def division(x, y): 4681 | try: 4682 | return x / y 4683 | except ZeroDivisionError: 4684 | return "ERROR: Попытка деление на нуль" 4685 | finally: 4686 | print("INFO: Работа функции завершена") 4687 | 4688 | 4689 | division(1, 0) 4690 | division(4, 2) 4691 | >>> INFO: Работа функции завершена 4692 | >>> INFO: Работа функции завершена 4693 | 4694 | ``` 4695 | ## Итераторы и генераторы 4696 | Плюсы итераторов и генераторов в их малом размере, так как они выдают по одному элементу и удаляют старые. 4697 | Существует конструкция `yield`, она возвращает значение несколько раз, образуя генератор: 4698 | ```python 4699 | def generator(a, b): 4700 | for i in range(a, b + 1): 4701 | yield i 4702 | 4703 | 4704 | my_generator = generator(1, 10) 4705 | for j in my_generator: 4706 | print(j) 4707 | >>> 1 4708 | >>> 2 4709 | >>> 3 4710 | >>> 4 4711 | >>> 5 4712 | >>> 6 4713 | >>> 7 4714 | >>> 8 4715 | >>> 9 4716 | >>> 10 4717 | 4718 | ``` 4719 | Существуют и генераторные выражения: 4720 | ```python 4721 | generator = ("*" for _ in range(5)) 4722 | 4723 | for j in generator: 4724 | print(j) 4725 | >>> * 4726 | >>> * 4727 | >>> * 4728 | >>> * 4729 | >>> * 4730 | 4731 | ``` 4732 | Итераторы же можно создать из любого итерируемого объекта: 4733 | ```python 4734 | iterator = iter([1, 3, 5, 6, 10]) 4735 | 4736 | for i in iterator: 4737 | print(i) 4738 | >>> 1 4739 | >>> 3 4740 | >>> 5 4741 | >>> 6 4742 | >>> 10 4743 | 4744 | ``` 4745 | Функция `next()` берёт итератор (или генератор) и выдаёт следующий элемент из него. Второй аргумент возвращается, если достигнут последний элемент. 4746 | ```python 4747 | iterator = iter([1, 3, 5, 6, 10]) 4748 | 4749 | for i in iterator: 4750 | print(next(iterator, "STOP")) 4751 | >>> 3 4752 | >>> 6 4753 | >>> STOP 4754 | 4755 | ``` 4756 | Если был достигнут конец итератора (генератора), но была использована функция `next()`, она вернёт исключение `StopIteration`. 4757 | 4758 | Ограничения итераторов и генераторов: 4759 | - Нельзя получить длину генераторного выражения с помощью встроенной функции `len()`. 4760 | - Нельзя распечатать элементы генераторного выражения с помощью функции `print()`, без 4761 | предварительной распаковки. 4762 | - Генераторные выражения не поддерживают получение элемента по индексу. 4763 | - К генераторному выражению нельзя применить обычные операции среза. 4764 | - После использования генераторного выражения, оно остается пустым. 4765 | 4766 | # Малоизвестные (или не мало) функции 4767 | ## Спецификаторы 4768 | ```python 4769 | "{:<10}".format("cat") # 'cat ' — влево 4770 | "{:>10}".format("cat") # ' cat' — вправо 4771 | "{:^10}".format("cat") # ' cat ' — по центру 4772 | "{:_<10}".format("cat") # 'cat_______' — влево с символом _ 4773 | "{:.>10}".format("cat") # '.......cat' — вправо с символом . 4774 | "{:*^10}".format("cat") # '**cat*****' — по центру с символом * 4775 | 4776 | "{:+}".format(42) # '+42' — всегда с знаком 4777 | "{:-}".format(42) # '42' — только минус 4778 | "{: }".format(42) # ' 42' — пробел вместо плюса 4779 | "{:+}".format(-42) # '-42' 4780 | "{: }".format(-42) # '-42' 4781 | 4782 | "{:#b}".format(10) # '0b1010' — двоичное с префиксом 4783 | "{:#o}".format(10) # '0o12' — восьмеричное с префиксом 4784 | "{:#x}".format(255) # '0xff' — шестнадцатеричное с префиксом 4785 | "{:#X}".format(255) # '0XFF' 4786 | 4787 | "{:05}".format(42) # '00042' — ширина 5, ведущие нули 4788 | "{:0=+8}".format(-42) # '-0000042' — знак отдельно, затем нули 4789 | "{:0>8}".format(42) # '00000042' — выравнивание вправо с нулями 4790 | 4791 | "{:10}".format("dog") # 'dog ' — минимум 10 символов 4792 | "{:>6}".format(123) # ' 123' 4793 | "{:06}".format(123) # '000123' 4794 | 4795 | "{:,}".format(1234567) # '1,234,567' 4796 | "{:_}".format(1234567) # '1_234_567' 4797 | "{:,.2f}".format(1234567.89) # '1,234,567.89' 4798 | 4799 | "{:.2f}".format(3.14159) # '3.14' — 2 знака после точки 4800 | "{:.3}".format(3.14159) # '3.14' — всего 3 значащих символа 4801 | "{:.1e}".format(1234.5) # '1.2e+03' 4802 | 4803 | "{:d}".format(42) # '42' — целое число 4804 | "{:b}".format(10) # '1010' — двоичное 4805 | "{:o}".format(10) # '12' — восьмеричное 4806 | "{:x}".format(255) # 'ff' — шестнадцатеричное (нижний регистр) 4807 | "{:X}".format(255) # 'FF' — шестнадцатеричное (верхний регистр' 4808 | "{:n}".format(1000000) # '1000000' — как d, но с локалью (влияние зависит от настроек) 4809 | 4810 | "{:f}".format(3.14) # '3.140000' 4811 | "{:.2f}".format(3.14) # '3.14' 4812 | "{:e}".format(1000) # '1.000000e+03' 4813 | "{:E}".format(1000) # '1.000000E+03' 4814 | "{:g}".format(0.0001234) # '0.0001234' — автоматический выбор между f и e 4815 | "{:.2%}".format(0.1234) # '12.34%' — значение * 100 и добавляется % 4816 | 4817 | ``` 4818 | Данные спецификаторы можно использовать в методе `format()`, в функции `format()` и в f-строках. 4819 | 4820 | ## Спецсимволы и экранирование 4821 | Следующие символы можно использовать в строках: 4822 | | Обозначение | Описание | 4823 | |---|---| 4824 | | \n | Перевод строки | 4825 | | \\ | Символ обратного слеша | 4826 | | \’ | Символ апострофа | 4827 | | \" | Символ двойной кавычки | 4828 | | \a | Звуковой сигнал | 4829 | | \b | Эмуляция клавиши BackSpace | 4830 | | \f | Перевод формата | 4831 | | \r | Возврат каретки | 4832 | | \t | Горизонтальная табуляция (размером в 4 пробела) | 4833 | | \v | Вертикальная табуляция | 4834 | | \0 | Символ Null (не признак конца строки) | 4835 | | \xhh | Символ с шестнадцатиричным кодом hh | 4836 | | \ooo | Символ с восьмиричным кодом ooo | 4837 | | \N{id} | Идентификатор из кодовой таблицы Unicode | 4838 | | \uhhhh | 16-битный символ Unicode в шестнадцатиричной форме | 4839 | | \Uhhhhhhhh | 32-битный символ Unicode в шестнадцатиричной форме | 4840 | | \другое | Не является экранированной последовательностью | 4841 | 4842 | ## Неявная конкатенация 4843 | Можно использовать неявную конкатенацию строк: 4844 | ```python 4845 | def say(message): 4846 | print(message) 4847 | 4848 | 4849 | data = ["Вот " "это " "да"] 4850 | print(data) 4851 | 4852 | data = "Вот " "это " "да" 4853 | print(data) 4854 | 4855 | say("Вот " "это " "да") 4856 | 4857 | >>> ['Вот это да'] 4858 | >>> Вот это да 4859 | >>> Вот это да 4860 | 4861 | ``` 4862 | ## Моржовый оператор 4863 | Можно использовать моржовый оператор, который присваивает и возвращает присвоенное значение: 4864 | ```python 4865 | print(a := 5) 4866 | print(a) 4867 | >>> 5 4868 | >>> 5 4869 | 4870 | ``` 4871 | ## Присвоение цепочкой 4872 | Можно присваивать нескольким переменным одно значение: 4873 | ```python 4874 | a = b = c = 1 4875 | print(a, b, c) 4876 | >>> 1 1 1 4877 | ``` 4878 | При чём они не будут ссылаться друг на друга, при изменении `c`, `a` и `b` не изменятся. 4879 | 4880 | ## Константы 4881 | Константы – обычные переменные, но которые не следует изменять. Их называют большими буквами. Python не будет предотвращать изменение констант, но для других разработчиков константы – сигнал, что их нельзя изменять. 4882 | 4883 | ## Docstrings (Докстринги) 4884 | Docstrings – несколько строк, объясняющих работу функции: 4885 | ```python 4886 | def my_pow(x, y): 4887 | """ 4888 | Принимает два числа на вход: x и y. 4889 | Возвращает x, возведенное в степень y. 4890 | """ 4891 | return x**y 4892 | 4893 | 4894 | print(my_pow(5, 3)) 4895 | >>> 125 4896 | ``` 4897 | В интерфейсах большинства IDE докстринги видны при наборе функции: 4898 | ![Image 23](images/image_23.png) 4899 | 4900 | ## Многоточие (…) как объект 4901 | В Python `...` является отдельным объектом типа `Ellipsis:` 4902 | ```python 4903 | print(...) 4904 | print(type(...)) 4905 | >>> Ellipsis 4906 | >>> 4907 | ``` 4908 | Его можно использовать как `pass:` 4909 | ```python 4910 | def func(): 4911 | pass 4912 | 4913 | 4914 | def func1(): ... 4915 | 4916 | ``` 4917 | ## Атрибуты функций 4918 | Функциям можно присваивать атрибуты, это удобно, чтобы, например, сохранять некую информацию между вызовами функций: 4919 | ```python 4920 | def my_pow(x, y): 4921 | if not hasattr(my_pow, "last_call"): # Проверка на наличие атрибута 4922 | my_pow.last_call = None 4923 | print(f"Прошлый вызов функции: {my_pow.last_call}") 4924 | my_pow.last_call = x, y 4925 | return x**y 4926 | 4927 | 4928 | my_pow(2, 2) 4929 | my_pow(3, 2) 4930 | my_pow(4, 5) 4931 | >>> Прошлый вызов функции: None 4932 | >>> Прошлый вызов функции: (2, 2) 4933 | >>> Прошлый вызов функции: (3, 2) 4934 | 4935 | ``` 4936 | ## locals(), globals() 4937 | ```python 4938 | def func(): 4939 | return "name" in locals() # Существует ли локальная переменная с таким именем 4940 | 4941 | 4942 | print("name" in globals()) # Существует ли глобальная переменная с таким именем 4943 | name = "Ivan" 4944 | print("name" in globals()) # Существует ли глобальная переменная с таким именем 4945 | print(func()) 4946 | >>> False 4947 | >>> True 4948 | >>> False 4949 | 4950 | ``` 4951 | ## maketrans(), translate() 4952 | ```python 4953 | table = str.maketrans("aeiou", "*****", " ") # Создание таблицы перевода с заменой гласных на звёздочки и удалением пробелов 4954 | print("hello world".translate(table)) # "Перевести" строку с использованием таблицы table 4955 | >>> h*ll*w*rld 4956 | ``` 4957 | Также можно использовать словари: 4958 | ```python 4959 | table = str.maketrans({"a": "*", "e": "*", "i": "*", "o": "*", "u": "*", " ": None}) # Создание таблицы перевода с заменой гласных на звёздочки и удалением пробелов 4960 | print("hello world".translate(table)) # "Перевести" строку с использованием таблицы table 4961 | >>> h*ll*w*rld 4962 | 4963 | 4964 | ``` --------------------------------------------------------------------------------