Archivos con Python =================== En los próximos ejercicios vamos a usar frecuentemente archivos de datos, así que es un buen momento para leer en detalle el capítulo 11 del libro de texto. Las funciones básicas de escritura son muy sencillas. .. code:: python f = open('ejemplo.txt', 'w') f.write('''Esto es un ejemplo de archivo escrito con Python. Puedo escribir en varias lineas porque estoy usando las triples comillas.''') f.close() Leer archivos es igual de sencillo. .. code:: python fi = open('ejemplo.txt', 'r') for linea in fi: print(linea,end='') fi.close() .. parsed-literal:: Esto es un ejemplo de archivo escrito con Python. Puedo escribir en varias lineas porque estoy usando las triples comillas. Observa que pongo una coma al final del ``print``. Lo hago porque las líneas incluyen el caracter terminador de línea si lo hubiera. También puedo quitarlos con ``strip`` pero observa cómo ``strip`` elimina también los espacios al principio de la línea: .. code:: python fi = open('ejemplo.txt', 'r') for linea in fi: print(linea.strip()) fi.close() .. parsed-literal:: Esto es un ejemplo de archivo escrito con Python. Puedo escribir en varias lineas porque estoy usando las triples comillas. Como resumen podemos decir que en la mayoría de los casos solo se necesitan 3 funciones para manejar archivos (``open``, ``close`` y ``write``). Hay muchas más y te animo a que leas en detalle el capítulo 11 del libro y la `documentación de archivos oficial `__. Lo que leemos o escribimos de/en archivos son cadenas de texto, así que para usos avanzados tendremos que dominar las cadenas de texto. Repasa el capítulo 7 del libro de texto y la `documentación de cadenas oficial `__. También puede que te resulten útiles los módulos `string `__ y `re `__. Lectura de archivos CSV ----------------------- Los archivos CSV no son diferentes de los demás, son simples archivos de texto en los que cada línea corresponde a una fila de una tabla. Cada campo en una línea se separa con una coma. (El nombre CSV deriva precisamente de ésto (*Comma Separated Values*). En Python existe un módulo ``csv`` que simplifica la lectura de estos archivos. Pero realmente es muy simple también procesarlos a mano. Esto podría ser un ejemplo de archivo CSV. .. raw:: html
,Ambos sexos,Mujeres
   Aragón,"6845.0","3962.0"
   Canarias,"11164.0","6181.0"
.. code:: python fi = open('ejemplo.csv', 'r') for linea in fi: fila = linea.strip() celdas = fila.split(',') for celda in celdas: print('[{!s:>11}]\t'.format(celda), end='') print() fi.close() .. parsed-literal:: [ ] [Ambos sexos] [ Mujeres] [ Aragón] [ "6845.0"] [ "3962.0"] [ Canarias] [ "11164.0"] [ "6181.0"] Caso de estudio: Censo de viviendas ----------------------------------- El INE distribuye datos del `Censo de Población y Viviendas `__ que incluyen dos archivos interesantes para nuestros propósitos: - Por un lado se distribuyen los `microdatos de toda España `__ que contienen todos los datos de la encuesta sin procesar. - Por otro lado se distribuye una hoja de cálculo que describe el `formato de cada registro del archivo de microdatos `__. Veamos cómo es el diseño de los registros. Es una tabla que indica a partir de qué posición empieza cada campo y hasta qué posición, así como la interpretación que tiene cada posible valor. Por ejemplo, para ver si la vivienda tiene o no Internet habría que consultar el caracter 25 (empezando desde 1). Es decir, si ``linea`` contiene una línea completa del archivo de microdatos entonces ``linea[24]`` nos indica si tiene o no Internet esa vivienda. .. raw:: html :: .. raw:: html
Nombre del campo Nombre de la variable Longitud del campo Inicio Fin Valores validos
Identificación




Código de provincia CPRO 2 1 2 Desde 1 hasta 52
Código o tamaño de municipio CMUN 3 3 5 Si tamaño de municipio <=2.000, CMUN=991
Si 2.001 <=tamaño de municipio <=5.000, CMUN=992
Si 5.001 <=tamaño de municipio <=10.000, CMUN=993
Si 10.001 <=tamaño de municipio <=20.000, CMUN=994
Si tamaño de municipio >20.000, CMUN=Código de municipio
Datos de la vivienda




Factor de elevación de la vivienda FACTOR 14 6 19
Clase de vivienda CVIVIF 1 20 20 1 Vivienda Prinicipal
2 Vivienda Secundaria
3 Vivienda Vacía
Régimen de tenencia TENEN 1 21 21 1 Propia, por compra, totalmente pagada
2 Propia, por compra, con pagos pendientes (hipotecas)
3 Propia por herencia o donación
4 Alquilada
5 Cedida gratis o a bajo precio (por otro hogar, pagada por la empresa...)
6 Otra forma
Blanco si CVIVIF <> 1
Calefacción CALE 1 22 22 1 Colectiva o central
2 Individual
3 No tiene calefacción pero sí algún aparato que permite calentar
4 No tiene calefacción
Blanco si CVIVIF <> 1
Cuanto de aseo con inodoro ASEO 1 23 23 1 Sí
2 No
Blanco si CVIVIF <> 1
Baño o ducha BADUCH 1 24 24 1 Sí
2 No
Blanco si CVIVIF <> 1
Acceso a Internet INTERNET 1 25 25 1 Sí
2 No
Blanco si CVIVIF <> 1
Sistema de suministro de agua AGUACOR 1 26 26 1 Agua corriente por abastecimiento público
2 Agua corriente por abastecimiento privado o particular del edificio
3 No tiene agua corriente
Blanco si CVIVIF <> 1
Superficie útil SUT 3 27 29 Desde 5 hasta 999
Blanco si CVIVIF <> 1
Número de habitaciones NHAB 2 30 31 Desde 1 hasta 99
Blanco si CVIVIF <> 1
...




Vamos a contestar alguna pregunta de ejemplo. Por ejemplo, ¿cuántas viviendas secundarias (caracter 20) tienen Internet (caracter 25)? .. code:: python def viviendas_secundarias_con_internet(): f = open('Microdatos_viviendas.txt', 'r') c = 0 for linea in f: if linea[19] == '2' and linea[24] == '1': c += 1 f.close() return c .. code:: python print('{} viviendas secundarias tienen Internet' .format(viviendas_secundarias_con_internet())) .. parsed-literal:: 0 viviendas secundarias tienen Internet ¿Y qué porcentaje de viviendas principales tiene Internet? .. code:: python def viviendas_1_con_internet(): f = open('Microdatos_viviendas.txt', 'r') viviendas = 0 internet = 0 for linea in f: if linea[19] == '1': viviendas += 1 if linea[24] == '1': internet += 1 f.close() return internet*100.0/viviendas .. code:: python print('El {:.2f}% de las primeras viviendas tienen Internet' .format(viviendas_1_con_internet())) .. parsed-literal:: El 50.65% de las primeras viviendas tienen Internet Ese código con tantos niveles de anidamiento no es bonito, vamos a refactorizarlo un poco. .. code:: python def viviendas_1_con_internet(): f = open('Microdatos_viviendas.txt', 'r') viviendas = 0 internet = 0 for linea in f: viviendas, internet = acum_datos_interes(linea, viviendas, internet) f.close() return 100.0 * internet / viviendas def acum_datos_interes(linea, viviendas, internet): if linea[19] == '1': viviendas += 1 if linea[24] == '1': internet += 1 return viviendas, internet .. code:: python print ('El {:.2f}% de las primeras viviendas tienen Internet' .format(viviendas_1_con_internet())) .. parsed-literal:: El 50.65% de las primeras viviendas tienen Internet Sigue sin ser especialmente elegante pero ya no tiene tantos niveles de indentación. Aprenderemos a mejorarlo cuando veamos clases.