Autor Tema: Ejercicio Java IntelliJ leer archivo TXT, guardar crear matriz y analizar ventas  (Leído 2317 veces)

Franmimego

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 3
    • Ver Perfil
Hola, estoy aprendiendo a trabajar en Java, pero me pidieron ayuda para desarrollar un ejercicio de una prueba de programación y no estoy segura de como lograr el código.

Tenemos una matriz con la siguiente estructura de datos que ya se encuentra almacenada en un archivo txt, sin comillas de separación, solo un espacio.

Zona          ID_Producto         Producto          Precio          Unidad
Caracas                1                Manzanas           2.50            2 lb
Maturin                7                Mandarinas         2.65            1 lb
Los Teques           2                Bananas             1.75            2 lb
Maturin                7                Peras                 2.05            1 lb
Maracay               3                Sandia               1.65            3 lb
Guanare               5                Manzanas           1.25            1 lb
Valencia               4                Fresas                6.85            1 lb
San Felipe            6                Uvas                  4.85            3 lb


-------------------------------------------------------------------------------
Asi se lee el TXT cuando lo abro
Guanare   7   Pescado   2   7
Guanare   7   Pescado   2   1
Caracas   1   Arroz   2.5   7
Maracay   2   Frijol   1.25   1
Maturin   6   Carne de Res   3.5   1
Caracas   1   Arroz   2.5   1
Barquisimeto   4   Aceite   2.75   1
Los Teques   3   Azucar   1.5   1
Maturin   6   Carne de Res   3.5   1
Merida   8   Leche   2.75   1
Maracay   2   Frijol   1.25   7
Guanare   7   Pescado   2   1
Guanare   7   Pescado   2   7
Maracay   2   Frijol   1.25   1

Caracas   1   Arroz   2.5   1
Valencia   11   Naranja   0.25   1
Los Teques   3   Azucar   1.5   1
Merida   8   Leche   2.75   1
Barquisimeto   4   Aceite   2.75   7
Guanare   7   Pescado   2   7
Guanare   7   Pescado   2   1
Isla de Margarita   5   Pollo   1.18   
Maturin   6   Carne de Res   3.5   1
Maracay   2   Frijol   1.25   1
Los Teques   3   Azucar   1.5   1
Los Teques   3   Azucar   1.5   1
Maturin   6   Carne de Res   3.5   1
Merida   8   Leche   2.75   1
Maracay   2   Frijol   1.25   7

Las preguntas que debo ayudar a desarrollar son las siguientes:

Crear una matriz que permita almacenar el ID_Producto, precio y unidad vendida.

Una sentencia de iteración que permita leer todos los artículos comprados.

Una sentencia condicional que evalúe las ventas de la region de Maracay, Maturin. Hacer un total para el resto de las zonas, tomando en cuenta ek yuso de variables diferentes para cada resultados.

Una sentencia condicional que evalúa cuántas libras de pollo se compró.

Valide que el valor de la variable (cantidad) sea de número entero.
Si el valor de esta variable es «nulo o cadena», utilizar el número 1 en su lugar

Y existe una segunda matriz, que pienso, es el resultado de la búsqueda para evaluar las ventas... de este archivo no hay encabezado o títulos en el txt.

3011   3   3   16731   Arroz
3012   3   3   29703   Arroz
3013   3   3   39228   Arroz
3014   3   3   14531   Arroz
3016   3   3   10290   Arroz
3017   3   3   2787   Arroz
1011   2   3   9656   Leche
1012   2   3   9810   Leche
1013   2   3   8808   Leche
1014   1   3   1196   Leche
1016   2   3   5410   Leche
1017   2   3   8259   Leche


Me ha costado un poco porque yo no tengo experiencia en Java.. y tratando de ayudar, quede un poco enredada en el código.

Espero me puedan ayudar!!
« Última modificación: 01 de Noviembre 2023, 14:43 por Ogramar »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
A ver, es un ejercicio un poco puñetero.

Para empezar, los datos del txt no están separados por UN espacio, si no por TRES espacios.
Y esto es necesario porque algunos nombres de ciudades se componen de varias palabras separadas a su vez por UN espacio:
Citar
Los Teques   3   Azucar   1.5   1
Entonces si se usara solo UN espacio para separar, habría confusiones para distinguir que es un dato de venta del producto, y que es un nombre compuesto de ciudad.
Así que para evitarlo han usado TRES espacios para separar datos.

