jueves, 7 de abril de 2011

~Semana 10. Eventos, excepciones y errores

Semana 10
Materia: Taller de Programación Orientada a Objetos
Jueves M1-M2

Hola a todos, en esta entrada les explicare un poco sobre el uso de excepciones, errores y eventos dentro de mi proyecto. 

Excepciones
Algunas de las excepciones que he agregado a mi proyecto están en la parte de validación de datos por parte del usuario.
package nutrilife.gui;
import nutrilife.dieta.*;
import java.util.InputMismatchException;
/**
 *
 * @author Carmen Suarez
 */
public class Main {

    public static void main(String[] args) {
        
        //Variable that stores that will stream the input from console
        Dieta D = new Dieta();
        boolean control = true;
        do
        {
            try
            {
                InputDieta.input(D);
                control = false;
            }
            catch (InputMismatchException inputMismatchException)
            {
                inputMismatchException.printStackTrace();
                System.out.println("Vuelve a meter los datos");
            }
        }while( control );
    }
}
package nutrilife.gui;
import nutrilife.dieta.*;
import java.util.*;
/**
 *
 * @author Carmen Suarez
 */
public class InputDieta {
    static void input(Dieta D) throws InputMismatchException
    {
        Scanner scan = new Scanner(System.in);
        System.out.println("Dame el numero de energia");
        D.setEnergia(scan.nextDouble());
        System.out.println("Energia: " + D.getEnergia());
        boolean c = true;  //Variable de control
        //Entrar porcentajes
        do
        {
            try
            {
                System.out.print("Dame el porcenaje de carbohidratos: ");
                D.setPorcentajeCarbohidrato(scan.nextDouble());
                System.out.println("Porcentaje de carbohidratos: " + D.getPorcentajeCarbohidrato());

                System.out.print("Dame el porcenaje de proteinas: ");
                D.setPorcentajeProteina(scan.nextDouble());
                System.out.println("Porcentaje de proteinas: " + D.getPorcentajeProteina());

                System.out.print("Dame el porcenaje de lipidos: ");
                D.setPorcentajeLipido(scan.nextDouble());
                System.out.println("Porcentaje de lipidos: " + D.getPorcentajeLipido());

                D.setPorcentajeTotal(); // Calcula el valor para la variable porcentajeTotal

                if( D.getPorcentajeTotal() != 100)
                {
                    throw new MyException();
                }
                c = false;
                D.setCarbohidratos(); // Calcula el valor para la variable carbohidrato
                D.setProteina(); // Calcula el valor para la variable proteina
                D.setLipido(); // Calcula el valor para la variable lipido
            }
            catch(MyException myException)
            {
                myException.getMessage();
                myException.printStackTrace();
            } 
        }while(c); // Termina entrada de porcentajes
        
        //Entrada de Intercambios
        //intercambios de grupo: Leche
        System.out.print("Dame el intercambio de leche descremada: ");
        D.setIntercambioLecheDescremada(scan.nextInt());
        System.out.println("Intercambios para leche descremada: " + D.getIntercambioLecheDescremada());
        System.out.print("Dame el intercambio de leche semidescremada: ");
        D.setIntercambioLecheDescremada(scan.nextInt());
        System.out.println("Intercambios para leche semidescremada: " + D.getIntercambioLecheSemidescremada());
        System.out.print("Dame el intercambio de leche entera: ");
        D.setIntercambioLecheEntera(scan.nextInt());
        System.out.println("Intercambios para leche entera: " + D.getIntercambioLecheEntera());
        System.out.print("Dame el intercambio de leche con azucar: ");
        D.setIntercambioLecheConAzucar(scan.nextInt());
        System.out.println("Intercambios para leche con azucar: " + D.getIntercambioLecheConAzucar());

        //Intercambios de grupo: Fruta
        System.out.print("Dame el intercambio de la fruta: ");
        D.setIntercambioFruta(scan.nextInt());
        System.out.println("Intercambios para la frutar: " + D.getIntercambioFruta());

        //Intercambios de grupo: Verdura
        System.out.print("Dame el intercambio de la verdura: ");
        D.setIntercambioVerdura(scan.nextInt());
        System.out.println("Intercambios para la verdura: " + D.getIntercambioVerdura());

        //Intercambios de grupo: Azucar
        System.out.print("Dame el intercambio de la azucar sin grasa: ");
        D.setIntercambioAzucarSinGrasa(scan.nextInt());
        System.out.println("Intercambios para la azucar sin grasa: " + D.getIntercambioAzucarSinGrasa());
        System.out.print("Dame el intercambio la azucar con grasa: ");
        D.setIntercambioAzucarConGrasa(scan.nextInt());
        System.out.println("Intercambios para la azucar con grasa: " + D.getIntercambioAzucarConGrasa());

        //Intercambios de grupo: Leguminosas y Cereales
        System.out.print("Dame el intercambio la leguminosa: ");
        D.setIntercambioLecheConAzucar(scan.nextInt());
        System.out.println("Intercambios para la leguminosa: " + D.getIntercambioLecheConAzucar());
        System.out.print("Dame el intercambio del cereal sin grasa: ");
        D.setIntercambioCerealSinGrasa(scan.nextInt());
        System.out.println("Intercambios para del cereal sin grasa: " + D.getIntercambioCerealSinGrasa());
        System.out.print("Dame el intercambio del cereal con grasa: ");
        D.setIntercambioCerealConGrasa(scan.nextInt());
        System.out.println("Intercambios para del cereal con grasa: " + D.getIntercambioCerealConGrasa());

        //Intercambios de grupo: Alimentos de origen animal
        System.out.print("Dame el intercambio la carne muy magra: ");
        D.setIntercambioAlimentoMuyMagro(scan.nextInt());
        System.out.println("Intercambios para la carne muy magra: " + D.getIntercambioAlimentoMuyMagro());
        System.out.print("Dame el intercambio la carne magra: ");
        D.setIntercambioAlimentoMagro(scan.nextInt());
        System.out.println("Intercambios para la carne magra: " + D.getIntercambioAlimentoMagro());
        System.out.print("Dame el intercambio la carne semigrasa: ");
        D.setIntercambioAlimentoSemigraso(scan.nextInt());
        System.out.println("Intercambios para la carne semigrasa: " + D.getIntercambioAlimentoSemigraso());
        System.out.print("Dame el intercambio la carne grasa: ");
        D.setIntercambioAlimentoGraso(scan.nextInt());
        System.out.println("Intercambios para la carne grasa: " + D.getIntercambioAlimentoGraso());

        //Intercambios de grupo: Aceites
        System.out.print("Dame el intercambio de aceite sin proteina: ");
        D.setIntercambioAceiteSinProteina(scan.nextInt());
        System.out.println("Intercambios para de aceite sin proteina: " + D.getIntercambioAceiteSinProteina());
        System.out.print("Dame el intercambio de aceite con proteina: ");
        D.setIntercambioAceiteConProteina(scan.nextInt());
        System.out.println("Intercambios para de aceite con proteina: " + D.getIntercambioAceiteConProteina());
    }
}
La clase IOUser lo que hace es crear una dieta con valores default y mandar a llamar a al método estático input de la clase InputDieta para que pueda inicializar los datos de la dieta. Este llamado está dentro de un bloque try, lo que nos permite atrapar cualquier excepción que se arroje dentro de él. 

