lunes, 28 de noviembre de 2011

Ordenar usando la interface Comparable

En este post revisaremos una duda que recibimos. El objetivo es leer un archivo que contiene en cada línea datos que representan una instancia. Por ejemplo el siguiente archivo (productos.txt) contiene:

555 Producto1 200 3
333 Producto2 300 1
222 Producto3 400 2
111 Producto4 150 5

Para representar un producto, creamos una clase Producto que contiene un id, nombre, precio y cantidad en inventario. Y deseamos ordenarlo por id del producto. El tip es que la clase Producto debe implementar la interface Comparable para que podamos comparar entre productos y de esta forma puedan ser ordenados.

El siguiente código muestra cómo ordenar el archivo anterior (copiar el código en un archivo con nombre OrdenarArchivo.java), los pasos son muy sencillos:

  1. leemos cada línea del archivo y la dividimos en los campos de un producto (se asume que los campos están separados por un espacio en blanco);
  2. creamos una instancia de Producto y la agregamos a una lista de Productos;
  3. ordenamos la lista usando Collections.sort

Es importante notar que tras bambalinas Collections.sort está usando el método compareTo (de la interface Comparable) que implementamos en la clase Producto. Al ejecutar el código debe imprimir:

Elementos originales:
[555 Producto1 200.0 3, 333 Producto2 300.0 1, 
222 Producto3 400.0 2, 111 Producto4 150.0 5]
Elementos ordenados:
[111 Producto4 150.0 5, 222 Producto3 400.0 2, 
333 Producto2 300.0 1, 555 Producto1 200.0 3]

OrdenarArchivo.java

import java.io.*;
import java.util.*;

public class OrdenarArchivo{
  public static void main(String [] args){
    String filename = "productos.txt";
    String linea = null;
    String[] datos = null;
    List<Producto> productos = new ArrayList<Producto>();
    Producto producto = null;
    try{
      BufferedReader br = new BufferedReader(
                           new FileReader(filename)); 
      // leer todas la lineas del archivo
      while((linea=br.readLine())!=null){
        // cada linea tiene los datos para crear un producto
        datos = linea.split(" ");
        producto = new Producto(
                    Integer.parseInt(datos[0]),
                    datos[1],
                    Double.parseDouble(datos[2]),
                    Integer.parseInt(datos[3]));
        // agregamos el producto a la lista de productos
        productos.add(producto);
      }
      br.close();
      // imprimir archivo en orden original
      System.out.println("Elementos originales:");
      System.out.println(productos);
      Collections.sort(productos);
      // imprimir archivo ordenado
      System.out.println("Elementos ordenados:");
      System.out.println(productos);
    }catch(IOException e){
      System.out.println(e);   
    }
  }
}

// Clase que representa lo que queremos ordenar
// Notar que estamos implementado Comparable
class Producto implements Comparable<Producto> {
  int id;
  String nombre;
  double precio;
  int inventario;
  
  public Producto(int id, String nombre, 
                  double precio, int inventario){
    this.id = id;
    this.nombre = nombre;
    this.precio = precio;
    this.inventario = inventario;
  }
  
  public String toString(){
    return id + " " + nombre + " " + 
           precio + " " + inventario;
  }
  
  // Este metodo es el que nos permite comparar
  // entre productos y de esta forma puedan ser ordenados.
  public int compareTo(Producto p){
    return id - p.id;
  }
}

sábado, 26 de noviembre de 2011

Modificadores en Java

A continuación podrán encontrar una tabla que resume en dónde es válido usar varios modificadores en Java. Por ejemplo una clase normal (es decir no anidada en otra clase o método) sólo tiene dos modificadores de acceso válidos: public y default; una clase anidada en otra clase (ya sea estática o no estática) puede usar private, default, protected, public; y una clase definida dentro de un método no puede usar modificadores de acceso.

Modificadores en Java.

Si encuentran algún error, por favor repórtenlo en los comentarios.

lunes, 14 de noviembre de 2011

CyArk: preservación digital de nuestro pasado

CyArk (Cyber Archive o Ciber Archivo) es una organización sin fines de lucro cuyo objetivo es la preservación digital de sitios considerados como patrimonio histórico y cultural de la humanidad.

La preservación de estos lugares se lleva a cabo mediante recursos de alta tecnología entre los cuales se encuentra el uso del escaneo a través de láser en 3D, lo que produce una serie de puntos que son transformados a una imagen tridimensional del área escaneada y cuya precisión se encuentra entre los 2 y 3 mm. El escaneo se lleva a cabo en cuestión de minutos y los datos que son colectados se utilizan para producir representaciones espectacularmente precisas de los sitios escaneados.