En el archivo parece que hay una línea vacía intencionada. Esto habrá que tenerlo en cuenta, pues no todas las líneas que componen el archivo proporcionan datos de venta.

Si usamos como referencia los TRES espacios en blanco para separar datos, las líneas nos van a dar 5 datos: Zona, ID, Producto, Precio y Unidades.

Todas, excepto una, pues no tiene ningún valor para el campo "Unidades"
Esta línea solo da 4 datos:
Citar
Isla de Margarita   5   Pollo   1.18   

Supongo que NO es un error, pues el enunciado nos dice que validemos el campo "Unidad" comprobando que sea un valor entero.
Pues para comprobar esto, habrá que tener en cuenta no solo que ese campo pueda ser una cadena, o un valor decimal..., si no que además puede que ni siquiera exista ese dato.


Teniendo en cuenta todo esto, creo que lo más cómodo sería hacer una única lectura en disco del archivo txt y componer una matriz con TODOS los datos.

Luego, el resto de tareas que pide, las haría trabajando sobre esa matriz y no volviendo a leer otra vez desde disco.

Así que tenemos que componer una matriz con los datos del archivo.
Para ello, primero vamos a necesitar saber cuántas líneas tiene ese archivo, ya que no podemos componer una matriz si no sabemos sus dimensiones.

Luego, sabemos que cada línea nos ha de dar 5 datos, pero ya hemos visto que alguna solo tiene 4. Esto habrá que controlarlo y cuando solo nos den 4 datos, habrá que añadir manualmente ese 5º dato que falta, que será el de "Cantidad" y hay que darle valor 1

Cuando sí tengamos los 5 datos, habrá que comprobar si el 5º dato representa un valor entero, de lo contrario, de nuevo tendremos que asignar manualmente el valor 1.
Comprobar si una cadena representa un entero es fácil. Basta con coger esa cadena e intentar parsearla a Integer.
Si sale bien, es que obviamente es un entero.
Si falla, se producirá una excepción y esto ya nos indica que NO es un entero.

Y ojo, porque alguna línea del archivo está vacía, no hay dato ninguno.

Bueno, para comenzar te propongo este código.
No realiza todas las tareas, solo lee el archivo y compone la matriz con los datos que contiene, teniendo en cuenta la validación de "Cantidad" y que puede haber alguna línea vacía en el archivo.
Código: [Seleccionar]
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;

public class MatrizProductos {

public static void main(String[] args) {
//Crearemos una matriz con TODOS los datos completos del archivo de texto.
String[][] productos = null;

try {
//Para ello, necesitamos saber cuántas líneas tiene el archivo
int lineas = (int) Files.lines(Paths.get("productos.txt")).count();
//Ahora podemos declarar las dimensiones de la matriz
productos = new String[lineas][5]; //5 datos por cada línea

//Procedemos a leer el archivo para transferir la información a la matriz
BufferedReader lector = new BufferedReader(new FileReader("productos.txt"));
for (int i = 0; i < lineas; i++) {
String linea = lector.readLine();

if (linea.isEmpty()) //El txt puede contener líneas "vacías"
productos[i] = null; //En ese caso añadimos valor null a la matriz
else {
/*
* Descomponemos los 5 datos de la línea en un array.
* Algunas lineas pueden contener solo 4 datos porque omiten
* el dato "Cantidad".
* A nosotros solo nos sirve tener un array de 5 datos, en caso de no tenerlos
* tendremos que componerlo añadiendo valor 1 al dato "Cantidad" que nos falta
*/
String[] datos;
if (linea.split("   ").length < 5) {
//Esta línea solo nos va a dar 4 datos, hemos componer un array de 5
String[] lineaIncompleta = linea.split("   ");
datos = new String[5];
for (int j = 0; j < 4; j++) //Añadimos los 4 datos que tenemos
datos[j] = lineaIncompleta[j];
//Y ahora el 5º datos que nos falta
datos[4] = "1";
}
else //Esta línea sí que nos proporciona los 5 datos.
datos = linea.split("   ");

//Comprobamos si el dato de "Cantidad" es un valor entero
if (!esEntero(datos[4]))
datos[4] = "1"; //Si no es entero, se asigna valor 1

//Ya podemos agregar datos validados a la matriz
productos[i] = datos;
}
}
//Lectura de archivo finalizada, la matriz está completada
lector.close();
} catch (FileNotFoundException e) {
System.out.println("ERROR: Archivo TXT no encontrado");
} catch (IOException e) {
System.out.println("ERROR: No se puede acceder al archivo TXT");
}

//Impresión de prueba para ver si hemos compuesto la matriz de productos
for (int i = 0; i < productos.length; i++)
System.out.println(Arrays.toString(productos[i]));
}

/**
* Método que comprueba si un dato String es un entero.
* @param dato String que queremos comprobar
* @return TRUE si la cadena representa un entero, FALSE en caso contrario.
*/
private static boolean esEntero(String dato) {
/*
* Para comprobar si es un entero, podemos intentar
* un parseo a Integer. Si esto produce una excepción,
* es que la cadena no representa un número entero.
*/
try {
Integer.parseInt(dato);
//Si la línea anterior no genera excepción, es que sí es un entero
return true;
}
catch(NumberFormatException nfe) {
//Excepción capturada, no es un entero
return false;
}
}

}

