lunes, 6 de junio de 2011

[SEGUNDA OPORTUNIDAD] Planeación de proyectos (Como evitar la segunda oportunidad)

Buenas tardes compañeros, en vista de que no logre pasar en primera oportunidad, me dieron la oportunidad de lograrlo en segundas. Pero segundas no es del agrado de todos, así que esta entrada explicaré como mantener organizado nuestro proyecto y avanzarlo durante el semestre en forma óptima para lograr tener éxito en tal proyecto.

Puesto que NO lo logre, espero que aparte de ustedes, esto también me sirva. Los pasos a seguir para terminar bien tu proyecto son los siguientes:
 
1.- Piensa bien lo que quieres hacer.
Esto es, piensa en tus posibilidades, no selecciones cualquier cosa porque se ve bonita, sino que selecciones algo que creas poder terminar. Después de todo, cualquier proyecto funcional es bueno sin importar que tanto grado de dificultad tenga.
En mi caso decidí hacer algo sencillo pero que cumple con las expectativas.

2.- Se constante.
No lograras terminar si solo decidiste que será algo fácil y asistiendo a clases. Necesitas meterle mano a tu proyecto, cualquier cosa ingeniosa que leas o que encuentres por la red que creas que te es útil, agrégasela a tu trabajo y veras que poco a poco irá creciendo.

Por parte mía, este punto también lo considere, mi proyecto está hecho de distintos trozos de códigos que encontré en YouTube, tutoriales, google y por supuesto que códigos implementados por mí.

Tal vez digas, "eso es copiar", yo digo no, copiar es robarse una idea de otro o tomar el examen de otra persona, si lo encuentras en internet, es de todos y por lo tanto puedes implementarlo, si no te quieres matar adivinando que es lo que te falta. En pocas palabras, investigar no es malo.

3.- Trabaja en equipo.
Posiblemente tu trabajo es individual o pienses que un equipo no funciona porque uno no trabaja o porque otro no se preocupa y terminaras haciendo todo tu solo. Pues existen muchas maneras de trabajar en equipo bajo cualquiera de estas condiciones. Por mencionar algunas:
  • En caso de que tu trabajo sea individual, puedes trabajar con otros, la manera más fácil es encontrar personas que tengan un trabajo similar al tuyo, así pueden dividir el trabajo entre más personas aunque no pertenezcan a la misma clase.
  • Si alguna de las personas no domina el tema o simplemente le es difícil, intenten dividir el trabajo de más fácil a más difícil y hagan lo más difícil juntos.
  • Si el proyecto de cada quien tiene cosas diferentes, hagan en equipo los temas comunes.
  • Si su proyecto no es individual, investiguen posibles implementaciones cada quien por su cuenta y hagan lluvia de ideas.

Creo que ésta fue una de las cosas que me falto.

4.- Pide opiniones.
Al iniciar un proyecto es muy probable que no sepas mucho del tema. Así que es mejor que busques opiniones de gente que conozca bien sobre lo que haces. Pueden ser alumnos de grados superiores o a tus maestros, porque no a la gente de internet. Ya que a veces aunque investiguemos no encontraremos lo que buscamos.

Esto tampoco lo aplique, creo que esto fue lo que me llevo directo a segundas.

5.- Organiza tu tiempo.
Algo importante para tener éxito con tu proyecto es tener tiempo, pero tener tiempo no significa que te encarguen pocas tareas y que te quede mucho tiempo libre, significa saber hacer lo que te pidan a tiempo sin importar cuánto trabajo sea.

Tener organizado el trabajo es esencial  para poder terminar a tiempo. Para lograr esto es necesario dividir la semana, incluso los días en partes; por ejemplo, tomar la tarde para avanzar en el proyecto, o bien dedicar un día para el.


Si tiempo es lo que no tienes, dedica tus horas libres para trabajar entre clases, como ir a la biblioteca a avanzar, sirve que preguntas a tus compañeros por algunas dudas.

Una de las cosas que empecé a utilizar hasta la mitad del semestre.

6.- Siempre ten un respaldo.
Esto es aplicable a la gente que sus proyectos consisten en un proyecto de software, ya que asta el punto 5 es aplicable a cualquier tipo de proyecto. También se aplica a alguna investigación o algo por el estilo.

Siempre carga contigo una copia de seguridad de tu trabajo. Nunca sabes que puede suceder. Otra opción es tener una copia en algún servidor en internet. Dropbox, iDrive u otros servidores son útiles en estos casos. Enviarse un correo con los archivos adjuntos asimismo es otra buena idea.

A veces necesitamos de grandes cantidades de datos, que solo podemos manejar en nuestra computadora, en este caso, instalar el software necesario en una USB es útil.

Personalmente he utilizado este método desde que tengo una USB.

Alguna otra idea? Comentala aquí.

domingo, 5 de junio de 2011

[SEGUNDA OPORTUNIDAD] Proyecto Final Taller

Proyecto Final

Video del programa funcionando, muy simple ya que no logre implementar una interfaz gráfica, pero funciona y es lo que importa.




Códigos finales del programa:

Para mi base de datos:
package Organidatabase;

import java.sql.*;

public class Database {
 
 PreparedStatement stmt = null;
 ResultSet rs=null;
 
 public final static String drv ="com.mysql.jdbc.Driver";
 public final static String db ="jdbc:mysql://localhost:3306/organischema";
 public final static String user ="***";
 public final static String pword="***";
 
 Connection ct;
 public Statement st;

 public Database(){
  try{
   Class.forName(drv);
   ct =DriverManager.getConnection(db, user, pword);
   st =ct.createStatement();
  }catch(Exception e){
   System.err.println("No se pudo conectar a la base de datos.");
   return;
  }
 }

 public Statement getSt(){
  return st;
 }

}


Aqui mis eventos:
package Organidatabase;

import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Scanner;

public class Eventos extends Database{
 
 String lugar;
 String fecha;
 String hora;
 
 public Eventos(){}
 
 public void total_eventos(String id){
  try{
   int i = 0;
   stmt = ct.prepareStatement("SELECT * FROM events, Alumnos WHERE events.idAlumnos = "+id+" and Alumnos.idAlumnos ="+id+"");
   rs= stmt.executeQuery();
   while(rs.next()){
    i++;
   }
   if(i!=0){
    System.out.println("Tiene "+i+" eventos pendientes.");
   }
   else{}
  }catch(SQLException e){
   System.out.println("No tiene eventos");
  } 
 }
 
 public void show_event(String id){
  try{
   int i = 0;
   stmt = ct.prepareStatement("SELECT * FROM events, Alumnos WHERE events.idAlumnos = "+id+" and Alumnos.idAlumnos ="+id+"");
   rs= stmt.executeQuery();
   while(rs.next()){
    i++;
    System.out.println("*******************************************************");
    System.out.println("("+i+")");
    System.out.println("Lugar: "+rs.getString("events.place"));
    System.out.println("El "+rs.getString("events.date")+"a las "+rs.getString("events.time"));
   }
   System.out.println("*******************************************************");
  }catch(SQLException e){}
 }
 
