Full text
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA (GRADO EN INGENIERÍA DE COMPUTADORES) APLICACIÓN ESTADÍSTICA MÓVIL PARA DATOS ABIERTOS MOBILE STATISTICAL APPLICATION FOR OPEN DATA Realizado por Juan de Dios Paredes Arjona Tutorizado por Daniel Garrido Márquez Departamento Lenguajes y Ciencias de la Computación UNIVERSIDAD DE MÁLAGA MÁLAGA, Diciembre, 2016 Fecha defensa: El Secretario del Tribunal
Resumen: Este TFG nace a partir del movimiento de Datos Abiertos que podemos encontrar en gran número de entidades a nivel mundial y sobre todo, en las administraciones públicas. Este movimiento se basa en la difusión de datos, según las leyes de cada país, que hacen estas entidades para que puedan ser tratados de manera automática por cualquier programa de forma libre y sin restricciones. Tenemos por objetivo realizar una aplicación móvil que permita realizar análisis estadísticos de estos datos, centrándose en el formato CSV, que es el formato más utilizado en estos momentos. Hemos implementado dicha aplicación, con éxito, en entorno Android, siguiendo las pautas de un proceso software de Desarrollo Iterativo e Incremental (IID), pasando así, por etapas retroalimentadas de capturas de requisitos, análisis, diseño, implementación y pruebas, tal y como se detalla en la presente memoria. Se obtiene un producto final completo que puede abordar cualquieras datos en formato CSV. Además podemos crear y analizar nuestro propios datos creados en este formato. Tiene limitaciones de memoria debido a que estos ficheros pueden consumir gran cantidades de memoria, pero esperamos que esta restricción sea superada por la evolución de capacidad física que tengan los móviles en un futuro próximo. Palabras Clave: Datos Abiertos, Android, Estadística, Ficheros CSV, Móvil, App, Aplicación, Teléfono, Celular y Smarthphone.
Abstract: This TFG born from the Open Data movement that can be found in many institutions worldwide and especially in government. This movement is based on the dissemination of data, according to the laws of each country, which make these entities so that they can be handled automatically by any program freely and without restrictions. We aim to make a mobile application that allows statistical analysis of these data, focusing on the CSV format, which is the most widely used format right now. We have implemented the application, successfully, in Android environment, following the guidelines of software Iterative Development and Incremental (IID) process and happening, fed back stages of catches of requirements, analysis, design, implementation and testing, as detailed herein. We complete end product that can address data in CSV format no matter who is obtained. We can also create and analyze our own data created in this format. Memory has limitations because these files can consume large amounts of memory, but we hope that this restriction is overcome by the evolution of physical capacity that are mobile in the future. Keywords: Open Data, Android, Statistics, CSV Files, Mobile, Cell, App, Application, Phone and Smarthphone.
ÍNDICE: INTRODUCCIÓN ........................................................................................................ 8 CAPÍTULO 1: MEDIDAS DE ESTADÍSTICA DESCRIPTIVAS ............................... 10 MEDIDAS DE DISPERSIÓN: ........................................................................................ 10 Medidas de Dispersión Absolutas: ..................................................................... 10 Varianza:......................................................................................................... 10 Desviación Típica: .......................................................................................... 11 Rango: ............................................................................................................ 11 Medidas de Dispersión Relativas: ...................................................................... 11 Error Estándar de la Media: ............................................................................ 11 Coeficiente de Variación de Pearson: ............................................................. 12 MEDIDAS DE RELACIÓN LINEAL ................................................................................. 12 Covarianza...................................................................................................... 12 Coeficiente de Correlación de Pearson .......................................................... 13 CAPÍTULO 2: INTRODUCCIÓN A ANDROID ......................................................... 15 ANDROID ................................................................................................................. 15 CONSIDERACIONES ANDROID DE OPEN DATA ............................................................. 15 VISTA ..................................................................................................................... 15 ACTIVIDAD ............................................................................................................... 16 INTENCIÓN .............................................................................................................. 16 MÁQUINA VIRTUAL DALVIK ........................................................................................ 16 CICLO DE VIDA DE UNA ACTIVIDAD.............................................................................. 16 CAPÍTULO 3: FICHEROS CSV ............................................................................... 19 CAPÍTULO 4: FASES DEL PROYECTO ................................................................. 21 CAPTURA DE REQUISITOS ......................................................................................... 24 ANÁLISIS ................................................................................................................. 29 DISEÑO ................................................................................................................... 34 PROGRAMACIÓN ...................................................................................................... 46 PRUEBAS ................................................................................................................ 54 CONCLUSIONES Y POSIBLES MEJORAS: .......................................................... 58 BIBLIOGRAFÍA: ...................................................................................................... 60 ANEXO A: MANUAL DE USUARIO ........................................................................ 61 ANEXO B: FORMATOS DE FECHA ACEPTADOS POR LA APLICACIÓN .......... 86
8 Introducción En esta introducción hablaremos de la motivación y objetivos del proyecto, de la estructura de esta memoria y haremos un breve estudio de la tecnología usada El concepto datos abiertos (open data, en inglés) es una filosofía y práctica que persigue que determinados tipos de datos estén disponibles de forma libre para todo el mundo, sin restricciones de derechos de autor, de patentes o de otros mecanismos de control. Tiene una ética similar a otros movimientos y comunidades abiertos, como el software libre, el código abierto (open source, en inglés) y el acceso libre (open access, en inglés). La utilización de estándares puede facilitar a cualquier persona acceder a estos datos y también el tratamiento automático de esta información. Son numerosas las administraciones que actualmente ponen a disposición de los ciudadanos datos públicos: ayuntamientos, comunidades autónomas y la propia administración central. Por ejemplo, tenemos el portal web para datos abiertos del ayuntamiento de Málaga (http://datosabiertos.malaga.eu/), Junta de Andalucía ( http://www.juntadeandalucia.es/datosabiertos/portal.html) o Gobierno de España ( http://datos.gob.es/). Todo ello, con el objetivo de conseguir una mayor transparencia de la actividad gubernativa. También existen reflejos de este movimiento en Europa, concretamente en la Unión Europea (http://europa.eu/publications/open-data/index_es.htm) y en el mundo, como por ejemplo en el banco mundial (http://datos.bancomundial.org/). En este contexto, es de utilidad la realización de aplicaciones que manejen estos datos de manera automática y pueden suponer una ventaja para el ciudadano. En este sentido, en este trabajo se realizará una aplicación móvil que permite recuperar y visualizar estos datos para su análisis estadístico (siempre que estos datos sean susceptibles a realizar este tipo de análisis). El objetivo de este TFG es realizar un programa para Smartphone que se encargue de realizar estadísticas descriptivas de los Datos Abiertos ofrecidos a los ciudadano aprovechando la cobertura que de ellos hacen las diferentes asociaciones e instituciones entre las que se encuentran las Administraciones Públicas encargadas de publicar estos datos en una variedad de formatos para su diferente tratamiento de forma automática. Nuestra aplicación se centrará en el formato „csv‟, que es quizás el más utilizado para difundir estos datos. La presente memoria se estructura en cuatro capítulos, el primero de ellos nos explican los concepto estadísticos utilizados en la App, el segundo nos explica los conceptos más generales de Android y está pensado para personas que no conozcan este plataforma de programación, y el tercero capítulo nos explican qué son los archivos CSV y por último capítulo cuatro nos explica las fases por las cuáles ha pasado este TFG. Además se explican las conclusiones a las que hemos
9 llegado en éste TFG y las posibles mejoras del trabajo. Complementariamente se aporta como anexos un completísimo manual de usuario y una descripción de los formatos de fecha aceptados por la App La tecnología a usar es la plataforma de programación Android aprovechando su funcionalidad y la enorme expansión que tiene su SO Android. Ésta funcionalidad permite la creación de aplicaciones como la nuestra permitiéndonos explotar los beneficios que supone hacer esta aplicación para un dispositivo móvil tipo smarthphone.
16 Actividad Definimos el concepto de Actividad: en Android una Actividad es una pantalla del Interfaz del Usuario y tiene asociada una subclase de la clase Activity. Es en ésta subclase donde definiremos todo el código de Android asociado a la actividad, como layouts, líneas de texto, eventos, etc. Por lo general no todo el código se escribe en esta clase, aunque se podría, y viene ayudado de otra forma alternativa de definir elementos de visualización como son los archivos XML. Con lo que nuestro código de la Actividad tiene mezclados código de las API, más archivos XML. Intención Intención: Una intención es con concepto asociado a la programación, y es la voluntad de una aplicación de hacer algo. Esta voluntad se comunica al S.O. y este reacciona adecuadamente. P.ej. Una intención de una aplicación sería podría ser hacer una llamada por teléfono, se define en el código de la aplicación y el S.O. reaccionará para facilitar esa llamada. Máquina Virtual Dalvik Máquina Virtual Dalvik: es una implementación del Máquina Virtual Java optimizada para dispositivos móviles. Aunque la sintaxis del código fuente de las actividades y demás código es igual a Java, las API de Android no son compatibles con todos los códigos Java, así, por ejemplo, no admite el AWT entre otros. Ciclo de vida de una actividad El ciclo de vida de una aplicación Android es bastante diferente al ciclo de vida de una aplicación en otros S.O., como Windows. La mayor diferencia es que, en Android el ciclo de vida es controlado principalmente por el sistema, en lugar de ser controlado directamente por el usuario. Son las actividades las que realmente controlan el ciclo de vida de las aplicaciones, dado que el usuario no cambia de aplicación, sino de actividad. El sistema mantiene una pila con las actividades previamente visualizadas, de forma que el usuario puede regresar a la actividad anterior pulsando la tecla “retorno”.
17 Una aplicación Android corre dentro de su propio proceso Linux. Este proceso se crea con la aplicación y continuará vivo hasta que ya no sea requerido y el sistema reclame su memoria para asignársela a otra aplicación. Una característica importante, y poco usual, de Android es que la destrucción de un proceso no es controlada directamente por la aplicación, sino que es el sistema el que determina cuándo destruir el proceso. Lo hace basándose en el conocimiento que tiene de las partes de la aplicación que están corriendo (actividades y servicios), en la importancia de dichas partes para el usuario y en cuánta memoria disponible hay en un determinado momento. Si tras eliminar el proceso de una aplicación, el usuario vuelve a ella, se crea de nuevo el proceso, pero se habrá perdido el estado que tenía esa aplicación. En estos casos, será responsabilidad del programador almacenar el estado de las actividades, si queremos que cuando sean reiniciadas conserven su estado. Como vemos, Android es sensible al ciclo de vida de una actividad; por lo tanto, necesitas comprender y manejar los eventos relacionados con el ciclo de vida si quieres crear aplicaciones estables. Una actividad en Android puede estar en uno de estos cuatro estados: Activa (Running): La actividad está encima de la pila, lo que quiere decir que es visible y tiene el foco. Visible (Paused): La actividad es visible pero no tiene el foco. Se alcanza este estado cuando pasa a activa otra actividad con alguna parte transparente o que no ocupa toda la pantalla. Cuando una actividad está tapada por completo, pasa a estar parada. Parada (Stopped): Cuando la actividad no es visible. El programador debe guardar el estado de la interfaz de usuario, preferencias, etc. Destruida (Destroyed): Cuando la actividad termina al invocarse el método finish(), o es matada por el sistema. Cada vez que una actividad cambia de estado se van a generar eventos que podrán ser capturados por ciertos métodos de la actividad. A continuación se muestra un esquema que ilustra los métodos que capturan estos eventos.
18 Ciclo de vida de una actividad. onCreate(Bundle): Se llama en la creación de la actividad. Se utiliza para realizar todo tipo de inicializaciones, como la creación de la interfaz de usuario o la inicialización de estructuras de datos. Puede recibir información de estado de la actividad (en una instancia de la clase Bundle), por si se reanuda desde una actividad que ha sido destruida y vuelta a crear. onStart(): Nos indica que la actividad está a punto de ser mostrada al usuario. onResume(): Se llama cuando la actividad va a comenzar a interactuar con el usuario. Es un buen lugar para lanzar las animaciones y la música. onPause(): Indica que la actividad está a punto de ser lanzada a segundo plano, normalmente porque otra actividad es lanzada. Es el lugar adecuado para detener animaciones, música o almacenar los datos que estaban en edición. onStop(): La actividad ya no va a ser visible para el usuario. Ojo si hay muy poca memoria, es posible que la actividad se destruya sin llamar a este método. onRestart(): Indica que la actividad va a volver a ser representada después de haber pasado por onStop(). onDestroy(): Se llama antes de que la actividad sea totalmente destruida. Por ejemplo, cuando el usuario pulsa el botón de volver o cuando se llama al método finish(). Ojo si hay muy poca memoria, es posible que la actividad se destruya sin llamar a este método.
19 Capítulo 3: Ficheros csv Este es el tipo de formato de documento que lee la aplicación Open Data. A continuación vamos a explicarlo con un sencillo ejemplo. Los archivos CSV (del inglés comma-separated values) son un tipo de documento en formato abierto sencillo para representar datos en forma de tabla, en las que las columnas se separan por comas (o punto y coma en donde la coma es el separador decimal: Argentina, Brasil...) y las filas por saltos de línea. Los campos que contengan una coma, un salto de línea o una comilla doble deben ser encerrados entre comillas dobles. El formato CSV es muy sencillo y no indica un juego de caracteres concreto, ni cómo van situados los bytes, ni el formato para el salto de línea. La primera fila que encontramos en el fichero se corresponde con los nombres de los campos y las siguientes filas se corresponden con los registros que contienen, cada uno, un valor para cada campo. Veamos un ejemplo de fichero CSV, al que llamaremos „Jugador.csv‟, este fichero podría ser creado fácilmente con el Bloc de Notas de Windows: Este fichero se correspondería con la tabla: Nombre Puntos Rebotes Asistencias Pau Gasol 17.4 10.4 5.5 Ricky Rubio 10.1 6.8 7.8 Marc Gasol 16.2 10.5 5.1 Fichero Jugador.csv Nombre, Puntos, Rebotes, Asistencias Pau Gasol, 17.4, 10.4, 5.5 Ricky Rubio, 10.1, 6.8, 7.8 Marc Gasol, 16.2, 10.5, 5.1
20 Nuestra aplicación puede leer datos separados por comas o por punto y coma y es responsabilidad del usuario configurarla adecuadamente para leer el fichero correctamente.
21 Capítulo 4: Fases del Proyecto En este capítulo vamos a ver explicar qué Proceso de Desarrollo Software hemos usado, además de explicar, con ejemplos, las fases de Captura de Requisitos, Análisis, Diseño, Implementación y Pruebas. Como punto inicial partimos de que nunca hemos desarrollado un producto parecido al que se pide y de que carecíamos de experiencia. Además la tecnología utilizada es nueva para nosotros, lo que aumenta la novedad e imprevisibilidad, con lo que hemos de afrontar y gestionar un desarrollo innovador teniendo en cuenta que tuvimos que: retrasar las especificaciones detalladas, retrasar las estimaciones de tiempo y esfuerzo, usar etapas de realimentación y pensar en una tasa de cambios de requisitos alta. Es por todo ello que decidimos seguir las prácticas de los Métodos de Desarrollo Iterativos e Incrementales (IID). Entre estas prácticas, de las esenciales, decimos usar las siguientes: Desarrollo Iterativo: En IID el ciclo de vida global se componen de varias iteraciones en secuencia. Cada iteración es un „mini proyecto‟ compuesto por actividades de captura de requisitos, análisis de requisitos, diseño, programación y prueba. Cada „mini proyecto‟ da como resultado una versión estable, integrada y probada. Y es la última versión, la de la última iteración, la que da como resultado el producto final. A continuación vemos un gráfico explicativo de esta práctica. Para el desarrollo de nuestra App hemos usado cuatro iteraciones, pasando por las sucesivas etapas de captura de requisitos, análisis, diseño, implementación y Versiones del producto: por eso es INCREMENTAL porque el producto va incrementando en tamaño Implementar algunos requisitos 1 Implementar algunos requisitos 2 Implementar algunos requisitos 3 Implementar últimos requisitos N … Se repiten todo el proceso nuevamente: por eso se llama ITERATIVO
22 pruebas, en cada iteración. Cada iteración se corresponde con una aproximación, más completa, a la solución final. En la primera nos centremos en definir, aún más, el interfaz de usuario general de la aplicación. En la segunda dividimos el proyecto en cuatro módulos e hicimos que funcionasen. Se conserva esta división en subsistemas en el producto final (subsistemas de: lectura de datos, selección, cálculo y modificación de datos). En la tercera iteración se hizo posible la comparación de muestras entre sí y refinamos la versión anterior, además de añadir algunos requisitos complementarios como la posibilidad de compartir los resultados. Y en la cuarto iteración se retocó el producto anterior y se facilitó el uso y la escritura de la url por parte del usuario a través de la inclusión de un navegador personalizado. Desarrollo Incremental y Evolutivo: Esta característica está casi siempre emparejada a la anterior. En cada iteración se hacen muchas cosas (como el refinamiento de requisitos…) y entre ellas está el aumento de la funcionalidad del sistema objeto. Es por ello que se habla de desarrollo incremental, es decir, en cada iteración se va incrementando la funcionalidad del producto. Dirigido por el Cliente: Está característica nos dice que es el cliente quién decide qué requisitos son los que hay que desarrollar en cada iteración. En nuestro caso el papel de Cliente ha sido realizado mi tutor y yo mismo. Requisitos Evolutivos: Al comienzo de cada iteración hemos revisado y refinado los diferentes requisitos. Planificación Adaptativa: La verdadera planificación del proyecto, precisa y detallada, era verdaderamente difícil darla al comienzo. Ha sido cuando teníamos un 20% del trabajo cuando podíamos hacerla. Centrado en la Arquitectura: Debemos de definir, sobre todos en sistema muy complejos, la arquitectura lo antes posible pues nos va a determinar, en términos de planificación todo el proyecto. Si tenemos dudas en la arquitectura a utilizar, la estrategia será abordar los casos de uso más determinante desde este punto de vista para poder decidir la arquitectura adecuada lo antes posible. En nuestro caso decidir esto fue muy fácil, pues era una arquitectura muy conocida y muy usada, además que los requisitos no influenciaron de manera determinante.
23 Nuestro diagrama de despliegue para describir la estructura física del sistema es el siguiente: Y dentro del smarthphone podemos representar su despliegue de la siguiente manera: En nuestro caso, nuestra arquitectura es bien simple: el programa está diseñado para correr en un Smarphone con acceso a internet. Y este Smarphone trabaja bajo el SO Android 4.1 como mínimo, pudiendo trabajar en cualquiera de las versiones posteriores. Cómo vemos en el segundo diagrama el sistema usa dos bibliotecas, una para leer correctamente archivos CSV y otra para representar gráficos en un Smarthphone. El artefacto Open_Data.apk está asociado al paquete android „com.example.modulo_lectura_datos‟ dentro del cual encontraremos los archivos interpretables de android correspondientes a la App creada. El uso de la plataforma Android API 16 hizo posible plantearnos los casos de uso: Compartir Gráfico, Compartir Cálculos y Compartir Fichero. Como vemos aquí Smarphone con Android 4.1 como mínimo.
24 es una clara influencia de la Arquitectura sobre el Modelo de Casos de Uso. Los Casos de Uso también puede influir sobre la Arquitectura, pero no es ese nuestro caso. A continuación detallamos las diferentes fases del proyecto en cada iteración. Captura de requisitos: En esta etapa, e iterativamente en cuatro entrevistas, además de los requisitos señalados en el Anteproyecto, hemos ido captando diferentes requisitos. Algunos imprescindibles que provienen del Anteproyecto y otros los hemos decidido añadirlos, sobre la marcha, para enriquecer el producto final. Es una etapa dirigida sobre todo al cliente, donde usamos el lenguaje natural y diagramas de caso de uso muy fácilmente entendibles por el cliente y el analista. Requisitos Funcionales y No Funcionales: Esta división de requisitos nos facilita el desarrollo del producto final al distinguir, los requisitos funcionales de los que no lo son. Es decir distinguir lo que sistema debe realizar sin tener en cuenta restricciones físicas (requisitos funcionales) y de los tienen sí tienen en cuenta estas restricciones (requisitos no funcionales). Estos últimos puede influenciar a los otros. Los requisitos funcionales, nos va a servir, para interactuar y potenciar la comunicación con el cliente. En nuestro producto, los podemos ver en la siguiente tabla: REQUISITOS FUNCIONALES DESCRIPCIÓN VISUALIZAR GRÁFICOS El usuario podrá visualizar la muestra de datos o las diferentes muestras de datos (en este segundo caso para poder compararlas entre sí) en diferentes gráficos: Gráfico de Líneas, Gráfico de Barras, Gráfico de Barras Horizontal y Gráfico de Tarta. En el gráfico de Líneas y cuando se selecciona una sola muestra se mostrará gráficamente el valor de la media y la mediana. COMPARTIR GRÁFICOS El usuario podrá compartir el estado actual de los gráficos que sean visibles al usuario en ese momento. VISUALIZAR CÁLCULOS El usuario podrá visualizar los cálculos estadísticos por cada campo seleccionado: Media, Moda, Mediana, Varianza, Desviación Típica, Rango, Error Estándar de la Media, Coeficiente de Variación de Pearson. COMPARTIR CÁLCULOS El usuario podrá compartir los datos calculados de las diferentes muestras. Se exceptúan la
25 Covarianza y el Coeficiente de Correlación de Pearson debido a sus características singulares. CALCULAR RELACIÓN LÍNEAL El usuario podrá calcular la Covarianza y Coeficiente de Correlación de Pearson de dos muestras. VISUALIZAR LOS DATOS El usuario podrá visualizar el estado actual de los datos de entrada (fichero csv). Se indicará cuando estos datos han sido filtrado y/o editados. EDITAR LOS DATOS El usuario podrá eliminar, insertar, añadir y editar los registros que conforman el estado actual de los datos de entrada (fichero csv). FILTRAR DATOS El usuario podrá filtrar los registros del estado actual de los datos de entrada con respecto a cualquier campo. Podremos filtrar campos numéricos, de cadenas de caracteres y con formato de fecha. EXPORTAR DATOS El usuario podrá salvar en cualquier momento el estado actual de los datos de entrada. Esto se salvará en un fichero CSV que podrá almacenarse tanto en la memoria interna como en la externa. IMPORTAR DATOS El usuario podrá leer los datos desde Internet. Se facilitará esta lectura con un Navegador personalizado encargado de averiguar la URL del fichero CSV a tratar, que podrá arrancarse desde la aplicación o desde cualquier otro navegador compartiendo el contenido web del mismo. También facilitará la introducción de URL con un Historial de carga. CREAR ARCHIVO El usuario podrá crear un archivo nuevo CSV que posteriormente se podrá editar para rellenar sus campos. ELIMINAR FICHERO El usuario podrá eliminar ficheros almacenados en el dispositivo en la memoria interna o en la memoria externa. COMPARTIR FICHERO El usuario podrá compartir ficheros almacenados en la memoria interna del dispositivo ENTRADA DE DATOS El usuario podrá introducir los datos a través de un fichero CSV colgado en internet, o desde el almacenamiento del dispositivo (desde la memoria interna o desde la memoria externa) o directamente desde teclado. AVISO DE DATOS NO Se advertirá al usuario cuando quiere
32 GARANTÍAS DE ÉXITO: El sistema visualiza los datos de la url en el móvil. ESCENARIO PRINCIPAL DE ÉXITO: 1. El usuario introduce la url del fichero a analizar 2. El sistema muestra los campos del fichero 3. El usuario pide que se le muestre el fichero. 4. El sistema muestra el fichero. EXTENSIONES: 2.a. El sistema advierte que el fichero seleccionado es demasiado grande para ser tratado. El caso de uso termina. Los diagramas de clases de análisis son los siguientes: Para el subcaso de uso „CÁLCULO desde Fichero‟ Y para el subcaso de uso „VISUALIZAR DATOS desde INTERNET‟: Para aclarar las relaciones entre las clases de arriba se realiza los diagramas de secuencia de análisis siguientes para cada subcaso:
33
34 Estos tres tipos de artefactos de análisis sirven para refinar aún más los requisitos captados en la primera fase. Damos un primer paso para la implementación y permite realizar, en el diseño, los casos de uso. En el caso de uso textual empezamos a entender en como interacciona el sistema con el usuario para lograr su objetivo. El diagrama de clases de análisis sirve para dar un primer paso e introducir las clases en su nivel más abstracto. El diagrama de secuencia de análisis de este escenario sirve para identificar la comunicación entre clases genéricas para llevar a cabo la realización de éste. Todavía no hemos despegado desde el punto de vista de la implementación. Estamos en una fase donde estamos más cerca de la abstracción que de su realidad física de la arquitectura. Se podría decir que estamos todavía más cerca del lenguaje natural, propio del cliente, que del lenguaje técnico propio del programador. De manera iterativa e incremental se realizarían todos los casos de uso, aumentando el tamaño del producto desde el punto de vista funcional. Los casos de uso realizados en esta etapa podrían sufrir alteraciones de requisitos o refinamientos. Diseño: Esta etapa es una etapa intermedia entre la abstracción del problema que tiene el cliente y la abstracción del problema que tiene el programador. Está pensada para facilitar el mantenimiento del producto final y es decisiva, en la construcción de un software de calidad. Para la realización de un caso de uso de análisis, usamos dos tipos de artefactos principalmente: El diagrama de clases de diseño del producto y los diagramas de secuencia que se hacen a partir de este diagrama de clases. DIAGRAMA DE CLASES DE DISEÑO: El diagrama de clases de diseño sirve para detectar las relaciones entre las clases que van a aparecer en esta etapa, muchas de estas clases de diseño se corresponden con una clase de análisis. Comencemos definiendo el diagrama de clases de diseño en una composición de Subsistemas relacionados entre sí.
35 En este diagrama podemos ver que el producto se puede descomponer en cuatro subsistemas: Lectura de Datos: este subsistema es el encargado de llevar los datos de entrada a la memoria de una manera correcta. Selección de Campos: es el subsistema encargado de hacer posible que el usuario seleccione los campos del fichero que desea tratar de manera estadística. Cálculo y Gráficos: es el subsistema encargado de explotar los resultados de los campos seleccionados en el anterior subsistema. Manipular Datos: este subsistema es el encargado de manipular los datos del fichero existentes en la memoria asignada a la App. Cada una de estos subsistemas contiene una vista parcial del diagrama de clases de diseño total. Un aspecto destacable de su diseño general, es el uso masivo de interfaces de las actividades. Este permite definir de antemano la funcionalidad deseada de cada actividad y es una buena técnica para una posible división del trabaja entre distintos programadores. Facilita mucho las potenciales modificaciones de funcionalidades de la aplicación y la organización del trabajo a realizar. También es importante la división de trabajo que permite las diferentes clases gestoras, haciendo posible la posible división de trabajo entre el diseñador de interfaz de usuario y el trabajo puro de programación que supone la gestión de la funcionalidad. Otro aspecto, fruto de un buen diseño, es prácticamente la ausencia, salvo los imprescindibles, de atributos de clases que pueden ser accedidos directamente. En su lugar son privados pero gestionados por „getters „y „setters‟.
36 Subsistema Lectura De Datos: Veamos primero el subsistema: „Lectura de Datos‟ pensado pare leer correctamente los ficheros CSV introducidos por el usuario o los datos directamente introducidos por el teclado. El siguiente diagrama nos muestra su estructura en clases:
37
38 Las actividades son las clases coloreadas de color azul claro. Cada actividad tiene asociado un interfaz que implementa (color blanco) y varias, una o ninguna clase gestora (color gris) que lleva el peso de la implementación y que suele corresponderse con las clases controladoras de la etapa de análisis. El que tenga una, varias o ninguna clases gestoras asociadas depende de la complejidad de esta gestión. Las actividades se relacionan entre sí mediante relaciones de asociación (color cian) que representan que unas abren a través de un evento. Las otras clases son clases „puras‟ (color verde) necesarias para el buen diseño. Algunas de las cuáles se corresponden con las clases entidad de la fase de análisis Vemos que la actividad „MainActivity’ es la encarga de cargar los datos. Tiene asociadas tres clases gestoras. Cada una encarga de llevar a cabo el correspondiente tipo de entrada que puede hacer el usuario y que están definidos en el interfaz „iEntradaDatos’. Estás son „leerFichero()‟, „leerUrl()‟ y „leerTeclado()‟. Estos métodos llevan los datos del fichero a la clase „Fichero’ encargada de almacenarlo en memoria y de soportar las operaciones que hacen las demás clases sobre estos datos. Señalar que el diseño de la funcionalidad de leer por teclado sigue un camino diferente que el diseño para leer desde internet o desde el almacenamiento del dispositivo móvil. La clase „MiFuncion’ es una clase que ofrece un tipo de funcionalidad común a todas las de los diferentes subsistemas y clases. Subsistema Seleccionar Campos: El subsistema Seleccionar Campos se encarga de hacer posible que el usuario seleccione qué campos del fichero desea analizar. El diagrama de clases de subsistema Seleccionar Campos es el siguiente:
39
40 En este subsistema existe una actividad principal, llamada „Campos’ que implemente el interfaz „iCampos’ que define la funcionalidad esencial de la actividad. A esta actividad le corresponde la clase gestora „gCampos’. Esta actividad es la encargada de seleccionar los campos numéricos que el usuario le indica. Para ello lee los datos de la clase „Fichero’ encargada de almacenar en memoria el fichero csv y los almacena en la clase „BancoDatosSeleccionados’ que va a ser utilizada por el Subsistema „Cálculo y Gráficos‟. Comentar que por temas tecnológicos, „Fichero’ y „BancoDatosSeleccionados’ son como grandes variables globales (tienen atributos estáticos para almacenar esta información). Es necesaria una forma de asegurarnos que no pueda haber dos instancias de la aplicación funcionando paralelamente, debido, al uso de atributos estáticos (variables globales). Este hecho es controlado por el atributo „libre’ de la clase „MiFuncion’. Cuando una Instancia de la aplicación trata de colarse a otra, esta variable sirve como barrera para que no pueda hacerlo. Otros atributos importantes, son los de la clase „Fichero‟ que indican cuando un fichero ha sido modificado, filtrado o editado. Se usará para advertirnos que se quiere salir de la aplicación y no se han guardado los datos modificados, cuando lo han sido. En este caso se lanzará la actividad „AdvertenciaEditado’. Cuando todo vaya bien, la actividad „Campos‟ hará paso a la actividad „ResultadoEstadistico‟ definido en el subsistema „Cálculo y Gráficos‟ que es el encargado de explotar los resultados obtenidos de cara al usuario. Subsistema Cálculo y Gráficos: El subsistema „Cálculo y Gráficos‟ es el encargado visualizar los datos estadísticos y los gráficos y explotar estos datos-resultados. Su subdiagrama de clases es el siguiente:
41
48 También convenientemente abstraída y con todas las ventajas que esto supone. En el diagrama de clases de arriba no aparecen los atributos y los métodos privados, pues no se sirven directamente al resto del mundo. Sí podemos contar que la clase „DatosGrafico’, que es equivalente a un registro que contiene un atributo tipo „String’ para almacenar un Identificador de Campo, otro atributo tipo „array’ de decimales, que contiene la muestra correspondiente y otro atributo de tipo „Color’, para almacenar el color con que se dibujará esta muestra en los diferentes gráficos, salvo el de Tarta que tiene un tratamiento diferente. La clase „ListaDatosGrafico’ encapsula una lista de objetos „DatosGrafico’ especificado anteriormente, y la clase „BancoDatosSeleccionados’ usa „ListaDatosGrafico’ para una mayor abstracción de clases. Punteros de Función: Otro aspecto destacable, desde el punto de vista de la programación, es el uso de punteros de función cuando se gestiona cualquier filtro, ya sea numérico, de cadenas o de fechas. Podemos crear punteros funciones definiendo en un interfaz la función y rescatándola en la creación de diferentes clases anónimas. Esto nos permite ahorrarnos una gran cantidad de código redundante, de difícil localización de errores y modificaciones futuras. El siguiente diagrama muestra estos punteros a funciones:
49 Vemos diagrama muestra estos uso de punteros de función: para decimales es „iMiFuncion_Numero‟ y su método „comparar(float a, float b, float c, float d)‟; para String „iMiFuncion_Cadena‟ y su método „comparar (String a, String b, String c, String d)‟ y para Fechas „iMiFuncion_Fecha‟ y su método abstracto „comparar (Date a, Date b, Date c, Date d)‟, todas ellas devuelve un valor booleano que va a ser determinante a la hora de filtrar datos. public interface iMiFuncion_Numero { public boolean comparar(float a, float b,float c, float d); } public interface iMiFuncion_Cadena { public boolean comparar(String a, String b,String c, String d); } public interface iMiFuncion_Fecha { public boolean comparar(Date a, Date b,Date c, Date d); } Veamos a continuación como usa estos interfaces las clases anónima:
50 Se define el constructor del interfaz y dentro de éste la implementación de su método abstracto. Con lo que creamos una clase anónima que implementa solo este interfaz. Esto se le pasa como parámetro a un método que espera esta clase anónima y la usa. Vemos en el ejemplo de abajo la función filtrar al que se le pasa un parámetro del tipo „iMiFuncion_Numero’. Más abajo en el cuerpo del método filtrar nos encontramos el uso del método comparar de esta clase anónima. Con lo que solo se codifica una vez este método filtrar. Sin punteros a función se debería codificar un método filtrar por cada variación de la función que se le aplica para filtrar. Esto nos supuso ahorrarnos en gran cantidad de código redundante. Pasa de parámetros de una clase anónima creada a partir de del interfaz iMiFuncion_Numero. Argumento del tipo iMiFuncion_Numero Uso del método comparar(..)
51 Uso de clases Abstractas: Otro aspecto importante desde el punto de vista del diseño y su posterior codificación es el uso de la clase abstracta „aGrafico’ que define de manera común las operaciones que se pueden hacer con los diferentes gráficos y deja el método abstracto para rellenar el gráfico de muestras para que lo implemente cada gráfico de manera particular. El siguiente diagrama muestra esta circunstancia: Vemos en este diagrama que los cuatro gráficos heredan de la clase abstracta „aGrafico’. Estos gráficos son gestionados por „gGrafico’ que resuelve la funcionalidad planteada por la actividad „ResultadoEstadistico’ encargada de representar el interfaz de usuario principal donde se muestran los resultados gráficos entre otros cálculos. Señalar que el gráfico de tarta funciona de manera diferente y define su propio método „rellenarGrafico()‟, diferente al método abstracto. Señalamos aquí el métodos ´‟guardarAGaleria()‟ y „compartir()‟ de la clase „gGrafico()‟, estos método están impuestos por la funcionalidad de la librería MPAndroidChart, esta librería sacrifica la posibilidad de seleccionar aisladamente un gráfico a favor de ser interactivo. Los métodos „guardarAGaleria()‟ y „compartir()‟ trabajan sobre los gráficos mostrados actualmente al usuario; el usuario es el responsable de tener en cada momento visibles los gráficos que quiere compartir o mandar a la galería del móvil.
52 Clase abstracta y su método abstracto de aGrafico Herencia de la clase abstracta e implementación de su método abstracto por parte de la clase GraficoLineas.
53 Implementación de Varios Interfaces: Otro aspecto de la programación es la posibilidad de que una clase puede implementar más de un interfaz. Esto es lo que le ocurre a la actividad „ResultadoEstadistico’. A continuación vemos las secciones más significativas de su diagrama de clases y de su codificación: Implementación de los interfaces iCalculoEstadistico e iGrafico
54 Conversión interna en formato decimal android: Esto consiste en convertir todo lo leído por la aplicación a formato decimal android (o java). Así si editamos o leemos un fichero que tiene los números decimales con coma, éste es automáticamente convertido al formato interno de android, que es de número decimales convertido por punto. Esta conversión es necesaria y ocurre constantemente en el programa como al pasar los datos del fichero a memoria, al editar un registro, etc. La raíz de esta funcionalidad es el método „vigilanteComasNuméricas()‟ de la clase „MiFuncion’. Rotaciones de la Pantalla: Cuando rotamos la pantalla del dispositivo o consultamos un menú entre otras acciones, la actividad se reinicializa. Tuvimos que retocar algunas actividades para que funcionaran correctamente. En muchos casos tuvimos que sobrescribir los métodos „onSaveInstanceState()‟ y „onRestoresInstanceState()‟ para guardar y recuperar el estado anterior de la actividad para esta clase de eventos. En algún caso tuvimos que retocar el método „onCreate()‟. El uso de argumentos en estos métodos lo permite. Utilizando un objeto „Bundle’ para guardar o recuperar estos datos. Pruebas: La fase final de cada iteración y la última que da pié al producto final es la fase de Pruebas. Ha pasado muchas veces que había fallos en la codificación y se resolvieron adecuadamente. Lo que vamos a citar aquí son los aspectos y situaciones más importantes que nos hemos encontrado en esta fase.
55 Memoria Rebasada Se observa que el software funciona bien para cuando tiene que descargar ficheros .csv relativamente pequeños o mejor dicho no muy grandes. Estos ficheros son pasados a memoria a una estructura de Vector de Vectores de „String‟. Estos objetos son almacenados en la parte de memoria „Heap‟ (Montículo) y este „Heap‟ tiene un tamaño máximo fijado en tiempo de compilación, si sobrepasa este tamaño la aplicación falla y deja de funcionar. He probado descargando ficheros del Ayuntamiento de Málaga como el dedicado a la Lecturas de cuadros electrónicos de Mayo 2016 con un peso de 13,8 MB y al intentar pasar estos datos a memoria, quedan rebasados la capacidad de memoria del montículo y el programa no sigue, lanza una error llamada „outofMemoryError‟. También nos falla en los ficheros de líneas y horarios de bus Horarios que ocupan 16,5 MB. Para intentar paliar este defecto podemos definir que tenga una cabecera más grande de lo normal dentro de los atributos XML de la aplicación: „android:largeHeap=”true”’. El error „outOfMemoryError‟ hace que el programa se detenga y es debido a que la máquina virtual Dalvik llena completamente la parte de memoria Heap (Montículo) que le asigna a la aplicación. No hay una buena o mala solución para esta error, debido a que no se garantiza que el estado de la máquina virtual vuelta a un estado estable. Algunos programadores la capturan pero depende mucho de lo que se quiera hacer pues como he dicho no se garantiza que podemos llevar al programa a un buen estado tras capturar este error. En mi aplicación ocurre este error por dos causas, principalmente: Una cuando se trata de abrir un fichero relativamente Atributo xml para permitir un Heap más grande.
56 grande (por ejemplo uno de 10MB), y otro cuando se llama al visor de fichero csv y el fichero correspondiente tiene una gran cantidad de registros para visualizar, esto hace que se gaste muchos recursos en visualizarlos todos a la vez en una tabla. Para solucionar o paliar la primera causa del error decidimos que el usuario pudiese especificar el máximo tamaño del fichero que se desea cargar. Si es un tamaño relativamente pequeño no tendrá problema y la aplicación podrá mostrarlo. Es el usuario el responsable de administrar este tamaño y ajustarlo a las demanda de memoria de su dispositivo móvil. Para ver cómo se hace se puede ir al Manual de Usuario incluido en esta memoria como anexo. La segunda causa de error lo intentamos solucionar de la misma manera que el primero, es decir, dejando al usuario que pueda especificar el máximo de registros del fichero que se puede visualizar de una vez. Con ello no renunciamos que queramos ver el fichero entero sino que aceptamos que esto puede dar problemas y decidimos visualizarlo por tramos. Esto también viene explicado en el manual de usuario. Tabla de caracteres usada en la aplicación: Para leer los ficheros se utiliza el código UTF-8 que es el más internacional que existe y cubre por ejemplo las tildes y la „ñ‟. Hay algunos ficheros que usan un formato distinto y hace que, por ejemplo, las tildes se lean mal. Esto, sin embargo, no es un gran problema pues los programas más populares como Excel pueden tener el mismo problema. Menú Contextuales a los Gráficos: Pensemos en ponerles menús contextuales a los gráficos pero no encontremos nada, ningún ejemplo que fuese la prueba de que se puede hacer. Al contrario nos informemos por internet y este es un tema que no se aborda en la actual versión de la biblioteca MPAndroidChart. Parece ser que no te deja pues el gráfico puede ser zoombeado con los dedos y hacer que capturase un evento de pulsación larga entorpecería estas acciones que podemos hacer con estos gráficos interactivos. Quizás en futuras versiones se pueda hacer pero actualmente todo indica a que no se puede hacer. Gráficos: leyendas. La biblioteca MPAndroidChart permite un número ilimitados de leyendas que se corresponde con cada campo numérico seleccionado. Por defecto, las recortar si son muchas, aunque dejas la opción de indicarle a la biblioteca que no las recorte, sino que crezca con una nueva línea cuando sea necesario, pero esta última opción tiene un gran inconveniente y es que al crear una nueva línea, disminuye en la
57 misma cantidad de líneas el recuadro que visualiza el gráfico en sí (las líneas o las barras). Mi opción fue dejarlo por defecto y asumir que no comparemos demasiadas muestras a la vez. Distintos Tamaños de Pantalla: Eclipse nos proporciona una vista donde podemos ver la mayoría de los tamaños de pantalla existente en el mercado, incluso para las tabletas. La aplicación desarrollada ha sido probada, en el simulador, en diversos tamaños de pantalla. Las distintas vistas de la aplicación son elementales y no han dado casi ningún problema en visualizarlas en distintos tamaños de pantalla. Tuvimos que retocar la actividad inicial donde ser cargan los datos, pues en la pantallas de 2.5‟ no se veían bien y en la opción edición de datos cargados tuvimos que poner el espacio que ocupan los distintos „layouts’ en porcentaje de ocupación en pantalla. Distintas Resoluciones de Pantalla: Al no tener, prácticamente ninguna imagen, no tuve que realizar ningún cambio para que se adaptase a las distintas resoluciones de pantalla más comunes que nos podemos encontrar.
64 Compartir Página desde cualquier Navegador del Mercado: Esta es la opción ideal y consiste en navegar normalmente en cualquier navegador comercial y cuando estemos en una página web cercana al enlace de descarga CSV deseado, compartamos esta web a nuestra aplicación Open Data que responderá arrancando su Navegador personalizado. En el que podemos continuar nuestra exploración de la web y cuando pulsemos sobre un enlace de descarga CSV, arranque la aplicación Open Data, proponiendo en la línea de texto la URL, este enlace CSV. En la imagen anterior aparece indicado como aparece la aplicación Open Data al compartir la página web en el navegador comercial Chrome. Solo tenemos que seleccionar esta opción y se nos mostrará el Navegador Personalizado de la aplicación Open Data. El fichero será analizado y tratado adecuadamente. La opción URL se realiza en „Background‟ pero el interfaz de usuario no tiene más remedio que esperar a que termine pues eso datos son fundamentales para la secuencia del programa. La opción tiene efecto al pulsar el botón Hecho.
65 Descargar el Fichero: Esta es la forma más simple de cargar un fichero CSV de internet. Se trata de descargar, como se hace normalmente, el fichero CSV con cualquier navegador del mercado. La aplicación está hecha para que este fichero pueda ser leído desde la opción „FICHERO‟ cuando está configurado para leer la memoria externa. FICHERO: La siguiente opción interesante es la de fichero, pensada para poder trabajar offline. Se trata de mostrar una lista desplegable con todos los ficheros CSV guardados por la aplicación. Si seleccionamos uno y pulsamos el botón Hecho cargaremos el correspondiente fichero en la aplicación, con lo que se realizará un análisis muy similar a la anterior opción de URL pero en este caso no accede a la red de internet. Al igual que el anterior caso el IU no le queda más remedio que esperar a que termine el análisis. Podemos cargar los ficheros desde el almacenamiento interno que asigna Android a la nuestra aplicación o bien optar por cargar los ficheros situados en donde Android descarga por defecto cualquier fichero, que llamaremos almacenamiento externo. TECLADO: Consiste en que el usuario introduzca directamente los datos sobre esta línea de texto. Estos datos pueden separarse por coma o punto y coma, según lo configure el usuario. Esta opción no pasa por el mismo camino que las anteriores, aunque también se analiza de forma similar. Se pedirá un identificador relacionado a estos datos introducidos para darles un significado a los mismos. 3. GESTIÓN DE ARCHIVOS En la pantalla de carga podemos hacer una pequeña y simplificada gestión de archivos. Así podemos eliminar uno previamente almacenado en memoria interna o externa o crear uno nuevo. A continuación veremos estas opciones: 3.1. Creación de un Archivo Nuevo: Para crear un archivo nuevo debemos de darle un nombre y crear al menos un identificador de campo, aunque podremos crear cuantos queramos. Este paso es muy importante ya que va a definir toda la estructura del fichero CSV y debemos de ser muy exactos a la hora de crear estos identificadores de campo pues no podremos modificarlos posteriormente. A continuación vemos un ejemplo ilustrativo:
66 En la imagen anterior vemos una captura de pantalla de esta opción. En primer lugar aparece el nombre que queremos darle al fichero, en este caso concreto se llamará „Alumnos‟ y no hará falta introducirle la extensión „.csv‟, pues se hace automáticamente. En la parte inferior aparece unas etiquetas que van modificándose conforme vamos añadiendo más campos al fichero „Alumnos‟, en este caso se han creado los campos „Nombre‟, „Edad‟ y „Curso‟ y está a punto de crearse el campo „Email‟, para ello debemos pulsar el botón „Añadir Campos‟ y se añadirá automáticamente a la lista anterior. El botón Aceptar confirma todos los cambios y el Cancelar retrocede y finaliza esta pantalla. El fichero nuevo se guardará en memoria interna o externa según la configuración general. Una vez creada el archivo CSV con la estructura básica de los campos, podemos añadirles los registros que queramos, editando éste. Para editarlos primero creamos el fichero solo con los campos y luego lo cargamos en la aplicación para editarlos posteriormente (La opción Edición se explica en su correspondiente apartado). 3.2. Eliminar Archivos: Para eliminar un archivo solo debemos de seleccionarlo de una lista desplegable y pulsar el correspondiente botón. Se podrán eliminar tanto los archivos almacenados en memoria interna como los almacenados en memoria externa según lo tengo configurado el usuario en ese momento. A continuación vemos una captura de pantalla de esta opción:
67 4. CONFIGURACIÓN GENERAL: En esta sección describimos una serie de parámetros que sirven para configurar la aplicación. Se carga desde la actividad que pide la entrada para carga de datos, seleccionando del menú la opción „Configuración‟. Distinguimos cuatro secciones: Separador de datos: Es una opción fundamental para poder cargar datos de manera correcta. Existen dos alternativas, valores separado por coma o valores separados por punto y coma. Por defecto el valor es por coma. Estas opciones reflejan la definición de CSV que hemos explicado en esta memoria. Antes de cargar los datos deberíamos saber de antemano cómo están separados entre ellos. En la imagen siguiente vemos su cuadro de diálogo: Acceso a Memoria: Nos permite definir de dónde se leerán los archivos almacenados en el dispositivo, desde memoria interna o desde memoria externa. Los archivos almacenados en la memoria interna son los que crean la aplicación ella misma, sólo son accesibles por la misma aplicación y se eliminan al desinstalarla. Los archivos almacenados en memoria externa, también los crea la aplicación, pero en este caso pueden ser accedidos por cualquier otra aplicación y no se eliminan cuando se desístale. La zona
68 donde se ha definido esta memoria externa corresponde a la carpeta que Android usa por defecto para descargar cualquier archivo, con lo que se podría descargar un fichero CSV por otra aplicación y ser visible esta descarga por Open Data a través de su memoria externa. Según hayamos definidos el uso de una u otra tipo de memoria, cuando leamos, creamos o eliminemos cualquier archivo, se realizará en la memoria en uso que hayamos definido en este opción. ´ Ventana de visualización: Esta opción se usa para indicar al visor de archivos cuantos registros nos muestra de una vez como máximo. Por efecto es 25 aunque puede ser cualquier número entero positivo. Si introducimos el valor 0 la aplicación intentará visualizar todos los registros del archivo a la vez. Tamaño de Fichero: Indica el máximo Tamaño del fichero, en bytes, que la aplicación está dispuesta a soportar. Su razón de existir es evitar en la medida de lo posible que la aplicación se comporte de manera ineficiente o se pare debido al gran tamaño de fichero de carga. Un cero como valor (que es su valor por defecto), indica que se intentará cargar cualquier fichero
69 independientemente de su tamaño. Si no se puede averiguar el tamaño del fichero (como ocurre en algunas URLS) se intentará cargar sin pasar por esta barrera. En el caso que no se admita el fichero, nos saldrá un mensaje indicando esta situación. 5. SELECCIÓN DE CAMPOS A MUESTREAR: Una vez seleccionado el Archivo a analizar ya sea desde la memoria del dispositivo o desde internet, pulsamos el botón „Hecho‟ y pasamos a una nueva actividad encargada de recoger los campos seleccionados por el usuario que quiere analizar. Estos campos se corresponden exactamente con las cabeceras del archivo CSV. En la imagen siguiente vemos un ejemplo: En este ejemplo se muestra siete campos de los cuales seleccionamos dos (Apple iOS y Windows) marcados en rojo. Como vemos podemos seleccionar más de un campo al mismo tiempo con objeto de poder comparar sus muestras asociadas. Si un campo no es numérico no es muestreable y no se puede seleccionar (se indicaría con el oportuno mensaje de advertencia). Una vez que
70 decidamos los campos a muestrear pulsamos el botón „Listo‟ para ver los resultados de lo seleccionado. En este pantalla también se puede visualizar el contenido actual del fichero, editarlo, filtrarlo y guardarlo en memoria. Es decir podemos manipular los datos cargados en memoria principal antes de ser tratados estadísticamente. Si el fichero asociado no tienes campos muestreables, el fichero no puede ser tratado por nuestra aplicación, sí podríamos manipular sus datos pero no podemos calcular ningún resultado. Cabe mencionar que esta opción no es aplicable cuando los datos son introducidos directamente por teclado. 6. VISOR DE DATOS: Esta opción está disponible cuando estamos en la pantalla para seleccionar el/los campo/s a muestrear. Aparece en el menú como una acción directa con el icono de un ojo: Nos aparece un IU como en la siguiente imagen:
71 Aparece una tabla con los primeros registros del archivo. Podemos desplazarnos tanto horizontalmente como verticalmente en esta pantalla. En la parte superior se encuentra los controles. Se visualiza el número de registros al mismo tiempo que hemos definido en la configuración (en este ejemplo se visualizar 9 registros, que son todos los del archivo). En la parte superior se indica el número total de registros del archivo, tres botones y dos líneas de texto que sirven para navegar por el archivo. Podemos ir a saltos, a través de los botones „Ant‟ y „Sig‟ o directamente colocando el rango de registros que deseamos ver en las líneas de texto y pulsando el botón „Actualizar‟. En este último caso la lista se recalcula teniendo en cuenta el máximo de registros a visualizar en cada momento y el rango colocado en la líneas de texto numérico. Si el rango es igual o menor a éste máximo, entonces el rango se muestra correctamente pero si es mayor, entonces se recorta a esté máximo definido en la configuración de la aplicación. 7. EDICIÓN DE DATOS: Ahora lo que vamos a explicar es la forma que tiene la aplicación de editar los datos que nos hemos traído desde el fichero ya sea descargado de internet o previamente guardado en el almacenamiento del dispositivo. En la parte superior se señala el icono asociado a esta actividad y a continuación mostramos el Interfaz de Usuario encargado de esta funcionalidad:
72 En la parte izquierda de la pantalla se visualizan uno a uno los registros actualmente en memoria. En la parte derecha de la pantalla muestra las opciones de visualización y edición que podemos realizar actualmente con el registro mostrado en la parte izquierda. El campo “Número de Registro” no es un campo real, es un campo calculado que nos facilita la navegación a través de los registros. Para visualizar los diferentes registros tenemos las opciones de: Ir a: Nos lleva al registro correspondiente al número insertado en este campo. Si introducimos un número fuera del rango nos advierte del error. Siguiente: Nos lleva al siguiente registro del registro visualizado actualmente. Anterior Nos lleva al anterior registro del registro visualizado actualmente. Primero Nos lleva al primer registro. Último Nos lleva al último registro. *Estás opciones de: Primero, Último, Siguiente y Anterior se habilitan y deshabilitan adecuadamente.
73 Para Editar los Registros tenemos las siguientes opciones: Añadir Añade un nuevo registro al final de la lista. Al pulsar esta opción nos muestra todos los campos vacíos y el número de Registro con el número siguiente al último. Debemos de pulsar el botón Guardar para confirmar el cambio o Cancelar en caso de no confirmarlo. Insertar Inserta un nuevo registro en la posición actual del campo “Número de Registros”. Al igual que la opción anterior se debe pulsar el botón Guardar para confirmar los cambios o Cancelar en caso contrario. Eliminar El botón eliminar elimina directamente el dato visualizado actualmente. En esta primera versión no te pide confirmación sino los elimina directamente. Ha de tratarse este botón con cuidado. Editar El botón editar permite editar el registro visualizado actualmente. Al igual que el botón Insertar y Añadir debemos usar el botón Guardar para confirmar el cambio si los descartamos usaremos el botón Cancelar. Guardar El botón Guardar guarda los cambios actuales en memoria RAM. Para guardarlos en memoria secundaria interna del dispositivo debemos usar la opción „Guardar Archivo‟ que explicaremos más adelante. Cancelar El botón Cancelar descarta los cambios efectuados sobre el registro actual o descarta Añadir un nuevo registro a la lista. 8. FILTROS: Esta opción está disponible inmediatamente después de la carga de datos y cuando el usuario puede seleccionar los campos numéricos para su análisis. Se activa pulsando el icono de lupa al lado del icono de edición.
80 Y el resultado correspondiente se muestra en la siguiente pantalla: Recuerda que el campo Num no es un Campo Real sino que está ahí para facilitarnos la lectura de los diferentes registros. Lo formatos de fechas aceptados por las líneas de texto de este filtro están en el anexo correspondiente de esta memoria. Las diferentes opciones son: Es igual a: Ocurre cuando las fechas son iguales. No es igual a: Ocurre cuando las fechas no son iguales. Es Posterior a: Ocurre con los datos de los registros que sean posteriores a la fecha introducida por el usuario. Es Posterior o Igual a: Lo mismo que el anterior pero además incluye el caso que sean iguales.
81 Es Anterior a: Ocurre con los datos de los registros que sean anteriores a la fecha introducida por el usuario. Es Anterior o Igual a: Lo mismo que el anterior pero además incluye el caso que sean iguales. 9. SALVAR A MEMORIA SECUNDARIA: Esta opción permite Salvar en memoria interna o en memoria externa el estado actual de registros del fichero cargado previamente ya sea por internet o desde el interior del dispositivo. Debemos de seleccionar el icono en forma de diskette que aparece junto al icono de Filtros. El interfaz de usuario que aparece se muestra en la siguiente imagen: Introducimos el nombre de fichero que queremos darle (la extensión CSV es opcional) en la línea de texto de cuadro de diálogo. Debemos seleccionar la opción de Almacenamiento Interno o Almacenamiento Externo, introducir un nombre de Fichero y pulsar el botón Guardar. Si queremos volver a la pantalla anterior sin guardar el estado actual de registros pulsaremos Cancelar. Si hemos seleccionado Al. Interno (Almacenamiento Interno) el fichero se almacenará en el espacio que Android asigna a esta aplicación. Este espacio tiene como característica que sólo lo puede acceder la aplicación Open Data y en caso de que se desístale, estos ficheros son eliminados. Sin embargo si seleccionamos Al. Externo (Almacenamiento Externo) ocurre: que estos ficheros se puede acceder por cualquier aplicación y no se borrar cuando
82 ésta de desístale. El programa almacenará en la carpeta por defecto Android para las descargar (carpeta download). Cuando queramos salir de la aplicación sin guardar los datos y siendo estos manipulados, el sistema nos mostrará un mensaje de advertencia indiciando este hecho con objeto de prevenir posibles olvidos de usar esta opción. 10. RESULTADOS: Una vez tratados los datos de entradas, seleccionados los campos que queremos analizar y pulsando el botón „Listo‟ aparecerá la pantalla „Resultados‟ mostrándonos los cálculos estadísticos automáticos por cada campo y el/los gráfico/s correspondiente/s, además de otras opciones. Lo primero que nos aparecen son los cálculos de las diferentes fórmulas estadísticas aplicadas por cada campo: así aparecerán la Media, Moda, Mediana, Rango, Varianza, Desviación Típica, Error Estándar de la Media y Coeficiente de Variación de Pearson. Podemos desplazarnos verticalmente por la pantalla sin problemas. En la otra pestaña de la actividad „Resultados‟ aparece la de Gráficos que nos muestra los gráficos asociados a estos campos y si se ha seleccionado más de un campo previamente aparecen las gráficas comparativas como es el caso de la imagen siguiente:
83 Se mostrarán tres gráficos posibles: de líneas, de barras y de barras horizontal. Todos ellos interactivos y podemos hacerles zoom pero siempre en el mismo tamaño del marco. También podemos controlar qué gráficos se muestran y cuáles no. Adicionalmente se muestra un gráfico de tarta donde se calcula el tanto por ciento de ocurrencias de los distintos valores de una determinada columna de la entrada CSV. En la imagen de abajo está calculado el porcentaje de muestra de cada ocurrencia distinta en el campo „Año‟. Podemos cambiar dinámicamente campo asociado a este gráfico seleccionando otro distinto en lista desplegable colocada en la parte superior de este gráfico y pulsando el botón „Actualizar‟. Podemos girar este gráfico o pulsar en alguna parte de él para que nos muestre que tanto por ciento corresponde al valor sobre el que pulsamos.
84 En esta pantalla existe un botón llamado „Relación Lineal‟ en la barra de acciones. Se trata de calcular la Covarianza y del Coeficiente de Correlación de Pearson de dos muestras, previamente seleccionadas por el usuario. Al pulsarlo sale un cuadro de diálogo que permite seleccionar las mencionadas muestras y realizar los dos cálculos correspondientes. Estas muestras son siempre muestreables, es decir numéricas. El resultado se indica en la misma pantalla. Existe el botón compartir que lo que hace es compartir cada una de las fotos actual de los gráficos que estén activos en ese momento. Se trata de una opción del menú que por su relevancia se decido colocar como botón de acceso directo. El menú de esta pantalla tiene las siguientes opciones: Compartir Números: Como su propio nombre indica comparte los datos estadísticos calculados para cada campo y que están en la primera pestaña. Compartir Archivo: Permite transferir cualquier archivo almacenado en memoria interna a otra aplicación del móvil o a otro dispositivo. A Galería: Manda las fotos de los estados actuales de los gráficos a la galería.
85 Configuración: Controla qué gráficos se muestran en cada momento. Es importante pues cuando compartamos sus „fotos‟ se compartirán solos los que estén activos en esta opción. Acerca de: Esta opción muestra información sobre la aplicación: la versión y sus creadores.
86 ANEXO B: Formatos de Fecha aceptados por la aplicación Los siguientes formatos de fechas son los aceptados por la aplicación y eso significa que son los que son aceptados en los ficheros csv, como en la entrada de usuario del filtro correspondiente a un campo de formato fecha. Cada letra indica un número y la letra „d‟ indica que va a ser tratado como una número de la cifra día, „M‟ un número de la cifra mes, „y‟ un número de la cifra año, „H‟ un número de la cifra hora, „m‟ un número de la cifra minuto y „s‟ un número de la cifra segundo. Fechas separadas por barra invertida: Fechas separadas por guión: "dd/MM/yyyy HH:mm:ss” "dd/MM/yyyy HH:mm" "dd/MM/yyyy HH" "dd/MM/yyyy" "dd-MM-yyyy HH:mm:ss" "dd-MM-yyyy HH:mm" "dd-MM-yyyy HH" "dd-MM-yyyy" "dd/yyyy/MM HH:mm:ss" "dd/yyyy/MM HH:mm" "dd/yyyy/MM HH" "dd/yyyy/MM" "dd-yyyy-MM HH:mm:ss" "dd-yyyy-MM HH:mm" "dd-yyyy-MM HH" "dd-yyyy-MM" "MM/dd/yyyy HH:mm:ss" "MM/dd/yyyy HH:mm" "MM/dd/yyyy HH" "MM/dd/yyyy" "MM-dd-yyyy HH:mm:ss" "MM-dd-yyyy HH:mm" "MM-dd-yyyy HH" "MM-dd-yyyy" "yyyy/dd/MM HH:mm:ss" "yyyy/dd/MM HH:mm" "yyyy/dd/MM HH" "yyyy/dd/MM" "yyyy-dd-MM HH:mm:ss" "yyyy-dd-MM HH:mm" "yyyy-dd-MM HH" "yyyy-dd-MM" "MM/yyyy/dd HH:mm:ss" "MM/yyyy/dd HH:mm" "MM/yyyy/dd HH" "MM/yyyy/dd" "MM-yyyy-dd HH:mm:ss" "MM-yyyy-dd HH:mm" "MM-yyyy-dd HH" "MM-yyyy-dd" "yyyy/MM/dd HH:mm:ss" "yyyy/MM/dd HH:mm" "yyyy/MM/dd HH" "yyyy/MM/dd" "yyyy-MM-dd HH:mm:ss" "yyyy-MM-dd HH:mm" "yyyy-MM-dd HH" "yyyy-MM-dd" Así por ejemplo: Podríamos introducir la fecha 14/08/2016 cuyo formato asociado sería "dd/MM/yyyy", es decir: catorce se agosto del 2016 o bien introducir la fecha de 09/10/2016 12:30:50 cuyo formato asociado sería "dd-MM-yyyy HH:mm:ss", es decir, nueve de noviembre del 2016 a las doce y media y cincuenta segundos.