├── .gitignore ├── 01_introduccion.ipynb ├── 02_ipython_y_jupyter.ipynb ├── 03_palabras_reservadas_y_nombres.ipynb ├── 04_introspeccion_y_ayuda.ipynb ├── 05_expresiones_y_comentarios.ipynb ├── 06_tipos_de_datos_en_python.ipynb ├── 07_conversion_de_tipos_basicos.ipynb ├── 08_colecciones_en_python.ipynb ├── 09_expresiones con operadores.ipynb ├── 10_entrada_y_salida_estandar.ipynb ├── 11_declaraciones_y_bloques_de_codigo.ipynb ├── 12_condicionales.ipynb ├── 13_ciclos_e_interrupciones_de_flujo .ipynb ├── 14_iteraciones.ipynb ├── 15_funciones.ipynb ├── 16_tipos_list_y_tuple.ipynb ├── 17_tipo_str.ipynb ├── 18_f-strings.ipynb ├── 19_tipos_bytes_y_bytearray.ipynb ├── 20_tipo_dict.ipynb ├── 21_tipos_set_y_frozenset.ipynb ├── 22_bases_de_programacion_funcional.ipynb ├── 23_gestion_de_excepciones.ipynb ├── 24_iteradores_y_generadores.ipynb ├── 25_completado_de_elementos.ipynb ├── 26_lectura_y_escritura_de_archivos.ipynb ├── 27_modulos_paquetes.ipynb ├── 28_distribucion_de_codigo.ipynb ├── 29_gestion_de_paquetes.ipynb ├── 30_entornos_virtuales.ipynb ├── LICENSE ├── README.md ├── formatos.ipynb ├── imagenes ├── conjuntos.png ├── difference.png ├── excepciones.png ├── idle.png ├── if-elif.png ├── if-else.png ├── if-simple.png ├── intersection.png ├── isdisjoint.png ├── issubset.png ├── issuperset.png ├── pythonista.png ├── symmetric_difference.png ├── union.png ├── while-break.png ├── while-continue.png ├── while-exit.png └── while.png ├── modulo.py ├── modulo2.py ├── paquete ├── __init__.py ├── primos │ ├── __init__.py │ └── funciones.py └── promedios.py ├── setup.py └── src ├── expresiones.py ├── expresiones_impresas.py ├── holamundo.py ├── holamundo2.py └── while_exit.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | # curso 107 | 108 | prueba/ 109 | prueba.* 110 | -------------------------------------------------------------------------------- /02_ipython_y_jupyter.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# *IPython* y *Jupyter*." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "## El proyecto *IPython*." 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "El proyecto [*IPython*](https://ipython.org/) es un (*shell*) que extiende al entorno interactivo de *Python*, permitiendo entre otras cosas:\n", 29 | "\n", 30 | "* Coloreado del código.\n", 31 | "* Autocompletado de comandos.\n", 32 | "* Historial de comandos.\n", 33 | "* Cómputo paralelo y concurrente.\n", 34 | "* Capacidad de desplegar los gráficos generados por [*Matplotlib*](https://matplotlib.org/) en la misma ventana.\n", 35 | "\n", 36 | "*IPython* puede ser accedido desde 3 interfaces:\n", 37 | "\n", 38 | "* Un shell dentro de una terminal de texto. \n", 39 | "* Un shell dentro de una aplicación de escritorio basada en la biblioteca [*QT*](https://www.qt.io/).\n", 40 | "* Una notebook de *Jupyter*." 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "## El proyecto *Jupyter*.\n", 48 | "\n", 49 | "En el proceso de desarrollo de *IPython* se creó una interfaz basada en web capaz de ofrecer las funcionalidades de *IPython* de forma más amigable.\n", 50 | "\n", 51 | "La interfaz web de *IPython* evolucionó de tal forma que la matéfora de una libreta o \"*notebook*\" no sólo podía conectarse a un intérprete de *IPython*, sino que podía adapatarse a otros lenguajes de programación mediante \"*kernels*\". Es así que a partir de *IPython* surgió el proyecto [*Jupyter*](https://jupyter.org/) (su nombre es una abreviación de [*JUlia*](https://julialang.org/), *PYThon* y [*R*](https://www.r-project.org/).\n", 52 | "\n", 53 | "*Jupyter* es servidor web capaz de desplegar una interfaz que incluye:\n", 54 | "\n", 55 | "* Un gestor de archivos.\n", 56 | "* Editor de texto.\n", 57 | "* Un emulador de terminal.\n", 58 | "* Entornos interactivos basados en *notebooks*.\n", 59 | "* Un gestor de *notebooks*." 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "### Las *notebooks* de *Jupyter*.\n", 67 | "\n", 68 | "Las *notebooks* de *Jupyter* pueden combinar dos tipos primordiales de celdas:\n", 69 | "* Celdas de texto capaces de desplegar código basado en la sintaxis de [*Markdown*](https://markdown.es/).\n", 70 | "* Celdas de código ejecutable con capacidad de desplegar gráficos e imágenes, entre otras muchas funcionalidades.\n", 71 | "\n", 72 | "*Jupyter* puede mantener múltiples *notebooks* y terminales ejecutándose simultáneamente e incluso generar clusters de servidores para cómputo paralelo.\n", 73 | "\n", 74 | "Actualmente las notebooks de *Jupyter* soportan [kernels de diversos lenguajes](https://github.com/jupyter/jupyter/wiki/Jupyter-kernels).\n", 75 | "\n", 76 | "Las notebooks de *Jupyter* pueden ser exportadas en múltiples formatos, tales como *HTML*, *PDF*, [*reStructuredText*](http://docutils.sourceforge.net/rst.html), [*LaTeX*](https://www.latex-project.org/), [*asciidocs*](http://asciidoc.org/), e incluso [*Reveal.js*](https://revealjs.com)." 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "## Los comandos mágicos de *IPython*.\n", 84 | "\n", 85 | "Todos los apuntes de este curso son *notebooks* de *Jupyter* que utilizan el kernel de *IPython*.\n", 86 | "\n", 87 | "Las notebooks de *Jupyter* son interfaces basada en web capaces de ejecutar comandos por medio de un \"*kernel*\", el cual permite ligar a la interfaz con un intérprete específico.\n", 88 | "\n", 89 | "El *kernel* de [*IPython*](https://ipython.org/) es utilizado por *Jupyter* por defecto y corresponde a un intérprete avanzado de *Python*, el cual además de ejecutar expresiones y delcaraciones de *Python* puede ejecutar sus propios \"comandos mágicos\" o \"*magics*\". \n", 90 | "\n", 91 | "Para conocer más al respecto puede consultar la siguiente liga: \n", 92 | "\n", 93 | "http://ipython.readthedocs.io/en/stable/interactive/magics.html\n", 94 | "\n", 95 | "Los comandos mágicos de *IPython* vienen precedidos generalmente por uno o dos signos de porcentaje ```%```. " 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "**Ejemplo:**" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "* La siguiente celda incluye el comando mágico ```%%html``` para insertar un elemento de tipo ```

``` en la ventana de salida de dicha celda." 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": null, 115 | "metadata": { 116 | "scrolled": true 117 | }, 118 | "outputs": [], 119 | "source": [ 120 | "%%html\n", 121 | "\n", 122 | "

Hola, mundo.

" 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "metadata": {}, 128 | "source": [ 129 | "* La siguiente celda incluye el comando mágico```%%javascript``` que modificará las reglas de estilo del elemento ```

``` de la celda superior." 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": null, 135 | "metadata": {}, 136 | "outputs": [], 137 | "source": [ 138 | "%%javascript\n", 139 | "\n", 140 | "let titulo = document.getElementById(\"saludo\");\n", 141 | "console.log(titulo);\n", 142 | "titulo.style.color=\"blue\";" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": {}, 148 | "source": [ 149 | "### Ejecución de un *script* desde una *notebook* de *Jupyter*.\n", 150 | "\n", 151 | "Para ejecutar un archivo de *Python* desde una *notebook* de *Jupyter* se utiliza la instrucción de *IPython* ```%run```, la cual permite ejecutar el *script* localizado en la ruta que se añade posteriormente.\n", 152 | "\n", 153 | "La sintaxis es la siguiente:\n", 154 | "\n", 155 | "```\n", 156 | "%run \n", 157 | "```" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "**Ejemplos:**" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "* La siguiente celda ejecutará el *script* localizado en [```src/holamundo.py```](src/holamundo.py)." 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": {}, 178 | "outputs": [], 179 | "source": [ 180 | "%run src/holamundo.py" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": {}, 186 | "source": [ 187 | "* La siguiente celda ejecutará el *script* localizado en [```src/holamundo2.py```](src/holamundo2.py), el cual desplegará un mensaje y abrirá una ventana que aceptará todos los caracteres que se escriban hasta que se presione la tecla Intro." 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": null, 193 | "metadata": {}, 194 | "outputs": [], 195 | "source": [ 196 | "%run src/holamundo2.py" 197 | ] 198 | }, 199 | { 200 | "cell_type": "markdown", 201 | "metadata": {}, 202 | "source": [ 203 | "## Instrucciones a la línea de comandos desde *Jupyter*.\n", 204 | "\n", 205 | "Además de los comandos mágicos, *IPython* permite ejecutar comandos directamente al sistema operativo desde el que está corriendo el servidor de *Jupyter* mediante la siguiente sintaxis:\n", 206 | "\n", 207 | "```\n", 208 | "!\n", 209 | "```\n", 210 | "Donde:\n", 211 | "\n", 212 | "* ```\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 270 | "

© José Luis Chiquete Valdivieso. 2022.