 public void make_event(String id){
  System.out.print("Lugar: ");
  Scanner a = new Scanner(System.in);
  lugar = a.nextLine();
  lugar = lugar.replace(' ','_');
  System.out.print("Fecha (dd/MM/aaaa): ");
  fecha = a.next();
  while(comprobar_fecha(fecha)==false){
   System.out.println("Fecha incorrecta");
   System.out.print("Fecha (dd/MM/aa): ");
   fecha = a.next();
  }
  System.out.print("Hora: ");
  hora = a.next();
  while(comprobar_hora(hora)==false){
   System.out.println("Hora incorrecta");
   System.out.print("Hora (hh:mm): ");
   hora = a.next();
  }
  send(id);
 }
 
 private boolean comprobar_hora(String hora) {
  int hora1 = Integer.parseInt(hora.substring(0, 2));
  int hora2 = Integer.parseInt(hora.substring(3, 5));
  if(hora1>23||hora2>59){
  return false;
  }
  else{
  return true;
  }
 }


 private static boolean comprobar_fecha(String fechax) {
  try {
  SimpleDateFormat formatoFecha = new SimpleDateFormat("dd/MM/yy", Locale.getDefault());
  formatoFecha.setLenient(false);
  formatoFecha.parse(fechax);
  } catch (ParseException e) {
  return false;
  }

  return true;
  }
 
 public void send(String id){
  try {
   stmt = ct.prepareStatement("INSERT INTO events (place, date, time, idAlumnos) VALUES (?,?,?,?)");
   stmt.setString(1, lugar);
   stmt.setString(2, fecha);
   stmt.setString(3, hora);
   stmt.setString(4, id);
   stmt.executeUpdate();
   stmt.close();

  } catch (SQLException e) {}
 }
 
}

Para mis horarios:
package Organidatabase;

import java.io.IOException;
import java.sql.SQLException;
import java.util.*;

public class Horario extends Database{

 public String dayselection;

 public String subselection;

 public Horario(){
  
 }

 public void phrs(int a){
  if(a==2)
   System.out.print("Profesor: ");
  if(a==3)
   System.out.print("Examen 1: ");
  if(a==4)
   System.out.print("Examen 2: ");
  if(a==5)
   System.out.print("Faltas: ");
  if(a==6)
   System.out.print("Tareas: ");
  if(a==7)
   System.out.print("Tareas no cumplidas: ");
  if(a==8)
   System.out.print("Total de tareas: ");
  if(a==9)
   System.out.print("Promedio: ");
 }

 public void showAll(String matt, String pass) throws IOException {
  boolean selec = true;
  while(selec == true){
  String dia = new String();
  Scanner a = new Scanner(System.in);
  System.out.println("Introduzca un dia (Lu, Ma, Mi, Ju, Vi, Sa): ");
  dia = a.next();
  dayselection = dia;
  try{
   do{
    stmt = ct.prepareStatement("SELECT * FROM Alumnos, "+dia+" WHERE  Alumnos.idAlumnos = ? AND Alumnos.idPass = ? AND Alumnos.idAlumnos = "+dia+".idAlumnos");

    stmt.setString(1,matt);
    stmt.setString(2, pass);
    rs = stmt.executeQuery();
    if(rs.next()){
     System.out.println("Seleccione Horario: ");
     String sub = a.next();
     subselection=rs.getString(sub);
     fill_data();
     rs.close();
    }
    else{
     System.out.print("Error");
     rs.close();
    }
   }while(rs.isClosed()==false);
  }catch(SQLException e){
   System.out.println("No se pudo realizar la consulta.");
  }
  System.out.print("¿Desea ver otra materia?(S/N): ");
  char sel= (char) System.in.read();
   switch(sel) {
   case 's': 
    selec = true;
       break;
       
   case 'S':
    selec=true;
    break;
   
   default:
    selec = false;
       break;
  }
  }
 }

 public void fill_data(){
  try{
   stmt = ct.prepareStatement("SELECT * FROM "+subselection+", "+dayselection+" WHERE "+dayselection+".idAlumnos = "+subselection+".idAlumnos");
   rs = stmt.executeQuery();
   while(rs.next()){
    System.out.println(subselection.replace('_', ' '));
    for(int i=2; i<=9; i++){
     phrs(i);
     if(rs.getString(i) == null){
      System.out.println("Sin Datos");
     }
     else{
      System.out.println(rs.getString(i));
     }
    }

   }
  }catch(SQLException i){
   System.out.println("No tiene materia asignada en ese horario.");
   
  }
 }
 
 

}

