TUTORIAL 4
Lenguaje de programación: Python
Autor: José Gerardo Carrillo González
Contenido
Números pseudoaleatorios...................................................................................................... 2
Flotantes .............................................................................................................................. 2
Enteros ................................................................................................................................ 2
Generar valores de una secuencia ....................................................................................... 2
Generar números de acuerdo con una distribución ............................................................. 3
Clases .................................................................................................................................... 10
Archivos ............................................................................................................................... 21
Escribir y leer archivos ..................................................................................................... 22
Manipular archivos ........................................................................................................... 26
Lectura y escritura de datos con formato.............................................................................. 29
Lectura .............................................................................................................................. 29
Escritura ............................................................................................................................ 33
Referencias ........................................................................................................................... 36
1
Números pseudoaleatorios
Podemos generar números aleatorios importando el módulo random.
Flotantes
Con la función [Link]() se puede generar un número aleatorio de clase 'float' en el
rango semiabierto por la derecha [0.0, 1.0). Ejemplo:
import random
n=[Link]()
print(n)
Salida:
0.8129191817530697
Por lo que 0.0<=n<1.0. Con [Link](a,b) se puede generar un número aleatorio de
clase 'float' en el rango [a,b]. Ejemplo:
n=[Link](0,1)
Salida:
0.7331947217937244
Enteros
Para generar números enteros tenemos [Link](a, b, incremento), a y b
corresponden al rango en el cual puede estar el numero generado, que es [a, b), además
incremento es para que el número generado sea múltiplo de incremento. Los valores a, b, e
incremento deben ser enteros. Por defecto, a=0 e incremento=1. Ejemplo:
n=[Link](0,10,2)
Salida:
8
En este caso n puede ser un número del conjunto {0,2,4,6,8}. Con [Link](a,b), el
numero generado puede estar en el rango [a,b].
Generar valores de una secuencia
Con [Link](secuencia) se obtiene un valor de secuencia, siendo secuencia una
colección de valores. Ejemplo: n=[Link]([1,2,3]), por lo que n puede ser cualquier
número de la lista [1,2,3].
2
Salida: 3
Tenemos [Link](sequence, weights=None, cum_weights=None, k=1), sequence es
(obligatoriamente) una lista, tupla, cadena, o rango de números. El parámetro weights es
opcional y es igual a una lista con el peso de cada valor de sequence, un peso determina la
probabilidad de que ocurra un valor (a mayor peso, mayor la probabilidad de ocurrir), por lo
que la longitud de sequence y weights debe ser la misma. El parámetro cum_weights es
opcional y es igual a una lista que contiene los pesos de manera acumulada, por lo que si
weights=[1,2,3] entonces cum_weights=[1,3,6]. De no especificarse weights ni cum_weights,
cada valor de sequence tiene la misma probabilidad de ocurrir. El parámetro k es opcional y
es igual al número de valores que debe contener la lista resultante, por defecto k=1. Ejemplo:
n=[Link](range(1,11,1),weights=[1]*10,k=5)
Salida:
[5, 10, 9, 4, 2]
Como sequence especificamos range(1,11,1), que equivale a los números enteros en el rango
[1,10] en intervalos de 1. El parámetro weigths es igual a una lista de longitud 10 que contiene
unos, por lo que cada valor en el rango establecido tiene la misma probabilidad de ocurrir. Y
k=5, por lo que el resultado es una lista con 5 números. Ahora con:
n=[Link]([Link](0.0,1.0,0.001),k=1)
Salida:
[0.513]
En este caso es necesario importar numpy, arange() funciona de manera similar que range()
pero soporta números de clase ‘float’. Para la secuencia hemos especificado el rango [0,1) a
intervalos de 0.001, por lo que el resultado será un valor entre 0 y 0.999; como no se
especificó weights ni cum_weights, cada valor dentro del rango tiene la misma probabilidad
de ocurrir. Ya que k=1, el resultado es una lista con un solo valor.
Tenemos [Link](sequence, k), se usa para seleccionar k objetos de una secuencia
(sequence), cada objeto de la secuencia puede ser seleccionado una sola vez (es decir, solo
una vez aparecerá en el resultado), por lo que k<=len(sequence). Ejemplo:
n=[Link]([1,2,2,3,3,3],k=3)
Salida:
[3, 2, 3]
Generar números de acuerdo con una distribución
Con [Link](alpha, beta) se obtiene un flotante aleatorio entre 0 y 1 con
distribución beta. Como condición se tiene aplha>0 y beta>0.
3
Con [Link](lambda) se obtiene un flotante aleatorio con distribución
exponencial. Condición: lambda != 0. Salida: si lambda>0, el resultado es un valor en el
rango de 0 a infinito positivo, si lambda<0, el resultado es un valor en el rango de 0 a infinito
negativo.
Con [Link](alpha, beta) se obtiene un flotante aleatorio con distribución
gamma. Condición: alpha>0 y beta>0.
Con [Link](mu, sigma) se obtiene un flotante aleatorio con distribución log
normal. La media es mu y la desviación estándar es sigma. Condición: sigma>0.
Con [Link](alpha, beta) se obtiene un flotante aleatorio con distribución
Weibull. Donde alpha es el parámetro de escala y beta es el parámetro de forma.
Con [Link](alpha) se obtiene un flotante aleatorio con distribución Pareto.
Donde alpha es el parámetro de forma.
Con [Link](mu, sigma) se obtiene un flotante aleatorio con distribución
normal. Donde mu es la media y sigma la desviación estándar. Ejemplo:
4
Para instalar matplotlib, desde command prompt escribir: pip install matplotlib
Para instalar scipy, desde command prompt escribir: pip install scipy
La función dist_norm tiene 4 parámetros: mu, sigma, p1 y p2, que son la media, la desviación
estándar, la cantidad de números aleatorios a generar con distribución normal y el número de
bins (intervalos del eje-x), respectivamente. En línea 10 tenemos
n=[Link](mu,sigma), que es la instrucción para generar un número flotante
aleatorio con distribución normal [1] de acuerdo con los valores mu y sigma. Ya que el for
en línea 9 hará p1=100 iteraciones, la lista data tendrá 100 números. Línea 13 es para obtener
p, que es para determinar si la muestra (data) viene de una distribución normal (o distribución
de Gauss), para lo cual se usó la prueba Shapiro-Wilk [2]. Si el p-value (p) es mayor que
alpha=5%, es decir p>0.05, no se puede rechazar la hipótesis de que la muestra viene de una
distribución normal. Líneas 27 y 28 son las instrucciones para graficar el histograma [3]. En
la Figura 1 tenemos el eje-x dividido en p2=10 intervalos, cada intervalo (igual al ancho del
bin) corresponde en el eje-y con la cantidad de números generados que están dentro de dicho
intervalo. Se puede determinar el ancho del bin (ancho) conociendo el valor mínimo (mi) y
máximo (ma) en data, de modo que ancho=(ma-mi)/p2. Salida:
5
Figura 1.
Los datos generados vienen de una distribución normal, ya que:
p-value = 0.9284147024154663 > 0.05
El ancho del bin es:
(max-min)/intervalos = (93.9250949471864-56.065771164232075)/10 =
3.785932378295432
Regla 68.27, 95.45, 99.73 resulto en: 67.0, 97.0, 100.0
Con el siguiente código podemos graficar el histograma de una muestra de números, cada
número es el resultado de sumar una cantidad variable (p3) de números aleatorios uniformes;
el rango de un número aleatorio uniforme es [a,b], con a=0 y b= int(100/p3). El parámetro
p1 es el número de elementos de la muestra y p2 es el número de intervalos en el eje-x del
histograma.
6
De acuerdo con el programa anterior, si p3=1 entonces los números en el rango [a, b] tienen
la misma probabilidad de ocurrir y se puede obtener el siguiente histograma con data (que
como se puede ver, tiene una distribución con tendencia uniforme):
7
Ejemplo de histograma de una muestra de números (que no siguen una distribución normal)
donde cada número es igual a la suma de dos números aleatorios uniformes (p3=2):
Ejemplo de histograma de una muestra de números (que siguen una distribución normal)
donde cada número es igual a la suma de cuatro números aleatorios uniformes (p3=4):
8
Ejemplo de histograma de una muestra de números (que siguen una distribución normal)
donde cada número es igual a la suma de cinco números aleatorios uniformes (p3=5):
Ejemplo de histograma de una muestra de números (que siguen una distribución normal)
donde cada número es igual a la suma de diez números aleatorios uniformes (p3=10):
9
Clases
Una clase es un modelo (una estructura de programación) a partir del cual se pueden crear
objetos (copias de la clase), por lo que al definir una clase se podrán crear instancias de la
clase [4]; en una clase se definen métodos y atributos. La sintaxis para definir una clase es:
class Nombre_Clase:
sentencia_1
sentencia_2
.
.
sentencia_N
Sinedo Nombre_Clase el nombre de la clase. Para instanciar una clase se hace de la siguiente
manera:
Nombre_Instancia = Nombre_Clase()
De modo que Nombre_Clase es de tipo 'type', Nombre_Clase() devuelve un objeto de clase
'Nombre_Clase', el cual puede ser vinculado con un nombre, en este caso Nombre_Instancia.
Los atributos que se definen en una clase estarán disponibles en las instancias. Si se cambia
el valor de un atributo por medio de la clase, también cambiará en las instancias. Si se cambia
el valor de un atributo para una determinada instancia, solo cambiara en dicha instancia.
Ejemplo:
Salida:
x.a = 1, y.a = 0
x.b = 3, z.b = 3
El constructor __init__() es invocado automáticamente cada vez que se crea una instancia de
una clase; el constructor deber tener como nombre __init__() y como parámetro self, que
hace referencia a la instancia creada (no pasamos argumento para self); si tiene otros
parámetros y no tienen valor por default, cuando se crea la instancia se debe hacer con los
valores que tomaran los parámetros. Los métodos de una clase (así llamaremos a las
10
funciones de una clase) deben tener como primer parámetro self (puede ser otro nombre),
que hace referencia a la instancia que llama el método; cuando por medio de una instancia
llamamos un método, no le pasamos valor al parámetro self, Python lo hace.
Salida:
Nueva instancia creada
x.c = 1, x1.c = 1
Nueva instancia creada
x.c = 2, x2.c = 2
El método __init__() se ejecuta cuando se crea una instancia, por lo que es útil para inicializar
la instancia. Se pueden definir atributos de la instancia en el constructor, de modo que pueden
tener valores por defecto, o también se les puede asignar valor cuando se crea la instancia.
Los atributos de una instancia se pueden crear, eliminar, leer y escribir. Cuando se llama el
método __init__, los parámetros del método se vinculan con los valores que van a la derecha
del nombre de la clase (separados por comas y entre paréntesis) que se indican cuando la
instancia es creada. Entonces:
class Nombre_Clase:
def __init__(self, parametro_1, parametro_2,…,parametro_n):
bloque de instrucciones
Nombre_Instancia=Nombre_Clase(valor_1, valor_2,…,valor_n)
Ejemplo:
11
Salida:
nombre: sin nombre, edad: sin edad
nombre: He-man, edad: 35
nombre: She-ra, edad: 33
Entonces, los atributos de clase son los definidos directamente en la clase y que comparten
las instancias de la clase. Los atributos de instancia se pueden definir en el constructor y en
los métodos, o bien Nombre_Instancia.Nombre_Atributo=valor, y son particulares para cada
instancia. Por convención, el primer parámetro de un método es llamado self y hace
referencia a la instancia que llama el método. Ejemplo:
Salida:
Yo soy He-man, tengo 35 años.
Con la función hasattr(Nombre_Instancia, Nombre_Atributo) se obtiene True si determinado
atributo (Nombre_Atributo) existe en una determinada instancia (Nombre_Instancia),
ejemplo:
hasattr(persona,'nombre')
False
12
hasattr(p0,'nombre')
True
Para eliminar un atributo, instancia, o clase, usaremos del. De acuerdo con el ejemplo
anterior, para eliminar un atributo, una instancia, y una clase, escribimos:
del [Link]
del p0
del persona
Es posible escribir, leer, y eliminar atributos de instancia mediante métodos. Ejemplo:
Salida:
v0 = 0
v1 = 3
v2 = 24
{'v0': 0}
self.__dict__ es un diccionario con los atributos que tiene self. Cuando eliminamos un objeto
instanciado y todas sus referencias se llama (automaticamente) el destructor, es decir, el
método __del__(self), el parámetro self del destructor es la instancia eliminada, ejemplo,
13
Salida:
<__main__.clase1 object at 0x0000026475E7B8D0> creado.
Se llamó el creador.
Continuamos...
<__main__.clase1 object at 0x0000026475E7B8D0> destruido.
Se llamó el destructor.
Una clase 'parent' o 'base' le puede heredar los atributos y métodos que contiene a una clase
'child' o 'sub'. La clase 'sub' puede heredar de una o más clases, si hereda solo de una clase se
conoce como herencia única, si hereda de dos o más clases se conoce como herencia múltiple.
La sintaxis es la siguiente:
class base_1:
bloque de código
class base_2:
bloque de código
class sub(base_1,base_2):
bloque de código
Si la clase sub no tiene constructor, cuando se crea una instancia de sub se ejecuta el
constructor de la primera clase (de izquierda a derecha en el orden presentado) de las que
está heredando que si tenga constructor; si la clase sub tiene constructor, este será el que se
ejecute.
Ejemplo:
14
Salida:
Perímetro = 31.416, área = 78.54
En el siguiente ejemplo se puede observar que los parámetros del constructor __init__ () de
clase3 tienen valor por default, por lo que cuando se crea una instancia de clase3 se puede
hacer sin pasar valores. Además, hay que notar que se tuvo que pasar self como argumento
cuando se llamó clase1.__init__() y clase2.__init__(), ya que estos métodos son llamados por
parte de una clase (self se pasa automáticamente solo cuando el método es llamado por parte
de una instancia).
15
Salida:
a=1, b=2, c=3, d=4
La clase sub puede tener un método con el mismo nombre que la clase base, sin embargo, si
dicho método es llamado por una instancia de la clase sub, el método de la clase sub tiene
más precedencia y anula el método de la clase base. Además, si la clase sub hereda un método
que no está en la clase sub pero si en alguna/s de las clases base, cuando dicho método se
manda a llamar por medio de una instancia de la clase sub se ejecuta el método de la primera
clase (de izquierda a derecha, de las que se indicaron como clases base que le heredan a la
clase sub) que tenga el método.
Ejemplo:
16
Salida:
Se llamo el método c_perimetro de la clase area.
Perímetro = 31.416, área = 78.54
En el siguiente ejemplo se puede apreciar que cuando se crea la instancia x, el método
__init__() de clase2 tiene más precedencia que el de clase1. Sin embargo, esto no impide que
se pueda llamar el método __init__() de clase1, siendo necesario pasar self como argumento.
Salida:
x.a=1, x.b=2, x.c=3, x.d=4
17
Los atributos de una clase se pueden hacer privados, de modo que solo se pueden acceder y
modificar dentro de la clase. Para hacer un atributo o método privado, que se conoce en inglés
como 'data mangling', se escriben dos guiones bajos antes del nombre. Ejemplo:
Salida:
a=2
Traceback (most recent call last):
File "C:\Users\user\Dropbox\Materias\Codigos\Tutorial 4\dar_clase.py", line 207, in
<module>
print(x.__a)
AttributeError: 'clase1' object has no attribute '__a'
Los atributos y métodos privados se pueden acceder y modificar dentro de la clase donde
están definidos. Además, si el método es privado no es condición que tenga self como
parámetro, de ser así (sin parámetro self) dicho método no puede ser llamado por una
instancia ya que al hacerlo la instancia se pasa automáticamente como argumento y el método
no lo puede recibir, pero si puede ser llamado por una clase ya que esta no se pasa
automáticamente como argumento. Entonces, cuando una instancia llama un método
automáticamente pasa un objeto (es decir, la instancia misma), cuando una clase lo hace no
pasa ningún objeto. En Python un método es una función que es miembro de una clase.
Ejemplos:
Salida:
18
a=1, b=2
Método privado
Salida:
a=1, b=2
Traceback (most recent call last):
File "C:\Users\user\Desktop\[Link]", line 13, in <module>
[Link]()
File "C:\Users\user\Desktop\[Link]", line 7, in imprimir
x.__mensaje()
TypeError: clase1.__mensaje() takes 0 positional arguments but 1 was given
Las variables protegidas son aquellas que por convención no se accede a estas fuera de la
clase, aunque es posible hacerlo. La sintaxis de una variable protegida es: _nombre. Ejemplo:
Salida:
clase1._a=1, x._a=2
19
En Python, un método de clase está vinculado a la clase y tiene como primer parámetro una
clase, cuando una clase llama un método de clase se pasa automáticamente la clase (que se
vincula con el primer parámetro del método); un método de clase puede acceder o modificar
el estado de una clase y se crea con el decorador @classmethod. Un método estático no
necesariamente tiene parámetros, no puede acceder o modificar el estado de una clase y se
crea con el decorador @staticmethod. Además, si una instancia llama un método estático no
se pasa automáticamente la instancia. Ejemplo:
Salida:
nombre=zara, edad=33, año de nacimiento aproximado=desconocido
nombre=john, edad=39.6986301369863, año de nacimiento
aproximado=1984.0438356164384
Notar que el método estático imprimir tiene como parámetro self, que lo usamos para hacer
referencia a una instancia, por lo que cuando se llama el método es necesario pasar la
instancia como argumento. El método de clase año_nacimiento lo usamos para calcular el
valor de nacimiento, además devuelve la instrucción para crear una instancia de persona.
20
Archivos
Se usan principalmente dos tipos de archivos en programación. Tenemos archivos de texto,
que contienen caracteres ASCII o UNICODE (UTF-8). En un archivo de texto cada línea
termina con \n, que es para finalizar la línea y continuar en la siguiente. Y tenemos archivos
binarios, que contienen datos para ser leídos por la computadora. En un archivo binario no
hay líneas, por lo que no hay final de línea. La aplicación que lea el archivo binario interpreta
el contenido de este.
Para escribir en un archivo lo primero será abrir el archivo, para lo cual usaremos la función
open(), de modo que:
f = open("nombre_archivo", "modo_acceso", encoding='cp1252')
Tenemos que f es el identificador del archivo, que lo usaremos para escribir (o leer). El primer
argumento es el nombre del archivo (se puede incluir la ruta donde se encuentra de no estar
en el directorio donde está el módulo). El segundo argumento define el modo en que se abrirá
el archivo, y por lo tanto lo que se puede hacer con este. El valor predeterminado es 'r' (solo
lectura), por lo que este argumento es opcional. El tercer argumento (opcional) es para definir
el tipo de codificación (es recomendable definir este argumento cuando se trabaja en un
archivo de texto), que es encoding='cp1252' en Windows, y encoding='utf-8' en Linux.
Python guarda un archivo de texto en el disco en forma de bytes, de modo que para leerlo se
decodifica en cadenas y para guardarlo se codifica. A continuación, los modos de acceso para
definir el argumento "modo_acceso":
'r' –Para leer, es el modo predeterminado. El offset (la posición del cursor) se coloca al inicio.
'w' – Para escribir. Si el archivo no existe, se crea. Si había un archivo con el mismo nombre
es reemplazado.
'x' – Igual que 'w' pero el archivo creado no debe existir sino hasta ese momento, caso
contrario da error.
'a' – Abre el archivo para escribir respetando el contenido anterior. Si no existe un archivo
con el nombre indicado, se crea. El cursor se coloca al final del archivo.
Los modos se pueden combinar con las siguientes letras:
'b' – Modo binario, regresa bytes cuando hacemos lectura. Se usa para manejar archivos de
imágenes o ejecutables.
't' – Modo texto, regresa cadenas cuando hacemos lectura. Es el predeterminado.
'+' – Para actualizar, leer, y escribir.
Se pueden hacer combinaciones como:
'r+' – Se puede leer y escribir en el archivo. Dará un error si el archivo no existe.
'w+' – Para escribir y leer el archivo. Funciona igual que el modo ‘w’ pero permite leer.
'a+' – Opera igual que el modo ‘a’, pero permite leer.
21
Para tener el panorama completo de lo que se puede hacer en cada modo (leer y/o escribir),
donde se coloca el cursor (al principio o al final), si el archivo debe existir o no, y si se borra
el contenido del archivo al abrirlo, ver la tabla que se presenta en la respuesta por parte de
Peilonrayz en [5].
Escribir y leer archivos
Para crear un archivo y escribir en este, lo podemos hacer de la siguiente manera:
Entonces f es el identificador del archivo. Con el modo 'w' se elimina el archivo [Link] si
ya existía, para luego crear la nueva versión sin contenido. Con la función write() agregamos
contenido. La función write() regresa un número, que es el tamaño (número de posiciones)
del contenido de llamar la función. Con la función close() cerramos el archivo. De modo que
el archivo [Link] ahora contiene:
Linea numero uno.
Linea numero dos.
Linea numero tres.
Para agregar contenido al final de archivo lo hacemos con el modo 'a'. Entonces:
Entonces [Link] ahora contiene:
Linea numero uno.
Linea numero dos.
Linea numero tres.
Linea numero cuatro.
Con read(n) se hace lectura. Si n es negativo o no se pone, se lee todo el archivo. Si es positivo
se leerán n posiciones a partir de la posición del cursor. Si ya se ha leído todo el contenido
del archivo y se usa read(), este regresa un 'str' sin contenido. Para leer [Link]:
22
Cuya salida es el contenido en [Link]. Con el modo 'a+' se pone el cursor al final de la
última línea y se puede leer y escribir. Con seek(x) cambiamos la posición del cursor, de
modo que nos desplazamos x posiciones desde el inicio en la posición 0. De acuerdo con el
contenido en [Link], con seek(19) nos posicionamos al principio del segundo renglón.
Además, con [Link](17) se lee el contenido de 17 posiciones.
Y la salida es:
Linea numero dos.
Para leer la tercer palabra del primer renglón lo podemos hacer así:
Con [Link](13) nos colocamos en la posición 13 a partir del principio, y con [Link](3)
indicamos leer lo que está en las siguientes tres posiciones, por lo que [Link](3)= 'uno'.
Además, con la función tell() podemos saber la posición actual. Ya que con [Link](13) nos
colocamos en la posición 13 e hicimos la lectura de 3 caracteres, ahora el cursor está en la
posición 13+3=16, que es lo que nos entrega [Link]()=16.
Con la función writelines(['cadena_1', 'cadena_2', 'cadena_3']) podemos escribir el contenido
de una lista (que contiene cadenas) en un archivo. Ejemplo:
Y la salida es lo que contiene [Link]. Para cerrar un archivo usamos close(), esto lo
hacemos para liberar los recursos del sistema que se están usando por tener el archivo abierto.
De no cerrar el archivo, el recolector de basura de Python eventualmente cerrará el archivo.
Esto sucede de acuerdo con la implementación de Python. Otra manera de abrir y cerrar un
archivo es:
23
Con la sentencia with (línea 69) abrimos el archivo [Link] en modo ‘w’, siendo f el
identificador del archivo. Después viene un bloque de instrucciones indentado (línea 70 a
77). Con el identificador f podemos acceder a atributos como [Link], que regresa True si el
archivo está cerrado, y False en caso contrario, [Link] regresa el modo de acceso al archivo,
y [Link] regresa el nombre del archivo. Entonces la salida es:
False
w
[Link]
True
En la línea 75 tenemos que [Link] = False, ya que dentro del bloque indentado el estado de
f es abierto. En la línea 79 tenemos [Link]=True, ya que esta instrucción ya no es parte del
bloque indentado el estado de f es cerrado.
Una manera para acceder renglón por renglón al contenido de un archivo es:
Que resulta:
Linea numero uno.
Linea numero dos.
Linea numero tres.
Con readline() accedemos al primer renglón, si volvemos a poner esta instrucción accedemos
al siguiente, y así sucesivamente. Si ponemos readline(n), leeremos el contenido de las
siguientes n posiciones del renglón donde se encuentre el cursor, sin pasar a leer el contenido
del siguiente renglón. Ejemplo:
24
Y obtenemos:
Renglon 1 = Linea numero uno.
Renglon 2 = Linea numero dos.
Renglon 3 = Linea
Para guardar cada renglón de un archivo como un objeto de una lista lo hacemos con list(f),
o con [Link](), siendo f el identificador del archivo. Entonces:
Salida:
<class 'list'>
['Linea numero uno.\n', 'Linea numero dos.\n', 'Linea numero tres.\n']
<class 'list'>
['Linea numero dos.\n', 'Linea numero tres.\n']
En lista=list(f) tenemos el contenido de cada renglón (incluido el cambio de línea, es decir
\n) de [Link] como un objeto de clase 'str'. En líneas=[Link]() tenemos los dos últimos
renglones de [Link], para eso previamente nos colocamos en la posición 19 con seek(19),
ya que desde esta posición empieza el contenido del segundo renglón.
Ahora:
25
Con [Link]() asignamos en salida (una lista) cada renglón de [Link]. Con un for
accedemos a cada objeto en salida. Además, con la variable i se lleva la numeración.
Ejemplo:
Y la salida es:
1.- Linea numero uno.
2.- Linea numero dos.
3.- Linea numero tres.
En la función print(), con end = '' se evita el cambio de línea, sin embargo si sucede el cambio
de línea indicado en cada renglón de [Link].
Manipular archivos
Para copiar un archivo lo podemos hacer con copyfile(archivo_fuente, archivo_destino), el
primer argumento es el archivo fuente, el segundo argumento es el archivo destino. Para
ambos archivos se pone la ruta completa si no están en el directorio del módulo. Ejemplo:
26
De shutil se importa copyfile. Tenemos que en fuente asignamos el nombre del archivo que
vamos a copiar, y en destino el nombre del archivo en el cual se hará la copia. La instrucción
copyfile(fuente, destino), copia el archivo '[Link]' en '[Link]', si el archivo destino no
existe se crea. De haber un error en la línea 7, con except en línea 24 se verifica si el error es
IOError (que sucede cuando se trata de abrir un archivo que no existe) para imprimirlo en
pantalla, con except en línea 27 se imprime el contenido de una tupla con tres valores
informativos de la excepción detectada. De no haber error en línea 7, en línea 8 se imprime
un mensaje para informar que el archivo fue copiado, luego dentro del bloque while (línea
11 a 22) se le pregunta al usuario si quiere imprimir el contenido del archivo destino, y
dependiendo de la respuesta se imprime en pantalla o no. El continue (línea 22) es para pasar
a la siguiente iteración del while (diferente de pass, que es para indicar que pase a la siguiente
línea del código). La salida con entrada='s' es:
Este es el contenido del archivo [Link]:
Linea numero uno.
Linea numero dos.
Linea numero tres.
Si una excepción (error) se presenta cuando estamos haciendo operaciones con un archivo
antes de cerrarlo, el resto de las instrucciones del módulo no se ejecutan y el archivo no será
cerrado. Esto se puede evitar con:
with open("nombre_archivo") as f:
bloque de código
ya que si sucede un error dentro del bloque, al salir del bloque a causa del error se cierra el
archivo. Si en un try tenemos:
f = open("nombre_archivo")
con finally podemos cerrar el archivo si sucede un error. Ejemplo:
Las instrucciones del bloque finally (línea 7 y 8) se ejecutan de haber o no error en el bloque
del try. Si hay error el intérprete pasa al bloque del except, luego al del finally. Si no hay
error se brinca el bloque del except pero si pasa al bloque del finally. Entonces las
27
instrucciones para abrir un archivo, y demás instrucciones que puedan producir un error, las
podemos poner en el bloque del try, y en el bloque finally la instrucción para cerrarlo. Con
esto se evita dejar abierto el archivo si sucede un error.
Salida:
except
Se pudo cerrar el archivo [Link]: True
¿Esta instruccion sucede o no sucede?
Pese al error, es decir que h no está definido y se intentó imprimir en pantalla, en el bloque
finally cerramos el archivo con la instrucción en línea 7. Cuando no tenemos bloque except
y no hay error en el bloque try, el intérprete pasa al bloque finally y continua con el resto de
las instrucciones. En el caso de si haber error, el interprete pasa al bloque finally pero no
ejecutara el resto de las instrucciones. Ejemplo:
Salida:
Se pudo cerrar el archivo [Link]: True
Traceback (most recent call last):
File "C:\Users\jgcg2\Dropbox\Materias\Codigos\[Link]", line 3, in <module>
print(h)
NameError: name 'h' is not defined
Para cambiar el nombre de un archivo es necesario importar os, luego con
[Link]('nombre_actual', 'nombre_nuevo'), donde 'nombre_actual' es el nombre actual del
archivo, y 'nombre_nuevo' es el nombre que le pondremos. Ejemplo:
Por lo que '[Link]' ahora se llama '[Link]'. También es posible eliminar un archivo
mediante [Link]('nombre_archivo'), el cual elimina el archivo llamado 'nombre_archivo'.
Ejemplo:
28
Y de esta manera queda eliminado '[Link]'.
Lectura y escritura de datos con formato
Lectura
Un archivo con extensión csv contiene valores separados por coma (Comma Separated
Values). Para hacer lectura de este tipo de archivos, e igualmente archivos con extensión txt
pero con formato, importaremos el módulo csv. Para dar un ejemplo, en Excel pongamos la
siguiente información:
Figura 2.
Y lo guardamos como [Link]
Figura 3.
En Python podemos leer la información del archivo [Link]. A continuación, un ejemplo
para leer el archivo, guardar la información en una lista de dos dimensiones, y convertir las
entradas numéricas de clase 'str' a clase 'float'.
29
En línea 1 importamos el módulo csv. En línea 3 abrimos el archivo en modo lectura y le
ponemos f como identificador. Para leer el archivo lo hacemos con contenido=[Link](f,
delimiter=','), el primer argumento es el identificador del archivo (f en este caso), con el
argumento delimiter= ',' indicamos que una coma es el separador, ya que implícitamente en
un archivo csv de excel se entiende que las columnas se separan por comas y los renglones
por cambios de línea. En contenido tenemos la lectura que se hizo del archivo. En la línea 5
inicializamos una lista vacía y la nombramos r. Con un for (línea 6) agregamos cada renglón
(que se pasa como una lista) en la lista r, por lo que en cada iteración del for se agrega una
lista a la lista r. Al concluir el for y una vez cerrado el archivo [Link], imprimimos el
contenido de r (línea 9):
r= [['Nombre', 'Edad', 'Profesion'], ['Uno', '23', 'Aviador'], ['Dos', '22', 'Chofer'], ['Tres', '33',
'Profesor']]
Podemos ver que r es una lista que contiene 4 listas, con 3 objetos de clase 'str' cada una.
Para acceder a cada objeto de cada lista en r podemos usar dos índices, i para acceder a una
lista, y j para acceder a los objetos de la lista i. Para acceder a la cadena 'Profesor', nos damos
cuenta de que está en la lista i=3, en la posición j=2, por lo tanto r[3][2]= 'Profesor'. Entonces
por cada lista con índice i, accedemos a sus objetos por medio del índice j. Con la instrucción
en línea 15, que es el bloque del try en línea 14, se intenta convertir el objeto en la lista i,
posición j, de 'str' a 'int'. Sin embargo, si el contenido en r[i][j] no es numérico se dará un
error, porque la conversión no se puede hacer. En el bloque del except tenemos la sentencia
pass, que lo ponemos de esta manera para ignorar el error, de haber error no se hace la
asignación de la línea 15. Entonces cuando se puede hacer la conversión de 'str' a 'int' se hace
y se actualiza el contenido en r[i][j], cuando no se puede el contenido en r[i][j] no cambia.
Luego de acceder a cada objeto j de cada lista i para intentar hacer la conversión, pasamos a
la línea 20 para imprimir el contenido actual de r:
30
r= [['Nombre', 'Edad', 'Profesion'], ['Uno', 23, 'Aviador'], ['Dos', 22, 'Chofer'], ['Tres', 33,
'Profesor']]
Entonces donde antes había una cadena con contenido numérico de clase 'str', ahora es clase
'int' (no está entre comillas). Esto lo podemos verificar imprimiendo la clase con la función
type() de r[i][j], con i en el rango 1 a 3, y j=1.
Se pueden leer archivos con extensión txt que tengan formato. La misma información del
archivo [Link] la escribimos en un editor de texto, pero la separación entre columnas
la hacemos presionando la tecla Tab, de modo que:
La lectura se hace igual pero ahora delimiter = '\t', que es para indicar que el delimitador es
Tab. Entonces:
Imprimimos en pantalla cada renglón del archivo leído. La salida es:
['Nombre', 'Edad', 'Profesion']
['Uno', '23', 'Aviador']
['Dos', '22', 'Chofer']
['Tres', '33', 'Profesor']
Con [Link](f), con f el identificador del archivo, se crea un diccionario (objeto de
clase dict) por cada renglón después del primero, ya que el primer renglón es donde está el
encabezado (nombre) de las columnas. Entonces en el primer renglón de [Link]
tenemos las claves, y en los renglones siguientes los valores asociados a cada clave (nombre
de columna). Ejemplo:
31
Salida:
{'Nombre': 'Uno', 'Edad': '23', 'Profesion': 'Aviador'}
{'Nombre': 'Dos', 'Edad': '22', 'Profesion': 'Chofer'}
{'Nombre': 'Tres', 'Edad': '33', 'Profesion': 'Profesor'}
Para leer un archivo podemos especificar dialect, que es un argumento de [Link]() para
especificar el formato del archivo. Ejemplo:
Crear el archivo [Link] con el siguiente contenido:
El código:
Con csv.register_dialect() indicaremos el formato. El argumento 'formato' es el nombre
(arbitrario) del formato, el argumento delimiter='|' se refiere al delimitador, el argumento
skipinitialspace=True es para ignorar la cantidad de espacios a la derecha del delimitador
(con False no lo hará). Cuando hacemos la lectura con [Link](), pasamos como
argumento el identificador del archivo y el argumento dialect='formato', que es el nombre
del formato. La salida es:
['ID', 'Nombre', 'Email']
32
['87', 'Alfonso', 'alfonsito@[Link]']
['85', 'Susana', 'susanita@[Link]']
['83', 'Katy', 'katy@[Link]']
Se puede hacer la lectura de un archivo del cual no conocemos el formato. Ejemplo:
En este caso para hacer la lectura inicial (sin especificar nada del formato) lo hacemos con
[Link](), y la asignamos a contenido. Con [Link]().has_header(contenido) se obtiene
True si las columnas tienen nombre (False en caso contrario). En este caso si tienen, que son:
ID, Nombre, Email. Con [Link]().sniff(contenido) obtenemos el formato y lo asignamos
a formato. El delimitador se obtiene con [Link], y True o False para ignorar los
espacios a la derecha del delimitador con [Link]. Salida:
ID| Nombre| Email
87| Alfonso| alfonsito@[Link]
85| Susana| susanita@[Link]
83| Katy| katy@[Link]
Tiene encabezado: True
Delimitador: |
Ignorar espacios después del delimitador: True
Escritura
Para escribir en un archivo con extensión csv lo podemos hacer así:
33
Abrimos el archivo pelí[Link] en modo 'w', para poder escribir en este y que se cree de no
existir, con f como el identificador del archivo. Con el argumento newline='' evitamos que se
pongan renglones en blanco entre los renglones que si tienen información. Creamos un objeto
para escribir con writer = [Link](f). Para escribir un renglón lo hacemos con
[Link](['cadena_1', 'cadena_2', 'cadena_x']), y dentro de los corchetes la
información con determinado formato. Después de ejecutar el módulo el archivo
'[Link]' contiene:
Podemos escribir el contenido deseado, se puede especificar todos los renglones con una sola
instrucción. Ejemplo:
La información la guardamos en una lista de dos dimensiones, que es lista_2d. Con
[Link](lista_2d) escribimos el contenido de lista_2d en el archivo [Link].
Se puede escoger el tipo de archivo y el delimitador. Ejemplo:
34
Se ha creado y escrito información en '[Link]', con delimiter = '|', por lo que el archivo
contiene:
También podemos escribir información como diccionario. Ejemplo:
En nombres_columnas asignamos en una lista el encabezado de cada columna (dos en este
caso). Con [Link]() creamos el objeto para escribir, como argumentos pasamos f,
que es el identificador del archivo, y fieldnames=nombres_columnas, que es donde va la
información de los encabezados. Con [Link]() escribimos en el archivo los
encabezados, luego escribimos cada renglón con [Link]({encabezado_1 : valor_1,
encabezado_x : valor_2}), y dentro de las llaves la información como diccionario. El archivo
queda así:
35
Referencias
[1] Wikipedia. "Normal distribution." [Link]
(accessed.
[2] Machinelearningmastery. "A Gentle Introduction to Normality Tests in Python."
[Link]
python/ (accessed.
[3] Wikipedia. "Histograma." [Link] (accessed.
[4] stackoverflow. "Objects vs instance in python."
[Link]
(accessed.
[5] Stackoverflow. "Difference between modes a, a+, w, w+, and r+ in built-in open
function?" [Link]
modes-a-a-w-w-and-r-in-built-in-open-function (accessed.
36