├── .gitignore ├── README.md └── Conceptos_de_Python_para_Backend_Carolina_Gomez.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .ipynb_checkpoints 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Conceptos de Python para Backend 2 | 3 | Clase introductoria para el Bootcamp de Backend de Código Facilito 4 | 5 | Para seguir los ejemplos se pueden seguir las siguientes opciones: 6 | 7 | 1. [Instalar Python](https://www.python.org/downloads/) 8 | 9 | 2. [Instalar Anaconda y ejecutar el notebook localmente](https://docs.conda.io/projects/conda/en/latest/user-guide/install/) 10 | ``` 11 | conda create --name conceptos-python 12 | conda activate conceptos-python 13 | conda install jupyter flask 14 | jupyter notebook 15 | ``` 16 | 17 | 3. Trabajar en la version online del notebook. Para ver el notebook click en el siguiente enlace: 18 | 19 | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/carogomezt/ConceptosPythonBackend/main?labpath=Conceptos_de_Python_para_Backend_Carolina_Gomez.ipynb) 20 | 21 | ## Diapositivas: 22 | [Conceptos de Python para Backend :snake:](https://docs.google.com/presentation/d/1i-b44tgVNSNkLN9nOTuFUucoVKLgDRfAZDQcuHBUWlA/edit?usp=sharing) 23 | -------------------------------------------------------------------------------- /Conceptos_de_Python_para_Backend_Carolina_Gomez.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Conceptos de Python para Backend por Carolina Gómez" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": { 13 | "id": "gPJTJ7pLk2EW" 14 | }, 15 | "source": [ 16 | "# Decoradores\n", 17 | "\n", 18 | "Son un patrón de diseño en Python que permite agregar funcionalidades a un objeto existente (funciones) sin modificar su estructura." 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 1, 24 | "metadata": {}, 25 | "outputs": [ 26 | { 27 | "name": "stdout", 28 | "output_type": "stream", 29 | "text": [ 30 | "Collecting package metadata (current_repodata.json): done\n", 31 | "Solving environment: done\n", 32 | "\n", 33 | "## Package Plan ##\n", 34 | "\n", 35 | " environment location: /Users/carolinagomez/miniforge3/envs/conceptos-python\n", 36 | "\n", 37 | " added / updated specs:\n", 38 | " - flask\n", 39 | "\n", 40 | "\n", 41 | "The following packages will be downloaded:\n", 42 | "\n", 43 | " package | build\n", 44 | " ---------------------------|-----------------\n", 45 | " openssl-3.0.7 | h03a7124_0 2.3 MB conda-forge\n", 46 | " ------------------------------------------------------------\n", 47 | " Total: 2.3 MB\n", 48 | "\n", 49 | "The following packages will be UPDATED:\n", 50 | "\n", 51 | " openssl 3.0.5-h03a7124_2 --> 3.0.7-h03a7124_0 None\n", 52 | "\n", 53 | "\n", 54 | "\n", 55 | "Downloading and Extracting Packages\n", 56 | "openssl-3.0.7 | 2.3 MB | ##################################### | 100% \n", 57 | "Preparing transaction: done\n", 58 | "Verifying transaction: done\n", 59 | "Executing transaction: done\n", 60 | "Retrieving notices: ...working... done\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "import sys\n", 66 | "!conda install --yes --prefix {sys.prefix} flask" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 2, 72 | "metadata": { 73 | "id": "my54FYW0k5g9" 74 | }, 75 | "outputs": [], 76 | "source": [ 77 | "from functools import wraps\n", 78 | "from flask import Flask, g, request, redirect, url_for\n", 79 | "import functools\n", 80 | "\n", 81 | "\n", 82 | "app = Flask(__name__)\n", 83 | "\n", 84 | "\n", 85 | "# Decorador para requerir login\n", 86 | "def login_required(f):\n", 87 | " @wraps(f)\n", 88 | " def decorated_function(*args, **kwargs):\n", 89 | " if g.user is None:\n", 90 | " return redirect(url_for('login', next=request.url))\n", 91 | " return f(*args, **kwargs)\n", 92 | " return decorated_function\n", 93 | "\n", 94 | "\n", 95 | "@app.route(\"/secret\")\n", 96 | "@login_required\n", 97 | "def secret_page():\n", 98 | " pass" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": { 104 | "id": "whm9vmLUk1gc" 105 | }, 106 | "source": [ 107 | "# Funciones\n", 108 | "\n", 109 | "Las funciones son muy importantes en Python y estas retornan un valor de acuerdo a los argumentos que les pasamos:\n", 110 | "\n", 111 | "\n" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 3, 117 | "metadata": { 118 | "id": "PElmtE1El9_e" 119 | }, 120 | "outputs": [], 121 | "source": [ 122 | "def plus_one(number):\n", 123 | " return number + 1" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": 5, 129 | "metadata": {}, 130 | "outputs": [ 131 | { 132 | "data": { 133 | "text/plain": [ 134 | "9" 135 | ] 136 | }, 137 | "execution_count": 5, 138 | "metadata": {}, 139 | "output_type": "execute_result" 140 | } 141 | ], 142 | "source": [ 143 | "plus_one(8)" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "metadata": {}, 149 | "source": [ 150 | "## Asignando funciones a variables" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 6, 156 | "metadata": {}, 157 | "outputs": [ 158 | { 159 | "data": { 160 | "text/plain": [ 161 | "6" 162 | ] 163 | }, 164 | "execution_count": 6, 165 | "metadata": {}, 166 | "output_type": "execute_result" 167 | } 168 | ], 169 | "source": [ 170 | "def plus_one(number):\n", 171 | " return number + 1\n", 172 | "\n", 173 | "add_one = plus_one\n", 174 | "add_one(5)" 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": {}, 180 | "source": [ 181 | "## Definiendo funciones dentro de otras funciones" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 7, 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "name": "stdout", 191 | "output_type": "stream", 192 | "text": [ 193 | "Ejecutando plus_one\n", 194 | "Ejecutando add_one\n" 195 | ] 196 | }, 197 | { 198 | "data": { 199 | "text/plain": [ 200 | "5" 201 | ] 202 | }, 203 | "execution_count": 7, 204 | "metadata": {}, 205 | "output_type": "execute_result" 206 | } 207 | ], 208 | "source": [ 209 | "def plus_one(number):\n", 210 | " def add_one(number):\n", 211 | " print(\"Executing add_one\")\n", 212 | " return number + 1\n", 213 | "\n", 214 | " print(\"Executing plus_one\")\n", 215 | " result = add_one(number)\n", 216 | " return result\n", 217 | "\n", 218 | "plus_one(4)" 219 | ] 220 | }, 221 | { 222 | "cell_type": "markdown", 223 | "metadata": {}, 224 | "source": [ 225 | "## Pasando funciones como argumentos de otras funciones" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": 8, 231 | "metadata": {}, 232 | "outputs": [ 233 | { 234 | "name": "stdout", 235 | "output_type": "stream", 236 | "text": [ 237 | "Executing function_call\n", 238 | "Executing plus_one\n" 239 | ] 240 | }, 241 | { 242 | "data": { 243 | "text/plain": [ 244 | "6" 245 | ] 246 | }, 247 | "execution_count": 8, 248 | "metadata": {}, 249 | "output_type": "execute_result" 250 | } 251 | ], 252 | "source": [ 253 | "def plus_one(number):\n", 254 | " print(\"Executing plus_one\")\n", 255 | " return number + 1\n", 256 | "\n", 257 | "def function_call(function):\n", 258 | " print(\"Executing function_call\")\n", 259 | " number_to_add = 5\n", 260 | " return function(number_to_add)\n", 261 | "\n", 262 | "function_call(plus_one)" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": {}, 268 | "source": [ 269 | "## Funciones retornando otras funciones" 270 | ] 271 | }, 272 | { 273 | "cell_type": "code", 274 | "execution_count": 9, 275 | "metadata": {}, 276 | "outputs": [ 277 | { 278 | "name": "stdout", 279 | "output_type": "stream", 280 | "text": [ 281 | "Executing hello_function\n", 282 | "Executing say_hi\n" 283 | ] 284 | }, 285 | { 286 | "data": { 287 | "text/plain": [ 288 | "'Hi'" 289 | ] 290 | }, 291 | "execution_count": 9, 292 | "metadata": {}, 293 | "output_type": "execute_result" 294 | } 295 | ], 296 | "source": [ 297 | "def hello_function():\n", 298 | " def say_hi():\n", 299 | " print(\"Executing say_hi\")\n", 300 | " return \"Hi\"\n", 301 | " print(\"Executing hello_function\")\n", 302 | " return say_hi\n", 303 | "\n", 304 | "hello = hello_function()\n", 305 | "hello()" 306 | ] 307 | }, 308 | { 309 | "cell_type": "markdown", 310 | "metadata": {}, 311 | "source": [ 312 | "## Las funciones anidadas tienen acceso al las variables de la función envolvente" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": 11, 318 | "metadata": {}, 319 | "outputs": [ 320 | { 321 | "name": "stdout", 322 | "output_type": "stream", 323 | "text": [ 324 | "Some random message\n" 325 | ] 326 | } 327 | ], 328 | "source": [ 329 | "def print_message(message):\n", 330 | " \"Enclosong Function\"\n", 331 | " def message_sender():\n", 332 | " \"Nested Function\"\n", 333 | " print(message)\n", 334 | "\n", 335 | " message_sender()\n", 336 | "\n", 337 | "print_message(\"Some random message\")" 338 | ] 339 | }, 340 | { 341 | "cell_type": "markdown", 342 | "metadata": {}, 343 | "source": [ 344 | "# Creando decoradores" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": 12, 350 | "metadata": {}, 351 | "outputs": [ 352 | { 353 | "name": "stdout", 354 | "output_type": "stream", 355 | "text": [ 356 | "Something is happening before the function is called.\n", 357 | "Whee!\n", 358 | "Something is happening after the function is called.\n" 359 | ] 360 | } 361 | ], 362 | "source": [ 363 | "def my_decorator(func):\n", 364 | " def wrapper():\n", 365 | " print(\"Something is happening before the function is called.\")\n", 366 | " func()\n", 367 | " print(\"Something is happening after the function is called.\")\n", 368 | " return wrapper\n", 369 | "\n", 370 | "def say_whee():\n", 371 | " print(\"Whee!\")\n", 372 | "\n", 373 | "say_whee = my_decorator(say_whee)\n", 374 | "say_whee()" 375 | ] 376 | }, 377 | { 378 | "cell_type": "code", 379 | "execution_count": 14, 380 | "metadata": {}, 381 | "outputs": [ 382 | { 383 | "name": "stdout", 384 | "output_type": "stream", 385 | "text": [ 386 | "Something is happening before the function is called.\n", 387 | "Whee!\n", 388 | "Something is happening after the function is called.\n" 389 | ] 390 | } 391 | ], 392 | "source": [ 393 | "def my_decorator(func):\n", 394 | " def wrapper():\n", 395 | " print(\"Something is happening before the function is called.\")\n", 396 | " func()\n", 397 | " print(\"Something is happening after the function is called.\")\n", 398 | " return wrapper\n", 399 | "\n", 400 | "@my_decorator\n", 401 | "def say_whee():\n", 402 | " print(\"Whee!\")\n", 403 | " \n", 404 | "say_whee()" 405 | ] 406 | }, 407 | { 408 | "cell_type": "markdown", 409 | "metadata": {}, 410 | "source": [ 411 | "## Aplicando multiples decoradores a una misma función" 412 | ] 413 | }, 414 | { 415 | "cell_type": "code", 416 | "execution_count": 21, 417 | "metadata": {}, 418 | "outputs": [], 419 | "source": [ 420 | "def uppercase_decorator(function):\n", 421 | " def wrapper():\n", 422 | " func = function()\n", 423 | " make_uppercase = func.upper()\n", 424 | " return make_uppercase\n", 425 | "\n", 426 | " return wrapper" 427 | ] 428 | }, 429 | { 430 | "cell_type": "code", 431 | "execution_count": 22, 432 | "metadata": {}, 433 | "outputs": [], 434 | "source": [ 435 | "def split_string(function):\n", 436 | " def wrapper():\n", 437 | " func = function()\n", 438 | " splitted_string = func.split()\n", 439 | " return splitted_string\n", 440 | "\n", 441 | " return wrapper" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": 23, 447 | "metadata": {}, 448 | "outputs": [ 449 | { 450 | "data": { 451 | "text/plain": [ 452 | "['HELLO', 'THERE']" 453 | ] 454 | }, 455 | "execution_count": 23, 456 | "metadata": {}, 457 | "output_type": "execute_result" 458 | } 459 | ], 460 | "source": [ 461 | "@split_string\n", 462 | "@uppercase_decorator\n", 463 | "def say_hi():\n", 464 | " return 'hello there'\n", 465 | "say_hi()\n" 466 | ] 467 | }, 468 | { 469 | "cell_type": "markdown", 470 | "metadata": {}, 471 | "source": [ 472 | "## Decorando funciones con argumentos" 473 | ] 474 | }, 475 | { 476 | "cell_type": "code", 477 | "execution_count": 25, 478 | "metadata": {}, 479 | "outputs": [ 480 | { 481 | "name": "stdout", 482 | "output_type": "stream", 483 | "text": [ 484 | "My arguments are: Pereira, Medellín\n", 485 | "Cities I love are Pereira and Medellín\n" 486 | ] 487 | } 488 | ], 489 | "source": [ 490 | "def decorator_with_arguments(function):\n", 491 | " def wrapper_accepting_arguments(arg1, arg2):\n", 492 | " print(f\"My arguments are: {arg1}, {arg2}\")\n", 493 | " function(arg1, arg2)\n", 494 | " return wrapper_accepting_arguments\n", 495 | "\n", 496 | "\n", 497 | "@decorator_with_arguments\n", 498 | "def cities(city_one, city_two):\n", 499 | " print(f\"Cities I love are {city_one} and {city_two}\")\n", 500 | "\n", 501 | "cities(\"Pereira\", \"Medellín\")" 502 | ] 503 | }, 504 | { 505 | "cell_type": "markdown", 506 | "metadata": {}, 507 | "source": [ 508 | "### Definiendo generadores de propósito general" 509 | ] 510 | }, 511 | { 512 | "cell_type": "code", 513 | "execution_count": 31, 514 | "metadata": {}, 515 | "outputs": [ 516 | { 517 | "name": "stdout", 518 | "output_type": "stream", 519 | "text": [ 520 | "The positional arguments are (1, 2, 3)\n", 521 | "The keyword arguments are {}\n", 522 | "1 2 3\n" 523 | ] 524 | } 525 | ], 526 | "source": [ 527 | "def a_decorator_passing_arbitrary_arguments(function_to_decorate):\n", 528 | " def a_wrapper_accepting_arbitrary_arguments(*args,**kwargs):\n", 529 | " print('The positional arguments are', args)\n", 530 | " print('The keyword arguments are', kwargs)\n", 531 | " function_to_decorate(*args, **kwargs)\n", 532 | " return a_wrapper_accepting_arbitrary_arguments\n", 533 | "\n", 534 | "@a_decorator_passing_arbitrary_arguments\n", 535 | "def function_with_arguments(a, b, c):\n", 536 | " print(a, b, c)\n", 537 | "\n", 538 | "function_with_arguments(1,2,3)" 539 | ] 540 | }, 541 | { 542 | "cell_type": "code", 543 | "execution_count": 35, 544 | "metadata": {}, 545 | "outputs": [ 546 | { 547 | "name": "stdout", 548 | "output_type": "stream", 549 | "text": [ 550 | "The positional arguments are ()\n", 551 | "The keyword arguments are {'first_name': 'Derrick', 'last_name': 'Mwiti'}\n", 552 | "This has shown keyword arguments: \n", 553 | "first_name: Derrick\n", 554 | "last_name: Mwiti\n", 555 | "country: Colombia\n" 556 | ] 557 | } 558 | ], 559 | "source": [ 560 | "@a_decorator_passing_arbitrary_arguments\n", 561 | "def function_with_keyword_arguments(first_name=\"\", last_name=\"\", country=\"Colombia\"):\n", 562 | " print(f\"This has shown keyword arguments: \")\n", 563 | " print(f\"first_name: {first_name}\")\n", 564 | " print(f\"last_name: {last_name}\")\n", 565 | " print(f\"country: {country}\")\n", 566 | "\n", 567 | "function_with_keyword_arguments(first_name=\"Derrick\", last_name=\"Mwiti\")" 568 | ] 569 | }, 570 | { 571 | "cell_type": "markdown", 572 | "metadata": {}, 573 | "source": [ 574 | "### Pasando argumentos al decorador" 575 | ] 576 | }, 577 | { 578 | "cell_type": "code", 579 | "execution_count": 39, 580 | "metadata": {}, 581 | "outputs": [ 582 | { 583 | "name": "stdout", 584 | "output_type": "stream", 585 | "text": [ 586 | "The wrapper can access all the variables\n", 587 | "\t- from the decorator maker: Pandas Numpy Scikit-learn\n", 588 | "\t- from the function call: Pandas Science Tools\n", 589 | "and pass them to the decorated function\n", 590 | "This is the decorated function and it only knows about its arguments: \n", 591 | "Pandas Science Tools\n" 592 | ] 593 | } 594 | ], 595 | "source": [ 596 | "def decorator_maker_with_arguments(decorator_arg1, decorator_arg2, decorator_arg3):\n", 597 | " def decorator(func):\n", 598 | " def wrapper(function_arg1, function_arg2, function_arg3) :\n", 599 | " \"This is the wrapper function\"\n", 600 | " print(f\"The wrapper can access all the variables\\n\"\n", 601 | " f\"\\t- from the decorator maker: {decorator_arg1} {decorator_arg2} {decorator_arg3}\\n\"\n", 602 | " f\"\\t- from the function call: {function_arg1} {function_arg2} {function_arg3}\\n\"\n", 603 | " f\"and pass them to the decorated function\")\n", 604 | " return func(function_arg1, function_arg2, function_arg3)\n", 605 | "\n", 606 | " return wrapper\n", 607 | "\n", 608 | " return decorator\n", 609 | "\n", 610 | "pandas = \"Pandas\"\n", 611 | "@decorator_maker_with_arguments(pandas, \"Numpy\",\"Scikit-learn\")\n", 612 | "def decorated_function_with_arguments(function_arg1, function_arg2, function_arg3):\n", 613 | " print(\"This is the decorated function and it only knows about its arguments: \")\n", 614 | " print(f\"{function_arg1} {function_arg2} {function_arg3}\")\n", 615 | "\n", 616 | "decorated_function_with_arguments(pandas, \"Science\", \"Tools\")" 617 | ] 618 | }, 619 | { 620 | "cell_type": "markdown", 621 | "metadata": {}, 622 | "source": [ 623 | "### Debugueando decoradores" 624 | ] 625 | }, 626 | { 627 | "cell_type": "code", 628 | "execution_count": 40, 629 | "metadata": {}, 630 | "outputs": [ 631 | { 632 | "data": { 633 | "text/plain": [ 634 | "'wrapper'" 635 | ] 636 | }, 637 | "execution_count": 40, 638 | "metadata": {}, 639 | "output_type": "execute_result" 640 | } 641 | ], 642 | "source": [ 643 | "decorated_function_with_arguments.__name__\n" 644 | ] 645 | }, 646 | { 647 | "cell_type": "code", 648 | "execution_count": 41, 649 | "metadata": {}, 650 | "outputs": [ 651 | { 652 | "data": { 653 | "text/plain": [ 654 | "'This is the wrapper function'" 655 | ] 656 | }, 657 | "execution_count": 41, 658 | "metadata": {}, 659 | "output_type": "execute_result" 660 | } 661 | ], 662 | "source": [ 663 | "decorated_function_with_arguments.__doc__\n" 664 | ] 665 | }, 666 | { 667 | "cell_type": "code", 668 | "execution_count": 42, 669 | "metadata": {}, 670 | "outputs": [], 671 | "source": [ 672 | "import functools\n", 673 | "\n", 674 | "def uppercase_decorator(func):\n", 675 | " @functools.wraps(func)\n", 676 | " def wrapper():\n", 677 | " return func().upper()\n", 678 | " return wrapper" 679 | ] 680 | }, 681 | { 682 | "cell_type": "code", 683 | "execution_count": 43, 684 | "metadata": {}, 685 | "outputs": [ 686 | { 687 | "data": { 688 | "text/plain": [ 689 | "'HELLO THERE'" 690 | ] 691 | }, 692 | "execution_count": 43, 693 | "metadata": {}, 694 | "output_type": "execute_result" 695 | } 696 | ], 697 | "source": [ 698 | "@uppercase_decorator\n", 699 | "def say_hi():\n", 700 | " \"This will say hi\"\n", 701 | " return 'hello there'\n", 702 | "\n", 703 | "say_hi()" 704 | ] 705 | }, 706 | { 707 | "cell_type": "code", 708 | "execution_count": 44, 709 | "metadata": {}, 710 | "outputs": [ 711 | { 712 | "data": { 713 | "text/plain": [ 714 | "'say_hi'" 715 | ] 716 | }, 717 | "execution_count": 44, 718 | "metadata": {}, 719 | "output_type": "execute_result" 720 | } 721 | ], 722 | "source": [ 723 | "say_hi.__name__" 724 | ] 725 | }, 726 | { 727 | "cell_type": "code", 728 | "execution_count": 45, 729 | "metadata": {}, 730 | "outputs": [ 731 | { 732 | "data": { 733 | "text/plain": [ 734 | "'This will say hi'" 735 | ] 736 | }, 737 | "execution_count": 45, 738 | "metadata": {}, 739 | "output_type": "execute_result" 740 | } 741 | ], 742 | "source": [ 743 | "say_hi.__doc__" 744 | ] 745 | }, 746 | { 747 | "cell_type": "markdown", 748 | "metadata": {}, 749 | "source": [ 750 | "# Funciones Lambda\n" 751 | ] 752 | }, 753 | { 754 | "cell_type": "code", 755 | "execution_count": 47, 756 | "metadata": {}, 757 | "outputs": [], 758 | "source": [ 759 | "cuadrado = lambda x: x ** 2" 760 | ] 761 | }, 762 | { 763 | "cell_type": "code", 764 | "execution_count": 48, 765 | "metadata": {}, 766 | "outputs": [ 767 | { 768 | "name": "stdout", 769 | "output_type": "stream", 770 | "text": [ 771 | "16\n" 772 | ] 773 | } 774 | ], 775 | "source": [ 776 | "print(cuadrado(4))" 777 | ] 778 | }, 779 | { 780 | "cell_type": "markdown", 781 | "metadata": {}, 782 | "source": [ 783 | "### map()\n", 784 | "La función map() en Python aplica una función a cada uno de los elementos de una lista." 785 | ] 786 | }, 787 | { 788 | "cell_type": "code", 789 | "execution_count": 49, 790 | "metadata": {}, 791 | "outputs": [ 792 | { 793 | "name": "stdout", 794 | "output_type": "stream", 795 | "text": [ 796 | "[1, 4, 16, 49]\n" 797 | ] 798 | }, 799 | { 800 | "data": { 801 | "text/plain": [ 802 | "[1, 4, 16, 49]" 803 | ] 804 | }, 805 | "execution_count": 49, 806 | "metadata": {}, 807 | "output_type": "execute_result" 808 | } 809 | ], 810 | "source": [ 811 | "enteros = [1, 2, 4, 7]\n", 812 | "cuadrados = []\n", 813 | "for e in enteros:\n", 814 | " cuadrados.append(e ** 2)\n", 815 | " \n", 816 | "print(cuadrados)\n", 817 | "[1, 4, 16, 49]" 818 | ] 819 | }, 820 | { 821 | "cell_type": "code", 822 | "execution_count": 53, 823 | "metadata": {}, 824 | "outputs": [ 825 | { 826 | "name": "stdout", 827 | "output_type": "stream", 828 | "text": [ 829 | "[1, 4, 16, 49]\n" 830 | ] 831 | } 832 | ], 833 | "source": [ 834 | "enteros = [1, 2, 4, 7]\n", 835 | "cuadrados = list(map(lambda x : x ** 2, enteros))\n", 836 | "print(cuadrados)" 837 | ] 838 | }, 839 | { 840 | "cell_type": "markdown", 841 | "metadata": {}, 842 | "source": [ 843 | "### filter()\n", 844 | "La función filter() filtra una lista de elementos para los que una función devuelve True.\n" 845 | ] 846 | }, 847 | { 848 | "cell_type": "code", 849 | "execution_count": 54, 850 | "metadata": {}, 851 | "outputs": [ 852 | { 853 | "name": "stdout", 854 | "output_type": "stream", 855 | "text": [ 856 | "Pares-> [2, 4, 6, 8]\n" 857 | ] 858 | } 859 | ], 860 | "source": [ 861 | "valores = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n", 862 | "pares = []\n", 863 | "for valor in valores:\n", 864 | " if valor % 2 == 0:\n", 865 | " pares.append(valor)\n", 866 | "print(\"Pares-> \", pares)" 867 | ] 868 | }, 869 | { 870 | "cell_type": "code", 871 | "execution_count": 55, 872 | "metadata": {}, 873 | "outputs": [ 874 | { 875 | "name": "stdout", 876 | "output_type": "stream", 877 | "text": [ 878 | "Pares-> [2, 4, 6, 8]\n" 879 | ] 880 | } 881 | ], 882 | "source": [ 883 | "valores = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n", 884 | "pares = list(filter(lambda x : x % 2 == 0, valores))\n", 885 | "print(\"Pares-> \", pares)" 886 | ] 887 | }, 888 | { 889 | "cell_type": "markdown", 890 | "metadata": {}, 891 | "source": [ 892 | "### reduce()\n", 893 | "Esta función se utiliza principalmente para llevar a cabo un cálculo acumulativo sobre una lista de valores y devolver el resultado." 894 | ] 895 | }, 896 | { 897 | "cell_type": "code", 898 | "execution_count": 56, 899 | "metadata": {}, 900 | "outputs": [ 901 | { 902 | "name": "stdout", 903 | "output_type": "stream", 904 | "text": [ 905 | "21\n" 906 | ] 907 | } 908 | ], 909 | "source": [ 910 | "valores = [2, 4, 6, 5, 4]\n", 911 | "suma = 0\n", 912 | "for el in valores:\n", 913 | " suma += el\n", 914 | "print(suma)" 915 | ] 916 | }, 917 | { 918 | "cell_type": "code", 919 | "execution_count": 57, 920 | "metadata": {}, 921 | "outputs": [ 922 | { 923 | "name": "stdout", 924 | "output_type": "stream", 925 | "text": [ 926 | "21\n" 927 | ] 928 | } 929 | ], 930 | "source": [ 931 | "from functools import reduce\n", 932 | "suma = reduce(lambda x, y: x + y, valores)\n", 933 | "print(suma)" 934 | ] 935 | }, 936 | { 937 | "cell_type": "markdown", 938 | "metadata": {}, 939 | "source": [ 940 | "### sorted()\n", 941 | "Esta función ordena una lista en forma lexicográfica." 942 | ] 943 | }, 944 | { 945 | "cell_type": "code", 946 | "execution_count": 58, 947 | "metadata": {}, 948 | "outputs": [ 949 | { 950 | "name": "stdout", 951 | "output_type": "stream", 952 | "text": [ 953 | "['id1', 'id100', 'id2', 'id22', 'id3', 'id30']\n" 954 | ] 955 | } 956 | ], 957 | "source": [ 958 | "ids = ['id1', 'id2', 'id30', 'id3', 'id22', 'id100']\n", 959 | "print(sorted(ids)) # Lexicographic sort" 960 | ] 961 | }, 962 | { 963 | "cell_type": "code", 964 | "execution_count": 59, 965 | "metadata": {}, 966 | "outputs": [ 967 | { 968 | "name": "stdout", 969 | "output_type": "stream", 970 | "text": [ 971 | "['id1', 'id2', 'id3', 'id22', 'id30', 'id100']\n" 972 | ] 973 | } 974 | ], 975 | "source": [ 976 | "sorted_ids = sorted(ids, key=lambda x: int(x[2:])) # Integer sort\n", 977 | "print(sorted_ids)\n" 978 | ] 979 | }, 980 | { 981 | "cell_type": "markdown", 982 | "metadata": {}, 983 | "source": [ 984 | "# Properties\n" 985 | ] 986 | }, 987 | { 988 | "cell_type": "code", 989 | "execution_count": 60, 990 | "metadata": {}, 991 | "outputs": [], 992 | "source": [ 993 | "class Point:\n", 994 | " def __init__(self, x, y):\n", 995 | " self._x = x\n", 996 | " self._y = y\n", 997 | "\n", 998 | " def get_x(self):\n", 999 | " return self._x\n", 1000 | "\n", 1001 | " def set_x(self, value):\n", 1002 | " self._x = value\n", 1003 | "\n", 1004 | " def get_y(self):\n", 1005 | " return self._y\n", 1006 | "\n", 1007 | " def set_y(self, value):\n", 1008 | " self._y = value" 1009 | ] 1010 | }, 1011 | { 1012 | "cell_type": "code", 1013 | "execution_count": 61, 1014 | "metadata": {}, 1015 | "outputs": [], 1016 | "source": [ 1017 | "point = Point(5, 9)" 1018 | ] 1019 | }, 1020 | { 1021 | "cell_type": "code", 1022 | "execution_count": 62, 1023 | "metadata": {}, 1024 | "outputs": [ 1025 | { 1026 | "data": { 1027 | "text/plain": [ 1028 | "5" 1029 | ] 1030 | }, 1031 | "execution_count": 62, 1032 | "metadata": {}, 1033 | "output_type": "execute_result" 1034 | } 1035 | ], 1036 | "source": [ 1037 | "point.get_x()" 1038 | ] 1039 | }, 1040 | { 1041 | "cell_type": "code", 1042 | "execution_count": 63, 1043 | "metadata": {}, 1044 | "outputs": [ 1045 | { 1046 | "data": { 1047 | "text/plain": [ 1048 | "9" 1049 | ] 1050 | }, 1051 | "execution_count": 63, 1052 | "metadata": {}, 1053 | "output_type": "execute_result" 1054 | } 1055 | ], 1056 | "source": [ 1057 | "point.get_y()" 1058 | ] 1059 | }, 1060 | { 1061 | "cell_type": "code", 1062 | "execution_count": 64, 1063 | "metadata": {}, 1064 | "outputs": [], 1065 | "source": [ 1066 | "point.set_x(8)" 1067 | ] 1068 | }, 1069 | { 1070 | "cell_type": "code", 1071 | "execution_count": 65, 1072 | "metadata": {}, 1073 | "outputs": [ 1074 | { 1075 | "data": { 1076 | "text/plain": [ 1077 | "8" 1078 | ] 1079 | }, 1080 | "execution_count": 65, 1081 | "metadata": {}, 1082 | "output_type": "execute_result" 1083 | } 1084 | ], 1085 | "source": [ 1086 | "point.get_x()" 1087 | ] 1088 | }, 1089 | { 1090 | "cell_type": "code", 1091 | "execution_count": 66, 1092 | "metadata": {}, 1093 | "outputs": [ 1094 | { 1095 | "data": { 1096 | "text/plain": [ 1097 | "8" 1098 | ] 1099 | }, 1100 | "execution_count": 66, 1101 | "metadata": {}, 1102 | "output_type": "execute_result" 1103 | } 1104 | ], 1105 | "source": [ 1106 | "point._x" 1107 | ] 1108 | }, 1109 | { 1110 | "cell_type": "markdown", 1111 | "metadata": {}, 1112 | "source": [ 1113 | "## ¿Cómo crear properties?" 1114 | ] 1115 | }, 1116 | { 1117 | "cell_type": "code", 1118 | "execution_count": 67, 1119 | "metadata": {}, 1120 | "outputs": [], 1121 | "source": [ 1122 | "class Circle:\n", 1123 | " def __init__(self, radius):\n", 1124 | " self._radius = radius\n", 1125 | "\n", 1126 | " def _get_radius(self):\n", 1127 | " print(\"Get radius\")\n", 1128 | " return self._radius\n", 1129 | "\n", 1130 | " def _set_radius(self, value):\n", 1131 | " print(\"Set radius\")\n", 1132 | " self._radius = value\n", 1133 | "\n", 1134 | " def _del_radius(self):\n", 1135 | " print(\"Delete radius\")\n", 1136 | " del self._radius\n", 1137 | "\n", 1138 | " radius = property(\n", 1139 | " fget=_get_radius,\n", 1140 | " fset=_set_radius,\n", 1141 | " fdel=_del_radius,\n", 1142 | " doc=\"The radius property.\"\n", 1143 | " )" 1144 | ] 1145 | }, 1146 | { 1147 | "cell_type": "code", 1148 | "execution_count": 68, 1149 | "metadata": {}, 1150 | "outputs": [], 1151 | "source": [ 1152 | "circle = Circle(42.0)" 1153 | ] 1154 | }, 1155 | { 1156 | "cell_type": "code", 1157 | "execution_count": 69, 1158 | "metadata": {}, 1159 | "outputs": [ 1160 | { 1161 | "name": "stdout", 1162 | "output_type": "stream", 1163 | "text": [ 1164 | "Get radius\n" 1165 | ] 1166 | }, 1167 | { 1168 | "data": { 1169 | "text/plain": [ 1170 | "42.0" 1171 | ] 1172 | }, 1173 | "execution_count": 69, 1174 | "metadata": {}, 1175 | "output_type": "execute_result" 1176 | } 1177 | ], 1178 | "source": [ 1179 | "circle.radius" 1180 | ] 1181 | }, 1182 | { 1183 | "cell_type": "code", 1184 | "execution_count": 70, 1185 | "metadata": {}, 1186 | "outputs": [ 1187 | { 1188 | "name": "stdout", 1189 | "output_type": "stream", 1190 | "text": [ 1191 | "Set radius\n" 1192 | ] 1193 | } 1194 | ], 1195 | "source": [ 1196 | "circle.radius = 50" 1197 | ] 1198 | }, 1199 | { 1200 | "cell_type": "code", 1201 | "execution_count": 71, 1202 | "metadata": {}, 1203 | "outputs": [ 1204 | { 1205 | "name": "stdout", 1206 | "output_type": "stream", 1207 | "text": [ 1208 | "Get radius\n" 1209 | ] 1210 | }, 1211 | { 1212 | "data": { 1213 | "text/plain": [ 1214 | "50" 1215 | ] 1216 | }, 1217 | "execution_count": 71, 1218 | "metadata": {}, 1219 | "output_type": "execute_result" 1220 | } 1221 | ], 1222 | "source": [ 1223 | "circle.radius" 1224 | ] 1225 | }, 1226 | { 1227 | "cell_type": "code", 1228 | "execution_count": 72, 1229 | "metadata": {}, 1230 | "outputs": [ 1231 | { 1232 | "name": "stdout", 1233 | "output_type": "stream", 1234 | "text": [ 1235 | "Delete radius\n" 1236 | ] 1237 | } 1238 | ], 1239 | "source": [ 1240 | "del circle.radius" 1241 | ] 1242 | }, 1243 | { 1244 | "cell_type": "code", 1245 | "execution_count": 73, 1246 | "metadata": {}, 1247 | "outputs": [ 1248 | { 1249 | "ename": "NameError", 1250 | "evalue": "name 'cicle' is not defined", 1251 | "output_type": "error", 1252 | "traceback": [ 1253 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1254 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 1255 | "Cell \u001b[0;32mIn [73], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mcicle\u001b[49m\u001b[38;5;241m.\u001b[39mradius\n", 1256 | "\u001b[0;31mNameError\u001b[0m: name 'cicle' is not defined" 1257 | ] 1258 | } 1259 | ], 1260 | "source": [ 1261 | "cicle.radius" 1262 | ] 1263 | }, 1264 | { 1265 | "cell_type": "markdown", 1266 | "metadata": {}, 1267 | "source": [ 1268 | "## Usando property() como decorador" 1269 | ] 1270 | }, 1271 | { 1272 | "cell_type": "code", 1273 | "execution_count": 74, 1274 | "metadata": {}, 1275 | "outputs": [], 1276 | "source": [ 1277 | "class Circle:\n", 1278 | " def __init__(self, radius):\n", 1279 | " self._radius = radius\n", 1280 | "\n", 1281 | " @property\n", 1282 | " def radius(self):\n", 1283 | " \"\"\"The radius property.\"\"\"\n", 1284 | " print(\"Get radius\")\n", 1285 | " return self._radius\n", 1286 | "\n", 1287 | " @radius.setter\n", 1288 | " def radius(self, value):\n", 1289 | " print(\"Set radius\")\n", 1290 | " self._radius = value\n", 1291 | "\n", 1292 | " @radius.deleter\n", 1293 | " def radius(self):\n", 1294 | " print(\"Delete radius\")\n", 1295 | " del self._radius" 1296 | ] 1297 | }, 1298 | { 1299 | "cell_type": "code", 1300 | "execution_count": 75, 1301 | "metadata": {}, 1302 | "outputs": [], 1303 | "source": [ 1304 | "circle = Circle(42.0)" 1305 | ] 1306 | }, 1307 | { 1308 | "cell_type": "code", 1309 | "execution_count": 76, 1310 | "metadata": {}, 1311 | "outputs": [ 1312 | { 1313 | "name": "stdout", 1314 | "output_type": "stream", 1315 | "text": [ 1316 | "Get radius\n" 1317 | ] 1318 | }, 1319 | { 1320 | "data": { 1321 | "text/plain": [ 1322 | "42.0" 1323 | ] 1324 | }, 1325 | "execution_count": 76, 1326 | "metadata": {}, 1327 | "output_type": "execute_result" 1328 | } 1329 | ], 1330 | "source": [ 1331 | "circle.radius" 1332 | ] 1333 | }, 1334 | { 1335 | "cell_type": "code", 1336 | "execution_count": 77, 1337 | "metadata": {}, 1338 | "outputs": [ 1339 | { 1340 | "name": "stdout", 1341 | "output_type": "stream", 1342 | "text": [ 1343 | "Set radius\n" 1344 | ] 1345 | } 1346 | ], 1347 | "source": [ 1348 | "circle.radius = 50" 1349 | ] 1350 | }, 1351 | { 1352 | "cell_type": "code", 1353 | "execution_count": 78, 1354 | "metadata": {}, 1355 | "outputs": [ 1356 | { 1357 | "name": "stdout", 1358 | "output_type": "stream", 1359 | "text": [ 1360 | "Get radius\n" 1361 | ] 1362 | }, 1363 | { 1364 | "data": { 1365 | "text/plain": [ 1366 | "50" 1367 | ] 1368 | }, 1369 | "execution_count": 78, 1370 | "metadata": {}, 1371 | "output_type": "execute_result" 1372 | } 1373 | ], 1374 | "source": [ 1375 | "circle.radius" 1376 | ] 1377 | }, 1378 | { 1379 | "cell_type": "code", 1380 | "execution_count": 79, 1381 | "metadata": {}, 1382 | "outputs": [ 1383 | { 1384 | "name": "stdout", 1385 | "output_type": "stream", 1386 | "text": [ 1387 | "Delete radius\n" 1388 | ] 1389 | } 1390 | ], 1391 | "source": [ 1392 | "del circle.radius" 1393 | ] 1394 | }, 1395 | { 1396 | "cell_type": "code", 1397 | "execution_count": 80, 1398 | "metadata": {}, 1399 | "outputs": [ 1400 | { 1401 | "ename": "NameError", 1402 | "evalue": "name 'cicle' is not defined", 1403 | "output_type": "error", 1404 | "traceback": [ 1405 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1406 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 1407 | "Cell \u001b[0;32mIn [80], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mcicle\u001b[49m\u001b[38;5;241m.\u001b[39mradius\n", 1408 | "\u001b[0;31mNameError\u001b[0m: name 'cicle' is not defined" 1409 | ] 1410 | } 1411 | ], 1412 | "source": [ 1413 | "cicle.radius" 1414 | ] 1415 | }, 1416 | { 1417 | "cell_type": "markdown", 1418 | "metadata": {}, 1419 | "source": [ 1420 | "## Creando atributos de solo lectura" 1421 | ] 1422 | }, 1423 | { 1424 | "cell_type": "code", 1425 | "execution_count": 81, 1426 | "metadata": {}, 1427 | "outputs": [], 1428 | "source": [ 1429 | "class Point:\n", 1430 | " def __init__(self, x, y):\n", 1431 | " self._x = x\n", 1432 | " self._y = y\n", 1433 | "\n", 1434 | " @property\n", 1435 | " def x(self):\n", 1436 | " return self._x\n", 1437 | "\n", 1438 | " @property\n", 1439 | " def y(self):\n", 1440 | " return self._y" 1441 | ] 1442 | }, 1443 | { 1444 | "cell_type": "code", 1445 | "execution_count": 82, 1446 | "metadata": {}, 1447 | "outputs": [], 1448 | "source": [ 1449 | "point = Point(12, 5)" 1450 | ] 1451 | }, 1452 | { 1453 | "cell_type": "code", 1454 | "execution_count": 83, 1455 | "metadata": {}, 1456 | "outputs": [ 1457 | { 1458 | "data": { 1459 | "text/plain": [ 1460 | "12" 1461 | ] 1462 | }, 1463 | "execution_count": 83, 1464 | "metadata": {}, 1465 | "output_type": "execute_result" 1466 | } 1467 | ], 1468 | "source": [ 1469 | "point.x" 1470 | ] 1471 | }, 1472 | { 1473 | "cell_type": "code", 1474 | "execution_count": 84, 1475 | "metadata": {}, 1476 | "outputs": [ 1477 | { 1478 | "data": { 1479 | "text/plain": [ 1480 | "5" 1481 | ] 1482 | }, 1483 | "execution_count": 84, 1484 | "metadata": {}, 1485 | "output_type": "execute_result" 1486 | } 1487 | ], 1488 | "source": [ 1489 | "point.y" 1490 | ] 1491 | }, 1492 | { 1493 | "cell_type": "code", 1494 | "execution_count": 85, 1495 | "metadata": {}, 1496 | "outputs": [ 1497 | { 1498 | "ename": "AttributeError", 1499 | "evalue": "can't set attribute", 1500 | "output_type": "error", 1501 | "traceback": [ 1502 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1503 | "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", 1504 | "Cell \u001b[0;32mIn [85], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mpoint\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mx\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m10\u001b[39m\n", 1505 | "\u001b[0;31mAttributeError\u001b[0m: can't set attribute" 1506 | ] 1507 | } 1508 | ], 1509 | "source": [ 1510 | "point.x = 10" 1511 | ] 1512 | }, 1513 | { 1514 | "cell_type": "markdown", 1515 | "metadata": {}, 1516 | "source": [ 1517 | "## Creando atributos de solo escritura" 1518 | ] 1519 | }, 1520 | { 1521 | "cell_type": "code", 1522 | "execution_count": 88, 1523 | "metadata": {}, 1524 | "outputs": [], 1525 | "source": [ 1526 | "import hashlib\n", 1527 | "import os\n", 1528 | "\n", 1529 | "class User:\n", 1530 | " def __init__(self, name, password):\n", 1531 | " self.name = name\n", 1532 | " self.password = password\n", 1533 | "\n", 1534 | " @property\n", 1535 | " def password(self):\n", 1536 | " raise AttributeError(\"Password is write-only\")\n", 1537 | "\n", 1538 | " @password.setter\n", 1539 | " def password(self, plaintext):\n", 1540 | " salt = os.urandom(32)\n", 1541 | " self._hashed_password = hashlib.pbkdf2_hmac(\n", 1542 | " \"sha256\", plaintext.encode(\"utf-8\"), salt, 100_000\n", 1543 | " )" 1544 | ] 1545 | }, 1546 | { 1547 | "cell_type": "code", 1548 | "execution_count": 89, 1549 | "metadata": {}, 1550 | "outputs": [], 1551 | "source": [ 1552 | "user = User(\"Carolina\", \"secure_password\")" 1553 | ] 1554 | }, 1555 | { 1556 | "cell_type": "code", 1557 | "execution_count": 90, 1558 | "metadata": {}, 1559 | "outputs": [ 1560 | { 1561 | "ename": "AttributeError", 1562 | "evalue": "Password is write-only", 1563 | "output_type": "error", 1564 | "traceback": [ 1565 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1566 | "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", 1567 | "Cell \u001b[0;32mIn [90], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43muser\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpassword\u001b[49m\n", 1568 | "Cell \u001b[0;32mIn [88], line 11\u001b[0m, in \u001b[0;36mUser.password\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[38;5;129m@property\u001b[39m\n\u001b[1;32m 10\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mpassword\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m---> 11\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mAttributeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mPassword is write-only\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", 1569 | "\u001b[0;31mAttributeError\u001b[0m: Password is write-only" 1570 | ] 1571 | } 1572 | ], 1573 | "source": [ 1574 | "user.password" 1575 | ] 1576 | }, 1577 | { 1578 | "cell_type": "code", 1579 | "execution_count": 91, 1580 | "metadata": {}, 1581 | "outputs": [], 1582 | "source": [ 1583 | "user.password = \"another_Secure_password\"" 1584 | ] 1585 | }, 1586 | { 1587 | "cell_type": "markdown", 1588 | "metadata": {}, 1589 | "source": [ 1590 | "## Algunos casos de uso de las properties" 1591 | ] 1592 | }, 1593 | { 1594 | "cell_type": "markdown", 1595 | "metadata": {}, 1596 | "source": [ 1597 | "### Validando atributos" 1598 | ] 1599 | }, 1600 | { 1601 | "cell_type": "code", 1602 | "execution_count": 98, 1603 | "metadata": {}, 1604 | "outputs": [], 1605 | "source": [ 1606 | "class Point:\n", 1607 | " def __init__(self, x, y):\n", 1608 | " self.x = x\n", 1609 | " self.y = y\n", 1610 | "\n", 1611 | " @property\n", 1612 | " def x(self):\n", 1613 | " return self._x\n", 1614 | "\n", 1615 | " @x.setter\n", 1616 | " def x(self, value):\n", 1617 | " try:\n", 1618 | " self._x = float(value)\n", 1619 | " print(\"Validated!\")\n", 1620 | " except ValueError:\n", 1621 | " raise ValueError('\"x\" must be a number') from None\n", 1622 | "\n", 1623 | " @property\n", 1624 | " def y(self):\n", 1625 | " return self._y\n", 1626 | "\n", 1627 | " @y.setter\n", 1628 | " def y(self, value):\n", 1629 | " try:\n", 1630 | " self._y = float(value)\n", 1631 | " print(\"Validated!\")\n", 1632 | " except ValueError:\n", 1633 | " raise ValueError('\"y\" must be a number') from None" 1634 | ] 1635 | }, 1636 | { 1637 | "cell_type": "code", 1638 | "execution_count": 99, 1639 | "metadata": {}, 1640 | "outputs": [ 1641 | { 1642 | "name": "stdout", 1643 | "output_type": "stream", 1644 | "text": [ 1645 | "Validated!\n", 1646 | "Validated!\n" 1647 | ] 1648 | } 1649 | ], 1650 | "source": [ 1651 | "point = Point(2, 5)" 1652 | ] 1653 | }, 1654 | { 1655 | "cell_type": "code", 1656 | "execution_count": 100, 1657 | "metadata": {}, 1658 | "outputs": [ 1659 | { 1660 | "ename": "ValueError", 1661 | "evalue": "\"x\" must be a number", 1662 | "output_type": "error", 1663 | "traceback": [ 1664 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1665 | "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", 1666 | "Cell \u001b[0;32mIn [100], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mpoint\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mx\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhola\u001b[39m\u001b[38;5;124m\"\u001b[39m\n", 1667 | "Cell \u001b[0;32mIn [98], line 16\u001b[0m, in \u001b[0;36mPoint.x\u001b[0;34m(self, value)\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mValidated!\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 15\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m:\n\u001b[0;32m---> 16\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mx\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m must be a number\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28mNone\u001b[39m\n", 1668 | "\u001b[0;31mValueError\u001b[0m: \"x\" must be a number" 1669 | ] 1670 | } 1671 | ], 1672 | "source": [ 1673 | "point.x = \"hola\"" 1674 | ] 1675 | }, 1676 | { 1677 | "cell_type": "markdown", 1678 | "metadata": {}, 1679 | "source": [ 1680 | "### Para agregar atributos que requieren algún calculo" 1681 | ] 1682 | }, 1683 | { 1684 | "cell_type": "code", 1685 | "execution_count": 101, 1686 | "metadata": {}, 1687 | "outputs": [], 1688 | "source": [ 1689 | "class Rectangle:\n", 1690 | " def __init__(self, width, height):\n", 1691 | " self.width = width\n", 1692 | " self.height = height\n", 1693 | "\n", 1694 | " @property\n", 1695 | " def area(self):\n", 1696 | " return self.width * self.height" 1697 | ] 1698 | }, 1699 | { 1700 | "cell_type": "code", 1701 | "execution_count": 102, 1702 | "metadata": {}, 1703 | "outputs": [], 1704 | "source": [ 1705 | "rectangle = Rectangle(30, 50)" 1706 | ] 1707 | }, 1708 | { 1709 | "cell_type": "code", 1710 | "execution_count": 103, 1711 | "metadata": {}, 1712 | "outputs": [ 1713 | { 1714 | "data": { 1715 | "text/plain": [ 1716 | "1500" 1717 | ] 1718 | }, 1719 | "execution_count": 103, 1720 | "metadata": {}, 1721 | "output_type": "execute_result" 1722 | } 1723 | ], 1724 | "source": [ 1725 | "rectangle.area" 1726 | ] 1727 | }, 1728 | { 1729 | "cell_type": "markdown", 1730 | "metadata": {}, 1731 | "source": [ 1732 | "# Métodos de instancia, métodos de clase y métodos estáticos\n" 1733 | ] 1734 | }, 1735 | { 1736 | "cell_type": "code", 1737 | "execution_count": 139, 1738 | "metadata": {}, 1739 | "outputs": [], 1740 | "source": [ 1741 | "class MyClass:\n", 1742 | " def method(self):\n", 1743 | " \"\"\" Instance method \"\"\"\n", 1744 | " return 'instance method called', self\n", 1745 | "\n", 1746 | " @classmethod\n", 1747 | " def class_method(cls):\n", 1748 | " \"\"\" Class method \"\"\"\n", 1749 | " return 'class method called', cls\n", 1750 | "\n", 1751 | " @staticmethod\n", 1752 | " def static_method():\n", 1753 | " \"\"\" Static method \"\"\"\n", 1754 | " return 'static method called'" 1755 | ] 1756 | }, 1757 | { 1758 | "cell_type": "code", 1759 | "execution_count": 140, 1760 | "metadata": {}, 1761 | "outputs": [], 1762 | "source": [ 1763 | "obj = MyClass()" 1764 | ] 1765 | }, 1766 | { 1767 | "cell_type": "code", 1768 | "execution_count": 141, 1769 | "metadata": {}, 1770 | "outputs": [ 1771 | { 1772 | "data": { 1773 | "text/plain": [ 1774 | "('instance method called', <__main__.MyClass at 0x10964c9a0>)" 1775 | ] 1776 | }, 1777 | "execution_count": 141, 1778 | "metadata": {}, 1779 | "output_type": "execute_result" 1780 | } 1781 | ], 1782 | "source": [ 1783 | "obj.method()" 1784 | ] 1785 | }, 1786 | { 1787 | "cell_type": "code", 1788 | "execution_count": 107, 1789 | "metadata": {}, 1790 | "outputs": [ 1791 | { 1792 | "data": { 1793 | "text/plain": [ 1794 | "('instance method called', <__main__.MyClass at 0x1089358e0>)" 1795 | ] 1796 | }, 1797 | "execution_count": 107, 1798 | "metadata": {}, 1799 | "output_type": "execute_result" 1800 | } 1801 | ], 1802 | "source": [ 1803 | "MyClass.method(obj)" 1804 | ] 1805 | }, 1806 | { 1807 | "cell_type": "code", 1808 | "execution_count": 108, 1809 | "metadata": {}, 1810 | "outputs": [ 1811 | { 1812 | "data": { 1813 | "text/plain": [ 1814 | "('class method called', __main__.MyClass)" 1815 | ] 1816 | }, 1817 | "execution_count": 108, 1818 | "metadata": {}, 1819 | "output_type": "execute_result" 1820 | } 1821 | ], 1822 | "source": [ 1823 | "obj.class_method()" 1824 | ] 1825 | }, 1826 | { 1827 | "cell_type": "code", 1828 | "execution_count": 109, 1829 | "metadata": {}, 1830 | "outputs": [ 1831 | { 1832 | "data": { 1833 | "text/plain": [ 1834 | "'static method called'" 1835 | ] 1836 | }, 1837 | "execution_count": 109, 1838 | "metadata": {}, 1839 | "output_type": "execute_result" 1840 | } 1841 | ], 1842 | "source": [ 1843 | "obj.static_method()" 1844 | ] 1845 | }, 1846 | { 1847 | "cell_type": "markdown", 1848 | "metadata": {}, 1849 | "source": [ 1850 | "### ¿Qué pasa si accedemos a los metodos sin instanciar un objeto de la clase?" 1851 | ] 1852 | }, 1853 | { 1854 | "cell_type": "code", 1855 | "execution_count": 110, 1856 | "metadata": {}, 1857 | "outputs": [ 1858 | { 1859 | "data": { 1860 | "text/plain": [ 1861 | "('class method called', __main__.MyClass)" 1862 | ] 1863 | }, 1864 | "execution_count": 110, 1865 | "metadata": {}, 1866 | "output_type": "execute_result" 1867 | } 1868 | ], 1869 | "source": [ 1870 | "MyClass.class_method()" 1871 | ] 1872 | }, 1873 | { 1874 | "cell_type": "code", 1875 | "execution_count": 111, 1876 | "metadata": {}, 1877 | "outputs": [ 1878 | { 1879 | "data": { 1880 | "text/plain": [ 1881 | "'static method called'" 1882 | ] 1883 | }, 1884 | "execution_count": 111, 1885 | "metadata": {}, 1886 | "output_type": "execute_result" 1887 | } 1888 | ], 1889 | "source": [ 1890 | "MyClass.static_method()" 1891 | ] 1892 | }, 1893 | { 1894 | "cell_type": "code", 1895 | "execution_count": 112, 1896 | "metadata": {}, 1897 | "outputs": [ 1898 | { 1899 | "ename": "TypeError", 1900 | "evalue": "method() missing 1 required positional argument: 'self'", 1901 | "output_type": "error", 1902 | "traceback": [ 1903 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1904 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 1905 | "Cell \u001b[0;32mIn [112], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mMyClass\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmethod\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", 1906 | "\u001b[0;31mTypeError\u001b[0m: method() missing 1 required positional argument: 'self'" 1907 | ] 1908 | } 1909 | ], 1910 | "source": [ 1911 | "MyClass.method()" 1912 | ] 1913 | }, 1914 | { 1915 | "cell_type": "markdown", 1916 | "metadata": {}, 1917 | "source": [ 1918 | "### Ejemplos de uso" 1919 | ] 1920 | }, 1921 | { 1922 | "cell_type": "code", 1923 | "execution_count": 115, 1924 | "metadata": {}, 1925 | "outputs": [], 1926 | "source": [ 1927 | "class Pizza:\n", 1928 | " def __init__(self, ingredients):\n", 1929 | " self.ingredients = ingredients\n", 1930 | "\n", 1931 | " def __repr__(self):\n", 1932 | " return f'Pizza({self.ingredients})'\n" 1933 | ] 1934 | }, 1935 | { 1936 | "cell_type": "code", 1937 | "execution_count": 116, 1938 | "metadata": {}, 1939 | "outputs": [], 1940 | "source": [ 1941 | "margherita = Pizza(['mozzarella', 'tomatoes'])\n", 1942 | "cheese = Pizza(['mozzarella', 'provolone', 'cheddar', 'Parmesan'])" 1943 | ] 1944 | }, 1945 | { 1946 | "cell_type": "code", 1947 | "execution_count": 117, 1948 | "metadata": {}, 1949 | "outputs": [ 1950 | { 1951 | "data": { 1952 | "text/plain": [ 1953 | "Pizza(['mozzarella', 'tomatoes'])" 1954 | ] 1955 | }, 1956 | "execution_count": 117, 1957 | "metadata": {}, 1958 | "output_type": "execute_result" 1959 | } 1960 | ], 1961 | "source": [ 1962 | "margherita" 1963 | ] 1964 | }, 1965 | { 1966 | "cell_type": "code", 1967 | "execution_count": 118, 1968 | "metadata": {}, 1969 | "outputs": [ 1970 | { 1971 | "data": { 1972 | "text/plain": [ 1973 | "Pizza(['mozzarella', 'provolone', 'cheddar', 'Parmesan'])" 1974 | ] 1975 | }, 1976 | "execution_count": 118, 1977 | "metadata": {}, 1978 | "output_type": "execute_result" 1979 | } 1980 | ], 1981 | "source": [ 1982 | "cheese" 1983 | ] 1984 | }, 1985 | { 1986 | "cell_type": "code", 1987 | "execution_count": 180, 1988 | "metadata": {}, 1989 | "outputs": [], 1990 | "source": [ 1991 | "class Pizza:\n", 1992 | " def __init__(self, ingredients):\n", 1993 | " self.ingredients = ingredients\n", 1994 | "\n", 1995 | " def __repr__(self):\n", 1996 | " return f'Pizza({self.ingredients})'\n", 1997 | " \n", 1998 | " def create_custom_pizza(self, ingredients):\n", 1999 | " self.ingredients = ingredients\n", 2000 | " return self\n", 2001 | "\n", 2002 | " @classmethod\n", 2003 | " def margherita(cls):\n", 2004 | " return cls(['mozzarella', 'tomatoes'])\n", 2005 | "\n", 2006 | " @classmethod\n", 2007 | " def cheese(cls):\n", 2008 | " return cls(['mozzarella', 'provolone', 'cheddar', 'Parmesan'])" 2009 | ] 2010 | }, 2011 | { 2012 | "cell_type": "code", 2013 | "execution_count": 184, 2014 | "metadata": {}, 2015 | "outputs": [ 2016 | { 2017 | "data": { 2018 | "text/plain": [ 2019 | "Pizza(['mozzarella', 'tomatoes'])" 2020 | ] 2021 | }, 2022 | "execution_count": 184, 2023 | "metadata": {}, 2024 | "output_type": "execute_result" 2025 | } 2026 | ], 2027 | "source": [ 2028 | "Pizza.margherita()" 2029 | ] 2030 | }, 2031 | { 2032 | "cell_type": "code", 2033 | "execution_count": 185, 2034 | "metadata": {}, 2035 | "outputs": [ 2036 | { 2037 | "data": { 2038 | "text/plain": [ 2039 | "Pizza(['mozzarella', 'provolone', 'cheddar', 'Parmesan'])" 2040 | ] 2041 | }, 2042 | "execution_count": 185, 2043 | "metadata": {}, 2044 | "output_type": "execute_result" 2045 | } 2046 | ], 2047 | "source": [ 2048 | "Pizza.cheese()" 2049 | ] 2050 | }, 2051 | { 2052 | "cell_type": "code", 2053 | "execution_count": 186, 2054 | "metadata": {}, 2055 | "outputs": [], 2056 | "source": [ 2057 | "first_pizza = Pizza([])" 2058 | ] 2059 | }, 2060 | { 2061 | "cell_type": "code", 2062 | "execution_count": 187, 2063 | "metadata": {}, 2064 | "outputs": [ 2065 | { 2066 | "data": { 2067 | "text/plain": [ 2068 | "[]" 2069 | ] 2070 | }, 2071 | "execution_count": 187, 2072 | "metadata": {}, 2073 | "output_type": "execute_result" 2074 | } 2075 | ], 2076 | "source": [ 2077 | "first_pizza.ingredients" 2078 | ] 2079 | }, 2080 | { 2081 | "cell_type": "code", 2082 | "execution_count": 188, 2083 | "metadata": {}, 2084 | "outputs": [ 2085 | { 2086 | "data": { 2087 | "text/plain": [ 2088 | "Pizza(['chicken', 'mozzarella'])" 2089 | ] 2090 | }, 2091 | "execution_count": 188, 2092 | "metadata": {}, 2093 | "output_type": "execute_result" 2094 | } 2095 | ], 2096 | "source": [ 2097 | "first_pizza.create_custom_pizza(['chicken', 'mozzarella'])" 2098 | ] 2099 | }, 2100 | { 2101 | "cell_type": "code", 2102 | "execution_count": 189, 2103 | "metadata": {}, 2104 | "outputs": [ 2105 | { 2106 | "data": { 2107 | "text/plain": [ 2108 | "Pizza(['mozzarella', 'tomatoes'])" 2109 | ] 2110 | }, 2111 | "execution_count": 189, 2112 | "metadata": {}, 2113 | "output_type": "execute_result" 2114 | } 2115 | ], 2116 | "source": [ 2117 | "first_pizza.margherita()" 2118 | ] 2119 | }, 2120 | { 2121 | "cell_type": "code", 2122 | "execution_count": 191, 2123 | "metadata": {}, 2124 | "outputs": [ 2125 | { 2126 | "data": { 2127 | "text/plain": [ 2128 | "['chicken', 'mozzarella']" 2129 | ] 2130 | }, 2131 | "execution_count": 191, 2132 | "metadata": {}, 2133 | "output_type": "execute_result" 2134 | } 2135 | ], 2136 | "source": [ 2137 | "first_pizza.ingredients" 2138 | ] 2139 | }, 2140 | { 2141 | "cell_type": "code", 2142 | "execution_count": 133, 2143 | "metadata": {}, 2144 | "outputs": [], 2145 | "source": [ 2146 | "import math\n", 2147 | "\n", 2148 | "class Pizza:\n", 2149 | " def __init__(self, radius, ingredients):\n", 2150 | " self.radius = radius\n", 2151 | " self.ingredients = ingredients\n", 2152 | "\n", 2153 | " def __repr__(self):\n", 2154 | " return (f'Pizza({self.radius}, '\n", 2155 | " f'{self.ingredients})')\n", 2156 | "\n", 2157 | " def area(self):\n", 2158 | " return self.circle_area(self.radius)\n", 2159 | "\n", 2160 | " @staticmethod\n", 2161 | " def circle_area(r):\n", 2162 | " return r ** 2 * math.pi" 2163 | ] 2164 | }, 2165 | { 2166 | "cell_type": "code", 2167 | "execution_count": 134, 2168 | "metadata": {}, 2169 | "outputs": [], 2170 | "source": [ 2171 | "p = Pizza(4, ['mozzarella', 'tomatoes'])" 2172 | ] 2173 | }, 2174 | { 2175 | "cell_type": "code", 2176 | "execution_count": 135, 2177 | "metadata": {}, 2178 | "outputs": [ 2179 | { 2180 | "data": { 2181 | "text/plain": [ 2182 | "50.26548245743669" 2183 | ] 2184 | }, 2185 | "execution_count": 135, 2186 | "metadata": {}, 2187 | "output_type": "execute_result" 2188 | } 2189 | ], 2190 | "source": [ 2191 | "p.area()" 2192 | ] 2193 | }, 2194 | { 2195 | "cell_type": "code", 2196 | "execution_count": 136, 2197 | "metadata": {}, 2198 | "outputs": [ 2199 | { 2200 | "data": { 2201 | "text/plain": [ 2202 | "50.26548245743669" 2203 | ] 2204 | }, 2205 | "execution_count": 136, 2206 | "metadata": {}, 2207 | "output_type": "execute_result" 2208 | } 2209 | ], 2210 | "source": [ 2211 | "Pizza.circle_area(4)" 2212 | ] 2213 | }, 2214 | { 2215 | "cell_type": "code", 2216 | "execution_count": 137, 2217 | "metadata": {}, 2218 | "outputs": [ 2219 | { 2220 | "data": { 2221 | "text/plain": [ 2222 | "78.53981633974483" 2223 | ] 2224 | }, 2225 | "execution_count": 137, 2226 | "metadata": {}, 2227 | "output_type": "execute_result" 2228 | } 2229 | ], 2230 | "source": [ 2231 | "Pizza.circle_area(5)" 2232 | ] 2233 | }, 2234 | { 2235 | "cell_type": "code", 2236 | "execution_count": 138, 2237 | "metadata": {}, 2238 | "outputs": [ 2239 | { 2240 | "data": { 2241 | "text/plain": [ 2242 | "50.26548245743669" 2243 | ] 2244 | }, 2245 | "execution_count": 138, 2246 | "metadata": {}, 2247 | "output_type": "execute_result" 2248 | } 2249 | ], 2250 | "source": [ 2251 | "p.area()" 2252 | ] 2253 | }, 2254 | { 2255 | "cell_type": "code", 2256 | "execution_count": null, 2257 | "metadata": {}, 2258 | "outputs": [], 2259 | "source": [] 2260 | } 2261 | ], 2262 | "metadata": { 2263 | "colab": { 2264 | "collapsed_sections": [], 2265 | "provenance": [] 2266 | }, 2267 | "kernelspec": { 2268 | "display_name": "Python 3 (ipykernel)", 2269 | "language": "python", 2270 | "name": "python3" 2271 | }, 2272 | "language_info": { 2273 | "codemirror_mode": { 2274 | "name": "ipython", 2275 | "version": 3 2276 | }, 2277 | "file_extension": ".py", 2278 | "mimetype": "text/x-python", 2279 | "name": "python", 2280 | "nbconvert_exporter": "python", 2281 | "pygments_lexer": "ipython3", 2282 | "version": "3.9.13" 2283 | } 2284 | }, 2285 | "nbformat": 4, 2286 | "nbformat_minor": 1 2287 | } 2288 | --------------------------------------------------------------------------------