Tambien las notas:
package Organidatabase;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class Notas extends Database{
 String nota;
 String para;
 
 InputStreamReader isr = new InputStreamReader(System.in);
 BufferedReader br = new BufferedReader (isr);

  public Notas () {
     }

  public void nuevo(String id){
   try{
    int i=0;
    stmt = ct.prepareStatement("SELECT * FROM notes, Alumnos WHERE notes.idTo = "+id+" and Alumnos.idAlumnos = notes.idAlumnos");
    rs = stmt.executeQuery();
    while(rs.next()){
     if(rs.getBoolean("visto")==false){
      i++;
     }
    }
    if(i==0){
     System.out.println("No tiene mensajes.");
    }
    else{
     System.out.println("Tiene "+i+" mensajes nuevos.");
    }
   }
   catch(SQLException e){}
 }

  public String note() throws IOException{
    System.out.println("Escriba su nota: ");
        nota=br.readLine();
        nota = nota.replace(' ','_');
        return nota;
  }

  public String to(){
   System.out.println("Para: ");
      Scanner a = new Scanner(System.in);
      para=a.next();
      para=comprueba(para);
      return para;
  }

  public void show_notes(String id){
   try{
    int i=0;
    stmt = ct.prepareStatement("SELECT * FROM notes, Alumnos WHERE notes.idTo = "+id+" and Alumnos.idAlumnos = notes.idAlumnos");
    rs = stmt.executeQuery();
    while(rs.next()){
     int x = rs.getInt(1);
     i++;
     System.out.println("*******************************************************");
     if(rs.getBoolean("visto")==false){
      System.out.print("Nuevo ");
      try{
       stmt = ct.prepareStatement("UPDATE notes SET visto = ? WHERE Idnote = "+x+"");
       stmt.setBoolean(1, true);
       stmt.executeUpdate();
       stmt.close();
      }catch(SQLException e){}
    }
     System.out.println("Mensaje: "+i);
     System.out.println(rs.getString("Alumnos.NomApell")+" ("+rs.getString("notes.idAlumnos")+"):");
     System.out.println(rs.getString("note").replace('_',' '));
     System.out.println("Recibida el "+rs.getString("fecha")+" a las "+rs.getString("hora"));
    }
    System.out.println("*******************************************************");
    if(i==0){
     System.out.println("No hay mensajes.");
    }
    else{
     System.out.print("Desea eliminar una nota?: ");
     Scanner a = new Scanner(System.in);
     String line = a.nextLine();
     char s = line.charAt(0);
     if(s=='S'||s=='s'){
      System.out.print("Seleccione el número de mensaje: ");
      int y = a.nextInt();
      eliminar(y,id);
     }
    }
    
   }
   catch(SQLException e){}
 }

  public void eliminar(int sel, String id){
   int x;
   int i=0;
   try{
    stmt = ct.prepareStatement("SELECT * FROM notes, Alumnos WHERE notes.idTo = "+id+" and Alumnos.idAlumnos = notes.idAlumnos");
    rs = stmt.executeQuery();
    while(rs.next()){
     i++;
     x=rs.getInt(1);
     if(i==sel){
    try{
      stmt = ct.prepareStatement("DELETE FROM notes WHERE Idnote="+x+"");
      stmt.executeUpdate();
      stmt.close();
      }catch(SQLException e){}
     }
    }
   }catch(SQLException e){
    System.out.println("wey");
   }

  }


  public String comprueba(String para){
   
 try {
  stmt = ct.prepareStatement("SELECT idAlumnos FROM Alumnos");    
  rs = stmt.executeQuery();
  while(para!=rs.getString("idAlumnos")){
   if(para.equals(rs.getString("idAlumnos")))
    para= rs.getString("idAumnos");
   else{
    rs.next();
    para= null;
   }
  }
 }catch (SQLException e) {
  }
 return para;
  }
   
  public String get_all(String note, String to, String from){
  Date fecha = new Date();
  SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yy");
  SimpleDateFormat formatohora = new SimpleDateFormat("hh:mm a");
  String cadenaFecha = formato.format(fecha);
  String cadenaHora =formatohora.format(fecha);
  try{
   stmt = ct.prepareStatement("INSERT INTO notes (idAlumnos, note, idTo, fecha, hora) VALUES (?,?,?,?,?)");
   stmt.setString(1,from);
   stmt.setString(2, note);
   stmt.setString(3, to);
   stmt.setString(4, cadenaFecha);
   stmt.setString(5, cadenaHora);
   stmt.executeUpdate();
   stmt.close();
   String all = "Se envió exitosamente:\n"+note+"\nPara:\n"+to;
   return all;
  }catch(SQLException i){
   System.out.println("Ocurrio un error.");
   return null;
  }
 }
}
Sus respectivas pruebas unitarias:
package Organidatabase;

import java.io.IOException;

import junit.framework.TestCase;

public class TestNotas extends TestCase {
 
 private String s;
 
  public TestNotas( String nombre ) {
    super( nombre );
  }

  public static void main( String args[] ) {
    junit.textui.TestRunner.run( TestNotas.class );
  }
  
  public void setUp() {
   Notas n = new Notas();
   try {
  s=n.get_all(n.note(), n.to(), "1441708");
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
  }

  public void testEnviaNota() {
    assertNotNull(s);
  }
}
Y por ultimo el main:
package Organidatabase;

import java.io.BufferedReader;
import java.io.Console;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

import javax.swing.UIManager;

public class Main {

 private static void limpiar(){
  try {
   String línea;

   Process p = Runtime.getRuntime().exec("clear");
   BufferedReader input = new BufferedReader (new InputStreamReader(p.getInputStream()));

   while ((línea = input.readLine()) != null) {
   System.out.print(línea);
   }
   input.close();
   } catch (Exception e) {
   e.printStackTrace();
   }
 }

 public static void main(String[] args) throws IOException{
  Horario h = new Horario();
  Notas n = new Notas();
  Eventos e = new Eventos();
  Scanner a = new Scanner(System.in);
  Console terminal = System.console();
        if (terminal==null ) {
            System.err.println("No puedo obtener la consola.");
            return;
        }
      
  String matt = new String (terminal.readLine("Ingresar Usuario: "));
  String pass= new String (terminal.readPassword("Ingresar contraseña: "));
  limpiar();
  n.nuevo(matt);
  e.total_eventos(matt);
  System.out.print("\n");
  System.out.println("Selecione una opcion:");
  System.out.println("1 - Ver Materias.");
  System.out.println("2 - Ver y crear notas.");
  System.out.println("3 - Ver y crear eventos.");
  System.out.println("0 - Salir.");
  System.out.print("Seleccion: ");
  int sel= a.nextInt();
  limpiar();
  while(sel!= 0){
   switch(sel){
   case 1:
    h.showAll(matt, pass);
    limpiar();
    break;
   case 2:
    System.out.println("1 - Ver notas recibidas.");
    System.out.println("2 - Crear una nota.");
    System.out.print("Seleccion: ");
    int sel1=a.nextInt();
    limpiar();
    switch(sel1){
    case 1:
     n.show_notes(matt);
     break;
    case 2:
     n.get_all(n.note(), n.to(), matt);
     break;
    }
    break;
   case 3:
    System.out.println("1 - Ver eventos pendientes.");
    System.out.println("2 - Crear un evento.");
    System.out.print("Seleccion: ");
    int sel2=a.nextInt();
    limpiar();
    switch(sel2){
    case 1:
     e.show_event(matt);
     break;
    case 2:
     e.make_event(matt);
     break;
    }
    break;
   }
   System.out.print("\n");
   n.nuevo(matt);
   System.out.print("\n");
   System.out.println("Selecione una opcion: ");
   System.out.println("1 - Ver Materias.");
   System.out.println("2 - Ver y crear notas.");
   System.out.println("3 - Ver y crear eventos.");
   System.out.println("0 - Salir.");
   System.out.print("Seleccion: ");
   sel= a.nextInt();
   limpiar();
  }
 }
 
}

Liga a la documentación: aquí.

miércoles, 4 de mayo de 2011

[TALLER] Implementación y aplicación de pruebas unitarias

En esta entrada explicare los pasos para realizar mi prueba.

Primero que nada quería decir que quería hacer esta prueba a modo de ejemplo, probando la funcionalidad del envió de notas a la base de datos, según yo si funcionaba, pero a la hora de ejecutar estos tests me doy cuenta que no funcionaba, afortunadamente lo solucione.

Para los test utilizare mi clase Notas:

package Organidatabase;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.Scanner;

public class Notas extends Database{
 String nota;
 String para;
 
 InputStreamReader isr = new InputStreamReader(System.in);
 BufferedReader br = new BufferedReader (isr);
  
  public Notas () {
     }
  
  public String note() throws IOException{
    System.out.println("Escriba su nota: ");
        nota=br.readLine();
        nota = nota.replace(' ','_');
        System.out.println(nota);
        return nota;
  }
  
  public String to(){
   System.out.println("Para: ");
      Scanner a = new Scanner(System.in);
      para=a.next();
      return para;
  }

