En este estudio de caso, desarrollaremos un sistema de procesamiento de datos en Ada. Este sistema leerá datos de un archivo, procesará la información y generará un informe basado en los datos procesados. Este ejercicio integrará varios conceptos aprendidos en los módulos anteriores, como manejo de archivos, estructuras de control, subprogramas y tipos de datos avanzados.
Objetivos del Estudio de Caso
- Lectura de datos desde un archivo: Aprender a manejar archivos en Ada para leer datos.
- Procesamiento de datos: Utilizar estructuras de control y subprogramas para procesar la información.
- Generación de informes: Escribir los resultados procesados en un archivo de salida.
- Aplicación de mejores prácticas: Implementar un código limpio y eficiente siguiendo las mejores prácticas de programación en Ada.
Paso 1: Definición del Problema
Requisitos
- Leer un archivo de entrada que contiene datos de ventas.
- Procesar los datos para calcular el total de ventas por producto.
- Generar un informe que muestre el total de ventas por producto en un archivo de salida.
Estructura del Archivo de Entrada
El archivo de entrada ventas.txt
tiene el siguiente formato:
Estructura del Archivo de Salida
El archivo de salida informe.txt
debe tener el siguiente formato:
Paso 2: Diseño del Sistema
Estructura del Programa
- Lectura de Datos: Leer los datos del archivo de entrada y almacenarlos en una estructura adecuada.
- Procesamiento de Datos: Calcular el total de ventas por producto.
- Generación del Informe: Escribir los resultados en un archivo de salida.
Diagrama de Flujo
+-------------------+ | Leer archivo | | de entrada | +-------------------+ | v +-------------------+ | Procesar datos | | (calcular totales)| +-------------------+ | v +-------------------+ | Generar informe | | en archivo salida | +-------------------+
Paso 3: Implementación
Lectura de Datos
Código
with Ada.Text_IO; use Ada.Text_IO; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Strings.Unbounded.Text_IO; use Ada.Strings.Unbounded.Text_IO; procedure Leer_Datos is type Producto_Venta is record Producto : Unbounded_String; Cantidad : Integer; end record; type Ventas_Array is array (Natural range <>) of Producto_Venta; Ventas : Ventas_Array(1 .. 100); -- Asumimos un máximo de 100 registros Linea : Unbounded_String; Index : Natural := 1; Archivo : File_Type; begin Open (Archivo, In_File, "ventas.txt"); while not End_Of_File(Archivo) loop Get_Line(Archivo, Linea); declare Producto : Unbounded_String; Cantidad : Integer; Coma_Pos : Natural; begin Coma_Pos := Index(Linea, ','); Producto := To_Unbounded_String(Linea(1 .. Coma_Pos - 1)); Cantidad := Integer'Value(Linea(Coma_Pos + 1 .. Length(Linea))); Ventas(Index) := (Producto, Cantidad); Index := Index + 1; end; end loop; Close(Archivo); end Leer_Datos;
Explicación
- Lectura del archivo: Utilizamos
Ada.Text_IO
para abrir y leer el archivoventas.txt
. - Almacenamiento de datos: Los datos se almacenan en un array de registros
Ventas_Array
. - Procesamiento de cada línea: Cada línea se divide en producto y cantidad utilizando la posición de la coma.
Procesamiento de Datos
Código
procedure Procesar_Datos is type Producto_Total is record Producto : Unbounded_String; Total : Integer := 0; end record; type Totales_Array is array (Natural range <>) of Producto_Total; Totales : Totales_Array(1 .. 100); -- Asumimos un máximo de 100 productos Total_Index : Natural := 1; function Buscar_Producto (Producto : Unbounded_String) return Natural is begin for I in Totales'Range loop if Totales(I).Producto = Producto then return I; end if; end loop; return 0; end Buscar_Producto; begin for I in Ventas'Range loop declare Producto : Unbounded_String := Ventas(I).Producto; Cantidad : Integer := Ventas(I).Cantidad; Pos : Natural; begin Pos := Buscar_Producto(Producto); if Pos = 0 then Totales(Total_Index) := (Producto, Cantidad); Total_Index := Total_Index + 1; else Totales(Pos).Total := Totales(Pos).Total + Cantidad; end if; end; end loop; end Procesar_Datos;
Explicación
- Estructura de Totales: Utilizamos un array de registros
Totales_Array
para almacenar el total de ventas por producto. - Búsqueda de Producto: La función
Buscar_Producto
busca un producto en el array de totales. - Actualización de Totales: Si el producto ya existe, se actualiza su total; de lo contrario, se añade un nuevo registro.
Generación del Informe
Código
procedure Generar_Informe is Archivo : File_Type; begin Create (Archivo, Out_File, "informe.txt"); for I in Totales'Range loop if Totales(I).Producto /= Null_Unbounded_String then Put_Line(Archivo, To_String(Totales(I).Producto) & ": " & Integer'Image(Totales(I).Total)); end if; end loop; Close(Archivo); end Generar_Informe;
Explicación
- Creación del archivo de salida: Utilizamos
Ada.Text_IO
para crear y escribir en el archivoinforme.txt
. - Escritura de datos: Iteramos sobre el array de totales y escribimos cada producto y su total en el archivo.
Paso 4: Ejecución del Programa
Código Completo
with Ada.Text_IO; use Ada.Text_IO; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Strings.Unbounded.Text_IO; use Ada.Strings.Unbounded.Text_IO; procedure Sistema_Procesamiento_Datos is type Producto_Venta is record Producto : Unbounded_String; Cantidad : Integer; end record; type Ventas_Array is array (Natural range <>) of Producto_Venta; Ventas : Ventas_Array(1 .. 100); -- Asumimos un máximo de 100 registros Linea : Unbounded_String; Index : Natural := 1; Archivo : File_Type; procedure Leer_Datos is begin Open (Archivo, In_File, "ventas.txt"); while not End_Of_File(Archivo) loop Get_Line(Archivo, Linea); declare Producto : Unbounded_String; Cantidad : Integer; Coma_Pos : Natural; begin Coma_Pos := Index(Linea, ','); Producto := To_Unbounded_String(Linea(1 .. Coma_Pos - 1)); Cantidad := Integer'Value(Linea(Coma_Pos + 1 .. Length(Linea))); Ventas(Index) := (Producto, Cantidad); Index := Index + 1; end; end loop; Close(Archivo); end Leer_Datos; procedure Procesar_Datos is type Producto_Total is record Producto : Unbounded_String; Total : Integer := 0; end record; type Totales_Array is array (Natural range <>) of Producto_Total; Totales : Totales_Array(1 .. 100); -- Asumimos un máximo de 100 productos Total_Index : Natural := 1; function Buscar_Producto (Producto : Unbounded_String) return Natural is begin for I in Totales'Range loop if Totales(I).Producto = Producto then return I; end if; end loop; return 0; end Buscar_Producto; begin for I in Ventas'Range loop declare Producto : Unbounded_String := Ventas(I).Producto; Cantidad : Integer := Ventas(I).Cantidad; Pos : Natural; begin Pos := Buscar_Producto(Producto); if Pos = 0 then Totales(Total_Index) := (Producto, Cantidad); Total_Index := Total_Index + 1; else Totales(Pos).Total := Totales(Pos).Total + Cantidad; end if; end; end loop; end Procesar_Datos; procedure Generar_Informe is Archivo : File_Type; begin Create (Archivo, Out_File, "informe.txt"); for I in Totales'Range loop if Totales(I).Producto /= Null_Unbounded_String then Put_Line(Archivo, To_String(Totales(I).Producto) & ": " & Integer'Image(Totales(I).Total)); end if; end loop; Close(Archivo); end Generar_Informe; begin Leer_Datos; Procesar_Datos; Generar_Informe; end Sistema_Procesamiento_Datos;
Ejecución
- Compilación: Compila el programa utilizando el compilador de Ada.
gnatmake sistema_procesamiento_datos.adb
- Ejecución: Ejecuta el programa.
./sistema_procesamiento_datos
Conclusión
En este estudio de caso, hemos desarrollado un sistema de procesamiento de datos en Ada que lee datos de un archivo, los procesa y genera un informe. Este ejercicio ha integrado varios conceptos clave de Ada, como el manejo de archivos, estructuras de control, subprogramas y tipos de datos avanzados. Al completar este estudio de caso, deberías tener una comprensión más profunda de cómo aplicar estos conceptos en un proyecto real.
Resumen de Conceptos Aprendidos
- Manejo de Archivos: Lectura y escritura de archivos en Ada.
- Estructuras de Control: Uso de bucles y condicionales para procesar datos.
- Subprogramas: Modularización del código mediante procedimientos y funciones.
- Tipos de Datos Avanzados: Uso de registros y arrays para almacenar y manipular datos.
Preparación para el Siguiente Tema
En el próximo estudio de caso, aplicaremos estos conceptos en un contexto de sistemas embebidos, lo que nos permitirá explorar las capacidades de Ada en entornos de tiempo real y sistemas con recursos limitados.
Curso de Programación en Ada
Módulo 1: Introducción a Ada
Módulo 2: Conceptos Básicos
- Variables y Tipos de Datos
- Operadores y Expresiones
- Estructuras de Control
- Bucles en Ada
- Subprogramas: Procedimientos y Funciones
Módulo 3: Tipos de Datos Avanzados
Módulo 4: Programación Modular
Módulo 5: Concurrencia y Programación en Tiempo Real
Módulo 6: Temas Avanzados
Módulo 7: Mejores Prácticas y Optimización
- Estilo de Código y Mejores Prácticas
- Depuración y Pruebas
- Optimización del Rendimiento
- Consideraciones de Seguridad