Si lo ejecutamos, veremos que sí hemos logrado componer una matriz con TODOS los datos (incluida la línea vacía que es un valor null)

Citar
[Guanare, 7, Pescado, 2, 7]
[Guanare, 7, Pescado, 2, 1]
[Caracas, 1, Arroz, 2.5, 7]
[Maracay, 2, Frijol, 1.25, 1]
[Maturin, 6, Carne de Res, 3.5, 1]
[Caracas, 1, Arroz, 2.5, 1]
[Barquisimeto, 4, Aceite, 2.75, 1]
[Los Teques, 3, Azucar, 1.5, 1]
[Maturin, 6, Carne de Res, 3.5, 1]
[Merida, 8, Leche, 2.75, 1]
[Maracay, 2, Frijol, 1.25, 7]
[Guanare, 7, Pescado, 2, 1]
[Guanare, 7, Pescado, 2, 7]
[Maracay, 2, Frijol, 1.25, 1]
null
[Caracas, 1, Arroz, 2.5, 1]
[Valencia, 11, Naranja, 0.25, 1]
[Los Teques, 3, Azucar, 1.5, 1]
[Merida, 8, Leche, 2.75, 1]
[Barquisimeto, 4, Aceite, 2.75, 7]
[Guanare, 7, Pescado, 2, 7]
[Guanare, 7, Pescado, 2, 1]
[Isla de Margarita, 5, Pollo, 1.18, 1]
[Maturin, 6, Carne de Res, 3.5, 1]
[Maracay, 2, Frijol, 1.25, 1]
[Los Teques, 3, Azucar, 1.5, 1]
[Los Teques, 3, Azucar, 1.5, 1]
[Maturin, 6, Carne de Res, 3.5, 1]
[Merida, 8, Leche, 2.75, 1]
[Maracay, 2, Frijol, 1.25, 7]

Vale, pues a partir de aquí, el resto de tareas que pide podemos hacerla trabajando sobre esta matriz y así ya nos olvidamos del archivo de texto.

De lo que pide, ya habríamos cumplido con estas:
Citar
Una sentencia de iteración que permita leer todos los artículos
comprados.

Valide que el valor de la variable (cantidad) sea de número entero.
Si el valor de esta variable es «nulo o cadena», utilizar el número 1 en
su lugar

Así que nos faltarían estas:
Citar
Crear una matriz que permita almacenar el ID_Producto, precio y
unidad vendida.

Una sentencia condicional que evalúe las ventas de la region de
Maracay, Maturin. Hacer un total para el resto de las zonas, tomando en cuenta ek yuso de variables diferentes para cada resultados.

Una sentencia condicional que evalúa cuántas libras de pollo se compró.


No se si se espera que demos algún enfoque concreto al programa.
A mi lo que se me ocurre es escribir tres métodos separados para cada una de esas tareas.
Que reciban la matriz como argumento y hagan lo que se pide.

