├── experiments ├── Demo.py ├── Graph.py └── 1.1.py ├── week3 ├── 5. API.ipynb ├── 4. CSV and JSON.ipynb ├── 3. Internet.ipynb ├── 1. Strings.ipynb └── 2. Regexp.ipynb ├── week2 ├── 2. Modules and import.ipynb ├── 5. Functions.ipynb ├── 4. Files.ipynb ├── 3. Iterators and generators.ipynb └── 1.Errors and exceptions.ipynb └── week1 └── week1.ipynb /experiments/Demo.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | class Loggable: 4 | def log(self, msg): 5 | print(str(time.ctime()) + ": " + str(msg)) 6 | 7 | class LoggableList(list, Loggable): 8 | def append(self, obj): 9 | super(LoggableList, self).append(obj) 10 | super(LoggableList, self).log(obj) 11 | 12 | 13 | lst = LoggableList() 14 | lst.append('something1') 15 | lst.append('something2') -------------------------------------------------------------------------------- /experiments/Graph.py: -------------------------------------------------------------------------------- 1 | h = dict() 2 | 3 | def addParents(class_name, *parents): 4 | h[class_name] = parents 5 | 6 | def isAncestor(ancestor, descendant): 7 | if ancestor == descendant: 8 | return True 9 | if ancestor in h[descendant]: 10 | return True 11 | for a in h[descendant]: 12 | if isAncestor(ancestor, a): 13 | return True 14 | return False 15 | 16 | def toYesNo(b): 17 | return "Yes" if b else "No" 18 | 19 | for _ in range(int(input())): 20 | parts = input().split(" : ") 21 | cl = parts[0] 22 | parents = [] if len(parts) == 1 else parts[1].split(" ") 23 | addParents(cl, *parents) 24 | 25 | for _ in range(int(input())): 26 | parts = input().split(" ") 27 | a = parts[0] 28 | d = parts[1] 29 | print(toYesNo(isAncestor(a, d))) -------------------------------------------------------------------------------- /experiments/1.1.py: -------------------------------------------------------------------------------- 1 | def searchChildren(classes, parent, child): 2 | 3 | if parent == child: 4 | return True 5 | 6 | if child in classes[parent]: 7 | return True 8 | 9 | for grandparent in classes[parent]: 10 | if searchChildren(classes, grandparent, child): 11 | return True 12 | return False 13 | 14 | 15 | lst = [] 16 | classes = dict() 17 | 18 | n = int(input()) 19 | for i in range(n): 20 | line = input().split(" ") 21 | if ':' in line: 22 | for i in range(2, len(line)): 23 | if classes.get(line[0]) is not None: 24 | classes[line[0]] += [line[i]] 25 | else: 26 | classes[line[0]] = [line[i]] 27 | if classes.get(line[i]) is None: 28 | classes[line[i]] = [] 29 | else: 30 | for i in range(len(line)): 31 | classes[line[i]] = [] 32 | 33 | n = int(input()) 34 | for i in range(n): 35 | line = input().split() 36 | lst += [(searchChildren(classes, line[1], line[0]))] 37 | 38 | # print(classes) 39 | for i in range(len(lst)): 40 | if lst[i] == 0: 41 | print("Yes") 42 | else: 43 | print("No") 44 | 45 | -------------------------------------------------------------------------------- /week3/5. API.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# API" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "API - набор функций, констант и методов, которые доступны пользователю" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "В качестве примера рассматривается api сервиса opnenteathermap - сервис для получения данных о погоди во всем мире" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 16, 27 | "metadata": { 28 | "collapsed": false 29 | }, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | "City ? Kaluga\n", 36 | "200\n", 37 | "application/json; charset=utf-8\n", 38 | "Current tamperature in Kaluga is 17.04\n" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | "import requests\n", 44 | "\n", 45 | "api_url = \"http://api.openweathermap.org/data/2.5/weather\"\n", 46 | "\n", 47 | "city = input(\"City ? \")\n", 48 | "\n", 49 | "params = {\n", 50 | " 'q': city,\n", 51 | " 'appid': '11c0d3dc6093f7442898ee49d2430d20',\n", 52 | " 'units': 'metric'\n", 53 | "}\n", 54 | "\n", 55 | "res = requests.get(api_url, params=params)\n", 56 | "print(res.status_code)\n", 57 | "print(res.headers[\"Content-Type\"])\n", 58 | "# print(res.json())\n", 59 | "\n", 60 | "data = res.json()\n", 61 | "template = 'Current tamperature in {} is {}'\n", 62 | "print(template.format(city, data[\"main\"][\"temp\"]))" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": { 68 | "collapsed": true 69 | }, 70 | "source": [ 71 | "### Задача 1" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 27, 77 | "metadata": { 78 | "collapsed": false 79 | }, 80 | "outputs": [ 81 | { 82 | "name": "stdout", 83 | "output_type": "stream", 84 | "text": [ 85 | "999\n", 86 | "200\n", 87 | "Interesting\n" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "import requests\n", 93 | "\n", 94 | "numb = input()\n", 95 | "\n", 96 | "api_url = \"http://numbersapi.com/\" + numb + \"/math?json=true\"\n", 97 | "\n", 98 | "res = requests.get(api_url)\n", 99 | "\n", 100 | "print(res.status_code)\n", 101 | "if res.status_code == 200:\n", 102 | " print('Interesting')\n", 103 | "else:\n", 104 | " print('Boring')" 105 | ] 106 | } 107 | ], 108 | "metadata": { 109 | "kernelspec": { 110 | "display_name": "Python 3", 111 | "language": "python", 112 | "name": "python3" 113 | }, 114 | "language_info": { 115 | "codemirror_mode": { 116 | "name": "ipython", 117 | "version": 3 118 | }, 119 | "file_extension": ".py", 120 | "mimetype": "text/x-python", 121 | "name": "python", 122 | "nbconvert_exporter": "python", 123 | "pygments_lexer": "ipython3", 124 | "version": "3.5.0" 125 | } 126 | }, 127 | "nbformat": 4, 128 | "nbformat_minor": 0 129 | } 130 | -------------------------------------------------------------------------------- /week2/2. Modules and import.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Модули и импорт" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "##### sys.modules - словарь (имя модуля: model obj), в котором хранятся имена вызываемых модулей. Если имя уже находится в словаре, то исполнения файла с ним не происходит." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "##### Пример рыботы со словарем модулей: " 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": { 28 | "collapsed": true 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "import sys\n", 33 | "print(type(sys.modules))\n", 34 | "print(sys.modules)" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "##### Задача " 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 14, 47 | "metadata": { 48 | "collapsed": false 49 | }, 50 | "outputs": [ 51 | { 52 | "name": "stdout", 53 | "output_type": "stream", 54 | "text": [ 55 | "2016 12 20\n", 56 | "61\n", 57 | "2017 2 19\n" 58 | ] 59 | } 60 | ], 61 | "source": [ 62 | "import datetime\n", 63 | "\n", 64 | "date_list = [int(i) for i in input().split()]\n", 65 | "\n", 66 | "old_date = datetime.date(year = date_list[0], month = date_list[1], day = date_list[2])\n", 67 | "new_date = old_date + datetime.timedelta(days = int(input()))\n", 68 | "\n", 69 | "print(new_date.year, new_date.month, new_date.day)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "##### Чтобы импортировать некоторые локальные имена из модуля используется конструкция: from some_module import some_local_name " 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "##### Для импорта всех локальных имен используется следующая конструкция: from some_module import *" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "##### Для того, чтобы ограничить импортированные имена, используется список __all__, в который заносятся все импортируемые локальные имена" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": {}, 96 | "source": [ 97 | "##### Или локальное имя можно начать с нижнего подчеркивания (_example), тогда оно станет невидимым для других модулей." 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "##### Задача" 105 | ] 106 | } 107 | ], 108 | "metadata": { 109 | "kernelspec": { 110 | "display_name": "Python 3", 111 | "language": "python", 112 | "name": "python3" 113 | }, 114 | "language_info": { 115 | "codemirror_mode": { 116 | "name": "ipython", 117 | "version": 3 118 | }, 119 | "file_extension": ".py", 120 | "mimetype": "text/x-python", 121 | "name": "python", 122 | "nbconvert_exporter": "python", 123 | "pygments_lexer": "ipython3", 124 | "version": "3.5.1" 125 | } 126 | }, 127 | "nbformat": 4, 128 | "nbformat_minor": 0 129 | } 130 | -------------------------------------------------------------------------------- /week2/5. Functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Работа с функциями: functool и лямбда функции" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Лямбда-функции в Python - это всего лишь синтаксис для создания новых объектов-функций" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 2, 20 | "metadata": { 21 | "collapsed": false 22 | }, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "True\n", 29 | "True\n" 30 | ] 31 | } 32 | ], 33 | "source": [ 34 | "# Функция поиска четных чисел\n", 35 | "def even(x):\n", 36 | " return x % 2 == 0\n", 37 | "print(even(124))\n", 38 | "\n", 39 | "# Функция поиска четных чисел с помощью labmda-выражения \n", 40 | "even = lambda x: x % 2 == 0\n", 41 | "print(even(124))" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "#### Синтаксис лямбда-выражений" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "##### Вначале идет ключевое слово lambda , после которого идет аргумент функции (который может указываться с * и **). После двоеточия указывается выражение, которое должно быть возвращаемым." 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "#### Преимуществом лямбда-фукнций являет и то, что их можно вызывать не по имени, а напрямую" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 6, 68 | "metadata": { 69 | "collapsed": false 70 | }, 71 | "outputs": [ 72 | { 73 | "name": "stdout", 74 | "output_type": "stream", 75 | "text": [ 76 | "1 2 3 4 5 6 7\n", 77 | "[2, 4, 6]\n", 78 | "[2, 4, 6]\n" 79 | ] 80 | } 81 | ], 82 | "source": [ 83 | "x = input().split()\n", 84 | "\n", 85 | "xs = (int(i) for i in x)\n", 86 | "\n", 87 | "# Такое выражение в две строчки\n", 88 | "even = lambda x: x % 2 == 0\n", 89 | "evens = list(filter(even, xs))\n", 90 | "print(evens)\n", 91 | "\n", 92 | "xs = (int(i) for i in x)\n", 93 | "\n", 94 | "# Может быть заменено на такое в одну\n", 95 | "evens = list(filter(lambda x: x % 2 == 0, xs))\n", 96 | "print(evens)" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": {}, 102 | "source": [ 103 | "### Для того, чтобы сделать из стандартного оператора функцию в языке Python используется библиотека operator" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 14, 109 | "metadata": { 110 | "collapsed": false 111 | }, 112 | "outputs": [ 113 | { 114 | "name": "stdout", 115 | "output_type": "stream", 116 | "text": [ 117 | "9\n", 118 | "20\n", 119 | "False\n", 120 | "2\n", 121 | "\n" 122 | ] 123 | } 124 | ], 125 | "source": [ 126 | "import operator as op\n", 127 | "\n", 128 | "print(op.add(4, 5)) # сложение\n", 129 | "print(op.mul(4, 5)) # умножение\n", 130 | "print(op.contains([1, 2, 3], 4)) # проверка - содержит ли список (первый аргумент) элемент (второй аргумент)\n", 131 | "\n", 132 | "x = [1, 2, 3]\n", 133 | "# конструктор itemgetter возвращет специальную функцию, которая может вернуть элемент по индексу\n", 134 | "# данный конструктор можно применить и к словарю, указав вместо индекса ключ\n", 135 | "f = op.itemgetter(1) # f(x) == x[1] <--- получили функцию, для того, \n", 136 | " # чтобы достать элемент с индексом 1 (т.к. аргумент = 1) \n", 137 | "print(f(x)) # Применяем полученную функцию к списку и выводим элемент с индексом 1\n", 138 | "\n", 139 | "# attrgetter позволяет получить атрибут объекта\n", 140 | "f = op.attrgetter(\"sort\") # получаем функцию f, которая вытаскивает атрибут sort из объекта\n", 141 | "print(f([])) # смотрим на атрибут sort у пустого списка" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": {}, 147 | "source": [ 148 | "### Одной из основных библиотек для работы с функциями является functools " 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 17, 154 | "metadata": { 155 | "collapsed": false 156 | }, 157 | "outputs": [ 158 | { 159 | "name": "stdout", 160 | "output_type": "stream", 161 | "text": [ 162 | "13\n" 163 | ] 164 | } 165 | ], 166 | "source": [ 167 | "from functools import partial\n", 168 | "\n", 169 | "# Работать с двоичными числами можно так:\n", 170 | "x = int(\"1101\", base = 2)\n", 171 | "print(x)\n", 172 | "\n", 173 | "# Но это не удобно, т.к. постоянно приходится указывать аргумент base и помнить, что это двочная система" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "metadata": {}, 179 | "source": [ 180 | "##### Функция partial из библиотеки functools может взять некоторую функцию и частично подставляет в нее какие-то из аргументов, при этом возвращая функцию, в которую эти аргументы больше подставлять уже не нужно" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 22, 186 | "metadata": { 187 | "collapsed": false 188 | }, 189 | "outputs": [ 190 | { 191 | "name": "stdout", 192 | "output_type": "stream", 193 | "text": [ 194 | "128\n" 195 | ] 196 | } 197 | ], 198 | "source": [ 199 | "# Для облегчения работы можно воспользовать функцией partial\n", 200 | "int_2 = partial(int, base=2)\n", 201 | "x = int_2(\"10000000\")\n", 202 | "print(x)" 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "metadata": {}, 208 | "source": [ 209 | "##### Воспользуемся полученными знания для того, чтобы отсортировать список кортежей по последнему символу" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": 26, 215 | "metadata": { 216 | "collapsed": false 217 | }, 218 | "outputs": [ 219 | { 220 | "name": "stdout", 221 | "output_type": "stream", 222 | "text": [ 223 | "[('Guido', 'van', 'Rossum'), ('Haskell', 'Churry'), ('John', 'Backus')]\n", 224 | "[('John', 'Backus'), ('Haskell', 'Churry'), ('Guido', 'van', 'Rossum')]\n", 225 | "['cba', 'abb', 'abc']\n" 226 | ] 227 | } 228 | ], 229 | "source": [ 230 | "x = [\n", 231 | " (\"Guido\", \"van\", \"Rossum\"),\n", 232 | " (\"Haskell\", \"Churry\"),\n", 233 | " (\"John\", \"Backus\")\n", 234 | " ]\n", 235 | "\n", 236 | "import operator as op\n", 237 | "from functools import partial\n", 238 | "\n", 239 | "sort_by_last = partial(list.sort, key=op.itemgetter(-1))\n", 240 | "print(x)\n", 241 | "sort_by_last(x)\n", 242 | "print(x)\n", 243 | "\n", 244 | "y = [\"abc\", \"cba\", \"abb\"]\n", 245 | "sort_by_last(y) # данная функция сработает с последним элементом в каждой строке, т.е. результат: cba, abb, abc \n", 246 | "print(y)" 247 | ] 248 | }, 249 | { 250 | "cell_type": "markdown", 251 | "metadata": {}, 252 | "source": [ 253 | "##### Задача" 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": 28, 259 | "metadata": { 260 | "collapsed": false 261 | }, 262 | "outputs": [ 263 | { 264 | "name": "stdout", 265 | "output_type": "stream", 266 | "text": [ 267 | "True\n", 268 | "False\n", 269 | "True\n" 270 | ] 271 | } 272 | ], 273 | "source": [ 274 | "def mod_checker(x, mod=0):\n", 275 | " return lambda y: y % x == mod\n", 276 | "\n", 277 | "mod_3 = mod_checker(3)\n", 278 | "print(mod_3(3))\n", 279 | "print(mod_3(4))\n", 280 | "\n", 281 | "mod_3_1 = mod_checker(3, 1)\n", 282 | "print(mod_3_1(4))" 283 | ] 284 | } 285 | ], 286 | "metadata": { 287 | "kernelspec": { 288 | "display_name": "Python 3", 289 | "language": "python", 290 | "name": "python3" 291 | }, 292 | "language_info": { 293 | "codemirror_mode": { 294 | "name": "ipython", 295 | "version": 3 296 | }, 297 | "file_extension": ".py", 298 | "mimetype": "text/x-python", 299 | "name": "python", 300 | "nbconvert_exporter": "python", 301 | "pygments_lexer": "ipython3", 302 | "version": "3.5.1" 303 | } 304 | }, 305 | "nbformat": 4, 306 | "nbformat_minor": 0 307 | } 308 | -------------------------------------------------------------------------------- /week2/4. Files.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Работа с файловой системой и файлами" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Работа с текстовыми файлами" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "#### Чтение из файла" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "##### open - функция для работы с файлами" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 10, 34 | "metadata": { 35 | "collapsed": false 36 | }, 37 | "outputs": [ 38 | { 39 | "name": "stdout", 40 | "output_type": "stream", 41 | "text": [ 42 | "['First line', 'Second line', 'Third line']\n" 43 | ] 44 | } 45 | ], 46 | "source": [ 47 | "# r (read) - открыть для ччтения (по умолчанию)\n", 48 | "# w (write) - открыть для записи, содержимое файла стирается\n", 49 | "# a (append) - открыть для записи, запись ведется в конец\n", 50 | "# b (binary) - открыть в бинарном режиме\n", 51 | "# t (text) - открыть в текстовом режиме (по умолчанию)\n", 52 | "\n", 53 | "# r+ - открыть для чтения и записи\n", 54 | "# w+ - открыть для чтения и записи, содержимое файла стирается\n", 55 | "\n", 56 | "f = open(\"D:\\\\test.txt\")\n", 57 | "x = f.read()\n", 58 | "x = x.splitlines() # Метод splitlines возвращает список строк\n", 59 | "print(repr(x)) # Функция repr позволяет вывести не просто строку, а ее представление (т.е. со всякими \\n)\n", 60 | "\n", 61 | "\n", 62 | "f.close()" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "##### Файл может оказаться слишком большим и тогда лучше считывать его построчно" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 14, 75 | "metadata": { 76 | "collapsed": false 77 | }, 78 | "outputs": [ 79 | { 80 | "name": "stdout", 81 | "output_type": "stream", 82 | "text": [ 83 | "'First line\\n'\n", 84 | "'Second line'\n" 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "f = open(\"D:\\\\test.txt\")\n", 90 | "x = f.readline()\n", 91 | "print(repr(x))\n", 92 | "\n", 93 | "x = f.readline().rstrip() # метод rstrip убирает справа все пробельные символы\n", 94 | "print(repr(x))\n", 95 | "\n", 96 | "f.close()" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": {}, 102 | "source": [ 103 | "##### У file object есть интеретор, который удобно использовать для чтения строк, т.к. он \"по умному\" расходует оперативную память." 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 17, 109 | "metadata": { 110 | "collapsed": false 111 | }, 112 | "outputs": [ 113 | { 114 | "name": "stdout", 115 | "output_type": "stream", 116 | "text": [ 117 | "'First line'\n", 118 | "'Second line'\n", 119 | "'Third line'\n" 120 | ] 121 | } 122 | ], 123 | "source": [ 124 | "f = open(\"D:\\\\test.txt\")\n", 125 | "for line in f:\n", 126 | " line = line.rstrip()\n", 127 | " print(repr(line))\n", 128 | " \n", 129 | "f.close()" 130 | ] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "metadata": {}, 135 | "source": [ 136 | "#### Запись в файл" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 19, 142 | "metadata": { 143 | "collapsed": true 144 | }, 145 | "outputs": [], 146 | "source": [ 147 | "f = open(\"D:\\\\test1.txt\", \"w\")\n", 148 | "f.write(\"Hello\")\n", 149 | "f.write(\" world!\")\n", 150 | "\n", 151 | "f.close()" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": {}, 157 | "source": [ 158 | "##### Метод write не делает переносов и необходимо всегда добавлять символ переноса строки. Чтобы это упростить часто использует метод join." 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 24, 164 | "metadata": { 165 | "collapsed": false 166 | }, 167 | "outputs": [], 168 | "source": [ 169 | "f = open(\"D:\\\\test1.txt\", \"w\")\n", 170 | "lines = [\"Line 1\", \"Line 2\", \"Line 3\"]\n", 171 | "contents = \"\\n\".join(lines) # Добавляем после каждой строки \\n, кроме последней\n", 172 | "f.write(contents)\n", 173 | "\n", 174 | "f.close()" 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": {}, 180 | "source": [ 181 | "#### Конструкция with" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "##### Для того, чтобы не писать всяких try - finally (для 100%-ого закрытия файла), используется конструкция with:" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 26, 194 | "metadata": { 195 | "collapsed": false 196 | }, 197 | "outputs": [ 198 | { 199 | "name": "stdout", 200 | "output_type": "stream", 201 | "text": [ 202 | "First line\n", 203 | "Second line\n", 204 | "Third line\n" 205 | ] 206 | } 207 | ], 208 | "source": [ 209 | "with open(\"D:\\\\test.txt\") as f:\n", 210 | " for line in f:\n", 211 | " line = line.rstrip()\n", 212 | " print(line)" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": {}, 218 | "source": [ 219 | "##### В одной конструкции with можно открыть несколько файлов" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 28, 225 | "metadata": { 226 | "collapsed": false 227 | }, 228 | "outputs": [], 229 | "source": [ 230 | "# Копирование текста из одного файла в другой\n", 231 | "with open(\"D:\\\\test.txt\") as f, open(\"D:\\\\test_copy.txt\", \"w\") as w:\n", 232 | " for line in f:\n", 233 | " w.write(line)" 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": {}, 239 | "source": [ 240 | "#### Задачa 1" 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": 45, 246 | "metadata": { 247 | "collapsed": false 248 | }, 249 | "outputs": [], 250 | "source": [ 251 | "with open(\"D:\\\\dataset_24465_4.txt\") as f, open(\"D:\\\\back_copy.txt\", \"w\") as w:\n", 252 | " lines = list()\n", 253 | " for line in f:\n", 254 | " lines += [line.rstrip()]\n", 255 | " \n", 256 | " lines = lines[::-1]\n", 257 | " lines = \"\\n\".join(lines)\n", 258 | " \n", 259 | " for line in lines:\n", 260 | " w.write(line)" 261 | ] 262 | }, 263 | { 264 | "cell_type": "markdown", 265 | "metadata": {}, 266 | "source": [ 267 | "## Работа с файловой системой" 268 | ] 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "metadata": {}, 273 | "source": [ 274 | "#### Самые используемые библиотеки для работы с файловой системой:" 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": {}, 280 | "source": [ 281 | "##### 1. os" 282 | ] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "metadata": {}, 287 | "source": [ 288 | "##### 2.os.path" 289 | ] 290 | }, 291 | { 292 | "cell_type": "code", 293 | "execution_count": null, 294 | "metadata": { 295 | "collapsed": false 296 | }, 297 | "outputs": [], 298 | "source": [ 299 | "import os\n", 300 | "import os.path\n", 301 | "\n", 302 | "print(os.getcwd()) # getcwd - узнать текущую директорию\n", 303 | "# os.chdir(\"..\\\\\") # chdir (change dir) - позволяет сменить текущую директорию, надо быть осторожным с этим методом. \n", 304 | " # Эффект от него сохраняет даже при перезапуске скрипта \n", 305 | "print(os.getcwd())\n", 306 | "\n", 307 | "print(os.listdir()) # listdir - файлы в текущей директории\n", 308 | "print(os.listdir(\"Videos\")) # listdir можно принимать в качестве аргумента относительный путь к какой-либо папке\n", 309 | "\n", 310 | "print(os.path.exists(\".jssc\")) # exists проверяет текущую директорию на наличие файла \n", 311 | "print(os.path.exists(\"Videos\")) # или другой директории\n", 312 | "print(os.path.exists(\"ThereIsNoSuchFile\"))\n", 313 | "\n", 314 | "print(os.path.abspath(\".jssc\")) # функция path позволяет узнать полный путь до файла" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "##### Одной из ключевых функций библиотеки os является функция os.walk, которая возвращает итератор со всеми каталогами и подкаталогами текущей директории. Каждый вызов итератора возвращает кортеж из 3-х элементов. " 322 | ] 323 | }, 324 | { 325 | "cell_type": "markdown", 326 | "metadata": {}, 327 | "source": [ 328 | "###### 1. Строковое представления текущей директории, которую он осматривает." 329 | ] 330 | }, 331 | { 332 | "cell_type": "markdown", 333 | "metadata": {}, 334 | "source": [ 335 | "###### 2. Список всех подпапок данной директории." 336 | ] 337 | }, 338 | { 339 | "cell_type": "markdown", 340 | "metadata": {}, 341 | "source": [ 342 | "###### 3. Список всех файлов в данной директории" 343 | ] 344 | }, 345 | { 346 | "cell_type": "markdown", 347 | "metadata": {}, 348 | "source": [ 349 | "###### Пример использования" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": 1, 355 | "metadata": { 356 | "collapsed": false 357 | }, 358 | "outputs": [], 359 | "source": [ 360 | "import os.path\n", 361 | "\n", 362 | "# Список всех папок, попдпапок и файлов, начиная с текущей директории\n", 363 | "# for current_dir, dirs, files in os.walk(\".\"):\n", 364 | "# print(current_dir, dirs, files)" 365 | ] 366 | }, 367 | { 368 | "cell_type": "markdown", 369 | "metadata": {}, 370 | "source": [ 371 | "### Для копирования файлов используются библиотека shutil" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": 7, 377 | "metadata": { 378 | "collapsed": false 379 | }, 380 | "outputs": [ 381 | { 382 | "name": "stdout", 383 | "output_type": "stream", 384 | "text": [ 385 | "\n", 386 | "\n", 387 | "Result:\n", 388 | "D:\\pytest\\ ['testdir1'] []\n", 389 | "D:\\pytest\\testdir1 [] ['test1.txt']\n", 390 | "\n", 391 | "\n", 392 | "Result:\n", 393 | "D:\\pytest\\ ['testdir1'] []\n", 394 | "D:\\pytest\\testdir1 [] ['test1.txt', 'test2.txt']\n", 395 | "\n", 396 | "\n", 397 | "Result:\n", 398 | "D:\\pytest\\ ['testdir1', 'testdir2'] []\n", 399 | "D:\\pytest\\testdir1 [] ['test1.txt', 'test2.txt']\n", 400 | "D:\\pytest\\testdir2 [] ['test1.txt', 'test2.txt']\n" 401 | ] 402 | } 403 | ], 404 | "source": [ 405 | "import shutil\n", 406 | "\n", 407 | "def showPyDir():\n", 408 | " print('\\n\\nResult:')\n", 409 | " for current_dir, dirs, files in os.walk(\"D:\\\\pytest\\\\\"):\n", 410 | " print(current_dir, dirs, files) \n", 411 | "\n", 412 | "showPyDir()\n", 413 | " \n", 414 | "# Функция copy копирует файлы\n", 415 | "shutil.copy(\"D:\\\\pytest\\\\testdir1\\\\test1.txt\", \"D:\\\\pytest\\\\testdir1\\\\test2.txt\")\n", 416 | "showPyDir()\n", 417 | "\n", 418 | "# Функция copytree копирует директории\n", 419 | "shutil.copytree(\"D:\\\\pytest\\\\testdir1\", \"D:\\\\pytest\\\\testdir2\")\n", 420 | "showPyDir()" 421 | ] 422 | }, 423 | { 424 | "cell_type": "markdown", 425 | "metadata": {}, 426 | "source": [ 427 | "#### Задача" 428 | ] 429 | }, 430 | { 431 | "cell_type": "code", 432 | "execution_count": 23, 433 | "metadata": { 434 | "collapsed": false 435 | }, 436 | "outputs": [ 437 | { 438 | "name": "stdout", 439 | "output_type": "stream", 440 | "text": [ 441 | "None\n" 442 | ] 443 | } 444 | ], 445 | "source": [ 446 | "import os\n", 447 | "import os.path\n", 448 | "import shutil\n", 449 | "\n", 450 | "list_of_paths = list()\n", 451 | "\n", 452 | "for current_dir, dirs, files in os.walk(\"D:\\\\pytest\\\\main\\\\\"):\n", 453 | " for file in files:\n", 454 | " filename, file_extension = os.path.splitext(file)\n", 455 | " if file_extension == \".py\" and current_dir not in list_of_paths:\n", 456 | " list_of_paths += [current_dir]\n", 457 | " \n", 458 | "list_of_paths.sort()\n", 459 | "with open(\"D:\\\\pytest\\\\task.txt\", 'w') as f:\n", 460 | " f.write('\\n'.join(list_of_paths))\n" 461 | ] 462 | } 463 | ], 464 | "metadata": { 465 | "kernelspec": { 466 | "display_name": "Python 3", 467 | "language": "python", 468 | "name": "python3" 469 | }, 470 | "language_info": { 471 | "codemirror_mode": { 472 | "name": "ipython", 473 | "version": 3 474 | }, 475 | "file_extension": ".py", 476 | "mimetype": "text/x-python", 477 | "name": "python", 478 | "nbconvert_exporter": "python", 479 | "pygments_lexer": "ipython3", 480 | "version": "3.5.0" 481 | } 482 | }, 483 | "nbformat": 4, 484 | "nbformat_minor": 0 485 | } 486 | -------------------------------------------------------------------------------- /week3/4. CSV and JSON.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Распространенные форматы текстовых файлов: CSV, JSON" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## CSV(comma separated values) - табличный формат хранения данных" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "### Чтение данных из файла" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 5, 27 | "metadata": { 28 | "collapsed": false 29 | }, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | "['first name', 'last name', 'module1', 'module2', 'module3', 'description']\n", 36 | "['student', 'best', '100', '100', '100', 'Excellent score']\n", 37 | "['student', 'good', '90', '90,2', '100', 'Good score\\nbut could do better']\n" 38 | ] 39 | } 40 | ], 41 | "source": [ 42 | "import csv\n", 43 | "\n", 44 | "with open(\"D:\\\\pytest\\example.csv\") as f:\n", 45 | " reader = csv.reader(f, delimiter=\",\")\n", 46 | " for row in reader:\n", 47 | " print(row)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "### Запись данных в файл" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 1, 60 | "metadata": { 61 | "collapsed": true 62 | }, 63 | "outputs": [], 64 | "source": [ 65 | "import csv\n", 66 | "\n", 67 | "students = [\n", 68 | " [\"Greg\", \"Dean\", 70, 80, 90, \"Good job, Greg\"],\n", 69 | " [\"Wirt\", \"Wood\", 80, 80.2, 80, \"Nicely done\"]\n", 70 | "]\n", 71 | "\n", 72 | "with open(\"D:\\\\pytest\\example.csv\", \"a\") as f:\n", 73 | " writer = csv.writer(f)\n", 74 | " for student in students:\n", 75 | " writer.writerow(student)" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "##### Для того, чтобы сказать writer'у о том, чтобы все значения были помещены в кавычки используется параметр конструктора quoting" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": { 89 | "collapsed": true 90 | }, 91 | "outputs": [], 92 | "source": [ 93 | "import csv\n", 94 | "\n", 95 | "students = [\n", 96 | " [\"Greg\", \"Dean\", 70, 80, 90, \"Good job, Greg\"],\n", 97 | " [\"Wirt\", \"Wood\", 80, 80.2, 80, \"Nicely done\"]\n", 98 | "]\n", 99 | "\n", 100 | "with open(\"D:\\\\pytest\\example.csv\", \"a\") as f:\n", 101 | " writer = csv.writer(f, quoting=csv.QUOTE_ALL) # или QUOTE_MINIMAL, QUOTE_NONE, QUOTE_NONNUMERIC\n", 102 | " for student in students:\n", 103 | " writer.writerow(student)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "#### Задача 1" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "Вам дана частичная выборка из датасета зафиксированных преступлений, совершенных в городе Чикаго с 2001 года по настоящее время.\n", 118 | "\n", 119 | "Одним из атрибутов преступления является его тип – Primary Type.\n", 120 | "\n", 121 | "Вам необходимо узнать тип преступления, которое было зафиксировано максимальное число раз в 2015 году.\n", 122 | "\n", 123 | "Файл с данными:\n", 124 | "Crimes.csv" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 21, 130 | "metadata": { 131 | "collapsed": false 132 | }, 133 | "outputs": [ 134 | { 135 | "name": "stdout", 136 | "output_type": "stream", 137 | "text": [ 138 | "THEFT\n" 139 | ] 140 | } 141 | ], 142 | "source": [ 143 | "import csv\n", 144 | "\n", 145 | "dict_pr_type = dict()\n", 146 | "is_header = True\n", 147 | "\n", 148 | "with open(\"D:\\\\pytest\\Crimes.csv\") as f:\n", 149 | " reader = csv.reader(f)\n", 150 | " for row in reader:\n", 151 | " if is_header:\n", 152 | " is_header = False\n", 153 | " else:\n", 154 | " if row[5] in dict_pr_type:\n", 155 | " dict_pr_type[row[5]] += 1\n", 156 | " else:\n", 157 | " dict_pr_type[row[5]] = 1\n", 158 | "\n", 159 | "sorted_types = sorted(dict_pr_type.items(), key=lambda x: x[1], reverse=True) \n", 160 | "\n", 161 | "print(sorted_types[0][0])" 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": {}, 167 | "source": [ 168 | "## JSON - изначальной использовался для представления объектов в JavaScript, сейчас используется повсеместно" 169 | ] 170 | }, 171 | { 172 | "cell_type": "markdown", 173 | "metadata": {}, 174 | "source": [ 175 | "##### Некоторые особенности Json" 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "metadata": {}, 181 | "source": [ 182 | "1. Ключем может быть только строка" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "metadata": {}, 188 | "source": [ 189 | "2. Значения true и false с маленькой буквы" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": {}, 195 | "source": [ 196 | "3. Значение null из json соответствует значению None из Python" 197 | ] 198 | }, 199 | { 200 | "cell_type": "markdown", 201 | "metadata": {}, 202 | "source": [ 203 | "4. Строки могут быть написаны только в двойных кавычках" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "metadata": {}, 209 | "source": [ 210 | "##### Для работы с форматом json в Python есть одноименная библиотека" 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": {}, 216 | "source": [ 217 | "##### Для преобразования данных в формат json используется функция dumps со следующими аргументами:" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": {}, 223 | "source": [ 224 | "Первый аргумент - данные для добавления" 225 | ] 226 | }, 227 | { 228 | "cell_type": "markdown", 229 | "metadata": {}, 230 | "source": [ 231 | "indent - количество отступов в списках и словарях" 232 | ] 233 | }, 234 | { 235 | "cell_type": "markdown", 236 | "metadata": {}, 237 | "source": [ 238 | "sort_keys - сортировка ключей каждого словаря, который попадается в каждом объекте" 239 | ] 240 | }, 241 | { 242 | "cell_type": "code", 243 | "execution_count": 22, 244 | "metadata": { 245 | "collapsed": false 246 | }, 247 | "outputs": [ 248 | { 249 | "name": "stdout", 250 | "output_type": "stream", 251 | "text": [ 252 | "[\n", 253 | " {\n", 254 | " \"certificate\": true,\n", 255 | " \"description\": \"Good job, Greg\",\n", 256 | " \"first_name\": \"Greg\",\n", 257 | " \"last_name\": \"Dean\",\n", 258 | " \"scores\": [\n", 259 | " 70,\n", 260 | " 80,\n", 261 | " 90\n", 262 | " ]\n", 263 | " },\n", 264 | " {\n", 265 | " \"certificate\": true,\n", 266 | " \"description\": \"Nicely Done\",\n", 267 | " \"first_name\": \"Wirt\",\n", 268 | " \"last_name\": \"Wood\",\n", 269 | " \"scores\": [\n", 270 | " 80,\n", 271 | " 80.2,\n", 272 | " 80\n", 273 | " ]\n", 274 | " }\n", 275 | "]\n" 276 | ] 277 | } 278 | ], 279 | "source": [ 280 | "import json\n", 281 | "student1 = {\n", 282 | " 'first_name': 'Greg',\n", 283 | " 'last_name': 'Dean',\n", 284 | " 'scores': [70, 80, 90],\n", 285 | " 'description': 'Good job, Greg',\n", 286 | " 'certificate': True\n", 287 | "}\n", 288 | "\n", 289 | "student2 = {\n", 290 | " 'first_name': 'Wirt',\n", 291 | " 'last_name': 'Wood',\n", 292 | " 'scores': [80, 80.2, 80],\n", 293 | " 'description': 'Nicely Done',\n", 294 | " 'certificate': True\n", 295 | "}\n", 296 | "\n", 297 | "data = [student1, student2]\n", 298 | "print(json.dumps(data, indent = 4, sort_keys=True))" 299 | ] 300 | }, 301 | { 302 | "cell_type": "markdown", 303 | "metadata": {}, 304 | "source": [ 305 | "##### Для записи информации в формате json в файл используется функция dump" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": 24, 311 | "metadata": { 312 | "collapsed": true 313 | }, 314 | "outputs": [], 315 | "source": [ 316 | "import json\n", 317 | "student1 = {\n", 318 | " 'first_name': 'Greg',\n", 319 | " 'last_name': 'Dean',\n", 320 | " 'scores': [70, 80, 90],\n", 321 | " 'description': 'Good job, Greg',\n", 322 | " 'certificate': True\n", 323 | "}\n", 324 | "\n", 325 | "student2 = {\n", 326 | " 'first_name': 'Wirt',\n", 327 | " 'last_name': 'Wood',\n", 328 | " 'scores': [80, 80.2, 80],\n", 329 | " 'description': 'Nicely Done',\n", 330 | " 'certificate': True\n", 331 | "}\n", 332 | "\n", 333 | "data = [student1, student2]\n", 334 | "with open(\"D:\\\\pytest\\students.json\", \"w\") as f:\n", 335 | " json.dump(data, f, indent=4, sort_keys=True)" 336 | ] 337 | }, 338 | { 339 | "cell_type": "markdown", 340 | "metadata": {}, 341 | "source": [ 342 | "#### Для получения объекта Python, соответствующим формату json используется функция loads" 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": 27, 348 | "metadata": { 349 | "collapsed": false 350 | }, 351 | "outputs": [ 352 | { 353 | "name": "stdout", 354 | "output_type": "stream", 355 | "text": [ 356 | "240\n" 357 | ] 358 | } 359 | ], 360 | "source": [ 361 | "import json\n", 362 | "student1 = {\n", 363 | " 'first_name': 'Greg',\n", 364 | " 'last_name': 'Dean',\n", 365 | " 'scores': [70, 80, 90],\n", 366 | " 'description': 'Good job, Greg',\n", 367 | " 'certificate': True\n", 368 | "}\n", 369 | "\n", 370 | "student2 = {\n", 371 | " 'first_name': 'Wirt',\n", 372 | " 'last_name': 'Wood',\n", 373 | " 'scores': [80, 80.2, 80],\n", 374 | " 'description': 'Nicely Done',\n", 375 | " 'certificate': True\n", 376 | "}\n", 377 | "\n", 378 | "data = [student1, student2]\n", 379 | "data_json = json.dumps(data, indent=4, sort_keys=True)\n", 380 | "data_again = json.loads(data_json)\n", 381 | "print(sum(data_again[0][\"scores\"]))" 382 | ] 383 | }, 384 | { 385 | "cell_type": "markdown", 386 | "metadata": {}, 387 | "source": [ 388 | "#### Для чтения данных из файла в формате json используется функция load" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": 30, 394 | "metadata": { 395 | "collapsed": false 396 | }, 397 | "outputs": [ 398 | { 399 | "name": "stdout", 400 | "output_type": "stream", 401 | "text": [ 402 | "240.2\n" 403 | ] 404 | } 405 | ], 406 | "source": [ 407 | "with open(\"D:\\\\pytest\\students.json\", \"r\") as f:\n", 408 | " data_again = json.load(f)\n", 409 | " print(sum(data_again[1][\"scores\"]))" 410 | ] 411 | }, 412 | { 413 | "cell_type": "markdown", 414 | "metadata": {}, 415 | "source": [ 416 | "#### Задача 2" 417 | ] 418 | }, 419 | { 420 | "cell_type": "markdown", 421 | "metadata": {}, 422 | "source": [ 423 | "Вам дано описание наследования классов в формате JSON. \n", 424 | "Описание представляет из себя массив JSON-объектов, которые соответствуют классам. У каждого JSON-объекта есть поле name, которое содержит имя класса, и поле parents, которое содержит список имен прямых предков.\n", 425 | "\n", 426 | "Пример:\n", 427 | "[{\"name\": \"A\", \"parents\": []}, {\"name\": \"B\", \"parents\": [\"A\", \"C\"]}, {\"name\": \"C\", \"parents\": [\"A\"]}]\n", 428 | "\n", 429 | "Эквивалент на Python:\n", 430 | "\n", 431 | "class A:\n", 432 | " pass\n", 433 | "\n", 434 | "class B(A, C):\n", 435 | " pass\n", 436 | "\n", 437 | "class C(A):\n", 438 | " pass\n", 439 | "\n", 440 | "Гарантируется, что никакой класс не наследуется от себя явно или косвенно, и что никакой класс не наследуется явно от одного класса более одного раза.\n", 441 | "\n", 442 | "Для каждого класса вычислите предком скольких классов он является и выведите эту информацию в следующем формате.\n", 443 | "\n", 444 | "<имя класса> : <количество потомков>\n", 445 | "\n", 446 | "Выводить классы следует в лексикографическом порядке." 447 | ] 448 | }, 449 | { 450 | "cell_type": "code", 451 | "execution_count": null, 452 | "metadata": { 453 | "collapsed": true 454 | }, 455 | "outputs": [], 456 | "source": [] 457 | } 458 | ], 459 | "metadata": { 460 | "kernelspec": { 461 | "display_name": "Python 3", 462 | "language": "python", 463 | "name": "python3" 464 | }, 465 | "language_info": { 466 | "codemirror_mode": { 467 | "name": "ipython", 468 | "version": 3 469 | }, 470 | "file_extension": ".py", 471 | "mimetype": "text/x-python", 472 | "name": "python", 473 | "nbconvert_exporter": "python", 474 | "pygments_lexer": "ipython3", 475 | "version": "3.5.0" 476 | } 477 | }, 478 | "nbformat": 4, 479 | "nbformat_minor": 0 480 | } 481 | -------------------------------------------------------------------------------- /week3/3. Internet.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Обзорно об интернете" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 3, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "200\n", 22 | "text/html\n", 23 | "\n", 25 | "\n", 26 | "\n", 27 | "\n", 28 | " \n", 29 | " \n", 30 | " \n", 31 | " Overview — Python 3.5.2 documentation\n", 32 | " \n", 33 | " \n", 34 | " \n", 35 | " \n", 36 | " \n", 45 | " \n", 46 | " \n", 47 | " \n", 48 | " \n", 49 | " \n", 52 | " \n", 53 | " \n", 54 | " \n", 55 | " \n", 56 | " \n", 57 | " \n", 58 | " \n", 59 | " \n", 60 | "\n", 61 | " \n", 62 | " \n", 63 | "
\n", 64 | "

