|
4 | 4 | "cell_type": "markdown", |
5 | 5 | "metadata": {}, |
6 | 6 | "source": [ |
7 | | - "# Functional programming style" |
| 7 | + "# Requirements" |
| 8 | + ] |
| 9 | + }, |
| 10 | + { |
| 11 | + "cell_type": "code", |
| 12 | + "execution_count": 5, |
| 13 | + "metadata": {}, |
| 14 | + "outputs": [], |
| 15 | + "source": [ |
| 16 | + "from collections import Counter\n", |
| 17 | + "from functools import reduce, partial\n", |
| 18 | + "import random" |
8 | 19 | ] |
9 | 20 | }, |
10 | 21 | { |
11 | 22 | "cell_type": "markdown", |
12 | 23 | "metadata": {}, |
13 | 24 | "source": [ |
14 | | - "## Applying function to iterables" |
| 25 | + "# Applying function to iterables" |
15 | 26 | ] |
16 | 27 | }, |
17 | 28 | { |
|
35 | 46 | } |
36 | 47 | ], |
37 | 48 | "source": [ |
38 | | - "import random\n", |
39 | 49 | "l1 = list(range(10))\n", |
40 | 50 | "l2 = random.choices(range(3), k=7)\n", |
41 | 51 | "print(l1, l2)" |
42 | 52 | ] |
43 | 53 | }, |
| 54 | + { |
| 55 | + "cell_type": "markdown", |
| 56 | + "metadata": {}, |
| 57 | + "source": [ |
| 58 | + "## map" |
| 59 | + ] |
| 60 | + }, |
44 | 61 | { |
45 | 62 | "cell_type": "markdown", |
46 | 63 | "metadata": {}, |
|
84 | 101 | "Note that the result of `map` is not a list, but rather an iterator, even when it is appllied to a list." |
85 | 102 | ] |
86 | 103 | }, |
| 104 | + { |
| 105 | + "cell_type": "markdown", |
| 106 | + "metadata": {}, |
| 107 | + "source": [ |
| 108 | + "## filter" |
| 109 | + ] |
| 110 | + }, |
87 | 111 | { |
88 | 112 | "cell_type": "markdown", |
89 | 113 | "metadata": {}, |
|
115 | 139 | "cell_type": "markdown", |
116 | 140 | "metadata": {}, |
117 | 141 | "source": [ |
118 | | - "Python has quite number of reduction functions such as `sum`, `max`, and `min`, however, using the `reduce` function in `functools` we can easily write our own." |
| 142 | + "## reduce" |
119 | 143 | ] |
120 | 144 | }, |
121 | 145 | { |
122 | | - "cell_type": "code", |
123 | | - "execution_count": 4, |
| 146 | + "cell_type": "markdown", |
124 | 147 | "metadata": {}, |
125 | | - "outputs": [], |
126 | 148 | "source": [ |
127 | | - "from collections import Counter\n", |
128 | | - "from functools import reduce" |
| 149 | + "Python has quite number of reduction functions such as `sum`, `max`, and `min`, however, using the `reduce` function in `functools` we can easily write our own." |
129 | 150 | ] |
130 | 151 | }, |
131 | 152 | { |
|
208 | 229 | "cell_type": "markdown", |
209 | 230 | "metadata": {}, |
210 | 231 | "source": [ |
211 | | - "## Higher order functions" |
| 232 | + "# Higher order functions" |
212 | 233 | ] |
213 | 234 | }, |
214 | 235 | { |
|
218 | 239 | "A new function can be created out of an existing function using `partial` to fix values for one or more arguments of the original function." |
219 | 240 | ] |
220 | 241 | }, |
221 | | - { |
222 | | - "cell_type": "code", |
223 | | - "execution_count": 9, |
224 | | - "metadata": {}, |
225 | | - "outputs": [], |
226 | | - "source": [ |
227 | | - "from functools import partial" |
228 | | - ] |
229 | | - }, |
230 | 242 | { |
231 | 243 | "cell_type": "code", |
232 | 244 | "execution_count": 10, |
|
318 | 330 | "cell_type": "markdown", |
319 | 331 | "metadata": {}, |
320 | 332 | "source": [ |
321 | | - "## Coroutines" |
| 333 | + "Closures can also be used to accumulate data. The following closure will generate a function that returns a value that is incremented by one on each invocation." |
| 334 | + ] |
| 335 | + }, |
| 336 | + { |
| 337 | + "cell_type": "code", |
| 338 | + "execution_count": 10, |
| 339 | + "metadata": {}, |
| 340 | + "outputs": [], |
| 341 | + "source": [ |
| 342 | + "def create_counter():\n", |
| 343 | + " n = 0\n", |
| 344 | + " def counter():\n", |
| 345 | + " nonlocal n\n", |
| 346 | + " n += 1\n", |
| 347 | + " return n\n", |
| 348 | + " return counter" |
| 349 | + ] |
| 350 | + }, |
| 351 | + { |
| 352 | + "cell_type": "code", |
| 353 | + "execution_count": 11, |
| 354 | + "metadata": {}, |
| 355 | + "outputs": [], |
| 356 | + "source": [ |
| 357 | + "c1, c2 = create_counter(), create_counter()" |
| 358 | + ] |
| 359 | + }, |
| 360 | + { |
| 361 | + "cell_type": "code", |
| 362 | + "execution_count": 12, |
| 363 | + "metadata": {}, |
| 364 | + "outputs": [ |
| 365 | + { |
| 366 | + "name": "stdout", |
| 367 | + "output_type": "stream", |
| 368 | + "text": [ |
| 369 | + "1\n", |
| 370 | + "2\n", |
| 371 | + "3\n", |
| 372 | + "4 1\n", |
| 373 | + "5 2\n", |
| 374 | + "6 3\n" |
| 375 | + ] |
| 376 | + } |
| 377 | + ], |
| 378 | + "source": [ |
| 379 | + "for _ in range(3):\n", |
| 380 | + " print(c1())\n", |
| 381 | + "for _ in range(3):\n", |
| 382 | + " print(c1(), c2())" |
| 383 | + ] |
| 384 | + }, |
| 385 | + { |
| 386 | + "cell_type": "markdown", |
| 387 | + "metadata": {}, |
| 388 | + "source": [ |
| 389 | + "`nonlocal` ensures that the `n` in outer scope is used, i.e., the variable `n` defined in the generating function `create_counter`." |
| 390 | + ] |
| 391 | + }, |
| 392 | + { |
| 393 | + "cell_type": "markdown", |
| 394 | + "metadata": {}, |
| 395 | + "source": [ |
| 396 | + "# Coroutines" |
322 | 397 | ] |
323 | 398 | }, |
324 | 399 | { |
|
337 | 412 | }, |
338 | 413 | { |
339 | 414 | "cell_type": "code", |
340 | | - "execution_count": 16, |
| 415 | + "execution_count": 24, |
341 | 416 | "metadata": {}, |
342 | 417 | "outputs": [], |
343 | 418 | "source": [ |
344 | 419 | "def create_elevator(highest_floor):\n", |
345 | 420 | " def elevator():\n", |
346 | | - " floor = 0\n", |
| 421 | + " prev_floor = None\n", |
| 422 | + " curr_floor = 0\n", |
347 | 423 | " while True:\n", |
348 | | - " next_floor = (yield f'current floor: {floor}')\n", |
| 424 | + " next_floor = (yield f'current floor: {curr_floor}' if prev_floor is None else f'move from {prev_floor} to {curr_floor}')\n", |
349 | 425 | " if next_floor is not None:\n", |
350 | | - " if 0 <= next_floor <= highest_floor:\n", |
351 | | - " floor = next_floor\n", |
| 426 | + " if -1 <= next_floor <= highest_floor:\n", |
| 427 | + " prev_floor = curr_floor\n", |
| 428 | + " curr_floor = next_floor\n", |
352 | 429 | " else:\n", |
353 | 430 | " print(f'no such floor: {next_floor}')\n", |
354 | 431 | " else:\n", |
355 | 432 | " break\n", |
356 | 433 | " my_elevator = elevator()\n", |
357 | | - " next(my_elevator)\n", |
| 434 | + " print(next(my_elevator))\n", |
358 | 435 | " return my_elevator " |
359 | 436 | ] |
360 | 437 | }, |
361 | 438 | { |
362 | 439 | "cell_type": "code", |
363 | | - "execution_count": 17, |
| 440 | + "execution_count": 25, |
364 | 441 | "metadata": {}, |
365 | | - "outputs": [], |
| 442 | + "outputs": [ |
| 443 | + { |
| 444 | + "name": "stdout", |
| 445 | + "output_type": "stream", |
| 446 | + "text": [ |
| 447 | + "current floor: 0\n" |
| 448 | + ] |
| 449 | + } |
| 450 | + ], |
366 | 451 | "source": [ |
367 | | - "my_elevator = create_elevator(2)" |
| 452 | + "my_elevator = create_elevator(3)" |
368 | 453 | ] |
369 | 454 | }, |
370 | 455 | { |
371 | 456 | "cell_type": "code", |
372 | | - "execution_count": 18, |
| 457 | + "execution_count": 26, |
373 | 458 | "metadata": {}, |
374 | 459 | "outputs": [ |
375 | 460 | { |
376 | 461 | "name": "stdout", |
377 | 462 | "output_type": "stream", |
378 | 463 | "text": [ |
379 | | - "no such floor: -1\n", |
380 | | - "press -1: current floor: 0\n", |
381 | | - "press 1: current floor: 1\n", |
382 | | - "press 2: current floor: 2\n", |
383 | | - "no such floor: 3\n", |
384 | | - "press 3: current floor: 2\n", |
385 | | - "press 2: current floor: 2\n", |
386 | | - "press 0: current floor: 0\n", |
387 | | - "no such floor: 3\n", |
388 | | - "press 3: current floor: 0\n", |
389 | | - "press 1: current floor: 1\n", |
390 | | - "press 1: current floor: 1\n", |
391 | | - "no such floor: -1\n", |
392 | | - "press -1: current floor: 1\n" |
| 464 | + "press 0: move from 0 to 0\n", |
| 465 | + "press -1: move from 0 to -1\n", |
| 466 | + "press 1: move from -1 to 1\n", |
| 467 | + "press 3: move from 1 to 3\n", |
| 468 | + "press 3: move from 3 to 3\n", |
| 469 | + "press 1: move from 3 to 1\n", |
| 470 | + "press 0: move from 1 to 0\n", |
| 471 | + "press 3: move from 0 to 3\n", |
| 472 | + "press -1: move from 3 to -1\n", |
| 473 | + "press 0: move from -1 to 0\n" |
393 | 474 | ] |
394 | 475 | } |
395 | 476 | ], |
|
415 | 496 | "name": "python", |
416 | 497 | "nbconvert_exporter": "python", |
417 | 498 | "pygments_lexer": "ipython3", |
418 | | - "version": "3.7.5" |
| 499 | + "version": "3.9.5" |
419 | 500 | } |
420 | 501 | }, |
421 | 502 | "nbformat": 4, |
|
0 commit comments