El programa final podría quedar de la siguiente manera.
No he hecho una presentación de datos "bonita" en pantalla, si luego quieres mostrar las matrices más elegantes, con cabecera de datos y tal..., ya es cosa tuya.
Código: [Seleccionar]
public class MatrizProductos {

public static void main(String[] args) {
//Crearemos una matriz con TODOS los datos completos del archivo de texto.
String[][] productos = null;

try {
//Para ello, necesitamos saber cuántas líneas tiene el archivo
int lineas = (int) Files.lines(Paths.get("productos.txt")).count();
//Ahora podemos declarar las dimensiones de la matriz
productos = new String[lineas][5]; //5 datos por cada línea

//Procedemos a leer el archivo para transferir la información a la matriz
BufferedReader lector = new BufferedReader(new FileReader("productos.txt"));
for (int i = 0; i < lineas; i++) {
String linea = lector.readLine();

if (linea.isEmpty()) //El txt puede contener líneas "vacías"
productos[i] = null; //En ese caso añadimos valor null a la matriz
else {
/*
* Descomponemos los 5 datos de la línea en un array.
* Algunas lineas pueden contener solo 4 datos porque omiten
* el dato "Cantidad".
* A nosotros solo nos sirve tener un array de 5 datos, en caso de no tenerlos
* tendremos que componerlo añadiendo valor 1 al dato "Cantidad" que nos falta
*/
String[] datos;
if (linea.split("   ").length < 5) {
//Esta línea solo nos va a dar 4 datos, hemos componer un array de 5
String[] lineaIncompleta = linea.split("   ");
datos = new String[5];
for (int j = 0; j < 4; j++) //Añadimos los 4 datos que tenemos
datos[j] = lineaIncompleta[j];
//Y ahora el 5º datos que nos falta
datos[4] = "1";
}
else //Esta línea sí que nos proporciona los 5 datos.
datos = linea.split("   ");

//Comprobamos si el dato de "Cantidad" es un valor entero
if (!esEntero(datos[4]))
datos[4] = "1"; //Si no es entero, se asigna valor 1

//Ya podemos agregar datos validados a la matriz
productos[i] = datos;
}
}
//Lectura de archivo finalizada, la matriz está completada
lector.close();
} catch (FileNotFoundException e) {
System.out.println("ERROR: Archivo TXT no encontrado");
} catch (IOException e) {
System.out.println("ERROR: No se puede acceder al archivo TXT");
}

System.out.println("\t\tMATRIZ COMPLETA");
System.out.println("\t\t------ --------");
for (int i = 0; i < productos.length; i++)
if (productos[i] != null) //Omitimos líneas vacías
System.out.println(Arrays.toString(productos[i]));

System.out.println("\n\n\t\tMATRIZ CON 3 DATOS");
System.out.println("\t\t------ --- - -----");
String[][] matriz3 = matriz3Datos(productos);
for (int i = 0; i < matriz3.length; i++)
if (matriz3[i] != null) //Omitimos líneas vacías
System.out.println(Arrays.toString(matriz3[i]));

System.out.println("\n\n\t\tVENTAS POR REGIONES");
System.out.println("\t\t------ --- --------");
evaluarRegiones(productos);

System.out.println("\n\n\t\tTOTAL DE POLLO VENDIDO");
System.out.println("\t\t----- -- ----- -------");
System.out.println("Peso total: " + librasDePollo(productos) + " lb");

System.out.println("\n\n\t\tFIN DE PROGRAMA");
}

/**
* Método que comprueba si un dato String es un entero.
* @param dato String que queremos comprobar
* @return TRUE si la cadena representa un entero, FALSE en caso contrario.
*/
private static boolean esEntero(String dato) {
/*
* Para comprobar si es un entero, podemos intentar
* un parseo a Integer. Si esto produce una excepción,
* es que la cadena no representa un número entero.
*/
try {
Integer.parseInt(dato);
//Si la línea anterior no genera excepción, es que sí es un entero
return true;
}
catch(NumberFormatException nfe) {
//Excepción capturada, no es un entero
return false;
}
}

/**
* Crea una matriz con solo 3 datos de los 5 originales.
* Los datos son: ID_Producto, precio y unidad vendida.
* @param matrizPrincipal Matriz con los datos originales.
* @return Matriz con una selección de solo 3 datos.
*/
private static String[][] matriz3Datos(String[][] matrizPrincipal) {

String[][] matriz = new String[matrizPrincipal.length][3];
//Recorremos las matrices, seleccionando los datos deseados
for (int i = 0; i < matriz.length; i++) {
//Ojo con las líneas null
if (matrizPrincipal[i] == null)
matriz[i] = null;
else {
matriz[i][0] = matrizPrincipal[i][1]; //ID_Producto
matriz[i][1] = matrizPrincipal[i][3]; //Precio
matriz[i][2] = matrizPrincipal[i][4]; //Unidades vendidas
}
}

return matriz;
}

/**
* Evalúa las ventas según 3 regiones:
* Maracay, Maturin, Resto zonas.
* @param matrizPrincipal Matriz con los datos originales.
*/
private static void evaluarRegiones(String[][] matrizPrincipal) {
double maracay = 0, maturin = 0, resto = 0;
for (int i = 0; i < matrizPrincipal.length; i++) {
if (matrizPrincipal[i] != null) {
//Parseamos precio a double
double precio = Double.parseDouble(matrizPrincipal[i][3]);
//Unidades vendidas
int unidades = Integer.parseInt(matrizPrincipal[i][4]);
//Calculamos venta
double venta = precio * unidades;

//Evaluamos región para saber donde sumamos esta venta
switch(matrizPrincipal[i][0]) {
case "Maracay":
maracay += venta;
break;
case "Maturin":
maturin += venta;
break;
default:
resto += venta;
}
}
}

//Presentación de datos
System.out.println("Ventas totales de Maracay: " + maracay);
System.out.println("Ventas totales de Maturin: " + maturin);
System.out.println("Ventas totales del resto de zonas: " + resto);
}

/**
* Calcula las libras de pollo totales vendidas
* @param matrizPrincipal Matriz con los datos originales.
* @return Peso total en libras vendidas
*/
private static int librasDePollo(String[][] matrizPrincipal) {
int total = 0;
for (int i = 0; i < matrizPrincipal.length; i++)
if (matrizPrincipal[i] != null)
total += Integer.parseInt(matrizPrincipal[i][4]);

return total;
}

}

