Thursday, March 25, 2010

Agenda mensual con calendario en PHP (III)

Esta es la clase para los días.

En este caso lo he limitado a un evento por día pero usando un array se puede modificar para recoger varios eventos por día.

/* Clase Dia */
class Dia
{   
    /* Miembros */
    private $perteneceAlMes; //Indica si pertenece al mes que muestra en el calendario
    private $numDia;         //Número del día en el mes
    private $diaSemana;      //Número del día de la semana
    private $evento;         //Objeto de la clase evento que contiene los datos asociados a un evento
    private $hayEvento;
    
    /* Constructor */
    public function __construct($diaSemana, $diaActual, $perteneceAlMes)  
    {

        //Pertenece al mes
        $this->setPerteneceAlMes($perteneceAlMes);
        
        //Día del mes
        if(!$perteneceAlMes)
        {
           $this->setNumDia(-1);
        }
        else
        {
           $this->setNumDia($diaActual);
        }
        
        //Día de la semana
        $this->setDiaSemana($diaSemana);
        
        //En principio no hay ningún evento
        $this->setHayEvento(false);
        
    }

    /* Métodos de acceso */
    public function setHayEvento($hayEvento) 
    {
        $this->hayEvento = $hayEvento;
    }
    
    public function getHayEvento() 
    {
        return $this->hayEvento;
    }
    
    public function setPerteneceAlMes($perteneceAlMes) 
    {
        $this->perteneceAlMes = $perteneceAlMes;
    }
    
    public function getPerteneceAlMes() 
    {
        return $this->perteneceAlMes;
    }

    public function setNumDia($numDia) 
    {
        $this->numDia = $numDia;
    }

    public function getNumDia() 
    {
        return $this->numDia;
    }
    
    public function setDiaSemana($diaSemana) 
    {
        $this->diaSemana = $diaSemana;
    }
    
    public function setEvento($evento) 
    {
        $this->evento = $evento;
        $this->setHayEvento(true); 
    }

    public function getEvento() 
    {
        return $this->evento;
    }
    
    public function muestraEvento()
    {
        $this->evento->muestraEvento();
    }
    
    /* Métodos */
    
    /* Muestra el HTML correspondiente a un día */
    public function muestraDia()
    {
        //Si el día pertenece al mes    
        if($this->getPerteneceAlMes())
        {
            //Si hay un evento en el día
            if($this->getHayEvento())
            {
                $numDia = $this->getNumDia();
                printf( "<td class =\"hayEvento\"<a href=\"#\" onClick=\"verEvento(%d)\">
                         %d</a></td>\n", 
                         $numDia, $numDia );                           
            }
            //Si no lo hay
            else
            {
                printf( "<td class=\"noHayEvento\">%d</td>\n", $this->getNumDia() );
            }
        }
        //Si el día no pertenece al mes
        else
        {
            printf("<td></td>\n");
        }
    }
}

Tuesday, March 23, 2010

Agenda mensual con calendario en PHP (II)

Esta clase la uso para los eventos de la agenda:
    
/* Clase Evento */
class Evento
{
    /* Miembros */
    private $referencia;
    private $nombre;
    private $fecha;
    private $hora;
    private $lugar;
    private $descripcion;
    
    /* Constructor */
    public function __construct($referencia, $nombre, $fecha, $hora, $descripcion, $lugar)  
    {
        $this->setReferencia($referencia);
        $this->setNombre($nombre);
        $this->setFecha($fecha);
        $this->setHora($hora);
        $this->setLugar($lugar);
        $this->setDescripcion($descripcion);
    }
    
    /* Métodos de acceso */
    public function getReferencia()
    {
        return $this->referencia;
    }
    
    public function setReferencia($referencia)
    {
        $this->referencia = $referencia;
    }
    
    public function getNombre()
    {
        return $this->nombre;
    }
    
    public function setNombre($nombre)
    {
        $this->nombre = $nombre;
    }
    
    public function getFecha()
    {
        return $this->fecha;
    }
    
    public function setFecha($fecha)
    {
        $this->fecha = $fecha;
    }
    
    public function getHora()
    {
        return $this->hora;
    }
    
    public function setHora($hora)
    {
        $this->hora = $hora;
    }
    
    public function getLugar()
    {
        return $this->lugar;
    }
    
    public function setLugar($lugar)
    {
        $this->lugar = $lugar;
    }
    
    public function getDescripcion()
    {
        return $this->descripcion;
    }
    
    public function setDescripcion($descripcion)
    {
        $this->descripcion = $descripcion;
    }
    
    /* Métodos */
    public function muestraEvento()
    {
       printf("%s \n", $this->getNombre());
       printf("Fecha: %s \n", $this->getFecha());
       printf("Hora: %s \n", $this->getHora());
       printf("Lugar: %s \n", $this->getLugar());
       printf("Descripción: %s \n",
                                              $this->getDescripcion());   
    }
}

Agenda mensual con calendario en PHP (I)

Hace poco hice un calendario en PHP para prácticar.

Estas son algunas de las clases que creé:

