|
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