  public String get_all(String note, String to, String from){
  try{
   stmt = ct.prepareStatement("INSERT INTO notes (idAlumnos, note, idTo) VALUES (?,?,?)");
   stmt.setString(1,from);
   stmt.setString(2, note);
   stmt.setString(3, to);
   stmt.executeUpdate();
   stmt.close();
   String all = "Se envió exitosamente:\n"+note+"\nPara:\n"+to;
   return all;
  }catch(SQLException i){
   System.out.println("Ocurrio un error.");
   return null;
  }
 }
}


Explico brevemente, lo que hace es tomar dos strings, e insertarlos dentro de la base de datos, el string note() genera la nota y transforma los espacios en blanco en guiones, el string to() solo recibe una cadena de texto equivalente a la matricula de quien se envia. Por ultimo el método get_all() inserta dentro de la base de datos los strings y devuelve un objeto string para asegurar que se envio la nota.

En cuanto a mi test:

package Organidatabase;

import java.io.IOException;

import junit.framework.TestCase;

public class TestNotas extends TestCase {
 
 private String s;
 
  public TestNotas( String nombre ) {
    super( nombre );
  }

  public static void main( String args[] ) {
    junit.textui.TestRunner.run( TestNotas.class );
  }
  
  public void setUp() {
   Notas n = new Notas();
   try {
  s=n.get_all(n.note(), n.to(), "1441708");
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
  }

  public void testEnviaNota() {
    assertNotNull(s);
  }


}


El test asegura el envío o marca el error al no poder enviarlo. En el setUp()
 se declara un objeto del tipo Notas, el string s recibe el valor de get_all().

En teoría todo está bien, una vez que s reciba el string dejara de ser null y el testEnviarNota() basicamente comprueba de que el string s no sea nulo.

Ok, pasare a ejecutar el test:

En la consola marcó un error.
JUnit marca una falla.

La falla se debe a que como el string s es precisamente un string, yo en el ejemplo puse a y b como entradas, y aunque teoricamente debería ser valido ya que dentro de un string  puede ir tansolo un caractér y a final de cuentas get_all() sevuelve un string completo donde a y b se juntan, hay una falla con el ImputStreamReader y el BufferReader, solo aceptan strings y lanzan una excepción del tipo IOexception, esto corta el programa y sucede el fallo.

Lo corro de nuevo, esta vez con parametros adecuados:

Y JUnit:





Parece que todo salió bien.

Ahora, el verdadero problema que tuve con mi clase fue, según yo, que mi base de datos no aceptaba una entrada de strings con espacios, tenía que cambiar el Scanner por el ImputStreamReader, o de lo contrario obtenía una linda excepción.

De esta manera, podia utilizar la función replace para cambiar los espacios por guiones y de la misma manera al recibir la nota hace el proceso contario.

JUnit me ayudó mas que nada a detectar dónde fallaba, de ahí me base para encontara el verdadero problema que generaba el fallo.

martes, 3 de mayo de 2011

Diseño de pruebas unitarias

En esta entrada explicaré lo que son las pruebas unitarias y las herramientas que utilizaré.

 
Primero que nada, las pruebas unitarias son una herramienta muy importante para el personal de pruebas pero, sobre todo, para los desarrolladores. Nos sirven para detectar errores dentro de los módulos de código, asegura el correcto funcionamiento de cada uno de estos por separado.

 
Una prueba unitaria es buena cuando:
  • Es automatizable: donde no se requiere una intervención manual.
  • Cubren la mayor cantidad de código.
  • Repetibles o reutilizables: pruebas que se utilizan más de una vez.
  • Independientes: la ejecución de una prueba no afecta la ejecución de otra.
  • Profesionales: las pruebas deben ser consideradas igual que el código, con la misma profesionalidad, documentación, etc.
 Algunas ventajas de utilizar pruebas unitarias son:
  • Fomentan el cambio: facilitan el cambio de código para mejorarlo asegurando que los cambios no introduzcan errores.
  • Sirven como documentación.
  • Los errores están más acotados y son más fáciles de localizar: dado que tenemos pruebas unitarias que pueden desenmascararlos.
Proceso de desarrollo de pruebas unitarias.
Esta metodología ha levantado bastante polémica dentro del mundo de la ingeniería del software en cuanto a los beneficios que proporciona y los límites que sobrepasa más allá de la programación tradicional. Es por esto que hay una gran diversidad de opiniones acerca de las desventajas que puede conllevar el uso de este sistema de programación.
  • En primer lugar el hecho de escribir todos los requerimientos al inicio podría provocar el abuso en la cantidad de los elegidos con el fin de evitar dejar en el olvido alguno.
  • A veces sucede que las propias pruebas unitarias resultan más costosas, desde el punto de vista de la implementación, que la propia implementación del software que se pretende crear, ya que a veces puede resultar más dificultoso encontrar los posibles fallos en los que puede caer la aplicación que la codificación de la misma.
  • Si los casos de prueba que se crean son incorrectos entonces se implementará un código incorrecto, esto en principio sería bastante grave ya que se crearía una aplicación que no tendría el valor que uno esperaba al inicio.
  • Es un sistema de desarrollo que no permite la creación de nuevos algoritmos.
Debido al gran éxito que esta metodología está teniendo en el mundo de la ingeniería del software, son muchas y variadas las herramientas que se han ido desarrollando hasta día de hoy. Algunas han surgido en forma de frameworks, otras en formato plug-in bajo el control de algún browser o incluso como librerías para su uso en plataformas de programación.

En mi caso, utilizaré una herramienta llamada JUnit, este es el framework más importante con que cuenta la metodología TDD (Test-driven Development ), de él han ido surgiendo la mayoría de los frameworks del conjunto de los xUnit. Su importancia seguramente radica en que está basado en el lenguaje java que es un lenguaje muy ágil, reusable y adaptable a otros lenguajes y plataformas.

JUnit es utilizado para testear funcionalidades sobre si funcionarán correctamente o no a través de funciones que ya trae consigo el propio framework, como runners para ejecutar directamente los test o asserts para comprobar la validez de los resultados.

Para instalar JUnit seguimos estos pasos:
  1. Descargamos la librería d la pagina oficial: Aquí.
  2. Descomprimimos el zip en cualquier directorio.
  3. Añadir junit.jar al CLASSPATH. Esta operación puede ser diferente según la máquina de que se trate. Por ejemplo, las máquinas arnelaxx tienen el CLASSPATH configurado (bajo linux) por el administrador y no tienes que hacer nada. En cambio, en la máquina java debes añadir la siguiente línea al fichero .profile del directorio principal de tu usuario y luego volver a conectarte:
    export CLASSPATH=$CLASSPATH:/usr/java13_64/lib/fic/junit.jar:.
En caso de utilizar una IDE como Eclipse (mi caso) ya viene incluido la librería de JUnit. Lo único que hay que hacer es abrir la vista de explorador de proyectos, aquí hacer clic con el botón derecho en la clase Test en concreto, en el menú que aparece elegir "Run as" -> "JUnit Test".


En caso que no se encuentre la librería, una vez descargada solo hay que agregarla. Para añadir un jar externo a nuestro proyecto con Eclipse seguimos los siguientes pasos:
  • Con el botón derecho del ratón sacamos el menú sobre el proyecto y elegimos "propiedades"
  • En la ventana que se abre, en el arbolito de la izquierda elegimos "java build path".
  • En el lado derecho de la ventana, elegimos la pestaña "Libraries"
  • Le damos al botón "add external jar"
  • Buscamos el jar que queremos añadir y lo seleccionamos.
  • Aceptar, aceptar, aceptar
y listo, ese jar ya forma parte de nuestro proyecto Eclipse y podemos usarlo en nuestro programa.
 
Con esto corremos la aplicación como una simp'le aplicación java desde Eclipse.

Las puebas se llevaran a cabo en la entrada de taller.

lunes, 11 de abril de 2011

[TALLER] Manejo de eventos, excepciones y errores

En esta entrada mostrare las excepciones en mi proyecto y una breve descripción del porqué se utilizan.

Exception:

public Database(){
  try{
   Class.forName(drv);
   ct =DriverManager.getConnection(db, user, pword);
   st =ct.createStatement();
   System.out.println("Conección exitosa.");
  }catch(Exception e){
   System.out.println("No se pudo conectar a la base de datos.");
  }
 }

En el código anterior se muestra un constructor utilizado para hacer conexión con la base de datos. Todo el código va dentro de un "try" y después un "catch" con una excepción y un mensaje al usuario.

La excepción es del tipo Exception ya que se utiliza la clase Class que solo puede aceptar un tipo de excepción general.

SQLException:

public void showAll(String matt, String pass) {
  String dia = new String();
  Scanner a = new Scanner(System.in);
  System.out.println("Introduzca un dia (Lu, Ma, Mi, Ju, Vi, Sa): ");
  dia = a.next();
  dayselection = dia;
  try{
   do{
    stmt = ct.prepareStatement("SELECT * FROM Alumnos, "+dia+" WHERE  Alumnos.idAlumnos = ? AND Alumnos.idPass = ? AND Alumnos.idAlumnos = "+dia+".idAlumnos");
    stmt.setString(1,matt);
    stmt.setString(2, pass);
    rs = stmt.executeQuery();
    if(rs.next()){
     System.out.println("Seleccione Horario: ");
     String sub = a.next();
     System.out.println(rs.getString(sub));
     subselection=rs.getString(sub);
     fill_data();
     rs.close();
    }
    else{
     System.out.print("Error");
     rs.close();
    }
   }while(rs.isClosed()==false);
  }catch(SQLException e){
   System.out.println("No se pudo realizar la consulta.");
  }
 }

En el código anterior se muestra un método para obtener información de una base de datos a partir de un usuario y una contraseña. Todas las consultas de SQL deben de ir en un try y acompañadas de un catch. En este caso es una excepción del tipo SQLException, que provee información sobre algún error de conexión a la base de datos, en este caso manda al usuario un mensaje de error diciendo que no se pudo conectar a la base de datos.

public void fill_data(){
  try{
   stmt = ct.prepareStatement("SELECT * FROM "+subselection+", "+dayselection+" WHERE "+dayselection+".idAlumnos = "+subselection+".idAlumnos");
   rs = stmt.executeQuery();
   while(rs.next()){
    for(int i=2; i<=9; i++){
     phrs(i);
     if(rs.getString(i) == null){
      System.out.println("Sin Datos");
     }
     else{
      System.out.println(rs.getString(i));
     }
    }

   }
  }catch(SQLException i){
   System.out.println("No tiene materia asignada en ese horario.");
  }
 }

En este caso sucede lo mismo ya que se desea realizar una consulta, este método se encarga de mostrar materias habiendo introducido un horario, de haber un error en la consulta, significa que no existe una materia en el horario seleccionado, de haber cualquier otro tipo de error, el programa jamas habría llegado a este punto.

IOException:
public static void main(String[] args) throws IOException{
  
  boolean selec=true;
  Horario h = new Horario();
  
  Console terminal = System.console();
        if (terminal==null ) {
            System.err.println("No puedo obtener la consola.");
            return;
        }
  String mat = new String (terminal.readLine("Ingresar Usuario: "));
  String pass= new String (terminal.readPassword("Ingresar contraseña: "));
  while(selec == true|| selec ==true){
   h.showAll(mat, pass);
   System.out.print("¿Desea ver otra materia?(S/N): ");
   char sel= (char) System.in.read();
   
    switch(sel) {
    case 's': 
     selec = true;
        break;
        
    case 'S':
     selec=true;
     break;
    
    default:
     selec = false;
        break;
   }
   
   
  }
 }

Existe otra forma de expresar un error, lanzando directamete una excepción sin un try y catch. Este es el método main, y la palabra seguida "throws" que significa lanza, que literalmente lanza una excepción de tipo IOException, es utilizada para mostrar información de errores de entrada y salida.

En este caso, la clase Console siempre debe de ser acompañada de este tipo de excepciones, ya que si se ejecuta el programa desde un lugar distinto de la consola, este lanzara un mensaje de error.

Eventos, excepciones y errores

En esta entrada explicare que son los eventos, errores y excepciones.

Eventos:

Los eventos son todas las acciones que el usuario inicia, dar clic sobre un botón, presionar las teclas del teclado, etc. Cada vez que se produce un evento, se crea un objeto. La clase padre de los eventos es "java.awt.event".

Cada lenguaje de programación tiene su propio modelo de eventos, en Java se definen clases auxiliares llamadas escuchadores (listeners) que reciben eventos específicos.

Los escuchadores se registran en las fuentes de eventos (teclado, ratón, etc). Estas envían objetos del tipo EventObjet la los escuchadores registrados al producirse un evento. Cada escuchador utiliza la información recibida a través del objeto para realizar las acciones adecuadas.

Dentro de "java.awt.event", los eventos están categorizados dentro de una jerarquía de clases.
  • La clase "java.util.EventObject" es la clase base de todos los
    eventos en Java.
  • La subclase "java.awt.AWTEvent" es la clase base de todos los
    eventos que se utilizan en la construcción de GUIs.
  • Cada tipo de evento "xxEvent" tiene asociada una interfaz "xxListener" que es la que nos permite definir escuchadores de eventos.
  • Para simplificar la implementación de algunos escuchadores de eventos, el paquete "java.awt.event" incluye clases base xxAdapter que implementan las interfaces xxListener.
Existen distintos tipos de eventos, los cuales son:

Eventos de Ventana

Son los que se generan en respuesta a los cambios de una ventana, un frame o un dialogo.
  •     WINDOW_DESTROY
  •     WINDOW_EXPOSE
  •     WINDOW_ICONIFY
  •     WINDOW_DEICONIFY
  •     WINDOW_MOVED
Eventos de Teclado

Son generados en respuesta a cuando el usuario pulsa y suelta una tecla mientras un Componente tiene el foco de entrada.
  •     KEY_PRESS
  •     KEY_RELEASE
  •     KEY_ACTION
  •     KEY_ACTION_RELEASE
Eventos de Ratón

Son los eventos generados por acciones sobre el ratón dentro de los límites de un Componente.
  •     MOUSE_DOWN
  •     MOUSE_UP
  •     MOUSE_MOVE
  •     MOUSE_ENTER
  •     MOUSE_EXIT
  •     MOUSE_DRAG
Eventos de Barras

Son los eventos generados como respuesta a la manipulación de barras de desplazamiento (scrollbars).
  •     SCROLL_LINE_UP
  •     SCROLL_LINE_DOWN
  •     SCROLL_PAGE_UP
  •     SCROLL_PAGE_DOWN
  •     SCROLL_ABSOLUTE
Eventos de Lista

Son los eventos generados al seleccionar elementos de una lista.
  •     LIST_SELECT
  •     LIST_DESELECT
Eventos Varios

Son los eventos generados en función de diversas acciones.
  •     ACTION_EVENT
  •     LOAD_FILE
  •     SAVE_FILE
  •     GOT_FOCUS
  •     LOST_FOCUS
Errores:

Los errores en la programación suelen ser comunes, ya que es casi imposible programar sin que exista un solo error, inclusive en productos finales existen errores de software, que casi siempre tratan de corregir con parches de seguridad y actualizaciones.

En algún momento por alguna causa, podría generarse algún conflicto en el programa. Ya sea porque no hay conexión a Internet, usuario o contraseña incorrecta, valores alfanuméricos en campos solo para números, y en algunos casos el código del programa no esta escrito correctamente, sin embargo, este ultimo se analizara en el siguiente tema (Diseño de pruebas unitarias).

Existen formas para detectar y corregir errores en un programa por medio de opciones alternativas llamadas excepciones.


Excepciones:

Las excepciones en Java están destinadas, al igual que en el resto de los lenguajes que las soportan, para la detección y corrección de errores.

Si hay un error, la aplicación no debería morirse y generar un core . Se debería lanzar (throw) una excepción que nosotros deberíamos capturar (catch) y resolver la situación de error.

Existen muchos tipos de excepciones,casi una por cada tipo de error, por lo que si tenemos error de entrada/salida de datos, el programa deberia de lanzar una excepción de tipo IOException.

En Java, cada excepción es una clase hija de "java.lang.Exception", por lo que podemos crear nuestras propias excepciones en lugar de utilizar las ya predefinidas.


En este gráfico podemos ver algunos de los errores y excepciones dentro de la clase Throwable que extiende de Object y tiene como hijas a Error y Exception.

jueves, 31 de marzo de 2011

[TALLER] Aplicación de patrones de diseño en proyectos individuales

Ahora la implementación de los patrones de diseño, primero comenzare con el Singleton, que recordemos, es para crear objetos solo dentro de la misma clase.

Si en el diagrama no se ve el constructor es por que en este patrón se declara con atributo privado. Aquí el código:

package Organidatabase;

import java.util.Scanner;

public class Notas{
 
