├── README.md ├── book_dl_cnn01_MNIST.ipynb ├── dj_AE_20220318.ipynb ├── dj_LSTMLangModel.ipynb ├── dj_TABLE_example.ipynb ├── dj_cat_coding.ipynb ├── dj_dl_cnn01_MNIST.ipynb ├── dj_fast_preprocessing.ipynb ├── dj_intro_pytorch20210125.ipynb ├── dj_matplotlib_intro.ipynb ├── dj_numpy_20181021.ipynb ├── dj_python_0_intro_20181004.ipynb ├── dj_python_2_oop_20181004.ipynb ├── dj_python_4_tonko_20181004.ipynb └── dj_value_counts.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # Приёмы при написании python-программ 2 | 3 | сделано для частного пользования и для выкладывания материалов, связанных с программированием на Питоне 4 | 5 | * [кодирование категориальных (факторных, номинальных) признаков](dj_cat_coding.ipynb) 6 | * [различные способы получения числа категорий](dj_value_counts.ipynb) 7 | * [4 задачи на быструю предобработку данных на Питоне (pandas)](dj_fast_preprocessing.ipynb) 8 | 9 | 10 | ### для лекции "Введение в ЯП Питон (Python)" курса https://github.com/Dyakonov/IML 11 | * [Питон часть I - общий обзор](dj_python_0_intro_20181004.ipynb) 12 | * части II пока нет 13 | * [Питон часть III - ООП](dj_python_2_oop_20181004.ipynb) 14 | * [Питон часть IV - тонкости](dj_python_4_tonko_20181004.ipynb) 15 | 16 | * [Пакеты Numpy, Scipy, Matplotlib](dj_numpy_20181021.ipynb) 17 | 18 | ### для начинающих 19 | * [Совсем начальное введение в Matplotlib](dj_matplotlib_intro.ipynb) 20 | 21 | 22 | ### Pytorch - для курса по DL 23 | 24 | * [Введение в Pytorch](dj_intro_pytorch20210125.ipynb) 25 | * [Пример сетей для табличных данных](dj_TABLE_example.ipynb) 26 | * [Пример работы с изображениями](book_dl_cnn01_MNIST.ipynb) 27 | * [Решение MNIST](dj_dl_cnn01_MNIST.ipynb) и выше тоже 28 | * [Автокодировщики](dj_AE_20220318.ipynb) и выше там тоже был пример (начать с него) 29 | * [Языковая модель на LSTM](dj_LSTMLangModel.ipynb) 30 | 31 | -------------------------------------------------------------------------------- /dj_LSTMLangModel.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "view-in-github", 7 | "colab_type": "text" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "id": "jr_HDBrT-XlW" 17 | }, 18 | "source": [ 19 | "# Языковая модель на LSTM\n", 20 | "\n", 21 | "по мотивам https://atcold.github.io/pytorch-Deep-Learning/" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": { 28 | "id": "I5cOUtpz-XlX", 29 | "outputId": "a9a97d48-b9cf-4c13-a072-c67b1323a3d7" 30 | }, 31 | "outputs": [ 32 | { 33 | "data": { 34 | "text/plain": [ 35 | "'cuda'" 36 | ] 37 | }, 38 | "execution_count": 1, 39 | "metadata": {}, 40 | "output_type": "execute_result" 41 | } 42 | ], 43 | "source": [ 44 | "import torch\n", 45 | "import torch.nn as nn\n", 46 | "import torch.nn.utils.rnn as rnn\n", 47 | "from torch.utils.data import Dataset, DataLoader, TensorDataset\n", 48 | "import numpy as np\n", 49 | "import time\n", 50 | "\n", 51 | "# import shakespeare_data as sh\n", 52 | "\n", 53 | "DEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", 54 | "DEVICE" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": { 60 | "id": "VYT7Q6Vd-XlY" 61 | }, 62 | "source": [ 63 | "## Загрузить данные" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "metadata": { 70 | "scrolled": true, 71 | "id": "VSoPFZvH-XlY", 72 | "outputId": "54991443-96e5-48d4-f280-786e10cc4a48" 73 | }, 74 | "outputs": [ 75 | { 76 | "name": "stdout", 77 | "output_type": "stream", 78 | "text": [ 79 | "александр сергеевич пушкин евгений онегин роман в стихах ,. проникнутый тщеславием, он обладал сверх того еще особенной гордостью, которая побуждает признаваться с одинаковым равнодушием в своих как добрых, так и дурных поступках, следствие чувства превосходства, быть может мнимого.из частного письма фр. мысля гордый свет забавить, вниманье дружбы возлюбя, хотел бы я тебе представить залог достойнее тебя, достойнее души прекрасной, святой исполненной мечты, поэзии живой и ясной, высоких дум и простоты; но так и быть рукой пристрастной прими собранье пестрых глав, полусмешных, полупечальных, простонародных, идеальных, небрежный плод моих забав, бессонниц, легких вдохновений, незрелых и увядших лет, ума холодных наблюдений и сердца горестных замет. глава первая и жить торопится, и чувствовать спешит. князь вяземский эпиграф взят из стихотворения п. а. вяземского первый снег. мой дядя самых честных правил, когда не в шутку занемог, он уважать себя заставил и лучше выдумать не мог. его пример другим наука; но, боже мой, какая скука с больным сидеть и день и ночь, не отходя ни шагу прочь! какое низкое коварство полуживого забавлять, ему подушки поправлять, печально подносить лекарство, вздыхать и думать про себя: когда же черт возьмет тебя! так думал молодой повеса, летя в пыли на почтовых, всевышней волею зевеса наследник всех своих родных. друзья людмилы и руслана! с героем моего романа без предисловий, сей же час позвольте познакомить вас: онегин, добрый мой приятель, родился на брегах невы, где, может быть, родились вы или блистали, мой читатель; там некогда гулял и я: но вреден север для меня писано в бесарабии. служив отлично благородно, долгами жил его отец, давал три бала ежегодно и промотался наконец. судьба евгения хранила: сперва за ним ходила, потом ее сменил; ребенок был резов, но мил. , француз убогой, чтоб не измучилось дитя, учил его всему шутя, не докучал моралью строгой, слегка за шалости бранил и в летний сад гулять водил. когда же юности мятежной приш\n" 80 | ] 81 | } 82 | ], 83 | "source": [ 84 | "# filename = 'onegin_small.txt'\n", 85 | "filename = 'onegin.txt'\n", 86 | "\n", 87 | "import re\n", 88 | "\n", 89 | "\n", 90 | "\n", 91 | "def read_corpus(filename):\n", 92 | " # r = re.compile(\"[а-яА-Я .!,;:]+\")\n", 93 | " lines = []\n", 94 | " with open(filename, 'r', encoding='Windows-1251', errors='ignore') as f:\n", 95 | " for pos, line in enumerate(f):\n", 96 | " # line = line.replace(\"\\t\", \"\").replace(\"\\n\", \" \")\n", 97 | " #line = ''.join([c for c in filter(r.match, line)]) # оставить русские буквы\n", 98 | " #\n", 99 | " line = re.sub('[^а-яА-Я .!,;:]+', ' ', line.replace(\"\\t\", \"\").replace(\"\\n\", \" \")).strip().lower()\n", 100 | " line = re.sub(\" +\", \" \", line) # схлопываем пробелы\n", 101 | " line = line.replace(\" .\", \".\")\n", 102 | " line = line.replace(\" ,\", \",\")\n", 103 | " line = line.replace(\" !\", \"!\")\n", 104 | " line = re.sub(\"[.]+\", \".\", line)\n", 105 | " line = re.sub(\"[,]+\", \",\", line)\n", 106 | " line = re.sub(\"[!]+\", \"!\", line)\n", 107 | " if len(line.strip()) > 0:\n", 108 | " lines.append(line)\n", 109 | " corpus = \" \".join(lines)\n", 110 | " return corpus\n", 111 | "\n", 112 | "corpus = read_corpus(filename)\n", 113 | "print (corpus[:2000])" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": null, 119 | "metadata": { 120 | "id": "l-_7Y72f-XlY", 121 | "outputId": "a2c1f6bb-59bd-45bd-f39d-7562276a45ea" 122 | }, 123 | "outputs": [ 124 | { 125 | "name": "stdout", 126 | "output_type": "stream", 127 | "text": [ 128 | "Число символов в корпусе: 147224\n", 129 | "Число уникальных символов: 38\n", 130 | "corpus_array.shape: (147224,)\n" 131 | ] 132 | } 133 | ], 134 | "source": [ 135 | "def get_charmap(corpus):\n", 136 | " chars = list(set(corpus))\n", 137 | " chars.sort()\n", 138 | " charmap = {c: i for i, c in enumerate(chars)}\n", 139 | " return chars, charmap\n", 140 | "\n", 141 | "\n", 142 | "def map_corpus(corpus, charmap):\n", 143 | " return np.array([charmap[c] for c in corpus], dtype=np.int64)\n", 144 | "\n", 145 | "\n", 146 | "def to_text(line, charset):\n", 147 | " return \"\".join([charset[c] for c in line])\n", 148 | "\n", 149 | "print(f\"Число символов в корпусе: {len(corpus)}\")\n", 150 | "chars, charmap = get_charmap(corpus)\n", 151 | "charcount = len(chars)\n", 152 | "print(f\"Число уникальных символов: {len(chars)}\")\n", 153 | "corpus_array = map_corpus(corpus, charmap)\n", 154 | "print(f\"corpus_array.shape: {corpus_array.shape}\")\n", 155 | "\n", 156 | "# Число символов в корпусе: 158663\n", 157 | "# Число уникальных символов: 148\n", 158 | "# corpus_array.shape: (158663,)" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": null, 164 | "metadata": { 165 | "id": "mVxZUUtV-XlY", 166 | "outputId": "c0173b1a-b9ec-48ee-ece0-7cc1a5eced90" 167 | }, 168 | "outputs": [ 169 | { 170 | "name": "stdout", 171 | "output_type": "stream", 172 | "text": [ 173 | " ! , . : ; а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я\n" 174 | ] 175 | } 176 | ], 177 | "source": [ 178 | "print (' '.join(chars)) # символы" 179 | ] 180 | }, 181 | { 182 | "cell_type": "code", 183 | "execution_count": null, 184 | "metadata": { 185 | "id": "uu7TGnaS-XlY", 186 | "outputId": "b509962b-da6f-4bda-a372-6981d9709134" 187 | }, 188 | "outputs": [ 189 | { 190 | "name": "stdout", 191 | "output_type": "stream", 192 | "text": [ 193 | "{' ': 0, '!': 1, ',': 2, '.': 3, ':': 4, ';': 5, 'а': 6, 'б': 7, 'в': 8, 'г': 9, 'д': 10, 'е': 11, 'ж': 12, 'з': 13, 'и': 14, 'й': 15, 'к': 16, 'л': 17, 'м': 18, 'н': 19, 'о': 20, 'п': 21, 'р': 22, 'с': 23, 'т': 24, 'у': 25, 'ф': 26, 'х': 27, 'ц': 28, 'ч': 29, 'ш': 30, 'щ': 31, 'ъ': 32, 'ы': 33, 'ь': 34, 'э': 35, 'ю': 36, 'я': 37}\n" 194 | ] 195 | } 196 | ], 197 | "source": [ 198 | "print (charmap)" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": null, 204 | "metadata": { 205 | "id": "wF577ue0-XlZ" 206 | }, 207 | "outputs": [], 208 | "source": [ 209 | "# текст -> последовательности фиксированной длины\n", 210 | "# плохая версия!!!\n", 211 | "\n", 212 | "class TextDataset(Dataset):\n", 213 | "\n", 214 | " def __init__(self, text, seq_len = 200):\n", 215 | " n_seq = len(text) // seq_len\n", 216 | " text = text[:n_seq * seq_len]\n", 217 | " self.data = torch.tensor(text).view(-1,seq_len)\n", 218 | "\n", 219 | " def __getitem__(self,i):\n", 220 | " txt = self.data[i]\n", 221 | " return txt[:-1], txt[1:] # метки - это те же последовательности, сдвинутые на 1\n", 222 | "\n", 223 | " def __len__(self):\n", 224 | " return self.data.size(0)\n", 225 | "\n", 226 | "# используется в DataLoader - список последовательностей в батч\n", 227 | "# ответ: seq_len x batch_size\n", 228 | "def collate(seq_list):\n", 229 | " inputs = torch.cat([s[0].unsqueeze(1) for s in seq_list], dim=1)\n", 230 | " targets = torch.cat([s[1].unsqueeze(1) for s in seq_list], dim=1)\n", 231 | " return inputs, targets" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": null, 237 | "metadata": { 238 | "id": "zW0cIQ3j-XlZ" 239 | }, 240 | "outputs": [], 241 | "source": [ 242 | "\"\"\"\n", 243 | "более хорошая версия\n", 244 | "\"\"\"\n", 245 | "class TextDataset(Dataset):\n", 246 | "\n", 247 | " def __init__(self, text, seq_len = 200):\n", 248 | " self.len = len(text) - seq_len + 1\n", 249 | " self.data = []\n", 250 | " self.seq_len = seq_len\n", 251 | " for i in range(self.len):\n", 252 | " self.data.append(torch.tensor(text[i: i+self.seq_len]))\n", 253 | "\n", 254 | " def __getitem__(self, i):\n", 255 | " #line = self.data[i: i+self.seq_len]\n", 256 | " #line = torch.tensor(line) # это плохо\n", 257 | " line = self.data[i]\n", 258 | " return line[:-1].to(DEVICE), line[1:].to(DEVICE)\n", 259 | "\n", 260 | " def __len__(self):\n", 261 | " return self.len" 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "execution_count": null, 267 | "metadata": { 268 | "id": "GD7qZAN--XlZ" 269 | }, 270 | "outputs": [], 271 | "source": [ 272 | "# Model\n", 273 | "class CharLanguageModel(nn.Module):\n", 274 | "\n", 275 | " def __init__(self, vocab_size, embed_size, hidden_size, nlayers):\n", 276 | " super(CharLanguageModel,self).__init__()\n", 277 | " self.vocab_size = vocab_size\n", 278 | " self.embed_size = embed_size\n", 279 | " self.hidden_size = hidden_size\n", 280 | " self.nlayers = nlayers\n", 281 | " self.embedding = nn.Embedding(vocab_size,\n", 282 | " embed_size) # Embedding layer\n", 283 | " self.rnn = nn.LSTM(input_size = embed_size,\n", 284 | " hidden_size=hidden_size,\n", 285 | " num_layers=nlayers) # Recurrent network\n", 286 | " self.scoring = nn.Linear(hidden_size, vocab_size) # Projection layer\n", 287 | "\n", 288 | " def forward(self, seq_batch): # L x N\n", 289 | " # returns 3D logits\n", 290 | " batch_size = seq_batch.size(1) # здесь это размерность 1\n", 291 | " embed = self.embedding(seq_batch) # L x N x E\n", 292 | " hidden = None\n", 293 | " output_lstm, hidden = self.rnn(embed, hidden) # L x N x H\n", 294 | " output_lstm_flatten = output_lstm.view(-1, self.hidden_size) # (L*N) x H\n", 295 | " output_flatten = self.scoring(output_lstm_flatten) #(L*N) x V\n", 296 | " return output_flatten.view(-1, batch_size, self.vocab_size)\n", 297 | "\n", 298 | " def generate(self, seq, n_words): # L x V\n", 299 | " # жадный поиск для генерации слов\n", 300 | " generated_words = []\n", 301 | " embed = self.embedding(seq).unsqueeze(1) # L x 1 x E\n", 302 | " hidden = None\n", 303 | " output_lstm, hidden = self.rnn(embed, hidden) # L x 1 x H\n", 304 | " output = output_lstm[-1] # 1 x H\n", 305 | " scores = self.scoring(output) # 1 x V\n", 306 | " _, current_word = torch.max(scores, dim=1) # 1 x 1\n", 307 | " generated_words.append(current_word)\n", 308 | " if n_words > 1:\n", 309 | " for i in range(n_words-1):\n", 310 | " embed = self.embedding(current_word).unsqueeze(0) # 1 x 1 x E\n", 311 | " output_lstm, hidden = self.rnn(embed, hidden) # 1 x 1 x H\n", 312 | " output = output_lstm[0] # 1 x H\n", 313 | " scores = self.scoring(output) # V\n", 314 | " _,current_word = torch.max(scores, dim=1) # 1\n", 315 | " generated_words.append(current_word)\n", 316 | " return torch.cat(generated_words, dim=0)" 317 | ] 318 | }, 319 | { 320 | "cell_type": "code", 321 | "execution_count": null, 322 | "metadata": { 323 | "id": "pKyS-MEm-XlZ" 324 | }, 325 | "outputs": [], 326 | "source": [ 327 | "def train_epoch(model, optimizer, train_loader, val_loader):\n", 328 | " criterion = nn.CrossEntropyLoss()\n", 329 | " criterion = criterion.to(DEVICE)\n", 330 | " train_loss = 0\n", 331 | " before = time.time()\n", 332 | " print(\"training\", len(train_loader), \"number of batches\")\n", 333 | " for batch_idx, (inputs,targets) in enumerate(train_loader):\n", 334 | " if batch_idx == 0:\n", 335 | " first_time = time.time()\n", 336 | " inputs = inputs.to(DEVICE)\n", 337 | " targets = targets.to(DEVICE)\n", 338 | " outputs = model(inputs) # 3D\n", 339 | " loss = criterion(outputs.view(-1,outputs.size(2)),targets.view(-1)) # Loss of the flattened outputs\n", 340 | " optimizer.zero_grad()\n", 341 | " loss.backward()\n", 342 | " optimizer.step()\n", 343 | "\n", 344 | " train_loss += loss.item()\n", 345 | "\n", 346 | " #if batch_idx == 0:\n", 347 | " # print(\"Time elapsed\", time.time() - first_time)\n", 348 | "\n", 349 | " #if batch_idx % 500 == 0 and batch_idx != 0:\n", 350 | " # after = time.time()\n", 351 | " # print(\"Time: \", after - before)\n", 352 | " # print(\"Loss per word: \", loss.item() / batch_idx)\n", 353 | " # print(\"Perplexity: \", np.exp(loss.item() / batch_idx))\n", 354 | " # after = before\n", 355 | "\n", 356 | " train_loss = train_loss / batch_idx\n", 357 | "\n", 358 | " val_loss = 0\n", 359 | " batch_id = 0\n", 360 | " for inputs,targets in val_loader:\n", 361 | " batch_id += 1\n", 362 | " inputs = inputs.to(DEVICE)\n", 363 | " targets = targets.to(DEVICE)\n", 364 | " outputs = model(inputs)\n", 365 | " loss = criterion(outputs.view(-1,outputs.size(2)), targets.view(-1))\n", 366 | " val_loss += loss.item()\n", 367 | " val_lpw = val_loss / batch_id\n", 368 | " # print(\"\\nValidation loss per word:\",val_lpw)\n", 369 | " print(\"Train perplexity :\", np.exp(train_loss))\n", 370 | " print(\"Validation perplexity :\", np.exp(val_loss / batch_id))\n", 371 | " return val_lpw" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": null, 377 | "metadata": { 378 | "id": "cc9E1D1q-XlZ" 379 | }, 380 | "outputs": [], 381 | "source": [ 382 | "#model = CharLanguageModel(charcount, 256, 256,3)\n", 383 | "model = CharLanguageModel(vocab_size=charcount,\n", 384 | " embed_size=256,\n", 385 | " hidden_size=256,\n", 386 | " nlayers=2)\n", 387 | "model = model.to(DEVICE)\n", 388 | "optimizer = torch.optim.Adam(model.parameters(),\n", 389 | " lr=0.01, weight_decay=1e-7) #, # lr=0.001,\n", 390 | " #weight_decay=1e-6)\n", 391 | "\n", 392 | "split = 120000\n", 393 | "train_dataset = TextDataset(corpus_array[:split], seq_len=100)\n", 394 | "val_dataset = TextDataset(corpus_array[split:], seq_len=100)\n", 395 | "train_loader = DataLoader(train_dataset, shuffle=True, batch_size=64, collate_fn = collate)\n", 396 | "val_loader = DataLoader(val_dataset, shuffle=False, batch_size=64, collate_fn = collate, drop_last=True)" 397 | ] 398 | }, 399 | { 400 | "cell_type": "code", 401 | "execution_count": null, 402 | "metadata": { 403 | "id": "elQpQNEe-XlZ" 404 | }, 405 | "outputs": [], 406 | "source": [ 407 | "#train_dataset = TextDataset(shakespeare_array, seq_len = 10)\n", 408 | "#train_loader = DataLoader(train_dataset, shuffle=True, batch_size=1, collate_fn = collate)" 409 | ] 410 | }, 411 | { 412 | "cell_type": "code", 413 | "execution_count": null, 414 | "metadata": { 415 | "id": "NSGHOPo--XlZ", 416 | "outputId": "c1131169-c035-4748-8335-db1ee0b16308" 417 | }, 418 | "outputs": [ 419 | { 420 | "data": { 421 | "text/plain": [ 422 | "(119901, 27125)" 423 | ] 424 | }, 425 | "execution_count": 16, 426 | "metadata": {}, 427 | "output_type": "execute_result" 428 | } 429 | ], 430 | "source": [ 431 | "train_dataset.__len__(), val_dataset.__len__()\n", 432 | "# (1200, 386)" 433 | ] 434 | }, 435 | { 436 | "cell_type": "code", 437 | "execution_count": null, 438 | "metadata": { 439 | "id": "2hlve73c-XlZ" 440 | }, 441 | "outputs": [], 442 | "source": [ 443 | "# i = 0\n", 444 | "# for i1, i2 in val_loader:\n", 445 | "# i = i + 1\n", 446 | "# if (i>10): break;\n", 447 | "# # print(i1.shape, i2.shape)\n", 448 | "# print(i1, i2)\n", 449 | "\n", 450 | "128 3 0.01\n", 451 | "Train perplexity : 1.708431299024099\n", 452 | "Validation perplexity : 68.95001547975727\n", 453 | "\n", 454 | "256 3 lr=0.01, weight_decay=1e-7\n", 455 | "Train perplexity : 1.6952816075689339\n", 456 | "Validation perplexity : 55.76105459243429\n", 457 | "\n", 458 | "256 2 lr=0.01, weight_decay=1e-7\n", 459 | "Train perplexity : 1.9566967733083707\n", 460 | "Validation perplexity : 32.95505913167213" 461 | ] 462 | }, 463 | { 464 | "cell_type": "code", 465 | "execution_count": null, 466 | "metadata": { 467 | "id": "vc_pd3kk-XlZ", 468 | "outputId": "bf04fc1a-d0c7-4eed-bbdb-448cc57f9fb0" 469 | }, 470 | "outputs": [ 471 | { 472 | "name": "stdout", 473 | "output_type": "stream", 474 | "text": [ 475 | "training 1874 number of batches\n", 476 | "Train perplexity : 3.100737592348649\n", 477 | "Validation perplexity : 20.92226048805598\n", 478 | "training 1874 number of batches\n", 479 | "Train perplexity : 1.68108752638697\n", 480 | "Validation perplexity : 44.035060143245296\n" 481 | ] 482 | } 483 | ], 484 | "source": [ 485 | "for i in range(2):\n", 486 | " train_epoch(model=model,\n", 487 | " optimizer=optimizer,\n", 488 | " train_loader=train_loader,\n", 489 | " val_loader=val_loader)" 490 | ] 491 | }, 492 | { 493 | "cell_type": "code", 494 | "execution_count": null, 495 | "metadata": { 496 | "id": "0WtciWCT-XlZ" 497 | }, 498 | "outputs": [], 499 | "source": [ 500 | "def generate(model, seed, nwords):\n", 501 | " seq = map_corpus(seed, charmap)\n", 502 | " seq = torch.tensor(seq).to(DEVICE)\n", 503 | " out = model.generate(seq, nwords)\n", 504 | " return to_text(out.cpu().detach().numpy(), chars)" 505 | ] 506 | }, 507 | { 508 | "cell_type": "code", 509 | "execution_count": null, 510 | "metadata": { 511 | "id": "hciqG-mN-XlZ", 512 | "outputId": "07b643a8-af9b-4178-c80a-9bbe99ba9c02" 513 | }, 514 | "outputs": [ 515 | { 516 | "name": "stdout", 517 | "output_type": "stream", 518 | "text": [ 519 | " значит видеть свет! где ж лучше гордым и после важно повторять одно, стараться вас задригалы иль пр\n" 520 | ] 521 | } 522 | ], 523 | "source": [ 524 | "print(generate(model, \"онегин встал и подошел, сказав, что\", 100))" 525 | ] 526 | }, 527 | { 528 | "cell_type": "code", 529 | "execution_count": null, 530 | "metadata": { 531 | "id": "m8Q05TkI-XlZ", 532 | "outputId": "e1bb8d44-8c2e-4830-e58b-da67d38f0450" 533 | }, 534 | "outputs": [ 535 | { 536 | "name": "stdout", 537 | "output_type": "stream", 538 | "text": [ 539 | " занеможественной мечты, поэзии живой и кума ему не наши внемя. тут же полуравет, и вдруг нетвал, пр\n" 540 | ] 541 | } 542 | ], 543 | "source": [ 544 | "print(generate(model, \"мой дядя самых честных правил, когда не в шутку\", 100))" 545 | ] 546 | }, 547 | { 548 | "cell_type": "code", 549 | "execution_count": null, 550 | "metadata": { 551 | "id": "6qtp4tIl-Xla" 552 | }, 553 | "outputs": [], 554 | "source": [] 555 | }, 556 | { 557 | "cell_type": "code", 558 | "execution_count": null, 559 | "metadata": { 560 | "id": "KE139E0x-Xla" 561 | }, 562 | "outputs": [], 563 | "source": [ 564 | "seq = map_corpus(corpus[500:530], charmap) # \"Высоких дум и простоты\"\n", 565 | "seq = torch.tensor(seq).to(DEVICE)\n", 566 | "out = model.generate(seq, 100)\n" 567 | ] 568 | }, 569 | { 570 | "cell_type": "code", 571 | "execution_count": null, 572 | "metadata": { 573 | "id": "RAR_fVDY-Xla", 574 | "outputId": "59ce5e54-9618-45e4-8c85-dee9003708d0" 575 | }, 576 | "outputs": [ 577 | { 578 | "data": { 579 | "text/plain": [ 580 | "'александр сергеевич пушкин евгений онегин роман в стихах ,. проникнутый тщеславием, он обладал сверх того еще особенной гордостью, которая побуждает признаваться с одинаковым равнодушием в своих как добрых, так и дурных поступках, следствие чувства превосходства, быть может мнимого.из частного письма фр. мысля гордый свет забавить, вниманье дружбы возлюбя, хотел бы я тебе представить залог достойнее тебя, достойнее души прекрасной, святой исполненной мечты, поэзии живой и ясной, высоких дум и простоты; но так и быть рукой пристрастной прими собранье пестрых глав, полусмешных, полупечальных, простонародных, идеальных, небрежный плод моих забав, бессонниц, легких вдохновений, незрелых и увядших лет, ума холодных наблюдений и сердца горестных замет. глава первая и жить торопится, и чувствовать спешит. князь вяземский эпиграф взят из стихотворения п. а. вяземского первый снег. мой дядя самых честных правил, когда не в шутку занемог, он уважать себя заставил и лучше выдумать не мог. его при'" 581 | ] 582 | }, 583 | "execution_count": 89, 584 | "metadata": {}, 585 | "output_type": "execute_result" 586 | } 587 | ], 588 | "source": [ 589 | "corpus[:1000] # 500:1530]" 590 | ] 591 | }, 592 | { 593 | "cell_type": "code", 594 | "execution_count": null, 595 | "metadata": { 596 | "id": "DEk6k6WM-Xla", 597 | "outputId": "0df0524a-a0a4-49bb-b9a0-ea81771af85f" 598 | }, 599 | "outputs": [ 600 | { 601 | "data": { 602 | "text/plain": [ 603 | "tensor([21, 20, 23, 24, 6, 17, 34, 19, 20, 0, 21, 20, 23, 24, 6, 17, 34, 19,\n", 604 | " 20, 0, 21, 20, 23, 24, 6, 17, 34, 19, 20, 0, 21, 20, 23, 24, 6, 17,\n", 605 | " 34, 19, 20, 0, 21, 20, 23, 24, 6, 17, 34, 19, 20, 0, 21, 20, 23, 24,\n", 606 | " 6, 17, 34, 19, 20, 0, 21, 20, 23, 24, 6, 17, 34, 19, 20, 0, 21, 20,\n", 607 | " 23, 24, 6, 17, 34, 19, 20, 0, 21, 20, 23, 24, 6, 17, 34, 19, 20, 0,\n", 608 | " 21, 20, 23, 24, 6, 17, 34, 19, 20, 0], device='cuda:0')" 609 | ] 610 | }, 611 | "execution_count": 23, 612 | "metadata": {}, 613 | "output_type": "execute_result" 614 | } 615 | ], 616 | "source": [ 617 | "out" 618 | ] 619 | }, 620 | { 621 | "cell_type": "code", 622 | "execution_count": null, 623 | "metadata": { 624 | "id": "PltYvTZW-Xla", 625 | "outputId": "6350a55a-3af4-4dbd-ca9f-532f76f099bf" 626 | }, 627 | "outputs": [ 628 | { 629 | "data": { 630 | "text/plain": [ 631 | "148" 632 | ] 633 | }, 634 | "execution_count": 72, 635 | "metadata": {}, 636 | "output_type": "execute_result" 637 | } 638 | ], 639 | "source": [ 640 | "charcount" 641 | ] 642 | } 643 | ], 644 | "metadata": { 645 | "kernelspec": { 646 | "display_name": "Python 3", 647 | "language": "python", 648 | "name": "python3" 649 | }, 650 | "language_info": { 651 | "codemirror_mode": { 652 | "name": "ipython", 653 | "version": 3 654 | }, 655 | "file_extension": ".py", 656 | "mimetype": "text/x-python", 657 | "name": "python", 658 | "nbconvert_exporter": "python", 659 | "pygments_lexer": "ipython3", 660 | "version": "3.8.8" 661 | }, 662 | "colab": { 663 | "provenance": [], 664 | "include_colab_link": true 665 | } 666 | }, 667 | "nbformat": 4, 668 | "nbformat_minor": 0 669 | } -------------------------------------------------------------------------------- /dj_fast_preprocessing.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Эксперименты по ускорению обработки данных в Python\n", 8 | "\n", 9 | "* 2019, Александр Дьяконов (https://dyakonov.org/ag/)\n", 10 | "\n", 11 | "Частично использованы материалы\n", 12 | "\n", 13 | "* Глеба Маслякова https://nbviewer.jupyter.org/github/glebmaslyak/PZAD_Homeworks/blob/student/PZAD_feature_preprocessing_hw.ipynb \n", 14 | "\n", 15 | "* Дениса Бибика https://nbviewer.jupyter.org/github/den-bibik/PZAD/blob/master/optimize.ipynb" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 136, 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "import pandas as pd\n", 25 | "import numpy as np" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "### Задача 1 - устранить знак доллара" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 137, 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "data": { 42 | "text/html": [ 43 | "
\n", 44 | "\n", 57 | "\n", 58 | " \n", 59 | " \n", 60 | " \n", 61 | " \n", 62 | " \n", 63 | " \n", 64 | " \n", 65 | " \n", 66 | " \n", 67 | " \n", 68 | " \n", 69 | " \n", 70 | " \n", 71 | " \n", 72 | " \n", 73 | " \n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | "
pricefeature
017$0.0
189$0.0
239$0.0
397$0.0
423$0.0
\n", 93 | "
" 94 | ], 95 | "text/plain": [ 96 | " price feature\n", 97 | "0 17$ 0.0\n", 98 | "1 89$ 0.0\n", 99 | "2 39$ 0.0\n", 100 | "3 97$ 0.0\n", 101 | "4 23$ 0.0" 102 | ] 103 | }, 104 | "execution_count": 137, 105 | "metadata": {}, 106 | "output_type": "execute_result" 107 | } 108 | ], 109 | "source": [ 110 | "def make_s(n_rows):\n", 111 | " tmp = pd.DataFrame({'price': (100*np.random.rand(n_rows)).astype(int), 'feature': np.zeros(n_rows)})\n", 112 | " tmp['price'] = tmp['price'].astype(str) + '$'\n", 113 | " return tmp\n", 114 | "\n", 115 | "data = make_s(5)\n", 116 | "data" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 139, 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "text/html": [ 127 | "
\n", 128 | "\n", 141 | "\n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | "
pricefeatureprice($)_v1price($)_v2price($)_v3price($)_v4
017$0.017171717
189$0.089898989
239$0.039393939
397$0.097979797
423$0.023232323
\n", 201 | "
" 202 | ], 203 | "text/plain": [ 204 | " price feature price($)_v1 price($)_v2 price($)_v3 price($)_v4\n", 205 | "0 17$ 0.0 17 17 17 17\n", 206 | "1 89$ 0.0 89 89 89 89\n", 207 | "2 39$ 0.0 39 39 39 39\n", 208 | "3 97$ 0.0 97 97 97 97\n", 209 | "4 23$ 0.0 23 23 23 23" 210 | ] 211 | }, 212 | "execution_count": 139, 213 | "metadata": {}, 214 | "output_type": "execute_result" 215 | } 216 | ], 217 | "source": [ 218 | "data['price($)_v1'] = data['price'].apply(lambda x: int(x[:-1]))\n", 219 | "data['price($)_v2'] = data['price'].apply(lambda x: x[:-1]).astype(int)\n", 220 | "data['price($)_v3'] = data['price'].apply(lambda x: x.replace('$', '')).astype(int)\n", 221 | "data['price($)_v4'] = data['price'].str.replace('$', '').astype(int)\n", 222 | "data" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": 140, 228 | "metadata": {}, 229 | "outputs": [], 230 | "source": [ 231 | "data = make_s(10000000)" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 141, 237 | "metadata": {}, 238 | "outputs": [ 239 | { 240 | "name": "stdout", 241 | "output_type": "stream", 242 | "text": [ 243 | "CPU times: user 4.26 s, sys: 60 ms, total: 4.32 s\n", 244 | "Wall time: 4.36 s\n" 245 | ] 246 | } 247 | ], 248 | "source": [ 249 | "%%time\n", 250 | "data['price($))_v1'] = data['price'].apply(lambda x: int(x[:-1]))\n", 251 | "# 4.2-4.33" 252 | ] 253 | }, 254 | { 255 | "cell_type": "code", 256 | "execution_count": 147, 257 | "metadata": {}, 258 | "outputs": [ 259 | { 260 | "name": "stdout", 261 | "output_type": "stream", 262 | "text": [ 263 | "CPU times: user 2.5 s, sys: 124 ms, total: 2.62 s\n", 264 | "Wall time: 2.65 s\n" 265 | ] 266 | } 267 | ], 268 | "source": [ 269 | "%%time\n", 270 | "data['price($)_v2'] = data['price'].apply(lambda x: x[:-1]).astype(int)\n", 271 | "# 2.47 s - 2.52 s" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": 144, 277 | "metadata": {}, 278 | "outputs": [ 279 | { 280 | "name": "stdout", 281 | "output_type": "stream", 282 | "text": [ 283 | "CPU times: user 3.19 s, sys: 152 ms, total: 3.34 s\n", 284 | "Wall time: 3.35 s\n" 285 | ] 286 | } 287 | ], 288 | "source": [ 289 | "%%time\n", 290 | "data['price($)_v3'] = data['price'].apply(lambda x: x.replace('$', '')).astype(int) \n", 291 | "# 3.14 - 3.31" 292 | ] 293 | }, 294 | { 295 | "cell_type": "code", 296 | "execution_count": 145, 297 | "metadata": {}, 298 | "outputs": [ 299 | { 300 | "name": "stdout", 301 | "output_type": "stream", 302 | "text": [ 303 | "CPU times: user 3.43 s, sys: 164 ms, total: 3.6 s\n", 304 | "Wall time: 3.63 s\n" 305 | ] 306 | } 307 | ], 308 | "source": [ 309 | "%%time\n", 310 | "data['price($)_v4'] = data['price'].str.replace('$', '').astype(int)\n", 311 | "# 3.43 - 4" 312 | ] 313 | }, 314 | { 315 | "cell_type": "markdown", 316 | "metadata": {}, 317 | "source": [ 318 | "### Задача - бинаризовать" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": 150, 324 | "metadata": {}, 325 | "outputs": [ 326 | { 327 | "data": { 328 | "text/html": [ 329 | "
\n", 330 | "\n", 343 | "\n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | "
typefeature
0A0.0
1B0.0
2A0.0
3A0.0
4A0.0
\n", 379 | "
" 380 | ], 381 | "text/plain": [ 382 | " type feature\n", 383 | "0 A 0.0\n", 384 | "1 B 0.0\n", 385 | "2 A 0.0\n", 386 | "3 A 0.0\n", 387 | "4 A 0.0" 388 | ] 389 | }, 390 | "execution_count": 150, 391 | "metadata": {}, 392 | "output_type": "execute_result" 393 | } 394 | ], 395 | "source": [ 396 | "def make_t(n_rows):\n", 397 | " tmp = pd.DataFrame({'type': np.where(np.random.rand(n_rows)<0.5, 'A', 'B'), 'feature': np.zeros(n_rows)})\n", 398 | " return tmp\n", 399 | "\n", 400 | "data = make_t(5)\n", 401 | "data" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": 155, 407 | "metadata": {}, 408 | "outputs": [ 409 | { 410 | "data": { 411 | "text/html": [ 412 | "
\n", 413 | "\n", 426 | "\n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | "
typefeaturetype_v1type_v2type_v3type_v4type_v5type_v6type_v7
0A0.01111010
1B0.00000101
2A0.01111010
3A0.01111010
4A0.01111010
\n", 504 | "
" 505 | ], 506 | "text/plain": [ 507 | " type feature type_v1 type_v2 type_v3 type_v4 type_v5 type_v6 type_v7\n", 508 | "0 A 0.0 1 1 1 1 0 1 0\n", 509 | "1 B 0.0 0 0 0 0 1 0 1\n", 510 | "2 A 0.0 1 1 1 1 0 1 0\n", 511 | "3 A 0.0 1 1 1 1 0 1 0\n", 512 | "4 A 0.0 1 1 1 1 0 1 0" 513 | ] 514 | }, 515 | "execution_count": 155, 516 | "metadata": {}, 517 | "output_type": "execute_result" 518 | } 519 | ], 520 | "source": [ 521 | "data['type_v1'] = data['type'].apply(lambda x: 1 if x == \"A\" else 0)\n", 522 | "data['type_v2'] = (data['type']=='A').astype(int)\n", 523 | "data['type_v3'] = np.where(data['type'] == 'A', 1 ,0)\n", 524 | "data['type_v4'] = data['type'].map({'A': 1, 'B': 0})\n", 525 | "data['type_v5'] = data['type'].factorize()[0] # некорректный ответ\n", 526 | "data['type_v6'] = pd.get_dummies(data['type'])['A'] # uint8!!!\n", 527 | "from sklearn import preprocessing\n", 528 | "data['type_v7'] = preprocessing.LabelEncoder().fit_transform(data['type']) # некорректный ответ\n", 529 | "\n", 530 | "data" 531 | ] 532 | }, 533 | { 534 | "cell_type": "code", 535 | "execution_count": 156, 536 | "metadata": {}, 537 | "outputs": [], 538 | "source": [ 539 | "data = make_t(10000000)" 540 | ] 541 | }, 542 | { 543 | "cell_type": "code", 544 | "execution_count": 157, 545 | "metadata": {}, 546 | "outputs": [ 547 | { 548 | "name": "stdout", 549 | "output_type": "stream", 550 | "text": [ 551 | "CPU times: user 2.14 s, sys: 72 ms, total: 2.22 s\n", 552 | "Wall time: 2.25 s\n" 553 | ] 554 | } 555 | ], 556 | "source": [ 557 | "%%time\n", 558 | "data['type_v1'] = data['type'].apply(lambda x: 1 if x == \"A\" else 0)\n", 559 | "# 2.14 s - 2.18 s" 560 | ] 561 | }, 562 | { 563 | "cell_type": "code", 564 | "execution_count": 159, 565 | "metadata": {}, 566 | "outputs": [ 567 | { 568 | "name": "stdout", 569 | "output_type": "stream", 570 | "text": [ 571 | "CPU times: user 1.82 s, sys: 60 ms, total: 1.88 s\n", 572 | "Wall time: 1.89 s\n" 573 | ] 574 | } 575 | ], 576 | "source": [ 577 | "%%time\n", 578 | "data['type_v1'] = data['type'].apply(lambda x: \"1\" if x == \"A\" else \"0\").astype(int)\n", 579 | "# 1.82 s - 1.86 s" 580 | ] 581 | }, 582 | { 583 | "cell_type": "code", 584 | "execution_count": 160, 585 | "metadata": {}, 586 | "outputs": [ 587 | { 588 | "name": "stdout", 589 | "output_type": "stream", 590 | "text": [ 591 | "CPU times: user 364 ms, sys: 20 ms, total: 384 ms\n", 592 | "Wall time: 386 ms\n" 593 | ] 594 | } 595 | ], 596 | "source": [ 597 | "%%time\n", 598 | "data['type_v2'] = (data['type']=='A').astype(int)\n", 599 | "# 348 - 364" 600 | ] 601 | }, 602 | { 603 | "cell_type": "code", 604 | "execution_count": 161, 605 | "metadata": {}, 606 | "outputs": [ 607 | { 608 | "name": "stdout", 609 | "output_type": "stream", 610 | "text": [ 611 | "CPU times: user 376 ms, sys: 20 ms, total: 396 ms\n", 612 | "Wall time: 398 ms\n" 613 | ] 614 | } 615 | ], 616 | "source": [ 617 | "%%time\n", 618 | "data['type_v3'] = np.where(data['type'] == 'A', 1 ,0)\n", 619 | "# 380-398" 620 | ] 621 | }, 622 | { 623 | "cell_type": "code", 624 | "execution_count": 162, 625 | "metadata": {}, 626 | "outputs": [ 627 | { 628 | "name": "stdout", 629 | "output_type": "stream", 630 | "text": [ 631 | "CPU times: user 420 ms, sys: 16 ms, total: 436 ms\n", 632 | "Wall time: 443 ms\n" 633 | ] 634 | } 635 | ], 636 | "source": [ 637 | "%%time\n", 638 | "data['type_v4'] = data['type'].map({'A': 1, 'B': 0})\n", 639 | "# 400-424" 640 | ] 641 | }, 642 | { 643 | "cell_type": "code", 644 | "execution_count": 163, 645 | "metadata": {}, 646 | "outputs": [ 647 | { 648 | "name": "stdout", 649 | "output_type": "stream", 650 | "text": [ 651 | "CPU times: user 304 ms, sys: 36 ms, total: 340 ms\n", 652 | "Wall time: 357 ms\n" 653 | ] 654 | } 655 | ], 656 | "source": [ 657 | "%%time\n", 658 | "data['type_v5'] = data['type'].factorize()[0]\n", 659 | "# 304-324" 660 | ] 661 | }, 662 | { 663 | "cell_type": "code", 664 | "execution_count": 164, 665 | "metadata": {}, 666 | "outputs": [ 667 | { 668 | "name": "stdout", 669 | "output_type": "stream", 670 | "text": [ 671 | "CPU times: user 364 ms, sys: 28 ms, total: 392 ms\n", 672 | "Wall time: 395 ms\n" 673 | ] 674 | } 675 | ], 676 | "source": [ 677 | "%%time\n", 678 | "data['type_v6'] = pd.get_dummies(data['type'])['A']\n", 679 | "# 360-392" 680 | ] 681 | }, 682 | { 683 | "cell_type": "code", 684 | "execution_count": 168, 685 | "metadata": {}, 686 | "outputs": [ 687 | { 688 | "name": "stdout", 689 | "output_type": "stream", 690 | "text": [ 691 | "CPU times: user 5.5 s, sys: 36 ms, total: 5.53 s\n", 692 | "Wall time: 5.52 s\n" 693 | ] 694 | } 695 | ], 696 | "source": [ 697 | "%%time\n", 698 | "from sklearn import preprocessing\n", 699 | "data['type_v7'] = preprocessing.LabelEncoder().fit_transform(data['type']) # некорректный ответ\n", 700 | "# 5.47 s - 5.57 s" 701 | ] 702 | }, 703 | { 704 | "cell_type": "markdown", 705 | "metadata": {}, 706 | "source": [ 707 | "### Задача - расщепить" 708 | ] 709 | }, 710 | { 711 | "cell_type": "code", 712 | "execution_count": 169, 713 | "metadata": {}, 714 | "outputs": [ 715 | { 716 | "data": { 717 | "text/html": [ 718 | "
\n", 719 | "\n", 732 | "\n", 733 | " \n", 734 | " \n", 735 | " \n", 736 | " \n", 737 | " \n", 738 | " \n", 739 | " \n", 740 | " \n", 741 | " \n", 742 | " \n", 743 | " \n", 744 | " \n", 745 | " \n", 746 | " \n", 747 | " \n", 748 | " \n", 749 | " \n", 750 | " \n", 751 | " \n", 752 | " \n", 753 | " \n", 754 | " \n", 755 | " \n", 756 | " \n", 757 | " \n", 758 | " \n", 759 | " \n", 760 | " \n", 761 | " \n", 762 | " \n", 763 | " \n", 764 | " \n", 765 | " \n", 766 | " \n", 767 | "
featureA/B
00.023/60
10.065/76
20.066/53
30.057/53
40.085/18
\n", 768 | "
" 769 | ], 770 | "text/plain": [ 771 | " feature A/B\n", 772 | "0 0.0 23/60\n", 773 | "1 0.0 65/76\n", 774 | "2 0.0 66/53\n", 775 | "3 0.0 57/53\n", 776 | "4 0.0 85/18" 777 | ] 778 | }, 779 | "execution_count": 169, 780 | "metadata": {}, 781 | "output_type": "execute_result" 782 | } 783 | ], 784 | "source": [ 785 | "def make_ab(n_rows):\n", 786 | " tmp = pd.DataFrame({'A': (100*np.random.rand(n_rows)).astype(int), 'B': (100*np.random.rand(n_rows)).astype(int), 'feature': np.zeros(n_rows)})\n", 787 | " tmp['A/B'] = tmp['A'].astype(str) + '/' + tmp['B'].astype(str)\n", 788 | " del tmp['A']\n", 789 | " del tmp['B']\n", 790 | " return tmp\n", 791 | "\n", 792 | "data = make_ab(5)\n", 793 | "data" 794 | ] 795 | }, 796 | { 797 | "cell_type": "code", 798 | "execution_count": 171, 799 | "metadata": {}, 800 | "outputs": [ 801 | { 802 | "data": { 803 | "text/html": [ 804 | "
\n", 805 | "\n", 818 | "\n", 819 | " \n", 820 | " \n", 821 | " \n", 822 | " \n", 823 | " \n", 824 | " \n", 825 | " \n", 826 | " \n", 827 | " \n", 828 | " \n", 829 | " \n", 830 | " \n", 831 | " \n", 832 | " \n", 833 | " \n", 834 | " \n", 835 | " \n", 836 | " \n", 837 | " \n", 838 | " \n", 839 | " \n", 840 | " \n", 841 | " \n", 842 | " \n", 843 | " \n", 844 | " \n", 845 | " \n", 846 | " \n", 847 | " \n", 848 | " \n", 849 | " \n", 850 | " \n", 851 | " \n", 852 | " \n", 853 | " \n", 854 | " \n", 855 | " \n", 856 | " \n", 857 | " \n", 858 | " \n", 859 | " \n", 860 | " \n", 861 | " \n", 862 | " \n", 863 | " \n", 864 | " \n", 865 | " \n", 866 | " \n", 867 | " \n", 868 | " \n", 869 | " \n", 870 | " \n", 871 | " \n", 872 | " \n", 873 | " \n", 874 | " \n", 875 | " \n", 876 | " \n", 877 | " \n", 878 | " \n", 879 | " \n", 880 | " \n", 881 | " \n", 882 | " \n", 883 | " \n", 884 | " \n", 885 | " \n", 886 | " \n", 887 | " \n", 888 | " \n", 889 | " \n", 890 | " \n", 891 | " \n", 892 | " \n", 893 | " \n", 894 | " \n", 895 | " \n", 896 | " \n", 897 | " \n", 898 | " \n", 899 | " \n", 900 | " \n", 901 | "
featureA/BA_v1B_v1A_v2B_v2A_v3B_v3A_v4B_v4
00.023/602360236023602360
10.065/766576657665766576
20.066/536653665366536653
30.057/535753575357535753
40.085/188518851885188518
\n", 902 | "
" 903 | ], 904 | "text/plain": [ 905 | " feature A/B A_v1 B_v1 A_v2 B_v2 A_v3 B_v3 A_v4 B_v4\n", 906 | "0 0.0 23/60 23 60 23 60 23 60 23 60\n", 907 | "1 0.0 65/76 65 76 65 76 65 76 65 76\n", 908 | "2 0.0 66/53 66 53 66 53 66 53 66 53\n", 909 | "3 0.0 57/53 57 53 57 53 57 53 57 53\n", 910 | "4 0.0 85/18 85 18 85 18 85 18 85 18" 911 | ] 912 | }, 913 | "execution_count": 171, 914 | "metadata": {}, 915 | "output_type": "execute_result" 916 | } 917 | ], 918 | "source": [ 919 | "tmp = data['A/B'].str.split('/')\n", 920 | "data['A_v1'] = tmp.apply(lambda x: x[0])\n", 921 | "data['B_v1'] = tmp.apply(lambda x: x[1])\n", 922 | "\n", 923 | "data[['A_v2', 'B_v2']] = pd.DataFrame(data['A/B'].str.split('/', 1).tolist())\n", 924 | "\n", 925 | "data[['A_v3', 'B_v3']] = data['A/B'].str.split('/', expand=True)\n", 926 | "\n", 927 | "st = '/'.join(data['A/B'])\n", 928 | "data[['A_v4', 'B_v4']] = pd.DataFrame(np.array(st.split('/')).reshape(-1, 2))\n", 929 | "\n", 930 | "data" 931 | ] 932 | }, 933 | { 934 | "cell_type": "code", 935 | "execution_count": 172, 936 | "metadata": {}, 937 | "outputs": [], 938 | "source": [ 939 | "data = make_ab(10000000)" 940 | ] 941 | }, 942 | { 943 | "cell_type": "code", 944 | "execution_count": 177, 945 | "metadata": {}, 946 | "outputs": [ 947 | { 948 | "name": "stdout", 949 | "output_type": "stream", 950 | "text": [ 951 | "CPU times: user 13.1 s, sys: 1.51 s, total: 14.6 s\n", 952 | "Wall time: 14.6 s\n" 953 | ] 954 | } 955 | ], 956 | "source": [ 957 | "%%time\n", 958 | "tmp = data['A/B'].str.split('/')\n", 959 | "data['A_v1'] = tmp.apply(lambda x: x[0])\n", 960 | "data['B_v1'] = tmp.apply(lambda x: x[1])\n", 961 | "# 12.5 s-13.4 s" 962 | ] 963 | }, 964 | { 965 | "cell_type": "code", 966 | "execution_count": 174, 967 | "metadata": {}, 968 | "outputs": [ 969 | { 970 | "name": "stdout", 971 | "output_type": "stream", 972 | "text": [ 973 | "CPU times: user 9.94 s, sys: 176 ms, total: 10.1 s\n", 974 | "Wall time: 10.2 s\n" 975 | ] 976 | } 977 | ], 978 | "source": [ 979 | "%%time\n", 980 | "data[['A_v2', 'B_v2']] = pd.DataFrame(data['A/B'].str.split('/', 1).tolist())\n", 981 | "# 10.2 s - 12.2 s" 982 | ] 983 | }, 984 | { 985 | "cell_type": "code", 986 | "execution_count": 175, 987 | "metadata": {}, 988 | "outputs": [ 989 | { 990 | "name": "stdout", 991 | "output_type": "stream", 992 | "text": [ 993 | "CPU times: user 26.1 s, sys: 368 ms, total: 26.5 s\n", 994 | "Wall time: 26.5 s\n" 995 | ] 996 | } 997 | ], 998 | "source": [ 999 | "%%time\n", 1000 | "data[['A_v3', 'B_v3']] = data['A/B'].str.split('/', expand=True)\n", 1001 | "# 26.1 s - 29.2 s" 1002 | ] 1003 | }, 1004 | { 1005 | "cell_type": "code", 1006 | "execution_count": 176, 1007 | "metadata": {}, 1008 | "outputs": [ 1009 | { 1010 | "name": "stdout", 1011 | "output_type": "stream", 1012 | "text": [ 1013 | "CPU times: user 3.65 s, sys: 168 ms, total: 3.82 s\n", 1014 | "Wall time: 3.84 s\n" 1015 | ] 1016 | } 1017 | ], 1018 | "source": [ 1019 | "%%time\n", 1020 | "st = '/'.join(data['A/B'])\n", 1021 | "data[['A_v4', 'B_v4']] = pd.DataFrame(np.array(st.split('/')).reshape(-1, 2))\n", 1022 | "# 3.65 s - 4.54 s" 1023 | ] 1024 | }, 1025 | { 1026 | "cell_type": "markdown", 1027 | "metadata": {}, 1028 | "source": [ 1029 | "### Задача - заменить пропуски средним" 1030 | ] 1031 | }, 1032 | { 1033 | "cell_type": "code", 1034 | "execution_count": 178, 1035 | "metadata": {}, 1036 | "outputs": [ 1037 | { 1038 | "data": { 1039 | "text/html": [ 1040 | "
\n", 1041 | "\n", 1054 | "\n", 1055 | " \n", 1056 | " \n", 1057 | " \n", 1058 | " \n", 1059 | " \n", 1060 | " \n", 1061 | " \n", 1062 | " \n", 1063 | " \n", 1064 | " \n", 1065 | " \n", 1066 | " \n", 1067 | " \n", 1068 | " \n", 1069 | " \n", 1070 | " \n", 1071 | " \n", 1072 | " \n", 1073 | " \n", 1074 | " \n", 1075 | " \n", 1076 | " \n", 1077 | " \n", 1078 | " \n", 1079 | " \n", 1080 | " \n", 1081 | " \n", 1082 | " \n", 1083 | " \n", 1084 | " \n", 1085 | " \n", 1086 | " \n", 1087 | " \n", 1088 | " \n", 1089 | " \n", 1090 | " \n", 1091 | " \n", 1092 | " \n", 1093 | " \n", 1094 | " \n", 1095 | " \n", 1096 | " \n", 1097 | " \n", 1098 | " \n", 1099 | " \n", 1100 | " \n", 1101 | " \n", 1102 | " \n", 1103 | " \n", 1104 | " \n", 1105 | " \n", 1106 | " \n", 1107 | " \n", 1108 | " \n", 1109 | " \n", 1110 | " \n", 1111 | " \n", 1112 | " \n", 1113 | " \n", 1114 | " \n", 1115 | " \n", 1116 | " \n", 1117 | " \n", 1118 | " \n", 1119 | " \n", 1120 | " \n", 1121 | " \n", 1122 | " \n", 1123 | " \n", 1124 | " \n", 1125 | " \n", 1126 | " \n", 1127 | " \n", 1128 | " \n", 1129 | " \n", 1130 | " \n", 1131 | " \n", 1132 | " \n", 1133 | " \n", 1134 | " \n", 1135 | " \n", 1136 | " \n", 1137 | " \n", 1138 | " \n", 1139 | " \n", 1140 | " \n", 1141 | " \n", 1142 | " \n", 1143 | " \n", 1144 | " \n", 1145 | " \n", 1146 | " \n", 1147 | " \n", 1148 | " \n", 1149 | " \n", 1150 | " \n", 1151 | " \n", 1152 | " \n", 1153 | " \n", 1154 | " \n", 1155 | " \n", 1156 | " \n", 1157 | " \n", 1158 | "
typefeaturefeature_v1feature_v2feature_v3feature_v4
0testNaNNaNNaNNaNNaN
1test43.043.043.043.043.0
2testNaNNaNNaNNaNNaN
3train4.04.04.04.04.0
4train18.018.018.018.018.0
5trainNaNNaNNaNNaNNaN
6trainNaNNaNNaNNaNNaN
7train25.025.025.025.025.0
8trainNaNNaNNaNNaNNaN
9trainNaNNaNNaNNaNNaN
\n", 1159 | "
" 1160 | ], 1161 | "text/plain": [ 1162 | " type feature feature_v1 feature_v2 feature_v3 feature_v4\n", 1163 | "0 test NaN NaN NaN NaN NaN\n", 1164 | "1 test 43.0 43.0 43.0 43.0 43.0\n", 1165 | "2 test NaN NaN NaN NaN NaN\n", 1166 | "3 train 4.0 4.0 4.0 4.0 4.0\n", 1167 | "4 train 18.0 18.0 18.0 18.0 18.0\n", 1168 | "5 train NaN NaN NaN NaN NaN\n", 1169 | "6 train NaN NaN NaN NaN NaN\n", 1170 | "7 train 25.0 25.0 25.0 25.0 25.0\n", 1171 | "8 train NaN NaN NaN NaN NaN\n", 1172 | "9 train NaN NaN NaN NaN NaN" 1173 | ] 1174 | }, 1175 | "execution_count": 178, 1176 | "metadata": {}, 1177 | "output_type": "execute_result" 1178 | } 1179 | ], 1180 | "source": [ 1181 | "def make_t(n_rows):\n", 1182 | " tmp = pd.DataFrame({'type': np.where(np.random.rand(n_rows)<0.5, 'train', 'test'),\n", 1183 | " 'feature': np.where(np.random.rand(n_rows)<0.5, (100*np.random.rand(n_rows)).astype(int), np.nan)})\n", 1184 | " tmp['feature_v1'] = tmp['feature']\n", 1185 | " tmp['feature_v2'] = tmp['feature']\n", 1186 | " tmp['feature_v3'] = tmp['feature']\n", 1187 | " tmp['feature_v4'] = tmp['feature']\n", 1188 | " return tmp\n", 1189 | "\n", 1190 | "data = make_t(10)\n", 1191 | "data" 1192 | ] 1193 | }, 1194 | { 1195 | "cell_type": "code", 1196 | "execution_count": 182, 1197 | "metadata": {}, 1198 | "outputs": [ 1199 | { 1200 | "data": { 1201 | "text/html": [ 1202 | "
\n", 1203 | "\n", 1216 | "\n", 1217 | " \n", 1218 | " \n", 1219 | " \n", 1220 | " \n", 1221 | " \n", 1222 | " \n", 1223 | " \n", 1224 | " \n", 1225 | " \n", 1226 | " \n", 1227 | " \n", 1228 | " \n", 1229 | " \n", 1230 | " \n", 1231 | " \n", 1232 | " \n", 1233 | " \n", 1234 | " \n", 1235 | " \n", 1236 | " \n", 1237 | " \n", 1238 | " \n", 1239 | " \n", 1240 | " \n", 1241 | " \n", 1242 | " \n", 1243 | " \n", 1244 | " \n", 1245 | " \n", 1246 | " \n", 1247 | " \n", 1248 | " \n", 1249 | " \n", 1250 | " \n", 1251 | " \n", 1252 | " \n", 1253 | " \n", 1254 | " \n", 1255 | " \n", 1256 | " \n", 1257 | " \n", 1258 | " \n", 1259 | " \n", 1260 | " \n", 1261 | " \n", 1262 | " \n", 1263 | " \n", 1264 | " \n", 1265 | " \n", 1266 | " \n", 1267 | " \n", 1268 | " \n", 1269 | " \n", 1270 | " \n", 1271 | " \n", 1272 | " \n", 1273 | " \n", 1274 | " \n", 1275 | " \n", 1276 | " \n", 1277 | " \n", 1278 | " \n", 1279 | " \n", 1280 | " \n", 1281 | " \n", 1282 | " \n", 1283 | " \n", 1284 | " \n", 1285 | " \n", 1286 | " \n", 1287 | " \n", 1288 | " \n", 1289 | " \n", 1290 | " \n", 1291 | " \n", 1292 | " \n", 1293 | " \n", 1294 | " \n", 1295 | " \n", 1296 | " \n", 1297 | " \n", 1298 | " \n", 1299 | " \n", 1300 | " \n", 1301 | " \n", 1302 | " \n", 1303 | " \n", 1304 | " \n", 1305 | " \n", 1306 | " \n", 1307 | " \n", 1308 | " \n", 1309 | " \n", 1310 | " \n", 1311 | " \n", 1312 | " \n", 1313 | " \n", 1314 | " \n", 1315 | " \n", 1316 | " \n", 1317 | " \n", 1318 | " \n", 1319 | " \n", 1320 | "
typefeaturefeature_v1feature_v2feature_v3feature_v4
0testNaN43.00000043.00000043.00000043.000000
1test43.043.00000043.00000043.00000043.000000
2testNaN43.00000043.00000043.00000043.000000
3train4.04.0000004.0000004.0000004.000000
4train18.018.00000018.00000018.00000018.000000
5trainNaN15.66666715.66666715.66666715.666667
6trainNaN15.66666715.66666715.66666715.666667
7train25.025.00000025.00000025.00000025.000000
8trainNaN15.66666715.66666715.66666715.666667
9trainNaN15.66666715.66666715.66666715.666667
\n", 1321 | "
" 1322 | ], 1323 | "text/plain": [ 1324 | " type feature feature_v1 feature_v2 feature_v3 feature_v4\n", 1325 | "0 test NaN 43.000000 43.000000 43.000000 43.000000\n", 1326 | "1 test 43.0 43.000000 43.000000 43.000000 43.000000\n", 1327 | "2 test NaN 43.000000 43.000000 43.000000 43.000000\n", 1328 | "3 train 4.0 4.000000 4.000000 4.000000 4.000000\n", 1329 | "4 train 18.0 18.000000 18.000000 18.000000 18.000000\n", 1330 | "5 train NaN 15.666667 15.666667 15.666667 15.666667\n", 1331 | "6 train NaN 15.666667 15.666667 15.666667 15.666667\n", 1332 | "7 train 25.0 25.000000 25.000000 25.000000 25.000000\n", 1333 | "8 train NaN 15.666667 15.666667 15.666667 15.666667\n", 1334 | "9 train NaN 15.666667 15.666667 15.666667 15.666667" 1335 | ] 1336 | }, 1337 | "execution_count": 182, 1338 | "metadata": {}, 1339 | "output_type": "execute_result" 1340 | } 1341 | ], 1342 | "source": [ 1343 | "name = 'feature_v1'\n", 1344 | "data.loc[data['type'] == 'test', name] = \\\n", 1345 | " data[data['type'] == 'test'][name].fillna(data[data['type'] == 'test'][name].mean())\n", 1346 | "data.loc[data['type'] == 'train', name] = \\\n", 1347 | " data[data['type'] == 'train'][name].fillna(data[data['type'] == 'train'][name].mean())\n", 1348 | "\n", 1349 | "name = 'feature_v2'\n", 1350 | "data[name] = data.groupby('type')[name].transform(lambda x: x.fillna(x.mean()))\n", 1351 | "\n", 1352 | "name = 'feature_v3'\n", 1353 | "data.loc[data[name].isnull(), name] = data.groupby('type')[name].transform('mean')\n", 1354 | "\n", 1355 | "name = 'feature_v4'\n", 1356 | "data[name] = np.where(data[name].isnull(), data['type'].map(data.groupby('type')[name].mean()), data[name])\n", 1357 | "\n", 1358 | "#name = 'feature_v4'\n", 1359 | "#gb = data.groupby('type')\n", 1360 | "#mn = gb.mean()\n", 1361 | "#for gn, x in gb:\n", 1362 | "# x[name].fillna(mn.loc[gn], inplace=True)\n", 1363 | "\n", 1364 | "data" 1365 | ] 1366 | }, 1367 | { 1368 | "cell_type": "code", 1369 | "execution_count": 191, 1370 | "metadata": {}, 1371 | "outputs": [], 1372 | "source": [ 1373 | "data = make_t(10000000)" 1374 | ] 1375 | }, 1376 | { 1377 | "cell_type": "code", 1378 | "execution_count": 195, 1379 | "metadata": {}, 1380 | "outputs": [ 1381 | { 1382 | "name": "stdout", 1383 | "output_type": "stream", 1384 | "text": [ 1385 | "CPU times: user 3.66 s, sys: 132 ms, total: 3.79 s\n", 1386 | "Wall time: 3.81 s\n" 1387 | ] 1388 | } 1389 | ], 1390 | "source": [ 1391 | "%%time\n", 1392 | "\n", 1393 | "name = 'feature_v1'\n", 1394 | "data.loc[data['type'] == 'test', name] = data[data['type'] == 'test'][name].fillna(data[data['type'] == 'test'][name].mean())\n", 1395 | "data.loc[data['type'] == 'train', name] = data[data['type'] == 'train'][name].fillna(data[data['type'] == 'train'][name].mean())\n", 1396 | "\n", 1397 | "# 3.44 s - 3.84 s" 1398 | ] 1399 | }, 1400 | { 1401 | "cell_type": "code", 1402 | "execution_count": 194, 1403 | "metadata": {}, 1404 | "outputs": [ 1405 | { 1406 | "name": "stdout", 1407 | "output_type": "stream", 1408 | "text": [ 1409 | "CPU times: user 1.9 s, sys: 152 ms, total: 2.05 s\n", 1410 | "Wall time: 2.06 s\n" 1411 | ] 1412 | } 1413 | ], 1414 | "source": [ 1415 | "%%time\n", 1416 | "name = 'feature_v2'\n", 1417 | "data[name] = data.groupby('type')[name].transform(lambda x: x.fillna(x.mean()))\n", 1418 | "# 1.9 s - 2.04 s" 1419 | ] 1420 | }, 1421 | { 1422 | "cell_type": "code", 1423 | "execution_count": 193, 1424 | "metadata": {}, 1425 | "outputs": [ 1426 | { 1427 | "name": "stdout", 1428 | "output_type": "stream", 1429 | "text": [ 1430 | "CPU times: user 1.2 s, sys: 128 ms, total: 1.32 s\n", 1431 | "Wall time: 1.35 s\n" 1432 | ] 1433 | } 1434 | ], 1435 | "source": [ 1436 | "%%time\n", 1437 | "name = 'feature_v3'\n", 1438 | "data.loc[data[name].isnull(), name] = data.groupby('type')[name].transform('mean')\n", 1439 | "# 1.17 - 1.18 s" 1440 | ] 1441 | }, 1442 | { 1443 | "cell_type": "code", 1444 | "execution_count": 192, 1445 | "metadata": {}, 1446 | "outputs": [ 1447 | { 1448 | "name": "stdout", 1449 | "output_type": "stream", 1450 | "text": [ 1451 | "CPU times: user 1.37 s, sys: 72 ms, total: 1.44 s\n", 1452 | "Wall time: 1.45 s\n" 1453 | ] 1454 | } 1455 | ], 1456 | "source": [ 1457 | "%%time\n", 1458 | "name = 'feature_v4'\n", 1459 | "data[name] = np.where(data[name].isnull(), data['type'].map(data.groupby('type')[name].mean()), data[name])\n", 1460 | "# 1.26 s - 1.38" 1461 | ] 1462 | }, 1463 | { 1464 | "cell_type": "code", 1465 | "execution_count": null, 1466 | "metadata": {}, 1467 | "outputs": [], 1468 | "source": [] 1469 | } 1470 | ], 1471 | "metadata": { 1472 | "kernelspec": { 1473 | "display_name": "Python 3", 1474 | "language": "python", 1475 | "name": "python3" 1476 | }, 1477 | "language_info": { 1478 | "codemirror_mode": { 1479 | "name": "ipython", 1480 | "version": 3 1481 | }, 1482 | "file_extension": ".py", 1483 | "mimetype": "text/x-python", 1484 | "name": "python", 1485 | "nbconvert_exporter": "python", 1486 | "pygments_lexer": "ipython3", 1487 | "version": "3.6.8" 1488 | } 1489 | }, 1490 | "nbformat": 4, 1491 | "nbformat_minor": 2 1492 | } 1493 | -------------------------------------------------------------------------------- /dj_python_2_oop_20181004.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# язык программирования Python\n", 8 | "## часть II - ООП\n", 9 | "\n", 10 | "автор: **Дьяконов Александр www.dyakonov.org**\n", 11 | "\n", 12 | "**для поддержки курсов автора, в частности https://github.com/Dyakonov/IML**\n", 13 | "\n", 14 | "\n", 15 | "##### материал частично основан на...\n", 16 | "\n", 17 | "* *Bruce Eckel* **Python 3 Patterns, Recipes and Idioms**\n", 18 | "* *Никита Лесников* **Беглый обзор внутренностей Python** // slideshare\n", 19 | "* *Сергей Лебедев* **Лекции по языку Питон** // youtube, канал \"Computer Science Center\"\n", 20 | "* Learn X in Y minutes https://learnxinyminutes.com/docs/python/\n", 21 | "* *Дэн Бейдер* **Чистый Python. Тонкости программирования для профи**" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "- Всё - объекты\n", 29 | "- Программа = объекты, посылающе друг другу сообщения. \n", 30 | "- Объект имеет собственную часть памяти и может состоять из других объектов. \n", 31 | "- Объект имеет тип (класс): формализует действия объекта / над объеком" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 8, 37 | "metadata": {}, 38 | "outputs": [ 39 | { 40 | "name": "stdout", 41 | "output_type": "stream", 42 | "text": [ 43 | "3.5\n", 44 | "NotImplemented\n" 45 | ] 46 | } 47 | ], 48 | "source": [ 49 | "a = 1\n", 50 | "b = 2.5\n", 51 | "print (a + b)\n", 52 | "print (a.__add__(b)) # НЕ РАБОТАЕТ" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 34, 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "name": "stdout", 62 | "output_type": "stream", 63 | "text": [ 64 | "1578102544 73531656\n", 65 | "1578102576 73531656\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "# в Python всё - объекты. Имеют id и значение\n", 71 | "a = 1\n", 72 | "b = [1, 2]\n", 73 | "print (id(a), id(b))\n", 74 | "a = a + 1\n", 75 | "b.append(3) # id не изменится\n", 76 | "print (id(a), id(b))\n", 77 | "del a # удаление объекта\n", 78 | "# a # будет ошибка" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 21, 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "name": "stdout", 88 | "output_type": "stream", 89 | "text": [ 90 | "{1, 2, 3, 4}; {(1, 2), (1, 3), (3, 4)}\n" 91 | ] 92 | } 93 | ], 94 | "source": [ 95 | "# определение класса\n", 96 | "# первый аргумент всех методов - экземпляр класса\n", 97 | "\n", 98 | "class MyGraph:\n", 99 | " def __init__(self, V, E): # конструктор (деструктор - __del__)\n", 100 | " self.vertices = set(V)\n", 101 | " self.edges = set(E)\n", 102 | " def add_vertex(self, v): # метод - функция, объявленная в теле класса\n", 103 | " self.vertices.add(v)\n", 104 | " def add_edge(self, e):\n", 105 | " self.vertices.add(e[0])\n", 106 | " self.vertices.add(e[1])\n", 107 | " self.edges.add(e)\n", 108 | " def __str__(self): # представление в виде строки\n", 109 | " return (\"%s; %s\" % (self.vertices, self.edges))\n", 110 | "\n", 111 | "g = MyGraph([1,2,3], [(1,2), (1,3)])\n", 112 | "g.add_edge((3,4))\n", 113 | "print (g)" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 22, 119 | "metadata": {}, 120 | "outputs": [ 121 | { 122 | "name": "stdout", 123 | "output_type": "stream", 124 | "text": [ 125 | "{1, 2, 3, 4}\n", 126 | "{1, 2, 3, 4}\n", 127 | "{1, 2, 3, 4, 5}; {(1, 2), (1, 3), (3, 4)}\n" 128 | ] 129 | } 130 | ], 131 | "source": [ 132 | "print (g.vertices)\n", 133 | "print (g.__getattribute__('vertices'))\n", 134 | "g.__setattr__('vertices', set([1,2,3,4,5]))\n", 135 | "print (g)" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 1, 141 | "metadata": {}, 142 | "outputs": [ 143 | { 144 | "name": "stdout", 145 | "output_type": "stream", 146 | "text": [ 147 | "['_X__c', '__doc__', '__module__', '_b', 'a']\n", 148 | "{'a': 0, '__module__': '__main__', '_X__c': 2, '_b': 1, '__doc__': None}\n" 149 | ] 150 | } 151 | ], 152 | "source": [ 153 | "class X:\n", 154 | " a = 0 # обычный атрибут\n", 155 | " _b = 1 # не желательно пользоваться, но доступен\n", 156 | " __c = 2 # доступен под другим именем ('_X__c')\n", 157 | "print (dir(X))\n", 158 | "print (X.__dict__) # все атрибуты в виде словаря" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 1, 164 | "metadata": {}, 165 | "outputs": [ 166 | { 167 | "name": "stdout", 168 | "output_type": "stream", 169 | "text": [ 170 | "3\n", 171 | "(, , , )\n" 172 | ] 173 | } 174 | ], 175 | "source": [ 176 | "# множественное наследование\n", 177 | "class A:\n", 178 | " def make(self, x):\n", 179 | " print(x+1)\n", 180 | "class B:\n", 181 | " def make(self, x):\n", 182 | " print(x-1)\n", 183 | "class C(A, B):\n", 184 | " pass\n", 185 | "\n", 186 | "c = C()\n", 187 | "c.make(2)\n", 188 | "print (C.__mro__) # в таком порядке ищутся методы" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 6, 194 | "metadata": {}, 195 | "outputs": [], 196 | "source": [ 197 | "# класс\n", 198 | "class Human(object):\n", 199 | "\n", 200 | " species = \"H. sapiens\" # атрибут\n", 201 | "\n", 202 | " # инициализатор\n", 203 | " # когда класс инициализируется\n", 204 | " def __init__(self, name): \n", 205 | " self.name = name # инициализация атрибута\n", 206 | " self.age = 0 # инициализация свойства\n", 207 | "\n", 208 | "\n", 209 | " # метод класса, первый аргумент - self\n", 210 | " def say(self, msg):\n", 211 | " return \"{0}: {1}\".format(self.name, msg)\n", 212 | "\n", 213 | " # общий метод для всех экземпляров\n", 214 | " # первый аргумент - кто вызвал\n", 215 | " @classmethod\n", 216 | " def get_species(cls):\n", 217 | " return cls.species\n", 218 | "\n", 219 | " # вызывается без ссылки на вызвавшего\n", 220 | " @staticmethod\n", 221 | " def grunt():\n", 222 | " return \"статика...\"\n", 223 | "\n", 224 | " # свойство - превращает метод в атрибут\n", 225 | " @property\n", 226 | " def age(self):\n", 227 | " return self._age\n", 228 | "\n", 229 | " # для присваивания свойству\n", 230 | " @age.setter\n", 231 | " def age(self, age):\n", 232 | " self._age = age\n", 233 | "\n", 234 | " # для удаления свойства\n", 235 | " @age.deleter\n", 236 | " def age(self):\n", 237 | " del self._age" 238 | ] 239 | }, 240 | { 241 | "cell_type": "code", 242 | "execution_count": 7, 243 | "metadata": {}, 244 | "outputs": [ 245 | { 246 | "name": "stdout", 247 | "output_type": "stream", 248 | "text": [ 249 | "Иван: привет\n", 250 | "Сергей: пока\n", 251 | "H. sapiens\n", 252 | "H. neanderthalensis H. neanderthalensis\n", 253 | "H. neanderthalensis H. neanderthalensis\n", 254 | "статика...\n", 255 | "42\n" 256 | ] 257 | } 258 | ], 259 | "source": [ 260 | "# инициализация\n", 261 | "i = Human(name=\"Иван\")\n", 262 | "print (i.say(\"привет\"))\n", 263 | "\n", 264 | "\n", 265 | "j = Human(\"Сергей\")\n", 266 | "print (j.say(\"пока\"))\n", 267 | "\n", 268 | "\n", 269 | "print (i.get_species())\n", 270 | "\n", 271 | "\n", 272 | "# меняем атрибут общий - для всего класса\n", 273 | "Human.species = \"H. neanderthalensis\"\n", 274 | "print (i.get_species(), i.species)\n", 275 | "print (j.get_species(), j.species)\n", 276 | "\n", 277 | "\n", 278 | "\n", 279 | "print (Human.grunt()) # статический метод\n", 280 | "\n", 281 | "\n", 282 | "i.age = 42 # свойство\n", 283 | "print (i.age)\n", 284 | "del i.age\n", 285 | "# i.age # будет исключение\n" 286 | ] 287 | }, 288 | { 289 | "cell_type": "code", 290 | "execution_count": 5, 291 | "metadata": {}, 292 | "outputs": [ 293 | { 294 | "data": { 295 | "text/plain": [ 296 | "4" 297 | ] 298 | }, 299 | "execution_count": 5, 300 | "metadata": {}, 301 | "output_type": "execute_result" 302 | } 303 | ], 304 | "source": [ 305 | "class Myclass:\n", 306 | " __slots__ = ['name1', 'name2'] # указываем ВСЕ возможные атрибуты\n", 307 | " \n", 308 | "# -- занимает меньше памяти\n", 309 | " \n", 310 | "c = Myclass()\n", 311 | "c.name1 = 10\n", 312 | "c.name2 = lambda x: x * x\n", 313 | "\n", 314 | "c.name2(2)\n", 315 | "\n", 316 | "#c.name3 = 20 # должна быть ошибка (в Python2 - нет)\n", 317 | "#c.name3" 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": 9, 323 | "metadata": {}, 324 | "outputs": [ 325 | { 326 | "name": "stdout", 327 | "output_type": "stream", 328 | "text": [ 329 | "[1, 2]\n", 330 | "[3, 2]\n", 331 | "[3, 2]\n" 332 | ] 333 | } 334 | ], 335 | "source": [ 336 | "a = [1, 2]\n", 337 | "b = a\n", 338 | "print (b)\n", 339 | "a[0] = 3\n", 340 | "print (b) # a и b идентичны\n", 341 | "del a\n", 342 | "print (b) # но b остаётся!" 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": 17, 348 | "metadata": {}, 349 | "outputs": [ 350 | { 351 | "name": "stdout", 352 | "output_type": "stream", 353 | "text": [ 354 | "dict_values(['mac_greek', 'zlib_codec', 'iso8859_15', 'cp1255', 'iso8859_9', 'shift_jis', 'gb2312', 'cp500', 'cp1140', 'iso8859_8', 'hp_roman8', 'cp037', 'cp949', 'cp864', 'euc_kr', 'gbk', 'cp852', 'iso8859_7', 'cp037', 'latin_1', 'utf_7', 'cp860', 'cp1253', 'iso8859_5', 'cp1125', 'big5', 'shift_jis_2004', 'cp850', 'utf_16_be', 'cp932', 'utf_8', 'iso2022_jp', 'iso8859_16', 'cp500', 'utf_8', 'ascii', 'iso8859_14', 'latin_1', 'base64_codec', 'gb2312', 'cp949', 'hp_roman8', 'euc_jis_2004', 'cp1258', 'quopri_codec', 'uu_codec', 'mac_turkish', 'euc_kr', 'iso8859_14', 'rot_13', 'euc_jp', 'cp1254', 'iso8859_8', 'cp1253', 'ptcp154', 'cp273', 'iso8859_14', 'cp1125', 'iso8859_14', 'cp424', 'big5hkscs', 'cp500', 'iso8859_2', 'cp437', 'hz', 'gbk', 'euc_jp', 'cp852', 'iso2022_jp_ext', 'euc_kr', 'iso8859_15', 'utf_7', 'utf_8', 'cp850', 'shift_jisx0213', 'euc_kr', 'cp437', 'iso8859_11', 'cp855', 'cp861', 'latin_1', 'cp1026', 'cp273', 'iso8859_16', 'shift_jis', 'cp932', 'iso8859_8', 'cp865', 'tis_620', 'iso8859_6', 'cp866', 'utf_8', 'iso8859_13', 'iso8859_16', 'iso8859_14', 'iso2022_jp_1', 'mac_iceland', 'iso8859_6', 'johab', 'iso8859_9', 'cp424', 'cp273', 'iso2022_jp_2004', 'ascii', 'utf_16_le', 'iso2022_jp_1', 'cp857', 'cp950', 'utf_32_le', 'cp1252', 'iso8859_3', 'cp037', 'gb2312', 'hz', 'cp1250', 'utf_16_le', 'iso8859_2', 'cp855', 'iso8859_7', 'iso8859_10', 'cp1256', 'iso8859_8', 'cp857', 'iso8859_14', 'cp437', 'iso8859_10', 'iso8859_2', 'iso8859_9', 'cp857', 'gb2312', 'iso8859_6', 'kz1048', 'iso8859_6', 'hex_codec', 'iso8859_7', 'euc_jis_2004', 'cp1125', 'cp869', 'zlib_codec', 'cp775', 'iso8859_3', 'iso8859_3', 'cp1257', 'iso8859_4', 'iso2022_jp_2', 'kz1048', 'shift_jis', 'cp1255', 'cp1254', 'iso8859_10', 'iso8859_10', 'cp424', 'iso8859_8', 'cp775', 'tis_620', 'latin_1', 'iso8859_3', 'iso8859_5', 'mac_roman', 'kz1048', 'cp949', 'cp037', 'cp037', 'cp1250', 'iso2022_jp_3', 'gb2312', 'latin_1', 'cp424', 'tis_620', 'euc_kr', 'ascii', 'iso8859_13', 'euc_jis_2004', 'iso8859_10', 'cp850', 'utf_16_be', 'ascii', 'iso8859_4', 'ptcp154', 'iso8859_4', 'iso8859_16', 'cp862', 'euc_jisx0213', 'iso8859_7', 'ascii', 'iso2022_kr', 'cp864', 'tis_620', 'utf_32_be', 'cp500', 'latin_1', 'big5', 'ascii', 'iso2022_jp_2004', 'cp037', 'iso2022_jp_2', 'iso8859_11', 'iso2022_jp_ext', 'big5', 'iso8859_9', 'cp1026', 'gb2312', 'cp862', 'cp861', 'latin_1', 'cp866', 'iso2022_jp', 'cp500', 'shift_jis_2004', 'cp860', 'cp950', 'koi8_r', 'cp1251', 'cp863', 'cp852', 'latin_1', 'gb2312', 'cp858', 'euc_kr', 'gb18030', 'cp932', 'utf_8', 'cp1125', 'cp037', 'base64_codec', 'ptcp154', 'cp1251', 'cp869', 'cp860', 'cp858', 'ptcp154', 'cp1256', 'iso8859_4', 'gb2312', 'iso8859_2', 'iso8859_9', 'quopri_codec', 'bz2_codec', 'cp865', 'johab', 'ascii', 'ascii', 'cp1258', 'mac_latin2', 'iso2022_kr', 'cp037', 'utf_7', 'mac_cyrillic', 'iso8859_9', 'cp861', 'iso8859_10', 'iso8859_5', 'utf_16', 'latin_1', 'iso8859_15', 'latin_1', 'cp863', 'iso8859_2', 'iso8859_6', 'utf_32', 'iso2022_jp', 'cp869', 'ascii', 'iso8859_4', 'cp864', 'cp863', 'cp862', 'gb2312', 'cp861', 'cp932', 'cp855', 'utf_32', 'ascii', 'mac_roman', 'quopri_codec', 'iso8859_6', 'ascii', 'iso8859_11', 'mac_latin2', 'euc_kr', 'cp869', 'iso8859_2', 'cp866', 'iso8859_4', 'ascii', 'shift_jisx0213', 'shift_jisx0213', 'cp1140', 'utf_16', 'iso8859_5', 'cp858', 'iso8859_5', 'shift_jis', 'mbcs', 'iso2022_jp_3', 'iso8859_7', 'cp1257', 'hz', 'iso8859_7', 'iso8859_6', 'big5hkscs', 'tis_620', 'cp865', 'tactis', 'iso2022_kr', 'euc_kr', 'hp_roman8', 'shift_jis', 'cp1026', 'iso8859_3', 'latin_1', 'iso8859_16', 'iso8859_3', 'euc_jp', 'shift_jis_2004', 'iso8859_7', 'cp775', 'latin_1', 'gbk', 'cp1252', 'iso8859_7', 'iso8859_13'])\n" 355 | ] 356 | } 357 | ], 358 | "source": [ 359 | "# чтобы Unicode-литералы правильно воспринимались интерпретатором, в начале программы укажите\n", 360 | "# -*- coding: koi8 -r -*-\n", 361 | "# -*- coding: cp1251 -*-\n", 362 | "# 2я запись - в Win\n", 363 | "\n", 364 | "import encodings.aliases\n", 365 | "print (encodings.aliases.aliases.values()) # возможные кодировки" 366 | ] 367 | }, 368 | { 369 | "cell_type": "code", 370 | "execution_count": 17, 371 | "metadata": {}, 372 | "outputs": [ 373 | { 374 | "name": "stdout", 375 | "output_type": "stream", 376 | "text": [ 377 | "First создан, счётчик = 1\n", 378 | "Second создан, счётчик = 2\n", 379 | "First удалён, счётчик = 1\n", 380 | "Third создан, счётчик = 2\n", 381 | "Third удалён, счётчик = 1\n" 382 | ] 383 | } 384 | ], 385 | "source": [ 386 | "# подсчёт числа объектов соответствующего класса\n", 387 | "\n", 388 | "class Counter:\n", 389 | " Count = 0 # счётчик\n", 390 | " \n", 391 | " def __init__(self, name): # внимание к отступам\n", 392 | " self.name = name # обращение через self\n", 393 | " Counter.Count += 1\n", 394 | " print (name, ' создан, счётчик =', Counter.Count)\n", 395 | " # Counter.Count - у класса, а не объекта!\n", 396 | " \n", 397 | " def __del__(self):\n", 398 | " Counter.Count -= 1\n", 399 | " print (self.name, 'удалён, счётчик = ', Counter.Count)\n", 400 | " if Counter.Count == 0:\n", 401 | " print ('Больше объектов нет...')\n", 402 | " \n", 403 | "x = Counter(\"First\")\n", 404 | "y = Counter(\"Second\")\n", 405 | "del x\n", 406 | "z = Counter(\"Third\")\n", 407 | "del z\n", 408 | "\n", 409 | "# если запустить второй раз - какая-то ерунда..." 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": 16, 415 | "metadata": {}, 416 | "outputs": [], 417 | "source": [ 418 | "# del x\n", 419 | "# del y\n", 420 | "del Counter" 421 | ] 422 | }, 423 | { 424 | "cell_type": "markdown", 425 | "metadata": {}, 426 | "source": [ 427 | "## Метаклассы\n", 428 | "\n", 429 | "Метакласс - класс для создания других классов (его экземпляры тоже классы)\n", 430 | "\n", 431 | "Пример - класс **type** (все классы это его экземпляры)\n", 432 | "\n", 433 | "**зачем нужны** (не будем)\n", 434 | "- изменение поведения классов\n", 435 | "- сохраняются при наследовании\n", 436 | "- временно подменяют --dict-- (?)" 437 | ] 438 | }, 439 | { 440 | "cell_type": "code", 441 | "execution_count": 14, 442 | "metadata": {}, 443 | "outputs": [ 444 | { 445 | "name": "stdout", 446 | "output_type": "stream", 447 | "text": [ 448 | "\n", 449 | "\n" 450 | ] 451 | } 452 | ], 453 | "source": [ 454 | "class Anyclass:\n", 455 | " x = 10\n", 456 | "\n", 457 | "print (type(Anyclass))\n", 458 | "\n", 459 | "class Nextclass(Anyclass): # Python 3 (metaclass = Anyclass):\n", 460 | " y = 20\n", 461 | " \n", 462 | "print (type(Nextclass))" 463 | ] 464 | }, 465 | { 466 | "cell_type": "code", 467 | "execution_count": 8, 468 | "metadata": { 469 | "collapsed": true 470 | }, 471 | "outputs": [], 472 | "source": [ 473 | "class C: pass\n", 474 | "# эквивалентная запись:\n", 475 | "С = type('C', (), {})\n", 476 | "\n", 477 | "# type - дефолтный метакласс для создания классов" 478 | ] 479 | }, 480 | { 481 | "cell_type": "code", 482 | "execution_count": 11, 483 | "metadata": {}, 484 | "outputs": [ 485 | { 486 | "name": "stdout", 487 | "output_type": "stream", 488 | "text": [ 489 | "список: ['one', 'two']\n" 490 | ] 491 | } 492 | ], 493 | "source": [ 494 | "def myprint(self):\n", 495 | " print(\"список: \", self)\n", 496 | "\n", 497 | "# такой способ создания класса \n", 498 | "MyList = type('MyList', (list,), dict(x=10, myprint=myprint))\n", 499 | "\n", 500 | "\n", 501 | "ml = MyList()\n", 502 | "ml.append(\"one\")\n", 503 | "ml.append(\"two\")\n", 504 | "ml.myprint()" 505 | ] 506 | }, 507 | { 508 | "cell_type": "code", 509 | "execution_count": 13, 510 | "metadata": {}, 511 | "outputs": [ 512 | { 513 | "name": "stdout", 514 | "output_type": "stream", 515 | "text": [ 516 | "10 Привет, мир! 5 Пока, мир!\n" 517 | ] 518 | } 519 | ], 520 | "source": [ 521 | "class MyClass: pass\n", 522 | "# это класс!\n", 523 | "MyClass.field = 10\n", 524 | "MyClass.method = lambda x: \"Привет, мир!\"\n", 525 | "\n", 526 | "x = MyClass()\n", 527 | "x.field2 = 5\n", 528 | "x.method2 = lambda x: \"Пока, мир!\"\n", 529 | "\n", 530 | "print (x.field, x.method(), x.field2, x.method2(None))\n", 531 | "# x.method2 - нужен аргумент" 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "execution_count": 10, 537 | "metadata": {}, 538 | "outputs": [ 539 | { 540 | "name": "stdout", 541 | "output_type": "stream", 542 | "text": [ 543 | "5 5\n" 544 | ] 545 | } 546 | ], 547 | "source": [ 548 | "# есть атрибуты экземпляра\n", 549 | "# а есть атрибуты класса\n", 550 | "\n", 551 | "class MyClass: pass\n", 552 | "\n", 553 | "MyClass.field = 10\n", 554 | "x = MyClass()\n", 555 | "y = MyClass()\n", 556 | "MyClass.field = 5 # модификация произойдёт во всех объектах\n", 557 | "\n", 558 | "print (x.field, y.field)" 559 | ] 560 | }, 561 | { 562 | "cell_type": "code", 563 | "execution_count": 26, 564 | "metadata": {}, 565 | "outputs": [], 566 | "source": [ 567 | "# много ещё чего про метаклассы - не стал писать" 568 | ] 569 | }, 570 | { 571 | "cell_type": "code", 572 | "execution_count": 2, 573 | "metadata": {}, 574 | "outputs": [ 575 | { 576 | "data": { 577 | "text/plain": [ 578 | "Path(./main/file.txt)" 579 | ] 580 | }, 581 | "execution_count": 2, 582 | "metadata": {}, 583 | "output_type": "execute_result" 584 | } 585 | ], 586 | "source": [ 587 | "# ???? - см. Python 3\n", 588 | "class Path:\n", 589 | " def __init__(self, directory):\n", 590 | " self.directory = directory\n", 591 | " \n", 592 | " def __repr__(self):\n", 593 | " return \"Path({})\".format(self.directory)\n", 594 | " \n", 595 | " @property\n", 596 | " def parent(self):\n", 597 | " return Path(dirname(self.directory))\n", 598 | " \n", 599 | "p = Path(\"./main/file.txt\")\n", 600 | "p" 601 | ] 602 | }, 603 | { 604 | "cell_type": "code", 605 | "execution_count": 17, 606 | "metadata": {}, 607 | "outputs": [ 608 | { 609 | "name": "stdout", 610 | "output_type": "stream", 611 | "text": [ 612 | "my_attr\n", 613 | "0\n", 614 | "val_other\n" 615 | ] 616 | } 617 | ], 618 | "source": [ 619 | "class Myclass:\n", 620 | " val = 0\n", 621 | " def __getattr__(self, name): # __getattr__ - при вызове несуществующего атрибута\n", 622 | " return name\n", 623 | "\n", 624 | "m = Myclass()\n", 625 | "print (m.my_attr)" 626 | ] 627 | }, 628 | { 629 | "cell_type": "code", 630 | "execution_count": 31, 631 | "metadata": {}, 632 | "outputs": [ 633 | { 634 | "name": "stdout", 635 | "output_type": "stream", 636 | "text": [ 637 | "2\n", 638 | "1.0\n" 639 | ] 640 | }, 641 | { 642 | "data": { 643 | "text/plain": [ 644 | "{'val': 2, 'val_other': 3.0}" 645 | ] 646 | }, 647 | "execution_count": 31, 648 | "metadata": {}, 649 | "output_type": "execute_result" 650 | } 651 | ], 652 | "source": [ 653 | "class Myclass:\n", 654 | " val = 0\n", 655 | "\n", 656 | "m = Myclass()\n", 657 | "\n", 658 | "setattr(m, \"val\", 2) # getattr - безопасное добавление атрибута\n", 659 | "# setattr(m, \"val_other\", 3.0) # m.val_other = 3.0 создастся новый атрибут\n", 660 | "print (getattr(m, \"val\")) # getattr - безопасный вызов атрибута\n", 661 | "print (getattr(m, \"val_some_other\", 1.0))\n", 662 | "\n", 663 | "m.__dict__" 664 | ] 665 | }, 666 | { 667 | "cell_type": "code", 668 | "execution_count": 5, 669 | "metadata": {}, 670 | "outputs": [ 671 | { 672 | "name": "stdout", 673 | "output_type": "stream", 674 | "text": [ 675 | "(1, 2)\n" 676 | ] 677 | } 678 | ], 679 | "source": [ 680 | "class Vec:\n", 681 | " def __init__(self, x=0.0, y=0.0):\n", 682 | " self.x = x\n", 683 | " self.y = y\n", 684 | " \n", 685 | " def __str__(self): # представление в виде строки\n", 686 | " return (\"(%s, %s)\" % (self.x, self.y))\n", 687 | "\n", 688 | "x = Vec(1, 2)\n", 689 | "print (x)" 690 | ] 691 | }, 692 | { 693 | "cell_type": "markdown", 694 | "metadata": {}, 695 | "source": [ 696 | "## Дескриптор\n", 697 | "\n", 698 | "-- атрибут объекта со скрытым поведеним, которое задают методы в протоколе дескриптора: __get__(), __set__(), and __delete__()" 699 | ] 700 | }, 701 | { 702 | "cell_type": "code", 703 | "execution_count": 5, 704 | "metadata": {}, 705 | "outputs": [ 706 | { 707 | "name": "stdout", 708 | "output_type": "stream", 709 | "text": [ 710 | "Выдаём var \"x\"\n", 711 | "11\n", 712 | "Получаем var \"x\"\n", 713 | "Выдаём var \"x\"\n", 714 | "21\n", 715 | "Получаем var \"x\"\n", 716 | "Отрицательное значение - будет обнулено\n", 717 | "Выдаём var \"x\"\n", 718 | "1\n", 719 | "5\n" 720 | ] 721 | } 722 | ], 723 | "source": [ 724 | "class RevealAccess(object):\n", 725 | " \"\"\"Пример дескриптора данных:\n", 726 | " устанавливает и возвращает значения,\n", 727 | " а также пишет сообщения\n", 728 | " \"\"\"\n", 729 | "\n", 730 | " def __init__(self, initval=None, name='var'):\n", 731 | " self.val = initval\n", 732 | " self.name = name\n", 733 | "\n", 734 | " def __get__(self, obj, objtype):\n", 735 | " print('Выдаём', self.name)\n", 736 | " return (self.val + 1) # выдаёт следующее число\n", 737 | "\n", 738 | " def __set__(self, obj, val):\n", 739 | " print('Получаем', self.name)\n", 740 | " if val<0:\n", 741 | " print('Отрицательное значение - будет обнулено')\n", 742 | " self.val = 0\n", 743 | " else:\n", 744 | " self.val = val\n", 745 | "\n", 746 | "class MyClass(object):\n", 747 | " x = RevealAccess(10, 'var \"x\"') # у переменное скрытое поведение\n", 748 | " y = 5\n", 749 | " \n", 750 | " \n", 751 | "m = MyClass()\n", 752 | "print (m.x)\n", 753 | "\n", 754 | "m.x = 20\n", 755 | "print (m.x)\n", 756 | "m.x = -20\n", 757 | "print (m.x)\n", 758 | "\n", 759 | "\n", 760 | "print(m.y)" 761 | ] 762 | }, 763 | { 764 | "cell_type": "code", 765 | "execution_count": 6, 766 | "metadata": { 767 | "collapsed": true 768 | }, 769 | "outputs": [], 770 | "source": [ 771 | "# свойства в Питоне - \"быстрый\" дескриптор\n", 772 | "\n", 773 | "# \"безопасный класс\"\n", 774 | "# контролирует значения атрибутов\n", 775 | "\n", 776 | "class SafeClass:\n", 777 | " def _get_attr(self):\n", 778 | " return self._x\n", 779 | " \n", 780 | " def _set_attr(self, x):\n", 781 | " assert x > 0, \"необходимо положительное значение\"\n", 782 | " self._x = x\n", 783 | " \n", 784 | " def _del_attr(self):\n", 785 | " del self._x\n", 786 | " \n", 787 | " x = property(_get_attr, _set_attr, _del_attr)\n", 788 | " \n", 789 | " \n", 790 | "safe = SafeClass()\n", 791 | "safe.x = 1\n", 792 | "# safe.x = -2 # будет исключение" 793 | ] 794 | }, 795 | { 796 | "cell_type": "code", 797 | "execution_count": 13, 798 | "metadata": {}, 799 | "outputs": [], 800 | "source": [ 801 | "# ??? пока не понял - МОЖНО УДАЛИТЬ\n", 802 | "class NonNegative:\n", 803 | " def _get_attr(self):\n", 804 | " return self._x\n", 805 | " \n", 806 | " def _set_attr(self, x):\n", 807 | " assert x > 0, \"необходимо положительное значение\"\n", 808 | " self._x = x\n", 809 | " \n", 810 | " def _del_attr(self):\n", 811 | " del self._x\n", 812 | " \n", 813 | "class SafeClass2:\n", 814 | " x = NonNegative()\n", 815 | " y = NonNegative()" 816 | ] 817 | }, 818 | { 819 | "cell_type": "code", 820 | "execution_count": 17, 821 | "metadata": { 822 | "collapsed": true 823 | }, 824 | "outputs": [], 825 | "source": [ 826 | "safe = SafeClass2()" 827 | ] 828 | }, 829 | { 830 | "cell_type": "code", 831 | "execution_count": 18, 832 | "metadata": {}, 833 | "outputs": [], 834 | "source": [ 835 | "safe.x = -2" 836 | ] 837 | }, 838 | { 839 | "cell_type": "code", 840 | "execution_count": 21, 841 | "metadata": {}, 842 | "outputs": [], 843 | "source": [ 844 | "safe.y = -2" 845 | ] 846 | }, 847 | { 848 | "cell_type": "code", 849 | "execution_count": 23, 850 | "metadata": { 851 | "collapsed": true 852 | }, 853 | "outputs": [], 854 | "source": [ 855 | "class SafeClass2:\n", 856 | " x = SafeClass()\n", 857 | " y = SafeClass()" 858 | ] 859 | } 860 | ], 861 | "metadata": { 862 | "kernelspec": { 863 | "display_name": "Python 3", 864 | "language": "python", 865 | "name": "python3" 866 | }, 867 | "language_info": { 868 | "codemirror_mode": { 869 | "name": "ipython", 870 | "version": 3 871 | }, 872 | "file_extension": ".py", 873 | "mimetype": "text/x-python", 874 | "name": "python", 875 | "nbconvert_exporter": "python", 876 | "pygments_lexer": "ipython3", 877 | "version": "3.6.5" 878 | } 879 | }, 880 | "nbformat": 4, 881 | "nbformat_minor": 1 882 | } 883 | -------------------------------------------------------------------------------- /dj_python_4_tonko_20181004.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# язык программирования Python\n", 8 | "## часть IV - некоторые тонкости\n", 9 | "\n", 10 | "автор: **Дьяконов Александр www.dyakonov.org**\n", 11 | "\n", 12 | "**для поддержки курсов автора, в частности https://github.com/Dyakonov/IML**\n", 13 | "\n", 14 | "\n", 15 | "### материал основан на...\n", 16 | "книге ***Дэн Бейдер*** **Чистый Python. Тонкости программирования для профи**. Питер, 2018." 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "### assert\n", 24 | "\n", 25 | "Инструкции assert должны применяться только для того, чтобы помогать разработчикам идентифицировать ошибки. Они не являются механизмом обработки ошибок периода исполнения программы." 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "## типичная ошибка - пропущенная запятая" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 2, 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "data": { 42 | "text/plain": [ 43 | "['Петя', 'МашаВася']" 44 | ] 45 | }, 46 | "execution_count": 2, 47 | "metadata": {}, 48 | "output_type": "execute_result" 49 | } 50 | ], 51 | "source": [ 52 | "lst = ['Петя',\n", 53 | " 'Маша'\n", 54 | " 'Вася'\n", 55 | " ]\n", 56 | "\n", 57 | "lst" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "## менеджер контекста\n", 65 | "\n", 66 | "эквивалентные куски кода" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "with open('hello.txt', 'w') as f:\n", 76 | " f.write('привет, мир!')\n", 77 | "\n", 78 | "\n", 79 | "f = open('hello.txt', 'w')\n", 80 | "try:\n", 81 | " f.write('привет, мир!')\n", 82 | "finally:\n", 83 | " f.close()" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 3, 89 | "metadata": {}, 90 | "outputs": [ 91 | { 92 | "name": "stdout", 93 | "output_type": "stream", 94 | "text": [ 95 | " раз\n", 96 | " два\n", 97 | " три\n", 98 | " четыре\n" 99 | ] 100 | } 101 | ], 102 | "source": [ 103 | "class Indenter:\n", 104 | " def __init__(self):\n", 105 | " self.level = 0\n", 106 | " \n", 107 | " def __enter__(self):\n", 108 | " self.level += 1\n", 109 | " return self\n", 110 | " \n", 111 | " def __exit__(self, exc_type, exc_val, exc_tb):\n", 112 | " self.level -= 1\n", 113 | " \n", 114 | " def print(self, text):\n", 115 | " print(' ' * self.level + text)\n", 116 | " \n", 117 | "\n", 118 | "with Indenter() as indent:\n", 119 | " indent.print('раз')\n", 120 | " with indent:\n", 121 | " indent.print('два')\n", 122 | " with indent:\n", 123 | " indent.print('три')\n", 124 | " indent.print('четыре')" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "## именования переменных\n", 132 | "\n", 133 | "\n", 134 | "\n", 135 | "«дандеры» (dunders — это сокращение от англ. double underscores) - с двойным подчёркиванием" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": null, 141 | "metadata": {}, 142 | "outputs": [], 143 | "source": [ 144 | "_var = 1 # для внутреннего пользования, не импортируются from my_module import *\n", 145 | "var_ = 1 # чтобы избежать конфликта имён\n", 146 | "__var = 1 # искажением имени (name mangling)\n", 147 | "__var__ = 1 # не будет искажения! Зарезервированы: __init__, __call__ и т.п.\n", 148 | "_ = 1 # неважное имя переменной (чаще при распаковке) часто: результат последнего выражения\n" 149 | ] 150 | }, 151 | { 152 | "cell_type": "markdown", 153 | "metadata": {}, 154 | "source": [ 155 | "# форматирование строк" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 1, 161 | "metadata": {}, 162 | "outputs": [ 163 | { 164 | "name": "stdout", 165 | "output_type": "stream", 166 | "text": [ 167 | "Привет, Иван\n", 168 | "Привет, Иван\n", 169 | "Привет, Иван\n", 170 | "Привет, Иван\n" 171 | ] 172 | } 173 | ], 174 | "source": [ 175 | "name = 'Иван'\n", 176 | "print ('Привет, %s' % name)\n", 177 | "print ('Привет, {}'.format(name))\n", 178 | "print (f'Привет, {name}') # форматированные строковые литералы (Formatted String Literals).\n", 179 | "\n", 180 | "from string import Template\n", 181 | "print (Template('Привет, $name').substitute(name=name)) # шаблонные строки" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "## лямбда-функции" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 7, 194 | "metadata": {}, 195 | "outputs": [ 196 | { 197 | "data": { 198 | "text/plain": [ 199 | "3" 200 | ] 201 | }, 202 | "execution_count": 7, 203 | "metadata": {}, 204 | "output_type": "execute_result" 205 | } 206 | ], 207 | "source": [ 208 | "(lambda x, y: x + y)(1, 2)" 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": 55, 214 | "metadata": {}, 215 | "outputs": [ 216 | { 217 | "name": "stdout", 218 | "output_type": "stream", 219 | "text": [ 220 | "[(-2, 'MINUS TWO'), (-1, 'MINUS ONE'), (1, 'ONE'), (4, 'FOUR')]\n", 221 | "[(1, 'ONE'), (-1, 'MINUS ONE'), (-2, 'MINUS TWO'), (4, 'FOUR')]\n" 222 | ] 223 | } 224 | ], 225 | "source": [ 226 | "tuples = [(1, 'ONE'), (4, 'FOUR'), (-1, 'MINUS ONE'), (-2, 'MINUS TWO')]\n", 227 | "\n", 228 | "print (sorted(tuples, key=lambda x: x[0])) # так по умолчанию!\n", 229 | "print (sorted(tuples, key=lambda x: x[0]*x[0]))" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 60, 235 | "metadata": {}, 236 | "outputs": [ 237 | { 238 | "data": { 239 | "text/plain": [ 240 | "[(-2, 'MINUS TWO'), (-1, 'MINUS ONE'), (1, 'ONE'), (4, 'FOUR')]" 241 | ] 242 | }, 243 | "execution_count": 60, 244 | "metadata": {}, 245 | "output_type": "execute_result" 246 | } 247 | ], 248 | "source": [ 249 | "import operator\n", 250 | "sorted(tuples, key=operator.itemgetter(0))" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 11, 256 | "metadata": {}, 257 | "outputs": [ 258 | { 259 | "data": { 260 | "text/plain": [ 261 | "[(-2, 'MINUS TWO'), (-1, 'MINUS ONE'), (1, 'ONE'), (4, 'FOUR')]" 262 | ] 263 | }, 264 | "execution_count": 11, 265 | "metadata": {}, 266 | "output_type": "execute_result" 267 | } 268 | ], 269 | "source": [ 270 | "sorted(tuples)" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": 13, 276 | "metadata": {}, 277 | "outputs": [ 278 | { 279 | "data": { 280 | "text/plain": [ 281 | "[0, 2, 4, 6, 8, 10, 12, 14]" 282 | ] 283 | }, 284 | "execution_count": 13, 285 | "metadata": {}, 286 | "output_type": "execute_result" 287 | } 288 | ], 289 | "source": [ 290 | "list(filter(lambda x: x % 2 == 0, range(16)))" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": 14, 296 | "metadata": {}, 297 | "outputs": [ 298 | { 299 | "data": { 300 | "text/plain": [ 301 | "[0, 2, 4, 6, 8, 10, 12, 14]" 302 | ] 303 | }, 304 | "execution_count": 14, 305 | "metadata": {}, 306 | "output_type": "execute_result" 307 | } 308 | ], 309 | "source": [ 310 | "[x for x in range(16) if x % 2 == 0]" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": 15, 316 | "metadata": {}, 317 | "outputs": [ 318 | { 319 | "name": "stdout", 320 | "output_type": "stream", 321 | "text": [ 322 | "[(4, 'FOUR'), (-1, 'MINUS ONE'), (-2, 'MINUS TWO'), (1, 'ONE')]\n" 323 | ] 324 | } 325 | ], 326 | "source": [ 327 | "tuples = [(1, 'ONE'), (4, 'FOUR'), (-1, 'MINUS ONE'), (-2, 'MINUS TWO')]\n", 328 | "\n", 329 | "print (sorted(tuples, key=lambda x: x[1])) # так по умолчанию!" 330 | ] 331 | }, 332 | { 333 | "cell_type": "markdown", 334 | "metadata": {}, 335 | "source": [ 336 | "# декораторы" 337 | ] 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": 24, 342 | "metadata": {}, 343 | "outputs": [ 344 | { 345 | "data": { 346 | "text/plain": [ 347 | "'HELLO!'" 348 | ] 349 | }, 350 | "execution_count": 24, 351 | "metadata": {}, 352 | "output_type": "execute_result" 353 | } 354 | ], 355 | "source": [ 356 | "def dec_upper(f):\n", 357 | " return lambda: f().upper()\n", 358 | "\n", 359 | "def dec_lower(f):\n", 360 | " return lambda: f().lower()\n", 361 | "\n", 362 | "@dec_upper\n", 363 | "@dec_lower\n", 364 | "def say():\n", 365 | " return('Hello!') # ' + x + '\n", 366 | "\n", 367 | "say()" 368 | ] 369 | }, 370 | { 371 | "cell_type": "code", 372 | "execution_count": 29, 373 | "metadata": {}, 374 | "outputs": [ 375 | { 376 | "data": { 377 | "text/plain": [ 378 | "'HELLOMIKE!'" 379 | ] 380 | }, 381 | "execution_count": 29, 382 | "metadata": {}, 383 | "output_type": "execute_result" 384 | } 385 | ], 386 | "source": [ 387 | "def dec_upper(f):\n", 388 | " def g(*args, **kwargs):\n", 389 | " return f(*args, **kwargs).upper()\n", 390 | " return g\n", 391 | "\n", 392 | "def dec_lower(f):\n", 393 | " def g(*args, **kwargs):\n", 394 | " return f(*args, **kwargs).lower()\n", 395 | " return g\n", 396 | "\n", 397 | "@dec_upper\n", 398 | "@dec_lower\n", 399 | "def say(x):\n", 400 | " return('Hello' + x + '!') # ' + x + '\n", 401 | "\n", 402 | "say('Mike')" 403 | ] 404 | }, 405 | { 406 | "cell_type": "markdown", 407 | "metadata": {}, 408 | "source": [ 409 | "## необязательные аргументы" 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": 21, 415 | "metadata": {}, 416 | "outputs": [ 417 | { 418 | "name": "stdout", 419 | "output_type": "stream", 420 | "text": [ 421 | "()\n" 422 | ] 423 | } 424 | ], 425 | "source": [ 426 | "def f(z, *x):\n", 427 | " print (x)\n", 428 | " \n", 429 | "f(1)" 430 | ] 431 | }, 432 | { 433 | "cell_type": "markdown", 434 | "metadata": {}, 435 | "source": [ 436 | "# распаковка аргументов" 437 | ] 438 | }, 439 | { 440 | "cell_type": "code", 441 | "execution_count": 33, 442 | "metadata": {}, 443 | "outputs": [ 444 | { 445 | "name": "stdout", 446 | "output_type": "stream", 447 | "text": [ 448 | "<1, 2, 3>\n", 449 | "<4, 5, 6>\n", 450 | "<0, 1, 4>\n", 451 | "\n", 452 | "<30, 10, 20>\n" 453 | ] 454 | } 455 | ], 456 | "source": [ 457 | "def print_vec(x, y, z):\n", 458 | " print('<%s, %s, %s>' % (x, y, z))\n", 459 | " \n", 460 | "lst = [1, 2, 3]\n", 461 | "tpl = (4, 5, 6)\n", 462 | "gen = (i*i for i in range(3))\n", 463 | "\n", 464 | "print_vec(*lst)\n", 465 | "print_vec(*tpl)\n", 466 | "print_vec(*gen)\n", 467 | "\n", 468 | "\n", 469 | "dct = {'y': 10, 'z': 20, 'x': 30}\n", 470 | "print_vec(*dct)\n", 471 | "print_vec(**dct)" 472 | ] 473 | }, 474 | { 475 | "cell_type": "markdown", 476 | "metadata": {}, 477 | "source": [ 478 | "## ООП" 479 | ] 480 | }, 481 | { 482 | "cell_type": "code", 483 | "execution_count": 34, 484 | "metadata": {}, 485 | "outputs": [ 486 | { 487 | "data": { 488 | "text/plain": [ 489 | "(False, False, True, False, [1, 2], None, [1, 2])" 490 | ] 491 | }, 492 | "execution_count": 34, 493 | "metadata": {}, 494 | "output_type": "execute_result" 495 | } 496 | ], 497 | "source": [ 498 | "a = [1, 2]\n", 499 | "b = [1].append(2)\n", 500 | "c = [1, 2]\n", 501 | "\n", 502 | "a == b, a is b, a == c, a is c, a, b, c" 503 | ] 504 | }, 505 | { 506 | "cell_type": "markdown", 507 | "metadata": {}, 508 | "source": [ 509 | "## что возвращает функция" 510 | ] 511 | }, 512 | { 513 | "cell_type": "code", 514 | "execution_count": 35, 515 | "metadata": {}, 516 | "outputs": [ 517 | { 518 | "name": "stdout", 519 | "output_type": "stream", 520 | "text": [ 521 | "None\n" 522 | ] 523 | } 524 | ], 525 | "source": [ 526 | "def f(x, y):\n", 527 | " z = x + y\n", 528 | " \n", 529 | "print (f(1, 2))" 530 | ] 531 | }, 532 | { 533 | "cell_type": "markdown", 534 | "metadata": {}, 535 | "source": [ 536 | "# описание функции" 537 | ] 538 | }, 539 | { 540 | "cell_type": "code", 541 | "execution_count": 36, 542 | "metadata": {}, 543 | "outputs": [ 544 | { 545 | "name": "stdout", 546 | "output_type": "stream", 547 | "text": [ 548 | "__str__ 2\n", 549 | "\n", 550 | "Help on MyClass in module __main__ object:\n", 551 | "\n", 552 | "class MyClass(builtins.object)\n", 553 | " | __comment__\n", 554 | " | \n", 555 | " | Methods defined here:\n", 556 | " | \n", 557 | " | __init__(self, var)\n", 558 | " | Initialize self. See help(type(self)) for accurate signature.\n", 559 | " | \n", 560 | " | __repr__(self)\n", 561 | " | Return repr(self).\n", 562 | " | \n", 563 | " | __str__(self)\n", 564 | " | Return str(self).\n", 565 | " | \n", 566 | " | ----------------------------------------------------------------------\n", 567 | " | Data descriptors defined here:\n", 568 | " | \n", 569 | " | __dict__\n", 570 | " | dictionary for instance variables (if defined)\n", 571 | " | \n", 572 | " | __weakref__\n", 573 | " | list of weak references to the object (if defined)\n", 574 | "\n" 575 | ] 576 | }, 577 | { 578 | "data": { 579 | "text/plain": [ 580 | "__repr__ 2" 581 | ] 582 | }, 583 | "execution_count": 36, 584 | "metadata": {}, 585 | "output_type": "execute_result" 586 | } 587 | ], 588 | "source": [ 589 | "class MyClass:\n", 590 | " \"\"\"\n", 591 | " __comment__\n", 592 | " \"\"\"\n", 593 | " def __init__(self, var):\n", 594 | " self.var = var\n", 595 | " def __repr__(self):\n", 596 | " # для разработчиков\n", 597 | " return '__repr__ %g' % self.var\n", 598 | " def __str__(self):\n", 599 | " # удобочитаемо\n", 600 | " return '__str__ %g' % self.var\n", 601 | "\n", 602 | "mc = MyClass(2)\n", 603 | "print (mc)\n", 604 | "print (MyClass)\n", 605 | "help(mc)\n", 606 | "mc" 607 | ] 608 | }, 609 | { 610 | "cell_type": "code", 611 | "execution_count": 37, 612 | "metadata": {}, 613 | "outputs": [ 614 | { 615 | "data": { 616 | "text/plain": [ 617 | "'__str__ 2'" 618 | ] 619 | }, 620 | "execution_count": 37, 621 | "metadata": {}, 622 | "output_type": "execute_result" 623 | } 624 | ], 625 | "source": [ 626 | "str(mc)" 627 | ] 628 | }, 629 | { 630 | "cell_type": "markdown", 631 | "metadata": {}, 632 | "source": [ 633 | "## копирование" 634 | ] 635 | }, 636 | { 637 | "cell_type": "code", 638 | "execution_count": 39, 639 | "metadata": {}, 640 | "outputs": [ 641 | { 642 | "name": "stdout", 643 | "output_type": "stream", 644 | "text": [ 645 | "[[1, 4], [2], [3]]\n", 646 | "[[1, 4], [2]]\n" 647 | ] 648 | } 649 | ], 650 | "source": [ 651 | "x = [[1], [2]]\n", 652 | "y = list(x)\n", 653 | "x.append([3])\n", 654 | "x[0].append(4)\n", 655 | "print (x)\n", 656 | "print (y)" 657 | ] 658 | }, 659 | { 660 | "cell_type": "markdown", 661 | "metadata": {}, 662 | "source": [ 663 | "## переменные класса и экземпляра" 664 | ] 665 | }, 666 | { 667 | "cell_type": "code", 668 | "execution_count": 40, 669 | "metadata": {}, 670 | "outputs": [ 671 | { 672 | "name": "stdout", 673 | "output_type": "stream", 674 | "text": [ 675 | "2\n", 676 | "2 10\n", 677 | "0 10 2 20 2\n" 678 | ] 679 | } 680 | ], 681 | "source": [ 682 | "class My:\n", 683 | " a = 2 # переменная класса\n", 684 | " def __init__(self, b):\n", 685 | " self.b = b # переменная экземпляра\n", 686 | " \n", 687 | "print (My.a)\n", 688 | "m = My(10)\n", 689 | "print (m.a, m.b)\n", 690 | "m2 = My(20)\n", 691 | "m.a = 0\n", 692 | "print (m.a, m.b, m2.a, m2.b, My.a)" 693 | ] 694 | }, 695 | { 696 | "cell_type": "code", 697 | "execution_count": 41, 698 | "metadata": {}, 699 | "outputs": [ 700 | { 701 | "name": "stdout", 702 | "output_type": "stream", 703 | "text": [ 704 | "10 20\n" 705 | ] 706 | } 707 | ], 708 | "source": [ 709 | "class My:\n", 710 | " a = 2 # переменная класса\n", 711 | " def __init__(self, b):\n", 712 | " self.b = b # переменная экземпляра\n", 713 | " \n", 714 | "m = My(0)\n", 715 | "m.a = 10\n", 716 | "m.b = 20\n", 717 | "My.a = 30\n", 718 | "# m = My(0)\n", 719 | "print (m.a, m.b)" 720 | ] 721 | }, 722 | { 723 | "cell_type": "code", 724 | "execution_count": 42, 725 | "metadata": {}, 726 | "outputs": [], 727 | "source": [ 728 | "class MyClass:\n", 729 | " def method(self):\n", 730 | " return 'вызван метод экземпляра', self\n", 731 | " @classmethod\n", 732 | " def classmethod(cls):\n", 733 | " return 'вызван метод класса', cls\n", 734 | " @staticmethod\n", 735 | " def staticmethod():\n", 736 | " return 'вызван статический метод'" 737 | ] 738 | }, 739 | { 740 | "cell_type": "code", 741 | "execution_count": 43, 742 | "metadata": {}, 743 | "outputs": [ 744 | { 745 | "data": { 746 | "text/plain": [ 747 | "('вызван метод экземпляра', <__main__.MyClass at 0x7f3a8f1ce8d0>)" 748 | ] 749 | }, 750 | "execution_count": 43, 751 | "metadata": {}, 752 | "output_type": "execute_result" 753 | } 754 | ], 755 | "source": [ 756 | "obj = MyClass()\n", 757 | "obj.method()" 758 | ] 759 | }, 760 | { 761 | "cell_type": "code", 762 | "execution_count": 44, 763 | "metadata": {}, 764 | "outputs": [ 765 | { 766 | "data": { 767 | "text/plain": [ 768 | "('вызван метод экземпляра', <__main__.MyClass at 0x7f3a8f1ce8d0>)" 769 | ] 770 | }, 771 | "execution_count": 44, 772 | "metadata": {}, 773 | "output_type": "execute_result" 774 | } 775 | ], 776 | "source": [ 777 | "MyClass.method(obj)" 778 | ] 779 | }, 780 | { 781 | "cell_type": "code", 782 | "execution_count": 45, 783 | "metadata": {}, 784 | "outputs": [ 785 | { 786 | "data": { 787 | "text/plain": [ 788 | "('вызван метод класса', __main__.MyClass)" 789 | ] 790 | }, 791 | "execution_count": 45, 792 | "metadata": {}, 793 | "output_type": "execute_result" 794 | } 795 | ], 796 | "source": [ 797 | "obj.classmethod()" 798 | ] 799 | }, 800 | { 801 | "cell_type": "code", 802 | "execution_count": 46, 803 | "metadata": {}, 804 | "outputs": [ 805 | { 806 | "data": { 807 | "text/plain": [ 808 | "'вызван статический метод'" 809 | ] 810 | }, 811 | "execution_count": 46, 812 | "metadata": {}, 813 | "output_type": "execute_result" 814 | } 815 | ], 816 | "source": [ 817 | "obj.staticmethod()\n", 818 | "\n", 819 | "# статические методы не могут получить доступ ни к состоянию экземпляра объекта, ни к состоянию класса" 820 | ] 821 | }, 822 | { 823 | "cell_type": "code", 824 | "execution_count": 47, 825 | "metadata": {}, 826 | "outputs": [ 827 | { 828 | "data": { 829 | "text/plain": [ 830 | "('вызван метод класса', __main__.MyClass)" 831 | ] 832 | }, 833 | "execution_count": 47, 834 | "metadata": {}, 835 | "output_type": "execute_result" 836 | } 837 | ], 838 | "source": [ 839 | "MyClass.classmethod()" 840 | ] 841 | }, 842 | { 843 | "cell_type": "code", 844 | "execution_count": 49, 845 | "metadata": {}, 846 | "outputs": [ 847 | { 848 | "data": { 849 | "text/plain": [ 850 | "'вызван статический метод'" 851 | ] 852 | }, 853 | "execution_count": 49, 854 | "metadata": {}, 855 | "output_type": "execute_result" 856 | } 857 | ], 858 | "source": [ 859 | "MyClass.staticmethod()" 860 | ] 861 | }, 862 | { 863 | "cell_type": "code", 864 | "execution_count": 50, 865 | "metadata": {}, 866 | "outputs": [ 867 | { 868 | "ename": "TypeError", 869 | "evalue": "method() missing 1 required positional argument: 'self'", 870 | "output_type": "error", 871 | "traceback": [ 872 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 873 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 874 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMyClass\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 875 | "\u001b[0;31mTypeError\u001b[0m: method() missing 1 required positional argument: 'self'" 876 | ] 877 | } 878 | ], 879 | "source": [ 880 | "MyClass.method()" 881 | ] 882 | }, 883 | { 884 | "cell_type": "markdown", 885 | "metadata": {}, 886 | "source": [ 887 | "# словари" 888 | ] 889 | }, 890 | { 891 | "cell_type": "code", 892 | "execution_count": 6, 893 | "metadata": {}, 894 | "outputs": [ 895 | { 896 | "data": { 897 | "text/plain": [ 898 | "{(1, 2): [1, 2]}" 899 | ] 900 | }, 901 | "execution_count": 6, 902 | "metadata": {}, 903 | "output_type": "execute_result" 904 | } 905 | ], 906 | "source": [ 907 | "dict({(1, 2): [1, 2]})" 908 | ] 909 | }, 910 | { 911 | "cell_type": "code", 912 | "execution_count": 63, 913 | "metadata": {}, 914 | "outputs": [ 915 | { 916 | "data": { 917 | "text/plain": [ 918 | "{True: 'возможно'}" 919 | ] 920 | }, 921 | "execution_count": 63, 922 | "metadata": {}, 923 | "output_type": "execute_result" 924 | } 925 | ], 926 | "source": [ 927 | "{True: 'да', 1: 'нет', 1.0: 'возможно'}" 928 | ] 929 | }, 930 | { 931 | "cell_type": "code", 932 | "execution_count": 64, 933 | "metadata": {}, 934 | "outputs": [ 935 | { 936 | "data": { 937 | "text/plain": [ 938 | "True" 939 | ] 940 | }, 941 | "execution_count": 64, 942 | "metadata": {}, 943 | "output_type": "execute_result" 944 | } 945 | ], 946 | "source": [ 947 | "True == 1 == 1.0" 948 | ] 949 | }, 950 | { 951 | "cell_type": "markdown", 952 | "metadata": {}, 953 | "source": [ 954 | "# словарь с порядком" 955 | ] 956 | }, 957 | { 958 | "cell_type": "code", 959 | "execution_count": 7, 960 | "metadata": {}, 961 | "outputs": [ 962 | { 963 | "data": { 964 | "text/plain": [ 965 | "OrderedDict([('one', 1), ('two', 2), ('three', 3)])" 966 | ] 967 | }, 968 | "execution_count": 7, 969 | "metadata": {}, 970 | "output_type": "execute_result" 971 | } 972 | ], 973 | "source": [ 974 | "# словарь с порядком ключей\n", 975 | "import collections \n", 976 | "d = collections.OrderedDict(one=1, two=2, three=3)\n", 977 | "d" 978 | ] 979 | }, 980 | { 981 | "cell_type": "code", 982 | "execution_count": 12, 983 | "metadata": {}, 984 | "outputs": [ 985 | { 986 | "data": { 987 | "text/plain": [ 988 | "(1, [])" 989 | ] 990 | }, 991 | "execution_count": 12, 992 | "metadata": {}, 993 | "output_type": "execute_result" 994 | } 995 | ], 996 | "source": [ 997 | "# словарь со значение по умолчанию\n", 998 | "import collections \n", 999 | "d = collections.defaultdict(list, one=1, two=2, three=3, default='111')\n", 1000 | "d['one'], d['2'] # по умолчанию - пустой список" 1001 | ] 1002 | }, 1003 | { 1004 | "cell_type": "code", 1005 | "execution_count": 14, 1006 | "metadata": {}, 1007 | "outputs": [ 1008 | { 1009 | "data": { 1010 | "text/plain": [ 1011 | "(1, 2, 4, 6)" 1012 | ] 1013 | }, 1014 | "execution_count": 14, 1015 | "metadata": {}, 1016 | "output_type": "execute_result" 1017 | } 1018 | ], 1019 | "source": [ 1020 | "# словари -> в один словарь\n", 1021 | "from collections import ChainMap \n", 1022 | "d1 = {1:1, 2:2}\n", 1023 | "d2 = {2:3, 3:4}\n", 1024 | "d3 = {3:5, 4:6}\n", 1025 | "cm = ChainMap(d1, d2, d3)\n", 1026 | "\n", 1027 | "cm[1], cm[2], cm[3], cm[4]" 1028 | ] 1029 | }, 1030 | { 1031 | "cell_type": "markdown", 1032 | "metadata": {}, 1033 | "source": [ 1034 | "# кортежи" 1035 | ] 1036 | }, 1037 | { 1038 | "cell_type": "code", 1039 | "execution_count": 19, 1040 | "metadata": {}, 1041 | "outputs": [ 1042 | { 1043 | "data": { 1044 | "text/plain": [ 1045 | "((), (1,), 1)" 1046 | ] 1047 | }, 1048 | "execution_count": 19, 1049 | "metadata": {}, 1050 | "output_type": "execute_result" 1051 | } 1052 | ], 1053 | "source": [ 1054 | "a = ()\n", 1055 | "# b = (,)\n", 1056 | "c = (1,)\n", 1057 | "#d = (,1)\n", 1058 | "e = (1)\n", 1059 | "\n", 1060 | "a, c, e" 1061 | ] 1062 | }, 1063 | { 1064 | "cell_type": "code", 1065 | "execution_count": 20, 1066 | "metadata": {}, 1067 | "outputs": [ 1068 | { 1069 | "data": { 1070 | "text/plain": [ 1071 | "(1,)" 1072 | ] 1073 | }, 1074 | "execution_count": 20, 1075 | "metadata": {}, 1076 | "output_type": "execute_result" 1077 | } 1078 | ], 1079 | "source": [ 1080 | "a + c" 1081 | ] 1082 | }, 1083 | { 1084 | "cell_type": "markdown", 1085 | "metadata": {}, 1086 | "source": [ 1087 | "## типизированные массивы" 1088 | ] 1089 | }, 1090 | { 1091 | "cell_type": "code", 1092 | "execution_count": 21, 1093 | "metadata": {}, 1094 | "outputs": [ 1095 | { 1096 | "data": { 1097 | "text/plain": [ 1098 | "(array('f', [1.0, 1.5, 2.0, 2.5]), array('f', [1.0, 1.5]))" 1099 | ] 1100 | }, 1101 | "execution_count": 21, 1102 | "metadata": {}, 1103 | "output_type": "execute_result" 1104 | } 1105 | ], 1106 | "source": [ 1107 | "import array \n", 1108 | "arr = array.array('f', (1.0, 1.5, 2.0, 2.5))\n", 1109 | "arr, arr[:2]" 1110 | ] 1111 | }, 1112 | { 1113 | "cell_type": "markdown", 1114 | "metadata": {}, 1115 | "source": [ 1116 | "# строки" 1117 | ] 1118 | }, 1119 | { 1120 | "cell_type": "code", 1121 | "execution_count": 22, 1122 | "metadata": {}, 1123 | "outputs": [ 1124 | { 1125 | "data": { 1126 | "text/plain": [ 1127 | "'3'" 1128 | ] 1129 | }, 1130 | "execution_count": 22, 1131 | "metadata": {}, 1132 | "output_type": "execute_result" 1133 | } 1134 | ], 1135 | "source": [ 1136 | "s1 = '123'\n", 1137 | "s2 = '45'\n", 1138 | "s1 + s2\n", 1139 | "#s1[4]\n", 1140 | "s1[-1]\n", 1141 | "# (s1 s2)\n", 1142 | "# del s1[1]" 1143 | ] 1144 | }, 1145 | { 1146 | "cell_type": "markdown", 1147 | "metadata": {}, 1148 | "source": [ 1149 | "## именнованный список" 1150 | ] 1151 | }, 1152 | { 1153 | "cell_type": "code", 1154 | "execution_count": 31, 1155 | "metadata": {}, 1156 | "outputs": [ 1157 | { 1158 | "name": "stdout", 1159 | "output_type": "stream", 1160 | "text": [ 1161 | "Авто(цвет='red', пробег='1200', автомат=True)\n" 1162 | ] 1163 | } 1164 | ], 1165 | "source": [ 1166 | "# именнованный список\n", 1167 | "from collections import namedtuple \n", 1168 | "Car = namedtuple('Авто' , 'цвет пробег автомат')\n", 1169 | "print (Car('red', '1200', True))" 1170 | ] 1171 | }, 1172 | { 1173 | "cell_type": "code", 1174 | "execution_count": 32, 1175 | "metadata": {}, 1176 | "outputs": [ 1177 | { 1178 | "name": "stdout", 1179 | "output_type": "stream", 1180 | "text": [ 1181 | "Car(цвет='red', пробег='1200', автомат=True)\n" 1182 | ] 1183 | } 1184 | ], 1185 | "source": [ 1186 | "# Python 3.x\n", 1187 | "from typing import NamedTuple\n", 1188 | "class Car(NamedTuple):\n", 1189 | " цвет: str\n", 1190 | " пробег: float\n", 1191 | " автомат: bool\n", 1192 | "print (Car('red', '1200', True))" 1193 | ] 1194 | }, 1195 | { 1196 | "cell_type": "markdown", 1197 | "metadata": {}, 1198 | "source": [ 1199 | "# мультимножество" 1200 | ] 1201 | }, 1202 | { 1203 | "cell_type": "code", 1204 | "execution_count": 35, 1205 | "metadata": {}, 1206 | "outputs": [ 1207 | { 1208 | "data": { 1209 | "text/plain": [ 1210 | "Counter({'клинок': 1, 'хлеб': 3})" 1211 | ] 1212 | }, 1213 | "execution_count": 35, 1214 | "metadata": {}, 1215 | "output_type": "execute_result" 1216 | } 1217 | ], 1218 | "source": [ 1219 | "from collections import Counter \n", 1220 | "\n", 1221 | "inventory = Counter() \n", 1222 | "loot = {'клинок': 1, 'хлеб': 3} \n", 1223 | "inventory.update(loot) \n", 1224 | "inventory " 1225 | ] 1226 | }, 1227 | { 1228 | "cell_type": "code", 1229 | "execution_count": 36, 1230 | "metadata": {}, 1231 | "outputs": [ 1232 | { 1233 | "data": { 1234 | "text/plain": [ 1235 | "Counter({'клинок': 2, 'хлеб': 3, 'яблоко': 1})" 1236 | ] 1237 | }, 1238 | "execution_count": 36, 1239 | "metadata": {}, 1240 | "output_type": "execute_result" 1241 | } 1242 | ], 1243 | "source": [ 1244 | "inventory.update({'клинок': 1, 'яблоко': 1}) \n", 1245 | "inventory" 1246 | ] 1247 | }, 1248 | { 1249 | "cell_type": "code", 1250 | "execution_count": 40, 1251 | "metadata": {}, 1252 | "outputs": [ 1253 | { 1254 | "data": { 1255 | "text/plain": [ 1256 | "(3, 6)" 1257 | ] 1258 | }, 1259 | "execution_count": 40, 1260 | "metadata": {}, 1261 | "output_type": "execute_result" 1262 | } 1263 | ], 1264 | "source": [ 1265 | "len(inventory), sum(inventory.values())" 1266 | ] 1267 | }, 1268 | { 1269 | "cell_type": "markdown", 1270 | "metadata": {}, 1271 | "source": [ 1272 | "# очередь с двусторониим доступом" 1273 | ] 1274 | }, 1275 | { 1276 | "cell_type": "code", 1277 | "execution_count": 41, 1278 | "metadata": {}, 1279 | "outputs": [ 1280 | { 1281 | "data": { 1282 | "text/plain": [ 1283 | "('2', '1')" 1284 | ] 1285 | }, 1286 | "execution_count": 41, 1287 | "metadata": {}, 1288 | "output_type": "execute_result" 1289 | } 1290 | ], 1291 | "source": [ 1292 | "# для очереди FIFO - лучше использовать это!\n", 1293 | "\n", 1294 | "from collections import deque\n", 1295 | "# LifoQueue - в параллельных вычислениях\n", 1296 | "s = deque() \n", 1297 | "s.append('1') \n", 1298 | "s.append('2') \n", 1299 | "s.pop(), s.pop()" 1300 | ] 1301 | }, 1302 | { 1303 | "cell_type": "code", 1304 | "execution_count": 42, 1305 | "metadata": {}, 1306 | "outputs": [ 1307 | { 1308 | "data": { 1309 | "text/plain": [ 1310 | "('1', '2')" 1311 | ] 1312 | }, 1313 | "execution_count": 42, 1314 | "metadata": {}, 1315 | "output_type": "execute_result" 1316 | } 1317 | ], 1318 | "source": [ 1319 | "s = deque() \n", 1320 | "s.append('1') \n", 1321 | "s.append('2') \n", 1322 | "s.popleft(), s.popleft()" 1323 | ] 1324 | }, 1325 | { 1326 | "cell_type": "markdown", 1327 | "metadata": {}, 1328 | "source": [ 1329 | "# очереди с приоритетом" 1330 | ] 1331 | }, 1332 | { 1333 | "cell_type": "code", 1334 | "execution_count": 43, 1335 | "metadata": {}, 1336 | "outputs": [ 1337 | { 1338 | "name": "stdout", 1339 | "output_type": "stream", 1340 | "text": [ 1341 | "(1, 'a')\n", 1342 | "(2, 'b')\n", 1343 | "(3, 'c')\n" 1344 | ] 1345 | } 1346 | ], 1347 | "source": [ 1348 | "from queue import PriorityQueue \n", 1349 | "q = PriorityQueue()\n", 1350 | "q.put((2, 'b')) \n", 1351 | "q.put((1, 'a')) \n", 1352 | "q.put((3, 'c'))\n", 1353 | "while not q.empty():\n", 1354 | " next_item = q.get()\n", 1355 | " print(next_item)" 1356 | ] 1357 | }, 1358 | { 1359 | "cell_type": "markdown", 1360 | "metadata": {}, 1361 | "source": [ 1362 | "## списки" 1363 | ] 1364 | }, 1365 | { 1366 | "cell_type": "code", 1367 | "execution_count": 45, 1368 | "metadata": {}, 1369 | "outputs": [ 1370 | { 1371 | "name": "stdout", 1372 | "output_type": "stream", 1373 | "text": [ 1374 | "[]\n", 1375 | "[]\n" 1376 | ] 1377 | } 1378 | ], 1379 | "source": [ 1380 | "# очистка списка\n", 1381 | "lst = [1, 2, 3]\n", 1382 | "del lst[:]\n", 1383 | "print (lst)\n", 1384 | "\n", 1385 | "lst = [1, 2, 3]\n", 1386 | "lst.clear()\n", 1387 | "print (lst)\n" 1388 | ] 1389 | }, 1390 | { 1391 | "cell_type": "markdown", 1392 | "metadata": {}, 1393 | "source": [ 1394 | "# генераторы" 1395 | ] 1396 | }, 1397 | { 1398 | "cell_type": "code", 1399 | "execution_count": 46, 1400 | "metadata": {}, 1401 | "outputs": [], 1402 | "source": [ 1403 | "def repeater(value):\n", 1404 | " while True:\n", 1405 | " yield value" 1406 | ] 1407 | }, 1408 | { 1409 | "cell_type": "code", 1410 | "execution_count": 54, 1411 | "metadata": {}, 1412 | "outputs": [ 1413 | { 1414 | "data": { 1415 | "text/plain": [ 1416 | "[0, -1, -4]" 1417 | ] 1418 | }, 1419 | "execution_count": 54, 1420 | "metadata": {}, 1421 | "output_type": "execute_result" 1422 | } 1423 | ], 1424 | "source": [ 1425 | "vals = range(3) \n", 1426 | "squared = (i * i for i in vals) \n", 1427 | "negated = (-i for i in squared)\n", 1428 | "list(negated)" 1429 | ] 1430 | }, 1431 | { 1432 | "cell_type": "markdown", 1433 | "metadata": {}, 1434 | "source": [ 1435 | "## когда функции - элементы списка" 1436 | ] 1437 | }, 1438 | { 1439 | "cell_type": "code", 1440 | "execution_count": 6, 1441 | "metadata": {}, 1442 | "outputs": [ 1443 | { 1444 | "name": "stdout", 1445 | "output_type": "stream", 1446 | "text": [ 1447 | "Populating the interactive namespace from numpy and matplotlib\n" 1448 | ] 1449 | }, 1450 | { 1451 | "name": "stderr", 1452 | "output_type": "stream", 1453 | "text": [ 1454 | "/home/dash/anaconda3/lib/python3.6/site-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['f']\n", 1455 | "`%matplotlib` prevents importing * from pylab and numpy\n", 1456 | " \"\\n`%matplotlib` prevents importing * from pylab and numpy\"\n", 1457 | "/home/dash/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:13: RuntimeWarning: divide by zero encountered in log\n", 1458 | " del sys.path[0]\n" 1459 | ] 1460 | }, 1461 | { 1462 | "data": { 1463 | "text/plain": [ 1464 | "(0.0, 2.0)" 1465 | ] 1466 | }, 1467 | "execution_count": 6, 1468 | "metadata": {}, 1469 | "output_type": "execute_result" 1470 | }, 1471 | { 1472 | "data": { 1473 | "image/png": "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UYeE/tChQxk7diwLFizA6/WyZ88elixZwuzZs1FVlenTp/Ppp58CcMUVV7B27VrefPNNAoEAb7zxBuvXr0/+Z7jmmmv4wx/+wKZNm6ivr2fhwoXk5OQcV8+1o9bh888/57XXXuOZZ5457N5n9f9v545djoujOICf948h6SeyGAySksJAFlIyGc0yyWS0KAaLzaKwIoyKsjASi8GT7RL6vtOjV+r1vMPzPvd2v5/6TffX6Z7O73SW370fH1Iul2W328nlcpFmsynb7Vbi8bhucjifz1Iul2W1Wsn1epV+vy/j8ViSyaSIGKMOn9brtVgslpdYP1WHvzFCL7xjhF54xwi98I4ReuF2u0mxWJR8Pi+BQODleSaTeVyajEajcjwepdFoiKZpMplMpNfrSTqdFhGRVCol3W5XptOpaJom9XpdTqeTRKPRb83BcP7Xt4GHwwG5XA5OpxMejweVSgW32w0AYLVaMRwOH3sHgwFCoRCUUgiHwxiPx0+xarUavF4vHA4HMpkMNpuNrnIoFAqw2WxQSj2tbDYLANA0DaVSCV6vF263G8lkEovFQlc53O93VKtV+Hw+uFwuxGIxjEajp1h6r8OnSCSCZrP5Euen6hAMBqGUgt1uh9VqfZyP/X5vmF74ag567oWv5qDnXviXswTorxdms9nTe/+59vs9/H4/Wq3WY/98PkcsFoNSCoFAAJ1O5yleu92G3++HUgqJRALL5fLbczCaXwBvRxAREZkB/71PRERkEhz6REREJsGhT0REZBIc+kRERCbBoU9ERGQSHPpEREQmwaFPRERkEhz6REREJvEbY5dNPGHORisAAAAASUVORK5CYII=\n", 1474 | "text/plain": [ 1475 | "
" 1476 | ] 1477 | }, 1478 | "metadata": {}, 1479 | "output_type": "display_data" 1480 | } 1481 | ], 1482 | "source": [ 1483 | "import pandas as pd\n", 1484 | "import numpy as np\n", 1485 | "# для встроенных картинок\n", 1486 | "%pylab inline\n", 1487 | "# чуть покрасивше картинки:\n", 1488 | "plt.style.use('seaborn-dark')\n", 1489 | "import matplotlib.pyplot as plt\n", 1490 | "plt.rc('font', size=14)\n", 1491 | "\n", 1492 | "plt.figure(figsize=(7, 3))\n", 1493 | "x = np.linspace(0, 2)\n", 1494 | "for f in [np.sin, np.cos, np.exp, np.log]:\n", 1495 | " plt.plot(x, f(x), label=f.__name__)\n", 1496 | "plt.legend(loc=(1,0))\n", 1497 | "plt.grid(lw=2)\n", 1498 | "plt.xlim(x.min(), x.max())" 1499 | ] 1500 | }, 1501 | { 1502 | "cell_type": "code", 1503 | "execution_count": null, 1504 | "metadata": {}, 1505 | "outputs": [], 1506 | "source": [] 1507 | } 1508 | ], 1509 | "metadata": { 1510 | "kernelspec": { 1511 | "display_name": "Python 3", 1512 | "language": "python", 1513 | "name": "python3" 1514 | }, 1515 | "language_info": { 1516 | "codemirror_mode": { 1517 | "name": "ipython", 1518 | "version": 3 1519 | }, 1520 | "file_extension": ".py", 1521 | "mimetype": "text/x-python", 1522 | "name": "python", 1523 | "nbconvert_exporter": "python", 1524 | "pygments_lexer": "ipython3", 1525 | "version": "3.6.5" 1526 | } 1527 | }, 1528 | "nbformat": 4, 1529 | "nbformat_minor": 2 1530 | } 1531 | --------------------------------------------------------------------------------