Navigation

\n", 65 | " \n", 81 | "
\n", 82 | "\n", 83 | "
\n", 84 | "
\n", 85 | "
\n", 86 | "
\n", 87 | " \n", 88 | "

Python 3.5.2 documentation

\n", 89 | "

\n", 90 | " Welcome! This is\n", 91 | " the documentation for Python\n", 92 | " 3.5.2, last updated Jun 30, 2016.\n", 93 | "

\n", 94 | " \n", 95 | "

Parts of the documentation:

\n", 96 | " \n", 97 | " \n", 122 | "
\n", 98 | "

What's new in Python 3.5?
\n", 99 | " or all \"What's new\" documents since 2.0

\n", 100 | "

Tutorial
\n", 101 | " start here

\n", 102 | "

Library Reference
\n", 103 | " keep this under your pillow

\n", 104 | "

Language Reference
\n", 105 | " describes syntax and language elements

\n", 106 | "

Python Setup and Usage
\n", 107 | " how to use Python on different platforms

\n", 108 | "

Python HOWTOs
\n", 109 | " in-depth documents on specific topics

\n", 110 | "
\n", 111 | "

Installing Python Modules
\n", 112 | " installing from the Python Package Index & other sources

\n", 113 | "

Distributing Python Modules
\n", 114 | " publishing modules for installation by others

\n", 115 | "

Extending and Embedding
\n", 116 | " tutorial for C/C++ programmers

\n", 117 | "

Python/C API
\n", 118 | " reference for C/C++ programmers

\n", 119 | "

FAQs
\n", 120 | " frequently asked questions (with answers!)

\n", 121 | "
\n", 123 | "\n", 124 | "

Indices and tables:

\n", 125 | " \n", 126 | " \n", 139 | "
\n", 127 | "

Global Module Index
\n", 128 | " quick access to all modules

\n", 129 | "

General Index
\n", 130 | " all functions, classes, terms

\n", 131 | "

Glossary
\n", 132 | " the most important terms explained

\n", 133 | "
\n", 134 | "

Search page
\n", 135 | " search this documentation

\n", 136 | "

Complete Table of Contents
\n", 137 | " lists all sections and subsections