 private Notas nuevo = new Notas();
 String nota;
  
  private Notas () {
          System.out.println("Escriba su nota: ");
          Scanner a = new Scanner(System.in);
          nota=a.next();
     }
  
  public Notas new_note() {
   return nuevo;
  }


}
Podemos ver en el código que la creación de un nuevo objeto se restringe solamente a su clase.

Ahora veremos la clase Eventos, donde pretendo utilizar el patrón de diseño Composite.

Puede notarse que en la clase Eventos se están aplicando dos patrones de diseño como lo había dicho en mi entrada de clase, aplican ambas.

package Organidatabase;   
import java.util.ArrayList;
   import java.util.Scanner;

   public abstract class Eventos extends Database{
    String dia;
    String mes;
    String año;
    String hora;
    String lugar;
     
     public Eventos (String dia, String mes, String año, String hora, String lugar) {
      this.dia = dia;
      this.mes = mes;
      this.año = año;
      this.hora = hora;
      this.lugar = lugar;
     }
     
     public abstract void new_event(Eventos e);
       
   }

   abstract class Ev_priv extends Eventos{
    
    private ArrayList hijo = new ArrayList();
    public Ev_priv(String dia, String mes, String año, String hora, String lugar){
     super(lugar, hora, año, mes, dia);
    }
    