Actualmente, CyArk está llevando a cabo proyectos de preservación en varios lugares alrededor del mundo y México no es la excepción. En nuestro país, se han llevado a cabo proyectos sumamente interesantes en las ciudades mayas de Chichén Itzá, Tikal, la capital zapoteca Monte Albán, así como un proyecto en progreso para preservar Teotihuacán, la Ciudad de los Dioses.

CyArk es un proyecto que merece la pena dar a conocer y más aún cuando se cuenta con hermosos sitios dignos de preservación para conocimiento y goce de las futuras generaciones. En México somos afortunados porque existe una gran variedad de estos lugares y vale la pena saber que se están realizando esfuerzos para preservarlos.

Visiten el sitio de CyArk, entérense de la maravillosa obra de esta organización y de alguna manera, comencemos a involucrarnos.

CyArk lanza página web en español

Página principal de CyArk

Sitios de Patrimonio: Monte Albán

Información para contribuir con el proyecto de CyArk

Preservación digital de Chichén Itzá

jueves, 10 de noviembre de 2011

Recursos Java Recomendados

Durante los últimos meses me estuve preparando para la certificación de Programador Java (Oracle Certified Professional Java Programmer). Sin lugar a dudas el libro recomendado es SCJP Sun Certified Programmer for Java 6 por Katherine Sierra y Bert Bates. Sin embargo, algunos tópicos requirieron materiales extra. Aún cuando existe una cantidad abrumadora de recursos y tutoriales acerca de Java, me gustaría compartir cuatro de los sitios que fueron de gran ayuda durante mi preparación.

1) Especificación de la API de Java

Fue de gran ayuda para estudiar métodos y parámetros, por ejemplo de las clases “Wrapper” (Integer, Double, Long, …). Además siempre que estemos desarrollando en Java debemos tener a la mano esta API.

2) Jdocs

El propósito de este sitio es presentar una versión aumentada de la tradicional API de Java. Lo que realmente me ayudó es que también permite visualizar el código fuente. Con ello entendí más detalles acerca del comportamiento de varias clases, en una ocasión lo usé para ver cómo estaban implementados los métodos equals, compareTo y hashCode de la clase Integer.

3) Vídeo Tutoriales por Clive Scott

Si son más del tipo de aprender a través de vídeo tutoriales, este sitio les fascinará. En youtube hay muchos tutoriales Java que generalmente cubren aspectos básicos o introductorios. Esta página presenta un compendio de vídeos que cubren a profundidad temas como overriding, overloading, clases anidadas, modificadores de acceso, entre otros. Si acabas de tomar alguna clase básica o intermedia de Java, estos tutoriales son de gran ayuda para repasar y profundizar varios temas. Altamente recomendable.

4) Tutoriales en mindprod.com

Este sitio contiene tutoriales que cubren tópicos con gran detalle. Por ejemplo, el tutorial acerca de la operación módulo menciona qué pasa si uno de los operandos es negativo (-10%4, 10%-4, -10%-4), presenta un par de tablas para poder comparar el módulo en java vs. el módulo de acuerdo a su definición matemática y menciona ejemplos de la utilidad de este operador. El tutorial de clases anidadas, además de conceptos básicos, tiene una tabla para mostrar los modificadores de acceso válidos para los diferentes tipos de clases y otra para mostrar las combinaciones de qué tipo de clases pueden heredar qué tipo de clases, por ejemplo una clase definida en un método sólo puede ser extendida por otra clase definida en el mismo método o una clase anónima en el mismo método. En general, un gran nivel de detalle con varios ejemplos.

5) Extra

Estos son algunos posts o tutoriales extras que también les recomiendo:

Por último, si alguien está interesado en certificarse les recomiendo los exámenes del sitio Whizlabs. Ofrece un examen de muestra. Y si deciden comprar el paquete de exámenes de práctica, les serán de gran utilidad ya que el nivel de dificultad es similar al examen de certificación. De hecho originalmente el examen tenía una duración de 3 horas, pero unos quince días antes de presentar mi examen, el tiempo límite cambió a 2.5 horas. Afortunadamente, gracias a los exámenes de práctica completé el examen de certificación en tiempo con 95% (57 de 60).

Espero que los recursos recomendados les sirvan y ayuden.

miércoles, 12 de octubre de 2011

Apuntes de la Unidad 2 de Matemáticas 5

En este apartado se encuentran los apuntes de la unidad 2 del curso de matemáticas 5 del Instituto Tecnológico de Toluca.

