.. _clase_01:
==================================
Clase 1: Introducción al lenguaje
==================================
========================
Cómo empezar: Instalación y uso
===============================
**Python** es un lenguaje de programación interpretado, que se puede
ejecutar sobre distintos sistemas operativos, es decir, es
multiplataforma (suele usarse el término *cross-platform*). Además, la
mayoría de los programas que existen (y posiblemente todos los que
nosotros escribamos) pueden ejecutarse tanto en Linux como en windows y
en Mac sin realizar ningún cambio.
Instalación
-----------
En este curso utilizaremos **Python 3**.
**Nota:** Existe una versión anterior de Python, **Python2.X**
(Python 2) cuya fecha de finalización de soporte fue el 1/1/2020. Fue
una una versión madura, estable, y con muchas aplicaciones, y
utilidades disponibles, sin embargo ya no se desarrolla ni se
corrigen los errores ni problemas de seguridad.
La instalación `oficial `__ de Python
provee lo necesario para utilizar el lenguaje. Sin embargo, con el
correr del tiempo, se han creado otras `muchas distribuciones de
Python `__ que
incluyen aplicaciones y bibliotecas de uso común.
Estas distribuciones son implementaciones del lenguaje basadas en
CPython, es decir, en C y Python. Existen otras implementaciones,
como por ejemplo `PyPy `__.
Para una instalación fácil de Python y los paquetes más comunes se
pueden usar alguna de las distribuciones:
- `Anaconda `__. (Linux,
Windows, MacOs)
- `ActiveState `__
- `Winpython `__. (Windows)
En este curso utilizaremos Anaconda, en su versión minimalista,
`miniconda `__. La diferencia más
importante es la cantidad de paquetes que instala cada distribución
inicialmente. Además, Anaconda provee una aplicación (Anaconda
Navigator) para el manejo de paquetes.
En el curso el manejo de paquetes se realizará mediante la línea de
comando y los *ambientes* de Python.
Linux
~~~~~
En la terminal,
.. code:: bash
mkdir -p ~/miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
rm ~/miniconda3/miniconda.sh
Eventualmente, en linux se podría instalar directamente todo lo
necesario desde los repositorios. Por ejemplo en Ubuntu:
.. code:: bash
sudo apt-get install ipython3 ipython3-notebook spyder python3-matplotlib python3-numpy python3-scipy
o, en Fedora 28, en adelante:
.. code:: bash
sudo dnf install python3-ipython python3-notebook python3-matplotlib python3-numpy python3-scipy
Obviamente esto tiene un alcance global para todos los usuarios.
Dependiendo de los casos de uso, será útil una u otra opción.
Windows
~~~~~~~
La instalación es bastante sencilla, bajando el instalador
`acá `__ o usando ``curl``:
.. code:: cmd
curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe -o miniconda.exe
start /wait "" .\miniconda.exe /S
del miniconda.exe
..
Atención! Pueden existir problemas si el nombre del usuario en
Windows contiene espacios.
Una vez instalado miniconda, veremos dos nuevos acceso directos en el
menú
.. image:: figuras/miniconda.png
que corresponden a los dos tipos de terminales que instala miniconda.
Por defecto, miniconda no agrega Python al PATH, por lo tanto,
``python`` no estará disponible en las terminales usuales
(``cmd.exe`` y PowerShell)
Edición de código
-----------------
Como todo lenguaje, se pueden utilizar distintos editores de texto
- En windows: `Notepad++ `__,
`Jedit `__, … (no Notepad o Wordpad)
- En Linux: cualquier editor de texto (gedit, geany, kate, nano, emacs,
vim, …)
- En Mac: TextEdit funciona, sino TextWrangler,
`JEdit `__, …
o IDEs:
- `Spyder `__. (IDE - También
viene con Anaconda, y con Python(x,y)).
- `Pycharm `__. (IDE, una versión
comercial y una libre, ambos con muchas funcionalidades)
- `Sublime Text `__
- `Ninja-IDE `__ (IDE *cross-platform*, libre)
y, por supuesto, `Visual Studio
Code `__. Todos estos editores ofrecen
plugins o extensiones para mejorar la experiencia de programación.
Documentación y ayudas
----------------------
Algunas fuentes de ayuda *constante* son:
- `La documentación oficial de Python `__
- En particular el `Tutorial `__,
también `en español `__ y la
`referencia de
bibliotecas `__
- En una terminal, puede obtener información sobre un paquete con
``pydoc ``
- En una consola interactiva de **Python**, mediante
``help()``
- La documentación de los paquetes:
- `Numpy `__
- `Matplotlib `__, en particular la
`galería `__
- `Scipy `__
- `Pandas `__
etc.
- Buscar “palabras clave + python” en un buscador. Es particularmente
útil el sitio `stackoverflow `__
..
Python es un lenguaje de tipos dinámicos, con lo cual las ayudas de
los IDE pueden ser en general escasas. Veremos sin embargo en el
curso algunas alternativas para poder mejorar la experiencia de
programación.
Uso de Python: Interactivo o no
-------------------------------
Interfaces interactivas (consolas/terminales, notebooks)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hay muchas maneras de usar el lenguaje Python. Es un lenguaje
**interpretado** e **interactivo**. Si ejecutamos la consola
(``cmd.exe`` en windows) y luego ``python``, se abrirá la consola
interactiva
.. image:: figuras/console.png
En la consola interactiva podemos escribir sentencias o pequeños bloques
de código que son ejecutados inmediatamente. Pero *la consola
interactiva* estándar no tiene tantas características de conveniencia
como otras, por ejemplo **IPython** que viene con “accesorios de
*comfort*”.
.. image:: figuras/ipython.png
La consola IPython supera a la estándar en muchos sentidos. Podemos
autocompletar (````), ver ayuda rápida de cualquier objeto (``?``),
etc.
Programas/scripts
~~~~~~~~~~~~~~~~~
Una forma muy común/poderosa de usar Python es en forma *no
interactiva*, escribiendo *programas* o *scripts*. Esto es, escribir
nuestro código en un archivo con extensión *.py* para luego ejecutarlo
con el intérprete. Por ejemplo, podemos crear un archivo *hello.py* (al
que se le llama *módulo*) con este contenido:
::
print("Hola Mundo!")
Si ejecutamos ``python hello.py`` o ``ipython hello.py`` se ejecutará el
interprete Python y obtendremos el resultado esperado (impresión por
pantalla de “Hola Mundo!”, sin las comillas)
**Python** no exige un editor específico y hay muchos modos y maneras de
programar. Lo que es importante al programar en **Python** es que la
*indentación* define los bloques (definición de loops, if/else,
funciones, clases, etc). Por esa razón es importante que el tabulado no
mezcle espacios con caracteres específicos de tabulación. La manera que
recomendaría es usar siempre espacios (uno usa la tecla [TAB] pero el
editor lo traduce a un número determinado de espacios). La indentación
recomendada es de **4** espacios (pero van a notar que yo uso **2**).
Un buen editor es **Spyder** que tiene características de IDE (entorno
integrado: editor + ayuda + consola interactiva).
.. image:: figuras/spyder.png
También Pycharm funciona muy bien
.. image:: figuras/pycharm.jpg
Y por supuesto, VS Code
.. image:: figuras/vscode.png
En todos los casos se puede ejecutar todo el código del archivo en la
consola interactiva que incluye. Alternativamente, también se puede
seleccionar **sólo** una porción del código para ejecutar.
Notebooks de Jupyter o Jupyter-Lab
----------------------------------
Para trabajar en forma interactiva es muy útil usar los *Notebooks* de
Jupyter. El notebook es un entorno interactivo enriquecido. Podemos
crear y editar “celdas” código Python que se pueden editar y volver a
ejecutar, se pueden intercalar celdas de texto, fórmulas matemáticas, y
hacer que los gráficos se muestren inscrutados en la misma pantalla o en
ventanas separadas. Además se puede escribir texto con formato (como
este que estamos viendo) con secciones, títulos. Estos archivos se
guardan con extensión *.ipynb*, que pueden exportarse en distintos
formatos tales como html (estáticos), en formato PDF, LaTeX, o como
código python puro. (.py)
Instalando Python interactivo
-----------------------------
Miniconda instala algunos paquetes básicos, con lo cual tenemos que ir
agregándolos. Primero instalaremos ``IPython``, la consola interactiva
de Python. Para eso utilizamos el comando ``conda``. Desde cualquiera de
las terminales de Anaconda instaladas:
.. code:: cmd
conda install ipython
Y luego instalaremos la versión más sofisticada de Python interactivo, a
través de Jupyter:
.. code:: cmd
conda install jupyter
Y obtendremos
.. image:: figuras/jupyter.png
Para usar los notebooks, simplemente cliqueamos en el nuevo acceso
directo a Jupyter Notebooks, o desde la terminal de Anaconda:
.. code:: cmd
python -m notebook
Existe una versión más moderna de Jupyter notebooks denominada
`JupyterLab `__
que puede instalarse como:
.. code:: cmd
conda install -c conda-forge jupyterlab
Una vez instalada, podemos correrla con
::
jupyter lab
desde una terminal de Anaconda.
Comandos de Jupyter (o IPython)
===============================
Comandos de Navegación
----------------------
Jupyter conoce varios de los comandos más comunes del sistema operativo.
En Jupyter (o en la terminal de Python) estos comandos funcionan
independientemente del sistema operativo (sí, incluso en windows, con
algunos *detalles*). Estos se conocen con el nombre de **comandos
mágicos** y comienzan con el signo porcentaje ``%``. Para obtener una
lista de los comandos usamos ``%lsmagic``:
.. code:: python
# Más util en IPhyton que en Jupyter
%lsmagic
.. parsed-literal::
Available line magics:
%alias %alias_magic %autoawait %autocall %automagic %autosave %bookmark %cat %cd %clear %code_wrap %colors %conda %config %connect_info %cp %debug %dhist %dirs %doctest_mode %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %lf %lk %ll %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %lx %macro %magic %mamba %man %matplotlib %micromamba %mkdir %more %mv %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %pip %popd %pprint %precision %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %rep %rerun %reset %reset_selective %rm %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode
Available cell magics:
%%! %%HTML %%SVG %%bash %%capture %%code_wrap %%debug %%file %%html %%javascript %%js %%latex %%markdown %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile
Automagic is ON, % prefix IS NOT needed for line magics.
.. code:: python
%magic
Algunos de los comandos mágicos
-------------------------------
Algunos de los comandos mágicos más importantes son:
- ``%cd`` *direct* (Nos ubica en la carpeta direct)
- ``%ls`` (muestra un listado del directorio)
- ``%pwd`` (muestra el directorio donde estamos trabajando)
- ``%run`` *filename* (corre un dado programa)
- ``%hist`` (muestra la historia de comandos utilizados)
- ``%mkdir`` *dname* (crea un directorio llamado dname)
- Tab completion: Apretando [TAB] completa los comandos o nombres de
archivos.
En la consola de IPython tipee ``%cd ~`` (*i.e.* “``%cd``” – “espacio” –
“tilde”, y luego presione [RETURN]. Esto nos pone en el directorio HOME
(default).
Después tipee ``%pwd`` (print working directory) y presione [RETURN]
para ver en qué directorio estamos:
.. code:: python
%pwd
.. parsed-literal::
'/Users/flavioc/Library/Mobile Documents/com~apple~CloudDocs/Documents/cursos/curso-python-y-datos/clases'
.. code:: python
%cd ~
.. parsed-literal::
/Users/flavioc
.. code:: python
%pwd
.. parsed-literal::
'/Users/flavioc'
En windows, el comando ``pwd`` va a dar algo así como:
::
In [3]: %pwd
Out[3]: C:\\Users\\usuario
Vamos a crear un directorio donde guardar ahora los programas de ejemplo
que escribamos. Lo vamos a llamar ``scripts``.
Primero vamos a ir al directorio que queremos, y crearlo. En mi caso lo
voy a crear en mi HOME.
.. code:: python
%cd
.. parsed-literal::
/Users/flavioc
.. code:: python
%mkdir scripts
.. code:: python
%cd scripts
.. code:: python
%hist
.. parsed-literal::
%pwd
%cd ~
%pwd
%cd
!type prog1.py
%magic
%hist
Hay varios otros comandos mágicos en IPython. Para leer información
sobre el sistema de comandos mágicos utilice:
Finalmente, para obtener un resumen de comandos con una explicación
breve, utilice:
.. code:: python
%quickref
.. parsed-literal::
IPython -- An enhanced Interactive Python - Quick Reference Card
================================================================
obj?, obj?? : Get help, or more help for object (also works as
?obj, ??obj).
?foo.*abc* : List names in 'foo' containing 'abc' in them.
%magic : Information about IPython's 'magic' % functions.
Magic functions are prefixed by % or %%, and typically take their arguments
without parentheses, quotes or even commas for convenience. Line magics take a
single % and cell magics are prefixed with two %%.
Example magic function calls:
%alias d ls -F : 'd' is now an alias for 'ls -F'
alias d ls -F : Works if 'alias' not a python name
alist = %alias : Get list of aliases to 'alist'
cd /usr/share : Obvious. cd - to choose from visited dirs.
%cd?? : See help AND source for magic %cd
%timeit x=10 : time the 'x=10' statement with high precision.
%%timeit x=2**100
x**100 : time 'x**100' with a setup of 'x=2**100'; setup code is not
counted. This is an example of a cell magic.
System commands:
!cp a.txt b/ : System command escape, calls os.system()
cp a.txt b/ : after %rehashx, most system commands work without !
cp ${f}.txt $bar : Variable expansion in magics and system commands
files = !ls /usr : Capture system command output
files.s, files.l, files.n: "a b c", ['a','b','c'], 'a\nb\nc'
History:
_i, _ii, _iii : Previous, next previous, next next previous input
_i4, _ih[2:5] : Input history line 4, lines 2-4
exec(_i81) : Execute input history line #81 again
%rep 81 : Edit input history line #81
_, __, ___ : previous, next previous, next next previous output
_dh : Directory history
_oh : Output history
%hist : Command history of current session.
%hist -g foo : Search command history of (almost) all sessions for 'foo'.
%hist -g : Command history of (almost) all sessions.
%hist 1/2-8 : Command history containing lines 2-8 of session 1.
%hist 1/ ~2/ : Command history of session 1 and 2 sessions before current.
%hist ~8/1-~6/5 : Command history from line 1 of 8 sessions ago to
line 5 of 6 sessions ago.
%edit 0/ : Open editor to execute code with history of current session.
Autocall:
f 1,2 : f(1,2) # Off by default, enable with %autocall magic.
/f 1,2 : f(1,2) (forced autoparen)
,f 1 2 : f("1","2")
;f 1 2 : f("1 2")
Remember: TAB completion works in many contexts, not just file names
or python names.
The following magic functions are currently available:
%alias:
Define an alias for a system command.
%alias_magic:
::
%autoawait:
%autocall:
Make functions callable without having to type parentheses.
%automagic:
Make magic functions callable without having to type the initial %.
%autosave:
Set the autosave interval in the notebook (in seconds).
%bookmark:
Manage IPython's bookmark system.
%cat:
Alias for `!cat`
%cd:
Change the current working directory.
%clear:
Clear the terminal.
%code_wrap:
::
%colors:
Switch color scheme for prompts, info system and exception handlers.
%conda:
Run the conda package manager within the current kernel.
%config:
configure IPython
%connect_info:
Print information for connecting other clients to this kernel
%cp:
Alias for `!cp`
%debug:
::
%dhist:
Print your history of visited directories.
%dirs:
Return the current directory stack.
%doctest_mode:
Toggle doctest mode on and off.
%ed:
Alias for `%edit`.
%edit:
Bring up an editor and execute the resulting code.
%env:
Get, set, or list environment variables.
%gui:
Enable or disable IPython GUI event loop integration.
%hist:
Alias for `%history`.
%history:
::
%killbgscripts:
Kill all BG processes started by %%script and its family.
%ldir:
Alias for `!ls -F -G -l %l | grep /$`
%less:
Show a file through the pager.
%lf:
Alias for `!ls -F -l -G %l | grep ^-`
%lk:
Alias for `!ls -F -l -G %l | grep ^l`
%ll:
Alias for `!ls -F -l -G`
%load:
Load code into the current frontend.
%load_ext:
Load an IPython extension by its module name.
%loadpy:
Alias of `%load`
%logoff:
Temporarily stop logging.
%logon:
Restart logging.
%logstart:
Start logging anywhere in a session.
%logstate:
Print the status of the logging system.
%logstop:
Fully stop logging and close log file.
%ls:
Alias for `!ls -F -G`
%lsmagic:
List currently available magic functions.
%lx:
Alias for `!ls -F -l -G %l | grep ^-..x`
%macro:
Define a macro for future re-execution. It accepts ranges of history,
%magic:
Print information about the magic function system.
%mamba:
Run the mamba package manager within the current kernel.
%man:
Find the man page for the given command and display in pager.
%matplotlib:
::
%micromamba:
Run the conda package manager within the current kernel.
%mkdir:
Alias for `!mkdir`
%more:
Show a file through the pager.
%mv:
Alias for `!mv`
%notebook:
::
%page:
Pretty print the object and display it through a pager.
%pastebin:
Upload code to dpaste.com, returning the URL.
%pdb:
Control the automatic calling of the pdb interactive debugger.
%pdef:
Print the call signature for any callable object.
%pdoc:
Print the docstring for an object.
%pfile:
Print (or run through pager) the file where an object is defined.
%pinfo:
Provide detailed information about an object.
%pinfo2:
Provide extra detailed information about an object.
%pip:
Run the pip package manager within the current kernel.
%popd:
Change to directory popped off the top of the stack.
%pprint:
Toggle pretty printing on/off.
%precision:
Set floating point precision for pretty printing.
%prun:
Run a statement through the python code profiler.
%psearch:
Search for object in namespaces by wildcard.
%psource:
Print (or run through pager) the source code for an object.
%pushd:
Place the current dir on stack and change directory.
%pwd:
Return the current working directory path.
%pycat:
Show a syntax-highlighted file through a pager.
%pylab:
::
%qtconsole:
Open a qtconsole connected to this kernel.
%quickref:
Show a quick reference sheet
%recall:
Repeat a command, or get command to input line for editing.
%rehashx:
Update the alias table with all executable files in $PATH.
%reload_ext:
Reload an IPython extension by its module name.
%rep:
Alias for `%recall`.
%rerun:
Re-run previous input
%reset:
Resets the namespace by removing all names defined by the user, if
%reset_selective:
Resets the namespace by removing names defined by the user.
%rm:
Alias for `!rm`
%rmdir:
Alias for `!rmdir`
%run:
Run the named file inside IPython as a program.
%save:
Save a set of lines or a macro to a given filename.
%sc:
Shell capture - run shell command and capture output (DEPRECATED use !).
%set_env:
Set environment variables. Assumptions are that either "val" is a
%store:
Lightweight persistence for python variables.
%sx:
Shell execute - run shell command and capture output (!! is short-hand).
%system:
Shell execute - run shell command and capture output (!! is short-hand).
%tb:
Print the last traceback.
%time:
Time execution of a Python statement or expression.
%timeit:
Time execution of a Python statement or expression
%unalias:
Remove an alias
%unload_ext:
Unload an IPython extension by its module name.
%who:
Print all interactive variables, with some minimal formatting.
%who_ls:
Return a sorted list of all interactive variables.
%whos:
Like %who, but gives some extra information about each variable.
%xdel:
Delete a variable, trying to clear it from anywhere that
%xmode:
Switch modes for the exception handlers.
%%!:
Shell execute - run shell command and capture output (!! is short-hand).
%%HTML:
Alias for `%%html`.
%%SVG:
Alias for `%%svg`.
%%bash:
%%bash script magic
%%capture:
::
%%code_wrap:
::
%%debug:
::
%%file:
Alias for `%%writefile`.
%%html:
::
%%javascript:
Run the cell block of Javascript code
%%js:
Run the cell block of Javascript code
%%latex:
Render the cell as a block of LaTeX
%%markdown:
Render the cell as Markdown text block
%%perl:
%%perl script magic
%%prun:
Run a statement through the python code profiler.
%%pypy:
%%pypy script magic
%%python:
%%python script magic
%%python2:
%%python2 script magic
%%python3:
%%python3 script magic
%%ruby:
%%ruby script magic
%%script:
::
%%sh:
%%sh script magic
%%svg:
Render the cell as an SVG literal
%%sx:
Shell execute - run shell command and capture output (!! is short-hand).
%%system:
Shell execute - run shell command and capture output (!! is short-hand).
%%time:
Time execution of a Python statement or expression.
%%timeit:
Time execution of a Python statement or expression
%%writefile:
::
Comandos de Shell
-----------------
Se pueden correr comandos del sistema operativo tipeando ``!`` seguido
por el comando que se quiere ejecutar. Por ejemplo:
.. code:: python
# En Linux
# !ls
# En Windows
!dir
Vamos a escribir un programa de Python con comandos:
.. code:: python
!echo "1+2" >> prog1.py
.. code:: python
!echo "print('hola otra vez')" >> prog1.py
Notar que en Windows, el comando no requiere las comillas (“):
::
!echo 1+2 >> prog1.py
!echo print('hola otra vez') >> prog1.py
.. code:: python
# En Windows
!echo 1+2 >> prog1.py
!echo print('hola otra vez') >> prog1.py
.. code:: python
%cat prog1.py
En windows ``%cat`` no está implementado, así que se debe usar
directamente el comando de la terminal ``!type``
.. code:: python
!type prog1.py
.. parsed-literal::
prog1.py not found
.. code:: python
%run prog1.py
.. code:: python
!date
En windows, ``!date`` imprime la fecha y hora, pero espera una nueva
fecha, con lo cual la ejecución del comando terminará cuando uno
detenga la ejecución de la celda
--------------
Ejercicios 01 (a)
=================
1. Abra una terminal (consola) o notebook y utilícela como una
calculadora para realizar las siguientes acciones:
- Suponiendo que, de las tres horas de clases, dedicamos dos
períodos de media hora para que realicen ejercicios (de Python),
dedicamos diez minutos a distraernos en un recreo, y el resto a la
exposición ‘teórica’, calcular cuántos minutos efectivos de
trabajo tendremos en las 13 clases.
- Calcule el porcentaje de horas del curso efectivamente dedicadas
al trabajo.
- ¿Cómo se modifica el porcentaje anterior si incluimos el examen
final?
- Para la cantidad de alumnos presentes en el aula: ¿cuántas
horas-persona de trabajo hay involucradas en este curso?
2. Muestre en la consola de Ipython (o usando Jupyter Notebooks):
- el nombre de su directorio actual
- los archivos en su directorio actual
- Cree un subdirectorio llamado ``tmp``
- si está usando Linux, muestre la fecha y hora
- Borre el subdirectorio ``tmp``
3. Sabiendo que la velocidad de la luz es aproximadamente 300000 km/s y
que un año luz se define como la distancia que recorre la luz en un
año, usando la terminal de python o la notebook:
- calcule cuántos kilómetros son nueve meses-luz,
- considerando que la luz del sol tarda ocho minutos en llegar a la
tierra, calcule a cuántos metros de la tierra está el sol.
--------------
Ambientes
=========
Uno de los problemas principales de cualquier proyecto de software es el
mantenimiento de las dependencias del código. Python no es ajeno a ello.
En Python las bibliotecas de software se distribuyen a través de
`paquetes `__. Cada paquete tiene su nombre y su
versión.
La manera tradicional de encapsular dependencias en proyectos que tiene
Python es a través de la creación de ambientes virtuales o *virtual
environments*. De esta forma, un conjunto de paquetes se instalan en
forma local en un directorio aislado de otros, en lugar de ser instalado
en forma global. De esa forma, determinados proyectos acudirán a cierto
*environment*, mientras otros usarán otros… Por ejemplo, un proyecto de
Machine Learning requerirá de ciertos paquetes de manejo de Álgebra
Lineal, optimización en GPU, etc., mientras que un server web no
necesitará de ellos.
Para manejar ambientes se usan ciertas herramientas equivalentes como:
- `venv `__
- `virtualenv `__
La distribución Anaconda a través del comando ``conda`` también puede
administrar *environments*, y es la que usaremos en este curso.
Gestionando ambientes con ``conda``
-----------------------------------
Empecemos viendo qué ambientes tenemos en nuestro sistema con:
.. code:: shell
conda env list
Si recién hemos instalado Python con miniconda, obtendremos:
.. code:: shell
(base) C:\Users\Heisenberg>conda env list
# conda environments:
#
base * C:\Users\Heisenberg\miniconda3
Vemos que existe un ambiente default que se llama ``base``, que también
es el indicado entre paréntesis en el prompt. Este ambiente se crea al
instalar Python a través de miniconda.
El comando ``conda`` tiene ayudas instructivas, basta agregar
``--help`` al final del comando
Creando ambientes
~~~~~~~~~~~~~~~~~
El comando para crear un nuevo ambiente es
``conda create -n ``:
.. code:: shell
conda create -n clases
Channels:
- defaults
Platform: win-64
Collecting package metadata (repodata.json): done
Solving environment: done
## Package Plan ##
environment location: C:\Users\Heisenberg\miniconda3\envs\clases
Proceed ([y]/n)? y
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
# $ conda activate clases
#
# To deactivate an active environment, use
#
# $ conda deactivate
El resultado de la ejecución del comando nos indica cómo activar y
desactivar el ambiente. ¿Qué significa esto? Para poder trabajar
ordenadamente en un proyecto, *activamos* primero el ambiente,
instalamos los paquetes requeridos, programamos, etc. etc., y luego
*desactivamos* el ambiente. Por supuesto que la instalación de paquetes
en un ambiente se hace una única vez.
.. code:: shell
conda activate clases
.. image:: figuras/activate.png
Nótese que el *prompt* cambia indicando bajo qué ambiente estamos
trabajando. En efecto:
.. code:: shell
(clases) C:\Users\Heisenberg>conda env list
# conda environments:
#
base C:\Users\Heisenberg\miniconda3
clases * C:\Users\Heisenberg\miniconda3\envs\clases
Nos indica que hay un nuevo ambiente creado, y es el que está activo
(indicado por el asterisco).
Para borrar un ambiente, usamos
.. code:: shell
conda env remove --name
..
Recordar desactivar el ambiente antes de borrarlo. De todas formas,
``conda`` avisará si uno se olvida de este paso
.. code:: shell
conda deactivate
conda env remove --name clases
Más documentación y opciones por
`acá `__.
Instalando paquetes
~~~~~~~~~~~~~~~~~~~
Por defecto ``conda create -n `` no instala ningún
paquete, con lo cual, tenemos que empezar instalando Python:
Recordar que estamos instalando paquetes *dentro del ambiente*, así
que hay que asegurarse que hayamos hecho
``conda activate ``
.. code:: bash
conda install python=3.11.4
Instalará la versión 3.11.4 de Python. La sintaxis es en general
.. code:: bash
conda install [=] [=] ...
Es optativo especificar la versión del paquete, por defecto ``conda``
usará la versión más nueva (compatible con el resto de los paquetes que
se están instalando o están instalados en el ambiente).
Ahora sí, podemos usar python
.. code:: bash
python --version
Python 3.11.3
Para ver qué paquetes están instalados, hacemos ``conda list``
.. image:: figuras/lista_de_paquetes.png
Ambientes y Notebooks
---------------------
Una vez que creamos un ambiente y le agregamos paquetes, nos gustaría
utilizarlo desde un jupyter notebook. Hay algunas opciones
Instalando ``jupyter``
~~~~~~~~~~~~~~~~~~~~~~
Una opción es instalar ``jupyter`` en cada ambiente, activarlo y
correrlo via ``python -m notebook`` como hicimos al comienzo en el
ambiente *base*. Si se prefiere, también se puede instalar jupyter labs
con ``conda install -c conda-forge jupyterlab`` y luego correr
``jupyter lab`` desde la terminal. En este caso tendremos un nuevo
jupyter en el menú de windows
.. image:: figuras/jupyter_ambiente.png
Instalando ``nb_conda_kernels``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jupyter es una plataforma poderosa y permite utilizar otros *kernels*.
Un kernel de Jupyter es un proceso que corre paralelamente al notebook,
y se ocupa de la ejecución del código. Si bien lo usaremos en Python,
Jupyter puede usar otros kernels en `distintos
lenguajes `__.
El paquete ``ipykernel`` es el que encapsula a IPython (la consola
interactiva) para que pueda usarse desde jupyter, y se instala como
dependencia del paquete ``jupyter``.
El paquete ``nb_conda_kernels`` permite que cualquier notebook pueda
ejecutarse con distintos ambientes (más documentación
`acá `__).
Atención! ``ipykernel`` tiene que estar instalado en cada ambiente
que se quiera utilizar con esta opción.
.. image:: figuras/kernels_en_jupyter.png
En resumen: - Si se quiere usar notebooks con un ambiente dedicado,
instalar jupyter en cada ambiente. - Si se desea usar notebooks con
distintos ambientes, instalar ``ipykernel`` en cada ambiente y
``nb_conda_kernels`` en el ambiente desde el cual se correrá jupyter (en
general, es el default *base*)
Visual Studio Code
~~~~~~~~~~~~~~~~~~
VS Code maneja esto automáticamente, instalando ``ipykernel`` en cada
ambiente de ser necesario, y realizando todas las conexiones necesarias
para que uno pueda tener disponibles todos los ambientes al abrir un
notebook.
Compartiendo ambientes
----------------------
La forma más sencilla es crear un archivo con la lista de paquetes del
ambiente local que estamos usando, compartir dicho archivo y recrear el
ambiente en la nueva locación. Extrayendo el ambiente local
.. code:: bash
conda env export --from-history > environment.yml
Resulta en un archivo
`YAML `__
de la forma:
.. code:: yaml
name: clases
channels:
- defaults
dependencies:
- ipykernel
- mypy
- jupyter
Esta es la forma más general de exportar los paquetes. Obsérvese que
están incluídos aquellos paquetes que hemos instalado explícitamente con
``conda``.
Se estila usar como nombre de archivo ``environment.yml``, pero se
puede usar cualquier otro nombre de base,
..
Existen otras maneras más específicas de crear archivos que contengan
el listado de paquetes instalados, pero adolecen de algunos
problemas, como por ejemplo, no son multiplataforma.
Una vez copiado el archivo yaml en la nueva máquina/usuario/etc.,
procedemos a crear el ambiente con
.. code:: bash
conda env create -n clases2 --file environment.yml
donde en este caso ``environment.yml`` es el archivo que creamos antes,
y ``clases2`` sería el nombre del nuevo ambiente.
Conceptos básicos de Python
===========================
Características generales del lenguaje
--------------------------------------
Python es un lenguaje de uso general que presenta características
modernas. Posiblemente su característica más visible/notable es que la
estructuración del código está fuertemente relacionada con su
legibilidad:
- Las funciones, bloques, ámbitos están definidos por la indentación
- Es un lenguaje interpretado (no se compila separadamente)
- Provee tanto un entorno interactivo como ejecución de programas
completos
- Tiene una estructura altamente modular, permitiendo su reusabilidad
- Es un lenguaje de *tipeado dinámico*, no tenemos que declarar el tipo
de variable antes de usarla.
Python es un lenguaje altamente modular con una biblioteca standard que
provee funciones y tipos para un amplio rango de aplicaciones, y que se
distribuye junto con el lenguaje. Además hay un conjunto muy importante
de utilidades que pueden instalarse e incorporarse muy fácilmente. El
núcleo del lenguaje es pequeño, existiendo sólo unas pocas palabras
reservadas:
====== ======== ======= ======== ========
Las Palabras claves del Lenguaje
====== ======== ======= ======== ========
False class finally is return
None continue for lambda try
True def from nonlocal while
and del global not with
as elif if or yield
assert else import pass
break except in raise
====== ======== ======= ======== ========
Tipos de variables
------------------
Python es un lenguaje de muy alto nivel y por lo tanto trae muchos
*tipos* de datos ya definidos:
- Números: enteros, reales, complejos
- Tipos lógicos (booleanos)
- Cadenas de caracteres (strings) y bytes
- Listas: una lista es una colección de cosas, ordenadas, que pueden
ser todas distintas entre sí
- Diccionarios: También son colecciones de cosas, pero no están
ordenadas y son identificadas con una etiqueta
- Conjuntos, tuples, …
Tipos simples: Números
~~~~~~~~~~~~~~~~~~~~~~
Hay varios tipos de números en Python. Veamos un ejemplo donde definimos
y asignamos valor a distintas variables:
.. code:: python
a = 13
b = 1.23
c = a + b
print(a, type(a))
print(b, type(b))
print(c, type(c))
Acá usamos la función ``type()`` que retorna el tipo de su argumento.
Acá ilustramos una de las características salientes de Python: El tipo
de variable se define en forma dinámica, al asignarle un valor.
De la misma manera se cambia el tipo de una variable en forma dinámica,
para poder operar. Por ejemplo en el último caso, la variable ``a`` es
de tipo ``int``, pero para poder sumarla con la variable ``b`` debe
convertirse su valor a otra de tipo ``float``.
.. code:: python
print (a, type(a))
a = 1.5 * a
print (a, type(a))
Ahora, la variable ``a`` es del tipo ``float``.
Lo que está pasando acá en realidad es que la variable ``a`` del tipo
entero en la primera, en la segunda línea se destruye (después de ser
multiplicada por ``1.5``) y se crea una nueva variable del tipo
``float`` que se llama ``a`` a la que se le asigna el valor real.
En Python 3 la división entre números enteros da como resultado un
número de punto flotante
.. code:: python
print(20/5)
print(type(20/5))
print(20/3)
.. warning:: En *Python 2.x* la división entre números enteros es
entera
Por ejemplo, en cualquier versión de Python 2 tendremos: 1/2 = 3/4 = 0.
Esto es diferente en *Python 3* donde 1/2=0.5 y 3/4=0.75.
.. note:: La función ``print``
Estuvimos usando, sin hacer ningún comentario, la función
``print(arg1, arg2, arg3, ..., sep=' ', end='\n', file=sys.stdout, flush=False)``
que acepta un número variable de argumentos. Esta función Imprime por
pantalla todos los argumentos que se le pasan separados por el string
``sep`` (cuyo valor por defecto es un espacio), y termina con el
string ``end`` (con valor por defecto *newline*).
.. code:: python
help(print)
.. parsed-literal::
Help on built-in function print in module builtins:
print(*args, sep=' ', end='\n', file=None, flush=False)
Prints the values to a stream, or to sys.stdout by default.
sep
string inserted between values, default a space.
end
string appended after the last value, default a newline.
file
a file-like object (stream); defaults to the current sys.stdout.
flush
whether to forcibly flush the stream.
.. code:: python
print(3,2,'hola')
print(4,1,'chau')
.. parsed-literal::
3 2 hola
4 1 chau
.. code:: python
print(3,2,'hola',sep='++++',end=' -> ')
print(4,1,'chau',sep='++++')
.. parsed-literal::
3++++2++++hola -> 4++++1++++chau
.. warning:: En *Python 2.x* no existe la función ``print()``. Se
trata de un comando. Para escribir las sentencias anteriores en
Python 2 sólo debemos omitir los paréntesis y separar la palabra
``print`` de sus argumentos con un espacio.
.. note:: Disgresión: Objetos
En python, la forma de tratar datos es mediante *objetos*. Todos los
objetos tienen, al menos:
- un tipo,
- un valor,
- una identidad.
Además, pueden tener:
- componentes
- métodos
Los *métodos* son funciones que pertenecen a un objeto y cuyo primer
argumento es el objeto que la posee.
Todos los números, al igual que otros tipos, son objetos y tienen
definidos algunos métodos que pueden ser útiles.
Números complejos
~~~~~~~~~~~~~~~~~
Los números complejos son parte standard del lenguaje, y las operaciones
básicas que están incorporadas en forma nativa pueden utilizarse
normalmente
.. code:: python
z1 = 3 + 1j
z2 = 2 + 2.124j
print ('z1 =', z1, ', z2 =', z2)
.. parsed-literal::
z1 = (3+1j) , z2 = (2+2.124j)
.. code:: python
print('1.5j * z2 + z1 = ', 1.5j * z2 + z1) # sumas, multiplicaciones de números complejos
print('z2² = ', z2**2) # potencia de números complejos
print('conj(z1) = ', z1.conjugate())
.. parsed-literal::
1.5j * z2 + z1 = (-0.18599999999999994+4j)
z2² = (-0.5113760000000003+8.496j)
conj(z1) = (3-1j)
.. code:: python
print ('Im(z1) = ', z1.imag)
print ('Re(z1) = ', z1.real)
print ('abs(z1) = ', abs(z1))
.. code:: python
type(z1)
.. code:: python
help(z1)
Operaciones
~~~~~~~~~~~
Las operaciones aritméticas básicas son:
- adición: ``+``
- sustracción: ``-``
- multiplicación: ``*``
- división: ``/``
- potencia: ``**``
- módulo: ``%``
- división entera: ``//``
Las operaciones se pueden agrupar con parentesis y tienen precedencia
estándar.
División entera (//) significa quedarse con la parte entera de la
división (sin redondear).
**Nota:** Las operaciones matemáticas están incluidas en el lenguaje.
En particular las funciones elementales: trigonométricas,
hiperbólicas, logaritmos no están incluidas. En todos los casos es
fácil utilizarlas porque las proveen módulos. Lo veremos pronto.
.. code:: python
print('división de 20/3: ', 20/3)
print('parte entera de 20/3: ', 20//3)
print('fracción restante de 20/3:', 20/3 - 20//3)
print('Resto de 20/3: ', 20%3)
.. parsed-literal::
división de 20/3: 6.666666666666667
parte entera de 20/3: 6
fracción restante de 20/3: 0.666666666666667
Resto de 20/3: 2
Tipos simples: Booleanos
~~~~~~~~~~~~~~~~~~~~~~~~
Los tipos lógicos o *booleanos*, pueden tomar los valores *Verdadero* o
*Falso* (``True`` o ``False``)
.. code:: python
t = False
print('¿t is True?', t == True)
print('¿t is False?', t == False)
.. parsed-literal::
¿t is True? False
¿t is False? True
.. code:: python
c = (t == True)
print('¿t is True?', c)
print (type(c))
.. parsed-literal::
¿t is True? False
Hay un tipo *especial*, el elemento ``None``.
.. code:: python
print ('True == None: ',True == None)
print ('False == None: ', False == None)
a = None
print ('type(a): ',type(a))
print (bool(None))
print(bool(0))
print(bool(1))
.. parsed-literal::
True == None: False
False == None: False
type(a):
False
False
True
Aquí hemos estado preguntando si dos cosas eran iguales o no (igualdad).
También podemos preguntar si una **es** la otra (identidad):
.. code:: python
a = 1280
b = 1280
print(a == b)
print ('b is a: ', b is a)
.. parsed-literal::
True
b is a: False
.. code:: python
a = None
b = True
c = a
print ('b is True: ', b is True)
print ('a is None: ', a is None)
print ('c is a: ', c is a)
.. parsed-literal::
b is True: True
a is None: True
c is a: True
Acá vemos que ``None`` es “único”, en el sentido de que si dos variables
son ``None``, entonces son el mismo objeto.
Operadores lógicos
~~~~~~~~~~~~~~~~~~
Los operadores lógicos en Python son muy explicitos:
::
A == B (A igual que B)
A > B (A mayor que B)
A < B (A menor que B)
A >= B (A igual o mayor que B)
A <= B (A igual o menor que B)
A != B (A diferente que B)
A in B (A incluido en B)
A is B (Identidad: A es el mismo elemento que B)
y a todos los podemos combinar con ``not``, que niega la condición.
Veamos algunos ejemplos
.. code:: python
print ('¿20/3 == 6?',20/3 == 6)
print ('¿20//3 == 6?', 20//3 == 6)
print ('¿20//3 >= 6?', 20//3 >= 6)
print ('¿20//3 > 6?', 20//3 > 6)
.. parsed-literal::
¿20/3 == 6? False
¿20//3 == 6? True
¿20//3 >= 6? True
¿20//3 > 6? False
.. code:: python
a = 1001
b = 1001
print ('a == b:', a == b)
print ('a is b:',a is b)
print ('a is not b:',a is not b)
.. parsed-literal::
a == b: True
a is b: False
a is not b: True
Note que en las últimas dos líneas estamos fijándonos si las dos
variables son la misma (identidad), y no ocurre aunque vemos que sus
valores son iguales.
--------------
**Warning:** En algunos casos **Python** puede reusar un lugar de
memoria.
Por razones de optimización, en algunos casos **Python** puede utilizar
el mismo lugar de memoria para dos variables que tienen el mismo valor,
cuando este es pequeño.
--------------
.. code:: python
a = 10
b = 5
print (a, ': a is b:', a is b)
.. parsed-literal::
10 : a is b: False
Este es un detalle de implementación y nuestros programas no deberían
depender de este comportamiento.
.. code:: python
b = 2*b
print(a, b, a is b)
.. parsed-literal::
10 10 True
Acá utilizó otro lugar de memoria para guardar el nuevo valor de ``b``
(22).
Esto sigue valiendo para otros números:
.. code:: python
a = -5
b = -5
print (a, ': a is b:', a is b)
print(type(a))
.. parsed-literal::
-5 : a is b: True
.. code:: python
a = 257
b = 257
print (a, ': a is b:', a is b)
.. parsed-literal::
257 : a is b: False
En la implementación que estamos usando, se utiliza el mismo lugar de
memoria para dos números enteros iguales si son menores o iguales a 256.
De todas maneras, es claro que deberíamos utilizar el símbolo ``==``
para probar igualdad y la palabra ``is`` para probar identidad.
En este caso, para valores mayores que 256, ya no usa el mismo lugar de
memoria. Tampoco lo hace para números de punto flotante.
.. code:: python
a = -6
b = -6
print (a, ': a is b:', a is b)
print(type(a))
.. parsed-literal::
-6 : a is b: False
.. code:: python
a = 1.5
b = 1.5
print (a, ': a is b:', a is b)
print(type(a))
.. parsed-literal::
1.5 : a is b: False
.. code:: python
a = 0.
b = 0.
a is b
.. parsed-literal::
False
--------------
Ejercicios 01 (b)
=================
4. Para cubos de lados de longitud L = 1, 3, y 5: calcule su superficie
y su volumen.
5. Para esferas de radios r = 1, 3, 5 y 8, calcule su superficie y su
volumen.
6. Fíjese si alguno de los valores: :math:`x_1=0.49`, :math:`x_2=0.50`,
:math:`x_3=0.51` es un cero de la función
:math:`f(x)=x^{2} + x/2 - 1/2`, esto es :math:`f(x_i)=0` para
:math:`i=1,2` o :math:`3` .
7. Para el número complejo :math:`z= 1 + 0.5\ i`
- Calcular :math:`z^2` y :math:`z^5`.
- Calcular los complejos conjugados de :math:`z` y :math:`z^3`.
- Escribir un programa que escriba las frases:
- “El conjugado de z=1+0.5i es 1-0.5j”
- “El conjugado de z=(1+0.5i)^2 es …” (con el valor
correspondiente)
--------------
.