    public void new_event(Ev_priv e){
      hijo.add(e);
      System.out.print("Introduzca un fecha: ");
    Scanner a = new Scanner(System.in);
    dia=a.next();
    mes=a.next();
    año=a.next();
    System.out.print("Introduzca la hora: ");
    hora=a.next();
    System.out.print("Introduzca el lugar: ");
    }
}

   abstract class Ev_pub extends Eventos{
     
     ArrayList hijo = new ArrayList();
     public Ev_pub(String dia, String mes, String año, String hora, String lugar){
      super(lugar, hora, año, mes, dia);
     }
     
     public void new_event(Ev_pub e){
       hijo.add(e);
       System.out.print("Introduzca un fecha: ");
     Scanner a = new Scanner(System.in);
     dia=a.next();
     mes=a.next();
     año=a.next();
     System.out.print("Introduzca la hora: ");
     hora=a.next();
     System.out.print("Introduzca el lugar: ");
     }
   }
Por ahora estos son los patrones de diseño que utilizo, sin embargo me he dado cuenta que podemos utilizar muchos patrones en un mismo proyecto por lo que tal vez estos no sean los unicos.

Patrones de diseño


Esta semana hablamos sobre patrones de diseño. Primero que nada, un patrón de diseño es una base para alguna solución especifica para problemas típicos en el desarrollo de software. 

Existen tres tipos de patrones de diseño, los creacionales, los estructurales y los de comportamiento.

Patrones creacionales.

Los patrones creacionales soportan la tarea mas común que tiene la programación orientada a objetos: La creación de las instancias de objetos en un sistema.

Ejemplo - Singleton:
Segun wikipedia:

"El patrón de diseño singleton (instancia única) está diseñado para restringir la creación de objetos pertenecientes a una clase o el valor de un tipo a un único objeto.
Su intención consiste en garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella."

El patrón Singleton se implementa mediante una clase con un constructor privado. Existirá un método que creará una instancia del objeto llamando al constructor sólo si todavía no existe ninguna.

A pesar de que es ampliamente utilizado, existe una corriente contraria al uso de este patrón debido a los problemas que introduce.