El bloque catch solamente imprime el StactTrace de la excepción que es una descripción de donde se origina el error de la excepción y todos los saltos que dio para llegar al try. Estuve leyendo que esta manera de desplegar, aunque es un tanto gorrosa para el usuario sirve mucho para hacer debugs de los programas y saber exactamente donde se origina el error.

Lo que hice fue meter los bloques try y catch dentro de un do-while para que el usuario vuelva a meter todos los datos desde el principio, ya que no se puede asegurar que ciertos datos estén bien y otros no (Como es en el caso de que la excepción se mande en la validación de porcentajeTotal). Este do-while solamente finaliza cuando el método input retorna el control del programa al método que lo llamo y después la variable booleana que controla el do-while es asignado con un valor falso para que salga. Si ocurre una excepción dentro del método input, no se ejecuta la instrucción de control es falso. Si no ocurre una excepción el programa continuara con la instrucción control es falso y saldrá del do-while.

Error

Los errores, como bien mencione en la entrada pasada, son en su mayoría errores tanto del JVM (memoria llena, errores internos, stak overflow, etc.) como de errores en la lectura de los recursos externos del programa como lo son lecturas de archivos, conexiones a bases de datos, etc.
package nutrilife.gui;
import java.sql.*;

/**
 *
 * @author Carmen Suarez
 */
public class CreateSQLConnection {
    static final String DRIVER = "com.mysql.jdbc.Driver";
    static final String DATABASE_URL = "jdbc:mysql://localhost/3306/Dieta";
    static final String USUARIO = "root";
    static final String PASSWORD = "";
    public static void connection()
    {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        
        try {
            Class.forName(DRIVER);
            connection = DriverManager.getConnection(DATABASE_URL, USUARIO, PASSWORD);
            statement = connection.createStatement();
            resultSet = statement.executeQuery("Select * from FichaIdentificacion");
            ResultSetMetaData metaData = resultSet.getMetaData();
            int numberOfColumns = metaData.getColumnCount();

            for ( int i = 1; i <= numberOfColumns; i++ )
            {
                System.out.printf( "%-8s\t", resultSet.getObject(i));
            }
            System.out.println();

            while(resultSet.next())
            {
                for ( int i = 1; i <= numberOfColumns; i++ )
                    System.out.printf( "%-8s\t", resultSet.getObject(i));
                System.out.println();
            }
            
        }
        catch (SQLException sqlException) {
            sqlException.getMessage();
            System.out.println();
            sqlException.printStackTrace();
            throw new Error();
        }        
        catch(ClassNotFoundException classNotFoundException)
        {
            classNotFoundException.getMessage();
            System.out.println();
            classNotFoundException.printStackTrace();
        }
        finally
        {
            try {
                resultSet.close();
                statement.close();
                connection.close();
            } catch (Exception exception) {
                exception.getMessage();
                exception.printStackTrace();
            }
        }      
    }
}
Por lo tanto decidí que si el programa no puede establecer una conexión con la base de datos, esta finalice ya que el programa no sirve para nada sino tiene los datos de pacientes o dietas. 
En la parte
connection = DriverManager.getConnection(DATABASE_URL, 
                                         USUARIO, PASSWORD);
