2564 lines
146 KiB
Plaintext
2564 lines
146 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<!-- dom:TITLE: Типы и модель данных -->\n",
|
||
"# Типы и модель данных\n",
|
||
"<!-- dom:AUTHOR: С.В. Лемешевский Email:sergey.lemeshevsky@gmail.com at Институт математики НАН Беларуси -->\n",
|
||
"<!-- Author: --> \n",
|
||
"**С.В. Лемешевский** (email: `sergey.lemeshevsky@gmail.com`), Институт математики НАН Беларуси\n",
|
||
"\n",
|
||
"Date: **Mar 18, 2020**\n",
|
||
"\n",
|
||
"<!-- Common Mako variable and functions -->\n",
|
||
"<!-- -*- coding: utf-8 -*- -->\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"Здесь разберем как Python работает с переменными и определим, какие\n",
|
||
"типы данных можно использовать в рамках этого языка. Подробно рассмотрим модель\n",
|
||
"данных Python, а также механизмы создания и изменения значения\n",
|
||
"переменных.\n",
|
||
"\n",
|
||
"# Кратко о типизации языков программирования\n",
|
||
"<div id=\"datatype:typization\"></div>\n",
|
||
"\n",
|
||
"Если достаточно формально подходить к вопросу о типизации языка Python, то\n",
|
||
"можно сказать, что он относится к языкам с неявной сильной динамической\n",
|
||
"типизацией.\n",
|
||
"\n",
|
||
"Неявная типизация означает, что при объявлении переменной вам не нужно\n",
|
||
"указывать её тип, при явной – это делать необходимо. В качестве примера языков с\n",
|
||
"явной типизацией можно привести Java, C++ . Вот как будет выглядеть объявление\n",
|
||
"целочисленной переменной в Java и Python.\n",
|
||
"\n",
|
||
"* Java:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
" int a = 1 ;\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* Python:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = 1"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"chapter\" -->\n",
|
||
"<!-- doconce-section-nickname: \"typization\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"# Типы данных в Python\n",
|
||
"<div id=\"datatype:types\"></div>\n",
|
||
"\n",
|
||
"В Python типы данных можно разделить на встроенные в интерпретатор (`built-in`) и\n",
|
||
"не встроенные, которые можно использовать при импортировании соответствующих\n",
|
||
"модулей.\n",
|
||
"\n",
|
||
"К основным встроенным типам относятся:\n",
|
||
"1. `None` (неопределенное значение переменной)\n",
|
||
"\n",
|
||
"2. Логические переменные (`Boolean Type`)\n",
|
||
"\n",
|
||
"3. Числа (`Numeric Type`)\n",
|
||
"\n",
|
||
"a. `int` – целое число\n",
|
||
"\n",
|
||
"b. `float` – число с плавающей точкой\n",
|
||
"\n",
|
||
"c. `complex` – комплексное число\n",
|
||
"\n",
|
||
"\n",
|
||
"4. Списки (`Sequence Type`)\n",
|
||
"\n",
|
||
"a. `list` – список\n",
|
||
"\n",
|
||
"b. `tuple` – кортеж\n",
|
||
"\n",
|
||
"c. `range` – диапазон\n",
|
||
"\n",
|
||
"\n",
|
||
"4. Строки (`Text Sequence Type`)\n",
|
||
"\n",
|
||
"a. `str`\n",
|
||
"\n",
|
||
"\n",
|
||
"2. Бинарные списки ( Binary Sequence Types )\n",
|
||
"\n",
|
||
"a. `bytes` – байты\n",
|
||
"\n",
|
||
"b. `bytearray` – массивы байт\n",
|
||
"\n",
|
||
"c. `memoryview` – специальные объекты для доступа к внутренним данным объекта через `protocol buffer`\n",
|
||
"\n",
|
||
"\n",
|
||
"4. Множества (`Set Types`)\n",
|
||
"\n",
|
||
"a. `set` – множество\n",
|
||
"\n",
|
||
"b. `frozenset` – неизменяемое множество\n",
|
||
"\n",
|
||
"\n",
|
||
"3. Словари (`Mapping Types`)\n",
|
||
"\n",
|
||
"a. `dict` – словарь\n",
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
|
||
"<!-- doconce-section-nickname: \"types\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"\n",
|
||
"\n",
|
||
"## Модель данных\n",
|
||
"<div id=\"datatype:model\"></div>\n",
|
||
"\n",
|
||
"Рассмотрим как создаются объекты в памяти, их устройство, процесс объявления\n",
|
||
"новых переменных и работу операции присваивания.\n",
|
||
"\n",
|
||
"Для того, чтобы объявить и сразу инициализировать переменную необходимо\n",
|
||
"написать её имя, потом поставить знак равенства и значение, с которым эта\n",
|
||
"переменная будет создана.\n",
|
||
"\n",
|
||
"Например строка:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"b = 5"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Объявляет переменную `b` и присваивает ей значение `5`.\n",
|
||
"\n",
|
||
"Целочисленное значение `5` в рамках языка Python по сути своей является\n",
|
||
"*объектом*. Объект, в данном случае – это абстракция для представления данных,\n",
|
||
"данные – это числа, списки, строки и т.п. При этом, под *данными* следует понимать как\n",
|
||
"непосредственно сами объекты, так и отношения между ними (об этом чуть позже).\n",
|
||
"Каждый объект имеет три атрибута – это *идентификатор*, *значение* и *тип*.\n",
|
||
"\n",
|
||
"*Идентификатор* – это уникальный признак объекта, позволяющий отличать объекты\n",
|
||
"друг от друга, а *значение* – непосредственно информация, хранящаяся в памяти,\n",
|
||
"которой управляет интерпретатор. \n",
|
||
"\n",
|
||
"При инициализации переменной, на уровне интерпретатора, происходит\n",
|
||
"следующее:\n",
|
||
"* создается целочисленный объект `5` (можно представить, что в этот момент создается ячейка и число `5` «кладется» в эту ячейку);\n",
|
||
"\n",
|
||
"* данный объект имеет некоторый идентификатор, значение: `5`, и тип: целое число;\n",
|
||
"\n",
|
||
"* посредством оператора `=` создается ссылка между переменной `b` и целочисленным объектом `5` (переменная `b` ссылается на объект `5`).\n",
|
||
"\n",
|
||
"> **Об именах переменных.**\n",
|
||
">\n",
|
||
"> Допустимые имена переменных в языке Python – это последовательность\n",
|
||
"> символов произвольной длины, содержащей «начальный символ»\n",
|
||
"> и ноль или более «символов продолжения». Имя переменной должно\n",
|
||
"> следовать определенным правилам и соглашениям. \n",
|
||
"> \n",
|
||
"> Первое правило касается начального символа и символов\n",
|
||
"> продолжения. Начальным символом может быть любой символ, который в\n",
|
||
"> кодировке Юникод рассматривается как принадлежащий диапазону\n",
|
||
"> алфавитных символов ASCII (`a`, `b`, ..., `z`, `A`, `B`, ..., `Z`),\n",
|
||
"> символ подчеркивания (`_`), а также символы большинства национальных\n",
|
||
"> (не английских) алфавитов. Каждый символ продолжения может быть\n",
|
||
"> любым символом из тех, что пригодны в качестве начального символа,\n",
|
||
"> а также любым непробельным символом, включая символы, которые\n",
|
||
"> в кодировке Юникод считаются цифрами, такие как (`0`, `1`, ...,\n",
|
||
"> `9`), и символ Каталана `·`. Идентификаторы чувствительны к регистру,\n",
|
||
"> поэтому `TAXRATE`, `Taxrate`, `TaxRate`, `taxRate` и `taxrate` – это\n",
|
||
"> пять разных переменных. \n",
|
||
"> \n",
|
||
"> Имя переменной не должно совпадать с ключевыми словами интерпретатора\n",
|
||
"> Python. Список ключевых слов можно получить непосредственно в программе, для\n",
|
||
"> этого нужно подключить модуль `keyword` и воспользоваться командой\n",
|
||
"> `keyword.kwlist`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"import keyword\n",
|
||
"print(\"Python keywords: \" , keyword.kwlist)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"> \n",
|
||
"> Проверить является или нет идентификатор ключевым словом можно так:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"keyword.iskeyword( \"try\" )"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
">"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"keyword.iskeyword( \"b\" )"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"> **Об использовании символа подчеркивания в именах переменных.**\n",
|
||
">\n",
|
||
"> Не должны использоваться имена, начинающиеся и заканчивающиеся двумя\n",
|
||
"> символами подчеркивания (такие как `__lt__`). В языке \n",
|
||
"> Python определено множество различных специальных методов и переменных\n",
|
||
"> с такими именами (и в случае специальных методов мы можем заменять их,\n",
|
||
"> то есть создать свои версии этих методов), но мы не должны вводить\n",
|
||
"> новые имена такого рода.\n",
|
||
"> \n",
|
||
"> Символ подчеркивания сам по себе может использоваться в качестве\n",
|
||
"> идентификатора; внутри интерактивной оболочки интерпретатора или\n",
|
||
"> в командной оболочке Python в переменной с именем `_` сохраняется\n",
|
||
"> результат последнего вычисленного выражения. Во время выполнения\n",
|
||
"> обычной программы идентификатор `_` отсутствует, если мы явно не\n",
|
||
"> определяем его в своем программном коде. Некоторые программисты \n",
|
||
"> любят использовать `_` в качестве идентификатора переменной цикла\n",
|
||
"> в циклах `for` ... `in`, когда не требуется обращаться к элементам, по\n",
|
||
"> которым выполняются итерации. Например:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"for _ in (0, 1, 2, 3, 4, 5):\n",
|
||
" print(\"Hello\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Для того, чтобы посмотреть на объект с каким идентификатором ссылается данная\n",
|
||
"переменная, можно использовать функцию `id()`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = 4\n",
|
||
"b = 5\n",
|
||
"id (a)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"id (b)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = b\n",
|
||
"id (a)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Как видно из примера, идентификатор – это некоторое целочисленное значение,\n",
|
||
"посредством которого уникально адресуется объект. Изначально переменная a\n",
|
||
"ссылается на объект `4` с идентификатором `1829984576`, переменная `b`\n",
|
||
"– на объект с `id = 1829984592`. После выполнения операции\n",
|
||
"присваивания `a = b`, переменная a стала ссылаться на тот же объект,\n",
|
||
"что и `b`.\n",
|
||
"\n",
|
||
"<!-- dom:FIGURE: [fig-datatype/refs.png, width=600 frac=1.0] -->\n",
|
||
"<!-- begin figure -->\n",
|
||
"<!-- end figure -->\n",
|
||
"\n",
|
||
"\n",
|
||
"Тип переменной можно определить с помощью функции `type()`. Пример\n",
|
||
"использования приведен ниже."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = 10\n",
|
||
"b = \"hello\"\n",
|
||
"c = ( 1 , 2 )\n",
|
||
"type (a)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"type (b)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"type (c)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
|
||
"<!-- doconce-section-nickname: \"model\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"# Изменяемые и неизменяемые типы данных\n",
|
||
"<div id=\"datatype:mutable\"></div>\n",
|
||
"\n",
|
||
"В Python существуют изменяемые и неизменяемые типы.\n",
|
||
"\n",
|
||
"К неизменяемым (`immutable`) типам относятся:\n",
|
||
"* целые числа (`int`);\n",
|
||
"\n",
|
||
"* числа с плавающей точкой (`float`);\n",
|
||
"\n",
|
||
"* комплексные числа (`complex`);\n",
|
||
"\n",
|
||
"* логические переменные (`bool`);\n",
|
||
"\n",
|
||
"* кортежи (`tuple`);\n",
|
||
"\n",
|
||
"* строки (`str`);\n",
|
||
"\n",
|
||
"* неизменяемые множества (`frozen set`).\n",
|
||
"\n",
|
||
"К изменяемым ( mutable ) типам относятся\n",
|
||
"* списки (`list`);\n",
|
||
"\n",
|
||
"* множества (`set`);\n",
|
||
"\n",
|
||
"* словари (`dict`).\n",
|
||
"\n",
|
||
"Как уже было сказано ранее, при создании переменной, вначале создается объект,\n",
|
||
"который имеет уникальный идентификатор, тип и значение, после этого переменная\n",
|
||
"может ссылаться на созданный объект.\n",
|
||
"\n",
|
||
"Неизменяемость типа данных означает, что созданный объект больше не\n",
|
||
"изменяется. Например, если мы объявим переменную `k = 15`, то будет создан объект\n",
|
||
"со значением `15`, типа `int` и идентификатором, который можно узнать с помощью\n",
|
||
"функции `id()`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"k = 15\n",
|
||
"id (k)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 14,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"type (k)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Объект с `id = 1672501744` будет иметь значение `15` и изменить его уже нельзя.\n",
|
||
"Если тип данных изменяемый, то можно менять значение объекта.\n",
|
||
"\n",
|
||
"Например, создадим список `[1, 2]`, а потом заменим второй элемент на\n",
|
||
"`3`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = [1 ,2]\n",
|
||
"id (a)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 16,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"a[1] = 3\n",
|
||
"a"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 17,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"id(a)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Как видно, объект на который ссылается переменная `a`, был изменен. Это можно\n",
|
||
"проиллюстрировать следующим рисунком.\n",
|
||
"\n",
|
||
"<!-- dom:FIGURE: [fig-datatype/mute.png, width=600 frac=1.0] -->\n",
|
||
"<!-- begin figure -->\n",
|
||
"<!-- end figure -->\n",
|
||
"\n",
|
||
"\n",
|
||
"В рассмотренном случае, в качестве данных списка, выступают не объекты, а\n",
|
||
"отношения между объектами. Т.е. в переменной a хранятся ссылки на объекты\n",
|
||
"содержащие числа `1` и `3`, а не непосредственно сами эти числа.\n",
|
||
"\n",
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
|
||
"<!-- doconce-section-nickname: \"mutable\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"# Целочисленные типы\n",
|
||
"<div id=\"datatype:decimal\"></div>\n",
|
||
"\n",
|
||
"В языке Python имеется два целочисленных типа, `int` и `bool`. И целые\n",
|
||
"числа, и логические значения являются неизменяемыми объектами,\n",
|
||
"но благодаря присутствию в языке Python комбинированных операторов\n",
|
||
"присваивания эта особенность практически незаметна. В логических\n",
|
||
"выражениях число `0` и значение `False` представляют `False`, а любое\n",
|
||
"другое целое число и значение `True` представляют `True`. В числовых \n",
|
||
"выражениях значение `True` представляет `1`, а `False` – `0`. Это означает,\n",
|
||
"что можно записывать весьма странные выражения, например, выражение `i\n",
|
||
"+= True` увеличит значение `i` на единицу. Естественно, более\n",
|
||
"правильным будет записывать подобные выражения как `i += 1`. \n",
|
||
"\n",
|
||
"Размер целого числа ограничивается только объемом памяти компьютера,\n",
|
||
"поэтому легко можно создать и обрабатывать целое число, состоящее из\n",
|
||
"тысяч цифр, правда, скорость работы с такими числами существенно\n",
|
||
"медленнее, чем с числами, которые соответствуют машинному\n",
|
||
"представлению.\n",
|
||
"\n",
|
||
"Литералы целых чисел по умолчанию записываются в десятичной сис-\n",
|
||
"теме счисления, но при желании можно использовать другие системы\n",
|
||
"счисления:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 18,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"14600926"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 19,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"0b110111101100101011011110"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 20,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"0o67545336"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 21,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"0xDECADE"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Двоичные числа записываются с префиксом `0b`, восьмеричные – в\n",
|
||
"префиксом `0o` и шестнадцатеричные – с префиксом `0x`. В префиксах\n",
|
||
"допускается использовать символы верхнего регистра.\n",
|
||
"\n",
|
||
"При работе с целыми числами могут использоваться обычные\n",
|
||
"математические функции и операторы, как показано в\n",
|
||
"табл. [Таблица 1 : Арифметические операторы и функции](#datatype:tbl:1). Для арифметических операций `+`, `-`, `/`,\n",
|
||
"`//`, `%` и `**` имеются соответствующие комбинированные операторы\n",
|
||
"присваивания: `+=`, `-=`, `/=`, `//=`, `%=` и `**=`, где выражение\n",
|
||
"`x op= y` является эквивалентом выражения `x = x op y`.\n",
|
||
"\n",
|
||
"\n",
|
||
"## Таблица 1 : Арифметические операторы и функции\n",
|
||
"<div id=\"datatype:tbl:1\"></div>\n",
|
||
"\n",
|
||
"\n",
|
||
"<table border=\"1\">\n",
|
||
"<thead>\n",
|
||
"<tr><th align=\"left\"> Синтаксис </th> <th align=\"left\"> Описание </th> </tr>\n",
|
||
"</thead>\n",
|
||
"<tbody>\n",
|
||
"<tr><td align=\"left\"> <code>x + y</code> </td> <td align=\"left\"> Складывает число <code>x</code> и число <code>y</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>x - y</code> </td> <td align=\"left\"> Вычитает число <code>y</code> из числа <code>x</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>x * y</code> </td> <td align=\"left\"> Умножает <code>x</code> на <code>y</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>x / y</code> </td> <td align=\"left\"> Делит <code>x</code> на <code>y</code> – результатом всегда является значение типа <code>float</code> (или <code>complex</code>, если <code>x</code> или <code>y</code> является комплексным числом) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>x // y</code> </td> <td align=\"left\"> Делит <code>x</code> на <code>y</code>, при этом усекает дробную часть, поэтому результатом всегда является значение типа <code>int</code>; смотрите также функцию <code>round()</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>x % y</code> </td> <td align=\"left\"> Возвращает модуль (остаток) от деления <code>x</code> на <code>y</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>x**y</code> </td> <td align=\"left\"> Возводит <code>x</code> в степень <code>y</code>; смотрите также функцию <code>pow()</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>-x</code> </td> <td align=\"left\"> Изменяет знак числа <code>x</code>, если оно не является нулем, если ноль – ничего не происходит </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>+x</code> </td> <td align=\"left\"> Ничего не делает иногда используется для повышения удобочитаемости программного кода </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>abs(x)</code> </td> <td align=\"left\"> Возвращает абсолютное значение <code>x</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>divmod(x, y)</code> </td> <td align=\"left\"> Возвращает частное и остаток деления <code>x</code> на <code>y</code> в виде кортежа двух значений типа <code>int</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>pow(x, y)</code> </td> <td align=\"left\"> Возводит <code>x</code> в степень <code>y</code>; то же самое что и оператор <code>**</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>pow(x, y, z)</code> </td> <td align=\"left\"> Более быстрая альтернатива выражению <code>(x ** y) % z</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>round(x, n)</code> </td> <td align=\"left\"> Возвращает значение типа <code>int</code>, соответствующее значению <code>x</code> типа <code>float</code>, округленному до ближайшего целого числа (или значение типа <code>float</code>, округленное до $n$-го знака после запятой, если задан аргумент <code>n</code>) </td> </tr>\n",
|
||
"</tbody>\n",
|
||
"</table>\n",
|
||
"\n",
|
||
"\n",
|
||
"Объекты могут создаваться путем присваивания литералов переменным,\n",
|
||
"например, `x = 17`, или обращением к имени соответствующего типа как к\n",
|
||
"функции, например, `x = int(17)`. Создание объекта посредством\n",
|
||
"использования его типа может быть выполнено одним из трех способов:\n",
|
||
"\n",
|
||
"* вызов типа данных без аргументов. В этом случае объект приобретает значение по умолчанию, например, выражение `x = int()` создаст целое число `0`. Любые встроенные типы могут вызываться без аргументов.\n",
|
||
"\n",
|
||
"* тип вызывается с единственным аргументом. Если указан аргумент соответствующего типа, будет создана поверхностная копия оригинального объекта. Если задан аргумент другого типа, будет предпринята попытка выполнить преобразование. Такой способ использования описывается в табл. [datatype:tbl:2](#datatype:tbl:2)\n",
|
||
"\n",
|
||
"* передается два или более аргументов; не все типы поддерживают такую возможность, а для тех типов, что поддерживают ее, типы аргументов и их назначение отличаются. В случае типа `int` допускается передавать два аргумента, где первый аргумент – это строка с представлением целого числа, а второй аргумент – число основания системы счисления. Например, вызов `int(\"A4\", 16)` создаст десятичное значение `164`.\n",
|
||
"\n",
|
||
"## Таблица 2 : Функции преобразования целых чисел <div id=\"datatype:tbl:2\"></div>\n",
|
||
"\n",
|
||
"\n",
|
||
"<table border=\"1\">\n",
|
||
"<thead>\n",
|
||
"<tr><th align=\"left\"> Синтаксис </th> <th align=\"left\"> Описание </th> </tr>\n",
|
||
"</thead>\n",
|
||
"<tbody>\n",
|
||
"<tr><td align=\"left\"> <code>bin(i)</code> </td> <td align=\"left\"> Возвращает двоичное представление целого числа <code>i</code> в виде строки, например, <code>bin(1980) == '0b11110111100'</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>hex(i)</code> </td> <td align=\"left\"> Возвращает шестнадцатеричное представление целого числа <code>i</code> в виде строки, например, <code>hex(1980) == '0x7bc'</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>int(x)</code> </td> <td align=\"left\"> Преобразует объект <code>x</code> в целое число; в случае ошибки во время преобразования возбуждает исключение <code>ValueError</code>, а если тип объекта <code>x</code> не поддерживает преобразование в целое число возбуждает исключение <code>TypeError</code>. Если <code>x</code> является числом с плавающей точкой, оно преобразуется в целое число путем усечения дробной части. </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>int(s, base)</code> </td> <td align=\"left\"> Преобразует строку <code>s</code> в целое число; в случае ошибки возбуждает исключение <code>ValueError</code>. Если задан необязательный аргумент <code>base</code>, он должен быть целым числом в диапазоне от <code>2</code> до <code>36</code> включительно. </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>oct(i)</code> </td> <td align=\"left\"> Возвращает восьмеричное представление целого числа <code>i</code> в виде строки, например, <code>oct(1980) == '0o3674'</code> </td> </tr>\n",
|
||
"</tbody>\n",
|
||
"</table>\n",
|
||
"\n",
|
||
"\n",
|
||
"В табл. [datatype:tbl:3](#datatype:tbl:3) перечислены битовые операторы. Все битовые операторы\n",
|
||
"(`|`, `^`, `&`, `<<` и `>>`) имеют соответствующие комбинированные операторы\n",
|
||
"присваивания (`|=`, `^=`, `&=`, `<<=` и `>>=`), где выражение `i op= j` является\n",
|
||
"логическим эквивалентом выражения `i = i op j` в случае, когда обращение\n",
|
||
"к значению `i` не имеет побочных эффектов. \n",
|
||
"\n",
|
||
"\n",
|
||
"## Таблица 3 : Функции преобразования целых чисел <div id=\"datatype:tbl:3\"></div>\n",
|
||
"\n",
|
||
"\n",
|
||
"<table border=\"1\">\n",
|
||
"<thead>\n",
|
||
"<tr><th align=\"left\">Синтаксис</th> <th align=\"left\"> Описание </th> </tr>\n",
|
||
"</thead>\n",
|
||
"<tbody>\n",
|
||
"<tr><td align=\"left\"> <code>i | j</code> </td> <td align=\"left\"> Битовая операция OR (ИЛИ) над целыми числами <code>i</code> и <code>j</code>; отрицательные числа представляются как двоичное дополнение </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>i ^ j</code> </td> <td align=\"left\"> Битовая операция XOR (исключающее ИЛИ) над целыми числами <code>i</code> и <code>j</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>i & j</code> </td> <td align=\"left\"> Битовая операция AND (И) над целыми числами <code>i</code> и <code>j</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>i << j</code> </td> <td align=\"left\"> Сдвигает значение <code>i</code> влево на <code>j</code> битов аналогично операции <code>i * (2 ** j)</code> без проверки на переполнение </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>i >> j</code> </td> <td align=\"left\"> Сдвигает значение <code>i</code> вправо на <code>j</code> битов аналогично операции <code>i // (2 ** j)</code> без проверки на переполнение </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\~i</code> </td> <td align=\"left\"> Инвертирует биты числа <code>i</code> </td> </tr>\n",
|
||
"</tbody>\n",
|
||
"</table>\n",
|
||
"\n",
|
||
"\n",
|
||
"## Логические значения\n",
|
||
"<div id=\"datatype:decimal:bool\"></div>\n",
|
||
"\n",
|
||
"Существует два встроенных логических объекта: `True` и `False`. Как\n",
|
||
"и все остальные типы данных в языке Python (встроенные, библиотечные\n",
|
||
"или ваши собственные), тип данных `bool` может вызываться как \n",
|
||
"функция – при вызове без аргументов возвращается значение `False`,\n",
|
||
"при вызове с аргументом типа `bool` возвращается копия аргумента,\n",
|
||
"а при вызове с любым другим аргументом предпринимается попытка\n",
|
||
"преобразовать указанный объект в тип `bool`. Все встроенные типы\n",
|
||
"данных и типы данных из стандартной библиотеки могут быть\n",
|
||
"преобразованы в тип `bool`, а добавить поддержку такого преобразования в\n",
|
||
"свои собственные типы данных не представляет никакой сложности. Ниже\n",
|
||
"приводится пара присваиваний логических значений и пара логических\n",
|
||
"выражений:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"t = True"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 23,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"f = False"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 24,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"t and f"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 25,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"t and True"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"в языке Python имеется три логических оператора: `and`, `or` и\n",
|
||
"`not`. Выражения с участием операторов `and` и `or` вычисляются в\n",
|
||
"соответствии с логикой сокращенных вычислений (*short-circuit logic*),\n",
|
||
"и возвращается операнд, определяющий значение всего\n",
|
||
"выражения, тогда как результатом оператора `not` всегда\n",
|
||
"является либо `True`, либо `False`.\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
|
||
"<!-- doconce-section-nickname: \"decimal\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"# Типы чисел с плавающей точкой\n",
|
||
"<div id=\"datatype:float\"></div>\n",
|
||
"\n",
|
||
"Язык Python предоставляет три типа значений с плавающей точкой:\n",
|
||
"встроенные типы `float` и `complex` и тип `decimal.Decimal` в\n",
|
||
"стандартной библиотеке. Все три типа данных относятся к категории\n",
|
||
"неизменяемых. Тип `float` представляет числа с плавающей точкой\n",
|
||
"двойной точности, диапазон значений которых зависит от компилятора\n",
|
||
"языка C (или C\\# или Java), применявшегося для компиляции интерпретатора\n",
|
||
"Python. Числа этого типа имеют ограниченную точность и не могут\n",
|
||
"надежно сравниваться на равенство значений. Числа типа `float`\n",
|
||
"записываются с десятичной точкой или в экспоненциальной форме записи, \n",
|
||
"например, `0.0`, `4.`, `5.7`, `-2.5`, `-2e9`, `8.9e-4`.\n",
|
||
"\n",
|
||
"В машинном представлении числа с плавающей точкой хранятся как\n",
|
||
"двоичные числа. Это означает, что одни дробные значения могут быть\n",
|
||
"представлены точно (такие как `0.5`), а другие – только приблизительно\n",
|
||
"(такие как `0.1` и `0.2`). Кроме того, для представления используется\n",
|
||
"фиксированное число битов, поэтому существует ограничение на\n",
|
||
"количество цифр в представлении таких чисел. Ниже приводится\n",
|
||
"поясняющий пример:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 26,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"0.0, 5.4, -2.5, 8.9e-4"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Проблема потери точности – это не проблема, свойственная только\n",
|
||
"языку Python; все языки программирования обнаруживают проблему\n",
|
||
"с точным представлением чисел с плавающей точкой.\n",
|
||
"\n",
|
||
"Если действительно необходимо обеспечить высокую точность,\n",
|
||
"можно использовать числа типа `decimal.Decimal`. Эти числа\n",
|
||
"обеспечивают уровень точности, который вы укажете (по умолчанию 28\n",
|
||
"знаков после запятой), и могут точно представлять периодические числа,\n",
|
||
"такие как $0.1$ , но скорость работы с такими числами существенно\n",
|
||
"ниже, чем с обычными числами типа `float`. Вследствие высокой точности\n",
|
||
"числа типа `decimal.Decimal` прекрасно подходят для производства\n",
|
||
"финансовых вычислений.\n",
|
||
"\n",
|
||
"Смешанная арифметика поддерживается таким образом, что результатом\n",
|
||
"выражения с участием чисел типов `int` и `float` является число типа\n",
|
||
"`float`, а с участием типов `float` и `complex` результатом является\n",
|
||
"число типа `complex`. Поскольку числа типа `decimal.Decimal` имеют\n",
|
||
"фиксированную точность, они могут участвовать в выражениях только с\n",
|
||
"другими числами `decimal.Decimal` и с числами типа `int`; результатом \n",
|
||
"таких выражений является число `decimal.Decimal`. В случае попытки\n",
|
||
"выполнить операцию над несовместимыми типами возбуждается исключение\n",
|
||
"`TypeError`.\n",
|
||
"\n",
|
||
"## Числа с плавающей точкой\n",
|
||
"<div id=\"datatype:float:foat\"></div>\n",
|
||
"\n",
|
||
"Все числовые операторы и функции, представленные в\n",
|
||
"табл. [Таблица 1 : Арифметические операторы и функции](#datatype:tbl:1), могут применяться к числам типа float,\n",
|
||
"включая комбинированные операторы присваивания. Тип данных float может\n",
|
||
"вызываться как функция – без аргументов возвращается число `0.0`, с\n",
|
||
"аргументом типа float возвращается копия аргумента, а с аргументом\n",
|
||
"любого другого типа предпринимается попытка выполнить преобразование\n",
|
||
"указанного объекта в тип float. При преобразовании строки \n",
|
||
"аргумент может содержать либо простую форму записи числа с десятичной\n",
|
||
"точкой, либо экспоненциальное представление числа. При выполнении\n",
|
||
"операций с числами типа float может возникнуть ситуация, \n",
|
||
"когда в результате получается значение `NaN` (*not a number* – не\n",
|
||
"число) или «бесконечность». К сожалению, поведение интерпретатора в\n",
|
||
"таких ситуациях может отличаться в разных реализациях и зависит от \n",
|
||
"математической библиотеки системы.\n",
|
||
"\n",
|
||
"Ниже приводится пример простой функции, выполняющей сравнение\n",
|
||
"чисел типа float на равенство в пределах машинной точности:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 27,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def equal_float(a, b):\n",
|
||
" return abs(a - b) <= sys.float_info.epsilon"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Чтобы воспользоваться этой функцией, необходимо импортировать\n",
|
||
"модуль `sys`. Объект `sys.float_info` имеет множество атрибутов. Так,\n",
|
||
"`sys.float_info.epsilon` хранит минимально возможную разницу между\n",
|
||
"двумя числами с плавающей точкой. На одной из 32-разрядных машин\n",
|
||
"автора книги это число чуть больше $0.000 000 000 000 000 2$.\n",
|
||
"Тип `float` в языке Python обеспечивает надежную точность до 17\n",
|
||
"значащих цифр.\n",
|
||
"\n",
|
||
"В дополнение к встроенным функциональным возможностям работы\n",
|
||
"с числами типа `float` модуль `math` предоставляет множество функций,\n",
|
||
"которые приводятся в табл. [datatype:tbl:4](#datatype:tbl:4). Ниже приводятся\n",
|
||
"несколько фрагментов программного кода, демонстрирующих, как можно\n",
|
||
"использовать функциональные возможности модуля:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 28,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"import math\n",
|
||
"math.pi * (5 ** 2)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 29,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"math.hypot(5, 12)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 30,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"math.modf(13.732)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Модуль `math` в значительной степени опирается на математическую\n",
|
||
"библиотеку, с которой был собран интерпретатор Python. Это означает,\n",
|
||
"что при некоторых условиях и в граничных случаях функции модуля могут\n",
|
||
"иметь различное поведение на различных платформах. \n",
|
||
"\n",
|
||
"\n",
|
||
"## Таблица 4 : Функции и константы модуля `math` <div id=\"datatype:tbl:4\"></div>\n",
|
||
"\n",
|
||
"\n",
|
||
"<table border=\"1\">\n",
|
||
"<thead>\n",
|
||
"<tr><th align=\"left\"> Синтаксис </th> <th align=\"left\"> Описание </th> </tr>\n",
|
||
"</thead>\n",
|
||
"<tbody>\n",
|
||
"<tr><td align=\"left\"> <code>math.acos(x)</code> </td> <td align=\"left\"> Возвращает арккосинус <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.acosh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический арккосинус <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.asin(x)</code> </td> <td align=\"left\"> Возвращает арксинус <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.asinh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический арксинус <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.atan(x)</code> </td> <td align=\"left\"> Возвращает арктангенс <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.atan2(y x)</code> </td> <td align=\"left\"> Возвращает арктангенс <code>y/x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.atanh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический арктангенс <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.ceil(x)</code> </td> <td align=\"left\"> Возвращает $ | x | $, то есть наименьшее целое число типа <code>int</code>, большее и равное <code>x</code>, например, <code>math.ceil(5.4) == 6</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.copysign(x y)</code> </td> <td align=\"left\"> Возвращает <code>x</code> со знаком числа <code>y</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.cos(x)</code> </td> <td align=\"left\"> Возвращает косинус <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.cosh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический косинус <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.degrees(r)</code> </td> <td align=\"left\"> Преобразует число <code>r</code> типа <code>float</code> из радианов в градусы </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.e</code> </td> <td align=\"left\"> Константа $e$, примерно равная значению $2.7182818284590451$ </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.exp(x)</code> </td> <td align=\"left\"> Возвращает $e^x$, то есть <code>math.e ** x</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.fabs(x)</code> </td> <td align=\"left\"> Возвращает $ | x | $, то есть абсолютное значение <code>x</code> в виде числа типа <code>float</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.factorial(x)</code> </td> <td align=\"left\"> Возвращает $x!$ </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.floor(x)</code> </td> <td align=\"left\"> Возвращает $ | x | $, то есть наименьшее целое число типа <code>int</code>, меньшее и равное <code>x</code>, например, <code>math.floor(5.4) == 5</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.fmod(x y)</code> </td> <td align=\"left\"> Выполняет деление по модулю (возвращает остаток) числа <code>x</code> на число <code>y</code>; дает более точный результат, чем оператор <code>%</code>, применительно к числам типа <code>float</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.frexp(x)</code> </td> <td align=\"left\"> Возвращает кортеж из двух элементов с мантиссой (в виде числа типа <code>float</code>) и экспонентой (в виде числа типа <code>int</code>) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.fsum(i)</code> </td> <td align=\"left\"> Возвращает сумму значений в итерируемом объекте <code>i</code> в виде числа типа <code>float</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.hypot(x y)</code> </td> <td align=\"left\"> Возвращает $\\sqrt{x^2 + y^2}$ </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.isinf(x)</code> </td> <td align=\"left\"> Возвращает <code>True</code>, если значение <code>x</code> типа <code>float</code> является бесконечностью ($\\pm \\infty$) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.isnan(x)</code> </td> <td align=\"left\"> Возвращает <code>True</code>, если значение <code>x</code> типа <code>float</code> не является числом </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.ldexp(m e)</code> </td> <td align=\"left\"> Возвращает $m\\times 2^e$ – операция обратная <code>math.frexp()</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.log(x b)</code> </td> <td align=\"left\"> Возвращает $\\log_b x$, аргумент <code>b</code> является необязательным и по умолчанию имеет значение <code>math.e</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.log10(x)</code> </td> <td align=\"left\"> Возвращает $log_{10} x$ </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.log1p(x)</code> </td> <td align=\"left\"> Возвращает $log_e (1+x)$; дает точные значения даже когда значение <code>x</code> близко к <code>0</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.modf(x)</code> </td> <td align=\"left\"> Возвращает дробную и целую часть числа <code>x</code> в виде двух значений типа <code>float</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.pi</code> </td> <td align=\"left\"> Константа $\\pi$, примерно равная $3.1415926535897931$ </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.pow(x y)</code> </td> <td align=\"left\"> Возвращает $x^y$ в виде числа типа <code>float</code> </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.radians(d)</code> </td> <td align=\"left\"> Преобразует число <code>d</code> типа <code>float</code> из градусов в радианы </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.sin(x)</code> </td> <td align=\"left\"> Возвращает синус <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.sinh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический синус <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.sqrt(x)</code> </td> <td align=\"left\"> Возвращает $\\sqrt{x}$ </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.tan(x)</code> </td> <td align=\"left\"> Возвращает тангенс <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.tanh(x)</code> </td> <td align=\"left\"> Возвращает гиперболический тангенс <code>x</code> в радианах </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>math.trunc(x)</code> </td> <td align=\"left\"> Возвращает целую часть числа <code>x</code> в виде значения типа <code>int</code>; то же самое что и <code>int(x)</code> </td> </tr>\n",
|
||
"</tbody>\n",
|
||
"</table>\n",
|
||
"\n",
|
||
"\n",
|
||
"## Комплексные числа\n",
|
||
"<div id=\"datatype:float:complex\"></div>\n",
|
||
"\n",
|
||
"Тип данных `complex` относится к категории неизменяемых и хранит пару\n",
|
||
"значений типа `float`, одно из которых представляет действительную\n",
|
||
"часть комплексного числа, а другое – мнимую. Литералы комплексных\n",
|
||
"чисел записываются как действительная и мнимая части, объединенные\n",
|
||
"знаком `+` или `-`, а за мнимой частью числа следует символ `j`.\n",
|
||
"Вот примеры нескольких комплексных чисел: `3.5+2j`, `0.5j`, `4+0j`,\n",
|
||
"`-1 - 3.7j`. Обратите внимание, что если действительная часть числа\n",
|
||
"равна `0`, ее можно вообще опустить.\n",
|
||
"\n",
|
||
"Отдельные части комплексного числа доступны в виде атрибутов `real`\n",
|
||
"и `imag`. Например:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 31,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"z = -89.5+2.125j\n",
|
||
"z.real, z.imag"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"За исключением `//`, `%`, `divmod()` и версии `pow()` с тремя\n",
|
||
"аргументами все остальные арифметические операторы и функции,\n",
|
||
"перечисленные в табл. [Таблица 1 : Арифметические операторы и функции](#datatype:tbl:1) могут использоваться для\n",
|
||
"работы с комплексными числами, так же как и соответствующие\n",
|
||
"комбинированные операторы присваивания. Кроме того, значения типа\n",
|
||
"`complex` имеют метод `conjugate()`, который изменяет знак мнимой\n",
|
||
"части. Например:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 32,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"z.conjugate()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 33,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"3-4j.conjugate()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Тип данных `complex` может вызываться как функция – без аргументов\n",
|
||
"она вернет значение `0j`, с аргументом типа `complex` она вернет копию\n",
|
||
"аргумента, а с аргументом любого другого типа она попытается\n",
|
||
"преобразовать указанный объект в значение типа `complex`. При\n",
|
||
"использовании для преобразования функция `complex()` принимает либо\n",
|
||
"единственный строковый аргумент, либо одно или два значения типа\n",
|
||
"`float`.\n",
|
||
"\n",
|
||
"Если ей передается единственное значение типа `float`, возвращается\n",
|
||
"комплексное число с мнимой частью, равной `0j`.\n",
|
||
"\n",
|
||
"Функции в модуле `math` не работают с комплексными числами. Это\n",
|
||
"сделано преднамеренно, чтобы гарантировать, что пользователи модуля \n",
|
||
"`math` будут получать исключения вместо получения комплексных чисел в\n",
|
||
"некоторых случаях.\n",
|
||
"\n",
|
||
"Если возникает необходимость использовать комплексные числа,\n",
|
||
"можно воспользоваться модулем `cmath`, который содержит комплексные\n",
|
||
"версии большинства тригонометрических и логарифмических функций,\n",
|
||
"присутствующих в модуле math, плюс ряд функций, специально\n",
|
||
"предназначенных для работы с комплексными числами, таких \n",
|
||
"как `cmath.phase()`, `cmath.polar()` и `cmath.rect()`, а также\n",
|
||
"константы `cmath.pi` и `cmath.e`, которые хранят те же самые значения\n",
|
||
"типа `float`, что и родственные им константы в модуле `math`.\n",
|
||
"\n",
|
||
"## Числа типа `Decimal`\n",
|
||
"<div id=\"datatype:float:decimal\"></div>\n",
|
||
"\n",
|
||
"Во многих приложениях недостаток точности, свойственный числам\n",
|
||
"типа `float`, не имеет существенного значения, и эта неточность\n",
|
||
"окупается скоростью вычислений. Но в некоторых случаях предпочтение \n",
|
||
"отдается точности, даже в обмен на снижение скорости работы. Модуль\n",
|
||
"`decimal` реализует неизменяемый числовой тип `Decimal`, который\n",
|
||
"представляет числа с задаваемой точностью. Вычисления с участием \n",
|
||
"таких чисел производятся значительно медленнее, чем в случае\n",
|
||
"использования значений типа `float`, но насколько это важно, будет\n",
|
||
"зависеть от приложения.\n",
|
||
"\n",
|
||
"Чтобы создать объект типа `Decimal`, необходимо импортировать модуль\n",
|
||
"`decimal`. Например:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 34,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"import decimal\n",
|
||
"a = decimal.Decimal(9876)\n",
|
||
"b = decimal.Decimal(\"54321.012345678987654321\")\n",
|
||
"a + b"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
|
||
"<!-- doconce-section-nickname: \"float\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"# Строки\n",
|
||
"<div id=\"datatype:strings\"></div>\n",
|
||
"\n",
|
||
"Строки в языке Python представлены неизменяемым типом данных `str`,\n",
|
||
"который хранит последовательность символов Юникода. Тип данных `str`\n",
|
||
"может вызываться как функция для создания строковых объектов – без\n",
|
||
"аргументов возвращается пустая строка; с аргументом, который не\n",
|
||
"является строкой, возвращается строковое представление аргумента; а в\n",
|
||
"случае, когда аргумент является строкой, возвращается его\n",
|
||
"копия. Функция `str()` может также использоваться как функция\n",
|
||
"преобразования. В этом случае первый аргумент должен быть строкой или\n",
|
||
"объектом, который можно преобразовать в строку, а, кроме того, функции\n",
|
||
"может быть передано до двух необязательных строковых аргументов, один\n",
|
||
"из которых определяет используемую кодировку, а второй определяет\n",
|
||
"порядок обработки ошибок кодирования.\n",
|
||
"\n",
|
||
"Литералы строк создаются с использованием кавычек или апострофов, при\n",
|
||
"этом важно, чтобы с обоих концов литерала использовались кавычки\n",
|
||
"одного и того же типа. В дополнение к этому мы можем использовать\n",
|
||
"строки в тройных кавычках, то есть строки, которые начинаются и\n",
|
||
"заканчиваются тремя символами кавычки (либо тремя кавычками, либо\n",
|
||
"тремя апострофами). Например:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 35,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"text = \"\"\"Строки в тройных кавычках могут включать 'апострофы' и \"кавычки\"\n",
|
||
"без лишних формальностей. Мы можем даже экранировать символ перевода строки \\,\n",
|
||
"благодаря чему данная конкретная строка будет занимать всего две строки.\"\"\""
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Если нам потребуется использовать кавычки в строке, это можно сделать\n",
|
||
"без лишних формальностей – при условии, что они отличаются от кавычек,\n",
|
||
"ограничивающих строку; в противном случае символы кавычек или\n",
|
||
"апострофов внутри строки следует экранировать:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 36,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = \"Здесь 'апострофы' можно не экранировать, а \\\"кавычки\\\" придется.\"\n",
|
||
"b = 'Здесь \\'апострофы\\' придется экранировать, а \"кавычки\" не обязательно.'"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"В языке Python символ перевода строки интерпретируется как завершающий\n",
|
||
"символ инструкции, но не внутри круглых скобок (`()`), квадратных\n",
|
||
"скобок (`[]`), фигурных скобок (`{}`) и строк в тройных кавычках. \n",
|
||
"Символы перевода строки могут без лишних формальностей использоваться\n",
|
||
"в строках в тройных кавычках, и мы можем включать символы перевода\n",
|
||
"строки в любые строковые литералы с помощью экранированной\n",
|
||
"последовательности `\\n`.\n",
|
||
"\n",
|
||
"Все экранированные последовательности, допустимые в языке Python,\n",
|
||
"перечислены в табл. 2.6.\n",
|
||
"\n",
|
||
"\n",
|
||
"## Таблица 5 : Функции и константы модуля `math` <div id=\"datatype:tbl:5\"></div>\n",
|
||
"\n",
|
||
"\n",
|
||
"<table border=\"1\">\n",
|
||
"<thead>\n",
|
||
"<tr><th align=\"left\">Последовательность</th> <th align=\"left\"> Значение </th> </tr>\n",
|
||
"</thead>\n",
|
||
"<tbody>\n",
|
||
"<tr><td align=\"left\"> <code>\\переводстроки</code> </td> <td align=\"left\"> Экранирует (то есть игнорирует) символ перевода строки </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\\\</code> </td> <td align=\"left\"> Символ обратного слеша (<code>\\</code>) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\'</code> </td> <td align=\"left\"> Апостроф (<code>'</code>) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\\"</code> </td> <td align=\"left\"> Кавычка (<code>\"</code>) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\a</code> </td> <td align=\"left\"> Символ ASCII «сигнал» (bell, BEL) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\b</code> </td> <td align=\"left\"> Символ ASCII «забой» (backspace, BS) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\f</code> </td> <td align=\"left\"> Символ ASCII «перевод формата» (formfeed, FF) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\n</code> </td> <td align=\"left\"> Символ ASCII «перевод строки» (linefeed, LF) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\N{название}</code> </td> <td align=\"left\"> Символ Юникода с заданным названием </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\ooo</code> </td> <td align=\"left\"> Символ с заданным восьмеричным кодом </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\r</code> </td> <td align=\"left\"> Символ ASCII «возврат каретки» (carriage return, CR) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\t</code> </td> <td align=\"left\"> Символ ASCII «табуляция» (tab, TAB) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\uhhhh</code> </td> <td align=\"left\"> Символ Юникода с указанным 16-битовым шестнадцатеричным значением </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\Uhhhhhhhh</code> </td> <td align=\"left\"> Символ Юникода с указанным 32-битовым шестнадцатеричным значением </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\v</code> </td> <td align=\"left\"> Символ ASCII «вертикальная табуляция» (vertical tab, VT) </td> </tr>\n",
|
||
"<tr><td align=\"left\"> <code>\\xhh</code> </td> <td align=\"left\"> Символ с указанным 8-битовым шестнадцатеричным значением </td> </tr>\n",
|
||
"</tbody>\n",
|
||
"</table>\n",
|
||
"\n",
|
||
"\n",
|
||
"Если потребуется записать длинный строковый литерал, занимающий\n",
|
||
"две или более строк, но без использования тройных кавычек, то можно\n",
|
||
"использовать один из приемов, показанных ниже:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 37,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"t = \"Это не самый лучший способ объединения двух длинных строк, \" + \\\n",
|
||
" \"потому что он основан на использовании неуклюжего экранирования\"\n",
|
||
"s = (\"Это отличный способ объединить две длинные строки, \"\n",
|
||
" \" потому что он основан на конкатенации строковых литералов.\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Обратите внимание, что во втором случае для создания единственного\n",
|
||
"выражения мы должны были использовать круглые скобки – без этих\n",
|
||
"скобок переменной s была бы присвоена только первая строка, а наличие\n",
|
||
"второй строки вызвало бы исключение `IndentationError`. \n",
|
||
"\n",
|
||
"## Сравнение строк\n",
|
||
"<div id=\"datatype:strings:compare\"></div>\n",
|
||
"\n",
|
||
"Строки поддерживают обычные операторы сравнения `<`, `<=`, `==`, `!=`,\n",
|
||
"`>` и `>=`. Эти операторы выполняют побайтовое сравнение строк в памяти.\n",
|
||
"К сожалению, возникают две проблемы при сравнении, например,\n",
|
||
"строк в отсортированных списках. Обе проблемы проявляются во всех\n",
|
||
"языках программирования и не являются характерной особенностью\n",
|
||
"Python.\n",
|
||
"\n",
|
||
"Первая проблема связана с тем, что символы Юникода могут быть\n",
|
||
"представлены двумя и более последовательностями байтов.\n",
|
||
"\n",
|
||
"Вторая проблема заключается в том, что порядок сортировки некоторых\n",
|
||
"символов зависит от конкретного языка.\n",
|
||
"\n",
|
||
"## Получение срезов строк\n",
|
||
"<div id=\"datatype:strings:slices\"></div>\n",
|
||
"\n",
|
||
"Отдельные элементы последовательности, а, следовательно, и отдельные\n",
|
||
"символы в строках, могут извлекаться с помощью оператора доступа к\n",
|
||
"элементам (`[]`). В действительности этот оператор намного более\n",
|
||
"универсальный и может использоваться для извлечения не только одного\n",
|
||
"символа, но и целых комбинаций (подпоследовательностей) элементов или\n",
|
||
"символов, когда этот оператор используется в контексте оператора\n",
|
||
"извлечения среза.\n",
|
||
"\n",
|
||
"Для начала мы рассмотрим возможность извлечения отдельных\n",
|
||
"символов. Нумерация позиций символов в строках начинается с 0 и\n",
|
||
"продолжается до значений длины строки минус 1. Однако допускается\n",
|
||
"использовать и отрицательные индексы – в этом случае отсчет начинается\n",
|
||
"с последнего символа и ведется в обратном направлении к первому \n",
|
||
"символу. На рис. [datatype:strings:fig:1](#datatype:strings:fig:1) показано, как нумеруются\n",
|
||
"позиции символов в строке, если предположить, что было выполнено\n",
|
||
"присваивание `s = \"Light ray\"`. \n",
|
||
"\n",
|
||
"<!-- dom:FIGURE: [fig-datatype/strings_1.png, width=600 frac=1.0] Номера позиций символов в строке <div id=\"datatype:strings:fig:1\"></div> -->\n",
|
||
"<!-- begin figure -->\n",
|
||
"<div id=\"datatype:strings:fig:1\"></div>\n",
|
||
"<!-- end figure -->\n",
|
||
"\n",
|
||
"\n",
|
||
"Отрицательные индексы удивительно удобны, особенно индекс `-1`,\n",
|
||
"который всегда соответствует последнему символу строки. Попытка\n",
|
||
"обращения к индексу, находящемуся за пределами строки (или к любому\n",
|
||
"индексу в пустой строке), будет вызывать исключение `IndexError`.\n",
|
||
"Оператор получения среза имеет три формы записи:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"```Python\n",
|
||
" seq[start]\n",
|
||
" seq[start:end]\n",
|
||
" seq[start:end:step]\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Ссылка `seq` может представлять любую последовательность, такую как\n",
|
||
"список, строку или кортеж. Значения `start`, `end` и `step` должны быть\n",
|
||
"целыми числами (или переменными, хранящими целые числа). Первая форма\n",
|
||
"— это запись оператора доступа к элементам: с ее помощью извлекается\n",
|
||
"элемент последовательности с индексом `start`. Вторая форма записи\n",
|
||
"извлекает подстроку, начиная с элемента с индексом `start` и заканчивая\n",
|
||
"элементом с индексом `end`, *не включая* его.\n",
|
||
"\n",
|
||
"При использовании второй формы записи (с одним двоеточием) мы можем\n",
|
||
"опустить любой из индексов. Если опустить начальный индекс, по\n",
|
||
"умолчанию будет использоваться значение `0`. Если опустить конечный\n",
|
||
"индекс, по умолчанию будет использоваться значение `len(seq)`. \n",
|
||
"Это означает, что если опустить оба индекса, например, `s[:]`, это будет\n",
|
||
"равносильно выражению `s[0:len(s)]`, и в результате будет извлечена,\n",
|
||
"то есть скопирована, последовательность целиком.\n",
|
||
"\n",
|
||
"На рис. [datatype:strings:fig:2](#datatype:strings:fig:2) приводятся некоторые примеры\n",
|
||
"извлечения срезов из строки `s`, которая получена в результате\n",
|
||
"присваивания `s = \"The waxwork man\"`.\n",
|
||
"\n",
|
||
"<!-- dom:FIGURE: [fig-datatype/strings_2.png, width=600 frac=1.0] Извлечение срезов из последовательности <div id=\"datatype:strings:fig:2\"></div> -->\n",
|
||
"<!-- begin figure -->\n",
|
||
"<div id=\"datatype:strings:fig:2\"></div>\n",
|
||
"<!-- end figure -->\n",
|
||
"\n",
|
||
"\n",
|
||
"Один из способов вставить подстроку в строку состоит в смешивании\n",
|
||
"операторов извлечения среза и операторов конкатенации. Например:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 38,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"s = s[:12] + \"wo\" + s[12:]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 39,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"s"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Кроме того, поскольку текст «wo» присутствует в оригинальной строке,\n",
|
||
"тот же самый эффект можно было бы получить путем присваивания значения\n",
|
||
"выражения `s[:12] + s[7:9] + s[12:]`.\n",
|
||
"\n",
|
||
"Оператор конкатенации `+` и добавления подстроки `+=` не\n",
|
||
"особенно эффективны, когда в операции участвует множество строк. Для\n",
|
||
"объединения большого числа строк обычно лучше использовать метод\n",
|
||
"`str.join()`, с которым мы познакомимся в следующем подразделе.\n",
|
||
"\n",
|
||
"Третья форма записи (с двумя двоеточиями) напоминает вторую форму, но\n",
|
||
"в отличие от нее значение `step` определяет, с каким шагом следует\n",
|
||
"извлекать символы. Как и при использовании второй формы записи, мы\n",
|
||
"можем опустить любой из индексов. Если опустить начальный \n",
|
||
"индекс, по умолчанию будет использоваться значение `0`, при условии,\n",
|
||
"что задано неотрицательное значение step; в противном случае начальный\n",
|
||
"индекс по умолчанию получит значение `-1`. Если опустить конечный\n",
|
||
"индекс, по умолчанию будет использоваться значение `len(seq)`, \n",
|
||
"при условии, что задано неотрицательное значение step; в противном\n",
|
||
"случае конечный индекс по умолчанию получит значение индекса перед\n",
|
||
"началом строки. Мы не можем опустить значение step, и оно не может\n",
|
||
"быть равно нулю – если задание шага не требуется, то следует\n",
|
||
"использовать вторую форму записи (с одним двоеточием), в которой шаг \n",
|
||
"выбора элементов не указывается.\n",
|
||
"\n",
|
||
"На рис. [datatype:strings:fig:3](#datatype:strings:fig:3) приводится пара примеров извлечения разреженных срезов из\n",
|
||
"строки `s`, которая получена в результате присваивания\n",
|
||
"`s = \"he ate camel food\"`.\n",
|
||
"\n",
|
||
"<!-- dom:FIGURE: [fig-datatype/strings_3.png, width=600 frac=1.0] Извлечение разреженных срезов <div id=\"datatype:strings:fig:3\"></div> -->\n",
|
||
"<!-- begin figure -->\n",
|
||
"<div id=\"datatype:strings:fig:3\"></div>\n",
|
||
"<!-- end figure -->\n",
|
||
"\n",
|
||
"\n",
|
||
"Здесь мы использовали значения по умолчанию для начального и ко-\n",
|
||
"нечного индексов, то есть извлечение среза s[:: – 2] начинается с по-\n",
|
||
"следнего символа строки и извлекается каждый второй символ по на-\n",
|
||
"правлению к началу строки. Аналогично извлечение среза s[::3] на-\n",
|
||
"чинается с первого символа строки и извлекается каждый третий сим-\n",
|
||
"вол по направлению к концу строки.\n",
|
||
"Существует возможность комбинировать индексы с размером шага,\n",
|
||
"как показано на рис. [datatype:strings:fig:4](#datatype:strings:fig:4).\n",
|
||
"\n",
|
||
"<!-- dom:FIGURE: [fig-datatype/strings_4.png, width=800 frac=1.0] Извлечение срезов из последовательности с определенным шагом <div id=\"datatype:strings:fig:4\"></div> -->\n",
|
||
"<!-- begin figure -->\n",
|
||
"<div id=\"datatype:strings:fig:4\"></div>\n",
|
||
"<!-- end figure -->\n",
|
||
"\n",
|
||
"\n",
|
||
"Операция извлечения элементов с определенным шагом часто применяется к\n",
|
||
"последовательностям, отличным от строк, но один из ее вариантов часто\n",
|
||
"применяется к строкам:\n",
|
||
"\n",
|
||
"## Операторы и методы строк\n",
|
||
"<div id=\"datatype:strings:operat\"></div>\n",
|
||
"\n",
|
||
"Поскольку строки относятся к категории неизменяемых\n",
|
||
"последовательностей, все функциональные возможности, применимые к\n",
|
||
"неизменяемым последовательностям, могут использоваться и со\n",
|
||
"строками. Сюда входят оператор проверки на вхождение `in`, оператор\n",
|
||
"конкатенации `+`, оператор добавления в конец `+=`, оператор\n",
|
||
"дублирования `*` и комбинированный оператор присваивания с\n",
|
||
"дублированием `*=`. Применение всех этих операторов в контексте строк\n",
|
||
"мы обсудим в этом подразделе, а также обсудим большинство строковых\n",
|
||
"методов. В табл. 2.7 приводится перечень некоторых строковых методов.\n",
|
||
"\n",
|
||
"Так как строки являются последовательностями, они являются объектами,\n",
|
||
"имеющими «размер», и поэтому мы можем вызывать функцию `len()`,\n",
|
||
"передавая ей строки в качестве аргумента. Возвращаемая функцией длина\n",
|
||
"представляет собой количество символов в строке (ноль – для пустых\n",
|
||
"строк).\n",
|
||
"\n",
|
||
"Мы уже знаем, что перегруженная версия оператора `+` для строк\n",
|
||
"выполняет операцию конкатенации. В случаях, когда требуется объединить\n",
|
||
"множество строк, лучше использовать метод `str.join()`. Метод \n",
|
||
"принимает в качестве аргумента последовательность (то есть список\n",
|
||
"или кортеж строк) и объединяет их в единую строку, вставляя между\n",
|
||
"ними строку, относительно которой был вызван метод. Например:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 40,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"treatises = [\"Arithmetica\", \"Conics\", \"Elements\"]\n",
|
||
"\" \".join(treatises)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 41,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"\"-<>-\".join(treatises)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 42,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"\"\".join(treatises)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Метод `str.join()` может также использоваться в комбинации со\n",
|
||
"встроенной функцией `reversed()`, которая переворачивает строку –\n",
|
||
"например, `\"\".join(reversed(s))`, хотя тот же результат может быть\n",
|
||
"получен более кратким оператором извлечения разреженного среза –\n",
|
||
"например, `s[:: – 1]`.\n",
|
||
"\n",
|
||
"Оператор `*` обеспечивает возможность дублирования строки:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 43,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"s = \"=\" * 5\n",
|
||
"print(s)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 44,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"s *= 10\n",
|
||
"print(s)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Как показано в примере, мы можем также использовать комбинированный\n",
|
||
"оператор присваивания с дублированием. \n",
|
||
"\n",
|
||
"## Форматирование строк с помощью метода `str.format()`\n",
|
||
"<div id=\"datatype:strings:format\"></div>\n",
|
||
"\n",
|
||
"Метод `str.format()` представляет собой очень мощное и гибкое средство\n",
|
||
"создания строк. Использование метода `str.format()` в простых случаях\n",
|
||
"не вызывает сложностей, но для более сложного форматирования нам\n",
|
||
"необходимо изучить синтаксис форматирования.\n",
|
||
"\n",
|
||
"Метод `str.format()` возвращает новую строку, замещая поля в\n",
|
||
"контекстной строке соответствующими аргументами. Например:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 45,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"\"The novel '{0}' was published in {1}\".format(\"Hard Times\", 1854)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Каждое замещаемое поле идентифицируется именем поля в фигурных\n",
|
||
"скобках. Если в качестве имени поля используется целое число, оно\n",
|
||
"определяет порядковый номер аргумента, переданного методу\n",
|
||
"`str.format()`. Поэтому в данном случае поле с именем `0` было замещено\n",
|
||
"первым аргументом, а поле с именем `1` – вторым аргументом. \n",
|
||
"\n",
|
||
"Если бы нам потребовалось включить фигурные скобки в строку формата,\n",
|
||
"мы могли бы сделать это, дублируя их, как показано ниже:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 46,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"\"{{{0}}} {1} ;-}}\".format(\"I'm in braces\", \"I'm not\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Если попытаться объединить строку и число, интерпретатор Python\n",
|
||
"совершенно справедливо возбудит исключение `TypeError`. Но это легко\n",
|
||
"можно сделать с помощью метода `str.format()`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 47,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"\"{0}{1}\".format(\"The amount due is $\", 200)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"С помощью `str.format()` мы также легко можем объединять строки\n",
|
||
"(хотя для этой цели лучше подходит метод `str.join()`):"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 48,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"x = \"three\"\n",
|
||
"s =\"{0} {1} {2}\"\n",
|
||
"s = s.format(\"The\", x, \"tops\")\n",
|
||
"s"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"В следующем разделе мы рассмотрим применение функции `str.format()`.\n",
|
||
"\n",
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
|
||
"<!-- doconce-section-nickname: \"strings\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"# Примеры\n",
|
||
"<div id=\"datatype:examples\"></div>\n",
|
||
"\n",
|
||
"## Печать символов Юникода\n",
|
||
"<div id=\"datatype:examples:print-unicode\"></div>\n",
|
||
"\n",
|
||
"Рассмотрим небольшой, но достаточно поучительный пример использования\n",
|
||
"метода `str.format()`, в котором мы увидим применение спецификаторов\n",
|
||
"формата в реальном контексте. Программа, состоящая всего из 25 строк\n",
|
||
"выполняемого кода, находится в файле\n",
|
||
"[print_unicode.py](src-datatype/print_unicode.py). Она импортирует\n",
|
||
"два модуля, `sys` и `unicodedata` и определяет одну функцию –\n",
|
||
"`print_unicode_table()`. Рассмотрение примера мы начнем\n",
|
||
"с запуска программы, чтобы увидеть, что она делает; затем мы\n",
|
||
"рассмотрим программный код в конце программы, где выполняется вся\n",
|
||
"фактическая работа; и в заключение рассмотрим функцию, определяемую в\n",
|
||
"программе."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 49,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"%run src-datatype/print_unnicode.py Spoked"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"При запуске без аргументов программа выводит таблицу всех символов\n",
|
||
"Юникода, начиная с пробела и до символа с наибольшим возможным\n",
|
||
"кодом. При запуске с аргументом, как показано в примере, выводятся \n",
|
||
"только те строки таблицы, где в названии символов Юникода содержится\n",
|
||
"значение строки-аргумента, переведенной в нижний регистр.\n",
|
||
"\n",
|
||
"Разберем исходный код программы:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 50,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Start main script\n",
|
||
"word = None\n",
|
||
"\n",
|
||
"if len(sys.argv) > 1:\n",
|
||
" if sys.argv[1] in (\"-h\", \"--help\"):\n",
|
||
" print(\"usage: {0} [string]\".format(sys.argv[0]))\n",
|
||
" word = 0\n",
|
||
" else:\n",
|
||
" word = sys.argv[1].lower()\n",
|
||
"\n",
|
||
"if word != 0:\n",
|
||
" print_unicode_table(word)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"После инструкций импортирования и определения функции\n",
|
||
"`print_unicode_table()` выполнение достигает программного кода,\n",
|
||
"показанного выше. Сначала предположим, что пользователь не указал в\n",
|
||
"командной строке искомое слово. Если аргумент командной строки\n",
|
||
"присутствует и это `-h` или `--help`, программа выводит информацию о\n",
|
||
"порядке использования и устанавливает флаг `word` в значение `0`, указывая\n",
|
||
"тем самым, что работа завершена. В противном случае в переменную `word`\n",
|
||
"записывается копия аргумента, введенного пользователем, с\n",
|
||
"преобразованием всех символов в нижний регистр. Если значение `word` не\n",
|
||
"равно `0`, программа выводит таблицу.\n",
|
||
"\n",
|
||
"При выводе информации о порядке использования применяется спецификатор\n",
|
||
"формата, который представляет собой простое имя формата, в данном\n",
|
||
"случае – порядковый номер позиционного аргумента. Мы могли бы записать\n",
|
||
"эту строку, как показано ниже:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 51,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(\"usage: {0[0]} [string]\".format(sys.argv))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"При таком подходе первый символ `0` соответствует порядковому номеру\n",
|
||
"позиционного аргумента, а `[0]` — это индекс элемента внутри\n",
|
||
"аргумента, и такой прием сработает, потому что `sys.argv` является\n",
|
||
"списком."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 52,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def print_unicode_table(word):\n",
|
||
" print(\"decimal hex chr {0:^40}\".format(\"name\"))\n",
|
||
" print(\"------- ----- --- {0:-<40}\".format(\"\"))\n",
|
||
"\n",
|
||
" code = ord(\" \")\n",
|
||
" end = sys.maxunicode\n",
|
||
"\n",
|
||
" while code < end:\n",
|
||
" c = chr(code)\n",
|
||
" name = unicodedata.name(c, \"*** unknown ***\")\n",
|
||
" if word is None or word in name.lower():\n",
|
||
" print(\"{0:7} {0:5X} {0:^3c} {1}\".format(code, name.title()))\n",
|
||
" code += 1"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Первый вызов `str.format()` выводит текст `\"name\"`, отцентрированный в\n",
|
||
"поле вывода, шириной 40 символов, а второй вызов выводит пустую строку\n",
|
||
"в поле шириной 40 символов, используя символ `-` в качестве\n",
|
||
"символа-заполнителя, с выравниванием по левому краю. \n",
|
||
"\n",
|
||
"Как вариант, вторую строку функции можно было записать, как показано ниже:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 53,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(\"------- ----- --- {0}\".format(\"-\" * 40))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Здесь мы использовали оператор дублирования строки (`*`), чтобы\n",
|
||
"создать необходимую строку, и просто вставили ее в строку формата.\n",
|
||
"\n",
|
||
"Текущий код символа Юникода сохраняется в переменной `code`, которая\n",
|
||
"инициализируется кодом пробела (`0x20`). В переменную end записывается\n",
|
||
"максимально возможный код символа Юникода, который может принимать\n",
|
||
"разные значения в зависимости от того, какая из кодировок\n",
|
||
"использовалась при компиляции Python.\n",
|
||
"\n",
|
||
"Внутри цикла `while` с помощью функции `chr()` мы получаем символ\n",
|
||
"Юникода, соответствующий числовому коду. Функция `unicodedata.name()`\n",
|
||
"возвращает название заданного символа Юникода, во втором\n",
|
||
"необязательном аргументе передается имя, которое будет использовано в\n",
|
||
"случае, когда имя символа не определено. \n",
|
||
"\n",
|
||
"Если пользователь не указывает аргумент командной строки (`word is None`)\n",
|
||
"или аргумент был указан и он входит в состав копии имени символа\n",
|
||
"Юникода, в которой все символы приведены к нижнему регистру, то\n",
|
||
"выводится соответствующая строка таблицы. \n",
|
||
"\n",
|
||
"Мы передаем переменную `code` методу `str.format()` один раз, но в\n",
|
||
"строке формата она используется трижды. Первый раз – при выводе\n",
|
||
"значения `code` как целого числа в поле с шириной 7 символов (по\n",
|
||
"умолчанию в качестве символа-заполнителя используется пробел, поэтому\n",
|
||
"нет необходимости явно указывать его). Второй раз – при выводе\n",
|
||
"значения `code` как целого числа в шестнадцатеричном формате символами\n",
|
||
"верхнего регистра в поле шириной 5 символов. И третий раз – при выводе \n",
|
||
"символа Юникода, соответствующего значению code, с помощью\n",
|
||
"спецификатора формата `c`, отцентрированного в поле с минимальной \n",
|
||
"шириной 3 символа. Обратите внимание, что нам не потребовалось\n",
|
||
"указывать тип `d` в первом спецификаторе формата, потому что он\n",
|
||
"подразумевается по умолчанию для целых чисел. Второй аргумент –\n",
|
||
"это имя символа Юникода, которое выводится с помощью метода\n",
|
||
"`str.title()`, в результате которого первый символ каждого слова\n",
|
||
"преобразуется к верхнему регистру, а остальные символы – к нижнему. \n",
|
||
"\n",
|
||
"\n",
|
||
"## Решение квадратного уравнения\n",
|
||
"<div id=\"datatype:examples:quadratic\"></div>\n",
|
||
"\n",
|
||
"Квадратные уравнения – это уравнения вида $ax^2 + bx + c = 0$, где $a \\ne 0$,\n",
|
||
"описывающие параболу. Корни таких уравнений находятся по формуле"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"$$\n",
|
||
"x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}.\n",
|
||
"$$"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Часть формулы $b^2 – 4ac$ называется дискриминантом – если это\n",
|
||
"положительная величина, уравнение имеет два действительных корня, если\n",
|
||
"дискриминант равен нулю – уравнение имеет один действительный корень,\n",
|
||
"и в случае отрицательного значения уравнение имеет два комплексных\n",
|
||
"корня. Мы напишем программу, которая будет принимать от пользователя\n",
|
||
"коэффициенты $a$, $b$ и $c$ (коэффициенты $b$ и c могут быть равны\n",
|
||
"нулю) и затем вычислять и выводить его корень или корни.\n",
|
||
"\n",
|
||
"\n",
|
||
"Для начала посмотрим, как работает программа:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"С коэффициентами $1.5$, $-3$ и $6$ программа выведет (некоторые цифры\n",
|
||
"обрезаны):\n",
|
||
"\n",
|
||
"Теперь обратимся к [программному коду](src-datatype/quadratic.py),\n",
|
||
"который начинается тремя инструкциями `import`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 54,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"import cmath\n",
|
||
"import math\n",
|
||
"import sys"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Нам необходимы обе математические библиотеки для работы с числами типа\n",
|
||
"`float` и `complex`, так как функции, вычисляющие квадратный \n",
|
||
"корень из вещественных и комплексных чисел, отличаются. Модуль\n",
|
||
"`sys` нам необходим, так как в нем определена константа\n",
|
||
"`sys.float_info.epsilon`, которая потребуется нам для сравнения\n",
|
||
"вещественных чисел со значением `0`.\n",
|
||
"\n",
|
||
"Нам также необходима функция, которая будет получать от пользова-\n",
|
||
"теля число с плавающей точкой:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 55,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def get_float(msg, allow_zero):\n",
|
||
" x = None\n",
|
||
" while x is None:\n",
|
||
" try:\n",
|
||
" x = float(input(msg))\n",
|
||
" if not allow_zero and abs(x) < sys.float_info.epsilon:\n",
|
||
" print(\"zero is not allowed\")\n",
|
||
" x = None\n",
|
||
"\n",
|
||
" except ValueError as err:\n",
|
||
" print(err)\n",
|
||
" return x"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Эта функция выполняет цикл, пока пользователь не введет допустимое\n",
|
||
"число с плавающей точкой (например, `0.5`, `-9`, `21`, `4.92`), и допускает\n",
|
||
"ввод значения `0`, только если аргумент `allow_zero` имеет значение `True`.\n",
|
||
"Вслед за определением функции `get_float()` выполняется оставшаяся\n",
|
||
"часть программного кода. Мы разделим его на три части и начнем со\n",
|
||
"взаимодействия с пользователем:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 56,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(\"ax\\N{SUPERSCRIPT TWO} + bx + c = 0\")\n",
|
||
"a = get_float(\"enter a: \", False)\n",
|
||
"b = get_float(\"enter b: \", False)\n",
|
||
"c = get_float(\"enter c: \", False)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Благодаря функции `get_float()` получить значения коэффициентов `a`,\n",
|
||
"`b` и `c` оказалось очень просто. Второй аргумент функции сообщает, когда\n",
|
||
"значение `0` является допустимым."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 57,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"x1 = None\n",
|
||
"x2 = None\n",
|
||
"discriminant = (b ** 2) - (4 * a * c)\n",
|
||
"if discriminant == 0:\n",
|
||
" x1 = -(b / (2 * a))\n",
|
||
"else:\n",
|
||
" if discriminant > 0:\n",
|
||
" root = math.sqrt(discriminant)\n",
|
||
" else: # discriminant < 0\n",
|
||
" root = cmath.sqrt(discriminant)\n",
|
||
" x1 = (-b + root) / (2 * a)\n",
|
||
" x2 = (-b - root) / (2 * a)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Программный код выглядит несколько иначе, чем формула, потому\n",
|
||
"что мы начали вычисления с определения значения дискриминанта.\n",
|
||
"Если дискриминант равен `0`, мы знаем, что уравнение имеет\n",
|
||
"единственное действительное решение и можно сразу же вычислить его. В\n",
|
||
"противном случае мы вычисляем действительный или комплексный\n",
|
||
"квадратный корень из дискриминанта и находим два корня уравнения."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 58,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"equation = (\"{0}x\\N{SUPERSCRIPT TWO} + {1}x + {2} = 0\"\n",
|
||
" \" \\N{RIGHTWARDS ARROW} x = {3}\").format(a, b, c, x1)\n",
|
||
"if x2 is not None:\n",
|
||
" equation += \" or x = {0}\".format(x2)\n",
|
||
"print(equation)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Мы не использовали сколько-нибудь сложного форматирования, поскольку\n",
|
||
"форматирование, используемое по умолчанию для чисел с плавающей точкой\n",
|
||
"в языке Python, прекрасно подходит для этого примера, но мы\n",
|
||
"использовали некоторые имена Юникода для вывода пары специальных\n",
|
||
"символов.\n",
|
||
"\n",
|
||
"## Представление таблицы `csv` в HTML\n",
|
||
"<div id=\"datatype:examples:csv2html\"></div>\n",
|
||
"\n",
|
||
"Часто бывает необходимо представить данные в формате HTML. В этом\n",
|
||
"подразделе мы разработаем программу, которая читает данные из\n",
|
||
"файла в простом формате CSV (Comma Separated Value – значения,\n",
|
||
"разделенные запятыми) и выводит таблицу HTML, содержащую эти\n",
|
||
"данные. В составе Python присутствует мощный и сложный модуль\n",
|
||
"для работы с форматом CSV и похожими на него – модуль csv, но здесь\n",
|
||
"мы будем выполнять всю обработку вручную.\n",
|
||
"\n",
|
||
"В формате CSV каждая запись располагается на одной строке, а поля\n",
|
||
"внутри записи отделяются друг от друга запятыми. Каждое поле может\n",
|
||
"быть либо строкой, либо числом. Строки должны окружаться апострофами\n",
|
||
"или кавычками, а числа не должны окружаться кавычками, если они не\n",
|
||
"содержат запятые. Внутри строк допускается присутствие запятых, и они\n",
|
||
"не должны интерпретироваться как разделители полей. Мы будем исходить\n",
|
||
"из предположения, что первая запись в файле содержит имена полей. На\n",
|
||
"выходе будет воспроизводиться таблица в формате HTML с выравниванием\n",
|
||
"текста по левому краю (по умолчанию для HTML) и с выравниванием чисел\n",
|
||
"по правому краю, по одной строке на запись и по одной ячейке на поле.\n",
|
||
"\n",
|
||
"Ниже приводится маленький фрагмент файла с данными:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
" \"COUNTRY\",2000,2001,2002,2003,2004\n",
|
||
" \"ANTIGUA AND BARBUDA\",0,0,0,0,0\n",
|
||
" \"ARGENTINA\",37,35,33,36,39\n",
|
||
" \"BAHAMAS, THE\",1,1,1,1,1\n",
|
||
" \"BAHRAIN\",5,6,6,6,6\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Предположим, что данные находятся в файле [sample.csv](src-datatype/sample.csv.txt) и выполнена комадна"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
" Terminal> python csv2html.py < sample.csv > sample.html\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"тогда файл [sample.html](src-datatype/sample.html) должен содержать\n",
|
||
"примерно следующее:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
" <table border='1'>\n",
|
||
" <tr bgcolor='lightgreen'>\n",
|
||
" <td>\"Country\"</td>\n",
|
||
" <td align='right'>2000</td>\n",
|
||
" <td align='right'>2001</td>\n",
|
||
" <td align='right'>2002</td>\n",
|
||
" <td align='right'>2003</td>\n",
|
||
" <td align='right'>2004</td>\n",
|
||
" </tr>\n",
|
||
" <tr bgcolor='white'>\n",
|
||
" <td>\"Antigua and Barbuda\"</td>\n",
|
||
" <td align='right'>0</td>\n",
|
||
" <td align='right'>0</td>\n",
|
||
" <td align='right'>0</td>\n",
|
||
" <td align='right'>0</td>\n",
|
||
" <td align='right'>0</td>\n",
|
||
" </tr>\n",
|
||
" <tr bgcolor='lightyellow'>\n",
|
||
" <td>\"Argentina\"</td>\n",
|
||
" <td align='right'>37</td>\n",
|
||
" <td align='right'>35</td>\n",
|
||
" <td align='right'>33</td>\n",
|
||
" <td align='right'>36</td>\n",
|
||
" <td align='right'>39</td>\n",
|
||
" </tr>\n",
|
||
" <tr bgcolor='white'>\n",
|
||
" <td>\"Bahamas, The\"</td>\n",
|
||
" <td align='right'>1</td>\n",
|
||
" <td align='right'>1</td>\n",
|
||
" <td align='right'>1</td>\n",
|
||
" <td align='right'>1</td>\n",
|
||
" <td align='right'>1</td>\n",
|
||
" </tr>\n",
|
||
" <tr bgcolor='lightyellow'>\n",
|
||
" <td>\"Bahrain\"</td>\n",
|
||
" <td align='right'>5</td>\n",
|
||
" <td align='right'>6</td>\n",
|
||
" <td align='right'>6</td>\n",
|
||
" <td align='right'>6</td>\n",
|
||
" <td align='right'>6</td>\n",
|
||
" </tr>\n",
|
||
" </table>\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"На рис. показано, как выглядит полученная таблица в веб-броузере.\n",
|
||
"\n",
|
||
"<!-- dom:FIGURE: [fig-datatype/example_1.png, width=400 frac=1.0] Таблица, произведенная программой [csv2html.py](src-datatype/csv2html.py), в броузере <div id=\"datatype:examples:fig:1\"></div> -->\n",
|
||
"<!-- begin figure -->\n",
|
||
"<div id=\"datatype:examples:fig:1\"></div>\n",
|
||
", в броузере](fig-datatype/example_1.png)<!-- end figure -->\n",
|
||
"\n",
|
||
"\n",
|
||
"Теперь, когда мы увидели, как используется программа и что она делает,\n",
|
||
"можно приступать к изучению программного кода.\n",
|
||
"\n",
|
||
"Последняя инструкция в программе – это простой вызов функции:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 59,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"main()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Хотя в языке Python не требуется явно указывать точку входа в\n",
|
||
"программу, как в некоторых других языках программирования, тем не\n",
|
||
"менее является распространенной практикой создание в программе на\n",
|
||
"языке Python функции с именем `main()`, которая вызывается для\n",
|
||
"выполнения обработки. Поскольку функция не может вызываться до того,\n",
|
||
"как она будет определена, мы должны вставлять вызов `main()` только\n",
|
||
"после того, как данная функция будет определена. Порядок следования\n",
|
||
"функций в файле (то есть порядок, в котором они создаются) не \n",
|
||
"имеет значения.\n",
|
||
"\n",
|
||
"В программе [csv2html.py](src-datatype/csv2html.py) первой\n",
|
||
"вызываемой функцией является функция `main()`, которая в свою очередь\n",
|
||
"вызывает функции `print_start()` и `print_line()`. Функция\n",
|
||
"`print_line()` вызывает функции `extract_fields()` и `escape_html()`.\n",
|
||
"\n",
|
||
"Когда интерпретатор Python читает файл, он начинает делать это с\n",
|
||
"самого начала. Поэтому сначала будет выполнен импорт (если он есть),\n",
|
||
"затем будет создана функция `main()`, а затем будут созданы остальные\n",
|
||
"функции – в том порядке, в каком они следуют в файле. Когда\n",
|
||
"интерпретатор, наконец, достигнет вызова `main()` в конце файла, все\n",
|
||
"функции, которые вызываются функцией `main()` (и все функции, которые\n",
|
||
"вызываются этими функциями), будут определены. Выполнение обработки,\n",
|
||
"как и следовало ожидать, начинается в точке вызова функции `main()`.\n",
|
||
"\n",
|
||
"Рассмотрим все функции по порядку, начиная с функции `main()`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 60,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def main():\n",
|
||
" maxwidth = 100\n",
|
||
" print_start()\n",
|
||
" count = 0\n",
|
||
" while True:\n",
|
||
" try:\n",
|
||
" line = input()\n",
|
||
" if count == 0:\n",
|
||
" color = \"lightgreen\"\n",
|
||
" elif count % 2:\n",
|
||
" color = \"white\"\n",
|
||
" else:\n",
|
||
" color = \"lightyellow\"\n",
|
||
" print_line(line, color, maxwidth)\n",
|
||
" count += 1\n",
|
||
" except EOFError:\n",
|
||
" break\n",
|
||
" print_end()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Переменная `maxwidth` используется для хранения числа символов в\n",
|
||
"ячейке. Если поле больше, чем это число, часть строки отсекается и на\n",
|
||
"место отброшенного текста добавляется многоточие. Программный код\n",
|
||
"функций `print_start()`, `print_line()` и `print_end()` будет приведен\n",
|
||
"чуть ниже. Цикл while выполняет обход всех входных строк – это могут\n",
|
||
"быть строки, вводимые пользователем с клавиатуры, но мы предполагаем,\n",
|
||
"что данные будут перенаправлены из файла. Далее выбирается цвет фона и\n",
|
||
"вызывается функция `print_line()`, которая выводит строку в виде строки\n",
|
||
"таблицы в формате HTML."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 61,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def print_start():\n",
|
||
" print(\"<table border='1'>\")\n",
|
||
"\n",
|
||
"def print_end():\n",
|
||
" print(\"</table>\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Мы могли бы не создавать эти две функции и просто вставить\n",
|
||
"соответствующие вызовы `print()` в функцию `main()`. Но мы предпочитаем\n",
|
||
"выделять логику, так как это делает реализацию более гибкой, хотя\n",
|
||
"в этом маленьком примере гибкость не имеет большого значения."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 62,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def print_line(line, color, maxwidth):\n",
|
||
" print(\"<tr bgcolor='{0}'>\".format(color))\n",
|
||
" fields = extract_fields(line)\n",
|
||
" for field in fields:\n",
|
||
" if not field:\n",
|
||
" print(\"<td></td>\")\n",
|
||
" else:\n",
|
||
" number = field.replace(\",\", \"\")\n",
|
||
" try:\n",
|
||
" x = float(number)\n",
|
||
" print(\"<td align='right'>{0:d}</td>\".format(round(x)))\n",
|
||
" except ValueError:\n",
|
||
" field = field.title()\n",
|
||
" field = field.replace(\" And \", \" and \")\n",
|
||
" field = escape_html(field)\n",
|
||
" if len(field) <= maxwidth:\n",
|
||
" print(\"<td>{0}</td>\".format(field))\n",
|
||
" else:\n",
|
||
" print(\"<td>{0:.{1}} ...</td>\".format(field, maxwidth))\n",
|
||
" print(\"</tr>\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Мы не можем использовать метод `str.split(\",\")` для разбиения каждой\n",
|
||
"строки на поля, потому что запятые могут находиться внутри строк в\n",
|
||
"кавычках. Поэтому мы возложили эту обязанность на функцию\n",
|
||
"`extract_fields()`. Получив список строк полей (в виде строк без\n",
|
||
"окружающих их кавычек), мы выполняем обход списка и создаем для \n",
|
||
"каждого поля ячейку таблицы.\n",
|
||
"\n",
|
||
"Если поле пустое, мы выводим пустую ячейку. Если поле было заключено в\n",
|
||
"кавычки, это может быть строка или число в кавычках, содержащее\n",
|
||
"символы запятой, например `\"1,566\"`. Учитывая такую возможность, мы\n",
|
||
"создаем копию поля без запятых и пытаемся преобразовать ее в число\n",
|
||
"типа `float`. Если преобразование удалось, мы определяем выравнивание\n",
|
||
"в ячейке по правому краю, а значение поля округляется до ближайшего\n",
|
||
"целого, которое и выводится. Если преобразование не удалось,\n",
|
||
"следовательно, поле содержит строку. В этом случае мы с помощью метода\n",
|
||
"`str.title()` изменяем регистр символов и замещаем слово «And» на слово\n",
|
||
"«and», устраняя побочный эффект действия метода \n",
|
||
"`str.title()`. Затем выполняется экранирование специальных символов\n",
|
||
"HTML и выводится либо поле целиком, либо первые `maxwidth` символов\n",
|
||
"с добавлением многоточия. Простейшей альтернативой использованию\n",
|
||
"вложенного поля замены в строке формата является получение \n",
|
||
"среза строки, например:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 63,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(\"<td>{0} ...</td>\".format(field[:maxwidth]))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Еще одно преимущество такого подхода состоит в том, что он требует\n",
|
||
"меньшего объема ввода с клавиатуры."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 64,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def extract_fields(line):\n",
|
||
" fields = []\n",
|
||
" field = \"\"\n",
|
||
" quote = None\n",
|
||
" for c in line:\n",
|
||
" if c in \"\\\"'\":\n",
|
||
" if quote is None: # начало строки в кавычках\n",
|
||
" quote = c\n",
|
||
" elif quote == c: # конец строки в кавычках\n",
|
||
" quote = None\n",
|
||
" else:\n",
|
||
" field += c\n",
|
||
" # другая кавычка внутри строки в кавычках\n",
|
||
" continue\n",
|
||
" if quote is None and c == \",\": # end of a field\n",
|
||
" fields.append(field)\n",
|
||
" field = \"\"\n",
|
||
" else:\n",
|
||
" field += c\n",
|
||
" # добавить символ в поле\n",
|
||
" if field:\n",
|
||
" fields.append(field) # добавить последнее поле в список\n",
|
||
" return fields"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Эта функция читает символы из строки один за другим и накапливает\n",
|
||
"список полей, где каждое поле – это строка без окружающих ее\n",
|
||
"кавычек. Функция способна обрабатывать поля, не заключенные в кавычки,\n",
|
||
"и поля, заключенные в кавычки или в апострофы, корректно обрабатывая\n",
|
||
"запятые и кавычки (апострофы в строках, заключенных в кавычки, и\n",
|
||
"кавычки в строках, заключенных в апострофы)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 65,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def escape_html(text):\n",
|
||
" text = text.replace(\"&\", \"&\")\n",
|
||
" text = text.replace(\"<\", \"<\")\n",
|
||
" text = text.replace(\">\", \">\")\n",
|
||
" return text"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Эта функция просто замещает каждый специальный символ HTML\n",
|
||
"соответствующей ему сущностью языка HTML. В первую очередь, конечно,\n",
|
||
"мы должны заменить символ амперсанда и угловые скобки, хотя порядок не\n",
|
||
"имеет никакого значения. \n",
|
||
"\n",
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
|
||
"<!-- doconce-section-nickname: \"examples\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"# Упражнения\n",
|
||
"<div id=\"datatype:exercises\"></div>\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- --- begin exercise --- -->\n",
|
||
"\n",
|
||
"## Изменение вывода символов Юникода\n",
|
||
"<div id=\"datatype:exercises:1\"></div>\n",
|
||
"\n",
|
||
"Измените программу `print_unicode.py` так, чтобы пользователь мог\n",
|
||
"вводить в командной строке несколько разных слов и получать\n",
|
||
"только те строки из таблицы символов Юникода, в которых содержатся все\n",
|
||
"слова, указанные пользователем. Это означает, что мы сможем вводить\n",
|
||
"такие команды:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 66,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"print_unicode_ans.py greek symbol"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<!-- --- begin hint in exercise --- -->\n",
|
||
"\n",
|
||
"**Подсказка.**\n",
|
||
"Один из способов достижения поставленной цели состоит в том,\n",
|
||
"чтобы заменить переменную `word` (которая может хранить `0`, `None` \n",
|
||
"или строку) списком `words`. Не забудьте изменить информацию о порядке\n",
|
||
"использования. В результате изменений не более десяти строк\n",
|
||
"программного кода добавится и не более десяти строк изменится.\n",
|
||
"\n",
|
||
"<!-- --- end hint in exercise --- -->\n",
|
||
"Имя файла: `print_unicode_ans.py`.\n",
|
||
"\n",
|
||
"<!-- --- end exercise --- -->\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- --- begin exercise --- -->\n",
|
||
"\n",
|
||
"## Изменение `quadratic.py`\n",
|
||
"<div id=\"datatype:exercises:2\"></div>\n",
|
||
"\n",
|
||
"Измените программу `quadratic.py` так, чтобы она не выводила\n",
|
||
"коэффициенты со значением `0.0`, а отрицательные коэффициенты\n",
|
||
"выводились бы как `-n`, а не `+ - n`.\n",
|
||
"Имя файла: `quadratic_ans.py`.\n",
|
||
"\n",
|
||
"<!-- --- end exercise --- -->\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- --- begin exercise --- -->\n",
|
||
"\n",
|
||
"## Использование функции `escape()`\n",
|
||
"<div id=\"datatype:exercises:escape\"></div>\n",
|
||
"\n",
|
||
"Удалите функцию `escape_html()` из программы `cvs2html.py` и\n",
|
||
"используйте вместо нее функцию `xml.sax.saxutils.escape()` из модуля \n",
|
||
"`xml.sax.saxutils`.\n",
|
||
"\n",
|
||
"<!-- --- begin hint in exercise --- -->\n",
|
||
"\n",
|
||
"**Подсказка.**\n",
|
||
"Для этого потребуется добавить одну новую строку\n",
|
||
"(с инструкцией `import`), удалить пять строк (с ненужной функцией)\n",
|
||
"и изменить одну строку (задействовать функцию\n",
|
||
"`xml.sax.saxutils.escape()` вместо `escape_html()`).\n",
|
||
"\n",
|
||
"<!-- --- end hint in exercise --- -->\n",
|
||
"Имя файла: `cvs2html_ans1.py`.\n",
|
||
"\n",
|
||
"<!-- --- end exercise --- -->\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- --- begin exercise --- -->\n",
|
||
"\n",
|
||
"## Добавление обработки параметров командной строки в `csv2html.py`\n",
|
||
"<div id=\"datatype:exercises:process_option\"></div>\n",
|
||
"\n",
|
||
"Измените программу `cvs2html.py` еще раз и добавьте в нее новую\n",
|
||
"функцию с именем `process_options()`. Эта функция должна вызываться из\n",
|
||
"функции main() и возвращать кортеж с двумя значениями: \n",
|
||
"`maxwidth` (типа `int`) и `format` (типа `str`). При вызове функция\n",
|
||
"`process_options()` должна устанавливать `maxwidth` в значение по\n",
|
||
"умолчанию `100`, а строку `format` – в значение по умолчанию `\".0f\"`,\n",
|
||
"которое будет использоваться как спецификатор формата при выводе чисел.\n",
|
||
"Если пользователь вводит в командной строке `-h` или `--help`,\n",
|
||
"должно выводиться сообщение о порядке использования и возвращаться\n",
|
||
"кортеж `(None, None)`. (В этом случае функция `main()` ничего\n",
|
||
"делать не должна.) В противном случае функция должна прочитать\n",
|
||
"аргументы командной строки и выполнить соответствующие\n",
|
||
"присваивания. Например, устанавливать значение переменной `maxwidth`,\n",
|
||
"если задан аргумент `maxwidth=n`, и точно так же устанавливать \n",
|
||
"значение переменной `format`, если задан аргумент `format=s`. Ниже\n",
|
||
"приводится сеанс работы с программой, когда пользователь затребовал\n",
|
||
"инструкцию о порядке работы:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
" Terminal> csv2html2_ans.py -h\n",
|
||
" usage:\n",
|
||
" csv2html.py [maxwidth=int] [format=str] < infile.csv > outfile.html\n",
|
||
" maxwidth - необязательное целое число. Если задано, определяет\n",
|
||
" максимальное число символов для строковых полей. В противном случае\n",
|
||
" используется значение по умолчанию 100.\n",
|
||
" \n",
|
||
" format - формат вывода чисел. Если не задан, по умолчанию используется\n",
|
||
" формат \".0f\".\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"А ниже приводится пример командной строки, в которой установ-\n",
|
||
"лены оба аргумента:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
" Terminal> csv2html2_ans.py maxwidth=20 format=0.2f < mydata.csv > mydata.html\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<!-- --- begin hint in exercise --- -->\n",
|
||
"\n",
|
||
"**Подсказка.**\n",
|
||
"Не забудьте изменить функцию `print_line()` так, чтобы она\n",
|
||
"использовала переменную `format` при выводе чисел – для этого вам\n",
|
||
"придется передавать функции дополнительный аргумент, добавить одну \n",
|
||
"строку и изменить еще одну строку. И это немного затронет функцию\n",
|
||
"`main()`. Функция `process_options()` должна содержать порядка\n",
|
||
"двадцати пяти строк (включая девять строк с текстом сообщения о\n",
|
||
"порядке использования).\n",
|
||
"\n",
|
||
"<!-- --- end hint in exercise --- -->\n",
|
||
"Имя файла: `cvs2html_ans2.py`.\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
|
||
"<!-- doconce-section-nickname: \"exercises\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"<!-- Local Variables: -->\n",
|
||
"<!-- doconce-chapter-nickname: \"datatype\" -->\n",
|
||
"<!-- End: -->\n",
|
||
"<!-- --- end exercise --- -->"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 2
|
||
}
|