  • Los Singletons normalmente se usan para proporcionar un punto de acceso global para un servicio.
  • Los Singletons permiten limitar la creación de los objetos.
  • Los Singletons promueven el acoplamiento fuerte entre clases.
  • Los Singletons mantienen el estado hasta la finalización del programa.


Patrones estructurales.

Los patrones estructurales están relacionados con cómo las clases y los objetos se combinan para dar lugar a estructuras más complejas.

Ejemplo - Composite:
Segun wikipedia:

"El patrón Composite sirve para construir objetos complejos a partir de otros más simples y similares entre sí, gracias a la composición recursiva y a una estructura en forma de árbol.
Esto simplifica el tratamiento de los objetos creados, ya que al poseer todos ellos una interfaz común, se tratan todos de la misma manera."

Compone objetos dentro de unas estructura arborescente con el que se representa una jerarquía parte-todo. El uso de este patrón permite tratar objetos individuales y composiciones uniformemente.

La utilización de recursos podría ser un problema, utiliza una estructura de tipo recursiva que podría generar un alto consumo de memoria, sin embargo fue pensado para tareas no repetitivas.

Esto ultimo debido a que el objeto complejo es independiente de los mas simples una vez creado.

Patrones de comportamiento.

Estos patrones de diseño están relacionados con algoritmos y asignación de responsabilidades a los objetos. Los patrones de comportamiento describen no solamente patrones de objetos o clases sino también patrones de comunicación entre ellos.

Ejemplo - Command:
Según wikipedia:

“Este patrón permite solicitar una operación a un objeto sin conocer realmente el contenido de esta operación, ni el receptor real de la misma. Para ello se encapsula la petición como un objeto, con lo que además se facilita la parametrización de los métodos.”

Encapsula peticiones como objetos, así permite parametrizar clientes con diferentes peticiones, auditar peticiones y deshacer operaciones. El Patrón permite:
  • Encapsular un mensaje como un objeto, con lo que podemos gestionar colas o registros de mensajes y deshacer operaciones.
  • Soportar restaurar el estado a partir de un momento dado.
  • Ofrecer una interfaz común que permita invocar las acciones de forma uniforme y extender el sistema con nuevas acciones de forma más sencilla.
Proyecto.


De estos patrones, puedo utilizar perfectamente el patrón Singleton:


La clase Eventos.java se utiliza para crear eventos del usuario, mediante el Singleton aseguramos que solo exista una sola instancia, ya que mantiene su estado asta la finalización del programa, los eventos se mantienen, y el uso limitado de objetos asegura su creacion y despues guardarlo en la base de datos.


La clase Notas.java aplica perfectamente, ya que su unico proposito es el de guardar texto en una base de datos.


Oviamente el patrón Composite queda perfectamente en la clase Eventos.java, puedo generar objetos de distintos tipos como lugar, fecha, hora, cada uno de estos objetos se obtienen de algun metodo, basandose en la fecha actual del sistema o la hora, o bien seleccionando de una lista el lugar. Unidos estos puedo generar un objeto de tipo evento compuesto de varios objetos mas simples.


Algunas clases mas complejas como Database.java (encargada de conección con la base de datos) o el propio main, pueden utilizar de una manera sencilla el patrón Command, ya que mantiene en memoria el usuario activo, de esta manera al seleccionar otra materia no habra que introducir de nuevo un usuario ni contraseña, ni volvera a reconectar a la base de datos para obtener información.

jueves, 24 de marzo de 2011

Presentaciones de diagramas de proyectos

Video explicativo sobre los diagramas de clases y de secuencia de mi proyecto:

[TALLER] Implementación de proyectos individuales

En esta entrada, explicare la función de mi programa a estas alturas, despues de un tiempo logre que funcionara, aunque para esta ocación, he modificado un poco el diseño para que funcione adecuadamente, ya que aún falta código.

Bueno, para empezar queria comentar que mi programa puede funcionar solo con la clase "Database", que es la que se encarga de conectar la base de datos, ya que la mayoria de las clases son solo para acomodar la información de una manera más organizada, por lo que necesita más código y tiempo, sin embargo utilizar la consola me ahorra ese codigo y mi programa sigue igual de funcional.



En esta imagen se muestra la ruta de mi programa, como pueden ver es un .jar, una ventaja de tener un .jar es que no necesita una orden específica, solo es correr el ejecutable y ya.



Como muestra la imagen antrior, la primer función de este programa es buscar un usuario y contraseña para acceder a los datos, el programa compara los strings dados por el usuario con la columna ya designada, puesto que el nombre de usuario es un número único, solo habra una coincidencia.

Lo siguiente sera comparar el string de contraseña, que para esto deberá esta en la misma fila que el nombre de usuario.


Seleccionamos un día de la semana que aparece en el programa y lo introducimos, lo siguiente sera seleccionar el horario de la materia. Se supone que esto es respetando minusculas y mayusculas, pero por alguna razón aveces no es necesario hacer esto, podemos introducir el dia y el horario sin respetar mayusculas.


Se puede observar que se ven todos los datos al dar enter, y despues pide si queremos repetir el proceso,
utilizando un while, una variable booleana y un switch logré hacer esto.

Aqui esta el código utilizado para este programa:

package Organidatabase;

import java.io.Console;
import java.io.IOException;

import javax.swing.UIManager;

public class Main {

 public static void main(String[] args) throws IOException{
  
  boolean selec=true;
  
  Console terminal = System.console();
        if (terminal==null ) {
            System.err.println("No puedo obtener la consola.");
            return;
        }
        
  Database db = new Database();
  String mat = new String (terminal.readLine("Ingresar Usuario: "));
  String pass= new String (terminal.readPassword("Ingresar contraseña: "));
  
  while(selec == true|| selec ==true){
   db.showAll(mat, pass);
   System.out.print("¿Desea ver otra materia?(S/N): ");
   char sel= (char) System.in.read();
   
    switch(sel) {
    case 's': 
     selec = true;
        break;
        
    case 'S':
     selec=true;
     break;
    
    default:
     selec = false;
        break;
   }
   
   
  }
 }
 
}
package Organidatabase;

import java.sql.*;
import java.util.Scanner;

public class Database {
 
 Alias a = new Alias();
 
 String aux;
 String aux2;
 
 PreparedStatement stmt = null;
 ResultSet rs=null;
 
 public final static String drv ="com.mysql.jdbc.Driver";
 public final static String db ="jdbc:mysql://localhost:3306/Organischema";
 public final static String user ="???";
 public final static String pword="???";
 
 Connection ct;
 public Statement st;

 public String dayselection;
 public String subselection;
 
 public Database(){
  try{
   Class.forName(drv);
   ct =DriverManager.getConnection(db, user, pword);
   st =ct.createStatement();
   System.out.println("Conección exitosa.");
  }catch(Exception e){
   System.out.println("No se pudo conectar a la base de datos.");
  }
 }
 
 public void showAll(String matt, String pass) {
  String dia = new String();
  Scanner a = new Scanner(System.in);
  System.out.println("Introduzca un dia (Lu, Ma, Mi, Ju, Vi, Sa): ");
  dia = a.next();
  dayselection = dia;
  try{
   do{
    stmt = ct.prepareStatement("SELECT * FROM Alumnos, "+dia+" WHERE  Alumnos.idAlumnos = ? AND Alumnos.idPass = ? AND Alumnos.idAlumnos = "+dia+".idAlumnos");
    /*String matt = a.next();
    String pass = a.next();*/
    stmt.setString(1,matt);
    stmt.setString(2, pass);
    rs = stmt.executeQuery();
    if(rs.next()){
     System.out.println("Seleccione Horario: ");
     String sub = a.next();
     System.out.println(rs.getString(sub));
     subselection=rs.getString(sub);
     fill_data();
     rs.close();
    }
    else{
     System.out.print("Error");
     rs.close();
    }
   }while(rs.isClosed()==false);
  }catch(Exception e){
   System.out.println("No se pudo realizar la consulta.");
  }
 }
 