Esta es una clase con métodos estáticos que sirven para hacer diferentes cálculos con fechas.
/* Clase Fechas */
class Fechas
{
    /* Obtiene el día de la semana a partir del año, del mes y del día */
    public static function getDiaSemana($anyo, $mes, $dia)
    {               
        /*Módulos acumulados del número de días antes del inicio de mes para años normales y bisisestos*/
        $modMeses = array(0,3,3,6,1,4,6,2,5,0,3,5);
        $modMesesBis = array(0,3,4,0,2,5,0,3,6,1,4,6); 
        
        /*Se comprueba si el año es bisiesto para saber cual de los dos vectores anteriores usar*/
        if( 1 == Fechas::esBisiesto($anyo))
        {
            $dMes = $modMesesBis[$mes-1];
        }
        else
        {
            $dMes = $modMeses[$mes-1];
        }
        
        /*Se calcula el día de la semana correspondiente a la fecha*/
        $divEntera1 = (int) ( ($anyo - 1.0) / 4.0 ); 
        $divEntera2 = (int) ( ($anyo - 1.0) / 100.0 );
        $divEntera3 = (int) ( ($divEntera2 + 1.0) / 4.0 );
        $divEntera4 =(int) ( $divEntera1 - 3 * $divEntera3 );
        
        /*Fórmula del día de la semana*/
        $diaSemana = ( (($anyo - 1) % 7) + ($divEntera4 % 7) + $dMes + ($dia % 7)  ) % 7;
        
        /*El 0 corresponde al Domingo*/
        if( 0 == $diaSemana) 
        {
            $diaSemana = 7;
        }
        return $diaSemana; 
    }
    
    /* Calcula la semana del año a partir del día, el mes y el año */
    public static function getSemanaAnyo($anyo, $mes, $dia)
    {   
        //Valores de los días acumulados antes del principio de cada mes
        $ordinalesNormal=array(0, 31, 59,  90, 120, 151, 181, 212, 243, 273, 304, 334);
        $ordinalesBisiesto=array(0,  31,  60,  91, 121, 152, 182, 213, 244, 274, 305, 335);
        
        //Según el año sea bisiesto o no se usan unos valores u otros
        if( 1 == Fechas::esBisiesto($anyo))
        {
           $ordinal= $ordinalesBisiesto[$mes - 1];
        }
        {
           $ordinal= $ordinalesNormal[$mes - 1];
        }
        
        //Se calcula el día ordinal
        $ordinal = $ordinal + $dia;
        
        //Se obtiene el número del día de la semana correspondiente a la fecha (L=1,...,D=7)
        $diaSemana = Fechas::getDiaSemana($anyo,$mes,$dia);
        
        //Se calcula la semana del año
        $semanaAnyo=(int) (( $ordinal - $diaSemana + 10)/7);
        
        //Si es cero quiere decir que es la última semana del año anterior
        if($semanaAnyo == 0)
        {
            $semanaAnyo = 53;
        }
        //Si es 53 es la última semana del año anterior
        else if($semanaAnyo == 53)
        {
            if( ( Fechas::getDiaSemana($anyo, $mes, 31) - 1 ) <= 2)
            {
                $semanaAnyo = 1;
            }
        }
        return $semanaAnyo;
    }
    
    /* Comprueba si un año es bisiesto */
    public static function esBisiesto($anyo)
    {            
        $a = (0 == $anyo%4); /*Año divisible por 4*/
        $b = (0 == $anyo%100); /*Año divisible por 100*/
        $c = (0 == $anyo%400);/*Año divisible por 400*/
        
        /*Un año es bisiesto si es divisible por 4 y por 400 
          o si es divisible por 4 pero no por 100 */
        $loEs = $a && ($c || !$b);
        
        return $loEs;
    }
    
    /* Devuelve el día en que acaba un mes */
    public static function getFinMes($anyo,$mes)
    {              
        /*Número de días de cada mes*/
        $diasMeses=array(31,28,31,30,31,30,31,31,30,31,30,31);
        $diasMesesBis=array(31,29,31,30,31,30,31,31,30,31,30,31);
        
        /*Según el año sea bisiesto o no, se usan unos valores u otros*/
        if( 1 == Fechas::esBisiesto($anyo) )
        {                
            $finMes = $diasMesesBis[$mes-1];
        }
        else
        {
            $finMes = $diasMeses[$mes-1];
        }

        return $finMes;
    }

}

Sunday, March 21, 2010

Completísimo curso de C++ orientado a objetos

He encontrado un curso de C++ orientado a objetos que está muuuy bien.
Me hubiera sido muy útil mientras hacía la parte de C++ de la asignatura de Introducció al desenvolupament de programari, que la verdad tenía muy poco de introducción.

Master Software Libre UOC: Introducció al Desenvolupament de programari

El semestre pasado hice la asignatura de Introducció al desenvolupament de programari de la UOC. Aprendí mucho y al final me fue muy bien, pero considero que hay una serie de cosas que sería interesante saber antes de matricularse.
Este es un extracto del análisis que posteé en el foro de CAUOC:
...lo de Introducció no es cierto. El ritmo de la asignatura y el nivel de exigencia y dimensión de las PACs, han hecho que la mayoría de las personas sin experiencia en programación acabaran abandonando la asignatura. Si no han programado nunca, esta no es la asignatura para empezar a aprender.

...el material de la asignatura es insuficiente para poder sacar las PACs adelante. Sólo se salva la parte de C. En las de C++ y Java casi no hay ejemplos y se pasa por encima o sólo se nombran cosas que luego son importantísimas para poder sacar adelante las PACs.

He aprendido bastante y al final he conseguido sacarla, pero considero que, a causa de PAcs sobredimensionadas y con un nivel de exigencia muy superior al que se encuentra en los materiales que facilitan, he tenido que invertir en ella demasiado tiempo.

Espero que el aluvión de quejas que han recibido este semestre, sirva para que la asignatura mejore para próximos semestres.

Al final, en respuesta a las quejas, parece que la UOC piensa revisar el material de la asignatura y cambiar su nombre quitando la palabra "Introducció".

Esperemos que así sea.