Si no obtiene una conexión con la base de datos, esta lanza una excepción que la tengo que agarrar porque se trata de una clase que lanza excepciones "checked" que a fuerzas se tienen que manejar. La excepción es agarrada por un catch que imprime su StackTrace y lanza un error para finalizar el programa.
También use los bloques finally porque de esta manera puedo asegurarme que aunque se lance o no se lance una excepción y/o error, el programa liberara los recursos de la base de datos. 

La clase todavía le falta bastante para obtener todos los datos, pero necesito ver cómo voy a estructurar las tablas del paciente en la base de datos junto con las tablas de las dietas.

Bueno esto es lo que corresponde a eventos, excepciones y errores de mi proyecto. Espero que hayan entendido, cualquier duda o comentario me lo hacen saber ;) saludos!

6 comentarios:

  1. Que tal carmen, lo que vi en tu codigo, es que te va a arrojar una excepcion al momento de que el porcentaje no sea 100, bueno realmente no siempre sera 100 por que los porcentaes de lipidos, carbohidratos y proteinas no te van a sumar un 100 %, por ejemplo una persona normal necesita de 35 a 65 gramos de proteina diarios, esto depende de la intensidad de la actividad fisica, en caso de que la persona tengo una actividad fisica intensa y necesita los 65, de ahi te vas a basar al 100 ? Lo que te recomiendo al usar esas excepciones es que solo en porcentaje de grasa uses estos porcentajes, y ya en lipidos proteinas y carbohidratos usalo en gramos.
    solo es una recomendacion carmen :)

    ResponderEliminar
  2. Si, eso lo tengo en mente pero esque esto es solo una parte de las operaciones que se obtendrán. Mi prima me dio un programa en excel donde viene como saca ella todo lo que necesita, mediante el numero de intercambios de cada comida se hacen ciertas operaciones que se sacan en gramos, estos porcentajes siempre tienen que dar 100, es una condición que ella me dijo que tenia que estar si no es así quiere decir que la dieta está mal equilibrada, solo tienen que sumar 100 el porcentaje de lipidos, carbohidratos y proteinas. Los gramos son algo diferente los gramos no son lo mismo que el porcentaje el porcentaje ella lo usa dependiendo de los resultados que tiene el paciente en unos estudios que se le hacen y ella sabe como distribuir este porcentaje siempre y cuando sumen 100. Al final te viene el porcentaje junto con los gramos totales de proteinas, lipidos y carbohidratos que le esta dando. Gracias por tu comentario :)

    ResponderEliminar
  3. Que tal carmen, supongo también en el futuro sería conveniente utilizar excepciones para generar dietas a los clientes, por ejemplo si hay 2 personas que pesan 100 kilos pero una tiene diabetes y la otra no, deberas tratarlas de manera diferente ¿verdad?, así que sugeriria agregaras algo así más adelante en tu proyecto
    Saludos =D

    ResponderEliminar
  4. Si, eso también lo tenía en mente. Pero eso eso lo pondre después cuando ya comience a hacer todas las dietas de los pacientes. Aunque creo que será medio laborioso ya que son muchas enfermedades o intolerancias, pero espero que en un futuro ya tenga todo esto manejado. Gracias por tu aportación Adan. Saludos :)

    ResponderEliminar
  5. Hola Carmen (: yo digo que podrías crear excepciones también dependiendo al cliente seria bueno tener Una dieta para personas que quieran bajar de peso y también subir de peso y también seria bueno implementar dietas para deportistas ya que los deportistas necesitan una dieta alta en proteinas solo es una sugerencia

    Saludos (:

    ResponderEliminar
  6. Los comentarios de Adán y Alex no entendí en el contexto de excepciones, aunque en general tienen sentido. +1 Héctor y +1 Carmen por sus respuestas. En la entrada me hubiera gustado saber también sobre cómo generarás los eventos, Carmen. 4 por la entrada.

    ResponderEliminar