 public void fill_data(){
  try{
   stmt = ct.prepareStatement("SELECT * FROM "+subselection+", "+dayselection+" WHERE "+dayselection+".idAlumnos = "+subselection+".idAlumnos");
   rs = stmt.executeQuery();
   while(rs.next()){
    for(int i=2; i<=9; i++){
     a.phrs(i);
     if(rs.getString(i) == null){
      System.out.println("Sin Datos");
     }
     else{
      System.out.println(rs.getString(i));
     }
    }

   }
  }catch(SQLException i){
   i.printStackTrace();
  }
 }
 
 public Statement getSt(){
  return st;
 }

}
Las palabras como "Profesor" o "Calificación" son distintos alias, esto quiere decir que los nombres de las columnas en la base de datos tienen nombres cortos, y con una clase temporal logre colocar estos alias a base de condiciones.
package Organidatabase;

import java.util.*;

public class Alias {
 Database d;
 int dia;
 public Alias(){
  
 }
 
 public void phrs(final int a){
  
  if(a==2)
   System.out.print("Profesor: ");
  if(a==3)
   System.out.print("Examen 1: ");
  if(a==4)
   System.out.print("Examen 2: ");
  if(a==5)
   System.out.print("Faltas: ");
  if(a==6)
   System.out.print("Tareas: ");
  if(a==7)
   System.out.print("Tareas no cumplidas: ");
  if(a==8)
   System.out.print("Total de tareas: ");
  if(a==9)
   System.out.print("Promedio: ");
 }

 public int day(){
  final Calendar calendario = Calendar.getInstance();
  dia =calendario.get(Calendar.DAY_OF_WEEK);
  return dia;
 }
 

}
Esta clase temporal vendria sustituyendo las clases que ya tenia planteadas, ya que lo unico que se supone que harían es mostrar información en una interfaz grafica y acomodarla.
Aqui hay un video demostrando el funcionamiento del programa:

jueves, 24 de febrero de 2011

[TALLER]Especificación técnica de proyectos individuales

Las personas, generalmente alumnos, necesitan de un organizador para hacer las cosas de una forma ordenada y a tiempo. Utilizar agendas es bueno pero no muy cómodo, puesto que la juventud demanda tecnología, para ellos es mejor realizar esto desde la comodidad de su PC.

Entre las ventajas de utilizar este programa se encuentran:
  • Tareas siempre organizadas y a tiempo ya sea en equipo o individual.
  • Mantiene actualizada la evaluación del alumno.
  • Recibe notificaciones de los profesores o de compañeros.
  • Muestra el horario y materia en la que se debería estar en ese momento.
Aspectos generales:

En general este programa muestra información relevante sobre semestre cursado, además cuenta con un practico visor de horario académico, el cual muestra la hora y el lugar actual donde se debería estar. Analizando cada aspecto tenemos que:

Horario: Es la zona donde nosotros vemos nuestro horario. El horario varía en función del día actual, por lo que siempre estará actualizado, esto es determinado con funciones que operan sobre fechas en Java. Además cada celda en la que se encuentran los distintos horarios del día funcionan como botones de acceso a información sobre la materia inscrita en el horario. Por defacto el horario seleccionado es el primero que aparece.

Materia: La parte principal del programa. Nos muestra información de la materia en general, un resumen de las evaluaciones, y un botón que muestra el resto de la información. El programa ya tiene asignadas las evaluaciones que normalmente se utilizan, pero si el profesor utiliza otro tipo de evaluaciones, entonces tiene la opción "Otras evaluaciones", que básicamente muestra información generalizada de datos que no están presentes en el programa.

Notas (antes novedades): Una de las opciones que se tiene es la de Notas, cada persona con acceso a el programa puede enviar notas a sus compañeros, donde hay de dos tipos:
  • Notas publicas: La persona publica una nota y todos los que tengan en común el mismo horario podrán visualizar la nota.
  • Notas privadas: La persona puede enviar notificaciones al profesor, a un alumno, o a un equipo en especifico sin importar el horario.


Eventos: Al seleccionar un horario libre, en lugar de aparecer la información de materia, aparecerán varios campos para agregar un evento en los que se puede involucrar a una persona o un equipo siempre y cuando estos tengan el mismo horario libre.


Aspectos técnicos:
  • Utiliza una base de datos basada en los sistemas adminisrativos de siempre (SIASE, NEXUS).
  • Java como base para su programación, lo que lo convierte en multiplataforma.
  • Interfaz simplista y agradable para el usuario.
  • Dependiendo de si el usuario es profesor o estudiante, la interfaz cambia para edición de calificaciónes(para profesores).
Concluciones:

Puesto que es un programa para PC, y se trata de un organizador, lo mas recomendabe para mi es utilizar plataformas moviles, pero por motivos de tiempo solo será para PC, sinembargo pienso continuar aportando más a este proyecto, ya que ha sido de interes para mi desde que inicie con materias de programación.

Dudas o comentarios todos son bienvenidos.

jueves, 17 de febrero de 2011

[TALLER] Documentación y herramientas avanzadas de desarrollo

La documentación la genere utilizando la herramienta que mencioné anteriormente.

Aquí se encuentra alojada la documentación de mi proyecto:

http://victoralex-poo.net76.net/

miércoles, 16 de febrero de 2011

Documentación y herramientas de desarrollo

La documentación de un código es una forma de mantener legible éste mediante etiquetas. Ademas podemos continuar  con el trabajo sin tener que revisar a fondo el codigo, muy util si se trata de un trabajo muy largo. Independientemente del lenguaje en que trabajamos, la documentacion es necesaria y esta disponible para todos los lenguajes conocidos.

Para generar la documentación en Java es necesaria la herramienta llamada "javadoc", incluida en el JDK, que nos generará un .html de las etiquetas dentro del código.

Éstas etiquetas son:

/**
 *Descripcion de la clase
 */
public class clase{
}

Donde lo que va entre /** y */ es la descripción de la clase.

Tambien existen tags para agregar información de variables, autor, versión, etc.

@author Donde se coloca el nombre del desarrollador.

@deprecated Indica que un método o clase es antigua y no se reco mienda su uso.

@param Es la definición de un parametro de un método.

@return Informa lo que devuelve el método.

@see Asocia con otro método o clase.

@throws Excepción lanzada por el método.

@version Versión del método o clase.

Con Eclipse podemos generar la documentación de la siguiente manera:

Abrimos el menú "Project" y damos clic en "Generate Javadoc..."

Se abrirá una ventana como la iguiente:


Tildeamos la carpeta de nuestro proyecto y elegimos "private" para que genere documentación de todas las clases. Damos clic en finish.

Por ultimo nos genera una serie de documentos .html que es la documentación de nuestro proyecto.