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, esto se conoce como 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.
Nota
Hay dos versiones activas del lenguaje Python.
Python2.X (Python 2) es una versión madura, estable, y con muchas aplicaciones, y utilidades disponibles. No se desarrolla pero se corrigen los errores. Su uso ha disminuido mucho en los últimos años y esencialmente todo el ecosistema de bibliotecas se ha convertido a Python-3
Python3.X (Python 3) es la versión actual. Se introdujo por primera vez en 2008, y produjo cambios incompatibles con Python 2. Por esa razón se mantienen ambas versiones y algunos de los desarrollos de Python 3 se portan a Python 2. En este momento la gran mayoría de las utilidades de Python 2 han sido modificadas para Python 3 por lo que, salvo muy contadas excepciones, no hay razones para seguir utilizando Python 2 en aplicaciones nuevas.
Instalación
En este curso utilizaremos Python 3
Para una instalación fácil de Python y los paquetes para uso científico se pueden usar alguna de las distribuciones:
En linux se podría instalar alguna de estas distribuciones pero puede ser más fácil instalar directamente todo lo necesario desde los repositorios. Por ejemplo en Ubuntu:
`sudo apt-get install ipython3 ipython3-notebook spyder python3-matplotlib python3-numpy python3-scipy`
o, en Fedora 28, en adelante:
`sudo dnf install python3-ipython python3-notebook python3-matplotlib python3-numpy python3-scipy`
Editores de Texto:
Editores Multiplataforma e IDEs
Documentación y ayudas
Algunas fuentes de ayuda constante son:
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 <comando>
En una consola interactiva de Python, mediante
help(<comando>)
La documentación de los paquetes:
Matplotlib, en particular la galería
Buscar “palabras clave + python” en un buscador. Es particularmente útil el sitio stackoverflow
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
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”.
La consola IPython supera a la estándar en muchos sentidos. Podemos
autocompletar (<TAB>
), 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).
Otro entorno integrado, que funciona muy bien, viene instalado con Canopy.
También Pycharm funciona muy bien
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)
Comandos de Ipython
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:
%pwd
'/home/fiol/Clases/IntPython/clases-python/clases'
%cd ~
/home/fiol
%pwd
'/home/fiol'
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.
%cd
%mkdir scripts
%cd scripts
Ahora voy a escribir una línea de Python en un archivo llamado
prog1.py. Y lo vamos a ver con el comando %cat
%cat prog1.py
%run prog1.py
%hist
Hay varios otros comandos mágicos en IPython. Para leer información sobre el sistema de comandos mágicos utilice:
%magic
Finalmente, para obtener un resumen de comandos con una explicación breve, utilice:
%quickref
Comandos de Shell
Se pueden correr comandos del sistema operativo (más útil en linux)
tipeando !
seguido por el comando que se quiere ejecutar. Por
ejemplo:
comandos
!echo "1+2" >> prog1.py
!echo "print('hola otra vez')" >> prog1.py
%cat prog1.py
%run prog1.py
!date
Ejercicios 01 (a)
Abra una terminal (consola) o notebook y utilícela como una calculadora para realizar las siguientes acciones:
Suponiendo que, de las cuatro horas de clases, tomamos dos descansos de 15 minutos cada uno y nos distraemos otros 13 minutos, calcular cuántos minutos efectivos de trabajo tendremos en las 16 clases.
Para la cantidad de alumnos presentes en el aula: ¿cuántas horas-persona de trabajo hay involucradas en este curso?
Muestre en la consola de Ipython:
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
Para cubos de lados de longitud L = 1, 3, y 5: calcule su superficie y su volumen.
Para esferas de radios r = 1, 3, 5 y 8, calcule su superficie y su volumen.
Fíjese si alguno de los valores: \(x=0.49\), \(x=0.50\), \(x=0.51\) es un cero de la función \(f(x)=x^{2} + x/2 - 1/2\).
.
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:
a = 13
b = 1.23
c = a + b
print(a, type(a))
print(b, type(b))
print(c, type(c))
13 <class 'int'>
1.23 <class 'float'>
14.23 <class 'float'>
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
.
print (a, type(a))
a = 1.5 * a
print (a, type(a))
13 <class 'int'>
19.5 <class 'float'>
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
print(20/5)
print(type(20/5))
print(20/3)
4.0
<class 'float'>
6.666666666666667
Advertencia
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.
Nota
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).
help(print)
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.
print(3,2,'hola')
print(4,1,'chau')
3 2 hola
4 1 chau
print(3,2,'hola',sep='++++',end=' -> ')
print(4,1,'chau',sep='++++')
3++++2++++hola -> 4++++1++++chau
Advertencia
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.
Nota
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
z1 = 3 + 1j
z2 = 2 + 2.124j
print ('z1 =', z1, ', z2 =', z2)
z1 = (3+1j) , z2 = (2+2.124j)
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())
1.5j * z2 + z1 = (-0.18599999999999994+4j)
z2² = (-0.5113760000000003+8.496j)
conj(z1) = (3-1j)
print ('Im(z1) = ', z1.imag)
print ('Re(z1) = ', z1.real)
print ('abs(z1) = ', abs(z1))
Im(z1) = 1.0
Re(z1) = 3.0
abs(z1) = 3.1622776601683795
type(z1)
complex
help(z1)
Help on complex object:
class complex(object)
| complex(real=0, imag=0)
|
| Create a complex number from a real part and an optional imaginary part.
|
| This is equivalent to (real + imag*1j) where imag defaults to 0.
|
| Methods defined here:
|
| __abs__(self, /)
| abs(self)
|
| __add__(self, value, /)
| Return self+value.
|
| __bool__(self, /)
| True if self else False
|
| __complex__(self, /)
| Convert this value to exact type complex.
|
| __eq__(self, value, /)
| Return self==value.
|
| __format__(self, format_spec, /)
| Convert to a string according to format_spec.
|
| __ge__(self, value, /)
| Return self>=value.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __getnewargs__(self, /)
|
| __gt__(self, value, /)
| Return self>value.
|
| __hash__(self, /)
| Return hash(self).
|
| __le__(self, value, /)
| Return self<=value.
|
| __lt__(self, value, /)
| Return self<value.
|
| __mul__(self, value, /)
| Return self*value.
|
| __ne__(self, value, /)
| Return self!=value.
|
| __neg__(self, /)
| -self
|
| __pos__(self, /)
| +self
|
| __pow__(self, value, mod=None, /)
| Return pow(self, value, mod).
|
| __radd__(self, value, /)
| Return value+self.
|
| __repr__(self, /)
| Return repr(self).
|
| __rmul__(self, value, /)
| Return value*self.
|
| __rpow__(self, value, mod=None, /)
| Return pow(value, self, mod).
|
| __rsub__(self, value, /)
| Return value-self.
|
| __rtruediv__(self, value, /)
| Return value/self.
|
| __sub__(self, value, /)
| Return self-value.
|
| __truediv__(self, value, /)
| Return self/value.
|
| conjugate(self, /)
| Return the complex conjugate of its argument. (3-4j).conjugate() == 3+4j.
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| imag
| the imaginary part of a complex number
|
| real
| the real part of a complex number
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.
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)
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
)
t = False
print('¿t is True?', t == True)
print('¿t is False?', t == False)
¿t is True? False
¿t is False? True
c = (t == True)
print('¿t is True?', c)
print (type(c))
¿t is True? False
<class 'bool'>
Hay un tipo especial, el elemento None
.
print ('True == None: ',True == None)
print ('False == None: ', False == None)
a = None
print ('type(a): ',type(a))
print (bool(None))
True == None: False
False == None: False
type(a): <class 'NoneType'>
False
Aquí hemos estado preguntando si dos cosas eran iguales o no (igualdad). También podemos preguntar si una es la otra (identidad):
a = 1280
b = 1280
print(a == b)
print ('b is a: ', b is a)
True
b is a: False
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)
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
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)
¿20/3 == 6? False
¿20//3 == 6? True
¿20//3 >= 6? True
¿20//3 > 6? False
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)
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.
a = 11
b = 11
print (a, ': a is b:', a is b)
11 : a is b: True
Este es un detalle de implementación y nuestros programas no deberían depender de este comportamiento.
b = 2*b
print(a, b, a is b)
11 22 False
Acá utilizó otro lugar de memoria para guardar el nuevo valor de b
(22).
Esto sigue valiendo para otros números:
a = 256
b = 256
print (a, ': a is b:', a is b)
256 : a is b: True
a = 257
b = 257
print (a, ': a is b:', a is b)
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.
a = -256
b = -256
print (a, ': a is b:', a is b)
print(type(a))
-256 : a is b: False
<class 'int'>
a = 1.5
b = 1.5
print (a, ': a is b:', a is b)
print(type(a))
1.5 : a is b: False
<class 'float'>
Ejercicios 01 (b)
Para el número complejo \(z= 1 + 0.5 i\)
Calcular \(z^2, z^3, z^4, z^5.\)
Calcular los complejos conjugados de \(z\), \(z^2\) y \(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)
.