El examen de la segunda unidad abarca hasta donde aparece una nota dentro de los apuntes. Si existe alguna aclaración respecto a la legibilidad de éstos, no duden en comentarla.

Descargar apuntes dando click derecho y luego "Guardar como".

domingo, 2 de octubre de 2011

SQL Sakila: rentas por día

Nota: Para seguir mejor este ejemplo y ejecutar las consultas, les recomiendo seguir las instrucciones para configurar el ambiente de trabajo en la parte 1 del tutorial de SQL. Además, en el siguiente enlace pueden ver el modelo de Sakila versión 0.8.

En este ejemplo continuaremos usando la base de datos Sakila. El objetivo es obtener el promedio de rentas por día de la semana. Esto puede ser útil para lanzar una promoción en el día con menos rentas (por ejemplo: martes de 2x1).

Usaremos la tabla rental que tiene un registro por cada renta realizada. El campo que nos interesa es rental_date que es de tipo fecha (datetime). Primero, tenemos que obtener el día de la semana para esa fecha, es decir, a partir de “3 de Julio de 2011” debemos obtener “Domingo”. La función WEEKDAY es justo lo que necesitamos, retorna 0 para lunes, 1 para martes, ... 6 para domingo. La siguiente consulta retorna el día de la semana cuando se realizó la renta.

SELECT WEEKDAY(rental_date) AS wday FROM rental;

Ahora, todo lo que tenemos que hacer es agrupar y contar las ocurrencias para cada día de la semana.

mysql> select weekday(rental_date) as wday, count(*)
    -> from rental
    -> group by weekday(rental_date);

Noten que en la cláusula group by podemos usar el resultado de una función, en este caso weekday. La siguiente imagen muestra el resultado.

Podemos observar, que jueves es cuando se han realizado menos rentas en total con 2200. Noten que obtuvimos el total de rentas, pero ¿cómo podemos obtener el promedio por día? En otras palabras, hasta el momento sabemos que de todos los jueves en la tabla hay un total de 2200 rentas, pero no sabemos cuántas películas se rentan por jueves (por ejemplo, en un jueves se rentan normalmente 70 películas).

Recordemos que la tabla rental tiene una renta por registro. Lo primero que tenemos que hacer es agrupar las retas por día, es decir, una consulta que nos permita obtener: el 17 de Julio se realizaron 45 rentas. Sin embargo, un simple group by rental_date no funciona ya que rental_date contiene fecha y hora (dos rentas en el mismo día pero a diferente hora no serían agrupadas en el mismo día). Para ello utilizaremos la función DATE() que nos permite extraer sólo la fecha. La siguiente consulta agrupa por fecha.

mysql> select date(rental_date) as solo_fecha, count(*) as rentas 
    -> from rental 
    -> group by solo_fecha;

Ahora podemos agrupar por día de la semana y obtener un promedio. Además del promedio, también desplegamos el número de días y el total (es decir, el promedio por día x número de días, éste debe ser igual al total que obtuvimos en la primer consulta).

mysql> select weekday(solo_fecha) as wday, 
    ->        avg(rentas), count(*) as ndias, 
    ->        avg(rentas) * count(*) as total 
    -> from ( 
    -> select date(rental_date) as solo_fecha, count(*) as rentas 
    -> from rental 
    -> group by solo_fecha 
    -> ) agrupado_por_dia 
    -> group by wday;

La siguiente imagen muestra el resultado de la consulta.

En la primer consulta obtuvimos que el día con menos rentas en total era jueves; sin embargo, con esta consulta vemos que en promedio se rentan menos películas los martes. Esto se debe a que en la base de datos hay más días martes en comparación con el resto de los días.

Como pueden ver es posible manipular los datos de la base de diferentes formas para tener varias perspectivas de la misma información. Además existen muchas funciones predeterminadas que nos ayudan a transformar los datos, en este post vimos 2 funciones para la manipulación de fechas (DATE y WEEKDAY).

Compartan sus consultas favoritas de la BD Sakila o describan alguna consulta que les gustaría que explicáramos en un post.

sábado, 24 de septiembre de 2011

Ejercicios de Matemáticas V (Parte 2)

En este post podrán descargar la segunda parte de los ejercicios de Matemáticas 5 del Instituto Tecnológico de Toluca, semestre Agosto-Diciembre de 2011.

Estos ejercicios son los 4 problemas de aplicación que la profesora dictó el viernes pasado. Simplemente da click sobre el enlace que se presenta a continuación.

Descargar Ejercicios: problemas de aplicación