Y con esto creo que se cumple lo que se pide.
Pregunta si algo no entiendes, si faltaría algo por hacer, lo que sea...
No se si hay que guardar alguna matriz en disco,...ya nos dirás algo.

Un saludo.
« Última modificación: 16 de Agosto 2022, 20:39 por Kabuto »
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Franmimego

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 3
    • Ver Perfil
Wao, esta genial... mil gracias Kabuto.. te consulto, das clases de Java? Me gustaria entender mejor este tipo de codigo... mi madre es Financista y decidió actualizarse un poco para dominar mejor las herramientas tecnologicas y estudia negocios digitales, innovacion y emprendimientos.. pero le agregaron una materia de pensamiento algoritmico, donde debe hacer ese codigo para pasar un modulo.. y he intentado ayudarla... encontre codigos para leer el txt pero no habia encontrado como hacer que todo junto funcionara.. mil gracias la verdad, porque habia estado intentando ayudar sin exito porque tenia solo parte del codigo hecho.. voy a copiar el codigo en IntelliJ para correrlo y ver como muestra los datos para colocar los titulos.. eso si ya lo se hacer jeje.. gracias mil por tu valiosisima ayuda.. tengo toda la semana acostandome de madrugada porque me faltaba mucho.

You're my hero!! jejejeje.

Un abrazo, gracias!!

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
No, no doy clases de Java.
Ni estoy capacitado para una tarea tan responsable ni tendría tiempo para ello.
Yo ni siquiera me dedico a la programación, mi trabajo no tiene nada que ver con ella.

Yo soy solo un aprendiz, por hobby, y que a veces rasco algo de tiempo libre para ir aprendiendo más cosas nuevas, o bien para ayudar a otros en lo que pueda.

Gracias por tu reconocimiento.
Un saludo.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".