" 271 | ] 272 | } 273 | ], 274 | "metadata": { 275 | "kernelspec": { 276 | "display_name": "Python 3 (ipykernel)", 277 | "language": "python", 278 | "name": "python3" 279 | }, 280 | "language_info": { 281 | "codemirror_mode": { 282 | "name": "ipython", 283 | "version": 3 284 | }, 285 | "file_extension": ".py", 286 | "mimetype": "text/x-python", 287 | "name": "python", 288 | "nbconvert_exporter": "python", 289 | "pygments_lexer": "ipython3", 290 | "version": "3.9.2" 291 | } 292 | }, 293 | "nbformat": 4, 294 | "nbformat_minor": 1 295 | } 296 | -------------------------------------------------------------------------------- /04_introspeccion_y_ayuda.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Introspección y ayuda." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "## Introspección en *Python*.\n", 22 | "\n", 23 | "Se entiende por instrospección a la capacidad de obtener información y documentación útil a partir de un objeto." 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "## La función ```dir()``` .\n", 31 | "\n", 32 | "Cada objeto contiene un espacio de nombres propio. La función ```dir()``` regresa una lista de los nombres que existen en el espacio de nombres de un objeto cuando éste es usado como argumento.\n", 33 | "\n", 34 | "\n", 35 | "```\n", 36 | "dir()\n", 37 | "```\n", 38 | "\n", 39 | "Donde:\n", 40 | "\n", 41 | "* `````` es cualquier objeto/valor de *Python*." 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "**Ejemplo:** " 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "* La siguiente celda regresará el listado del espacio de nombres del objeto ```object```. " 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": null, 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | " dir(object)" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "Cabe recordar que cuando se ejectua ```dir()``` sin argumentos, la función regresa el listado de nombres del espacio de nombres principal." 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "**Ejemplo:**" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": null, 84 | "metadata": {}, 85 | "outputs": [], 86 | "source": [ 87 | "dir()" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "## La función ```help()```.\n", 95 | "\n", 96 | "Python puede ofrecer información al usuario mediante un proceso llamado \"Introspección\", el cual es capaz de analizar al objeto y a partir de su estructura y comentarios del código, generar documentación.\n", 97 | "\n", 98 | "La función ```help(``` despliega la información sobre la estructura y documentación de un objeto en el entorno interactivo mediante la siguiente sintaxis:\n", 99 | "\n", 100 | "```\n", 101 | "help()\n", 102 | "```\n", 103 | "\n", 104 | "Donde:\n", 105 | "\n", 106 | "* `````` es cualquier objeto/valor de *Python*.\n", 107 | "\n", 108 | "\n", 109 | "La función ```help()``` también despliega algunos otros datos a partir de ciertas palabras clave en formato de cadena de texto como ```\"keywords\"```, ```\"modules\"```, ```\"topics\"```, etc. \n", 110 | "\n", 111 | "Si se usa ```help()``` con una cadena de caracteres que no coincida con alguna palabra clave como las mencionadas, se generará un error." 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "**Ejemplo:**" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "* La siguiente celda desplegará la documentación del objeto ```object```." 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": null, 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [ 134 | "help(object)" 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": {}, 140 | "source": [ 141 | "### Navegación dentro de la ventana de ayuda desde el intérprete de Python.\n", 142 | "\n", 143 | "Debido a que el contenido desplegado por ```help()``` generalmente se extiende más allá de la capacidad de una pantalla de texto, el entorno interactivo cambia a un modo de lectura en el cual uno se puede trasladar a lo largo del texto de ayuda con las teclas , , AvPág, RePág, Inicio y Fin.\n", 144 | "\n", 145 | "Para salir del modo de lectura sólo es necesario ingresar la tecla q." 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "metadata": {}, 151 | "source": [ 152 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 153 | "

© José Luis Chiquete Valdivieso. 2022.

" 154 | ] 155 | } 156 | ], 157 | "metadata": { 158 | "kernelspec": { 159 | "display_name": "Python 3 (ipykernel)", 160 | "language": "python", 161 | "name": "python3" 162 | }, 163 | "language_info": { 164 | "codemirror_mode": { 165 | "name": "ipython", 166 | "version": 3 167 | }, 168 | "file_extension": ".py", 169 | "mimetype": "text/x-python", 170 | "name": "python", 171 | "nbconvert_exporter": "python", 172 | "pygments_lexer": "ipython3", 173 | "version": "3.9.2" 174 | } 175 | }, 176 | "nbformat": 4, 177 | "nbformat_minor": 1 178 | } 179 | -------------------------------------------------------------------------------- /05_expresiones_y_comentarios.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Expresiones y comentarios." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "## Expresiones.\n", 22 | "\n", 23 | "Una expresión es una combinación de nombres, objetos, operadores, funciones y métodos cuya sintaxis es correcta para el intérprete de *Python* y que puede dar por resultado un objeto específico." 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "**Ejemplos:**" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "* La siguiente celda es una expresión de asignación, la cual liga el nombre ```numero``` al objeto ```78.3``` mediante el operador de asignación ```=```." 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": null, 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "numero = 78.3" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "* La siguiente es una expresión que despliega el objeto relacionado con el nombre ```numero```." 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "numero" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "* La siguiente es una expresión aritmética que implica valores numéricos y el operador ```+```." 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": null, 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "1 + 1" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": {}, 84 | "source": [ 85 | "* La siguiente es una expresión de relación que evalúa si ```45``` es mayor o igual a ```11``` usando el operador ```>=```." 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "45 >= 11" 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "metadata": {}, 100 | "source": [ 101 | "* La siguiente expresión ejecuta el método ```upper()```, propio de los objetos tipo ```str``` mediante el operador de atributo ```.```. En este caso, convierte todos los caracteres del texto en mayúsculas." 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "\"carro\".upper()" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "La siguiente celda ejecuta una expresión que invoca a la función ```len()```." 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": null, 123 | "metadata": {}, 124 | "outputs": [], 125 | "source": [ 126 | "len('Saludo')" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "metadata": {}, 132 | "source": [ 133 | "### Ejecución de varias expresiones en una sola línea.\n", 134 | "\n", 135 | "El intérprete de *Python* permite ejecutar múltiples expresiones en una sola línea, denotando el final de una expresión usando el signo de punto y coma ```;```. \n", 136 | "\n", 137 | "Al usar esta sintaxis, el intérprete sólo se desplegará el resultado de la última expresión ejecutada." 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": {}, 143 | "source": [ 144 | "**Ejemplos:**" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "* A continuación se ejecutarán varias expresiones en una sola línea. Todas las expresiones se ejecutaron, pero sólo la última será desplegada." 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": null, 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [ 160 | "a = 3; \"hola\".upper(); a + 5" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": null, 166 | "metadata": {}, 167 | "outputs": [], 168 | "source": [ 169 | "a" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": {}, 175 | "source": [ 176 | "* Si la última expresión también termina con un punto y coma, tampoco será desplegada." 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": null, 182 | "metadata": {}, 183 | "outputs": [], 184 | "source": [ 185 | "a += 11; \"amigos\" * 3; a == 1;" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": null, 191 | "metadata": {}, 192 | "outputs": [], 193 | "source": [ 194 | "a" 195 | ] 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "metadata": {}, 200 | "source": [ 201 | "**Advertencia:** No se recomienda usar este recurso ya que se corre el riesgo de ofuscar el código innecesariamente." 202 | ] 203 | }, 204 | { 205 | "cell_type": "markdown", 206 | "metadata": {}, 207 | "source": [ 208 | "### Expresiones en el entorno interactivo.\n", 209 | "\n", 210 | "La interfaz interactiva evalúa las expresiones tan pronto como son ingresadas y en su caso despliega el resultado." 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": {}, 216 | "source": [ 217 | "**Ejemplos:**" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": {}, 223 | "source": [ 224 | "* Las siguientes celdas contienen varias expresiones cuyo resultado será desplegado por el intérprete de *IPython*." 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": null, 230 | "metadata": { 231 | "scrolled": true 232 | }, 233 | "outputs": [], 234 | "source": [ 235 | "4 * 3" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": null, 241 | "metadata": {}, 242 | "outputs": [], 243 | "source": [ 244 | "15 == 25" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": null, 250 | "metadata": {}, 251 | "outputs": [], 252 | "source": [ 253 | "'hola' + ' mundo'" 254 | ] 255 | }, 256 | { 257 | "cell_type": "markdown", 258 | "metadata": {}, 259 | "source": [ 260 | "### Expresiones al ejecutar un *script*.\n", 261 | "\n", 262 | "A diferencia del entorno interactivo, el intérprete de *Python* no despliega el resultado de las expresiones cuando éste ejecuta un *script*." 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": {}, 268 | "source": [ 269 | "**Ejemplo:**" 270 | ] 271 | }, 272 | { 273 | "cell_type": "markdown", 274 | "metadata": {}, 275 | "source": [ 276 | "* El script ```src/expresiones.py``` contiene el siguiente código:\n", 277 | "\n", 278 | "``` python\n", 279 | "#!/usr/bin/env python \n", 280 | "4 * 3\n", 281 | "15 == 25\n", 282 | "'hola' + ' mundo'\n", 283 | "```" 284 | ] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "metadata": {}, 289 | "source": [ 290 | "* La siguiente celda ejecutará el script ```src/expresiones.py``` usando el comando mágico ```%run```. El resultado de cada expresión no será visible." 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": null, 296 | "metadata": {}, 297 | "outputs": [], 298 | "source": [ 299 | "%run src/expresiones.py" 300 | ] 301 | }, 302 | { 303 | "cell_type": "markdown", 304 | "metadata": {}, 305 | "source": [ 306 | "* La siguiente celda ejecutará al script ```src/expresiones.py``` usando al intérprete de *Python*.\n", 307 | "\n", 308 | "**Nota:** Algunos sistemas identifican al intérprete de *Python 3* como ```python3```." 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": null, 314 | "metadata": {}, 315 | "outputs": [], 316 | "source": [ 317 | "!python src/expresiones.py" 318 | ] 319 | }, 320 | { 321 | "cell_type": "markdown", 322 | "metadata": {}, 323 | "source": [ 324 | "### Despliegue de expresiones en un *script*.\n", 325 | "\n", 326 | "Para que una expresión sea desplegada en un *script* se utiliza la función ```print()```.\n", 327 | "\n", 328 | "```\n", 329 | "print()\n", 330 | "```\n", 331 | "\n", 332 | "Donde:\n", 333 | "\n", 334 | "* `````` es la expresión cuyo resultado se desea desplegar.\n", 335 | "\n", 336 | "**Nota:** La función ```print()``` se estudiará con mayor detalle en capítulos posteriores." 337 | ] 338 | }, 339 | { 340 | "cell_type": "markdown", 341 | "metadata": {}, 342 | "source": [ 343 | "**Ejemplo:**" 344 | ] 345 | }, 346 | { 347 | "cell_type": "markdown", 348 | "metadata": {}, 349 | "source": [ 350 | "El *script* ```src/expresiones_impresas.py``` contiene el siguiente código, en el que se uiliza la función ```print()```.\n", 351 | "\n", 352 | "```python \n", 353 | "#!/usr/bin/env python \n", 354 | "print(4 * 3)\n", 355 | "print(15 == 25)\n", 356 | "print('hola' + ' mundo')\n", 357 | "```" 358 | ] 359 | }, 360 | { 361 | "cell_type": "markdown", 362 | "metadata": {}, 363 | "source": [ 364 | "* La siguiente celda ejecutará dicho *script*. El resultado es el despliegue de las expresiones que se ingresaron como argumentos." 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": null, 370 | "metadata": {}, 371 | "outputs": [], 372 | "source": [ 373 | "%run src/expresiones_impresas.py" 374 | ] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": {}, 379 | "source": [ 380 | "## Comentarios.\n", 381 | "\n", 382 | "Los comentarios son porciones de texto que aún cuando se encuentran dentro de un bloque de código, no son interpretados por *Python* y sirven primordialmente para documentar al código." 383 | ] 384 | }, 385 | { 386 | "cell_type": "markdown", 387 | "metadata": {}, 388 | "source": [ 389 | "### Comentarios de una sola línea.\n", 390 | "\n", 391 | "Cualquier texto después del carácter ```#``` y hasta el final de la línea es considerado como un comentario." 392 | ] 393 | }, 394 | { 395 | "cell_type": "markdown", 396 | "metadata": {}, 397 | "source": [ 398 | "**Ejemplo:**" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": null, 404 | "metadata": {}, 405 | "outputs": [], 406 | "source": [ 407 | "15 + 23 # El resultado es 38." 408 | ] 409 | }, 410 | { 411 | "cell_type": "markdown", 412 | "metadata": {}, 413 | "source": [ 414 | "#### Especificaciones de entorno.\n", 415 | "\n", 416 | "Algunas especificaciones de ejecución de *Python* también se colocan como si fueran comentarios de este tipo.\n", 417 | "\n", 418 | "**Ejemplo:**\n", 419 | "\n", 420 | "``` python\n", 421 | "#! /usr/bin/python\n", 422 | "# -*- coding: utf-8 -*-\n", 423 | "```" 424 | ] 425 | }, 426 | { 427 | "cell_type": "markdown", 428 | "metadata": {}, 429 | "source": [ 430 | "### *Docstrings*.\n", 431 | "\n", 432 | "*Python* también permite incluir comentarios de varias líneas. Éstos deben de estar encerrados entre triples comillas ```\"\"\"``` o entre triples apóstrofes ```'''```. \n", 433 | "\n", 434 | "Este tipo de comentarios son conocidos como *docstrings* y son utilizados para generar documentación que se desplegaría mediante la función ```help()```.\n", 435 | "\n", 436 | "**NOTA:** Los *docstrings* que se incluyen al principio de un módulo, función o clase son reconocidos por *Python* para generación automática de la documentación. El [PEP 257](https://www.python.org/dev/peps/pep-0257/) describe la forma y estilo de documentar en Python." 437 | ] 438 | }, 439 | { 440 | "cell_type": "markdown", 441 | "metadata": {}, 442 | "source": [ 443 | "**Ejemplo:**" 444 | ] 445 | }, 446 | { 447 | "cell_type": "markdown", 448 | "metadata": {}, 449 | "source": [ 450 | "* La siguiente celda define una función con nombre ```mifuncion()```, la cual incluye un *docstring* al principio de esta y otro al final." 451 | ] 452 | }, 453 | { 454 | "cell_type": "code", 455 | "execution_count": null, 456 | "metadata": {}, 457 | "outputs": [], 458 | "source": [ 459 | "def mifuncion():\n", 460 | " \"\"\"Ejemplo del uso de una docstring.\n", 461 | " En este caso se utiliza para documentar una función.\"\"\"\n", 462 | " print(\"Hola\")\n", 463 | " \"\"\"Este es otro docstring.\n", 464 | " No formará parte de la documentación.\"\"\"" 465 | ] 466 | }, 467 | { 468 | "cell_type": "markdown", 469 | "metadata": {}, 470 | "source": [ 471 | "* Una vez que fue definida la funcion ```mifuncion()```, el primer *docstring* será parte de la documentación." 472 | ] 473 | }, 474 | { 475 | "cell_type": "code", 476 | "execution_count": null, 477 | "metadata": { 478 | "scrolled": false 479 | }, 480 | "outputs": [], 481 | "source": [ 482 | "help(mifuncion)" 483 | ] 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "metadata": {}, 488 | "source": [ 489 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 490 | "

© José Luis Chiquete Valdivieso. 2022.

" 491 | ] 492 | } 493 | ], 494 | "metadata": { 495 | "kernelspec": { 496 | "display_name": "Python 3 (ipykernel)", 497 | "language": "python", 498 | "name": "python3" 499 | }, 500 | "language_info": { 501 | "codemirror_mode": { 502 | "name": "ipython", 503 | "version": 3 504 | }, 505 | "file_extension": ".py", 506 | "mimetype": "text/x-python", 507 | "name": "python", 508 | "nbconvert_exporter": "python", 509 | "pygments_lexer": "ipython3", 510 | "version": "3.9.2" 511 | } 512 | }, 513 | "nbformat": 4, 514 | "nbformat_minor": 1 515 | } 516 | -------------------------------------------------------------------------------- /06_tipos_de_datos_en_python.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Tipos de datos en Python 3." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Python ha evolucionado para ofrecer poderosos tipos de datos que lo diferencian de otros lenguajes de programación por su sencillez y flexibilidad.\n", 22 | "\n", 23 | "Aún cuando Python cuenta con una amplia biblioteca que incluye muy diversos tipos de datos, ofrece ciertos tipos básicos." 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "## Particularidades los tipos de datos en Python.\n", 31 | "\n", 32 | "### Tipos dinámicos.\n", 33 | "\n", 34 | "Python es un lenguaje que no requiere que se defina el tipo de un objeto. El intérprete \"infiere\" el tipo de dato del que se trata.\n", 35 | " \n", 36 | "### Fuertemente tipado.\n", 37 | "\n", 38 | "Existen operaciones que no están permitidas entre tipos que no sean compatibles.\n", 39 | "\n", 40 | "### Los tipos son clases.\n", 41 | "\n", 42 | "En Python todos sus elementos son objetos y los datos, una vez identificados, se convierten en objetos instanciados del tipo al que pertenecen. " 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "## Tabla de tipos de datos básicos de Python 3.\n", 50 | "\n", 51 | "La siguiente tabla resume y describe los tipos de datos básicos de Python 3. \n", 52 | "\n", 53 | "|Tipo de dato|Colección|Indexable|Mutable|Contenido|Ejemplo|\n", 54 | "|:-----------:|:--:|:--:|:--:|:----:|:-----|\n", 55 | "|```int```|NO|NO|NO|Números enteros|```-12```|\n", 56 | "|```float```|NO|NO|NO|Números de punto flotante|```4.361```|\n", 57 | "|```complex```|NO|NO|NO|Números complejos|```(41.6-11.3j)```|\n", 58 | "|```bool```|NO|NO|NO|Valores booleanos|```True```|\n", 59 | "|```NoneType```|NO|NO|NO|Sin valor|```None```|\n", 60 | "|```str```|SÍ|Numérico|NO|Caracteres Unicode|```'Gödel'```|\n", 61 | "|```bytes```|SÍ|Numérico|NO|Caracteres ASCII|```b'Hola'```|\n", 62 | "|```bytearray```|SÍ|Numérico|SÍ|Caracteres ASCII|```bytearray(b'Hola')```|\n", 63 | "|```list```|SÍ|Numérico|SÍ|Cualquier objeto|```[1, 2.0, 'Tres']```|\n", 64 | "|```tuple```|SÍ|Numérico|NO|Cualquier objeto|```(1, 2.0, 'Tres')```|\n", 65 | "|```dict```|SÍ|Por clave|Sí|Pares *clave:valor*|```{'nombre':'Juan', 'promedio':10}```|\n", 66 | "|```set```|SÍ|NO|SÍ|Objetos inmutables|```{1, False, 'María'}```|\n", 67 | "|```frozenset```|SÍ|NO|NO|Objetos inmutables|```frozenset({{1, False, 'María'})```|\n", 68 | "\n", 69 | "* **Las colecciones** son objetos que contienen a otros objetos. A los objetos contenidos también se les refiere como elementos.\n", 70 | "\n", 71 | "* **Los tipos indexables** tienen la capacidad de asignar a cada uno de los elementos que contienen un identificador único (índice) que puede consistir en un número entero o una clave dependiendo del tipo del que se trate.\n", 72 | "\n", 73 | "* **Los tipos mutables** permiten eliminar, sustituir e incluso añadir elementos a su contenido." 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "\n", 81 | "\n", 82 | "## Números enteros (```int```).\n", 83 | "\n", 84 | "Python identifica a los número enteros como un tipo de dato el cual puede ser expresado de la siguiente manera. \n", 85 | "\n", 86 | "* Decimal: ```24```, ```60```.\n", 87 | "* Binario: ```0b010011```, ```0b1101```. \n", 88 | "* Hexadecimal: ```0x18```, ```0x3cf4```.\n", 89 | "* Octal: ``0o30``, ```0o74```.\n", 90 | "\n", 91 | "Python 2 también identifica a un tipo llamado entero largo (```long```), al cual se le añade la letra ```L``` al final de número, pero ya no es reconocido por Python 3. " 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": {}, 97 | "source": [ 98 | "**Ejemplos:**" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "* La siguiente celda define al número ```24```." 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "metadata": {}, 112 | "outputs": [], 113 | "source": [ 114 | "24" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "* La siguiente celda define al número ```139``` en formato binario." 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": null, 127 | "metadata": { 128 | "scrolled": true 129 | }, 130 | "outputs": [], 131 | "source": [ 132 | "0b10001011" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "* La siguiente celda define al número ```1522``` en formato hexadecimal." 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [ 148 | "0x5f2" 149 | ] 150 | }, 151 | { 152 | "cell_type": "markdown", 153 | "metadata": {}, 154 | "source": [ 155 | "* La siguiente celda define al número ```159``` en formato octal." 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "metadata": {}, 162 | "outputs": [], 163 | "source": [ 164 | "0o237" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "## Números de punto flotante (``float``).\n", 172 | "\n", 173 | "Los objetos tipo ``float`` corresponden al conjunto de los números reales.\n", 174 | "\n", 175 | "**Ejemplos:**\n", 176 | "\n", 177 | "* ```3.141595``` \n", 178 | "* ```12.``` \n", 179 | "* ```-45.35```" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "#### Precisión de los números flotantes.\n", 187 | "\n", 188 | "Hay que tomar en cuenta que la precisión de los números dependen en gran medida de la capacidad del equipo de cómputo, por lo que en ocasiones una operación con números de tipo ```float``` no dará el resultado exacto, sino una aproximación." 189 | ] 190 | }, 191 | { 192 | "cell_type": "markdown", 193 | "metadata": {}, 194 | "source": [ 195 | "**Ejemplo:**" 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": {}, 201 | "source": [ 202 | "* La siguiente expresión da por resultado un número racional que corresponde a una suceción infinita del dígito ```6``` después del punto decimal." 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": null, 208 | "metadata": {}, 209 | "outputs": [], 210 | "source": [ 211 | "2 / 3" 212 | ] 213 | }, 214 | { 215 | "cell_type": "markdown", 216 | "metadata": {}, 217 | "source": [ 218 | "En este caso, es imposible para Python calcular una sucesión infinita de ```6``` y por ende, el intérprete truncó el número a 16 decimales." 219 | ] 220 | }, 221 | { 222 | "cell_type": "markdown", 223 | "metadata": {}, 224 | "source": [ 225 | "## Números complejos (```complex```).\n", 226 | "\n", 227 | "Los objetos de tipo ```complex``` corresponden al conjunto de los números complejos.\n", 228 | "\n", 229 | "Siempre que el componente en los números reales sea distinto de ```0```, los objetos de tipo ```complex``` se expresarán como un par de números de tipo ```float``` separados por el operador de adición ```+```, en el que el primer número corresponde al componente en los números reales y el componente en los números imaginarios es identificado añadiéndole la letra ```j``` al final.\n", 230 | "\n", 231 | "La sintaxis estricta es la siguiente:\n", 232 | "\n", 233 | "\n", 234 | "* Cuando el componente imaginario es postivo.\n", 235 | "\n", 236 | "```\n", 237 | "(+j)\n", 238 | "```\n", 239 | "\n", 240 | "* Cuando el componente imaginario es negativo.\n", 241 | "\n", 242 | "```\n", 243 | "(-j)\n", 244 | "\n", 245 | "```\n", 246 | "\n", 247 | "* Cuando el componente real es igual a ```0```.\n", 248 | "\n", 249 | "```\n", 250 | "j\n", 251 | "```\n", 252 | "\n", 253 | "Donde:\n", 254 | "\n", 255 | "* `````` es el componente real del número compejo.\n", 256 | "* `````` es el componente imaginario del número complejo." 257 | ] 258 | }, 259 | { 260 | "cell_type": "markdown", 261 | "metadata": {}, 262 | "source": [ 263 | "**Ejemplos:**" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "* La siguiente celda muestra la forma estricta en la que se define un objeto tipo ```complex```." 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": null, 276 | "metadata": {}, 277 | "outputs": [], 278 | "source": [ 279 | "(2+5j)" 280 | ] 281 | }, 282 | { 283 | "cell_type": "markdown", 284 | "metadata": {}, 285 | "source": [ 286 | "* Las siguientes expresiones implican operaciones aritméticas con números imaginarios, las cuales dan por resultado objetos tipo ```complex```." 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": null, 292 | "metadata": {}, 293 | "outputs": [], 294 | "source": [ 295 | "1.323 - 1j " 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": null, 301 | "metadata": {}, 302 | "outputs": [], 303 | "source": [ 304 | "-2.9j - 23.03" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": null, 310 | "metadata": {}, 311 | "outputs": [], 312 | "source": [ 313 | "12.4 + 0j" 314 | ] 315 | }, 316 | { 317 | "cell_type": "markdown", 318 | "metadata": {}, 319 | "source": [ 320 | "* En caso de que sólo se defina el componente imaginario, el resultado sólo será ```15j```." 321 | ] 322 | }, 323 | { 324 | "cell_type": "code", 325 | "execution_count": null, 326 | "metadata": {}, 327 | "outputs": [], 328 | "source": [ 329 | "15j" 330 | ] 331 | }, 332 | { 333 | "cell_type": "markdown", 334 | "metadata": {}, 335 | "source": [ 336 | "## Valores booleanos (```bool```).\n", 337 | "\n", 338 | "El tipo ```bool``` es una especie de tipo numérico que es utilizado para evaluar expresiones lógicas y tiene dos valores: ```True``` y ```False```.\n", 339 | "\n", 340 | "* Si una expresión lógica se cumple, el resultado es ```True```.\n", 341 | "* Si una expresión lógica NO se cumple, el resultado es ```False```.\n", 342 | "* ```False``` equivale numéricamente a ```0```. \n", 343 | "* Cualquier otro valor no vacío equivale a ```True``` y su valor por defecto es ```1```.\n", 344 | "\n", 345 | "**Nota:** Las expresiones lógicas se estudiarán más adelante." 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "**Ejemplos:**" 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": null, 358 | "metadata": {}, 359 | "outputs": [], 360 | "source": [ 361 | "True" 362 | ] 363 | }, 364 | { 365 | "cell_type": "code", 366 | "execution_count": null, 367 | "metadata": {}, 368 | "outputs": [], 369 | "source": [ 370 | "False" 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "metadata": {}, 376 | "source": [ 377 | "## ```NoneType```.\n", 378 | "\n", 379 | "El único objeto de este tipo es ```None``` y representa un valor nulo. \n", 380 | "\n", 381 | "Una expresión que dé por resultado ```None``` no es desplegado por el intérprete." 382 | ] 383 | }, 384 | { 385 | "cell_type": "markdown", 386 | "metadata": {}, 387 | "source": [ 388 | "**Ejemplo:**" 389 | ] 390 | }, 391 | { 392 | "cell_type": "markdown", 393 | "metadata": {}, 394 | "source": [ 395 | "* La siguiente celda incluye al objeto ```None```, pero al ejecutarla, no se despliega nada." 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": null, 401 | "metadata": {}, 402 | "outputs": [], 403 | "source": [ 404 | "None" 405 | ] 406 | }, 407 | { 408 | "cell_type": "markdown", 409 | "metadata": {}, 410 | "source": [ 411 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 412 | "

© José Luis Chiquete Valdivieso. 2020.

" 413 | ] 414 | } 415 | ], 416 | "metadata": { 417 | "kernelspec": { 418 | "display_name": "Python 3 (ipykernel)", 419 | "language": "python", 420 | "name": "python3" 421 | }, 422 | "language_info": { 423 | "codemirror_mode": { 424 | "name": "ipython", 425 | "version": 3 426 | }, 427 | "file_extension": ".py", 428 | "mimetype": "text/x-python", 429 | "name": "python", 430 | "nbconvert_exporter": "python", 431 | "pygments_lexer": "ipython3", 432 | "version": "3.9.2" 433 | } 434 | }, 435 | "nbformat": 4, 436 | "nbformat_minor": 1 437 | } 438 | -------------------------------------------------------------------------------- /11_declaraciones_y_bloques_de_codigo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Declaraciones y bloques de código." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "## Flujo de ejecución del código.\n", 22 | "\n", 23 | "El intérprete de Python es capaz de leer, evaluar y ejecutar una sucesión de instrucciones línea por línea de principio a fin. A esto se le conoce copmo flujo de ejecución de código.\n", 24 | "\n", 25 | "Los lenguajes de programacion modernos pueden ejecutar o no porciones de código dependiendo de ciertas condiciones. Estas prociondes de código también se conocen como \"bloques\" y deben de ser delimitados sintácticamente. \n", 26 | "\n", 27 | "Así como algunos lenguajes de programación identifican el final de una expresión mendiante el uso del punto y coma ```;```, también suelen delimitar bloques de código encerrándolos entre llaves ```{``` ```}```.\n", 28 | "\n", 29 | "**Ejemplo:**\n", 30 | "\n", 31 | "* El siguiente código ejemplifca el uso de llaves en un código simple de Javascript.\n", 32 | "\n", 33 | "\n", 34 | "```javascript\n", 35 | "\n", 36 | "for (let i = 1; i <= 10; i++) {\n", 37 | " console.log(i);\n", 38 | "}\n", 39 | "console.log(\"Esta es la línea final.\");\n", 40 | "```" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "## Declaraciones.\n", 48 | "\n", 49 | "Las declaraciones (statements) son expresiones capaces de contener a un bloque de código, las cuales se ejecutarán e incluso repetirán en caso de que se cumplan ciertas condiciones.\n", 50 | "\n", 51 | "La inmensa mayoría de los lenguajes de programación utilizan a las declaraciones como parte fundamental de su estructura de código. \n", 52 | "\n", 53 | "En el caso de Python, se colocan dos puntos ```:``` al final de la línea que define a una declaración y se indenta el código que pertence a dicha declaración.\n", 54 | "\n", 55 | "```\n", 56 | "\n", 57 | "...\n", 58 | "...\n", 59 | ":\n", 60 | " \n", 61 | "\n", 62 | "```" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "### Indentación.\n", 70 | "\n", 71 | "Es una buena práctica entre programadores usar la indentación (dejar espacios o tabualdores antes de ingresar el código en una línea) como una regla de estilo a fin de poder identificar visualmente los bloques de código.\n", 72 | "\n", 73 | "En el caso de Python , la indentación no sólo es una regla de estilo, sino un elemento sintáctico, por lo que en vez de encerrar un bloque de código entre llaves, un bloque de código se define indentándolo. El PEP-8 indica que la indentación correcta es de cuatro espacios y no se usan tabuladores." 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "**Ejemplo:**" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "* La siguiente celda ejemplifica del uso de indentación en Python para delimitar bloques de código." 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "metadata": { 94 | "scrolled": true 95 | }, 96 | "outputs": [], 97 | "source": [ 98 | "for i in range(1, 11):\n", 99 | " print(i)\n", 100 | "print('Esta es la línea final.')" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "### Declaraciones anidadas.\n", 108 | "\n", 109 | "Es muy común que el código incluya declaraciones dentro de otras declaraciones, por lo que para delimitar el códifgo dentro de una declaración anidada se utiliza la misma regla de indentación dejando 4 espacios adicionales." 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "**Ejemplo:**" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "metadata": { 123 | "scrolled": true 124 | }, 125 | "outputs": [], 126 | "source": [ 127 | "'''Esta celda realizará una iteración de números en el rango \n", 128 | "entre el ```1``` y ```10``` y mostrará un mensaje dependiendo\n", 129 | "si el número es par o non.'''\n", 130 | "\n", 131 | "for i in range (1, 11):\n", 132 | " if i % 2 == 0:\n", 133 | " print ('El número %d es par.' %i)\n", 134 | " else:\n", 135 | " print ('El número %d es non.' %i)\n", 136 | "print('Esta es la línea final.')" 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": {}, 142 | "source": [ 143 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 144 | "

© José Luis Chiquete Valdivieso. 2022.

" 145 | ] 146 | } 147 | ], 148 | "metadata": { 149 | "kernelspec": { 150 | "display_name": "Python 3 (ipykernel)", 151 | "language": "python", 152 | "name": "python3" 153 | }, 154 | "language_info": { 155 | "codemirror_mode": { 156 | "name": "ipython", 157 | "version": 3 158 | }, 159 | "file_extension": ".py", 160 | "mimetype": "text/x-python", 161 | "name": "python", 162 | "nbconvert_exporter": "python", 163 | "pygments_lexer": "ipython3", 164 | "version": "3.10.4" 165 | } 166 | }, 167 | "nbformat": 4, 168 | "nbformat_minor": 1 169 | } 170 | -------------------------------------------------------------------------------- /12_condicionales.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Declaraciones condicionales. " 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "En los primeros años del cómputo, los programas consistían una secuencia lineal de instrucciones que eran ejecutadas por una máquina, tal como lo hace una pianola o una caja de música. Sin embargo conforme el cómputo fue evolucionando, se volvió imperativo que el flujo de un programa de cómputo dejara de ser lineal.\n", 22 | "\n", 23 | "Mediante las estructuras derivadas de ```if```, Python puede evaluar ciertas expresiones lógicas que resultarían finalmente en un valor booleano, el cual ejecutaría el código correspondiente." 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### Declaraciones con una estructura ```if``` simple.\n", 31 | "\n", 32 | "La palabra clave ```if``` siempre evalúa una expresión lógica y en caso de que dicha expresión de por resultado el valor ```True```, se ejecutará el código indentado justo por debajo del ```if```. En caso de que la declaración resulte en el valor ```False```, el intérprete ignorará el bloque de código indentado y éste continuará con la instrucción siguiente inmediata a la indentación.\n", 33 | "\n", 34 | "```\n", 35 | "\n", 36 | "...\n", 37 | "...\n", 38 | "if :\n", 39 | " \n", 40 | "\n", 41 | "```\n", 42 | "A continuación se muestra un diagrama de flujo que ejemplifica al uso del condicional ```if``` en su modo más simple:\n", 43 | "![if simple](imagenes/if-simple.png)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "**Ejemplo:**" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": { 57 | "scrolled": true 58 | }, 59 | "outputs": [], 60 | "source": [ 61 | "\"\"\"Ejemplo sobre el uso del condicional if.\n", 62 | " Si se ingresa un texto igual a \"gato\", se desplegará el mensaje \"miau\".\"\"\"\n", 63 | "\n", 64 | "animal = input(\"¿Qué animal es? \")\n", 65 | "if animal == \"gato\":\n", 66 | " print(\"miau\")\n", 67 | "print (\"Sólo los gatos maullan.\")" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "### Estructura ```if``` ... ```else```.\n", 75 | "\n", 76 | "Si el resultado de la expresión lógica evaluada por ```if``` da por resultado ```False```, se puede utilizar ```else``` para ejecutar el bloque de código indentado debajo de esta expresión.\n", 77 | "\n", 78 | "\n", 79 | "```\n", 80 | "\n", 81 | "...\n", 82 | "...\n", 83 | "if :\n", 84 | " \n", 85 | "else:\n", 86 | " \n", 87 | "\n", 88 | "```\n", 89 | "A continuación se muestra un diagrama de flujo que ejemplifica al uso del condicional ```if``` y ```else```:\n", 90 | "\n", 91 | "![if-else](imagenes/if-else.png)" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": {}, 97 | "source": [ 98 | "**Ejemplo:**" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "metadata": {}, 105 | "outputs": [], 106 | "source": [ 107 | "\"\"\"Ejemplo sobre el uso de la estructura condicional if-else.\n", 108 | " Si se ingresa un texto igual a \"gato\", se desplegará el mensaje \"miau\", \n", 109 | "introducir cualquier otro texto desplegará \"no sé que ruido hace ese animal.\" \"\"\"\n", 110 | "\n", 111 | "animal = input(\"¿Qué animal es? \")\n", 112 | "print(\"Este animal es un %s.\" % animal)\n", 113 | "if animal == \"gato\":\n", 114 | " print(\"miau\")\n", 115 | "else:\n", 116 | " print(\"No sé que ruido hace este animal.\")\n", 117 | "print(\"Sólo los gatos maullan.\")" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": {}, 123 | "source": [ 124 | "### Estructura ```if```...```elif```...```else```.\n", 125 | "\n", 126 | "Es posible evaluar más de una expresión lógica mediante el uso de ```elif```. En el caso de que exista más de una expresión lógica que de por resultado ```True```, Python ejecutará solamente el código delimitado por la primera que ocurra.\n", 127 | "\n", 128 | "En caso de que ninguna de las condiciones de por resultado ```True``` se puede utilizar ```else``` al final de la estructura.\n", 129 | "\n", 130 | "```\n", 131 | "\n", 132 | "...\n", 133 | "...\n", 134 | "if :\n", 135 | " \n", 136 | "elif :\n", 137 | " \n", 138 | "elif :\n", 139 | " \n", 140 | "...\n", 141 | "...\n", 142 | "elif :\n", 143 | " \n", 144 | "else:\n", 145 | " \n", 146 | "\n", 147 | "```\n", 148 | "\n", 149 | "A continuación se muestra un diagrama de flujo que ejemplifica al uso del condicional ```if```, ```elif``` y ```else```:\n", 150 | "\n", 151 | "![if-elif-else](imagenes/if-elif.png)" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": {}, 157 | "source": [ 158 | "**Ejemplo:**" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": null, 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [ 167 | "\"\"\"Ejemplo sobre el uso de la estructura condicional if-elif-else.\n", 168 | "Si se ingresa un texto igual a alguno de los nombres de animales, se desplegará\n", 169 | "el mensaje correspondiente, introducir cualquier otro texto desplegará \n", 170 | "\"no sé que ruido hace ese animal.\" \"\"\"\n", 171 | "\n", 172 | "animal = input(\"¿Qué animal sugiere? \")\n", 173 | "print(\"Este animal es %s.\" % animal)\n", 174 | "if animal == \"gato\":\n", 175 | " print(\"miau\")\n", 176 | "elif animal == \"perro\":\n", 177 | " print(\"guau\")\n", 178 | "elif animal == \"pez\":\n", 179 | " print (\"glub glub\")\n", 180 | "elif animal == \"gallo\":\n", 181 | " print(\"kikiriki\")\n", 182 | "elif animal == \"vaca\":\n", 183 | " print(\"muuu\")\n", 184 | "else:\n", 185 | " print(\"No sé que ruido hace este animal.\")\n", 186 | "print(\"Sólo los gatos maullan.\")" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "### Ejemplo de condicionales anidados.\n", 194 | "\n", 195 | "Aún cuandolas estruturas ```if```...```elif```...```else``` pueden cubrir muchos casos, es común anidar declaraciones condicionales dentro de otras declaraciones condicionales tal como se ilustra a continuación." 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": null, 201 | "metadata": {}, 202 | "outputs": [], 203 | "source": [ 204 | "\"\"\"Ejemplo sobre el uso de condicionales anidados. Validará si un valor \n", 205 | "ingresado sea entero, además de validar si es positivo o negativo.\"\"\"\n", 206 | "\n", 207 | "dato_texto = input('Ingrese un número entero: ')\n", 208 | "dato = eval(dato_texto)\n", 209 | "if type(dato) is int:\n", 210 | " print('Es un entero.')\n", 211 | " if dato < 0:\n", 212 | " print('Es negativo.')\n", 213 | " elif dato > 0:\n", 214 | " print('Es positivo.')\n", 215 | " else:\n", 216 | " print('Es cero')\n", 217 | "else:\n", 218 | " print('No es un entero.')" 219 | ] 220 | }, 221 | { 222 | "cell_type": "markdown", 223 | "metadata": {}, 224 | "source": [ 225 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 226 | "

© José Luis Chiquete Valdivieso. 2022.

" 227 | ] 228 | } 229 | ], 230 | "metadata": { 231 | "kernelspec": { 232 | "display_name": "Python 3 (ipykernel)", 233 | "language": "python", 234 | "name": "python3" 235 | }, 236 | "language_info": { 237 | "codemirror_mode": { 238 | "name": "ipython", 239 | "version": 3 240 | }, 241 | "file_extension": ".py", 242 | "mimetype": "text/x-python", 243 | "name": "python", 244 | "nbconvert_exporter": "python", 245 | "pygments_lexer": "ipython3", 246 | "version": "3.10.4" 247 | } 248 | }, 249 | "nbformat": 4, 250 | "nbformat_minor": 1 251 | } 252 | -------------------------------------------------------------------------------- /13_ciclos_e_interrupciones_de_flujo .ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Ciclos, e interrupciones de ejecución." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "## Ciclos con ```while```.\n", 22 | "\n", 23 | "Python cuenta con la declaración ```while```, la cual permite ejecutar un bloque de código recursivamente mientras se cumpla una condición determinada.\n", 24 | "\n", 25 | "```\n", 26 | "\n", 27 | "...\n", 28 | "...\n", 29 | "while :\n", 30 | " \n", 31 | "\n", 32 | "```\n", 33 | "\n", 34 | "Donde:\n", 35 | "\n", 36 | "* `````` es una expresión que regresa un objeto cuyo valor puede ser interpretado como ```True``` o ```False```. En caso de que dicho objeto tenga un valor equivalente a ```True```, se ejecutará el bloque de código contenido en la declaración. Cuando `````` de por resultado un objeto con valor equivalente a ```False``` , el flujo de ejecución regresará al flujo principal sin ejecutar el bloque de código pertenecioente a la declaración.\n", 37 | "\n", 38 | "A continuación se muestra un diagrama de flujo que ejemplifica al uso de ```while```:\n", 39 | "![while](imagenes/while.png)\n", 40 | "\n", 41 | "**Ejemplo:**" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "''' Este ciclo se repetirá 3 veces o hasta que se ingrese\n", 51 | " la palabra \"despedida\" y desplegará el número de intentos\n", 52 | " hasta que cualquiera de los eventos ocurra.'''\n", 53 | "\n", 54 | "entrada = \"\"\n", 55 | "suma = 0\n", 56 | "while suma < 3 and entrada != \"despedida\":\n", 57 | " entrada = input(\"Clave: \")\n", 58 | " suma += 1\n", 59 | " print(\"Intento %d. \\n \" % suma)\n", 60 | "print(\"Utilizaste %d intentos.\" % suma)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "\n", 68 | "## Interrupciones de ejecución de un bloque.\n", 69 | "\n", 70 | "En ciertas circunstancias es necesario interrumpir el flujo lógico de un programa. Python cuenta con los siguientes recursos para hacerlo.\n", 71 | "\n", 72 | "* La palabra reservada ```continue```.\n", 73 | "* La palabra reservada ```break```.\n", 74 | "* La función ```exit()```." 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "### La palabra reservada ```continue```.\n", 82 | "\n", 83 | "La palabra reservada ```continue``` termina de forma prematura la ejecución de un bloque dentro de un ciclo.\n", 84 | "\n", 85 | "A continuación se muestra un diagrama de flujo que ejemplifica al uso de ```continue``` dentro de un ciclo con ```while```:\n", 86 | "\n", 87 | "![while-continue](imagenes/while-continue.png)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "**Ejemplo:**" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "''' Este ciclo se repetirá 3 veces y desplegará el número de intentos en los\n", 104 | " que se ingresó la palabra \"despedida\".'''\n", 105 | "\n", 106 | "entrada = \"\"\n", 107 | "suma = 0\n", 108 | "fallido = 0\n", 109 | "while suma < 3:\n", 110 | " suma += 1\n", 111 | " print(\"Intento %d.\" % suma)\n", 112 | " entrada = input(\"Clave: \")\n", 113 | " print()\n", 114 | " # Al ingresar \"despedida\", se evita que la variable fallido se incremente.\n", 115 | " if entrada == \"despedida\":\n", 116 | " continue \n", 117 | " fallido += 1\n", 118 | "print(\"Tuviste %d intentos fallidos.\" % fallido)" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "### La palabra reservada ```break``` .\n", 126 | "\n", 127 | "La palabra reservada ```break``` termina prematuramente la ejecución del bloque de código en el que se encuentra y restablece el flujo de ejecución al bloque de código que lo precede.\n", 128 | "\n", 129 | "A continuación se muestra un diagrama de flujo que ejemplifica al uso de ```break``` dentro de un ciclo con ```while```:\n", 130 | "![while-break](imagenes/while-break.png)\n", 131 | "\n", 132 | "**NOTA:** ```break``` no sólo se puede aplicar a ciclos o iteraciones, sino también a funciones, métodos y a cualquier elemento que contenga bloques de código ejecutable. " 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "**Ejemplo:**" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [ 148 | "''' Este ciclo se repetirá 3 veces o hasta que se ingrese\n", 149 | " la palabra \"despedida\" y desplegará sólo el número de intentos\n", 150 | " fallidos hasta que cualquiera de los eventos ocurra.'''\n", 151 | "\n", 152 | "suma = 0\n", 153 | "while suma < 3:\n", 154 | " entrada = input(\"Clave:\")\n", 155 | " #Si se ingresa la palabra \"despedida, se termina el ciclo.\n", 156 | " if entrada == \"despedida\":\n", 157 | " break\n", 158 | " suma = suma + 1\n", 159 | " print(\"Intento %d. \\n \" % suma)\n", 160 | "print(\"Tuviste %d intentos fallidos.\" % suma)\n" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": {}, 166 | "source": [ 167 | "### La función ```exit()```.\n", 168 | "\n", 169 | "La función ```exit()``` termina la ejecución de un programa y cierra el intérprete de Python.\n", 170 | "\n", 171 | "A continuación se muestra un diagrama de flujo que ejemplifica al uso de ```break``` dentro de un ciclo con ```while```:\n", 172 | "![while-exit()](imagenes/while-exit.png)\n", 173 | "\n", 174 | "**Advertencia:** En el caso de las notebooks de Jupyter, cuando el servidor detecta que el kernel se detiene, levanta uno nuevo." 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": {}, 180 | "source": [ 181 | "#### El script [```src/while_exit.py```](src/while_exit.py).\n", 182 | "\n", 183 | "Este ciclo se detendrá la ejecución de un programa al ingresar la cadena de caracteres ```termina```. \n", 184 | "\n", 185 | "**Advertencia:** Debido a las características de Jupyter, este script debe de ser ejecutado mediante el intérprete convencional de Python.\n", 186 | "\n", 187 | "**El código:**" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "``` python\n", 195 | "#! /usr/bin/python3\n", 196 | "\n", 197 | "''' Este programa se repetirá 3 veces o hasta que se ingrese\n", 198 | " la palabra \"despedida\" y desplegará sólo el número de intentos\n", 199 | " fallidos hasta que cualquiera de los eventos ocurra. Al\n", 200 | " ingresar la palabra \"termina\" el programa se detendrá.'''\n", 201 | "\n", 202 | "entrada = \"\"\n", 203 | "suma = 0\n", 204 | "while suma < 3:\n", 205 | " entrada = input(\"Clave:\")\n", 206 | " if entrada == \"despedida\":\n", 207 | " break\n", 208 | " elif entrada == \"termina\":\n", 209 | " exit()\n", 210 | " suma = suma + 1\n", 211 | " print(\"Intento %d. \\n \" % suma)\n", 212 | "print(\"Tuviste %d intentos fallidos.\" % suma)\n", 213 | "```" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": {}, 219 | "source": [ 220 | "### Ciclos infinitos.\n", 221 | "\n", 222 | "Un ciclo infinito con ```while``` se puede provocar cuando la condición lógica que se evalúa siempre sea ```True```." 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "**Ejemplo:**" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": null, 235 | "metadata": {}, 236 | "outputs": [], 237 | "source": [ 238 | "'''Este es un ciclo infinito, del cual solo se puede salir \n", 239 | "cuando se ingrese la cadena despedida.'''\n", 240 | "\n", 241 | "suma = 0\n", 242 | "while True:\n", 243 | " entrada = input(\"Clave:\")\n", 244 | " if entrada == \"despedida\":\n", 245 | " break\n", 246 | " suma = suma + 1\n", 247 | " print(\"Intento %d. \\n \" % suma)\n", 248 | "print(\"Tuviste %d intentos fallidos.\" % suma)" 249 | ] 250 | }, 251 | { 252 | "cell_type": "markdown", 253 | "metadata": {}, 254 | "source": [ 255 | "####

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 256 | "

© José Luis Chiquete Valdivieso. 2020.

" 257 | ] 258 | } 259 | ], 260 | "metadata": { 261 | "kernelspec": { 262 | "display_name": "Python 3 (ipykernel)", 263 | "language": "python", 264 | "name": "python3" 265 | }, 266 | "language_info": { 267 | "codemirror_mode": { 268 | "name": "ipython", 269 | "version": 3 270 | }, 271 | "file_extension": ".py", 272 | "mimetype": "text/x-python", 273 | "name": "python", 274 | "nbconvert_exporter": "python", 275 | "pygments_lexer": "ipython3", 276 | "version": "3.10.4" 277 | } 278 | }, 279 | "nbformat": 4, 280 | "nbformat_minor": 1 281 | } 282 | -------------------------------------------------------------------------------- /14_iteraciones.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "\n", 15 | "# Iteraciones con ```for```... ```in```.\n", 16 | "\n", 17 | "\n", 18 | "## Objetos iterables.\n", 19 | "\n", 20 | "Una de las grandes fortalezas de Python es la de poder de realizar iteraciones de forma dinámica a partir de diversos objetos \"iterables\", los cuales son colecciones de objetos con métodos capaces de regresar elementos de uno en uno.\n", 21 | "\n", 22 | "Algunos tipos iterables son:\n", 23 | "\n", 24 | "* ```str```.\n", 25 | "* ```list```.\n", 26 | "* ```tuple```.\n", 27 | "* ```dict```.\n", 28 | "* ```set```.\n", 29 | "* ```frozenset```.\n", 30 | "* ```bytes```.\n", 31 | "* ```bytearray```." 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "## Iteradores y generadores.\n", 39 | "\n", 40 | "Además de los objetos iterables existen otros objetos capaces de regresar otros objetos de uno en uno. Estos objetos son los iteradores y los generadores, los cuales se estudiarán más adelante." 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "## La estructura ```for``` ... ```in```.\n", 48 | "\n", 49 | "Para iterar un objeto iterable se utiliza la siguiente sintaxis:\n", 50 | "\n", 51 | "```\n", 52 | "for in :\n", 53 | " ...\n", 54 | " ...\n", 55 | "```\n", 56 | "Donde: \n", 57 | "\n", 58 | "* `````` puede ser un objeto iterable, un iterador o un generador.\n", 59 | "\n", 60 | "* `````` es el nombre al que se le asignará cada objeto entregado por el objeto iterable en cada iteración. Al final, dicho estará ligado al último objeto entregado." 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "**Ejemplos:**" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "* La siguiente celda asignará al nombre ```letra``` cada caracter del objeto ```'Chapultepec'```, el cual será desplegado por la función ```print()```. " 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "for letra in \"Chapultepec\":\n", 84 | " print(letra)" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "* El nombre ```letra``` queda ligado al objeto ```'c'```, el cual es el útlimo elemento del objeto ```'Chapultepec'```." 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": null, 97 | "metadata": {}, 98 | "outputs": [], 99 | "source": [ 100 | "letra" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "* La siguiente celda asignará al nombre ```item``` cada elemento contenido en el objeto ```['uno', 'dos', 3]```, el cual será desplegado por la función ```print()```. " 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": {}, 114 | "outputs": [], 115 | "source": [ 116 | "for item in ['uno', 'dos', 3]:\n", 117 | " print(item)" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": {}, 123 | "source": [ 124 | "* El nombre ```item``` queda ligado al objeto ```'3'```, el cual es el útlimo elemento del objeto ```['uno', 'dos', 3]\n", 125 | "```." 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": null, 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [ 134 | "item" 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": {}, 140 | "source": [ 141 | "## Iteraciones con la función ```range()```.\n", 142 | "\n", 143 | "La forma más común de realizar iteraciones en otros lenguajes de programación es por medio de rangos numéricos de forma similar a lo que hace la función ```range()```.\n", 144 | "\n", 145 | "Esta función es un generador que regresa una sucesión de números en un rango definido.\n", 146 | "\n", 147 | "```\n", 148 | "range(, , )\n", 149 | "```\n", 150 | "\n", 151 | "Donde:\n", 152 | "\n", 153 | "* `````` es el primer número del rango.\n", 154 | "* `````` es el valor límite del rango. La sucesión llegará a un número previo a ```n```.\n", 155 | "* `````` es a magnitud de los inrementos o decrementos del rango.\n", 156 | "\n", 157 | "Si sólo se ingresa un argumento, ese valor se le asignará a ```n```, mientras que `````` será igual a ```0``` y `````` será igual a ```1```.\n", 158 | "\n", 159 | "Si sólo se ingresan 2 argumentos, el primero se le asignará a ```m```, el segundo a `````` y `````` será igual a ```1```.\n", 160 | "\n", 161 | "Es posible que el valor de `````` sea negativo siempre que ```m```, sea menor que ``````." 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": {}, 167 | "source": [ 168 | "**Ejemplos:**" 169 | ] 170 | }, 171 | { 172 | "cell_type": "markdown", 173 | "metadata": {}, 174 | "source": [ 175 | "* La siguiente celda desplegará una sucesión de números del ```0``` al ```7``` en incrmentos de ```1```." 176 | ] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": null, 181 | "metadata": {}, 182 | "outputs": [], 183 | "source": [ 184 | "\"\"\" Cuenta del 0 hasta 7 en incrementos de a 1.\"\"\"\n", 185 | "for contador in range(8):\n", 186 | " print(contador)\n", 187 | "print()\n" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "* La siguiente celda desplegará una sucesión de números del ```5``` al ```9``` en incrementos de ```1```." 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": null, 200 | "metadata": {}, 201 | "outputs": [], 202 | "source": [ 203 | "\"\"\" Cuenta del 5 hasta antes de 9 en incrementos de a 1. \"\"\"\n", 204 | "for contador in range(5, 9):\n", 205 | " print(contador)\n", 206 | "print()" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": {}, 212 | "source": [ 213 | "* La siguiente celda desplegará una sucesión de números del ```3``` al ```9``` en incrementos de ```2```." 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": null, 219 | "metadata": {}, 220 | "outputs": [], 221 | "source": [ 222 | "\"\"\" Cuenta de 3 hasta antess de 11 en incrementos de a 2. \"\"\"\n", 223 | "for contador in range(3, 11, 2):\n", 224 | " print(contador)\n", 225 | "print()" 226 | ] 227 | }, 228 | { 229 | "cell_type": "markdown", 230 | "metadata": {}, 231 | "source": [ 232 | "* La siguiente celda desplegará una sucesión de números del ```26``` al ```14``` en decrementos de ```-4```." 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": null, 238 | "metadata": {}, 239 | "outputs": [], 240 | "source": [ 241 | "\"\"\" Cuenta del 26 hasta más de 10 en decrementos de a -4. \"\"\"\n", 242 | "for contador in range(26, 10, -4):\n", 243 | " print(contador)" 244 | ] 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "metadata": {}, 249 | "source": [ 250 | "## Desempaquetado.\n", 251 | "\n", 252 | "Python permite el uso de expresiones capaces de asignar valores a mas de un nombre a partir de una colección.\n", 253 | "\n", 254 | "Si el número de nombres coincide con el número de objetos contenidos en la colección, entonces se asignará el primer valor al primer nombre y así sucesivamente. \n", 255 | "\n", 256 | "```\n", 257 | ", , ..., = \n", 258 | "```\n", 259 | "\n", 260 | "En caso de que el número de nombres y el tamaño de la colección no coincida, se desencadenará un error de tipo ```ValueError```." 261 | ] 262 | }, 263 | { 264 | "cell_type": "markdown", 265 | "metadata": {}, 266 | "source": [ 267 | "**Ejemplo:**" 268 | ] 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "metadata": {}, 273 | "source": [ 274 | "* La siguiente celda asignará a cada uno de los 3 nombres definidos el valor de cada elemento del objeto tipo ```list``` cuyo tamaño es igual a ```3```." 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": null, 280 | "metadata": {}, 281 | "outputs": [], 282 | "source": [ 283 | "nombre, apellido, calificacion = 'Juan', 'Pérez', 7.5" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": null, 289 | "metadata": {}, 290 | "outputs": [], 291 | "source": [ 292 | "nombre" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": null, 298 | "metadata": {}, 299 | "outputs": [], 300 | "source": [ 301 | "apellido" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": null, 307 | "metadata": {}, 308 | "outputs": [], 309 | "source": [ 310 | "calificacion" 311 | ] 312 | }, 313 | { 314 | "cell_type": "markdown", 315 | "metadata": {}, 316 | "source": [ 317 | "* En la siguiente celda se intentarán asignar 3 nombres a partir de una colección con 4 elementos, lo que desencadenará un error de tipo ```ValueError```." 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": null, 323 | "metadata": {}, 324 | "outputs": [], 325 | "source": [ 326 | "nombre, apellido, calificacion = ['Juan', 'Pérez', 'Erroneo', 7.5]" 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "metadata": {}, 332 | "source": [ 333 | "### Desempaquetado con ```for```... ```in```.\n", 334 | "\n", 335 | "La declaración ```for``` ... ```in``` es capaz de realizar el desempaquetado de colecciones contenidas dentro de un objeto iterable cuando se definen más de un nombre. La condición es que el tamaño de las colecciones que regrese el objeto iterable sea igual al numero de nombres definidos después del ```for```.\n", 336 | "\n", 337 | "```\n", 338 | "for , , ..., in :\n", 339 | " ...\n", 340 | " ...\n", 341 | " \n", 342 | "```\n", 343 | "\n", 344 | "Donde:\n", 345 | "\n", 346 | "* `````` es un objeto capaz de regresar colecciones de tamaño ```n``` en cada iteración.\n", 347 | "* `````` es el nombre al que se le asignará el elemento con índice ```x``` a partir de la colección de tamaño ```n ```." 348 | ] 349 | }, 350 | { 351 | "cell_type": "markdown", 352 | "metadata": {}, 353 | "source": [ 354 | "**Ejemplo:**" 355 | ] 356 | }, 357 | { 358 | "cell_type": "markdown", 359 | "metadata": {}, 360 | "source": [ 361 | "* El objeto ```palabras``` es un objeto de tipo ```list``` que contiene objetos de tipo ```str``` de 4 letras." 362 | ] 363 | }, 364 | { 365 | "cell_type": "code", 366 | "execution_count": null, 367 | "metadata": {}, 368 | "outputs": [], 369 | "source": [ 370 | "palabras = [\"gato\", \"pato\", \"zeta\", \"cita\"]" 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "metadata": {}, 376 | "source": [ 377 | "* La siguiente celda hará una iteración para cada objeto contenido por ```palabras```, el cual será asignado a ```item``` en cada iteración." 378 | ] 379 | }, 380 | { 381 | "cell_type": "code", 382 | "execution_count": null, 383 | "metadata": {}, 384 | "outputs": [], 385 | "source": [ 386 | "for item in palabras:\n", 387 | " print(item)" 388 | ] 389 | }, 390 | { 391 | "cell_type": "markdown", 392 | "metadata": {}, 393 | "source": [ 394 | "* La siguiente celda realizará una iteración para cada elemento contenido en ```palabras```. \n", 395 | "* Para cada elemento obtenido en la iteración desempacará los 4 caracteres que contiene y los asignará de forma consecutiva a:\n", 396 | " * ```primera```\n", 397 | " * ```segunda```\n", 398 | " * ```tercera```\n", 399 | " * ```cuarta```" 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": null, 405 | "metadata": {}, 406 | "outputs": [], 407 | "source": [ 408 | "for primera, segunda, tercera, cuarta in palabras:\n", 409 | " print(primera)\n", 410 | " print(segunda)\n", 411 | " print(tercera)\n", 412 | " print(cuarta)\n", 413 | " print(\"----------\")" 414 | ] 415 | }, 416 | { 417 | "cell_type": "markdown", 418 | "metadata": {}, 419 | "source": [ 420 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 421 | "

© José Luis Chiquete Valdivieso. 2020.

" 422 | ] 423 | } 424 | ], 425 | "metadata": { 426 | "kernelspec": { 427 | "display_name": "Python 3 (ipykernel)", 428 | "language": "python", 429 | "name": "python3" 430 | }, 431 | "language_info": { 432 | "codemirror_mode": { 433 | "name": "ipython", 434 | "version": 3 435 | }, 436 | "file_extension": ".py", 437 | "mimetype": "text/x-python", 438 | "name": "python", 439 | "nbconvert_exporter": "python", 440 | "pygments_lexer": "ipython3", 441 | "version": "3.10.4" 442 | } 443 | }, 444 | "nbformat": 4, 445 | "nbformat_minor": 1 446 | } 447 | -------------------------------------------------------------------------------- /18_f-strings.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![imagenes](imagenes/pythonista.png)](https://pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": { 13 | "collapsed": true 14 | }, 15 | "source": [ 16 | "# f-strings." 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "Como se ha visto en capítulos anteriores, es posible formatear cadenas de caracteres utilizando la sintaxis del caracter de escape ```%``` y el método ```str.format()```.\n", 24 | "\n", 25 | "Ambas técnicas sustituyen dentro de un texto el resultado de las expresiones que se ingresan ya sea como una tupla en el caso del caracter de escape ```%``` o como argumentos del método ```str.format())```." 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "**Ejemplos:**" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "radio = 12\n", 42 | "pi = 3.14" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "'La superficie de una circunferencia de radio %f es de %f' %(radio, pi * radio **2)" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "'La superficie de una circunferencia de radio %d es de %f' %(radio, pi * radio **2)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "metadata": { 67 | "scrolled": true 68 | }, 69 | "outputs": [], 70 | "source": [ 71 | "'La superficie de una circunferencia de radio {} es de {}'.format(radio, pi * radio ** 2)" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "## Las *f-tstrings*." 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": {}, 84 | "source": [ 85 | "La [*PEP-498*](https://peps.python.org/pep-0498/) define el uso de cadenas de caracteres especiales, conocidas como *f-strings*, las cuales permiten sustituir expresiones directamente en un texto. La representaciópn de cada expresión debe de estar delimitada por llaves ```{``` ```}```.\n", 86 | "\n", 87 | "\n", 88 | "```\n", 89 | "f'...{}...{}...{}...'\n", 90 | "```\n", 91 | "\n", 92 | "```\n", 93 | "f\"...{}...{}...{}...\"\n", 94 | "```\n", 95 | "\n", 96 | "Donde:\n", 97 | "\n", 98 | "* `````` es la representación de una expresión de *Python*. " 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "**Ejemplos:**" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "metadata": {}, 112 | "outputs": [], 113 | "source": [ 114 | "mi_nombre = \"Juan\"" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "metadata": {}, 121 | "outputs": [], 122 | "source": [ 123 | "f'Hola. Mi nombre es {mi_nombre}.'" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": null, 129 | "metadata": {}, 130 | "outputs": [], 131 | "source": [ 132 | "f'Mi dirección decorreo electrónico es {e_mail}.'" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "metadata": {}, 139 | "outputs": [], 140 | "source": [ 141 | "radio = 12\n", 142 | "pi = 3.14" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "metadata": {}, 149 | "outputs": [], 150 | "source": [ 151 | "f'La superficie de una circunferencia de radio {radio} es de {pi * radio ** 2}'" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": {}, 157 | "source": [ 158 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 159 | "

© José Luis Chiquete Valdivieso. 2022.

" 160 | ] 161 | } 162 | ], 163 | "metadata": { 164 | "kernelspec": { 165 | "display_name": "Python 3 (ipykernel)", 166 | "language": "python", 167 | "name": "python3" 168 | }, 169 | "language_info": { 170 | "codemirror_mode": { 171 | "name": "ipython", 172 | "version": 3 173 | }, 174 | "file_extension": ".py", 175 | "mimetype": "text/x-python", 176 | "name": "python", 177 | "nbconvert_exporter": "python", 178 | "pygments_lexer": "ipython3", 179 | "version": "3.9.2" 180 | } 181 | }, 182 | "nbformat": 4, 183 | "nbformat_minor": 1 184 | } 185 | -------------------------------------------------------------------------------- /19_tipos_bytes_y_bytearray.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Tipos ```bytes``` y ```bytearray```." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "## El tipo tipo ```bytes```.\n", 22 | "\n", 23 | "Los objetos de tipo ```bytes``` son una colección ordenada, indexable e inmutable de valores que representan a un caracter conforme a su número correspondiente en el [código ASCII](http://www.asciitable.com/) y se definen anteponiendo la letra ```b``` a los apóstrofes o comillas.\n", 24 | "```\n", 25 | "b''\n", 26 | "b\"\" \n", 27 | "```" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "## Métodos compartidos por los objetos ```str```, ```bytes``` y ```bytearray```.\n", 35 | "\n", 36 | "Los objetos de tipo ```bytes``` y ```bytearray``` comparten los siguientes métodos con los de tipo ```str```: \n", 37 | "* ```capitalize()```\n", 38 | "* ```center()```\n", 39 | "* ```count()```\n", 40 | "* ```endswith()```\n", 41 | "* ```expandtabs()```\n", 42 | "* ```find()```\n", 43 | "* ```index()```\n", 44 | "* ```isalnum()```\n", 45 | "* ```isalpha()```\n", 46 | "* ```isdigit()```\n", 47 | "* ```islower()```\n", 48 | "* ```isspace()```\n", 49 | "* ```istitle()```\n", 50 | "* ```isupper()```\n", 51 | "* ```ljust()```\n", 52 | "* ```lower()```\n", 53 | "* ```lstrip()```\n", 54 | "* ```maketrans()```\n", 55 | "* ```partition()```\n", 56 | "* ```replace()```\n", 57 | "* ```rfind()```\n", 58 | "* ```rindex()```\n", 59 | "* ```rjust()```\n", 60 | "* ```rpartition()```\n", 61 | "* ```rsplit()```\n", 62 | "* ```rstrip()```\n", 63 | "* ```split()```\n", 64 | "* ```splitlines()```\n", 65 | "* ```startswith()```\n", 66 | "* ```strip()```\n", 67 | "* ```swapcase()```\n", 68 | "* ```title()```\n", 69 | "* ```translate()```\n", 70 | "* ```upper()```\n", 71 | "* ```zfill()```" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "**Ejemplos:**" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": null, 84 | "metadata": {}, 85 | "outputs": [], 86 | "source": [ 87 | "palabra = b\"Hola\"" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "type(palabra)" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "metadata": {}, 103 | "outputs": [], 104 | "source": [ 105 | "print(palabra)" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "metadata": {}, 112 | "outputs": [], 113 | "source": [ 114 | "palabra[0]" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "metadata": {}, 121 | "outputs": [], 122 | "source": [ 123 | "palabra[2:4]" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": null, 129 | "metadata": { 130 | "scrolled": true 131 | }, 132 | "outputs": [], 133 | "source": [ 134 | "palabra[1] = b'm'" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": null, 140 | "metadata": {}, 141 | "outputs": [], 142 | "source": [ 143 | "str(b'Hola')" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": null, 149 | "metadata": { 150 | "scrolled": true 151 | }, 152 | "outputs": [], 153 | "source": [ 154 | "str(b'Hola', encoding=\"ascii\")" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "metadata": {}, 160 | "source": [ 161 | "### El método ```decode()```.\n", 162 | "\n", 163 | "Este método funciona de manera inversa al método ```encode()``` de los objetos tipo ```str```. \n", 164 | "Se ingresan como argumentos el valor de codficación ligado al identificador _encoding_ y el valor de manejo de errores de codificación ligado al identificador _errors_.\n", 165 | "\n" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "**Ejemplo:**" 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": null, 178 | "metadata": {}, 179 | "outputs": [], 180 | "source": [ 181 | "b'Hola,'.decode(encoding=\"utf-8\")" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "### El método ```hex()```.\n", 189 | "\n", 190 | "Regresa un objeto tipo ```str``` que contiene la representación en hexadecimal de cada elemento del objeto tipo ```bytes```." 191 | ] 192 | }, 193 | { 194 | "cell_type": "markdown", 195 | "metadata": {}, 196 | "source": [ 197 | "**Ejemplo:**" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "metadata": {}, 204 | "outputs": [], 205 | "source": [ 206 | "b'Hola'.hex()" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": {}, 212 | "source": [ 213 | "### El método ```fromhex()```.\n", 214 | "\n", 215 | "Regresa un objeto tipo ```bytes``` a partir de un objeto ```str``` que contiene la representación en hexadecimal de uno o más caracteres *ASCII*." 216 | ] 217 | }, 218 | { 219 | "cell_type": "markdown", 220 | "metadata": {}, 221 | "source": [ 222 | "**Ejemplo:**" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": null, 228 | "metadata": {}, 229 | "outputs": [], 230 | "source": [ 231 | "b''.fromhex('486f6c61')" 232 | ] 233 | }, 234 | { 235 | "cell_type": "markdown", 236 | "metadata": {}, 237 | "source": [ 238 | "## Los objetos de tipo ```bytearray()```.\n", 239 | "\n", 240 | "Los objetos de tipo ```bytearray``` son una colección ordenada, indexable y mutable de valores que representan a un caracter conforme a su número correspondiente en el [código ASCII](http://www.asciitable.com/)." 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "**Ejemplos:**" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": null, 253 | "metadata": {}, 254 | "outputs": [], 255 | "source": [ 256 | "arreglo = bytearray(b'hola')" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": null, 262 | "metadata": {}, 263 | "outputs": [], 264 | "source": [ 265 | "arreglo" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": null, 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "arreglo[3]" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": null, 280 | "metadata": {}, 281 | "outputs": [], 282 | "source": [ 283 | "arreglo[3] = 101" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": null, 289 | "metadata": {}, 290 | "outputs": [], 291 | "source": [ 292 | "arreglo" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": null, 298 | "metadata": {}, 299 | "outputs": [], 300 | "source": [ 301 | "del arreglo[0]" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": null, 307 | "metadata": {}, 308 | "outputs": [], 309 | "source": [ 310 | "arreglo" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": null, 316 | "metadata": {}, 317 | "outputs": [], 318 | "source": [ 319 | "dir(arreglo)" 320 | ] 321 | }, 322 | { 323 | "cell_type": "markdown", 324 | "metadata": {}, 325 | "source": [ 326 | "### El método ```pop()```." 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "metadata": {}, 332 | "source": [ 333 | "**Ejemplos:**" 334 | ] 335 | }, 336 | { 337 | "cell_type": "code", 338 | "execution_count": null, 339 | "metadata": {}, 340 | "outputs": [], 341 | "source": [ 342 | "arreglo = bytearray(b'hola')" 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": null, 348 | "metadata": {}, 349 | "outputs": [], 350 | "source": [ 351 | "arreglo.pop()" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": null, 357 | "metadata": {}, 358 | "outputs": [], 359 | "source": [ 360 | "arreglo" 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "execution_count": null, 366 | "metadata": {}, 367 | "outputs": [], 368 | "source": [ 369 | "arreglo.pop()" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": null, 375 | "metadata": {}, 376 | "outputs": [], 377 | "source": [ 378 | "arreglo" 379 | ] 380 | }, 381 | { 382 | "cell_type": "code", 383 | "execution_count": null, 384 | "metadata": {}, 385 | "outputs": [], 386 | "source": [ 387 | "arreglo.pop(0)\n" 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "execution_count": null, 393 | "metadata": {}, 394 | "outputs": [], 395 | "source": [ 396 | "arreglo" 397 | ] 398 | }, 399 | { 400 | "cell_type": "code", 401 | "execution_count": null, 402 | "metadata": {}, 403 | "outputs": [], 404 | "source": [ 405 | "arreglo.pop()" 406 | ] 407 | }, 408 | { 409 | "cell_type": "code", 410 | "execution_count": null, 411 | "metadata": {}, 412 | "outputs": [], 413 | "source": [ 414 | "arreglo" 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": null, 420 | "metadata": {}, 421 | "outputs": [], 422 | "source": [ 423 | "arreglo.pop()" 424 | ] 425 | }, 426 | { 427 | "cell_type": "markdown", 428 | "metadata": {}, 429 | "source": [ 430 | "### El método ```clear()```." 431 | ] 432 | }, 433 | { 434 | "cell_type": "markdown", 435 | "metadata": {}, 436 | "source": [ 437 | "**Ejemplo:**" 438 | ] 439 | }, 440 | { 441 | "cell_type": "code", 442 | "execution_count": null, 443 | "metadata": {}, 444 | "outputs": [], 445 | "source": [ 446 | "arreglo = bytearray(b'hola')" 447 | ] 448 | }, 449 | { 450 | "cell_type": "code", 451 | "execution_count": null, 452 | "metadata": {}, 453 | "outputs": [], 454 | "source": [ 455 | "arreglo.clear()" 456 | ] 457 | }, 458 | { 459 | "cell_type": "code", 460 | "execution_count": null, 461 | "metadata": {}, 462 | "outputs": [], 463 | "source": [ 464 | "arreglo" 465 | ] 466 | }, 467 | { 468 | "cell_type": "markdown", 469 | "metadata": {}, 470 | "source": [ 471 | "### El método ```reverse()```." 472 | ] 473 | }, 474 | { 475 | "cell_type": "markdown", 476 | "metadata": {}, 477 | "source": [ 478 | "**Ejemplo:**" 479 | ] 480 | }, 481 | { 482 | "cell_type": "code", 483 | "execution_count": null, 484 | "metadata": {}, 485 | "outputs": [], 486 | "source": [ 487 | "arreglo = bytearray(b'hola')" 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": null, 493 | "metadata": {}, 494 | "outputs": [], 495 | "source": [ 496 | "arreglo.reverse()" 497 | ] 498 | }, 499 | { 500 | "cell_type": "code", 501 | "execution_count": null, 502 | "metadata": {}, 503 | "outputs": [], 504 | "source": [ 505 | "arreglo" 506 | ] 507 | }, 508 | { 509 | "cell_type": "markdown", 510 | "metadata": {}, 511 | "source": [ 512 | "### El método ```append()```." 513 | ] 514 | }, 515 | { 516 | "cell_type": "markdown", 517 | "metadata": {}, 518 | "source": [ 519 | "**Ejemplo:**" 520 | ] 521 | }, 522 | { 523 | "cell_type": "code", 524 | "execution_count": null, 525 | "metadata": {}, 526 | "outputs": [], 527 | "source": [ 528 | "arreglo = bytearray(b'hola')" 529 | ] 530 | }, 531 | { 532 | "cell_type": "code", 533 | "execution_count": null, 534 | "metadata": {}, 535 | "outputs": [], 536 | "source": [ 537 | "arreglo.append(108)" 538 | ] 539 | }, 540 | { 541 | "cell_type": "code", 542 | "execution_count": null, 543 | "metadata": {}, 544 | "outputs": [], 545 | "source": [ 546 | "arreglo" 547 | ] 548 | }, 549 | { 550 | "cell_type": "markdown", 551 | "metadata": {}, 552 | "source": [ 553 | "### El método ```insert()```." 554 | ] 555 | }, 556 | { 557 | "cell_type": "markdown", 558 | "metadata": {}, 559 | "source": [ 560 | "**Ejemplo:**" 561 | ] 562 | }, 563 | { 564 | "cell_type": "code", 565 | "execution_count": null, 566 | "metadata": {}, 567 | "outputs": [], 568 | "source": [ 569 | "arreglo = bytearray(b'hola')" 570 | ] 571 | }, 572 | { 573 | "cell_type": "code", 574 | "execution_count": null, 575 | "metadata": {}, 576 | "outputs": [], 577 | "source": [ 578 | "arreglo.insert(3, 100)" 579 | ] 580 | }, 581 | { 582 | "cell_type": "code", 583 | "execution_count": null, 584 | "metadata": {}, 585 | "outputs": [], 586 | "source": [ 587 | "arreglo" 588 | ] 589 | }, 590 | { 591 | "cell_type": "markdown", 592 | "metadata": {}, 593 | "source": [ 594 | "### El método ```remove()```." 595 | ] 596 | }, 597 | { 598 | "cell_type": "markdown", 599 | "metadata": {}, 600 | "source": [ 601 | "**Ejemplo:**" 602 | ] 603 | }, 604 | { 605 | "cell_type": "code", 606 | "execution_count": null, 607 | "metadata": {}, 608 | "outputs": [], 609 | "source": [ 610 | "arreglo = bytearray(b'hola')" 611 | ] 612 | }, 613 | { 614 | "cell_type": "code", 615 | "execution_count": null, 616 | "metadata": {}, 617 | "outputs": [], 618 | "source": [ 619 | "arreglo.remove(108)" 620 | ] 621 | }, 622 | { 623 | "cell_type": "code", 624 | "execution_count": null, 625 | "metadata": {}, 626 | "outputs": [], 627 | "source": [ 628 | "arreglo" 629 | ] 630 | }, 631 | { 632 | "cell_type": "markdown", 633 | "metadata": {}, 634 | "source": [ 635 | "### El método ```copy()```." 636 | ] 637 | }, 638 | { 639 | "cell_type": "markdown", 640 | "metadata": {}, 641 | "source": [ 642 | "**Ejemplo:**" 643 | ] 644 | }, 645 | { 646 | "cell_type": "code", 647 | "execution_count": null, 648 | "metadata": {}, 649 | "outputs": [], 650 | "source": [ 651 | "arreglo = bytearray(b'hola')" 652 | ] 653 | }, 654 | { 655 | "cell_type": "code", 656 | "execution_count": null, 657 | "metadata": {}, 658 | "outputs": [], 659 | "source": [ 660 | "nuevo_arreglo = arreglo.copy()" 661 | ] 662 | }, 663 | { 664 | "cell_type": "code", 665 | "execution_count": null, 666 | "metadata": {}, 667 | "outputs": [], 668 | "source": [ 669 | "nuevo_arreglo == arreglo" 670 | ] 671 | }, 672 | { 673 | "cell_type": "code", 674 | "execution_count": null, 675 | "metadata": {}, 676 | "outputs": [], 677 | "source": [ 678 | "nuevo_arreglo" 679 | ] 680 | }, 681 | { 682 | "cell_type": "code", 683 | "execution_count": null, 684 | "metadata": {}, 685 | "outputs": [], 686 | "source": [ 687 | "nuevo_arreglo is arreglo" 688 | ] 689 | }, 690 | { 691 | "cell_type": "markdown", 692 | "metadata": {}, 693 | "source": [ 694 | "### El método ```extend()```." 695 | ] 696 | }, 697 | { 698 | "cell_type": "markdown", 699 | "metadata": {}, 700 | "source": [ 701 | "**Ejemplo:**" 702 | ] 703 | }, 704 | { 705 | "cell_type": "code", 706 | "execution_count": null, 707 | "metadata": {}, 708 | "outputs": [], 709 | "source": [ 710 | "arreglo" 711 | ] 712 | }, 713 | { 714 | "cell_type": "code", 715 | "execution_count": null, 716 | "metadata": {}, 717 | "outputs": [], 718 | "source": [ 719 | "arreglo.extend(b\" amigo\")" 720 | ] 721 | }, 722 | { 723 | "cell_type": "code", 724 | "execution_count": null, 725 | "metadata": {}, 726 | "outputs": [], 727 | "source": [ 728 | "arreglo" 729 | ] 730 | }, 731 | { 732 | "cell_type": "markdown", 733 | "metadata": {}, 734 | "source": [ 735 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 736 | "

© José Luis Chiquete Valdivieso. 2022.

" 737 | ] 738 | } 739 | ], 740 | "metadata": { 741 | "kernelspec": { 742 | "display_name": "Python 3 (ipykernel)", 743 | "language": "python", 744 | "name": "python3" 745 | }, 746 | "language_info": { 747 | "codemirror_mode": { 748 | "name": "ipython", 749 | "version": 3 750 | }, 751 | "file_extension": ".py", 752 | "mimetype": "text/x-python", 753 | "name": "python", 754 | "nbconvert_exporter": "python", 755 | "pygments_lexer": "ipython3", 756 | "version": "3.9.2" 757 | } 758 | }, 759 | "nbformat": 4, 760 | "nbformat_minor": 1 761 | } 762 | -------------------------------------------------------------------------------- /22_bases_de_programacion_funcional.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Programación funcional." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "\n", 22 | "## Funciones anidadas.\n", 23 | "\n", 24 | "A partir de concepto de cerradura, *Python* permite definir funciones dentro de otras funciones.\n", 25 | "\n", 26 | "Cada función crea y contiene su propio ámbito en cada invocación y la cerradura es entregada al ámbito inmediatamente superior. \n" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "**Ejemplo:**" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "* La función ```lista_primos()``` contiene a su vez a la función ```es_primo()```.\n", 41 | "* La función ```es_primo()``` solamente existe dentro del ámbito local de la función ```lista_primos()```." 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "def lista_primos(limite=100):\n", 51 | " '''Genera una lista de los números primos comprendidos\n", 52 | " entre el 2 y el valor de limite.'''\n", 53 | " \n", 54 | " #La lista inicia con el número 2.\n", 55 | " lista = [2]\n", 56 | " \n", 57 | " def es_primo(numero):\n", 58 | " '''Valida si numero es divisible entre un numero \n", 59 | " contenido en lista.'''\n", 60 | " \n", 61 | " # Iterará cada número primo contenido en lista.\n", 62 | " for primo in lista:\n", 63 | " \n", 64 | " # Si numero es divisible entre primo, regresa False.\n", 65 | " if numero % primo == 0:\n", 66 | " return False\n", 67 | " \n", 68 | " # Si numero no es divisible entre ningún número\n", 69 | " # contenido en lista, regresa True.\n", 70 | " return True\n", 71 | " \n", 72 | " # Iterará todos los número enteros entre 3 y limite.\n", 73 | " for numero in range(3, limite + 1):\n", 74 | " \n", 75 | " # Si es_primo(numero) regresa True, añade \n", 76 | " # el valor de numero a lista.\n", 77 | " if es_primo(numero):\n", 78 | " lista.append(numero)\n", 79 | " # Regresa la lista de numeros primos. \n", 80 | " return lista" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [ 89 | "lista_primos(1050)" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "es_primo()" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "* En el ejemplo anterior se definió a la función ```es_primo()``` dentro de la función ```lista_primos()```. \n", 106 | "* Como se puede observar, el nombre ```lista``` está en el espacio de nombres de ```lista_primos()```, pero al estar en un entorno superior al ámbito de ```es_primo()```, ésta función puede acceder a ```lista```." 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "## Recursividad.\n", 114 | "\n", 115 | "*Python* permite hacer llamadas recursivas a una función. Es decir, que la función se invoque a si misma. \n", 116 | "\n", 117 | "Cada vez que una función se invoca a si misma, *Python* crea un nuevo objeto de tipo ```function``` con las mismas características que la función original, pero con un ámbito totalmente nuevo y de nivel inferior a la función original." 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": {}, 123 | "source": [ 124 | "**Ejemplo:**" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "```\n", 132 | "1! = 1\n", 133 | "2! = 2 * 1! = 2\n", 134 | "3! = 3 * 2! = 6\n", 135 | "4! = 4 * 3! = 24\n", 136 | "5! = 5 * 4! = 120\n", 137 | "```" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "metadata": {}, 144 | "outputs": [], 145 | "source": [ 146 | "def factorial(n):\n", 147 | " if n == 1:\n", 148 | " return 1\n", 149 | " else:\n", 150 | " return n * factorial(n - 1)" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "metadata": {}, 157 | "outputs": [], 158 | "source": [ 159 | "factorial(5)" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "En este caso, la función ```factorial()``` se invoca recursivamente, pero cada vez que lo hace, el valor del parámetro ```n``` decrece en ```1``` de forma sucesiva hasta que el parámetro ```n``` alcanza el valor de ```1``` y entonces regresa dicho valor. Es entonces que la cerradura de la función de nivel inferior se multiplica por el parámetro ```n``` de la función superior hasta llegar a la función de más alto nivel." 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "metadata": {}, 172 | "source": [ 173 | "Ahora se incluirán algunas modificaciones al ejemplo anterior para ilustrar el proceso." 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": null, 179 | "metadata": {}, 180 | "outputs": [], 181 | "source": [ 182 | "def factorial(n):\n", 183 | " print(f'En este ámbito, el valor de n es {n}.')\n", 184 | " if n == 1:\n", 185 | " print('Llegó a 1.')\n", 186 | " print('Regresa 1! = 1.')\n", 187 | " return 1\n", 188 | " else:\n", 189 | " fact = n * factorial(n - 1)\n", 190 | " print(f'Regresa {n} * {n - 1}! = {fact}.')\n", 191 | " return fact" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": null, 197 | "metadata": { 198 | "scrolled": false 199 | }, 200 | "outputs": [], 201 | "source": [ 202 | "factorial(5)" 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "metadata": {}, 208 | "source": [ 209 | "## Funciones de orden superior.\n", 210 | "\n", 211 | "Las funciones de orden superior son funciones que aceptan funciones como argumentos y a su vez regresan funciones." 212 | ] 213 | }, 214 | { 215 | "cell_type": "markdown", 216 | "metadata": {}, 217 | "source": [ 218 | "**Ejemplo:**" 219 | ] 220 | }, 221 | { 222 | "cell_type": "markdown", 223 | "metadata": {}, 224 | "source": [ 225 | "* La función ```p()``` transforma al texto ingresado como argumento to en el código *HTML* correspondiente a un elemento ```

```." 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": null, 231 | "metadata": {}, 232 | "outputs": [], 233 | "source": [ 234 | "def p(texto):\n", 235 | " '''Crea el código HTML de un bloque

.'''\n", 236 | " return f'

{texto}

'" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": null, 242 | "metadata": {}, 243 | "outputs": [], 244 | "source": [ 245 | "p('Hola, Mundo.')" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": null, 251 | "metadata": { 252 | "scrolled": false 253 | }, 254 | "outputs": [], 255 | "source": [ 256 | "help(p)" 257 | ] 258 | }, 259 | { 260 | "cell_type": "markdown", 261 | "metadata": {}, 262 | "source": [ 263 | "* La función ```h1()``` transforma al texto ingresado como argumento to en el código *HTML* correspondiente a un elemento ```

```." 264 | ] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "execution_count": null, 269 | "metadata": {}, 270 | "outputs": [], 271 | "source": [ 272 | "def h1(texto):\n", 273 | " '''Genera el código HTML de un bloque

'''\n", 274 | " return \"

\" + texto + \"

\"" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": null, 280 | "metadata": {}, 281 | "outputs": [], 282 | "source": [ 283 | "h1('Título')" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": null, 289 | "metadata": { 290 | "scrolled": false 291 | }, 292 | "outputs": [], 293 | "source": [ 294 | "help(h1)" 295 | ] 296 | }, 297 | { 298 | "cell_type": "markdown", 299 | "metadata": {}, 300 | "source": [ 301 | "* La función ```doc()``` regresa una cadena de caracteres que representa a un documento *HTML5*, incluyendo el texto ingresado como argumento como el contenido de ``````." 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": null, 307 | "metadata": {}, 308 | "outputs": [], 309 | "source": [ 310 | "def doc(texto):\n", 311 | " '''Permite crear un documento HTML5.'''\n", 312 | " plantilla = '\\n\\\n", 313 | " \\n\\\n", 314 | " \\n\\\n", 315 | " Página\\n\\\n", 316 | " \\n\\\n", 317 | " \\n\\\n", 318 | " {}\\n\\\n", 319 | " \\n\\\n", 320 | " '\n", 321 | " return plantilla.format(texto)" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": null, 327 | "metadata": {}, 328 | "outputs": [], 329 | "source": [ 330 | "doc('

Hola

')" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": null, 336 | "metadata": { 337 | "scrolled": true 338 | }, 339 | "outputs": [], 340 | "source": [ 341 | "print(doc('

Hola

'))" 342 | ] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "execution_count": null, 347 | "metadata": {}, 348 | "outputs": [], 349 | "source": [ 350 | "print(doc(p('Hola')))" 351 | ] 352 | }, 353 | { 354 | "cell_type": "code", 355 | "execution_count": null, 356 | "metadata": {}, 357 | "outputs": [], 358 | "source": [ 359 | "print(doc(h1('Hola')))" 360 | ] 361 | }, 362 | { 363 | "cell_type": "markdown", 364 | "metadata": {}, 365 | "source": [ 366 | "* La función ```html()``` es una función de orden superior que:\n", 367 | " * Recibe una función como argumento para el parámetro ```func```. \n", 368 | " * Define a la función anidada ```doc()```, la cual crea una cadena de caracteres a partir de una plantilla y del resutado de invocar ```func()``` pasándole el argumento ```texto```. " 369 | ] 370 | }, 371 | { 372 | "cell_type": "code", 373 | "execution_count": null, 374 | "metadata": {}, 375 | "outputs": [], 376 | "source": [ 377 | "def html(func):\n", 378 | " '''Regresa una función que construye un documento HTML5 \n", 379 | " a partir del texto que regresa el parámetro func.'''\n", 380 | " def doc(texto):\n", 381 | " '''Permite crear un documento HTML5.'''\n", 382 | " \n", 383 | " plantilla = '\\n\\\n", 384 | " \\n\\\n", 385 | " \\n\\\n", 386 | " Página\\n\\\n", 387 | " \\n\\\n", 388 | " \\n\\\n", 389 | " {}\\n\\\n", 390 | " \\n\\\n", 391 | " '\n", 392 | " \n", 393 | " # Se regresará la plantilla con lo que regrese\n", 394 | " # la función` correspondiente al parámetro func.\n", 395 | " return plantilla.format(func(texto))\n", 396 | " \n", 397 | " # Regresa a la función doc\n", 398 | " return doc" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": null, 404 | "metadata": { 405 | "scrolled": true 406 | }, 407 | "outputs": [], 408 | "source": [ 409 | "help(html)" 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": null, 415 | "metadata": {}, 416 | "outputs": [], 417 | "source": [ 418 | "html(p)" 419 | ] 420 | }, 421 | { 422 | "cell_type": "code", 423 | "execution_count": null, 424 | "metadata": {}, 425 | "outputs": [], 426 | "source": [ 427 | "html(p)(\"Hola\")" 428 | ] 429 | }, 430 | { 431 | "cell_type": "code", 432 | "execution_count": null, 433 | "metadata": { 434 | "scrolled": true 435 | }, 436 | "outputs": [], 437 | "source": [ 438 | "print(html(p)(\"Hola\"))" 439 | ] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "execution_count": null, 444 | "metadata": {}, 445 | "outputs": [], 446 | "source": [ 447 | "print(html(h1)(\"Hola\"))" 448 | ] 449 | }, 450 | { 451 | "cell_type": "markdown", 452 | "metadata": {}, 453 | "source": [ 454 | "## Decoradores.\n", 455 | "\n", 456 | "Los decoradores son un recursos de *Python* que permiten aplicar una función de orden superior a otra función con la siguiente sintaxis.\n", 457 | "\n", 458 | "```\n", 459 | "@\n", 460 | "def ():\n", 461 | " ...\n", 462 | " ...\n", 463 | "```\n", 464 | "\n", 465 | "**Ejemplo:**\n", 466 | "\n", 467 | "Se utilizará el decorador de la función ```html()``` aplicado a la función ```parrafo()```." 468 | ] 469 | }, 470 | { 471 | "cell_type": "code", 472 | "execution_count": null, 473 | "metadata": {}, 474 | "outputs": [], 475 | "source": [ 476 | "@html\n", 477 | "def p(texto):\n", 478 | " '''Crea el código HTML de un bloque

.'''\n", 479 | " return f'

{texto}

'" 480 | ] 481 | }, 482 | { 483 | "cell_type": "code", 484 | "execution_count": null, 485 | "metadata": {}, 486 | "outputs": [], 487 | "source": [ 488 | "p" 489 | ] 490 | }, 491 | { 492 | "cell_type": "code", 493 | "execution_count": null, 494 | "metadata": { 495 | "scrolled": true 496 | }, 497 | "outputs": [], 498 | "source": [ 499 | "print(p(\"Hola, Mundo.\"))" 500 | ] 501 | }, 502 | { 503 | "cell_type": "code", 504 | "execution_count": null, 505 | "metadata": { 506 | "scrolled": true 507 | }, 508 | "outputs": [], 509 | "source": [ 510 | "help(p)" 511 | ] 512 | }, 513 | { 514 | "cell_type": "code", 515 | "execution_count": null, 516 | "metadata": {}, 517 | "outputs": [], 518 | "source": [ 519 | "@html\n", 520 | "def h1(texto):\n", 521 | " '''Genera el código HTML de un bloque

'''\n", 522 | " return \"

\" + texto + \"

\"" 523 | ] 524 | }, 525 | { 526 | "cell_type": "code", 527 | "execution_count": null, 528 | "metadata": {}, 529 | "outputs": [], 530 | "source": [ 531 | "print(h1('Título'))" 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "execution_count": null, 537 | "metadata": {}, 538 | "outputs": [], 539 | "source": [ 540 | "help(h1)" 541 | ] 542 | }, 543 | { 544 | "cell_type": "markdown", 545 | "metadata": {}, 546 | "source": [ 547 | "\n", 548 | "## Definición de funciones con la declaración ```lambda```.\n", 549 | "\n", 550 | "Python permite definir funciones en una sola línea mediante el uso del la expresión lambda con la siguiente sintaxis:\n", 551 | "\n", 552 | "```\n", 553 | "lambda , ... : \n", 554 | "```\n", 555 | "\n", 556 | "A este tipo de funciones se les conoce como funciones lambda o funciones anónimas debido a que no requieren de un nombre para ser definidas.\n", 557 | "\n", 558 | "Para nombrar a estas funciones se utiliza el operador de asignación ```=```." 559 | ] 560 | }, 561 | { 562 | "cell_type": "markdown", 563 | "metadata": {}, 564 | "source": [ 565 | "**Ejemplos:**" 566 | ] 567 | }, 568 | { 569 | "cell_type": "code", 570 | "execution_count": null, 571 | "metadata": {}, 572 | "outputs": [], 573 | "source": [ 574 | "saluda = lambda t='extraño', w=50: f'Hola, {t}.'.center(w)" 575 | ] 576 | }, 577 | { 578 | "cell_type": "code", 579 | "execution_count": null, 580 | "metadata": {}, 581 | "outputs": [], 582 | "source": [ 583 | "type(saluda)" 584 | ] 585 | }, 586 | { 587 | "cell_type": "code", 588 | "execution_count": null, 589 | "metadata": {}, 590 | "outputs": [], 591 | "source": [ 592 | "saluda()" 593 | ] 594 | }, 595 | { 596 | "cell_type": "code", 597 | "execution_count": null, 598 | "metadata": {}, 599 | "outputs": [], 600 | "source": [ 601 | "saluda('Mundo', 20)" 602 | ] 603 | }, 604 | { 605 | "cell_type": "markdown", 606 | "metadata": {}, 607 | "source": [ 608 | "* La función ```es_par()``` regresa ```True``` si el argumento ingresado es un número par y regresa ```False``` si el argumento ingresado es un número non." 609 | ] 610 | }, 611 | { 612 | "cell_type": "code", 613 | "execution_count": null, 614 | "metadata": {}, 615 | "outputs": [], 616 | "source": [ 617 | "es_par = lambda n: True if n % 2 == 0 else False" 618 | ] 619 | }, 620 | { 621 | "cell_type": "code", 622 | "execution_count": null, 623 | "metadata": {}, 624 | "outputs": [], 625 | "source": [ 626 | "es_par(2)" 627 | ] 628 | }, 629 | { 630 | "cell_type": "code", 631 | "execution_count": null, 632 | "metadata": {}, 633 | "outputs": [], 634 | "source": [ 635 | "es_par(3)" 636 | ] 637 | }, 638 | { 639 | "cell_type": "markdown", 640 | "metadata": {}, 641 | "source": [ 642 | "* La función ```factorial()``` calcula el factorial de un número mediante recursividad." 643 | ] 644 | }, 645 | { 646 | "cell_type": "code", 647 | "execution_count": null, 648 | "metadata": {}, 649 | "outputs": [], 650 | "source": [ 651 | "factorial = lambda n: n * factorial(n - 1) if n > 1 else 1" 652 | ] 653 | }, 654 | { 655 | "cell_type": "code", 656 | "execution_count": null, 657 | "metadata": {}, 658 | "outputs": [], 659 | "source": [ 660 | "factorial(5)" 661 | ] 662 | }, 663 | { 664 | "cell_type": "code", 665 | "execution_count": null, 666 | "metadata": { 667 | "scrolled": true 668 | }, 669 | "outputs": [], 670 | "source": [ 671 | "list(map(lambda x, y: x + y, [1, 2, 3, 4], [5, 6, 7, 8]))" 672 | ] 673 | }, 674 | { 675 | "cell_type": "code", 676 | "execution_count": null, 677 | "metadata": {}, 678 | "outputs": [], 679 | "source": [ 680 | "from functools import reduce" 681 | ] 682 | }, 683 | { 684 | "cell_type": "code", 685 | "execution_count": null, 686 | "metadata": {}, 687 | "outputs": [], 688 | "source": [ 689 | "reduce(lambda x, y: x + y, [1, 2, 3, 4])" 690 | ] 691 | }, 692 | { 693 | "cell_type": "markdown", 694 | "metadata": {}, 695 | "source": [ 696 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 697 | "

© José Luis Chiquete Valdivieso. 2022.

" 698 | ] 699 | } 700 | ], 701 | "metadata": { 702 | "kernelspec": { 703 | "display_name": "Python 3 (ipykernel)", 704 | "language": "python", 705 | "name": "python3" 706 | }, 707 | "language_info": { 708 | "codemirror_mode": { 709 | "name": "ipython", 710 | "version": 3 711 | }, 712 | "file_extension": ".py", 713 | "mimetype": "text/x-python", 714 | "name": "python", 715 | "nbconvert_exporter": "python", 716 | "pygments_lexer": "ipython3", 717 | "version": "3.10.4" 718 | } 719 | }, 720 | "nbformat": 4, 721 | "nbformat_minor": 2 722 | } 723 | -------------------------------------------------------------------------------- /24_iteradores_y_generadores.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Iteradores y generadores." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Uno de los conceptos más poderosos en *Python* es el uso de iteradores y generadores." 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "## Iteradores.\n", 29 | "\n", 30 | "Los \"iteradores\" y \"generadores\" son objetos que cuentan con el método ```__next__()```, el cual regresa una serie de objetos de uno en uno cada vez que es invocado.\n", 31 | "\n", 32 | "La implementación del método ```__next__()``` corresponde a la función ```next()```." 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "metadata": {}, 38 | "source": [ 39 | "## Iterables.\n", 40 | "\n", 41 | "Un objeto \"iterable\" es un objeto que cuenta con al menos una implementación del método ```__iter__()```, el cual da por resultado un objeto \"iterador\" cuando es invocado.\n", 42 | "\n", 43 | "La implementación del método ```__iter__()``` corresponde a la función ```iter()```." 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "**Ejemplo:**\n", 51 | "\n", 52 | "Por ejemplo, el tipo ```list``` es iterable de la siguiente forma." 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": { 59 | "scrolled": false 60 | }, 61 | "outputs": [], 62 | "source": [ 63 | "lista = ['1', 2, 'tres', 4.0]" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "Los objetos de tipo ```list``` cuentan con un método ```__iter__()```, pero no con un método ```__next__()```." 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": { 77 | "scrolled": false 78 | }, 79 | "outputs": [], 80 | "source": [ 81 | "hasattr(lista, \"__iter__\")" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": null, 87 | "metadata": { 88 | "scrolled": true 89 | }, 90 | "outputs": [], 91 | "source": [ 92 | "hasattr(lista, \"__next__\")" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": {}, 98 | "source": [ 99 | "Sin embargo, el objeto creado a partir del método ``__iter__()``` sí cuenta con un método ```__next__()``` y por lo tanto se trata de un iterador." 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": null, 105 | "metadata": { 106 | "scrolled": false 107 | }, 108 | "outputs": [], 109 | "source": [ 110 | "iterador = iter(lista)\n", 111 | "print(iterador)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": null, 117 | "metadata": { 118 | "scrolled": false 119 | }, 120 | "outputs": [], 121 | "source": [ 122 | "type(iterador)" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": null, 128 | "metadata": { 129 | "scrolled": false 130 | }, 131 | "outputs": [], 132 | "source": [ 133 | "hasattr(iterador, \"__next__\")" 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": {}, 139 | "source": [ 140 | "El objeto ```iterador``` va a regresar cada elemento del objeto ```lista``` de uno en uno cada vez que se invoque la función ```next()``` y cuando ya haya dado todos, regresará un mensaje de error de tipo ```StopIteration``` indicando que el iterador está vacío." 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "metadata": { 147 | "scrolled": false 148 | }, 149 | "outputs": [], 150 | "source": [ 151 | "next(iterador)" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": null, 157 | "metadata": { 158 | "scrolled": false 159 | }, 160 | "outputs": [], 161 | "source": [ 162 | "next(iterador)" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": null, 168 | "metadata": { 169 | "scrolled": false 170 | }, 171 | "outputs": [], 172 | "source": [ 173 | "next(iterador)" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": null, 179 | "metadata": { 180 | "scrolled": false 181 | }, 182 | "outputs": [], 183 | "source": [ 184 | "next(iterador)" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": { 191 | "scrolled": false 192 | }, 193 | "outputs": [], 194 | "source": [ 195 | "next(iterador)" 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": {}, 201 | "source": [ 202 | "## Implementación de las iteraciones con ```for``` ... ```in```.\n", 203 | "\n", 204 | "La estructura ```for``` ... ```in``` es la implementación de *Python* para aprovechar a los objetos iterables.\n", 205 | "\n", 206 | "Cuando se utiliza esta estructura, el intérprete de *Python* realiza los siguientes pasos:\n", 207 | "\n", 208 | "1. Busca un método ```__iter__()``` que se ajuste al requerimiento y crea un objeto iterador.\n", 209 | "2. Realiza una sucesión de ejecuciones de ```__next__()``` para el objeto iterador resultante hasta que éste quede vacío." 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "metadata": {}, 215 | "source": [ 216 | "Por lo que el siguiente código:" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": null, 222 | "metadata": { 223 | "scrolled": false 224 | }, 225 | "outputs": [], 226 | "source": [ 227 | "for i in ['1', 2, 'tres', 4.0]:\n", 228 | " print(i)" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": {}, 234 | "source": [ 235 | "Sería similar al siguiente:" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": null, 241 | "metadata": { 242 | "scrolled": false 243 | }, 244 | "outputs": [], 245 | "source": [ 246 | "iterador = ['1', 2, 'tres', 4.0].__iter__()\n", 247 | "while True:\n", 248 | " try: \n", 249 | " i = iterador.__next__()\n", 250 | " print(i)\n", 251 | " except StopIteration:\n", 252 | " break" 253 | ] 254 | }, 255 | { 256 | "cell_type": "markdown", 257 | "metadata": {}, 258 | "source": [ 259 | "**Ejemplo:**" 260 | ] 261 | }, 262 | { 263 | "cell_type": "code", 264 | "execution_count": null, 265 | "metadata": {}, 266 | "outputs": [], 267 | "source": [ 268 | "persona = {'nombre': \"Juan\", 'primer apellido': \"Pérez\", 'Promedio': 7.5}" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": null, 274 | "metadata": {}, 275 | "outputs": [], 276 | "source": [ 277 | "persona.items()" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": null, 283 | "metadata": {}, 284 | "outputs": [], 285 | "source": [ 286 | "persona.keys()" 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": null, 292 | "metadata": {}, 293 | "outputs": [], 294 | "source": [ 295 | "persona.values()" 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": null, 301 | "metadata": {}, 302 | "outputs": [], 303 | "source": [ 304 | "persona.__iter__()" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": null, 310 | "metadata": {}, 311 | "outputs": [], 312 | "source": [ 313 | "persona.keys().__iter__()" 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": null, 319 | "metadata": {}, 320 | "outputs": [], 321 | "source": [ 322 | "for item in persona:\n", 323 | " print(item)" 324 | ] 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "metadata": {}, 329 | "source": [ 330 | "## Generadores.\n", 331 | "Los generadores son objetos invocables (*callables*), tales como las funciones y los métodos, los cuales implementan un método ```__next__()```. Por lo general esto se realiza utilizando la palabra reservada ```yield```." 332 | ] 333 | }, 334 | { 335 | "cell_type": "markdown", 336 | "metadata": {}, 337 | "source": [ 338 | "La palabra reservada ```yield``` regresa un objeto del ámbito local de una función al ámbito superior de ésta, pero a diferencia de ```return``` la función no es terminada, sino que continúa su ejecución." 339 | ] 340 | }, 341 | { 342 | "cell_type": "markdown", 343 | "metadata": {}, 344 | "source": [ 345 | "**Ejemplo:**\n", 346 | "\n", 347 | "Para ilustrar el uso de ```yield``` se creará una función que genere números primos a partir del número ```2``` de forma ascendente, uno a la vez." 348 | ] 349 | }, 350 | { 351 | "cell_type": "code", 352 | "execution_count": null, 353 | "metadata": { 354 | "scrolled": false 355 | }, 356 | "outputs": [], 357 | "source": [ 358 | "def gen_primos():\n", 359 | " \"\"\" Generador de números primos.\"\"\"\n", 360 | " \n", 361 | " contador = 1\n", 362 | " lista_primos = []\n", 363 | " \n", 364 | " # Comienza una secuencia infinita.\n", 365 | " while True:\n", 366 | " es_primo = True\n", 367 | " contador += 1\n", 368 | " if len(lista_primos) > 0:\n", 369 | " for primo in lista_primos: \n", 370 | " if contador % primo == 0:\n", 371 | " es_primo = False\n", 372 | " break\n", 373 | " if es_primo:\n", 374 | " lista_primos.append(contador)\n", 375 | " yield contador" 376 | ] 377 | }, 378 | { 379 | "cell_type": "code", 380 | "execution_count": null, 381 | "metadata": { 382 | "scrolled": false 383 | }, 384 | "outputs": [], 385 | "source": [ 386 | "generador = gen_primos()" 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "execution_count": null, 392 | "metadata": { 393 | "scrolled": false 394 | }, 395 | "outputs": [], 396 | "source": [ 397 | "type(generador)" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": null, 403 | "metadata": { 404 | "scrolled": false 405 | }, 406 | "outputs": [], 407 | "source": [ 408 | "hasattr(generador, '__next__')" 409 | ] 410 | }, 411 | { 412 | "cell_type": "code", 413 | "execution_count": null, 414 | "metadata": { 415 | "scrolled": false 416 | }, 417 | "outputs": [], 418 | "source": [ 419 | "next(generador)" 420 | ] 421 | }, 422 | { 423 | "cell_type": "code", 424 | "execution_count": null, 425 | "metadata": { 426 | "scrolled": false 427 | }, 428 | "outputs": [], 429 | "source": [ 430 | "next(generador)" 431 | ] 432 | }, 433 | { 434 | "cell_type": "code", 435 | "execution_count": null, 436 | "metadata": { 437 | "scrolled": false 438 | }, 439 | "outputs": [], 440 | "source": [ 441 | "next(generador)" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": null, 447 | "metadata": { 448 | "scrolled": false 449 | }, 450 | "outputs": [], 451 | "source": [ 452 | "next(generador)" 453 | ] 454 | }, 455 | { 456 | "cell_type": "code", 457 | "execution_count": null, 458 | "metadata": { 459 | "scrolled": false 460 | }, 461 | "outputs": [], 462 | "source": [ 463 | "next(generador)" 464 | ] 465 | }, 466 | { 467 | "cell_type": "code", 468 | "execution_count": null, 469 | "metadata": { 470 | "scrolled": false 471 | }, 472 | "outputs": [], 473 | "source": [ 474 | "next(generador)" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "execution_count": null, 480 | "metadata": { 481 | "scrolled": false 482 | }, 483 | "outputs": [], 484 | "source": [ 485 | "next(generador)" 486 | ] 487 | }, 488 | { 489 | "cell_type": "code", 490 | "execution_count": null, 491 | "metadata": {}, 492 | "outputs": [], 493 | "source": [ 494 | "for numero in generador:\n", 495 | " print(numero)" 496 | ] 497 | }, 498 | { 499 | "cell_type": "code", 500 | "execution_count": null, 501 | "metadata": { 502 | "scrolled": false 503 | }, 504 | "outputs": [], 505 | "source": [ 506 | "def gen_finito(limite=100):\n", 507 | " contador = 1\n", 508 | " lista_primos=[]\n", 509 | " \n", 510 | " # Comienza una secuencia infinita.\n", 511 | " while contador < limite:\n", 512 | " es_primo = True\n", 513 | " contador += 1\n", 514 | " if len(lista_primos) > 0:\n", 515 | " for primo in lista_primos: \n", 516 | " if contador % primo == 0:\n", 517 | " es_primo = False\n", 518 | " break\n", 519 | " if es_primo:\n", 520 | " lista_primos.append(contador)\n", 521 | " yield contador" 522 | ] 523 | }, 524 | { 525 | "cell_type": "code", 526 | "execution_count": null, 527 | "metadata": { 528 | "scrolled": false 529 | }, 530 | "outputs": [], 531 | "source": [ 532 | "finito = gen_finito(70)" 533 | ] 534 | }, 535 | { 536 | "cell_type": "code", 537 | "execution_count": null, 538 | "metadata": {}, 539 | "outputs": [], 540 | "source": [ 541 | "next(finito)" 542 | ] 543 | }, 544 | { 545 | "cell_type": "code", 546 | "execution_count": null, 547 | "metadata": { 548 | "scrolled": false 549 | }, 550 | "outputs": [], 551 | "source": [ 552 | "type(finito)" 553 | ] 554 | }, 555 | { 556 | "cell_type": "code", 557 | "execution_count": null, 558 | "metadata": { 559 | "scrolled": false 560 | }, 561 | "outputs": [], 562 | "source": [ 563 | "for item in finito:\n", 564 | " print(item)" 565 | ] 566 | }, 567 | { 568 | "cell_type": "code", 569 | "execution_count": null, 570 | "metadata": { 571 | "scrolled": false 572 | }, 573 | "outputs": [], 574 | "source": [ 575 | "next(finito)" 576 | ] 577 | }, 578 | { 579 | "cell_type": "code", 580 | "execution_count": null, 581 | "metadata": { 582 | "scrolled": true 583 | }, 584 | "outputs": [], 585 | "source": [ 586 | "for item in gen_finito(1000):\n", 587 | " print(item)" 588 | ] 589 | }, 590 | { 591 | "cell_type": "markdown", 592 | "metadata": {}, 593 | "source": [ 594 | "En este caso, se puede realizar una sucesión indefinida de iteraciones, las cuales estarían restringidas exclusivamente a la capacidad del sistema para manejo de números enteros y/o los recursos de memoria." 595 | ] 596 | }, 597 | { 598 | "cell_type": "markdown", 599 | "metadata": {}, 600 | "source": [ 601 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 602 | "

© José Luis Chiquete Valdivieso. 2022.

" 603 | ] 604 | } 605 | ], 606 | "metadata": { 607 | "kernelspec": { 608 | "display_name": "Python 3 (ipykernel)", 609 | "language": "python", 610 | "name": "python3" 611 | }, 612 | "language_info": { 613 | "codemirror_mode": { 614 | "name": "ipython", 615 | "version": 3 616 | }, 617 | "file_extension": ".py", 618 | "mimetype": "text/x-python", 619 | "name": "python", 620 | "nbconvert_exporter": "python", 621 | "pygments_lexer": "ipython3", 622 | "version": "3.9.2" 623 | } 624 | }, 625 | "nbformat": 4, 626 | "nbformat_minor": 2 627 | } 628 | -------------------------------------------------------------------------------- /25_completado_de_elementos.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Completado de elementos en objetos que contengan iterables\n", 15 | "\n", 16 | "Python permite insertar código que genere una serie de objetos mediante iteradores y condicionales. Este \"autollenado\" de elementos se conoce por su nombre en inglés \"comprehension\" y se puede apicar entre otros a objetos de tipo.\n", 17 | "\n", 18 | "* ```list```.\n", 19 | "* ```tuple```.\n", 20 | "* ```dict```.\n", 21 | "* ```set```.\n", 22 | "* ```forzenset```.\n", 23 | "* ```bytes```.\n", 24 | "* ```bytearray```.\n", 25 | "\n", 26 | "## Completado de elementos en objetos de tipo _list_.\n", 27 | "\n", 28 | "La sintaxis es la siguente para un objeto de tipo _list_.\n", 29 | "```\n", 30 | "[ for in if ]\n", 31 | "```\n", 32 | "El proceso de completado es el siguiente:\n", 33 | "* Realiza la iteración definida por la expresión _for_ .. *in*.\n", 34 | "* A cada elemento iterado le aplica la condición lógica.\n", 35 | "* Si la condición lógica se cumple, añade el resultado de la expresión aplicada al elemento.\n", 36 | "\n", 37 | "Es válido no incluir una expresión condicional." 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "**Ejemplos:**" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": null, 50 | "metadata": {}, 51 | "outputs": [], 52 | "source": [ 53 | "[x for x in 'Hola']" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "list('Hola')" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": null, 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "[5 * x for x in range(1, 21) if x % 2 == 0]" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": null, 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "[letra.upper() for letra in 'Parangaricutirimicuaro' if letra.lower() not in ['a', 'e', 'i', 'o', 'u']]" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "Usando el último ejemplo, el código sin utilizar completado de elementos sería algo similar a lo siguiente:" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "lista = []\n", 97 | "for letra in 'Parangaricutirimicuaro':\n", 98 | " if letra.lower() not in ['a', 'e', 'i', 'o', 'u']:\n", 99 | " lista.append(letra.upper())" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": null, 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "print(lista)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "### Completado con expresiones ternarias.\n", 116 | "\n", 117 | "Es posible utilizar expresiones ternarias para el completado de elementos con la siguiente sintaxis:\n", 118 | "\n", 119 | "```\n", 120 | "[ for in ]\n", 121 | "```\n", 122 | "**Ejemplos:**" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": null, 128 | "metadata": {}, 129 | "outputs": [], 130 | "source": [ 131 | "[x if x % 2 == 0 else 5 * x for x in range(1, 21)]" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": null, 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "[letra.upper() if letra.lower() not in ['a', 'e', 'i', 'o', 'u'] else letra.lower() for letra in 'chapultepec']" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "metadata": {}, 146 | "source": [ 147 | "## Completado de elementos en objetos de tipo _tuple_.\n", 148 | "\n", 149 | "Cuando se utiliza el completado en un objeto tipo *tuple*, el objeto resultante es un generador.\n", 150 | "\n", 151 | "**Ejemplo:**\n" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": null, 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [ 160 | "generador = (5 * x for x in range(1, 21) if x % 2 == 0)" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": null, 166 | "metadata": {}, 167 | "outputs": [], 168 | "source": [ 169 | "type(generador)" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "metadata": {}, 176 | "outputs": [], 177 | "source": [ 178 | "print(generador)" 179 | ] 180 | }, 181 | { 182 | "cell_type": "code", 183 | "execution_count": null, 184 | "metadata": {}, 185 | "outputs": [], 186 | "source": [ 187 | "for item in generador:\n", 188 | " print(item)" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": null, 194 | "metadata": {}, 195 | "outputs": [], 196 | "source": [ 197 | "generador = (5 * x for x in range(1, 21) if x % 2 == 0)" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "metadata": {}, 204 | "outputs": [], 205 | "source": [ 206 | "list(generador)" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": {}, 212 | "source": [ 213 | "## Completado de elementos en objetos de tipo _dict_.\n", 214 | "\n", 215 | "En este caso, lo más común es que el elemento iterable sea el identificador.\n", 216 | "\n", 217 | "Sintaxis:\n", 218 | "```\n", 219 | "{ for in iterable> if }\n", 220 | "```" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "**Ejemplo:** \n", 228 | "\n", 229 | "* Las siguientes celdas definirán una serie de identificadores en *campos*, los cuales serán utilizados como el objeto iterable en el completado de objetos tipo *dict*. \n", 230 | "* En cada iteración se ejecutará la función *input()* y el texto ingresado será asociado al identificador correspondiente." 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": null, 236 | "metadata": {}, 237 | "outputs": [], 238 | "source": [ 239 | "campos = ('nombre', 'primer apellido', 'segundo apellido', 'correo')" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": null, 245 | "metadata": {}, 246 | "outputs": [], 247 | "source": [ 248 | "{campo: input('Ingrese {}: '.format(campo)) for campo in campos}" 249 | ] 250 | }, 251 | { 252 | "cell_type": "code", 253 | "execution_count": null, 254 | "metadata": {}, 255 | "outputs": [], 256 | "source": [ 257 | "registro = {campo: input('Ingrese {}: '.format(campo)) for campo in campos}" 258 | ] 259 | }, 260 | { 261 | "cell_type": "code", 262 | "execution_count": null, 263 | "metadata": {}, 264 | "outputs": [], 265 | "source": [ 266 | "registro" 267 | ] 268 | }, 269 | { 270 | "cell_type": "markdown", 271 | "metadata": {}, 272 | "source": [ 273 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 274 | "

© José Luis Chiquete Valdivieso. 2019.

" 275 | ] 276 | } 277 | ], 278 | "metadata": { 279 | "kernelspec": { 280 | "display_name": "Python 3", 281 | "language": "python", 282 | "name": "python3" 283 | }, 284 | "language_info": { 285 | "codemirror_mode": { 286 | "name": "ipython", 287 | "version": 3 288 | }, 289 | "file_extension": ".py", 290 | "mimetype": "text/x-python", 291 | "name": "python", 292 | "nbconvert_exporter": "python", 293 | "pygments_lexer": "ipython3", 294 | "version": "3.8.5" 295 | } 296 | }, 297 | "nbformat": 4, 298 | "nbformat_minor": 1 299 | } 300 | -------------------------------------------------------------------------------- /28_distribucion_de_codigo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Python pone a disposición de los desarrolladores mediante la \"Autoridad de Empaquetado de Python\" (pypa) herramientas que le permiten \"empaquetar\" sus proyectos para que estos sean distribuidos con facilidad.\n", 15 | "\n", 16 | "El sitio https://packaging.python.org/ ofrece tutoriales, especificaciones y contenidos para facilitar y normar el empaquetado y distribución de paquetes en Python.\n", 17 | "\n", 18 | "Un paquete es una estructura de directorios que incluye una biblioteca de código, documentación, archivos de configuración y datos de un proyecto específico, la cual se encuentra comprimida y puede ser reutilizada por cualquier otro usuario o desarrollador." 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "## Los módulos ```distutils``` y ```setuptools```.\n", 26 | "\n", 27 | "El módulo ```distutils``` fue la herramienta de gestión de paquetes original de Python, sin embargo esta ha sido extendida y en la mayoría de los casos, sustituida por el módulo ```setuptools```." 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": null, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "import setuptools" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "help(setuptools)" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "import distutils" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "help(distutils)" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "## Estructura general de un proyecto.\n", 71 | "\n", 72 | "Un proyecto por lo general tiene una estructura específica. Un ejemplo de dicha estructura puede ser consultado en https://github.com/pypa/sampleproject. Dicha estructura comprende por lo general diversos directorios correspondientes a:\n", 73 | "* La bilbioteca de código.\n", 74 | "* Archivos de configuración.\n", 75 | "* Archivos de datos.\n", 76 | "* Archivos para pruebas." 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "### Archivos de texto que normalmente se incluyen en un proyecto.\n", 84 | "* ```README.rst```, el cual es un archivo de texto que puede contener una estructura basada en [reStrcuturedText](http://docutils.sourceforge.net/rst.html).\n", 85 | "* ```LICENSE.txt```, en donde se especifica la licencia bajo la que se libera el código fuente.\n", 86 | "* ```MANIFEST.in``` en el que se indica el contenido del paquete.\n", 87 | "* ```setup.cfg``` en el que se indica la configuración del paquete.\n", 88 | "* ```setup.py``` el script para la creación del paquete." 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "## El archivo ```setup.py```.\n", 96 | "\n", 97 | "Este archivo es el que se utiliza para empaquetar el proyecto y un ejemplo básico es el siguiente.\n", 98 | "\n", 99 | "``` python\n", 100 | "from setuptools import setup, find_packages\n", 101 | "setup(\n", 102 | " name=\"HelloWorld\",\n", 103 | " version=\"0.1\",\n", 104 | " packages=find_packages(),\n", 105 | ")\n", 106 | "```" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "### La función ```setup()``` de ```setuptools```.\n", 114 | "Esta es la función primordial para la creación de los paquetes.\n", 115 | "\n", 116 | "### Campos que puede de incluir en la función ```setup()```. \n", 117 | "\n", 118 | "Entre otras cosas, se pueden incluir los siguientes campos:\n", 119 | "* ```name```\n", 120 | "* ```version```\n", 121 | "* ```description```\n", 122 | "* ```author```\n", 123 | "* ```author_email```\n", 124 | "* ```url```\n", 125 | "* ```download_url```\n", 126 | "* ```license```\n", 127 | "* ```packages```\n", 128 | "* ```py_modules```" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "**Ejemplo:**\n", 136 | " \n", 137 | " A continuación se muestra un ejemplo de script ```setup.py``` más completo.\n", 138 | " \n", 139 | " ``` python\n", 140 | " from setuptools import setup, find_packages\n", 141 | "setup(\n", 142 | " name=\"HelloWorld\",\n", 143 | " version=\"0.1\",\n", 144 | " packages=find_packages(),\n", 145 | " scripts=['say_hello.py'],\n", 146 | "\n", 147 | " # Project uses reStructuredText, so ensure that the docutils get\n", 148 | " # installed or upgraded on the target machine\n", 149 | " install_requires=['docutils>=0.3'],\n", 150 | "\n", 151 | " package_data={\n", 152 | " # If any package contains *.txt or *.rst files, include them:\n", 153 | " '': ['*.txt', '*.rst'],\n", 154 | " # And include any *.msg files found in the 'hello' package, too:\n", 155 | " 'hello': ['*.msg'],\n", 156 | " },\n", 157 | "\n", 158 | " # metadata for upload to PyPI\n", 159 | " author=\"Me\",\n", 160 | " author_email=\"me@example.com\",\n", 161 | " description=\"This is an Example Package\",\n", 162 | " license=\"PSF\",\n", 163 | " keywords=\"hello world example examples\",\n", 164 | " url=\"http://example.com/HelloWorld/\", # project home page, if any\n", 165 | " project_urls={\n", 166 | " \"Bug Tracker\": \"https://bugs.example.com/HelloWorld/\",\n", 167 | " \"Documentation\": \"https://docs.example.com/HelloWorld/\",\n", 168 | " \"Source Code\": \"https://code.example.com/HelloWorld/\",\n", 169 | " }\n", 170 | "\n", 171 | " # could also include long_description, download_url, classifiers, etc.\n", 172 | ")\n", 173 | "```" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "metadata": {}, 179 | "source": [ 180 | "### La función ```find_packages()``` de ```setuptools```.\n", 181 | "\n", 182 | "Esta función permite encontrar la estructura de paquetes en un directorio.\n", 183 | "En este casó, se identifica a un paquete cuando el subdirectorio contiene un archivo ```__init__.py```.\n", 184 | "Además de la identificación de paquetes, la función ```find_packages()``` incluye los parámetros:\n", 185 | "* ```where```, el cual corresponde al directorio desde el cual se buscaran los paquetes. Por defecto se utiliza el directorio desde el que se ejecuta la función. \n", 186 | "* ```exclude```, el cual puede ser un objeto tipo tuple que contiene una lista de aquellos paquetes que no se quieran añadir.\n", 187 | "* ```include```, el cual corresponde a una tupla que contiene una lista de los paquetes a añadir. Por defecto, añade a todos." 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "**Ejemplo:**\n", 195 | "\n", 196 | "La función ```find_packages()``` se ejecutará en el directorio de esta notebook." 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": null, 202 | "metadata": {}, 203 | "outputs": [], 204 | "source": [ 205 | "from setuptools import find_packages" 206 | ] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": null, 211 | "metadata": {}, 212 | "outputs": [], 213 | "source": [ 214 | "find_packages()" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": {}, 220 | "source": [ 221 | "## Creación del paquete.\n", 222 | "\n", 223 | "Una vez que el archivo ``setup.py`` se encuentra disponible, sólo hay que ejecutarlo de la siguiente manera:\n", 224 | "\n", 225 | "``` python\n", 226 | "python setup.py sdist --formats=\n", 227 | "```\n", 228 | "Los formatos soportados son:\n", 229 | "\n", 230 | "* ```zip``` para archivos con extensión ```.zip```.\n", 231 | "* ```bztar``` para archivos con extensión ```.tar.bz```.\n", 232 | "* ```gztar``` para archivos con extensión ```.tar.gz```.\n", 233 | "* ```ztar``` para archivos con extensión ```.tar.z```.\n", 234 | "* ```tar``` para archivos con extensión ```.tar```.\n" 235 | ] 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "metadata": {}, 240 | "source": [ 241 | "**Ejemplo:**\n", 242 | "\n", 243 | "* El archivo [```setup.py```](setup.py) contiene el siguiente código:\n", 244 | "\n", 245 | "``` python\n", 246 | "from setuptools import setup, find_packages\n", 247 | "setup(\n", 248 | " name=\"paquete\",\n", 249 | " version=0.1,\n", 250 | " packages=find_packages(),\n", 251 | ")\n", 252 | "```" 253 | ] 254 | }, 255 | { 256 | "cell_type": "markdown", 257 | "metadata": {}, 258 | "source": [ 259 | "* A continuación se ejecutará el script ```setup.py``` indicando que se deben crear paquetes ```.zip``` \n", 260 | "y ```.tar.gz```." 261 | ] 262 | }, 263 | { 264 | "cell_type": "code", 265 | "execution_count": null, 266 | "metadata": { 267 | "scrolled": true 268 | }, 269 | "outputs": [], 270 | "source": [ 271 | "%run setup.py sdist --formats=zip, gztar" 272 | ] 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "metadata": {}, 277 | "source": [ 278 | "* El resultado serán un par de archivos en el directorio [```dist```](dist)." 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": null, 284 | "metadata": {}, 285 | "outputs": [], 286 | "source": [ 287 | "!dir dist" 288 | ] 289 | }, 290 | { 291 | "cell_type": "markdown", 292 | "metadata": {}, 293 | "source": [ 294 | "Cualquiera de los dos paquetes puede ser instalado mediante el gestor de paquetes ```pip```." 295 | ] 296 | }, 297 | { 298 | "cell_type": "code", 299 | "execution_count": null, 300 | "metadata": {}, 301 | "outputs": [], 302 | "source": [ 303 | "!pip install dist/paquete-0.1.zip" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": null, 309 | "metadata": { 310 | "scrolled": true 311 | }, 312 | "outputs": [], 313 | "source": [ 314 | "!pip list" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": null, 320 | "metadata": {}, 321 | "outputs": [], 322 | "source": [ 323 | "help('modules paquete')" 324 | ] 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "metadata": {}, 329 | "source": [ 330 | "Debido a que existe el directorio ```paquete``` en el directorio de trabajo de esta notebook, es necesario camibarla a otro para importar el paquete que está en la biblioteca." 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": null, 336 | "metadata": {}, 337 | "outputs": [], 338 | "source": [ 339 | "%cd .." 340 | ] 341 | }, 342 | { 343 | "cell_type": "code", 344 | "execution_count": null, 345 | "metadata": {}, 346 | "outputs": [], 347 | "source": [ 348 | "import paquete" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": null, 354 | "metadata": {}, 355 | "outputs": [], 356 | "source": [ 357 | "paquete.saluda()" 358 | ] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "execution_count": null, 363 | "metadata": {}, 364 | "outputs": [], 365 | "source": [ 366 | "help(paquete)" 367 | ] 368 | }, 369 | { 370 | "cell_type": "markdown", 371 | "metadata": {}, 372 | "source": [ 373 | "Para mayor información sobre el uso de ```setuptools``` y las opciones de empaquetado, puede acudir a https://setuptools.readthedocs.io/en/latest/setuptools.html" 374 | ] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": {}, 379 | "source": [ 380 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 381 | "

© José Luis Chiquete Valdivieso. 2020.

" 382 | ] 383 | } 384 | ], 385 | "metadata": { 386 | "kernelspec": { 387 | "display_name": "Python 3", 388 | "language": "python", 389 | "name": "python3" 390 | }, 391 | "language_info": { 392 | "codemirror_mode": { 393 | "name": "ipython", 394 | "version": 3 395 | }, 396 | "file_extension": ".py", 397 | "mimetype": "text/x-python", 398 | "name": "python", 399 | "nbconvert_exporter": "python", 400 | "pygments_lexer": "ipython3", 401 | "version": "3.8.5" 402 | } 403 | }, 404 | "nbformat": 4, 405 | "nbformat_minor": 2 406 | } 407 | -------------------------------------------------------------------------------- /29_gestion_de_paquetes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## La biblioteca de paquetes de Python.\n", 15 | "\n", 16 | "Como se mencionó con anterioridad, existe una enorme cantidad de aplicaciones escritas en Python y publicadas en el sitio [https://pypi.org/](https://pypi.org/)." 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "## El gestor de paquetes ```pip```.\n", 24 | "\n", 25 | "Para poder acceder de forma local a la biblioteca de paquetes de Python se creó el gestos de paquetes llamado ```pip```.\n", 26 | "\n", 27 | "### Instalación de ```pip```.\n", 28 | "\n", 29 | "La mayoría de las distribuciones de GNU/Linux cuentan con un paquete de instalación de ```pip``` tanto para Python 2 como para Python 3.\n", 30 | "\n", 31 | "El gestor ```pip``` ya está incluído con el instalador de Python para Windows y en Anaconda.\n", 32 | "\n", 33 | "La versión más reciente de ```pip``` puede ser instalado descargando el script ```get-pip.py``` desde https://bootstrap.pypa.io/get-pip.py y ejecutándolo con permisos de administrador." 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "**Ejemplo:**\n", 41 | "\n", 42 | "A continuación se muestra la forma de instalar ```pip``` desde GNU/Linux mediante ```sudo```.\n", 43 | "\n", 44 | "``` bash\n", 45 | "$ sudo -H python3 get-pip.py\n", 46 | "```" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "## Operaciones básicas con ```pip```.\n", 54 | "\n", 55 | "Para poder gestionar paquetes con *pip* es necesario ejecutarlo desde la línea de comandos.\n", 56 | "\n", 57 | "Es necesario contar con los permisos necesarios para modificar la biblioteca de Python en caso de querer instalar, eliminar o actualizar paquetes. \n", 58 | "\n", 59 | "```\n", 60 | "pip \n", 61 | "```" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "### Búsqueda de paquetes.\n", 69 | "\n", 70 | "El gestor ```pip``` puede buscar los paquetes que se encuentran en https://pypi.org que coincidan con una cadena de caracteres ingresada de la siguiente forma:\n", 71 | "\n", 72 | "````\n", 73 | "$ pip search \n", 74 | "```\n", 75 | "**Ejemplo:**" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "!pip search networkx" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "### Instalación de paquetes.\n", 92 | "\n", 93 | "Para instalar uno o varios paquetes con ```pip``` se utiliza el subcomando install seguido del nombre de uno o de varios paquetes.\n", 94 | "```\n", 95 | "$ pip install ... \n", 96 | "```\n", 97 | "Una de las ventajas de ```pip``` es que el gestor calcula los paquetes adicionales (dependencias) que requiere el paquete a instalar, por lo que es capaz de descargarlos e instalarlos también." 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "**Ejemplo:**\n", 105 | "\n", 106 | "Se instalarán los paquetes ```networkx``` y ```numpy```, así como sus dependencias." 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "metadata": {}, 113 | "outputs": [], 114 | "source": [ 115 | "!pip install networkx numpy django" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "### Actualización de paquetes.\n", 123 | "\n", 124 | "En caso de que se requiera de actualizar uno o varios paquetes, se utiliza el subcomando ```install``` con el parámetro adicional ```--upgrade```.\n", 125 | "\n", 126 | "```\n", 127 | "$ pip install --upgrade ... \n", 128 | "```" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "**Ejemplo:**\n", 136 | "\n", 137 | "Se actualizará el paquete ```pip```." 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "metadata": {}, 144 | "outputs": [], 145 | "source": [ 146 | "!pip install --upgrade pip" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "### Listado de paquetes instalados.\n", 154 | "\n", 155 | "El gestor ```pip``` permite desplegar un listado de los paquetes que se han instalado utuilizando esta herramienta utilizando el subcomando ```list```.\n", 156 | "\n", 157 | "``` bash\n", 158 | "$ pip list\n", 159 | "```" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "**Ejemplo:**" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "!pip list" 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "metadata": {}, 181 | "source": [ 182 | "### Desinstalación de paquetes.\n", 183 | "\n", 184 | "Para desinstalar un paquete se utiliza el subcomando ```uninstall```.\n", 185 | "\n", 186 | "``` bash\n", 187 | "$ pip uninstall ... \n", 188 | "```\n", 189 | "\n", 190 | "**Nota:** Antes de desinstalar los paquetes, ```pip``` pregunta si en realidad se quiere realizar esa operación. Para indicarle a ```pip``` que realice dicha operación sin preguntar, se utiliza la opción. ```-y```." 191 | ] 192 | }, 193 | { 194 | "cell_type": "markdown", 195 | "metadata": {}, 196 | "source": [ 197 | "**Ejemplo:**\n", 198 | "\n", 199 | "Se desinstalará el paquete ```networkx```." 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": null, 205 | "metadata": {}, 206 | "outputs": [], 207 | "source": [ 208 | "!pip uninstall networkx -y" 209 | ] 210 | }, 211 | { 212 | "cell_type": "markdown", 213 | "metadata": {}, 214 | "source": [ 215 | "### Documentación adicional sobre ```pip```.\n", 216 | "\n", 217 | "El gestor ```pip``` cuenta con más subcomando y opciones avanzadas que pueden ser consultadas en https://pip.pypa.io/en/stable/." 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": { 223 | "collapsed": true 224 | }, 225 | "source": [ 226 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 227 | "

© José Luis Chiquete Valdivieso. 2020.

" 228 | ] 229 | } 230 | ], 231 | "metadata": { 232 | "kernelspec": { 233 | "display_name": "Python 3", 234 | "language": "python", 235 | "name": "python3" 236 | }, 237 | "language_info": { 238 | "codemirror_mode": { 239 | "name": "ipython", 240 | "version": 3 241 | }, 242 | "file_extension": ".py", 243 | "mimetype": "text/x-python", 244 | "name": "python", 245 | "nbconvert_exporter": "python", 246 | "pygments_lexer": "ipython3", 247 | "version": "3.8.5" 248 | } 249 | }, 250 | "nbformat": 4, 251 | "nbformat_minor": 1 252 | } 253 | -------------------------------------------------------------------------------- /30_entornos_virtuales.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Entornos virtuales.\n", 15 | "\n", 16 | "Cuando se tiene varios proyectos de desarrollo en Python es muy conveniente separar las bibliotecas que utiliza un proyecto en particular de las bibliotecas principales del sistema, en especial cuando los usuarios no cuentan con permisos de administrador." 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "**NOTA:**\n", 24 | "En el caso de estar usando la máquina virtual de Pythonista®, el sistema ya se encuentra utilizando un entorno virtual localizado en ```/home/oi/pythonista/```. En el caso de estar usando Anaconda, ésta genera su propio entorno virtual mediante ```conda```." 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "## Directorios de busqueda de bibliotecas de módulos.\n", 32 | "Como se discutió previamente, Python define las rutas en las cuales puede acceder a las diveras bibliotecas de módulos, las cuales pueden ser consultadas y/o modificadas mediante ```sys.path```." 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "from sys import path \n", 42 | "path" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "Los entornos virtuales permiten indicarle a Python que utilice otra ruta por defecto desde la línea de comando o el símbolo del sistema." 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "### El paquete ```virtualenv```.\n", 57 | "\n", 58 | "Este paquete copia los elementos mínimos para conformar una biblioteca de Python en el directorio indicado, incluyendo una versión propia de ```pip``` y ```setuptools```." 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": null, 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "!pip install virtualenv" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": null, 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "!mkdir prueba" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": null, 82 | "metadata": { 83 | "scrolled": false 84 | }, 85 | "outputs": [], 86 | "source": [ 87 | "!virtualenv prueba" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "### Habilitando el entorno virtual.\n", 95 | "Para habilitar el nuevo entorno virtual, es necesario modificar las variables de entorno desde una terminal. Estas modificaciones sólo tendrán efecto en la terminal en cuestión.\n", 96 | "\n", 97 | "#### Para Linux y MacOS X:\n", 98 | "```\n", 99 | "source /bin/activate\n", 100 | "```\n", 101 | "\n", 102 | "#### Para Windows:\n", 103 | "\n", 104 | "```\n", 105 | "\\bin\\activate\n", 106 | "```\n", 107 | "\n", 108 | "Una vez que el entorno está habilitado, todos los paquetes instalados mediante *pip*, se instalarán en el directorio del entorno virtual, dejando la biblioteca principal del sistema, intacta. " 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "**Ejemplo:**\n", 116 | "\n", 117 | "Para habilitar al entorno virtual localizado en [```prueba```](prueba) es necesario ejecutar lo siguiente desde una terminal en Linux desde el directorio en el que se encuentra esta notebook.\n", 118 | "\n", 119 | "Para conocer el directorio en el se se encuentra la notebook se utiliza el siguiente comando mágico de Jupyter:" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": null, 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "%pwd" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "* Para Linux y MacOS X" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "``` bash \n", 143 | "$ source prueba/bin/activate\n", 144 | "```" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "* Para Windows:" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": {}, 157 | "source": [ 158 | "```\n", 159 | "prueba\\Scripts\\activate\n", 160 | "```" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": {}, 166 | "source": [ 167 | "**Advertencia:** \n", 168 | "\n", 169 | "En caso de tratar de activar un entorno virtual desde una notebook de Jupyter, la celda desde la que se ejecutaría el comando ```source```, esta se bloqueará y deberá reiniciar el kernel." 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": {}, 175 | "source": [ 176 | "### Deshabilitando el entorno virtual.\n", 177 | "\n", 178 | "Para salir del entorno virtual se utiliza el comando ```deactivate``` en cualquier plataforma." 179 | ] 180 | }, 181 | { 182 | "cell_type": "markdown", 183 | "metadata": {}, 184 | "source": [ 185 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 186 | "

© José Luis Chiquete Valdivieso. 2020.

" 187 | ] 188 | } 189 | ], 190 | "metadata": { 191 | "kernelspec": { 192 | "display_name": "Python 3", 193 | "language": "python", 194 | "name": "python3" 195 | }, 196 | "language_info": { 197 | "codemirror_mode": { 198 | "name": "ipython", 199 | "version": 3 200 | }, 201 | "file_extension": ".py", 202 | "mimetype": "text/x-python", 203 | "name": "python", 204 | "nbconvert_exporter": "python", 205 | "pygments_lexer": "ipython3", 206 | "version": "3.8.5" 207 | } 208 | }, 209 | "nbformat": 4, 210 | "nbformat_minor": 1 211 | } 212 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Pythonista® 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![imagenes](imagenes/pythonista.png)](https://pythonista.mx) 2 | 3 | # py101 Introducción a Python 3. 4 | 5 | ## Temario: 6 | 7 | * Introducción al lenguaje Python. 8 | * Palabras reservadas, nombres y espacio de nombres. 9 | * Expresiones y declaraciones. 10 | * Tipos de datos. 11 | * Colecciones. 12 | * Expresiones con operadores. 13 | * Conversión de tipos. 14 | * Introspección. 15 | * Entrada y salida estándar. 16 | * Flujo de ejecución y comentarios. 17 | * Condicionales. 18 | * Ciclos e interrupciones de ejecución. 19 | * Iteraciones. 20 | * Objetos tipo ```list``` y tipo ```tuple```. 21 | * Objetos tipo ```dict```. 22 | * Objetos tipo ```str``` y ```bytes```. 23 | * Objetos tipo ```set``` y ```frozenset```. 24 | * Funciones. 25 | * Gestión de excepciones. 26 | * Iteradores y generadores. 27 | * Completado de elementos. 28 | * Escritura y lectura de archivos. 29 | * Módulos y paquetes. 30 | * Gestión de módulos y paquetes con pip. 31 | * Creación de paquetes con setuptools. 32 | * Entornos virtuales. 33 | 34 | ## Descarga de los apuntes. 35 | 36 | Para descargar los apuntes ejecute el siguiente comando: 37 | ``` 38 | git clone https://github.com/PythonistaMX/py101.git 39 | ``` 40 | 41 | ## La máquina virtual de Pythonista® 42 | 43 | Para poder aprovechar por completo el código de los apuntes, se recomienda descargar y ejecutar desde VirtualBox la imagen que se encuentra disponible en https://pythonista.io/descargas/base/view. 44 | 45 | 46 |

Licencia Creative Commons
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

47 |

© José Luis Chiquete Valdivieso. 2019.

-------------------------------------------------------------------------------- /formatos.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![pythonista.io](imagenes/pythonista.png)](https://www.pythonista.io)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# Entrada y salida estándar." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "En la actualidad existen muchas fuentes desde las que se puede obtener y desplegar la información que un sistema de cómputo consume, gestiona y genera. Sin embargo, para el intérprete de Python la salida por defecto (salida estándar) de datos es la terminal de texto y la entrada estándar es el teclado.\n", 22 | "\n", 23 | "En el caso de las notebooks de *Jupyter*, cada celda de código representa a la entrada estándar mediante:\n", 24 | "\n", 25 | "```In[ ]:```\n", 26 | "\n", 27 | "Y la salida estándar mediante:\n", 28 | "\n", 29 | "```Out[ ]:```" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "**Ejemplo:**" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "* La siguiente celds desplegará el resultado de la expesión ```3 * \"Hola\"```. " 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | " 3 * \"Hola\"" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "## Salida estándar con la funcion ```print()```.\n", 60 | "\n", 61 | "En Python 3, la función ```print()``` se utiliza para desplegar información en la salida estándar.\n", 62 | "\n", 63 | "La sintaxis es la siguiente:\n", 64 | "\n", 65 | "```\n", 66 | "print(, , ...)\n", 67 | "```\n", 68 | "\n", 69 | "* La función ```print()``` evalúa y despliega una o varias expresiones.\n", 70 | "* Si el resultado de la expresión es un objeto ```str```, este es desplegado sin los apóstrofes o las comillas que lo delimitan." 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "**Ejemplos:**" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "* La siguiente celda define el nombre ```a``` con valor igual a ```2```." 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "metadata": {}, 91 | "outputs": [], 92 | "source": [ 93 | "a = 2" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "* La siguiente celda evalúa la expresión ```a```, por lo que desplegará ```2```." 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "metadata": { 107 | "scrolled": false 108 | }, 109 | "outputs": [], 110 | "source": [ 111 | "print(a)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "* La siguiente celda desplegará el mensaje dentro del objeto ```\"Hola\"```." 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "metadata": {}, 125 | "outputs": [], 126 | "source": [ 127 | "print(\"Hola\")" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": {}, 133 | "source": [ 134 | "* En la siguiente celda la función ```print()``` desplegará dos expresiones que corresponde cada una a un objeto de tipo ```str```. Cada objeto será desplegado separado por un espacio.\n", 135 | "\n", 136 | "* La salida será ```Hola Mundo```." 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": null, 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "print(\"Hola\", \"Mundo \" * 3)" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "metadata": {}, 151 | "source": [ 152 | "* En la siguiente celda la función ```print()``` desplegará el resultado de una expresión de concatenación entre dos objetos de tipo ```str```. El resultado es un objeto ```str```.\n", 153 | "\n", 154 | "* La salida será ```HolaMundo```." 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": null, 160 | "metadata": {}, 161 | "outputs": [], 162 | "source": [ 163 | "print(\"Hola\" + \"Mundo\")" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": {}, 169 | "source": [ 170 | "* En la siguiente celda la función ```print()``` desplegará tres expresiones que corresponden a:\n", 171 | " * El objeto ```'Tienes'``` de tipo ```str```.\n", 172 | " * El objeto de nombre ```a```.\n", 173 | " * El objeto ```'buenos amigos'``` de tipo ```str```.\n", 174 | "\n", 175 | "Cada expresión será desplegada separada por un espacio.\n", 176 | "\n", 177 | "* La salida será ```Tienes 2 buenos amigos.```." 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": null, 183 | "metadata": {}, 184 | "outputs": [], 185 | "source": [ 186 | "print(\"Tienes\", a, \"buenos amigos.\")" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "* En la siguiente celda la función ```print()``` intentará desplegar el resultado de la expresión ```\"Tienes\" + a + \"buenos amigos.\"```, la cual no es correcta y generará un error de tipo ```TypeError```." 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": null, 199 | "metadata": { 200 | "scrolled": true 201 | }, 202 | "outputs": [], 203 | "source": [ 204 | "print(\"Tienes\" + a + \"buenos amigos.\")" 205 | ] 206 | }, 207 | { 208 | "cell_type": "markdown", 209 | "metadata": {}, 210 | "source": [ 211 | "## Despliegue con formato de los objetos ```str```.\n", 212 | "\n", 213 | "Los objetos ```str``` permiten insertar las representaciones de otros objetos dentro de ellos mismos de 3 formas:\n", 214 | "\n", 215 | "* El uso del caracter de escape ```%```.\n", 216 | "* El método ```format()```, el cual se estudiará más adelante.\n", 217 | "* A partir de Python 3.6 se incluye el usos de \"f-strings\", las cuales son descritas en el [*PEP 498*](https://www.python.org/dev/peps/pep-0498/) y se explorarán más adelante." 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": {}, 223 | "source": [ 224 | "### Inserción de objetos con formato en objetos ```str``` mediante el caracter de escape ```%```.\n", 225 | "\n", 226 | "\n", 227 | "Para intercalar valores dentro de un formato específico de texto se utiliza el caracter sobre-escritura definido como el signo de porcentaje ```%``` seguido de algún caracter que definirá el modo de desplegar la expresión correspondiente.\n", 228 | "\n", 229 | "```\n", 230 | "\"...%...\" % expresión 1) \n", 231 | "```\n", 232 | "\n", 233 | "```\n", 234 | "\"...%...%...\" %(,...)\n", 235 | "```\n", 236 | "|Caracter de escape|Modo de despliegue|\n", 237 | "|:----------------:|:----------------:|\n", 238 | "|```%s```|\tcadena de texto|\n", 239 | "|```%d```|\t entero|\n", 240 | "|```%o```|\t octal|\n", 241 | "|```%x```|\t hexadecimal|\n", 242 | "|```%f```|\t punto flotante|\n", 243 | "|```%e```|\t punto flotante en formato exponencial| \n", 244 | "\n", 245 | "El uso de ```%s```, equivale a aplicar la función ```str()``` al valor a desplegar.\n", 246 | "\n", 247 | "Para desplegar el signo de porcentaje ```%``` se utiliza ```%%```." 248 | ] 249 | }, 250 | { 251 | "cell_type": "markdown", 252 | "metadata": {}, 253 | "source": [ 254 | "**Ejemplos:**" 255 | ] 256 | }, 257 | { 258 | "cell_type": "markdown", 259 | "metadata": {}, 260 | "source": [ 261 | "* La siguiente celda definirán los objetos ```pi``` y ```radio```." 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "execution_count": null, 267 | "metadata": {}, 268 | "outputs": [], 269 | "source": [ 270 | "pi = 3.141592\n", 271 | "radio = 2" 272 | ] 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "metadata": {}, 277 | "source": [ 278 | "* Las siguientes celdas desplegarán en formatos distintos las expresiones correspondientes." 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": null, 284 | "metadata": {}, 285 | "outputs": [], 286 | "source": [ 287 | "print(\"El perímetro de un círculo de radio %d es %f.\" % (radio, 2 * radio * pi))" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": null, 293 | "metadata": {}, 294 | "outputs": [], 295 | "source": [ 296 | "print(\"El perímetro de un círculo de radio %d es %d.\" % (radio, 2 * radio * pi))" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": null, 302 | "metadata": {}, 303 | "outputs": [], 304 | "source": [ 305 | "print(\"El perímetro de un circulo de radio %s es %s.\" % (radio, 2 * radio * pi))" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": null, 311 | "metadata": {}, 312 | "outputs": [], 313 | "source": [ 314 | "print(\"El valor de pi es %f.\" % (pi))" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": null, 320 | "metadata": {}, 321 | "outputs": [], 322 | "source": [ 323 | "print(\"El valor de pi es %e.\" % pi)" 324 | ] 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "metadata": {}, 329 | "source": [ 330 | "La siguiente celda incluye varias expresiones que definen a los objetos ```valor```, ```porciento``` y ```porcentaje```. Dichos objetos serán desplegados dentro de un objeto ```str``` usando el caracter de escape ```%``` y el signo de porcentaje usando ```%%```." 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": null, 336 | "metadata": { 337 | "scrolled": true 338 | }, 339 | "outputs": [], 340 | "source": [ 341 | "# Esta celda desplegará varias expresiones usando diversos formatos.\n", 342 | "valor = 13\n", 343 | "porciento = 15\n", 344 | "porcentaje = (valor * porciento) / 100\n", 345 | "print(\"El %d%% de %f es %f.\" % (porciento, valor, porcentaje))" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "#### Despliegue de cifras significativas.\n", 353 | "\n", 354 | "Para desplegar un número específico de cifras significativas de un valor de punto flotante, se añade un punto ```.``` y el número de cifras a desplegarse después del signo de porcentaje ```%``` y antes del carácter ```f``` o ```e```.\n", 355 | "\n", 356 | "```\n", 357 | "\" %.f \"\n", 358 | "```\n", 359 | "\n", 360 | "Donde:\n", 361 | "\n", 362 | "`````` es el número de decimales que serán desplegados." 363 | ] 364 | }, 365 | { 366 | "cell_type": "markdown", 367 | "metadata": {}, 368 | "source": [ 369 | "**Ejemplos:**" 370 | ] 371 | }, 372 | { 373 | "cell_type": "markdown", 374 | "metadata": {}, 375 | "source": [ 376 | "* La siguiente celda definirán los objetos ```pi``` y ```radio```." 377 | ] 378 | }, 379 | { 380 | "cell_type": "code", 381 | "execution_count": null, 382 | "metadata": {}, 383 | "outputs": [], 384 | "source": [ 385 | "pi = 3.14169265\n", 386 | "radio = 2" 387 | ] 388 | }, 389 | { 390 | "cell_type": "markdown", 391 | "metadata": {}, 392 | "source": [ 393 | "* Las siguientes celdas desplegarán de formas distintas las expresiones ```radio``` y ```2 * pi * radio```." 394 | ] 395 | }, 396 | { 397 | "cell_type": "code", 398 | "execution_count": null, 399 | "metadata": {}, 400 | "outputs": [], 401 | "source": [ 402 | "print(\"El perímetro de un círculo de radio igual a %d es %f.\" % (radio, 2 * pi * radio))" 403 | ] 404 | }, 405 | { 406 | "cell_type": "code", 407 | "execution_count": null, 408 | "metadata": {}, 409 | "outputs": [], 410 | "source": [ 411 | "print(\"El perímetro de un círculo de radio igual a %d es %.2f.\" % (radio, 2 * pi * radio))" 412 | ] 413 | }, 414 | { 415 | "cell_type": "markdown", 416 | "metadata": {}, 417 | "source": [ 418 | "### Caracteres de escape.\n", 419 | "\n", 420 | "Existen algunos caracteres que por su función o por la sintaxis de Python, tales como los apóstrofes, las comillas, los retornos de línea; que deben de utilizar un \"caracter de escape\", para que puedan ser desplegados. Los caracteres de escape pueden ser introducidos después de una diagonal invertida ```\\```. \n", 421 | "\n", 422 | "Estos caracteres de escape son usados en cinjubto con la función ```print()```.\n", 423 | "\n", 424 | "|Secuencia|Despliegue|\n", 425 | "|:-------:|:--------:|\n", 426 | "|```\\n``` |Retorno de línea|\n", 427 | "|```\\t``` |Tabulador |\n", 428 | "|```\\\"``` |Comillas |\n", 429 | "|```\\'``` |Apóstrofe |\n", 430 | "|```\\\\``` |Diagonal invertida|\n", 431 | "|```\\xNN``` |Caracter que corresponde al número hexadecimal *NN* en ASCII|\n", 432 | "|```\\uNNNN``` |Caracter que corresponde al número hexadecimal *NN* en Unicode|" 433 | ] 434 | }, 435 | { 436 | "cell_type": "markdown", 437 | "metadata": {}, 438 | "source": [ 439 | "**Ejemplos:**" 440 | ] 441 | }, 442 | { 443 | "cell_type": "markdown", 444 | "metadata": {}, 445 | "source": [ 446 | "* Las siguientes celdas desplegarán cadenas de caracteres que incluyen caracteres de escape." 447 | ] 448 | }, 449 | { 450 | "cell_type": "code", 451 | "execution_count": null, 452 | "metadata": {}, 453 | "outputs": [], 454 | "source": [ 455 | "print(\"Primera línea.\\nSegunda línea\\t con tabulador.\")" 456 | ] 457 | }, 458 | { 459 | "cell_type": "code", 460 | "execution_count": null, 461 | "metadata": {}, 462 | "outputs": [], 463 | "source": [ 464 | "print(\"Este es el signo de \\\"gato\\\" \\x23.\")" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": null, 470 | "metadata": {}, 471 | "outputs": [], 472 | "source": [ 473 | "print(\"Beta: \\u00DF\")" 474 | ] 475 | }, 476 | { 477 | "cell_type": "code", 478 | "execution_count": null, 479 | "metadata": {}, 480 | "outputs": [], 481 | "source": [ 482 | "print('I \\u2764 YOU!')" 483 | ] 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "metadata": {}, 488 | "source": [ 489 | "## Entrada estándar con la función ```input()```. \n", 490 | "\n", 491 | "La función por defecto de entrada estándar para Python 3 es ```input()```.\n", 492 | "\n", 493 | "La función ```input()``` captura los caracteres provenientes de entrada estándar (el teclado) hasta que se introduce un retorno de carro Intro y el contenido capturado es devuelto al intérprete como una cadena de texto. \n", 494 | "\n", 495 | "La cadena de caracteres resultante puede ser almacenada como un objeto de tipo ```str``` mediante la asignación de un nombre.\n", 496 | "\n", 497 | "La función permite desplegar un mensaje de tipo ```str``` como parámetro.\n", 498 | "\n", 499 | "``` \n", 500 | "input()\n", 501 | "```" 502 | ] 503 | }, 504 | { 505 | "cell_type": "markdown", 506 | "metadata": {}, 507 | "source": [ 508 | "**Ejemplos:**" 509 | ] 510 | }, 511 | { 512 | "cell_type": "markdown", 513 | "metadata": {}, 514 | "source": [ 515 | "* La siguiente celda ejecutará a la función ```input()```, la cual pedirá que se ingresen datos e Intro. Dicha función regresará la cadena de caracteres capturada como un objeto de tipo ```str```." 516 | ] 517 | }, 518 | { 519 | "cell_type": "code", 520 | "execution_count": null, 521 | "metadata": {}, 522 | "outputs": [], 523 | "source": [ 524 | "input()" 525 | ] 526 | }, 527 | { 528 | "cell_type": "markdown", 529 | "metadata": {}, 530 | "source": [ 531 | "* La siguiente celda ejecutará a la función ```input()```, la cual pedirá que se ingresen datos e Intro. Al objeto ```str``` resultante se le asignará el nombre de ```texto```." 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "execution_count": null, 537 | "metadata": {}, 538 | "outputs": [], 539 | "source": [ 540 | "texto = input()" 541 | ] 542 | }, 543 | { 544 | "cell_type": "code", 545 | "execution_count": null, 546 | "metadata": {}, 547 | "outputs": [], 548 | "source": [ 549 | "type(texto)" 550 | ] 551 | }, 552 | { 553 | "cell_type": "code", 554 | "execution_count": null, 555 | "metadata": {}, 556 | "outputs": [], 557 | "source": [ 558 | "texto" 559 | ] 560 | }, 561 | { 562 | "cell_type": "code", 563 | "execution_count": null, 564 | "metadata": {}, 565 | "outputs": [], 566 | "source": [ 567 | "print(texto)" 568 | ] 569 | }, 570 | { 571 | "cell_type": "markdown", 572 | "metadata": {}, 573 | "source": [ 574 | "* La siguiente celda ejecutará a la función ```input()```, desplegando el mensaje ```Escribe un nombre: ```, la cual pedirá que se ingresen datos e Intro. Al objeto ```str``` resultante se le asignará el nombre de ```nombre```." 575 | ] 576 | }, 577 | { 578 | "cell_type": "code", 579 | "execution_count": null, 580 | "metadata": {}, 581 | "outputs": [], 582 | "source": [ 583 | "nombre = input(\"Escribe un nombre: \")" 584 | ] 585 | }, 586 | { 587 | "cell_type": "code", 588 | "execution_count": null, 589 | "metadata": {}, 590 | "outputs": [], 591 | "source": [ 592 | "print(nombre)" 593 | ] 594 | }, 595 | { 596 | "cell_type": "markdown", 597 | "metadata": {}, 598 | "source": [ 599 | "## Entrada y salida estándar en Python 2." 600 | ] 601 | }, 602 | { 603 | "cell_type": "markdown", 604 | "metadata": {}, 605 | "source": [ 606 | "\n", 607 | "### La función ```raw_input()```.\n", 608 | "\n", 609 | "La sintaxis es la siguiente para Python 2:\n", 610 | "\n", 611 | "``` \n", 612 | "raw_input()\n", 613 | "```\n", 614 | "\n", 615 | "**Ejemplo:**\n", 616 | "\n", 617 | "``` python\n", 618 | ">>> raw_input()\n", 619 | "Hola\n", 620 | "'Hola'\n", 621 | ">>> texto = raw_input()\n", 622 | "Hola\n", 623 | ">>> type(texto)\n", 624 | "\n", 625 | ">>> print texto\n", 626 | "Hola\n", 627 | ">>> nombre = raw_input(\"Escribe un nombre: \")\n", 628 | "Escribe un nombre: Juan\n", 629 | ">>> print nombre\n", 630 | "Juan\n", 631 | ">>> \n", 632 | "```\n", 633 | "### La función ```input()``` en Python 2.\n", 634 | "\n", 635 | "Además de ```raw_input()```, existe la función ```input()```, la cual es semejante a ejecutar ```eval(raw_input())```.\n", 636 | "\n", 637 | "Si la expresión ingresada es correcta, La función ```input()``` puede regresar valores de diversos tipos, en vez de sólo cadenas de texto.\n", 638 | "\n", 639 | "**Ejemplo:**\n", 640 | "\n", 641 | "``` python\n", 642 | ">>> mensaje = \"Ingresa el texto: \"\n", 643 | ">>> valor = raw_input(mensaje)\n", 644 | "Ingresa el texto: 35 + 21\n", 645 | ">>> type(valor)\n", 646 | "\n", 647 | ">>> print valor\n", 648 | "35 + 21\n", 649 | ">>> valor = input(mensaje)\n", 650 | "Ingresa el texto: 35 + 21\n", 651 | ">>> type(valor)\n", 652 | "\n", 653 | ">>> print valor\n", 654 | "56\n", 655 | ">>> valor = input(mensaje)\n", 656 | "Ingresa el texto: \"Hola\"\n", 657 | ">>> type(valor)\n", 658 | "\n", 659 | ">>> print valor\n", 660 | "Hola\n", 661 | ">>> valor = input(mensaje)\n", 662 | "Ingresa el texto: Hola\n", 663 | "Traceback (most recent call last):\n", 664 | " File \"\", line 1, in \n", 665 | " File \"\", line 1, in \n", 666 | "NameError: name 'Hola' is not defined\n", 667 | ">>>\n", 668 | "```\n", 669 | "**NOTA:** La función ```input()```, tal como se usa en Python 2 tiene el potencial de generar diversos errores y es susceptible de vulnerabilidades de seguridad debido a que podría usarse para inyectar código malicioso. Es por eso por lo que en Python 3, ```input()``` se comporta como ```raw_input()``` y la función ```raw_input()``` fue desechada." 670 | ] 671 | }, 672 | { 673 | "cell_type": "markdown", 674 | "metadata": {}, 675 | "source": [ 676 | "

\"Licencia
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.

\n", 677 | "

© José Luis Chiquete Valdivieso. 2020.

" 678 | ] 679 | } 680 | ], 681 | "metadata": { 682 | "kernelspec": { 683 | "display_name": "Python 3", 684 | "language": "python", 685 | "name": "python3" 686 | }, 687 | "language_info": { 688 | "codemirror_mode": { 689 | "name": "ipython", 690 | "version": 3 691 | }, 692 | "file_extension": ".py", 693 | "mimetype": "text/x-python", 694 | "name": "python", 695 | "nbconvert_exporter": "python", 696 | "pygments_lexer": "ipython3", 697 | "version": "3.8.5" 698 | } 699 | }, 700 | "nbformat": 4, 701 | "nbformat_minor": 1 702 | } 703 | -------------------------------------------------------------------------------- /imagenes/conjuntos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/conjuntos.png -------------------------------------------------------------------------------- /imagenes/difference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/difference.png -------------------------------------------------------------------------------- /imagenes/excepciones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/excepciones.png -------------------------------------------------------------------------------- /imagenes/idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/idle.png -------------------------------------------------------------------------------- /imagenes/if-elif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/if-elif.png -------------------------------------------------------------------------------- /imagenes/if-else.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/if-else.png -------------------------------------------------------------------------------- /imagenes/if-simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/if-simple.png -------------------------------------------------------------------------------- /imagenes/intersection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/intersection.png -------------------------------------------------------------------------------- /imagenes/isdisjoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/isdisjoint.png -------------------------------------------------------------------------------- /imagenes/issubset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/issubset.png -------------------------------------------------------------------------------- /imagenes/issuperset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/issuperset.png -------------------------------------------------------------------------------- /imagenes/pythonista.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/pythonista.png -------------------------------------------------------------------------------- /imagenes/symmetric_difference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/symmetric_difference.png -------------------------------------------------------------------------------- /imagenes/union.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/union.png -------------------------------------------------------------------------------- /imagenes/while-break.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/while-break.png -------------------------------------------------------------------------------- /imagenes/while-continue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/while-continue.png -------------------------------------------------------------------------------- /imagenes/while-exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/while-exit.png -------------------------------------------------------------------------------- /imagenes/while.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonistaMX/py101/fa5e2c55f03297fba19397c6954683317cdb18cd/imagenes/while.png -------------------------------------------------------------------------------- /modulo.py: -------------------------------------------------------------------------------- 1 | #! /bin/bash/python3 2 | 3 | '''Ejemplo de un script que puede ser importado como módulo.''' 4 | 5 | titulo = "Espacio muestral" 6 | datos = (76, 81, 75, 77, 80, 75, 76, 79, 75) 7 | 8 | def promedio(encabezado, muestra): 9 | '''Despliega el contenido de encabezado,así como el cálculo del promedio de muestra, ingresado en una lista o tupla.''' 10 | print("El promedio de %s con %d elementos es %f." % (encabezado, len(muestra), sum(muestra) / len(muestra))) 11 | 12 | promedio(titulo, datos) -------------------------------------------------------------------------------- /modulo2.py: -------------------------------------------------------------------------------- 1 | #! /bin/bash/python3 2 | 3 | '''Ejemplo de un script que puede ser importado como módulo y comportarse de forma diferenciada.''' 4 | 5 | titulo = "Espacio muestral" 6 | datos = (76, 81, 75, 77, 80, 75, 76, 79, 75) 7 | 8 | def promedio(encabezado, muestra): 9 | '''Despliega el contenido de encabezado,así como el cálculo del promedio de muestra, 10 | ingresado en una lista o tupla.''' 11 | print("El promedio de %s con %d elementos es %f." % (titulo, len(muestra), sum(muestra) / len(muestra))) 12 | 13 | if __name__ == "__main__": 14 | print(__name__) 15 | promedio(titulo, datos) -------------------------------------------------------------------------------- /paquete/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3 2 | '''Paquete que incluye un par de módulos''' 3 | 4 | def saluda(): 5 | print('Bienvenido a paquete.') -------------------------------------------------------------------------------- /paquete/primos/__init__.py: -------------------------------------------------------------------------------- 1 | '''Paquete que incluye un módulo que calcula números primos.''' -------------------------------------------------------------------------------- /paquete/primos/funciones.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3 2 | '''Funciones que calculan número primos.''' 3 | 4 | def esprimo(lista, numero): 5 | '''Valida si numero es divisible entre algún elemento de lista. De ocurrir, 6 | regresa False. De lo contrario, regresa True.''' 7 | for primo in lista: 8 | if numero % primo == 0: 9 | return False 10 | return True 11 | 12 | 13 | def lista_primos(limite): 14 | '''Genera una lista de los números primos comprendidos entre el 2 y el valor de limite.''' 15 | #La lista inicia con el número 2 16 | lista = [2] 17 | #Se realizará una iteración de cada número entero desde 3 hasta el valor de limite. 18 | for numero in range(3, limite + 1): 19 | #Si esprimo(numero) regresa True, añade el valor de numero a lista 20 | if esprimo(lista, numero): 21 | lista.append(numero) 22 | return lista 23 | 24 | 25 | def gen_primos(): 26 | """ Generador de números primos.""" 27 | contador = 1 28 | lista_primos=[] 29 | # Comienza una secuencia infinita. 30 | while True: 31 | primo = True 32 | contador += 1 33 | if len(lista_primos) > 0: 34 | primo = esprimo(lista_primos, contador) 35 | if primo: 36 | lista_primos.append(contador) 37 | yield contador -------------------------------------------------------------------------------- /paquete/promedios.py: -------------------------------------------------------------------------------- 1 | '''Funciones que calculan el promedio de una serie arbitaria de números.''' 2 | 3 | def promedio(*muestras): 4 | '''Calcula el promedio de la muestra correspondiente a todos los parámetros ingresados.''' 5 | print(promedio = sum(muestras)/len(muestras)) 6 | 7 | def promedio_titulo(titulo, *muestras): 8 | '''Calcula el promedio de la muestra correspondiente a todos los parámetros ingresados con excepción 9 | del primero, el cual será utilizado como título.''' 10 | promedio = sum(muestras)/len(muestras) 11 | print(titulo) 12 | print('El promedio de la muestra de %d elementos es %.3f.' %(len(muestras), promedio)) 13 | 14 | if __name__ == "__main__": 15 | promedio_titulo("Muestra de demostración", 16, 15.5, 17.2, 18.6, 15.3, 16.7, 18, 16.1, 17,2) -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | setup( 3 | name="paquete", 4 | version=0.1, 5 | packages=find_packages(), 6 | ) 7 | -------------------------------------------------------------------------------- /src/expresiones.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 4 * 3 3 | 15 == 25 4 | 'hola' + ' mundo' -------------------------------------------------------------------------------- /src/expresiones_impresas.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | print(4 * 3) 4 | print(15 == 25) 5 | print('hola' + ' mundo') -------------------------------------------------------------------------------- /src/holamundo.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | print("Hola, Mundo.") 3 | -------------------------------------------------------------------------------- /src/holamundo2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | print("Hola, Mundo.") 3 | input() -------------------------------------------------------------------------------- /src/while_exit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' Este programa se repetirá 3 veces o hasta que se ingrese 4 | la palabra "despedida" y desplegará sólo el número de intentos 5 | fallidos hasta que cualquiera de los eventos ocurentradara. Al 6 | ingresar la palabra "termina" el programa se detendrá.''' 7 | 8 | entrada = "" 9 | suma = 0 10 | while suma < 3: 11 | entrada = input("Clave:") 12 | if entrada == "despedida": 13 | break 14 | elif entrada == "termina": 15 | exit() 16 | suma = suma + 1 17 | print("Intento %d. \n " % suma) 18 | print("Tuviste %d intentos fallidos." % suma) 19 | --------------------------------------------------------------------------------