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_IOpara 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_Arraypara almacenar el total de ventas por producto. - Búsqueda de Producto: La función
Buscar_Productobusca 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_IOpara 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