\n", 138 | "
\n", 140 | "\n", 141 | "

Meta information:

\n", 142 | " \n", 143 | " \n", 150 | "
\n", 144 | "

Reporting bugs

\n", 145 | "

About the documentation

\n", 146 | "
\n", 147 | "

History and License of Python

\n", 148 | "

Copyright

\n", 149 | "
\n", 151 | "\n", 152 | "\n", 153 | "
\n", 154 | "
\n", 155 | "
\n", 156 | "
\n", 157 | "
\n", 158 | "

Download

\n", 159 | "

Download these documents

\n", 160 | "

Docs for other versions

\n", 161 | "\n", 166 | "\n", 167 | "

Other resources

\n", 168 | "\n", 175 | "
\n", 176 | "

Quick search

\n", 177 | "
\n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | "
\n", 183 | "

\n", 184 | " Enter search terms or a module, class or function name.\n", 185 | "

\n", 186 | "
\n", 187 | "\n", 188 | "
\n", 189 | "
\n", 190 | "
\n", 191 | "
\n", 192 | "
\n", 193 | "

Navigation

\n", 194 | " \n", 210 | "
\n", 211 | "
\n", 212 | " © Copyright 2001-2016, Python Software Foundation.\n", 213 | "
\n", 214 | " The Python Software Foundation is a non-profit corporation.\n", 215 | " Please donate.\n", 216 | "
\n", 217 | " Last updated on Jun 30, 2016.\n", 218 | " Found a bug?\n", 219 | "
\n", 220 | " Created using Sphinx 1.3.3.\n", 221 | "
\n", 222 | "\n", 223 | " \n", 224 | "\n" 225 | ] 226 | } 227 | ], 228 | "source": [ 229 | "import requests\n", 230 | "\n", 231 | "res = requests.get(\"https://docs.python.org/3.5/\") # Метод возвращаеn объект типа Response\n", 232 | "print(res.status_code)\n", 233 | "print(res.headers['Content-Type'])\n", 234 | "\n", 235 | "#print(res.content)\n", 236 | "\n", 237 | "# Если мы уверены в том, что содержание ответа текст, то можно воспользоваться атрибутом text\n", 238 | "print(res.text)" 239 | ] 240 | }, 241 | { 242 | "cell_type": "code", 243 | "execution_count": null, 244 | "metadata": { 245 | "collapsed": true 246 | }, 247 | "outputs": [], 248 | "source": [ 249 | "Если нам известны имена параметров, то их можно передать с помощью библиотеки requests" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": 7, 255 | "metadata": { 256 | "collapsed": false 257 | }, 258 | "outputs": [ 259 | { 260 | "name": "stdout", 261 | "output_type": "stream", 262 | "text": [ 263 | "200\n", 264 | "text/html; charset=utf-8\n", 265 | "https://yandex.ru/search/?name=Name+Width+Spaces&test=test1&list=test1&list=test2\n" 266 | ] 267 | } 268 | ], 269 | "source": [ 270 | "import requests\n", 271 | "\n", 272 | "res = requests.get(\"https://yandex.ru/search/\", \n", 273 | " params = {\n", 274 | " \"test\": \"Stepic\",\n", 275 | " \"test\": \"test1\",\n", 276 | " \"name\": \"Name Width Spaces\",\n", 277 | " \"list\": [\"test1\", \"test2\"]\n", 278 | " })\n", 279 | "\n", 280 | "print(res.status_code)\n", 281 | "print(res.headers['Content-Type'])\n", 282 | "print(res.url)\n", 283 | "\n", 284 | "# print(res.text)" 285 | ] 286 | }, 287 | { 288 | "cell_type": "markdown", 289 | "metadata": {}, 290 | "source": [ 291 | "### Задачи" 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": {}, 297 | "source": [ 298 | "#### Задача 1" 299 | ] 300 | }, 301 | { 302 | "cell_type": "markdown", 303 | "metadata": {}, 304 | "source": [ 305 | "Рассмотрим два HTML-документа A и B.\n", 306 | "Из A можно перейти в B за один переход, если в A есть ссылка на B, т. е. внутри A есть тег , возможно с дополнительными параметрами внутри тега.\n", 307 | "Из A можно перейти в B за два перехода если существует такой документ C, что из A в C можно перейти за один переход и из C в B можно перейти за один переход.\n", 308 | "\n", 309 | "Вашей программе на вход подаются две строки, содержащие url двух документов A и B.\n", 310 | "Выведите Yes, если из A в B можно перейти за два перехода, иначе выведите No.\n", 311 | "\n", 312 | "Обратите внимание на то, что не все ссылки внутри HTML документа могут вести на существующие HTML документы." 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": 30, 318 | "metadata": { 319 | "collapsed": false 320 | }, 321 | "outputs": [ 322 | { 323 | "name": "stdout", 324 | "output_type": "stream", 325 | "text": [ 326 | "https://stepic.org/media/attachments/lesson/24472/sample1.html\n", 327 | "https://stepic.org/media/attachments/lesson/24472/sample2.html\n", 328 | "Yes\n" 329 | ] 330 | } 331 | ], 332 | "source": [ 333 | "import requests\n", 334 | "import re\n", 335 | "\n", 336 | "# В данном задании я не учитываю возможные пробелы, но вообще это делать нужно\n", 337 | "pattern = r\"\"\n", 338 | "\n", 339 | "url1 = input()\n", 340 | "url2 = input()\n", 341 | "\n", 342 | "res = requests.get(url1)\n", 343 | "all_href = re.findall(pattern, res.text)\n", 344 | "\n", 345 | "result = \"No\"\n", 346 | "\n", 347 | "for href in all_href:\n", 348 | " temp_res = requests.get(href)\n", 349 | " if re.search(url2, temp_res.text):\n", 350 | " result = \"Yes\"\n", 351 | "print(result)\n" 352 | ] 353 | }, 354 | { 355 | "cell_type": "markdown", 356 | "metadata": {}, 357 | "source": [ 358 | "#### Задача 2" 359 | ] 360 | }, 361 | { 362 | "cell_type": "markdown", 363 | "metadata": {}, 364 | "source": [ 365 | "Вашей программе на вход подается ссылка на HTML файл.\n", 366 | "Вам необходимо скачать этот файл, затем найти в нем все ссылки вида \"\" и вывести список сайтов, на которые есть ссылка.\n", 367 | "\n", 368 | "Сайтом в данной задаче будем называть имя домена вместе с именами поддоменов. То есть, это последовательность символов, которая следует сразу после символов протокола, если он есть, до символов порта или пути, если они есть, за исключением случаев с относительными ссылками вида\n", 369 | "\"\".\n", 370 | "\n", 371 | "Сайты следует выводить в алфавитном порядке." 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": 14, 377 | "metadata": { 378 | "collapsed": false 379 | }, 380 | "outputs": [ 381 | { 382 | "name": "stdout", 383 | "output_type": "stream", 384 | "text": [ 385 | "http://localhost/\n", 386 | "mail.ru\n", 387 | "neerc.ifmo.ru\n", 388 | "stepic.org\n", 389 | "www.ya.ru\n", 390 | "ya.ru\n" 391 | ] 392 | } 393 | ], 394 | "source": [ 395 | "import requests\n", 396 | "import re\n", 397 | "\n", 398 | "def get_list_of_urls(url):\n", 399 | " pattern = r''\n", 400 | " res = requests.get(url)\n", 401 | " return re.findall(pattern, res.text)\n", 402 | "\n", 403 | "def get_domain_from_list_of_urls(urls):\n", 404 | " pattern = r\"//(\\w[\\w\\.-]+)[/:]?\"\n", 405 | " domains = list()\n", 406 | " for url in urls:\n", 407 | " temp = re.search(pattern, url)\n", 408 | " if temp is not None:\n", 409 | " domains += [temp.group(1)]\n", 410 | " else:\n", 411 | " domains += [url]\n", 412 | " return domains\n", 413 | "\n", 414 | "\n", 415 | "list_of_urls = get_list_of_urls(input())\n", 416 | "#print(list_of_urls)\n", 417 | "list_of_domain = list(set(get_domain_from_list_of_urls(list_of_urls)))\n", 418 | "list_of_domain.sort()\n", 419 | "for domain in list_of_domain:\n", 420 | " print(domain)\n" 421 | ] 422 | } 423 | ], 424 | "metadata": { 425 | "kernelspec": { 426 | "display_name": "Python 3", 427 | "language": "python", 428 | "name": "python3" 429 | }, 430 | "language_info": { 431 | "codemirror_mode": { 432 | "name": "ipython", 433 | "version": 3 434 | }, 435 | "file_extension": ".py", 436 | "mimetype": "text/x-python", 437 | "name": "python", 438 | "nbconvert_exporter": "python", 439 | "pygments_lexer": "ipython3", 440 | "version": "3.5.0" 441 | } 442 | }, 443 | "nbformat": 4, 444 | "nbformat_minor": 0 445 | } 446 | -------------------------------------------------------------------------------- /week3/1. Strings.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Стандартные методы и функции для строк" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Основные методы для работы с поиском в строках" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "### Для того, чтобы найти строку в строке можно воспользоваться ключевым словом in или функцией find и index для определения конткретного места одной строки в другой" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 1, 27 | "metadata": { 28 | "collapsed": false 29 | }, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | "True\n", 36 | "False\n" 37 | ] 38 | } 39 | ], 40 | "source": [ 41 | "print(\"abc\" in \"abcba\")\n", 42 | "print(\"abce\" in \"abcba\")" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 3, 48 | "metadata": { 49 | "collapsed": false 50 | }, 51 | "outputs": [ 52 | { 53 | "name": "stdout", 54 | "output_type": "stream", 55 | "text": [ 56 | "1\n", 57 | "-1\n" 58 | ] 59 | } 60 | ], 61 | "source": [ 62 | "print(\"cabcd\".find(\"abc\")) # Начиная с индекса 1\n", 63 | "print(\"cabcd\".find(\"aec\")) # Если функция ничего не нашла, то возвращает результат: -1" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "##### ! Для того, чтобы получить справку по функции можно воспользоваться атрибутом __doc__ нужного метода" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 4, 76 | "metadata": { 77 | "collapsed": false 78 | }, 79 | "outputs": [ 80 | { 81 | "name": "stdout", 82 | "output_type": "stream", 83 | "text": [ 84 | "S.find(sub[, start[, end]]) -> int\n", 85 | "\n", 86 | "Return the lowest index in S where substring sub is found,\n", 87 | "such that sub is contained within S[start:end]. Optional\n", 88 | "arguments start and end are interpreted as in slice notation.\n", 89 | "\n", 90 | "Return -1 on failure.\n" 91 | ] 92 | } 93 | ], 94 | "source": [ 95 | "print(str.find.__doc__)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "###### Так по справке можно узнать, что в метода find можно указать второй аргумент, который являет индексом, с которого начнется поиск в строке" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 5, 108 | "metadata": { 109 | "collapsed": false 110 | }, 111 | "outputs": [ 112 | { 113 | "name": "stdout", 114 | "output_type": "stream", 115 | "text": [ 116 | "1\n" 117 | ] 118 | } 119 | ], 120 | "source": [ 121 | "print(\"cabcd\".find(\"abc\", 1)) # индекс первого вхождения или -1" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "#### В отличае от метода find, метод index вызывает ошибку ValueError, если строка не была найдена" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 6, 134 | "metadata": { 135 | "collapsed": false 136 | }, 137 | "outputs": [ 138 | { 139 | "name": "stdout", 140 | "output_type": "stream", 141 | "text": [ 142 | "1\n" 143 | ] 144 | }, 145 | { 146 | "ename": "ValueError", 147 | "evalue": "substring not found", 148 | "output_type": "error", 149 | "traceback": [ 150 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 151 | "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", 152 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"cabcd\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"abc\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# индекс первого вхождения или ValueError\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"cabcd\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"aec\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 153 | "\u001b[1;31mValueError\u001b[0m: substring not found" 154 | ] 155 | } 156 | ], 157 | "source": [ 158 | "print(\"cabcd\".index(\"abc\")) # индекс первого вхождения или ValueError\n", 159 | "print(\"cabcd\".index(\"aec\"))" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "### Для того, чтобы проверить начинается ли строка с какой-то другой строки, существует метода startswith" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 7, 172 | "metadata": { 173 | "collapsed": false 174 | }, 175 | "outputs": [ 176 | { 177 | "name": "stdout", 178 | "output_type": "stream", 179 | "text": [ 180 | "True\n" 181 | ] 182 | } 183 | ], 184 | "source": [ 185 | "s = \"The man in black fled across the desert, and the gunslinger followed\"\n", 186 | "print(s.startswith(\"The man in black\"))" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "#### В качестве аргумента метода startswith может выступать не просто строка, но и кортеж из строк. Тогда будет осуществлена проверка на принадлежность к хотя бы одной строке из кортежа" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": 11, 199 | "metadata": { 200 | "collapsed": false 201 | }, 202 | "outputs": [ 203 | { 204 | "name": "stdout", 205 | "output_type": "stream", 206 | "text": [ 207 | "False\n" 208 | ] 209 | } 210 | ], 211 | "source": [ 212 | "s = \"The whale in black fled across the desert, and the gunslinger followed\"\n", 213 | "print(s.startswith((\"The man in black\", \"The dog\", \"The woman\")))" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": {}, 219 | "source": [ 220 | "### Для проверки наличия одной строки в окончании другой, используется метод endswith. С его помощью удобно сделать проверку расширения файла" 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": 12, 226 | "metadata": { 227 | "collapsed": false 228 | }, 229 | "outputs": [ 230 | { 231 | "name": "stdout", 232 | "output_type": "stream", 233 | "text": [ 234 | "True\n" 235 | ] 236 | } 237 | ], 238 | "source": [ 239 | "s = \"image.png\"\n", 240 | "print(s.endswith(\".png\"))" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "### Для расчета вхождения одной строки внутрь другой используется метод count" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": 15, 253 | "metadata": { 254 | "collapsed": false 255 | }, 256 | "outputs": [ 257 | { 258 | "name": "stdout", 259 | "output_type": "stream", 260 | "text": [ 261 | "2\n" 262 | ] 263 | } 264 | ], 265 | "source": [ 266 | "s = \"abacaba\"\n", 267 | "print(s.count(\"aba\"))" 268 | ] 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "metadata": {}, 273 | "source": [ 274 | "### У многих функций по поиску одних строк внутри других есть аналоги для поиска справо налево. Например, у функции find есть аналог rfind." 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 17, 280 | "metadata": { 281 | "collapsed": false 282 | }, 283 | "outputs": [ 284 | { 285 | "name": "stdout", 286 | "output_type": "stream", 287 | "text": [ 288 | "0\n", 289 | "4\n" 290 | ] 291 | } 292 | ], 293 | "source": [ 294 | "s = \"abacaba\"\n", 295 | "print(s.find(\"aba\"))\n", 296 | "print(s.rfind(\"aba\"))" 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "metadata": {}, 302 | "source": [ 303 | "### Для приведения к верхнему и нижнему регистру используются методы upper и lower" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": 18, 309 | "metadata": { 310 | "collapsed": false 311 | }, 312 | "outputs": [ 313 | { 314 | "name": "stdout", 315 | "output_type": "stream", 316 | "text": [ 317 | "the man in black fled across the desert, and the gunslinger followed\n", 318 | "THE MAN IN BLACK FLED ACROSS THE DESERT, AND THE GUNSLINGER FOLLOWED\n" 319 | ] 320 | } 321 | ], 322 | "source": [ 323 | "s = \"The man in black fled across the desert, and the gunslinger followed\"\n", 324 | "print(s.lower())\n", 325 | "print(s.upper())" 326 | ] 327 | }, 328 | { 329 | "cell_type": "markdown", 330 | "metadata": {}, 331 | "source": [ 332 | "### Для замены одних символов в строке на другие используется метод replace" 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": 24, 338 | "metadata": { 339 | "collapsed": false 340 | }, 341 | "outputs": [ 342 | { 343 | "name": "stdout", 344 | "output_type": "stream", 345 | "text": [ 346 | "1,2,3,4\n", 347 | "1, 2, 3,4\n" 348 | ] 349 | } 350 | ], 351 | "source": [ 352 | "s = \"1,2,3,4\"\n", 353 | "print(s)\n", 354 | "print(s.replace(\",\", \", \", 2)) # второй аргумент не обязателен и используется для указания количества замен в тексте" 355 | ] 356 | }, 357 | { 358 | "cell_type": "markdown", 359 | "metadata": {}, 360 | "source": [ 361 | "### Для разбиения строки используется метод split" 362 | ] 363 | }, 364 | { 365 | "cell_type": "code", 366 | "execution_count": 27, 367 | "metadata": { 368 | "collapsed": false 369 | }, 370 | "outputs": [ 371 | { 372 | "name": "stdout", 373 | "output_type": "stream", 374 | "text": [ 375 | "['1', '2', '3 4']\n" 376 | ] 377 | } 378 | ], 379 | "source": [ 380 | "s = \"1 2 3 4\"\n", 381 | "print(s.split(\" \", 2)) # Второй аргумент не обязателен и используется для указания количества разбиений текста\n", 382 | " # По умолчанию равен -1" 383 | ] 384 | }, 385 | { 386 | "cell_type": "markdown", 387 | "metadata": {}, 388 | "source": [ 389 | "#### Если метод split вызвать без аргументов (или с аргументом None), то тогда разбивка произойдет по пробельным символам." 390 | ] 391 | }, 392 | { 393 | "cell_type": "code", 394 | "execution_count": 28, 395 | "metadata": { 396 | "collapsed": false 397 | }, 398 | "outputs": [ 399 | { 400 | "name": "stdout", 401 | "output_type": "stream", 402 | "text": [ 403 | "['1', '2', '3', '4']\n" 404 | ] 405 | } 406 | ], 407 | "source": [ 408 | "s = \"1\\t\\t 2 3 4 \"\n", 409 | "print(s.split())" 410 | ] 411 | }, 412 | { 413 | "cell_type": "markdown", 414 | "metadata": {}, 415 | "source": [ 416 | "### Для удаления части строки используются методы strip, rstrip и lstrip" 417 | ] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "execution_count": 29, 422 | "metadata": { 423 | "collapsed": false 424 | }, 425 | "outputs": [ 426 | { 427 | "name": "stdout", 428 | "output_type": "stream", 429 | "text": [ 430 | "'_*__1, 2, 3, 4'\n", 431 | "'1, 2, 3, 4__*_'\n", 432 | "'1, 2, 3, 4'\n" 433 | ] 434 | } 435 | ], 436 | "source": [ 437 | "s = \"_*__1, 2, 3, 4__*_\"\n", 438 | "print(repr(s.rstrip(\"*_\"))) # удаление символов справа\n", 439 | "print(repr(s.lstrip(\"*_\"))) # удаление символов слева\n", 440 | "print(repr(s.strip(\"*_\"))) # удаление символов из всех строки" 441 | ] 442 | }, 443 | { 444 | "cell_type": "markdown", 445 | "metadata": {}, 446 | "source": [ 447 | "### Метод join принимает в качестве аргумента iterable object и вставляет строку от которой он был вызван между всему элементами последовательности" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": 30, 453 | "metadata": { 454 | "collapsed": false 455 | }, 456 | "outputs": [ 457 | { 458 | "name": "stdout", 459 | "output_type": "stream", 460 | "text": [ 461 | "'1 2 3 4 5'\n" 462 | ] 463 | } 464 | ], 465 | "source": [ 466 | "numbers = map(str, [1, 2, 3, 4, 5])\n", 467 | "print(repr(\" \".join(numbers)))" 468 | ] 469 | }, 470 | { 471 | "cell_type": "markdown", 472 | "metadata": {}, 473 | "source": [ 474 | "## Форматирование строк" 475 | ] 476 | }, 477 | { 478 | "cell_type": "markdown", 479 | "metadata": {}, 480 | "source": [ 481 | "### Часто текст необходимо менять лишь в отдельных местах, оставляя весь остальной текст без изменений. Специально для этого используются шаблоны с методом format." 482 | ] 483 | }, 484 | { 485 | "cell_type": "code", 486 | "execution_count": 3, 487 | "metadata": { 488 | "collapsed": false 489 | }, 490 | "outputs": [ 491 | { 492 | "name": "stdout", 493 | "output_type": "stream", 494 | "text": [ 495 | "London us the capital of Great Britain\n", 496 | "Vaduz us the capital of Liechtenstein\n" 497 | ] 498 | } 499 | ], 500 | "source": [ 501 | "template = '{} is the capital of {}'\n", 502 | "print(template.format(\"London\", \"Great Britain\"))\n", 503 | "print(template.format(\"Vaduz\", \"Liechtenstein\"))" 504 | ] 505 | }, 506 | { 507 | "cell_type": "markdown", 508 | "metadata": {}, 509 | "source": [ 510 | "#### Можно явно указать позицию для вставки элемента в шаблоне" 511 | ] 512 | }, 513 | { 514 | "cell_type": "code", 515 | "execution_count": 4, 516 | "metadata": { 517 | "collapsed": false 518 | }, 519 | "outputs": [ 520 | { 521 | "name": "stdout", 522 | "output_type": "stream", 523 | "text": [ 524 | "Hello, guy. Who are you ?\n" 525 | ] 526 | } 527 | ], 528 | "source": [ 529 | "template = \"{1}, guy. {0}\"\n", 530 | "print(template.format(\"Who are you ?\", \"Hello\"))" 531 | ] 532 | }, 533 | { 534 | "cell_type": "markdown", 535 | "metadata": {}, 536 | "source": [ 537 | "#### Также, можно указать значение для подстановки в шаблон и внутри метода format" 538 | ] 539 | }, 540 | { 541 | "cell_type": "code", 542 | "execution_count": 5, 543 | "metadata": { 544 | "collapsed": false 545 | }, 546 | "outputs": [ 547 | { 548 | "name": "stdout", 549 | "output_type": "stream", 550 | "text": [ 551 | "London is the capital of Great Britain\n", 552 | "Vaduz is the capital of Liechtenstein\n" 553 | ] 554 | } 555 | ], 556 | "source": [ 557 | "template = '{capital} is the capital of {country}'\n", 558 | "print(template.format(capital='London', country='Great Britain'))\n", 559 | "print(template.format(country='Liechtenstein', capital='Vaduz'))" 560 | ] 561 | }, 562 | { 563 | "cell_type": "markdown", 564 | "metadata": {}, 565 | "source": [ 566 | "### Благодаря форматированию можно обращаться к атрибутам объектов, которые были переданы" 567 | ] 568 | }, 569 | { 570 | "cell_type": "markdown", 571 | "metadata": {}, 572 | "source": [ 573 | "##### Пример 1" 574 | ] 575 | }, 576 | { 577 | "cell_type": "code", 578 | "execution_count": 9, 579 | "metadata": { 580 | "collapsed": false 581 | }, 582 | "outputs": [ 583 | { 584 | "name": "stdout", 585 | "output_type": "stream", 586 | "text": [ 587 | "Response from https://docs.python.org/3.5/ with code 200\n", 588 | "Response from https://docs.python.org/3.5/random with code 404\n" 589 | ] 590 | } 591 | ], 592 | "source": [ 593 | "import requests\n", 594 | "template = \"Response from {0.url} with code {0.status_code}\"\n", 595 | "\n", 596 | "res = requests.get(\"http://docs.python.org/3.5/\")\n", 597 | "print(template.format(res))\n", 598 | "\n", 599 | "res = requests.get(\"https://docs.python.org/3.5/random\")\n", 600 | "print(template.format(res))" 601 | ] 602 | }, 603 | { 604 | "cell_type": "markdown", 605 | "metadata": {}, 606 | "source": [ 607 | "##### Пример 2" 608 | ] 609 | }, 610 | { 611 | "cell_type": "code", 612 | "execution_count": 10, 613 | "metadata": { 614 | "collapsed": false 615 | }, 616 | "outputs": [ 617 | { 618 | "name": "stdout", 619 | "output_type": "stream", 620 | "text": [ 621 | "0.6064778776496461\n", 622 | "0.606\n" 623 | ] 624 | } 625 | ], 626 | "source": [ 627 | "from random import random\n", 628 | "x = random()\n", 629 | "print(x)\n", 630 | "print(\"{:.3}\".format(x))" 631 | ] 632 | }, 633 | { 634 | "cell_type": "markdown", 635 | "metadata": {}, 636 | "source": [ 637 | "###### это просто суперкруто!" 638 | ] 639 | }, 640 | { 641 | "cell_type": "markdown", 642 | "metadata": {}, 643 | "source": [ 644 | "## Задачи" 645 | ] 646 | }, 647 | { 648 | "cell_type": "markdown", 649 | "metadata": {}, 650 | "source": [ 651 | "### Задача 1" 652 | ] 653 | }, 654 | { 655 | "cell_type": "code", 656 | "execution_count": 28, 657 | "metadata": { 658 | "collapsed": false 659 | }, 660 | "outputs": [ 661 | { 662 | "name": "stdout", 663 | "output_type": "stream", 664 | "text": [ 665 | "ababac\n", 666 | "c\n", 667 | "c\n", 668 | "Impossible\n" 669 | ] 670 | } 671 | ], 672 | "source": [ 673 | "s = input()\n", 674 | "a = input()\n", 675 | "b = input()\n", 676 | "\n", 677 | "counter = 0\n", 678 | "\n", 679 | "\n", 680 | "while a in s:\n", 681 | " if a in b:\n", 682 | " counter = 'Impossible'\n", 683 | " break\n", 684 | " s = s.replace(a, b)\n", 685 | " counter += 1\n", 686 | "print(counter)\n" 687 | ] 688 | }, 689 | { 690 | "cell_type": "markdown", 691 | "metadata": {}, 692 | "source": [ 693 | "### Задача 2" 694 | ] 695 | }, 696 | { 697 | "cell_type": "code", 698 | "execution_count": 3, 699 | "metadata": { 700 | "collapsed": false 701 | }, 702 | "outputs": [ 703 | { 704 | "name": "stdout", 705 | "output_type": "stream", 706 | "text": [ 707 | "adfsdf\n", 708 | "fs\n", 709 | "1\n" 710 | ] 711 | } 712 | ], 713 | "source": [ 714 | "s = input()\n", 715 | "t = input()\n", 716 | "\n", 717 | "start = 0\n", 718 | "end = start + len(t)\n", 719 | "counter = 0\n", 720 | "\n", 721 | "while end <= len(s):\n", 722 | " if s[start:end] == t:\n", 723 | " counter += 1\n", 724 | " start += 1\n", 725 | " end += 1\n", 726 | "\n", 727 | "print(counter)" 728 | ] 729 | } 730 | ], 731 | "metadata": { 732 | "kernelspec": { 733 | "display_name": "Python 3", 734 | "language": "python", 735 | "name": "python3" 736 | }, 737 | "language_info": { 738 | "codemirror_mode": { 739 | "name": "ipython", 740 | "version": 3 741 | }, 742 | "file_extension": ".py", 743 | "mimetype": "text/x-python", 744 | "name": "python", 745 | "nbconvert_exporter": "python", 746 | "pygments_lexer": "ipython3", 747 | "version": "3.5.1" 748 | } 749 | }, 750 | "nbformat": 4, 751 | "nbformat_minor": 0 752 | } 753 | -------------------------------------------------------------------------------- /week2/3. Iterators and generators.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Итераторы и генераторы" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Итератор - объект-перечислитель, который \"знает\" о следующем элементе. " 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "#### Допустим, есть список x = [1, 2]. У списка есть итератор, который при первом запросе ( функия next() ) вернет 1, при втором - 2, а при третьем запросе вызовет ошибку StopIteration." 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "metadata": { 28 | "collapsed": false 29 | }, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | "1\n", 36 | "2\n" 37 | ] 38 | }, 39 | { 40 | "ename": "StopIteration", 41 | "evalue": "", 42 | "output_type": "error", 43 | "traceback": [ 44 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 45 | "\u001b[1;31mStopIteration\u001b[0m Traceback (most recent call last)", 46 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0miterator\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0miterator\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0miterator\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 47 | "\u001b[1;31mStopIteration\u001b[0m: " 48 | ] 49 | } 50 | ], 51 | "source": [ 52 | "x = [1, 2]\n", 53 | "iterator = iter(x)\n", 54 | "print(next(iterator))\n", 55 | "print(next(iterator))\n", 56 | "print(next(iterator))" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "#### Как на самом деле работает цикл for:" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 5, 69 | "metadata": { 70 | "collapsed": false 71 | }, 72 | "outputs": [ 73 | { 74 | "name": "stdout", 75 | "output_type": "stream", 76 | "text": [ 77 | "year_published author title \n", 78 | "year_published author title " 79 | ] 80 | } 81 | ], 82 | "source": [ 83 | "# Пример со словарем\n", 84 | "book = {\n", 85 | " 'title': 'The Langoliers',\n", 86 | " 'author': 'Stephen King',\n", 87 | " 'year_published': 1990\n", 88 | "}\n", 89 | "\n", 90 | "# Стандартный цикл for\n", 91 | "for i in book:\n", 92 | " print(i, end = ' ')\n", 93 | "\n", 94 | "print()\n", 95 | " \n", 96 | "# Альтернатива циклу for\n", 97 | "it = iter(book)\n", 98 | "while True:\n", 99 | " try:\n", 100 | " i = next(it)\n", 101 | " print(i, end = ' ')\n", 102 | " except StopIteration:\n", 103 | " break\n", 104 | " \n", 105 | "# Результат работы будет идентичен для любого итерируемого множества значение (словарь, список и т.д.)" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "#### Итераторы удобно использовать для перебора значений в собственном классе" 113 | ] 114 | }, 115 | { 116 | "cell_type": "markdown", 117 | "metadata": {}, 118 | "source": [ 119 | "##### Для того, чтобы сделать класс итерируемым, необходимо добавить в него метод __next__" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 32, 125 | "metadata": { 126 | "collapsed": false 127 | }, 128 | "outputs": [ 129 | { 130 | "name": "stdout", 131 | "output_type": "stream", 132 | "text": [ 133 | "0.6031746933791006\n", 134 | "0.9320624366212921\n", 135 | "0.3720349275674475\n" 136 | ] 137 | }, 138 | { 139 | "ename": "StopIteration", 140 | "evalue": "", 141 | "output_type": "error", 142 | "traceback": [ 143 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 144 | "\u001b[1;31mStopIteration\u001b[0m Traceback (most recent call last)", 145 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 18\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 19\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 20\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# При попытке вывести 4-ое число, возникает ошибка StopItaration\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 146 | "\u001b[1;32m\u001b[0m in \u001b[0;36m__next__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 12\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mrandom\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 13\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 14\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mStopIteration\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 15\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[0mx\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mRandomIterator\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# Создаем класс для вывода 3 случайных чисел\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 147 | "\u001b[1;31mStopIteration\u001b[0m: " 148 | ] 149 | } 150 | ], 151 | "source": [ 152 | "from random import random\n", 153 | "\n", 154 | "# Итератор данного класса возвращает число от 0 до 1\n", 155 | "class RandomIterator:\n", 156 | " def __init__(self, k):\n", 157 | " self.k = k # Количество чисел, которые будут выведен\n", 158 | " self.i = 0 # Количество уже перечисленных чисел\n", 159 | " \n", 160 | " def __next__(self):\n", 161 | " if self.i < self.k:\n", 162 | " self.i += 1\n", 163 | " return random()\n", 164 | " else:\n", 165 | " raise StopIteration\n", 166 | " \n", 167 | "x = RandomIterator(3) # Создаем класс для вывода 3 случайных чисел\n", 168 | "print(next(x)) # next(x) ~ x.__next__(), x -- iterator\n", 169 | "print(next(x))\n", 170 | "print(next(x))\n", 171 | "print(next(x)) # При попытке вывести 4-ое число, возникает ошибка StopItaration" 172 | ] 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "metadata": {}, 177 | "source": [ 178 | "##### Для того, чтобы пользоваться собственным интеретором в цикле for, необходимо сделать так, чтобы к нашему класса стала применима функция iter(OurClass) " 179 | ] 180 | }, 181 | { 182 | "cell_type": "markdown", 183 | "metadata": {}, 184 | "source": [ 185 | "##### Для этого в классе добавляется новый метод - __iter__(self)" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": 33, 191 | "metadata": { 192 | "collapsed": false 193 | }, 194 | "outputs": [ 195 | { 196 | "name": "stdout", 197 | "output_type": "stream", 198 | "text": [ 199 | "0.7511639708765198\n", 200 | "0.6725760817590697\n", 201 | "0.5242811862821755\n", 202 | "0.13444313889360582\n", 203 | "0.26930906566637225\n", 204 | "0.8388957781049017\n", 205 | "0.043991401100652805\n", 206 | "0.7284012259893162\n", 207 | "0.7424071456845994\n", 208 | "0.3444885809651007\n" 209 | ] 210 | } 211 | ], 212 | "source": [ 213 | "from random import random\n", 214 | "\n", 215 | "# Итератор данного класса возвращает число от 0 до 1\n", 216 | "class RandomIterator:\n", 217 | " def __iter__(self):\n", 218 | " return self\n", 219 | " \n", 220 | " def __init__(self, k):\n", 221 | " self.k = k # Количество чисел, которые будут выведен\n", 222 | " self.i = 0 # Количество уже перечисленных чисел\n", 223 | " \n", 224 | " def __next__(self):\n", 225 | " if self.i < self.k:\n", 226 | " self.i += 1\n", 227 | " return random()\n", 228 | " else:\n", 229 | " raise StopIteration\n", 230 | " \n", 231 | "for x in RandomIterator(10):\n", 232 | " print(x)" 233 | ] 234 | }, 235 | { 236 | "cell_type": "markdown", 237 | "metadata": { 238 | "collapsed": true 239 | }, 240 | "source": [ 241 | "##### Пример итератора для вовзращения пары значений" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 37, 247 | "metadata": { 248 | "collapsed": false 249 | }, 250 | "outputs": [ 251 | { 252 | "name": "stdout", 253 | "output_type": "stream", 254 | "text": [ 255 | "(1, 2)\n", 256 | "(3, 4)\n" 257 | ] 258 | } 259 | ], 260 | "source": [ 261 | "class DoubleElementListIterator:\n", 262 | " def __init__(self, lst):\n", 263 | " self.lst = lst # Сам список\n", 264 | " self.i = 0 # Отсчет \n", 265 | " \n", 266 | " def __next__(self):\n", 267 | " if self.i < len(self.lst): # если i < размера списка\n", 268 | " self.i += 2 # прибавляем 2 к i\n", 269 | " return self.lst[self.i - 2], self.lst[self.i - 1] # и возвращаем два значения из списка\n", 270 | " else:\n", 271 | " raise StopIteration\n", 272 | " \n", 273 | "class MyList(list): # Класс MyList наследуется от класса list\n", 274 | " def __iter__(self):\n", 275 | " return DoubleElementListIterator(self) # Почему объект DoubleElementListIterator возвращаем два элемента ?\n", 276 | " \n", 277 | "for pair in MyList([1, 2, 3, 4]):\n", 278 | " print(pair)\n" 279 | ] 280 | }, 281 | { 282 | "cell_type": "markdown", 283 | "metadata": {}, 284 | "source": [ 285 | "##### Для таких простых задач использование итераторов накладно, т.к. надо создавать классы, а это не быстро и занимает много строчек кода. Как раз для это в python есть генераторы." 286 | ] 287 | }, 288 | { 289 | "cell_type": "markdown", 290 | "metadata": {}, 291 | "source": [ 292 | "### Генератор - функция, которая вместо того, чтобы возвращать какое-нибудь значение, генерирует его." 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": {}, 298 | "source": [ 299 | "##### Для этого используется ключевое слова yield" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": 6, 305 | "metadata": { 306 | "collapsed": false 307 | }, 308 | "outputs": [ 309 | { 310 | "name": "stdout", 311 | "output_type": "stream", 312 | "text": [ 313 | "\n" 314 | ] 315 | } 316 | ], 317 | "source": [ 318 | "def random_generator(k):\n", 319 | " for i in range(k):\n", 320 | " yield random()\n", 321 | " \n", 322 | "gen = random_generator(3)\n", 323 | "print(type(gen))" 324 | ] 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "metadata": {}, 329 | "source": [ 330 | "##### Работа генератора заключается в следующем: интерпретатор выполняет тело генератора до тех пор пока не встретит ключевое слово yield, после чего вернет значение. Однако, при следующем вызове генератора, интерпретатор продолжет выполнение с того места, на котором он остановился и до нового значения yield. И так далее." 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "##### Если после очередного вызова интерпретатор дойдет до конца генератора и не встретит ключевое слово yield, то будет вызвана ошибка StopIteration." 338 | ] 339 | }, 340 | { 341 | "cell_type": "markdown", 342 | "metadata": {}, 343 | "source": [ 344 | "##### Пример" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": 10, 350 | "metadata": { 351 | "collapsed": false 352 | }, 353 | "outputs": [ 354 | { 355 | "name": "stdout", 356 | "output_type": "stream", 357 | "text": [ 358 | "Checkpoint 1\n", 359 | "1\n", 360 | "Checkpoint 2\n", 361 | "2\n", 362 | "Checkpoint 3\n" 363 | ] 364 | }, 365 | { 366 | "ename": "StopIteration", 367 | "evalue": "", 368 | "output_type": "error", 369 | "traceback": [ 370 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 371 | "\u001b[1;31mStopIteration\u001b[0m Traceback (most recent call last)", 372 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 11\u001b[0m \u001b[0my\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgen\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 12\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 13\u001b[1;33m \u001b[0mz\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgen\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 373 | "\u001b[1;31mStopIteration\u001b[0m: " 374 | ] 375 | } 376 | ], 377 | "source": [ 378 | "def simple_gen():\n", 379 | " print(\"Checkpoint 1\")\n", 380 | " yield 1\n", 381 | " print(\"Checkpoint 2\")\n", 382 | " yield 2\n", 383 | " print(\"Checkpoint 3\")\n", 384 | " \n", 385 | "gen = simple_gen()\n", 386 | "x = next(gen)\n", 387 | "print(x)\n", 388 | "y = next(gen)\n", 389 | "print(y)\n", 390 | "z = next(gen)\n" 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": 11, 396 | "metadata": { 397 | "collapsed": false 398 | }, 399 | "outputs": [ 400 | { 401 | "name": "stdout", 402 | "output_type": "stream", 403 | "text": [ 404 | "Checkpoint 1\n", 405 | "1\n", 406 | "Checkpoint 2\n", 407 | "2\n", 408 | "Checkpoint 3\n" 409 | ] 410 | } 411 | ], 412 | "source": [ 413 | "for i in simple_gen():\n", 414 | " print(i)" 415 | ] 416 | }, 417 | { 418 | "cell_type": "markdown", 419 | "metadata": {}, 420 | "source": [ 421 | "##### Такой подход в программировании носит название \"Концепция отложенного исполнения\"" 422 | ] 423 | }, 424 | { 425 | "cell_type": "markdown", 426 | "metadata": {}, 427 | "source": [ 428 | "##### Таким образом удобный генератор для k случайных чисел будет выглядеть следующим образом" 429 | ] 430 | }, 431 | { 432 | "cell_type": "code", 433 | "execution_count": 24, 434 | "metadata": { 435 | "collapsed": false 436 | }, 437 | "outputs": [ 438 | { 439 | "name": "stdout", 440 | "output_type": "stream", 441 | "text": [ 442 | "0.9459063795938274\n", 443 | "0.7598931795804734\n", 444 | "0.6949079834391128\n" 445 | ] 446 | } 447 | ], 448 | "source": [ 449 | "from random import random\n", 450 | "\n", 451 | "def random_generator(k):\n", 452 | " for i in range(k):\n", 453 | " yield random()\n", 454 | "\n", 455 | "gen = random_generator(3)\n", 456 | "for i in gen:\n", 457 | " print(i)" 458 | ] 459 | }, 460 | { 461 | "cell_type": "markdown", 462 | "metadata": { 463 | "collapsed": true 464 | }, 465 | "source": [ 466 | "##### Если внутри генератора интерпретатор встретит return, то будет вызвана ошибка StopItaration, а возвращаемое значение return будет сообщением об ошибке." 467 | ] 468 | }, 469 | { 470 | "cell_type": "code", 471 | "execution_count": 25, 472 | "metadata": { 473 | "collapsed": false 474 | }, 475 | "outputs": [ 476 | { 477 | "name": "stdout", 478 | "output_type": "stream", 479 | "text": [ 480 | "Checkpoint 1\n", 481 | "1\n", 482 | "Checkpoint 2\n", 483 | "2\n", 484 | "Checkpoint 3\n" 485 | ] 486 | }, 487 | { 488 | "ename": "StopIteration", 489 | "evalue": "No more elements", 490 | "output_type": "error", 491 | "traceback": [ 492 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 493 | "\u001b[1;31mStopIteration\u001b[0m Traceback (most recent call last)", 494 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgen\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 11\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgen\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 12\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgen\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 495 | "\u001b[1;31mStopIteration\u001b[0m: No more elements" 496 | ] 497 | } 498 | ], 499 | "source": [ 500 | "def simple_gen():\n", 501 | " print(\"Checkpoint 1\")\n", 502 | " yield 1\n", 503 | " print(\"Checkpoint 2\")\n", 504 | " yield 2\n", 505 | " print(\"Checkpoint 3\")\n", 506 | " return 'No more elements'\n", 507 | "\n", 508 | "gen = simple_gen()\n", 509 | "print(next(gen))\n", 510 | "print(next(gen))\n", 511 | "print(next(gen))\n" 512 | ] 513 | }, 514 | { 515 | "cell_type": "markdown", 516 | "metadata": {}, 517 | "source": [ 518 | "###### Сообщение No more elements было взято из return" 519 | ] 520 | }, 521 | { 522 | "cell_type": "markdown", 523 | "metadata": {}, 524 | "source": [ 525 | "###### Задача 1" 526 | ] 527 | }, 528 | { 529 | "cell_type": "code", 530 | "execution_count": null, 531 | "metadata": { 532 | "collapsed": true 533 | }, 534 | "outputs": [], 535 | "source": [ 536 | "class multifilter:\n", 537 | " def judge_half(pos, neg):\n", 538 | " # допускает элемент, если его допускает хотя бы половина фукнций (pos >= neg)\n", 539 | " return pos >= neg\n", 540 | "\n", 541 | " def judge_any(pos, neg):\n", 542 | " # допускает элемент, если его допускает хотя бы одна функция (pos >= 1)\n", 543 | " return pos >= 1\n", 544 | "\n", 545 | " def judge_all(pos, neg):\n", 546 | " # допускает элемент, если его допускают все функции (neg == 0)\n", 547 | " return neg == 0\n", 548 | "\n", 549 | " def __init__(self, iterable, *funcs, judge=judge_any):\n", 550 | " # iterable - исходная последовательность\n", 551 | " # funcs - допускающие функции\n", 552 | " # judge - решающая функция\n", 553 | " self.pos = 0;\n", 554 | " self.neg = 0;\n", 555 | " self.i = 0\n", 556 | " self.n = len(iterable)\n", 557 | " self.iterable = iterable\n", 558 | " self.funcs = funcs\n", 559 | " self.judge = judge\n", 560 | "\n", 561 | " def __next__(self):\n", 562 | " while True:\n", 563 | " if self.i < self.n:\n", 564 | " for f in self.funcs:\n", 565 | " if f(self.iterable[self.i]):\n", 566 | " self.pos += 1\n", 567 | " else:\n", 568 | " self.neg += 1\n", 569 | "\n", 570 | " if self.judge(self.pos, self.neg):\n", 571 | " self.pos = 0\n", 572 | " self.neg = 0\n", 573 | " res = self.i\n", 574 | " self.i += 1\n", 575 | " return res\n", 576 | " self.i += 1\n", 577 | " self.pos = 0\n", 578 | " self.neg = 0\n", 579 | " else:\n", 580 | " raise StopIteration\n", 581 | "\n", 582 | " def __iter__(self):\n", 583 | " # возвращает итератор по результирующей последовательности\n", 584 | " return self" 585 | ] 586 | }, 587 | { 588 | "cell_type": "markdown", 589 | "metadata": {}, 590 | "source": [ 591 | "##### Задача 2" 592 | ] 593 | }, 594 | { 595 | "cell_type": "code", 596 | "execution_count": null, 597 | "metadata": { 598 | "collapsed": true 599 | }, 600 | "outputs": [], 601 | "source": [ 602 | "def primes():\n", 603 | " prime = True\n", 604 | " i = 1\n", 605 | " while True:\n", 606 | " i += 1\n", 607 | " for j in range(2, i):\n", 608 | " if i % j == 0:\n", 609 | " prime = False\n", 610 | " if prime:\n", 611 | " yield i\n", 612 | " else:\n", 613 | " prime = True" 614 | ] 615 | }, 616 | { 617 | "cell_type": "markdown", 618 | "metadata": {}, 619 | "source": [ 620 | "### List comprehension" 621 | ] 622 | }, 623 | { 624 | "cell_type": "markdown", 625 | "metadata": {}, 626 | "source": [ 627 | "#### List comprehension - способ создания списка \"не лету\", т.е. возможность объявить содержимое списка прямо внутри списка" 628 | ] 629 | }, 630 | { 631 | "cell_type": "code", 632 | "execution_count": 11, 633 | "metadata": { 634 | "collapsed": false 635 | }, 636 | "outputs": [ 637 | { 638 | "name": "stdout", 639 | "output_type": "stream", 640 | "text": [ 641 | "[1, 4]\n" 642 | ] 643 | } 644 | ], 645 | "source": [ 646 | "x = [-2, -1, 0, 1, 2]\n", 647 | "y = [i * i for i in x if i > 0]\n", 648 | "print(y)" 649 | ] 650 | }, 651 | { 652 | "cell_type": "markdown", 653 | "metadata": {}, 654 | "source": [ 655 | "#### С помощью list comprehension можно генерировать и несколько значений, например, можно сделать список пар чисел, второй элемент которого, больше первого" 656 | ] 657 | }, 658 | { 659 | "cell_type": "code", 660 | "execution_count": 12, 661 | "metadata": { 662 | "collapsed": false 663 | }, 664 | "outputs": [ 665 | { 666 | "name": "stdout", 667 | "output_type": "stream", 668 | "text": [ 669 | "[(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)]\n" 670 | ] 671 | } 672 | ], 673 | "source": [ 674 | "z = [(x, y) for x in range(3) for y in range(3) if y >= x]\n", 675 | "print(z)" 676 | ] 677 | }, 678 | { 679 | "cell_type": "markdown", 680 | "metadata": {}, 681 | "source": [ 682 | "#### Если в такой конструкции заменить квадратные скобки на круглые то получится объект генератора (круто!!!)" 683 | ] 684 | }, 685 | { 686 | "cell_type": "code", 687 | "execution_count": 13, 688 | "metadata": { 689 | "collapsed": false 690 | }, 691 | "outputs": [ 692 | { 693 | "name": "stdout", 694 | "output_type": "stream", 695 | "text": [ 696 | " at 0x00000000043822B0>\n", 697 | "(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)\n" 698 | ] 699 | } 700 | ], 701 | "source": [ 702 | "z = ((x, y) for x in range(3) for y in range(3) if y >= x)\n", 703 | "print(z)\n", 704 | "print(next(z), end= \", \")\n", 705 | "print(next(z), end= \", \")\n", 706 | "print(next(z), end= \", \")\n", 707 | "print(next(z), end= \", \")\n", 708 | "print(next(z), end= \", \")\n", 709 | "print(next(z))" 710 | ] 711 | }, 712 | { 713 | "cell_type": "markdown", 714 | "metadata": {}, 715 | "source": [ 716 | "###### Примечание" 717 | ] 718 | }, 719 | { 720 | "cell_type": "code", 721 | "execution_count": 1, 722 | "metadata": { 723 | "collapsed": false 724 | }, 725 | "outputs": [ 726 | { 727 | "name": "stdout", 728 | "output_type": "stream", 729 | "text": [ 730 | "[1, 2, 3, 4]\n", 731 | "[1, 2, 3, 4]\n" 732 | ] 733 | } 734 | ], 735 | "source": [ 736 | "# такая запись\n", 737 | "a = [i + 1 for i in range(4)]\n", 738 | "\n", 739 | "#эквивалентна такой\n", 740 | "b = list(i + 1 for i in range(4))\n", 741 | "\n", 742 | "#Проверим\n", 743 | "print(a)\n", 744 | "print(b)" 745 | ] 746 | } 747 | ], 748 | "metadata": { 749 | "kernelspec": { 750 | "display_name": "Python 3", 751 | "language": "python", 752 | "name": "python3" 753 | }, 754 | "language_info": { 755 | "codemirror_mode": { 756 | "name": "ipython", 757 | "version": 3 758 | }, 759 | "file_extension": ".py", 760 | "mimetype": "text/x-python", 761 | "name": "python", 762 | "nbconvert_exporter": "python", 763 | "pygments_lexer": "ipython3", 764 | "version": "3.5.0" 765 | } 766 | }, 767 | "nbformat": 4, 768 | "nbformat_minor": 0 769 | } 770 | -------------------------------------------------------------------------------- /week2/1.Errors and exceptions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Неделя 2. Стандартные средства языка Python " 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Ошибки и исключения " 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "### Все ошибки деляется на два типа" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "#### 1. SyntaxError - ошибка в синтаксисе" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "##### Пример " 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 1, 41 | "metadata": { 42 | "collapsed": false 43 | }, 44 | "outputs": [ 45 | { 46 | "ename": "SyntaxError", 47 | "evalue": "invalid syntax (, line 1)", 48 | "output_type": "error", 49 | "traceback": [ 50 | "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m def myFinc\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" 51 | ] 52 | } 53 | ], 54 | "source": [ 55 | "print(\"This line will not be executed\")\n", 56 | "def myFinc\n", 57 | " pass" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "Перед тем как интерпритатор начинает свою работу, он проверяет весь код целиком на синтаксические ошибки и только если их нет, начинается исполнение программы." 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "#### 2. Ошибки, которые встречаются в момент выполнения программы" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 4, 77 | "metadata": { 78 | "collapsed": false 79 | }, 80 | "outputs": [ 81 | { 82 | "name": "stdout", 83 | "output_type": "stream", 84 | "text": [ 85 | "This line will be executed\n" 86 | ] 87 | }, 88 | { 89 | "ename": "TypeError", 90 | "evalue": "unorderable types: str() < int()", 91 | "output_type": "error", 92 | "traceback": [ 93 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 94 | "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", 95 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'This line will be executed'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mlst\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'abc'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mlst\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msort\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 96 | "\u001b[1;31mTypeError\u001b[0m: unorderable types: str() < int()" 97 | ] 98 | } 99 | ], 100 | "source": [ 101 | "print('This line will be executed')\n", 102 | "lst = [1, 2, 'abc', 3]\n", 103 | "lst.sort() # TypeError, т.к. строки и числа не могут сравниваться" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "#### В Python ошибка - это обычные класс, которые имеет 3 обязательных атрибута" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "##### 1. Название ошибки" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": {}, 123 | "source": [ 124 | "##### 2. Дополнительная информация об ошибки" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "##### 3. Состояние стека вызова на этапе совершения ошибки" 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": {}, 137 | "source": [ 138 | "##### Пример " 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 7, 144 | "metadata": { 145 | "collapsed": false 146 | }, 147 | "outputs": [ 148 | { 149 | "ename": "IndexError", 150 | "evalue": "list index out of range", 151 | "output_type": "error", 152 | "traceback": [ 153 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 154 | "\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)", 155 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mx\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 156 | "\u001b[1;32m\u001b[0m in \u001b[0;36mf\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mx\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 157 | "\u001b[1;31mIndexError\u001b[0m: list index out of range" 158 | ] 159 | } 160 | ], 161 | "source": [ 162 | "def f():\n", 163 | " x = [1, 2, 3]\n", 164 | " print(x[4])\n", 165 | "f()" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "###### Здесь " 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "###### IndexError - название ошибки " 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "###### list index out of range - дополнительная информация об ошибки" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "###### Стек вызова: " 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "###### module() - основная функция программы, отсюда нам ошибка и попала" 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "metadata": {}, 206 | "source": [ 207 | "###### f() - функция, которая \"передала\" ошибку функции module()" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "### Ошибки можно ловить " 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "execution_count": 9, 220 | "metadata": { 221 | "collapsed": false 222 | }, 223 | "outputs": [ 224 | { 225 | "name": "stdout", 226 | "output_type": "stream", 227 | "text": [ 228 | "Type error :(\n", 229 | "It will be executed after error\n" 230 | ] 231 | } 232 | ], 233 | "source": [ 234 | "try: # ключевое слово для участка кода, который мы хотели бы проверить на ошибки\n", 235 | " x = [1, 2, \"hello\", 7]\n", 236 | " x.sort()\n", 237 | " print(x)\n", 238 | "except TypeError: # ошибка, которую мы ловим\n", 239 | " print(\"Type error :(\")\n", 240 | " \n", 241 | "print(\"It will be executed after error\")" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 12, 247 | "metadata": { 248 | "collapsed": false 249 | }, 250 | "outputs": [ 251 | { 252 | "name": "stdout", 253 | "output_type": "stream", 254 | "text": [ 255 | "Type error\n", 256 | "Zero division error\n" 257 | ] 258 | } 259 | ], 260 | "source": [ 261 | "def f(x, y):\n", 262 | " try:\n", 263 | " return x / y\n", 264 | " # ошибка будет будет проброшена по всем except'ам, пока не встретит подходящий\n", 265 | " except TypeError:\n", 266 | " print(\"Type error\")\n", 267 | " except ZeroDivisionError:\n", 268 | " print(\"Zero division error\")\n", 269 | " \n", 270 | "f(5, 'abc')\n", 271 | "f(5, 0)" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": null, 277 | "metadata": { 278 | "collapsed": true 279 | }, 280 | "outputs": [], 281 | "source": [ 282 | "def f(x, y):\n", 283 | " try:\n", 284 | " return x / y\n", 285 | " # ошибки можно обрабатывать и списком:\n", 286 | " except (TypeError, ZeroDivisionError):\n", 287 | " print(\"Some error\")" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": 14, 293 | "metadata": { 294 | "collapsed": false 295 | }, 296 | "outputs": [ 297 | { 298 | "name": "stdout", 299 | "output_type": "stream", 300 | "text": [ 301 | "\n", 302 | "division by zero\n", 303 | "('division by zero',)\n" 304 | ] 305 | } 306 | ], 307 | "source": [ 308 | "def f(x, y):\n", 309 | " try:\n", 310 | " return x / y\n", 311 | " # как и во многих современных языках, в Python можно создать класс, который содержит объект - ошибку:\n", 312 | " except (TypeError, ZeroDivisionError) as e:\n", 313 | " print(type(e))\n", 314 | " print(e)\n", 315 | " print(e.args)\n", 316 | "f(5, 0)" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": {}, 322 | "source": [ 323 | "###### Имеется возможность ловли любой возникающей ошибки" 324 | ] 325 | }, 326 | { 327 | "cell_type": "code", 328 | "execution_count": 17, 329 | "metadata": { 330 | "collapsed": false 331 | }, 332 | "outputs": [ 333 | { 334 | "name": "stdout", 335 | "output_type": "stream", 336 | "text": [ 337 | "Some Error\n" 338 | ] 339 | } 340 | ], 341 | "source": [ 342 | "try:\n", 343 | " 7 / 0\n", 344 | "except:\n", 345 | " print('Some Error')" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "###### Более подробный разбор действий про возникновении ошибки " 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": 19, 358 | "metadata": { 359 | "collapsed": false 360 | }, 361 | "outputs": [ 362 | { 363 | "name": "stdout", 364 | "output_type": "stream", 365 | "text": [ 366 | "Division by zero\n" 367 | ] 368 | } 369 | ], 370 | "source": [ 371 | "try:\n", 372 | " 15 / 0\n", 373 | " # при возникновении ошибки, формируется некий объект e\n", 374 | " \n", 375 | "# если выполняется условие isinstance (e, ZeroDivisionError) == True\n", 376 | "except ZeroDivisionError: \n", 377 | " # то мы попадаем в обработчик ошибки\n", 378 | " print(\"Division by zero\")\n", 379 | " \n", 380 | "# иначе ошибка пробрасывается дальше" 381 | ] 382 | }, 383 | { 384 | "cell_type": "markdown", 385 | "metadata": {}, 386 | "source": [ 387 | "##### Ошибки наследуются друг от друга " 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "execution_count": 20, 393 | "metadata": { 394 | "collapsed": false 395 | }, 396 | "outputs": [ 397 | { 398 | "name": "stdout", 399 | "output_type": "stream", 400 | "text": [ 401 | "Division by zero\n", 402 | "[, , , , ]\n" 403 | ] 404 | } 405 | ], 406 | "source": [ 407 | "try:\n", 408 | " 15 / 0\n", 409 | "\n", 410 | "except : \n", 411 | " print(\"Division by zero\")\n", 412 | " \n", 413 | "print(ZeroDivisionError.mro())" 414 | ] 415 | }, 416 | { 417 | "cell_type": "markdown", 418 | "metadata": {}, 419 | "source": [ 420 | "В Python ошибки не используют множественное наследование, поэтому можно сказать точко кто является предком определенной ошибки." 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": 21, 426 | "metadata": { 427 | "collapsed": false 428 | }, 429 | "outputs": [ 430 | { 431 | "name": "stdout", 432 | "output_type": "stream", 433 | "text": [ 434 | "arithmetic error\n" 435 | ] 436 | } 437 | ], 438 | "source": [ 439 | "try:\n", 440 | " 15 / 0\n", 441 | " \n", 442 | "# можно поймать ошибку по ее предку\n", 443 | "except ArithmeticError: # isinstance (e, ArithmeticError) == True\n", 444 | " print(\"arithmetic error\")" 445 | ] 446 | }, 447 | { 448 | "cell_type": "markdown", 449 | "metadata": {}, 450 | "source": [ 451 | "Таким образом мы поймали арифметическую ошибку без уточнения того, что она возникает из-за деления на ноль." 452 | ] 453 | }, 454 | { 455 | "cell_type": "markdown", 456 | "metadata": {}, 457 | "source": [ 458 | "###### else - ключевое слово на случай выполнения кода, если исключение не произошло " 459 | ] 460 | }, 461 | { 462 | "cell_type": "markdown", 463 | "metadata": {}, 464 | "source": [ 465 | "###### finally - ключевое слово для участка кода, который будет выполнен независимо от ошибки (в любом случае)" 466 | ] 467 | }, 468 | { 469 | "cell_type": "code", 470 | "execution_count": 22, 471 | "metadata": { 472 | "collapsed": false 473 | }, 474 | "outputs": [ 475 | { 476 | "name": "stdout", 477 | "output_type": "stream", 478 | "text": [ 479 | "result is 2.0\n", 480 | "finally\n", 481 | "division by zero\n", 482 | "finally\n", 483 | "finally\n" 484 | ] 485 | }, 486 | { 487 | "ename": "TypeError", 488 | "evalue": "unsupported operand type(s) for /: 'int' and 'list'", 489 | "output_type": "error", 490 | "traceback": [ 491 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 492 | "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", 493 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 11\u001b[0m \u001b[0mdivide\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 12\u001b[0m \u001b[0mdivide\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 13\u001b[1;33m \u001b[0mdivide\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 494 | "\u001b[1;32m\u001b[0m in \u001b[0;36mdivide\u001b[1;34m(x, y)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdivide\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mx\u001b[0m \u001b[1;33m/\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mZeroDivisionError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"division by zero\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 495 | "\u001b[1;31mTypeError\u001b[0m: unsupported operand type(s) for /: 'int' and 'list'" 496 | ] 497 | } 498 | ], 499 | "source": [ 500 | "def divide(x, y):\n", 501 | " try:\n", 502 | " result = x / y\n", 503 | " except ZeroDivisionError:\n", 504 | " print(\"division by zero\")\n", 505 | " else:\n", 506 | " print(\"result is\", result)\n", 507 | " finally:\n", 508 | " print(\"finally\")\n", 509 | " \n", 510 | "divide(2, 1) # все правильно, ошибки не будет, а значит выполнится блок else и finally\n", 511 | "divide(2, 0) # здесь возникнет ошибка деления на ноль, поэтому произойдет вызов блока except ZeroDivisionError и finally\n", 512 | "divide(2, []) # здесь возникает TypeError, который никем не обратывается, произойдет вызов блока finally, \n", 513 | "# программа прекратит выполнение и пробросит ошибку на экран" 514 | ] 515 | }, 516 | { 517 | "cell_type": "markdown", 518 | "metadata": {}, 519 | "source": [ 520 | "### Ошибки можно бросать самому " 521 | ] 522 | }, 523 | { 524 | "cell_type": "markdown", 525 | "metadata": {}, 526 | "source": [ 527 | "#### Для этого используется ключевое слово rise " 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": 23, 533 | "metadata": { 534 | "collapsed": false 535 | }, 536 | "outputs": [ 537 | { 538 | "name": "stdout", 539 | "output_type": "stream", 540 | "text": [ 541 | "Hello, Anton\n" 542 | ] 543 | }, 544 | { 545 | "ename": "ValueError", 546 | "evalue": "anton is inappropriate name", 547 | "output_type": "error", 548 | "traceback": [ 549 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 550 | "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", 551 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgreet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Anton\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 8\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgreet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"anton\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 552 | "\u001b[1;32m\u001b[0m in \u001b[0;36mgreet\u001b[1;34m(name)\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;34m\"Hello, \"\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mname\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;34m\" is inappropriate name\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgreet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Anton\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 553 | "\u001b[1;31mValueError\u001b[0m: anton is inappropriate name" 554 | ] 555 | } 556 | ], 557 | "source": [ 558 | "def greet(name):\n", 559 | " if name[0].isupper(): # если используется верхний регистр\n", 560 | " return \"Hello, \" + name\n", 561 | " else:\n", 562 | " raise ValueError(name + \" is inappropriate name\") # конструктор ошибки ValueError\n", 563 | " \n", 564 | "print(greet(\"Anton\"))\n", 565 | "print(greet(\"anton\"))" 566 | ] 567 | }, 568 | { 569 | "cell_type": "code", 570 | "execution_count": 24, 571 | "metadata": { 572 | "collapsed": false 573 | }, 574 | "outputs": [ 575 | { 576 | "name": "stdout", 577 | "output_type": "stream", 578 | "text": [ 579 | "Please enter your namesergei\n", 580 | "Please try again\n", 581 | "Please enter your nameSergei\n", 582 | "Hello, Sergei\n" 583 | ] 584 | } 585 | ], 586 | "source": [ 587 | "def greet(name):\n", 588 | " if name[0].isupper(): # если используется верхний регистр\n", 589 | " return \"Hello, \" + name\n", 590 | " else:\n", 591 | " raise ValueError(name + \" is inappropriate name\") # конструктор ошибки ValueError\n", 592 | " \n", 593 | "while True:\n", 594 | " try:\n", 595 | " name = input(\"Please enter your name\")\n", 596 | " print(greet(name))\n", 597 | " except ValueError:\n", 598 | " print(\"Please try again\")\n", 599 | " else:\n", 600 | " break " 601 | ] 602 | }, 603 | { 604 | "cell_type": "markdown", 605 | "metadata": {}, 606 | "source": [ 607 | "##### Написание собственной ошибки" 608 | ] 609 | }, 610 | { 611 | "cell_type": "code", 612 | "execution_count": 25, 613 | "metadata": { 614 | "collapsed": false 615 | }, 616 | "outputs": [ 617 | { 618 | "name": "stdout", 619 | "output_type": "stream", 620 | "text": [ 621 | "Hello, Anton\n" 622 | ] 623 | }, 624 | { 625 | "ename": "BadName", 626 | "evalue": "anton is inappropriate name", 627 | "output_type": "error", 628 | "traceback": [ 629 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 630 | "\u001b[1;31mBadName\u001b[0m Traceback (most recent call last)", 631 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgreet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Anton\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 11\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgreet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"anton\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 632 | "\u001b[1;32m\u001b[0m in \u001b[0;36mgreet\u001b[1;34m(name)\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;34m\"Hello, \"\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 8\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mBadName\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mname\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;34m\" is inappropriate name\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# конструктор ошибки ValueError\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 9\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgreet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Anton\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 633 | "\u001b[1;31mBadName\u001b[0m: anton is inappropriate name" 634 | ] 635 | } 636 | ], 637 | "source": [ 638 | "#####################################################################\n", 639 | "class BadName(Exception): # Exception - предок всех исключений\n", 640 | " pass\n", 641 | "#####################################################################\n", 642 | "\n", 643 | "\n", 644 | "def greet(name):\n", 645 | " if name[0].isupper(): \n", 646 | " return \"Hello, \" + name\n", 647 | " else:\n", 648 | " raise BadName(name + \" is inappropriate name\") # конструктор ошибки ValueError\n", 649 | " \n", 650 | "print(greet(\"Anton\"))\n", 651 | "print(greet(\"anton\"))" 652 | ] 653 | }, 654 | { 655 | "cell_type": "markdown", 656 | "metadata": {}, 657 | "source": [ 658 | "### Задача 1 " 659 | ] 660 | }, 661 | { 662 | "cell_type": "code", 663 | "execution_count": null, 664 | "metadata": { 665 | "collapsed": true 666 | }, 667 | "outputs": [], 668 | "source": [ 669 | "try:\n", 670 | " foo()\n", 671 | "except ZeroDivisionError :\n", 672 | " print(\"ZeroDivisionError \") \n", 673 | "except ArithmeticError:\n", 674 | " print(\"ArithmeticError\")\n", 675 | "except AssertionError:\n", 676 | " print(\"AssertionError\")" 677 | ] 678 | }, 679 | { 680 | "cell_type": "markdown", 681 | "metadata": {}, 682 | "source": [ 683 | "### Задача 2 " 684 | ] 685 | }, 686 | { 687 | "cell_type": "code", 688 | "execution_count": null, 689 | "metadata": { 690 | "collapsed": true 691 | }, 692 | "outputs": [], 693 | "source": [] 694 | } 695 | ], 696 | "metadata": { 697 | "kernelspec": { 698 | "display_name": "Python 3", 699 | "language": "python", 700 | "name": "python3" 701 | }, 702 | "language_info": { 703 | "codemirror_mode": { 704 | "name": "ipython", 705 | "version": 3 706 | }, 707 | "file_extension": ".py", 708 | "mimetype": "text/x-python", 709 | "name": "python", 710 | "nbconvert_exporter": "python", 711 | "pygments_lexer": "ipython3", 712 | "version": "3.5.0" 713 | } 714 | }, 715 | "nbformat": 4, 716 | "nbformat_minor": 0 717 | } 718 | -------------------------------------------------------------------------------- /week3/2. Regexp.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Регулярные выражения" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "В Python регулярные выражения представляют собой специальную библиотеку. Для использования регулярных выражений в Python обычно пишется специальный шаблон, а потом уже работаем с ним." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Т.к. многие регулярные выражения используют обладный слеш, то для написания строки с ними следует использовать \"сырые\" строки " 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 1, 27 | "metadata": { 28 | "collapsed": false 29 | }, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | "Hello\\nWorld\n" 36 | ] 37 | } 38 | ], 39 | "source": [ 40 | "s = r\"Hello\\nWorld\" #row\n", 41 | "print(s) # сырая строка выводится как есть, не учитывая специальные символы типа \\n" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "re - библиотека для работы с регулярными выражениями" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 2, 54 | "metadata": { 55 | "collapsed": false 56 | }, 57 | "outputs": [ 58 | { 59 | "name": "stdout", 60 | "output_type": "stream", 61 | "text": [ 62 | "\n", 63 | "\n", 64 | "\n", 65 | "\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "import re\n", 71 | "\n", 72 | "# Основные функции для работы с регулярками\n", 73 | "print(re.match)\n", 74 | "print(re.search)\n", 75 | "print(re.findall)\n", 76 | "print(re.sub)" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "#### Функция match берет шаблон и строку и проверяет подходит ли начало данной строки под данный шаблон" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 12, 89 | "metadata": { 90 | "collapsed": false 91 | }, 92 | "outputs": [ 93 | { 94 | "name": "stdout", 95 | "output_type": "stream", 96 | "text": [ 97 | "<_sre.SRE_Match object; span=(0, 3), match='abc'>\n" 98 | ] 99 | } 100 | ], 101 | "source": [ 102 | "import re\n", 103 | "\n", 104 | "pattern = r\"abc\"\n", 105 | "string = \"abcdasdasd\"\n", 106 | "match_object = re.match(pattern, string)\n", 107 | "print(match_object)" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "Функция match пробегает всю строку слева направо до тех пор пока строка подходит под регулярное выражение. А как только такая подстрока найдется, то она сразу вернутся в объект типа Match." 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "От сюда следует, что если нужная подстрока не встрелась в тексте, то функция ничего не вернет, а точнее вернется None." 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "#### Функция serch берет строку и находит первую подстроку, которая совпадает с шаблоном" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 16, 134 | "metadata": { 135 | "collapsed": false 136 | }, 137 | "outputs": [ 138 | { 139 | "name": "stdout", 140 | "output_type": "stream", 141 | "text": [ 142 | "<_sre.SRE_Match object; span=(1, 4), match='abc'>\n" 143 | ] 144 | } 145 | ], 146 | "source": [ 147 | "import re\n", 148 | "\n", 149 | "pattern = r\"abc\"\n", 150 | "string = \"babc\"\n", 151 | "match_object = re.search(pattern, string)\n", 152 | "print(match_object)" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "Как и в случае функции match, функция search вернет None если искомая подстрока не встретилась." 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "#### Функция findall находит все подстроки строки, которые совпадают с шаблоном" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "metadata": {}, 172 | "source": [ 173 | "#### Функция sub позволяет заменить все подстроки, которые совпадают с шаблоном на что-то другое" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "metadata": {}, 179 | "source": [ 180 | "### Метасимволы" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": {}, 186 | "source": [ 187 | "#### [] - множество всех подходящих символов" 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 24, 193 | "metadata": { 194 | "collapsed": false 195 | }, 196 | "outputs": [ 197 | { 198 | "name": "stdout", 199 | "output_type": "stream", 200 | "text": [ 201 | "<_sre.SRE_Match object; span=(0, 3), match='acc'>\n", 202 | "['abc', 'acc', 'aac']\n", 203 | "abc, abc, abc\n" 204 | ] 205 | } 206 | ], 207 | "source": [ 208 | "import re\n", 209 | "\n", 210 | "# [] -- можно указать множество подходящих символов\n", 211 | "\n", 212 | "pattern = r\"a[abc]c\"\n", 213 | "\n", 214 | "# Возвращает объект в случае успешного поиска\n", 215 | "string = \"accfjfyf\"\n", 216 | "match_object = re.match(pattern, string)\n", 217 | "print(match_object)\n", 218 | "\n", 219 | "# Возращает список значений \n", 220 | "string = \"abc, acc, aac\"\n", 221 | "all_inclusions = re.findall(pattern, string)\n", 222 | "print(all_inclusions)\n", 223 | "\n", 224 | "# Возвращает строку с заменой всех найденых подстрок дргой подстрокой\n", 225 | "fixed_typos = re.sub(pattern, \"abc\", string) # Замена в строке string все подсрок поподающих под шаблон pattern \n", 226 | " # на подстроку abc\n", 227 | "print(fixed_typos)" 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "metadata": {}, 233 | "source": [ 234 | "#### Некоторые сокращенные обозначения для множества подъодящих символов" 235 | ] 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "metadata": {}, 240 | "source": [ 241 | "\\d ~ [0-9] -- цифры" 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "metadata": {}, 247 | "source": [ 248 | "\\D ~ [^0-9] -- не цифры" 249 | ] 250 | }, 251 | { 252 | "cell_type": "markdown", 253 | "metadata": {}, 254 | "source": [ 255 | "\\s ~ [ \\t\\n\\r\\f\\v] -- пробельные символы" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": {}, 261 | "source": [ 262 | "\\S ~ [^ \\t\\n\\r\\f\\v]" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": {}, 268 | "source": [ 269 | "\\w ~ [a-zA-Z0-9_] -- буквы + цифры + _" 270 | ] 271 | }, 272 | { 273 | "cell_type": "markdown", 274 | "metadata": {}, 275 | "source": [ 276 | "\\W ~ [^a-zA-Z0-9_]" 277 | ] 278 | }, 279 | { 280 | "cell_type": "markdown", 281 | "metadata": {}, 282 | "source": [ 283 | "#### . -- любой символ, кроме переноса строки" 284 | ] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "metadata": {}, 289 | "source": [ 290 | "#### * -- любое количество символов (в том числе 0)" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": 25, 296 | "metadata": { 297 | "collapsed": false 298 | }, 299 | "outputs": [ 300 | { 301 | "name": "stdout", 302 | "output_type": "stream", 303 | "text": [ 304 | "['aa', 'aba', 'abba']\n" 305 | ] 306 | } 307 | ], 308 | "source": [ 309 | "import re\n", 310 | "\n", 311 | "pattern = r\"ab*a\"\n", 312 | "string = \"aa, aba, abba\"\n", 313 | "all_inclusions = re.findall(pattern, string)\n", 314 | "print(all_inclusions)" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "#### + -- положительно число вхождений символа (> 0)" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 26, 327 | "metadata": { 328 | "collapsed": false 329 | }, 330 | "outputs": [ 331 | { 332 | "name": "stdout", 333 | "output_type": "stream", 334 | "text": [ 335 | "['aba', 'abba']\n" 336 | ] 337 | } 338 | ], 339 | "source": [ 340 | "import re\n", 341 | "\n", 342 | "pattern = r\"ab+a\"\n", 343 | "string = \"aa, aba, abba\"\n", 344 | "all_inclusions = re.findall(pattern, string)\n", 345 | "print(all_inclusions)" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "#### ? -- ноль или одно вхождение символа" 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": 27, 358 | "metadata": { 359 | "collapsed": false 360 | }, 361 | "outputs": [ 362 | { 363 | "name": "stdout", 364 | "output_type": "stream", 365 | "text": [ 366 | "['aa', 'aba']\n" 367 | ] 368 | } 369 | ], 370 | "source": [ 371 | "import re\n", 372 | "\n", 373 | "pattern = r\"ab?a\"\n", 374 | "string = \"aa, aba, abba\"\n", 375 | "all_inclusions = re.findall(pattern, string)\n", 376 | "print(all_inclusions)" 377 | ] 378 | }, 379 | { 380 | "cell_type": "markdown", 381 | "metadata": {}, 382 | "source": [ 383 | "#### {n} -- n вхождений символа" 384 | ] 385 | }, 386 | { 387 | "cell_type": "code", 388 | "execution_count": 28, 389 | "metadata": { 390 | "collapsed": false 391 | }, 392 | "outputs": [ 393 | { 394 | "name": "stdout", 395 | "output_type": "stream", 396 | "text": [ 397 | "['abbba']\n" 398 | ] 399 | } 400 | ], 401 | "source": [ 402 | "import re\n", 403 | "\n", 404 | "pattern = r\"ab{3}a\"\n", 405 | "string = \"aa, aba, abba, abbba, abbbba\"\n", 406 | "all_inclusions = re.findall(pattern, string)\n", 407 | "print(all_inclusions)" 408 | ] 409 | }, 410 | { 411 | "cell_type": "markdown", 412 | "metadata": {}, 413 | "source": [ 414 | "#### {n, m} -- от n до m вхождений сивола" 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": 29, 420 | "metadata": { 421 | "collapsed": false 422 | }, 423 | "outputs": [ 424 | { 425 | "name": "stdout", 426 | "output_type": "stream", 427 | "text": [ 428 | "['abba', 'abbba', 'abbbba']\n" 429 | ] 430 | } 431 | ], 432 | "source": [ 433 | "import re\n", 434 | "\n", 435 | "pattern = r\"ab{2,4}a\"\n", 436 | "string = \"aa, aba, abba, abbba, abbbba\"\n", 437 | "all_inclusions = re.findall(pattern, string)\n", 438 | "print(all_inclusions)" 439 | ] 440 | }, 441 | { 442 | "cell_type": "markdown", 443 | "metadata": {}, 444 | "source": [ 445 | "#### По умолчанию символы повтора (вроде * или +) являются \"жадными.\" Это значит, что они пытаюсь вообрать в себя как можно больше символов." 446 | ] 447 | }, 448 | { 449 | "cell_type": "code", 450 | "execution_count": 31, 451 | "metadata": { 452 | "collapsed": false 453 | }, 454 | "outputs": [ 455 | { 456 | "name": "stdout", 457 | "output_type": "stream", 458 | "text": [ 459 | "<_sre.SRE_Match object; span=(0, 6), match='abaaba'>\n", 460 | "['abaaba']\n" 461 | ] 462 | } 463 | ], 464 | "source": [ 465 | "import re\n", 466 | "\n", 467 | "pattern = r'a[ab]+a'\n", 468 | "string = 'abaaba'\n", 469 | "print(re.match(pattern, string)) # Функция match \"заберет\" всю строку целиком, \n", 470 | " # не смотря на более короткие варианты ответа\n", 471 | "print(re.findall(pattern, string))" 472 | ] 473 | }, 474 | { 475 | "cell_type": "markdown", 476 | "metadata": {}, 477 | "source": [ 478 | "#### Для того, чтобы символы постора перестали быть \"жадными\" и стали ориентироваться на минимальное количество символов, необходимо поставить знак ? после метасимвола." 479 | ] 480 | }, 481 | { 482 | "cell_type": "code", 483 | "execution_count": 33, 484 | "metadata": { 485 | "collapsed": false 486 | }, 487 | "outputs": [ 488 | { 489 | "name": "stdout", 490 | "output_type": "stream", 491 | "text": [ 492 | "<_sre.SRE_Match object; span=(0, 3), match='aba'>\n", 493 | "['aba', 'aba']\n" 494 | ] 495 | } 496 | ], 497 | "source": [ 498 | "import re \n", 499 | "\n", 500 | "pattern = r\"a[ab]+?a\"\n", 501 | "string = \"abaaba\"\n", 502 | "print(re.match(pattern, string))\n", 503 | "print(re.findall(pattern, string))" 504 | ] 505 | }, 506 | { 507 | "cell_type": "markdown", 508 | "metadata": {}, 509 | "source": [ 510 | "#### Регулярные выражения можно группировать с помощью круглых скобок" 511 | ] 512 | }, 513 | { 514 | "cell_type": "markdown", 515 | "metadata": {}, 516 | "source": [ 517 | "#### Внутри скобок часто бывает удобно указать логическое \"или\" с помощью символа |" 518 | ] 519 | }, 520 | { 521 | "cell_type": "code", 522 | "execution_count": 40, 523 | "metadata": { 524 | "collapsed": false 525 | }, 526 | "outputs": [ 527 | { 528 | "name": "stdout", 529 | "output_type": "stream", 530 | "text": [ 531 | "<_sre.SRE_Match object; span=(0, 12), match='testtesttext'>\n" 532 | ] 533 | } 534 | ], 535 | "source": [ 536 | "import re\n", 537 | "\n", 538 | "pattern = r\"(test|text)*\"\n", 539 | "string = \"testtesttext\"\n", 540 | "print(re.match(pattern, string))" 541 | ] 542 | }, 543 | { 544 | "cell_type": "markdown", 545 | "metadata": {}, 546 | "source": [ 547 | "##### Метосимвол или ( | ) обладает наименьшем приоритетом в регулярных выражениях" 548 | ] 549 | }, 550 | { 551 | "cell_type": "code", 552 | "execution_count": 42, 553 | "metadata": { 554 | "collapsed": false 555 | }, 556 | "outputs": [ 557 | { 558 | "name": "stdout", 559 | "output_type": "stream", 560 | "text": [ 561 | "<_sre.SRE_Match object; span=(0, 8), match='testtext'>\n", 562 | "('testtext', None, 'text')\n" 563 | ] 564 | } 565 | ], 566 | "source": [ 567 | "import re\n", 568 | "\n", 569 | "pattern = r\"((abc)|(test|text)*)\"\n", 570 | "string = \"testtext\"\n", 571 | "match = re.match(pattern, string)\n", 572 | "print(match)\n", 573 | "print(match.groups()) # совпадения в groups() перечисленны в том же порядке, что и открывающиеся скобки" 574 | ] 575 | }, 576 | { 577 | "cell_type": "markdown", 578 | "metadata": {}, 579 | "source": [ 580 | "###### Можно явно указать группу, которую мы хотим проверить на совпадение" 581 | ] 582 | }, 583 | { 584 | "cell_type": "code", 585 | "execution_count": 45, 586 | "metadata": { 587 | "collapsed": false 588 | }, 589 | "outputs": [ 590 | { 591 | "name": "stdout", 592 | "output_type": "stream", 593 | "text": [ 594 | "<_sre.SRE_Match object; span=(0, 9), match='Hello abc'>\n", 595 | "Hello abc\n", 596 | "abc\n" 597 | ] 598 | } 599 | ], 600 | "source": [ 601 | "import re\n", 602 | "\n", 603 | "pattern = r\"Hello (abc|test)\"\n", 604 | "string = \"Hello abc\"\n", 605 | "match = re.match(pattern, string)\n", 606 | "print(match)\n", 607 | "print(match.group(0))\n", 608 | "print(match.group(1))" 609 | ] 610 | }, 611 | { 612 | "cell_type": "markdown", 613 | "metadata": {}, 614 | "source": [ 615 | "#### Можно использовать результат группировки прямо внутри регулярного выражения, для этого используется метосимвол обращения к группе \\n, где n - номер группы." 616 | ] 617 | }, 618 | { 619 | "cell_type": "code", 620 | "execution_count": 46, 621 | "metadata": { 622 | "collapsed": false 623 | }, 624 | "outputs": [ 625 | { 626 | "name": "stdout", 627 | "output_type": "stream", 628 | "text": [ 629 | "<_sre.SRE_Match object; span=(0, 9), match='test-test'>\n" 630 | ] 631 | } 632 | ], 633 | "source": [ 634 | "import re\n", 635 | "\n", 636 | "pattern = r\"(\\w+)-\\1\" # метосимвол \\1 является обращением к первой группе \n", 637 | "string = \"test-test\"\n", 638 | "match = re.match(pattern, string)\n", 639 | "print(match)" 640 | ] 641 | }, 642 | { 643 | "cell_type": "markdown", 644 | "metadata": {}, 645 | "source": [ 646 | "#### Можно даже переиспользовать эту группу, в том числе в методе sub" 647 | ] 648 | }, 649 | { 650 | "cell_type": "code", 651 | "execution_count": 48, 652 | "metadata": { 653 | "collapsed": false 654 | }, 655 | "outputs": [ 656 | { 657 | "name": "stdout", 658 | "output_type": "stream", 659 | "text": [ 660 | "test chow\n" 661 | ] 662 | } 663 | ], 664 | "source": [ 665 | "import re\n", 666 | "\n", 667 | "pattern = r\"(\\w+)-\\1\" # Регулярное выражения для всех одинаковых слов, соединенных тире\n", 668 | "string = \"test-test chow-chow\" # Тут у нас два раза встречается такое безобразие\n", 669 | "duplicates = re.sub(pattern, r\"\\1\", string) # Заменяем все одинаковые слова с тире на одно слово\n", 670 | "print(duplicates)" 671 | ] 672 | }, 673 | { 674 | "cell_type": "markdown", 675 | "metadata": {}, 676 | "source": [ 677 | "#### При работе с группами надо быть осторожным с функцией findall, т.к. если раньше она возвращала целиком подстроку, которая подходила под шаблон, теперь она будет возвращать кортеж групп." 678 | ] 679 | }, 680 | { 681 | "cell_type": "markdown", 682 | "metadata": {}, 683 | "source": [ 684 | "##### Пример, который демонтрирует работу findall с одногой группой. В этом случае функция возвращет список совпадений" 685 | ] 686 | }, 687 | { 688 | "cell_type": "code", 689 | "execution_count": 49, 690 | "metadata": { 691 | "collapsed": false 692 | }, 693 | "outputs": [ 694 | { 695 | "name": "stdout", 696 | "output_type": "stream", 697 | "text": [ 698 | "['test', 'chow']\n" 699 | ] 700 | } 701 | ], 702 | "source": [ 703 | "import re\n", 704 | "\n", 705 | "pattern = r\"(\\w+)-\\1\"\n", 706 | "string = \"test-test chow-chow\"\n", 707 | "duplicates = re.findall(pattern, string)\n", 708 | "print(duplicates)" 709 | ] 710 | }, 711 | { 712 | "cell_type": "markdown", 713 | "metadata": {}, 714 | "source": [ 715 | "##### Однако, в случае, если мы работаем с несколькими группами функция findall возвращает список картежей" 716 | ] 717 | }, 718 | { 719 | "cell_type": "code", 720 | "execution_count": 53, 721 | "metadata": { 722 | "collapsed": false 723 | }, 724 | "outputs": [ 725 | { 726 | "name": "stdout", 727 | "output_type": "stream", 728 | "text": [ 729 | "[('test-test', 'test'), ('chow-chow', 'chow')]\n" 730 | ] 731 | } 732 | ], 733 | "source": [ 734 | "import re\n", 735 | "\n", 736 | "pattern = r\"((\\w+)-\\2)\"\n", 737 | "strind = \"test=test chow-chow\"\n", 738 | "duplicates = re.findall(pattern, string)\n", 739 | "print(duplicates)" 740 | ] 741 | }, 742 | { 743 | "cell_type": "markdown", 744 | "metadata": {}, 745 | "source": [ 746 | "## Так же, вместе с регулярными выражениями используются специальные флаги для того, чтобы определенить парметры поиска" 747 | ] 748 | }, 749 | { 750 | "cell_type": "markdown", 751 | "metadata": {}, 752 | "source": [ 753 | "### Для того, чтобы включить игнорирование регистров используется флаг IGNORECASE" 754 | ] 755 | }, 756 | { 757 | "cell_type": "code", 758 | "execution_count": 1, 759 | "metadata": { 760 | "collapsed": false 761 | }, 762 | "outputs": [ 763 | { 764 | "name": "stdout", 765 | "output_type": "stream", 766 | "text": [ 767 | "<_sre.SRE_Match object; span=(0, 4), match='TEXT'>\n" 768 | ] 769 | } 770 | ], 771 | "source": [ 772 | "import re\n", 773 | "\n", 774 | "print(re.match(r\"text\", \"TEXT\", re.IGNORECASE))\n" 775 | ] 776 | }, 777 | { 778 | "cell_type": "markdown", 779 | "metadata": {}, 780 | "source": [ 781 | "### Для получения инфомации о регулярном выражении используется флаг DEBUG" 782 | ] 783 | }, 784 | { 785 | "cell_type": "markdown", 786 | "metadata": {}, 787 | "source": [ 788 | "Для того, чтобы выставить сразу несколько флагов используется логическое или" 789 | ] 790 | }, 791 | { 792 | "cell_type": "code", 793 | "execution_count": 5, 794 | "metadata": { 795 | "collapsed": false 796 | }, 797 | "outputs": [ 798 | { 799 | "name": "stdout", 800 | "output_type": "stream", 801 | "text": [ 802 | "MAX_REPEAT 0 MAXREPEAT\n", 803 | " SUBPATTERN 1\n", 804 | " LITERAL 116\n", 805 | " LITERAL 101\n", 806 | "LITERAL 120\n", 807 | "LITERAL 116\n", 808 | "<_sre.SRE_Match object; span=(0, 4), match='TEXT'>\n" 809 | ] 810 | } 811 | ], 812 | "source": [ 813 | "import re\n", 814 | "print(re.match(r\"(te)*xt\", \"TEXT\", re.IGNORECASE | re.DEBUG))" 815 | ] 816 | }, 817 | { 818 | "cell_type": "markdown", 819 | "metadata": {}, 820 | "source": [ 821 | "## Задачи" 822 | ] 823 | }, 824 | { 825 | "cell_type": "markdown", 826 | "metadata": {}, 827 | "source": [ 828 | "### Задача 1" 829 | ] 830 | }, 831 | { 832 | "cell_type": "markdown", 833 | "metadata": {}, 834 | "source": [ 835 | "Вам дана последовательность строк.\n", 836 | "Выведите строки, содержащие \"cat\" в качестве подстроки хотя бы два раза." 837 | ] 838 | }, 839 | { 840 | "cell_type": "code", 841 | "execution_count": 6, 842 | "metadata": { 843 | "collapsed": true 844 | }, 845 | "outputs": [], 846 | "source": [ 847 | "import re\n", 848 | "import sys\n", 849 | "\n", 850 | "pattern = r\"cat.*cat\"\n", 851 | "\n", 852 | "for line in sys.stdin:\n", 853 | " line = line.rstrip()\n", 854 | " if re.search(pattern, line) is not None:\n", 855 | " print(line)" 856 | ] 857 | }, 858 | { 859 | "cell_type": "markdown", 860 | "metadata": {}, 861 | "source": [ 862 | "### Задача 2" 863 | ] 864 | }, 865 | { 866 | "cell_type": "code", 867 | "execution_count": null, 868 | "metadata": { 869 | "collapsed": true 870 | }, 871 | "outputs": [], 872 | "source": [ 873 | "Вам дана последовательность строк.\n", 874 | "Выведите строки, содержащие \"cat\" в качестве слова." 875 | ] 876 | }, 877 | { 878 | "cell_type": "code", 879 | "execution_count": null, 880 | "metadata": { 881 | "collapsed": true 882 | }, 883 | "outputs": [], 884 | "source": [ 885 | "import re\n", 886 | "import sys\n", 887 | "\n", 888 | "# \\b указыает на конец или начало слова\n", 889 | "pattern = r\"\\bcat\\b\"\n", 890 | "\n", 891 | "for line in sys.stdin:\n", 892 | " line = line.rstrip()\n", 893 | " if re.search(pattern, line) is not None:\n", 894 | " print(line)" 895 | ] 896 | }, 897 | { 898 | "cell_type": "markdown", 899 | "metadata": {}, 900 | "source": [ 901 | "### Задача 3" 902 | ] 903 | }, 904 | { 905 | "cell_type": "markdown", 906 | "metadata": {}, 907 | "source": [ 908 | "Вам дана последовательность строк.\n", 909 | "Выведите строки, содержащие две буквы \"z\", между которыми ровно три символа." 910 | ] 911 | }, 912 | { 913 | "cell_type": "code", 914 | "execution_count": null, 915 | "metadata": { 916 | "collapsed": true 917 | }, 918 | "outputs": [], 919 | "source": [ 920 | "import re\n", 921 | "import sys\n", 922 | "\n", 923 | "pattern = r\"z.{3}z\"\n", 924 | "\n", 925 | "for line in sys.stdin:\n", 926 | " line = line.rstrip()\n", 927 | " if re.search(pattern, line) is not None:\n", 928 | " print(line)" 929 | ] 930 | }, 931 | { 932 | "cell_type": "markdown", 933 | "metadata": {}, 934 | "source": [ 935 | "### Задача 4" 936 | ] 937 | }, 938 | { 939 | "cell_type": "markdown", 940 | "metadata": {}, 941 | "source": [ 942 | "Вам дана последовательность строк.\n", 943 | "Выведите строки, содержащие обратный слеш \"\\\"." 944 | ] 945 | }, 946 | { 947 | "cell_type": "code", 948 | "execution_count": null, 949 | "metadata": { 950 | "collapsed": true 951 | }, 952 | "outputs": [], 953 | "source": [ 954 | "import re\n", 955 | "import sys\n", 956 | "\n", 957 | "pattern = r\"\\\\\"\n", 958 | "\n", 959 | "for line in sys.stdin:\n", 960 | " line = line.rstrip()\n", 961 | " if re.search(pattern, line) is not None:\n", 962 | " print(line)" 963 | ] 964 | }, 965 | { 966 | "cell_type": "markdown", 967 | "metadata": {}, 968 | "source": [ 969 | "### Задача 5" 970 | ] 971 | }, 972 | { 973 | "cell_type": "code", 974 | "execution_count": null, 975 | "metadata": { 976 | "collapsed": true 977 | }, 978 | "outputs": [], 979 | "source": [ 980 | "Вам дана последовательность строк.\n", 981 | "Выведите строки, содержащие слово, состоящее из двух одинаковых частей (тандемный повтор)." 982 | ] 983 | }, 984 | { 985 | "cell_type": "code", 986 | "execution_count": null, 987 | "metadata": { 988 | "collapsed": true 989 | }, 990 | "outputs": [], 991 | "source": [ 992 | "import re\n", 993 | "import sys\n", 994 | "\n", 995 | "pattern = r\"\\b(\\w+)\\1\\b\"\n", 996 | "\n", 997 | "for line in sys.stdin:\n", 998 | " line = line.rstrip()\n", 999 | " if re.search(pattern, line) is not None:\n", 1000 | " print(line)" 1001 | ] 1002 | }, 1003 | { 1004 | "cell_type": "markdown", 1005 | "metadata": {}, 1006 | "source": [ 1007 | "### Здача 6" 1008 | ] 1009 | }, 1010 | { 1011 | "cell_type": "markdown", 1012 | "metadata": {}, 1013 | "source": [ 1014 | "Вам дана последовательность строк.\n", 1015 | "В каждой строке замените все вхождения подстроки \"human\" на подстроку \"computer\" и выведите полученные строки." 1016 | ] 1017 | }, 1018 | { 1019 | "cell_type": "code", 1020 | "execution_count": null, 1021 | "metadata": { 1022 | "collapsed": true 1023 | }, 1024 | "outputs": [], 1025 | "source": [ 1026 | "import re\n", 1027 | "import sys\n", 1028 | "\n", 1029 | "# pattern = r\"\\b(\\w+)\\1\\b\"\n", 1030 | "for line in sys.stdin:\n", 1031 | " line = line.rstrip()\n", 1032 | " if re.search(r\"human\", line) is not None:\n", 1033 | " line = re.sub(r\"human\", \"computer\", line)\n", 1034 | " print(line)" 1035 | ] 1036 | }, 1037 | { 1038 | "cell_type": "markdown", 1039 | "metadata": {}, 1040 | "source": [ 1041 | "### Задача 7" 1042 | ] 1043 | }, 1044 | { 1045 | "cell_type": "markdown", 1046 | "metadata": {}, 1047 | "source": [ 1048 | "Вам дана последовательность строк.\n", 1049 | "В каждой строке замените первое вхождение слова, состоящего только из латинских букв \"a\" (регистр не важен), на слово \"argh\"." 1050 | ] 1051 | }, 1052 | { 1053 | "cell_type": "code", 1054 | "execution_count": null, 1055 | "metadata": { 1056 | "collapsed": true 1057 | }, 1058 | "outputs": [], 1059 | "source": [ 1060 | "import re\n", 1061 | "import sys\n", 1062 | "\n", 1063 | "pattern = r\"\\b[a]+\\b\"\n", 1064 | "\n", 1065 | "for line in sys.stdin:\n", 1066 | " line = line.rstrip()\n", 1067 | " if re.search(pattern, line, re.IGNORECASE) is not None:\n", 1068 | " line = re.sub(pattern, \"argh\", line, flags=re.IGNORECASE, count=1)\n", 1069 | " print(line)" 1070 | ] 1071 | }, 1072 | { 1073 | "cell_type": "markdown", 1074 | "metadata": {}, 1075 | "source": [ 1076 | "### Задача 8" 1077 | ] 1078 | }, 1079 | { 1080 | "cell_type": "markdown", 1081 | "metadata": {}, 1082 | "source": [ 1083 | "Вам дана последовательность строк.\n", 1084 | "В каждой строке поменяйте местами две первых буквы в каждом слове, состоящем хотя бы из двух букв.\n", 1085 | "Буквой считается символ из группы \\w." 1086 | ] 1087 | }, 1088 | { 1089 | "cell_type": "code", 1090 | "execution_count": null, 1091 | "metadata": { 1092 | "collapsed": true 1093 | }, 1094 | "outputs": [], 1095 | "source": [ 1096 | "import re\n", 1097 | "import sys\n", 1098 | "\n", 1099 | "pattern = r\"\\b(\\w)(\\w)(\\w*)\\b\"\n", 1100 | "\n", 1101 | "for line in sys.stdin:\n", 1102 | " line = line.rstrip()\n", 1103 | " if re.search(pattern, line, re.IGNORECASE) is not None:\n", 1104 | " line = re.sub(pattern, r\"\\2\\1\\3\", line, flags=re.IGNORECASE,)\n", 1105 | " print(line)" 1106 | ] 1107 | }, 1108 | { 1109 | "cell_type": "markdown", 1110 | "metadata": {}, 1111 | "source": [ 1112 | "### Задача 9" 1113 | ] 1114 | }, 1115 | { 1116 | "cell_type": "markdown", 1117 | "metadata": {}, 1118 | "source": [ 1119 | "Вам дана последовательность строк.\n", 1120 | "В каждой строке замените все вхождения нескольких одинаковых букв на одну букву.\n", 1121 | "Буквой считается символ из группы \\w." 1122 | ] 1123 | }, 1124 | { 1125 | "cell_type": "code", 1126 | "execution_count": null, 1127 | "metadata": { 1128 | "collapsed": true 1129 | }, 1130 | "outputs": [], 1131 | "source": [ 1132 | "import re\n", 1133 | "import sys\n", 1134 | "\n", 1135 | "pattern = r\"(\\w)\\1+\"\n", 1136 | "\n", 1137 | "for line in sys.stdin:\n", 1138 | " line = line.rstrip()\n", 1139 | " if re.search(pattern, line) is not None:\n", 1140 | " line = re.sub(pattern, r\"\\1\", line)\n", 1141 | " print(line)" 1142 | ] 1143 | } 1144 | ], 1145 | "metadata": { 1146 | "kernelspec": { 1147 | "display_name": "Python 3", 1148 | "language": "python", 1149 | "name": "python3" 1150 | }, 1151 | "language_info": { 1152 | "codemirror_mode": { 1153 | "name": "ipython", 1154 | "version": 3 1155 | }, 1156 | "file_extension": ".py", 1157 | "mimetype": "text/x-python", 1158 | "name": "python", 1159 | "nbconvert_exporter": "python", 1160 | "pygments_lexer": "ipython3", 1161 | "version": "3.5.1" 1162 | } 1163 | }, 1164 | "nbformat": 4, 1165 | "nbformat_minor": 0 1166 | } 1167 | -------------------------------------------------------------------------------- /week1/week1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Неделя 1. Базовые принципы языка Python" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Модель данных: объекты" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 23, 20 | "metadata": { 21 | "collapsed": false 22 | }, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "102\n" 29 | ] 30 | } 31 | ], 32 | "source": [ 33 | "# Задача 1\n", 34 | "# Кэш объекта со значением True и объекта со значение 1 одинаков, поэтому 1 == True = True\n", 35 | "# Тоже самое 0 и False - 0 == False = True\n", 36 | "import random\n", 37 | "\n", 38 | "def mapObjects(myDict, value):\n", 39 | " if myDict.get(value) is not None:\n", 40 | " myDict[value] += 1\n", 41 | " else:\n", 42 | " myDict[value] = 1\n", 43 | "\n", 44 | "\n", 45 | "objects = []\n", 46 | "for i in range(100):\n", 47 | " objects += [i]\n", 48 | " \n", 49 | " \n", 50 | "objects += [ True ]\n", 51 | "objects += [ False]\n", 52 | "\n", 53 | "myDict = dict()\n", 54 | "for obj in objects:\n", 55 | " mapObjects(myDict, id(obj))\n", 56 | "\n", 57 | "print(len(myDict))" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": { 63 | "collapsed": true 64 | }, 65 | "source": [ 66 | "## Функции и стек вызовов " 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": {}, 72 | "source": [ 73 | "##### Задача 1 " 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 2, 79 | "metadata": { 80 | "collapsed": false 81 | }, 82 | "outputs": [ 83 | { 84 | "name": "stdout", 85 | "output_type": "stream", 86 | "text": [ 87 | "15\n" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "def closest_mod_5(x):\n", 93 | " i = x\n", 94 | " while True:\n", 95 | " if i % 5 == 0:\n", 96 | " return i\n", 97 | " i = i + 1\n", 98 | " \n", 99 | "print(closest_mod_5(11))" 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "metadata": {}, 105 | "source": [ 106 | "##### Для передачи в качестве аргументов функции список значений используется оператор *:" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 3, 112 | "metadata": { 113 | "collapsed": false 114 | }, 115 | "outputs": [ 116 | { 117 | "name": "stdout", 118 | "output_type": "stream", 119 | "text": [ 120 | "10\n", 121 | "20\n" 122 | ] 123 | } 124 | ], 125 | "source": [ 126 | "def myFunc(a, b):\n", 127 | " print(a)\n", 128 | " print(b)\n", 129 | "\n", 130 | "myList = [10, 20]\n", 131 | "myFunc(*myList) # эквивалентно myFunc(list[0], list[1])" 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": {}, 137 | "source": [ 138 | "##### В качестве аргументов можно использовать и словарь, для этого используется оператор **:" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 8, 144 | "metadata": { 145 | "collapsed": false 146 | }, 147 | "outputs": [ 148 | { 149 | "name": "stdout", 150 | "output_type": "stream", 151 | "text": [ 152 | "20\n", 153 | "10\n" 154 | ] 155 | } 156 | ], 157 | "source": [ 158 | "myDict = {'b':10, 'a':20} # ключ должен обязательно совпадать с именем аргумента\n", 159 | "myFunc(**myDict)" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "##### Использование оператора * в качестве приема аргументов функции позволяет объединить набор элементов в один список:" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 9, 172 | "metadata": { 173 | "collapsed": false 174 | }, 175 | "outputs": [ 176 | { 177 | "name": "stdout", 178 | "output_type": "stream", 179 | "text": [ 180 | "positional argument a 10\n", 181 | "positional argument b 20\n", 182 | "additional arguments:\n", 183 | "30\n", 184 | "40\n", 185 | "50\n" 186 | ] 187 | } 188 | ], 189 | "source": [ 190 | "def printab(a, b, *args):\n", 191 | " print('positional argument a ', a)\n", 192 | " print('positional argument b ', b)\n", 193 | " print(\"additional arguments:\")\n", 194 | " for arg in args:\n", 195 | " print(arg)\n", 196 | "\n", 197 | "printab(10, 20, 30, 40, 50)" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": {}, 203 | "source": [ 204 | "##### Существует похожий механизм и для именнованных аргументов:" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 35, 210 | "metadata": { 211 | "collapsed": false 212 | }, 213 | "outputs": [ 214 | { 215 | "name": "stdout", 216 | "output_type": "stream", 217 | "text": [ 218 | "positional argument a 10\n", 219 | "positional argument b 20\n", 220 | "additional arguments:\n", 221 | "c 30\n", 222 | "jimmi 123\n", 223 | "d 40\n" 224 | ] 225 | } 226 | ], 227 | "source": [ 228 | "def printab(a, b, **kwargs):\n", 229 | " print('positional argument a ', a)\n", 230 | " print('positional argument b ', b)\n", 231 | " print(\"additional arguments:\")\n", 232 | " for key in kwargs:\n", 233 | " print(key, kwargs[key])\n", 234 | "\n", 235 | "printab(10, 20, c = 30, d = 40, jimmi = 123)" 236 | ] 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "metadata": {}, 241 | "source": [ 242 | "##### Формальное, синтаксически " 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": {}, 248 | "source": [ 249 | "def function_name ([ position_args, - позиционные элементы" 250 | ] 251 | }, 252 | { 253 | "cell_type": "markdown", 254 | "metadata": {}, 255 | "source": [ 256 | " [ porisional_args_with_default, - позиционные элементы со значениями по умолчанию" 257 | ] 258 | }, 259 | { 260 | "cell_type": "markdown", 261 | "metadata": {}, 262 | "source": [ 263 | " [ *pos_args_name, - имя кортежа, куда кладутся элементы, которые не участвовали в инициализации" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | " [ keyword_only_args, - блок элементов, который можно передать только по имени" 271 | ] 272 | }, 273 | { 274 | "cell_type": "markdown", 275 | "metadata": {}, 276 | "source": [ 277 | " [ **kw_args_name]]]]]): - имя словаря, в который складываются все именнованные переменные, которые в инициализации не участвовали" 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": {}, 283 | "source": [ 284 | "###### Пример:" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 38, 290 | "metadata": { 291 | "collapsed": false, 292 | "scrolled": false 293 | }, 294 | "outputs": [ 295 | { 296 | "name": "stdout", 297 | "output_type": "stream", 298 | "text": [ 299 | "15 10 10 15\n" 300 | ] 301 | } 302 | ], 303 | "source": [ 304 | "def printab(a, b = 10, *args, c = 10, d, **kwargs):\n", 305 | " print(a, b, c, d)\n", 306 | "printab(15, d = 15)" 307 | ] 308 | }, 309 | { 310 | "cell_type": "code", 311 | "execution_count": 48, 312 | "metadata": { 313 | "collapsed": false 314 | }, 315 | "outputs": [ 316 | { 317 | "name": "stdout", 318 | "output_type": "stream", 319 | "text": [ 320 | "31\n" 321 | ] 322 | } 323 | ], 324 | "source": [ 325 | "def s(a, *vs, b=10):\n", 326 | " res = a + b\n", 327 | " for v in vs:\n", 328 | " res += v\n", 329 | " return res\n", 330 | "print(s(11, 10))" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "##### Задача " 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 51, 343 | "metadata": { 344 | "collapsed": false 345 | }, 346 | "outputs": [ 347 | { 348 | "name": "stdout", 349 | "output_type": "stream", 350 | "text": [ 351 | "3 2\n", 352 | "3\n" 353 | ] 354 | } 355 | ], 356 | "source": [ 357 | "def myFunc(n, k):\n", 358 | " if k > n:\n", 359 | " return 0\n", 360 | " if k == 0:\n", 361 | " return 1\n", 362 | " return myFunc(n - 1, k) + myFunc(n - 1, k - 1)\n", 363 | "\n", 364 | "myList = [int(i) for i in input().split(\" \")]\n", 365 | "print(myFunc(*myList))" 366 | ] 367 | }, 368 | { 369 | "cell_type": "markdown", 370 | "metadata": {}, 371 | "source": [ 372 | "## Пространство имен и области видимости " 373 | ] 374 | }, 375 | { 376 | "cell_type": "markdown", 377 | "metadata": {}, 378 | "source": [ 379 | "Пространство имен - сопоставление реальных имен переменных к их именам в пространстве оперативной памяти" 380 | ] 381 | }, 382 | { 383 | "cell_type": "markdown", 384 | "metadata": {}, 385 | "source": [ 386 | "builtins - пространство имен, которое создается сразу же после запуска интерпритатора и содержит такие имена как int, float, max, print и т.д." 387 | ] 388 | }, 389 | { 390 | "cell_type": "markdown", 391 | "metadata": {}, 392 | "source": [ 393 | "main - пространство имен, которое содержит пользовательские глобальные переменные, пользовательские имена функций и прочее, что было создано пользователем. " 394 | ] 395 | }, 396 | { 397 | "cell_type": "markdown", 398 | "metadata": {}, 399 | "source": [ 400 | "Когда интерпритатор переходит к выполнению некоторой функции - создается локальное пространство имен и разрушатся при выходе из функции" 401 | ] 402 | }, 403 | { 404 | "cell_type": "markdown", 405 | "metadata": {}, 406 | "source": [ 407 | "Локальная область видимости не создается в условных операторах и циклах " 408 | ] 409 | }, 410 | { 411 | "cell_type": "markdown", 412 | "metadata": {}, 413 | "source": [ 414 | "##### Пример " 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": 57, 420 | "metadata": { 421 | "collapsed": false 422 | }, 423 | "outputs": [ 424 | { 425 | "name": "stdout", 426 | "output_type": "stream", 427 | "text": [ 428 | "4\n" 429 | ] 430 | } 431 | ], 432 | "source": [ 433 | "for i in range(5):\n", 434 | " i = i\n", 435 | "print(i)" 436 | ] 437 | }, 438 | { 439 | "cell_type": "markdown", 440 | "metadata": {}, 441 | "source": [ 442 | "Из локальной области видимости можно обратиться к глобальной области видимости с помощью ключевого слова global" 443 | ] 444 | }, 445 | { 446 | "cell_type": "markdown", 447 | "metadata": {}, 448 | "source": [ 449 | "##### Пример " 450 | ] 451 | }, 452 | { 453 | "cell_type": "code", 454 | "execution_count": 61, 455 | "metadata": { 456 | "collapsed": false 457 | }, 458 | "outputs": [ 459 | { 460 | "name": "stdout", 461 | "output_type": "stream", 462 | "text": [ 463 | "True\n", 464 | "True\n", 465 | "False\n", 466 | "False\n" 467 | ] 468 | } 469 | ], 470 | "source": [ 471 | "ok_status = True\n", 472 | "vowels = [\"a\", \"u\", \"i\", \"e\", \"o\"]\n", 473 | "\n", 474 | "def check(word):\n", 475 | " global ok_status # говорим о том, что переменная ok_status - глобальнаяи\n", 476 | " for vowel in vowels:\n", 477 | " if vowel in word:\n", 478 | " return True\n", 479 | " \n", 480 | " ok_status = False\n", 481 | " return False\n", 482 | "\n", 483 | "print(check(\"abacaba\"))\n", 484 | "print(ok_status)\n", 485 | "print(check(\"www\"))\n", 486 | "print(ok_status)" 487 | ] 488 | }, 489 | { 490 | "cell_type": "markdown", 491 | "metadata": {}, 492 | "source": [ 493 | "Но надо быть осторожным с вызывом из глобальной области видимости. Может случится следующее:" 494 | ] 495 | }, 496 | { 497 | "cell_type": "code", 498 | "execution_count": 63, 499 | "metadata": { 500 | "collapsed": false 501 | }, 502 | "outputs": [ 503 | { 504 | "name": "stdout", 505 | "output_type": "stream", 506 | "text": [ 507 | "True\n", 508 | "True\n", 509 | "False\n", 510 | "True\n", 511 | "False\n" 512 | ] 513 | } 514 | ], 515 | "source": [ 516 | "def f():\n", 517 | " ok_status = True\n", 518 | " vowels = [\"a\", \"u\", \"i\", \"e\", \"o\"]\n", 519 | " \n", 520 | " def check(word):\n", 521 | " global os_status\n", 522 | " for vowel in vowels:\n", 523 | " if vowel in word:\n", 524 | " return True\n", 525 | " \n", 526 | " ok_status = False\n", 527 | " return False\n", 528 | " \n", 529 | " print(check(\"abacaba\"))\n", 530 | " print(ok_status)\n", 531 | " print(check(\"www\"))\n", 532 | " print(ok_status)\n", 533 | " \n", 534 | "f()\n", 535 | "print(ok_status) # ok_status появилась в глобальной области видимости и оно не равно значению из функции" 536 | ] 537 | }, 538 | { 539 | "cell_type": "markdown", 540 | "metadata": {}, 541 | "source": [ 542 | "Если требуется обратить к ближайшему пространству имен по стеку вызова выше текущего (не обязательно global), то используется ключевое слово nonlocal." 543 | ] 544 | }, 545 | { 546 | "cell_type": "markdown", 547 | "metadata": {}, 548 | "source": [ 549 | "##### Пример " 550 | ] 551 | }, 552 | { 553 | "cell_type": "code", 554 | "execution_count": 62, 555 | "metadata": { 556 | "collapsed": false 557 | }, 558 | "outputs": [ 559 | { 560 | "name": "stdout", 561 | "output_type": "stream", 562 | "text": [ 563 | "False\n" 564 | ] 565 | } 566 | ], 567 | "source": [ 568 | "def f():\n", 569 | " ok_status = True\n", 570 | " vowels = [\"a\", \"u\", \"i\", \"e\", \"o\"]\n", 571 | " \n", 572 | " def check(word):\n", 573 | " nonlocal ok_status ## обращение к переменной vowels из f scope (область видимости функции f)\n", 574 | " for vowel in vowels:\n", 575 | " if vowel in word:\n", 576 | " return True\n", 577 | " \n", 578 | " ok_status = False\n", 579 | " return False\n", 580 | " \n", 581 | " print(check(\"abacaba\"))\n", 582 | " print(ok_status)\n", 583 | " print(check(\"www\"))\n", 584 | " print(ok_status)\n", 585 | " \n", 586 | "f()\n", 587 | "print(ok_status)" 588 | ] 589 | }, 590 | { 591 | "cell_type": "markdown", 592 | "metadata": {}, 593 | "source": [ 594 | "#### Задача " 595 | ] 596 | }, 597 | { 598 | "cell_type": "code", 599 | "execution_count": 42, 600 | "metadata": { 601 | "collapsed": false 602 | }, 603 | "outputs": [ 604 | { 605 | "name": "stdout", 606 | "output_type": "stream", 607 | "text": [ 608 | "9\n", 609 | "add global a\n", 610 | "create foo global\n", 611 | "add foo b\n", 612 | "get foo a\n", 613 | "get foo c\n", 614 | "create bar foo\n", 615 | "add bar a\n", 616 | "get bar a\n", 617 | "get bar b\n", 618 | "global\n", 619 | "None\n", 620 | "bar\n", 621 | "foo\n" 622 | ] 623 | } 624 | ], 625 | "source": [ 626 | "def searchElement(namespaces, key, value):\n", 627 | " fun = key\n", 628 | " \n", 629 | " while fun != None:\n", 630 | " if value in namespaces[fun]:\n", 631 | " return fun\n", 632 | " lst = namespaces[fun]\n", 633 | " fun = lst[0]\n", 634 | " return None\n", 635 | "\n", 636 | "n = int(input())\n", 637 | "\n", 638 | "count = 1\n", 639 | "namespaces = {'None': [None] ,'global': ['None']}\n", 640 | "ans = []\n", 641 | "\n", 642 | "for i in range(n):\n", 643 | " inputData = [s for s in input().split(\" \")]\n", 644 | " \n", 645 | " if inputData[0] == 'add':\n", 646 | " namespaces[inputData[1]] += [inputData[2]]\n", 647 | "\n", 648 | " elif inputData[0] == 'create':\n", 649 | " namespaces[inputData[1]] = [inputData[2]]\n", 650 | " \n", 651 | " elif inputData[0] == 'get':\n", 652 | " ans += [searchElement(namespaces, inputData[1], inputData[2])]\n", 653 | " \n", 654 | "for i in ans:\n", 655 | " print(i)" 656 | ] 657 | }, 658 | { 659 | "cell_type": "markdown", 660 | "metadata": {}, 661 | "source": [ 662 | "## Введение в классы " 663 | ] 664 | }, 665 | { 666 | "cell_type": "markdown", 667 | "metadata": {}, 668 | "source": [ 669 | "#### Синтаксис " 670 | ] 671 | }, 672 | { 673 | "cell_type": "code", 674 | "execution_count": 85, 675 | "metadata": { 676 | "collapsed": false 677 | }, 678 | "outputs": [ 679 | { 680 | "name": "stdout", 681 | "output_type": "stream", 682 | "text": [ 683 | "10\n", 684 | "Hello\n", 685 | "\n", 686 | "50\n", 687 | "15\n" 688 | ] 689 | } 690 | ], 691 | "source": [ 692 | "class myClass:\n", 693 | " a = 10\n", 694 | " \n", 695 | " def func(self):\n", 696 | " print('Hello')\n", 697 | " \n", 698 | "print(myClass.a)\n", 699 | "myClass.func(4)\n", 700 | "\n", 701 | "myClass.a = 50\n", 702 | "x = myClass() # экземпляр класса (instance object) создается через конструктор\n", 703 | "y = myClass()\n", 704 | "y.a = 15\n", 705 | "print(type(x))\n", 706 | "print(x.a)\n", 707 | "print(y.a)" 708 | ] 709 | }, 710 | { 711 | "cell_type": "markdown", 712 | "metadata": {}, 713 | "source": [ 714 | "Определить поведение конструктора класса можно с помощью функции __init__(self) - обязательным входным аргументом такой функции является self - ссылка на текущий объект. " 715 | ] 716 | }, 717 | { 718 | "cell_type": "code", 719 | "execution_count": 72, 720 | "metadata": { 721 | "collapsed": false 722 | }, 723 | "outputs": [ 724 | { 725 | "name": "stdout", 726 | "output_type": "stream", 727 | "text": [ 728 | "0\n", 729 | "1\n" 730 | ] 731 | } 732 | ], 733 | "source": [ 734 | "class Counter:\n", 735 | " def __init__(self, start = 0): # помимо self в методе могут быть и другие аргументы, но self обязан быть первым\n", 736 | " self.count = start # внутри конструктора можно присвоить классу некоторые атрибуты\n", 737 | " \n", 738 | "Counter\n", 739 | "x1 = Counter(10)\n", 740 | "x = Counter()\n", 741 | "print(x.count)\n", 742 | "x.count += 1\n", 743 | "print(x.count)" 744 | ] 745 | }, 746 | { 747 | "cell_type": "markdown", 748 | "metadata": {}, 749 | "source": [ 750 | "##### Методы класса" 751 | ] 752 | }, 753 | { 754 | "cell_type": "code", 755 | "execution_count": 74, 756 | "metadata": { 757 | "collapsed": false 758 | }, 759 | "outputs": [ 760 | { 761 | "name": "stdout", 762 | "output_type": "stream", 763 | "text": [ 764 | "1\n", 765 | "2\n", 766 | "0\n" 767 | ] 768 | } 769 | ], 770 | "source": [ 771 | "class Counter:\n", 772 | " def __init__(self):\n", 773 | " self.count = 0\n", 774 | " \n", 775 | " def inc(self):\n", 776 | " self.count += 1\n", 777 | " \n", 778 | " def reset(self):\n", 779 | " self.count = 0\n", 780 | " \n", 781 | " \n", 782 | "Counter\n", 783 | "x = Counter()\n", 784 | "x.inc() # эта запись абсолютно эквивалентна этой: Counter.inc(x), то есть по умолчанию в метод класса передается сам объект\n", 785 | "print(x.count)\n", 786 | "Counter.inc(x) \n", 787 | "print(x.count)\n", 788 | "x.reset()\n", 789 | "print(x.count)" 790 | ] 791 | }, 792 | { 793 | "cell_type": "markdown", 794 | "metadata": {}, 795 | "source": [ 796 | "В примере выше x.inc() - связанный метод (Bound Method). Связанные методы - специальные объекты, которые позволяет вначале найти функцию, а потом связывает ее с объектом." 797 | ] 798 | }, 799 | { 800 | "cell_type": "markdown", 801 | "metadata": {}, 802 | "source": [ 803 | "##### Задача 1 " 804 | ] 805 | }, 806 | { 807 | "cell_type": "code", 808 | "execution_count": 78, 809 | "metadata": { 810 | "collapsed": false 811 | }, 812 | "outputs": [], 813 | "source": [ 814 | "class MoneyBox:\n", 815 | " def __init__(self, capacity):\n", 816 | " self.capacity = capacity\n", 817 | " self.v = 0\n", 818 | "\n", 819 | " def can_add(self, v):\n", 820 | " if self.v + v <= self.capacity:\n", 821 | " return True\n", 822 | " else:\n", 823 | " return False\n", 824 | "\n", 825 | " def add(self, v):\n", 826 | " self.v += v" 827 | ] 828 | }, 829 | { 830 | "cell_type": "markdown", 831 | "metadata": {}, 832 | "source": [ 833 | "##### Задача 2 " 834 | ] 835 | }, 836 | { 837 | "cell_type": "code", 838 | "execution_count": 84, 839 | "metadata": { 840 | "collapsed": false 841 | }, 842 | "outputs": [ 843 | { 844 | "name": "stdout", 845 | "output_type": "stream", 846 | "text": [ 847 | "[1, 2, 3]\n", 848 | "15\n", 849 | "[6]\n", 850 | "40\n", 851 | "[]\n", 852 | "5\n", 853 | "5\n", 854 | "[1]\n" 855 | ] 856 | } 857 | ], 858 | "source": [ 859 | "class Buffer:\n", 860 | " def __init__(self):\n", 861 | " # конструктор без аргументов\n", 862 | " self.list = []\n", 863 | " \n", 864 | " def add(self, *a):\n", 865 | " # добавить следующую часть последовательности\n", 866 | " for i in range(len(a)):\n", 867 | " self.list += [a[i]] # и тут я понял, что можно было просто использовать метод строк extend, расширяющий лист\n", 868 | " if len(self.list) == 5:\n", 869 | " sum = 0\n", 870 | " for i in range(5):\n", 871 | " sum += self.list.pop()\n", 872 | " print(sum)\n", 873 | "\n", 874 | " def get_current_part(self):\n", 875 | " # вернуть сохраненные в текущий момент элементы последовательности в порядке, в котором они были \n", 876 | " # добавлены\n", 877 | " return self.list\n", 878 | "\n", 879 | "buf = Buffer()\n", 880 | "buf.add(1, 2, 3)\n", 881 | "print(buf.get_current_part()) # вернуть [1, 2, 3]\n", 882 | "buf.add(4, 5, 6) # print(15) – вывод суммы первой пятерки элементов\n", 883 | "print(buf.get_current_part()) # вернуть [6]\n", 884 | "buf.add(7, 8, 9, 10) # print(40) – вывод суммы второй пятерки элементов\n", 885 | "print(buf.get_current_part()) # вернуть []\n", 886 | "buf.add(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) # print(5), print(5) – вывод сумм третьей и четвертой пятерки\n", 887 | "print(buf.get_current_part()) # вернуть [1]\n", 888 | " " 889 | ] 890 | }, 891 | { 892 | "cell_type": "markdown", 893 | "metadata": {}, 894 | "source": [ 895 | "Переменные, которые не указываются со ссылкой на класс(self) являются общими для всех классов (что-то типа static)." 896 | ] 897 | }, 898 | { 899 | "cell_type": "code", 900 | "execution_count": null, 901 | "metadata": { 902 | "collapsed": true 903 | }, 904 | "outputs": [], 905 | "source": [ 906 | "class A:\n", 907 | " val = 1\n", 908 | " \n", 909 | " def foo(self):\n", 910 | " A.val += 2 # значение изменится для всего класса\n", 911 | " \n", 912 | " def bar(self):\n", 913 | " self.val += 1 # значение изменится только для одного объекта" 914 | ] 915 | }, 916 | { 917 | "cell_type": "markdown", 918 | "metadata": {}, 919 | "source": [ 920 | "## Наследование классов" 921 | ] 922 | }, 923 | { 924 | "cell_type": "markdown", 925 | "metadata": {}, 926 | "source": [ 927 | "##### Синтаксис " 928 | ] 929 | }, 930 | { 931 | "cell_type": "code", 932 | "execution_count": 4, 933 | "metadata": { 934 | "collapsed": false 935 | }, 936 | "outputs": [ 937 | { 938 | "name": "stdout", 939 | "output_type": "stream", 940 | "text": [ 941 | "[]\n", 942 | "[1, 2, 3, 4, 5]\n", 943 | "False\n", 944 | "True\n" 945 | ] 946 | } 947 | ], 948 | "source": [ 949 | "class MyList(list): # в скобках указыаем от какого класса наследоваться\n", 950 | " def even_length(self): # добавляем новый метод\n", 951 | " pass # ничего не делать\n", 952 | " return len(self) % 2 == 0\n", 953 | "\n", 954 | "x = MyList()\n", 955 | "print(x)\n", 956 | "x.extend([1, 2, 3, 4, 5])\n", 957 | "print(x) # [1, 2, 3, 4, 5]\n", 958 | "print(x.even_length()) # False\n", 959 | "x.append(6)\n", 960 | "print(x.even_length()) #False" 961 | ] 962 | }, 963 | { 964 | "cell_type": "markdown", 965 | "metadata": {}, 966 | "source": [ 967 | "В Python есть специальная функция для получения информации о наследовании - issubclass(arg1, arg2), которая возвращает True, если первый аргумент является наследником второго." 968 | ] 969 | }, 970 | { 971 | "cell_type": "code", 972 | "execution_count": 5, 973 | "metadata": { 974 | "collapsed": false 975 | }, 976 | "outputs": [ 977 | { 978 | "data": { 979 | "text/plain": [ 980 | "False" 981 | ] 982 | }, 983 | "execution_count": 5, 984 | "metadata": {}, 985 | "output_type": "execute_result" 986 | } 987 | ], 988 | "source": [ 989 | "class D: pass\n", 990 | "class E: pass\n", 991 | "class B(D, E): pass\n", 992 | "class C: pass\n", 993 | "class A(B, C): pass\n", 994 | "\n", 995 | "issubclass(A, A) # True\n", 996 | "issubclass(C, D) # False\n", 997 | "issubclass(A, D) # True\n", 998 | "issubclass(C, object) # True\n", 999 | "issubclass(object, C) # False" 1000 | ] 1001 | }, 1002 | { 1003 | "cell_type": "markdown", 1004 | "metadata": {}, 1005 | "source": [ 1006 | "Для того, чтобы узнать является ли объект экземпляром некоторого класса используется функция isinstance" 1007 | ] 1008 | }, 1009 | { 1010 | "cell_type": "code", 1011 | "execution_count": 6, 1012 | "metadata": { 1013 | "collapsed": false 1014 | }, 1015 | "outputs": [ 1016 | { 1017 | "data": { 1018 | "text/plain": [ 1019 | "False" 1020 | ] 1021 | }, 1022 | "execution_count": 6, 1023 | "metadata": {}, 1024 | "output_type": "execute_result" 1025 | } 1026 | ], 1027 | "source": [ 1028 | "x = A\n", 1029 | "isinstance(x, A) # True\n", 1030 | "isinstance(x, B) # True, т.к. B - предок A\n", 1031 | "isinstance(x, object) # True\n", 1032 | "isinstance(x, str) # False" 1033 | ] 1034 | }, 1035 | { 1036 | "cell_type": "markdown", 1037 | "metadata": {}, 1038 | "source": [ 1039 | "mro - метод класса object для определения предков класса" 1040 | ] 1041 | }, 1042 | { 1043 | "cell_type": "code", 1044 | "execution_count": 7, 1045 | "metadata": { 1046 | "collapsed": false 1047 | }, 1048 | "outputs": [ 1049 | { 1050 | "name": "stdout", 1051 | "output_type": "stream", 1052 | "text": [ 1053 | "[, , , , , ]\n" 1054 | ] 1055 | } 1056 | ], 1057 | "source": [ 1058 | "print(A.mro()) # Предки класса" 1059 | ] 1060 | }, 1061 | { 1062 | "cell_type": "code", 1063 | "execution_count": null, 1064 | "metadata": { 1065 | "collapsed": true 1066 | }, 1067 | "outputs": [], 1068 | "source": [ 1069 | "При множественном наследовании больший преоритет имеет тот класс, что был наследован раньше других в списке наследуемых объектов." 1070 | ] 1071 | }, 1072 | { 1073 | "cell_type": "markdown", 1074 | "metadata": {}, 1075 | "source": [ 1076 | "Для обращения к родительским методам используется метод super(arg1, arg2). arg1 - класс родителя, который мы хотим проверить, arg2 - объект с которым мы хотим связать метод." 1077 | ] 1078 | }, 1079 | { 1080 | "cell_type": "code", 1081 | "execution_count": 21, 1082 | "metadata": { 1083 | "collapsed": false 1084 | }, 1085 | "outputs": [ 1086 | { 1087 | "name": "stdout", 1088 | "output_type": "stream", 1089 | "text": [ 1090 | "Last value is 17\n", 1091 | "17\n", 1092 | "[1, 2, 4]\n" 1093 | ] 1094 | } 1095 | ], 1096 | "source": [ 1097 | "class EvenLengthMixin:\n", 1098 | " def even_length(self):\n", 1099 | " return len(self) % 2 == 0\n", 1100 | "\n", 1101 | "class MyList(list, EvenLengthMixin):\n", 1102 | " def pop(self):\n", 1103 | " x = super(MyList, self).pop()\n", 1104 | " print(\"Last value is\", x)\n", 1105 | " return x\n", 1106 | " \n", 1107 | "ml = MySuperList([1, 2, 4, 17])\n", 1108 | "z = ml.pop() # Last value is 17\n", 1109 | "print(z) # 17\n", 1110 | "print(ml) # [1, 2, 4]" 1111 | ] 1112 | }, 1113 | { 1114 | "cell_type": "code", 1115 | "execution_count": 27, 1116 | "metadata": { 1117 | "collapsed": false 1118 | }, 1119 | "outputs": [ 1120 | { 1121 | "name": "stdout", 1122 | "output_type": "stream", 1123 | "text": [ 1124 | "[, , , , , ]\n" 1125 | ] 1126 | } 1127 | ], 1128 | "source": [ 1129 | "class A:\n", 1130 | " pass\n", 1131 | "\n", 1132 | "class B(A):\n", 1133 | " pass\n", 1134 | "\n", 1135 | "class C:\n", 1136 | " pass\n", 1137 | "\n", 1138 | "class D(C):\n", 1139 | " pass\n", 1140 | "\n", 1141 | "class E(B, D, C):\n", 1142 | " pass\n", 1143 | "print(E.mro())" 1144 | ] 1145 | }, 1146 | { 1147 | "cell_type": "markdown", 1148 | "metadata": {}, 1149 | "source": [ 1150 | "##### Задача 1 " 1151 | ] 1152 | }, 1153 | { 1154 | "cell_type": "code", 1155 | "execution_count": 2, 1156 | "metadata": { 1157 | "collapsed": false 1158 | }, 1159 | "outputs": [ 1160 | { 1161 | "name": "stdout", 1162 | "output_type": "stream", 1163 | "text": [ 1164 | "1\n", 1165 | "A\n", 1166 | "0\n" 1167 | ] 1168 | } 1169 | ], 1170 | "source": [ 1171 | "# Решена\n", 1172 | "def searchChildren(classes, parent, child):\n", 1173 | "\n", 1174 | " if parent == child:\n", 1175 | " return True\n", 1176 | "\n", 1177 | " if child in classes[parent]:\n", 1178 | " return True\n", 1179 | "\n", 1180 | " for grandparent in classes[parent]:\n", 1181 | " if searchChildren(classes, grandparent, child):\n", 1182 | " return True\n", 1183 | " return False\n", 1184 | "\n", 1185 | "\n", 1186 | "lst = []\n", 1187 | "classes = dict()\n", 1188 | "\n", 1189 | "n = int(input())\n", 1190 | "for i in range(n):\n", 1191 | " line = input().split(\" \")\n", 1192 | " if ':' in line:\n", 1193 | " for i in range(2, len(line)):\n", 1194 | " if classes.get(line[0]) is not None:\n", 1195 | " classes[line[0]] += [line[i]]\n", 1196 | " else:\n", 1197 | " classes[line[0]] = [line[i]]\n", 1198 | " if classes.get(line[i]) is None:\n", 1199 | " classes[line[i]] = []\n", 1200 | " else:\n", 1201 | " for i in range(len(line)):\n", 1202 | " classes[line[i]] = []\n", 1203 | "\n", 1204 | "n = int(input())\n", 1205 | "for i in range(n):\n", 1206 | " line = input().split()\n", 1207 | " lst += [(searchChildren(classes, line[1], line[0]))]\n", 1208 | "\n", 1209 | "# print(classes)\n", 1210 | "for i in range(len(lst)):\n", 1211 | " if lst[i] == 0:\n", 1212 | " print(\"Yes\")\n", 1213 | " else:\n", 1214 | " print(\"No\")" 1215 | ] 1216 | }, 1217 | { 1218 | "cell_type": "markdown", 1219 | "metadata": {}, 1220 | "source": [ 1221 | "##### Задача 2 " 1222 | ] 1223 | }, 1224 | { 1225 | "cell_type": "code", 1226 | "execution_count": 10, 1227 | "metadata": { 1228 | "collapsed": false 1229 | }, 1230 | "outputs": [ 1231 | { 1232 | "name": "stdout", 1233 | "output_type": "stream", 1234 | "text": [ 1235 | "0\n" 1236 | ] 1237 | } 1238 | ], 1239 | "source": [ 1240 | "# Решена\n", 1241 | "# Кстати, тут не совсем корректно используется переопределение методов, но ошибки, судя по всему, не возникает из-за того, \n", 1242 | "# что класс является наследником только одного класса list\n", 1243 | "class ExtendedStack(list):\n", 1244 | " def sum(self):\n", 1245 | " # операция сложения\n", 1246 | " self.append(self.pop() + self.pop())\n", 1247 | "\n", 1248 | " def sub(self):\n", 1249 | " # операция вычитания\n", 1250 | " self.append(self.pop() - self.pop())\n", 1251 | "\n", 1252 | " def mul(self):\n", 1253 | " # операция умножения\n", 1254 | " self.append(self.pop() * self.pop())\n", 1255 | "\n", 1256 | " def div(self):\n", 1257 | " # операция целочисленного деления\n", 1258 | " self.append(self.pop() // self.pop())" 1259 | ] 1260 | }, 1261 | { 1262 | "cell_type": "markdown", 1263 | "metadata": {}, 1264 | "source": [ 1265 | "##### Задача 3 " 1266 | ] 1267 | }, 1268 | { 1269 | "cell_type": "code", 1270 | "execution_count": null, 1271 | "metadata": { 1272 | "collapsed": true 1273 | }, 1274 | "outputs": [], 1275 | "source": [ 1276 | "# Решена\n", 1277 | "# Тут решение из задачи 2 уже не подойдет, т.к. присутствует множественное наследование (предположительно), \n", 1278 | "# поэтому используется ключевое слово super\n", 1279 | "import time\n", 1280 | "\n", 1281 | "class Loggable:\n", 1282 | " def log(self, msg):\n", 1283 | " print(str(time.ctime()) + \": \" + str(msg))\n", 1284 | "\n", 1285 | "class LoggableList(list, Loggable):\n", 1286 | " def append(self, obj):\n", 1287 | " super(LoggableList, self).append(obj)\n", 1288 | " super(LoggableList, self).log(obj)\n", 1289 | "\n", 1290 | "\n", 1291 | "lst = LoggableList()\n", 1292 | "lst.append('something1')\n", 1293 | "lst.append('something2')" 1294 | ] 1295 | } 1296 | ], 1297 | "metadata": { 1298 | "kernelspec": { 1299 | "display_name": "Python 3", 1300 | "language": "python", 1301 | "name": "python3" 1302 | }, 1303 | "language_info": { 1304 | "codemirror_mode": { 1305 | "name": "ipython", 1306 | "version": 3 1307 | }, 1308 | "file_extension": ".py", 1309 | "mimetype": "text/x-python", 1310 | "name": "python", 1311 | "nbconvert_exporter": "python", 1312 | "pygments_lexer": "ipython3", 1313 | "version": "3.5.0" 1314 | } 1315 | }, 1316 | "nbformat": 4, 1317 | "nbformat_minor": 0 1318 | } 1319 | --------------------------------------------------------------------------------