├── .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 | "[](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 ```
© 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 | "[](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(
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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(
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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 | "(
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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 | "
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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 | "
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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 | "
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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'...{
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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'
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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 ```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 | ".'''\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
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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 | "
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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 | "[
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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=
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | "[](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
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | [](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 |
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© José Luis Chiquete Valdivieso. 2019.
-------------------------------------------------------------------------------- /formatos.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[](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(
Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional.
© 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 | --------------------------------------------------------------------------------