domingo, 27 de septiembre de 2015

Examen POO Junio 2015 prMaternidad (Segunda Parte)

Aquí os traigo la segunda parte. Lo siento por haber sido un vago... Al final ha sido uno de mis alumnos de éste verano quien ha hecho el código conmigo y me lo ha mandado. Gracias Álvaro ;)

Os recuerdo que la primera parte y el enunciado a descargar se encuentran aquí.

De todas formas os pego la segunda parte del enunciado:
(2 ptos.) La clase MaternidadLimiteBebeHabitacion se comporta como la clase Maternidad, con la diferencia de que va a detectar aquellas habitaciones que tienen un número de bebés que supera el valor máximo definido en la variable llamada maximo (int). Para cada habitación que supere el máximo permitido se guardará un mensaje informando de tal situación en la variable cambios (List). Con el propósito de saber la ocupación actual de cada habitación esta clase cuenta con una variable ocupacion (Map) que asocia cada habitación con el número de bebés actualmente asignados a ella. La variable ocupación se va actualizando cada vez que un nuevo bebé es registrado en el sistema y será consultada para ver si se supera el mencionado límite. 
a. Los constructores MaternidadLimiteBebeHabitacion(int maximo) y MaternidadLimiteBebeHabitacion(int maximo, String nombreFichero) deben crear todas las estructuras de datos: en el primer caso se crean vacías; en el segundo caso se añade toda la información del fichero cuyo nombre se pasa como segundo parámetro. El formato de dicho fichero es el mismo que el utilizado para la clase Maternidad. 
b. Redefinir addMadreBebes(Persona madre, Collection bebes). La nueva versión el método debe añadir la información de pacientes a la estructura de datos paciente sin tener en cuenta el límite de bebés. En caso de que se detecte que ello hace que alguna habitación supere dicho límite, se deberá añadir un mensaje informativo donde conste el número de habitación al listado de cambios (cambios) que han de hacerse. Se debe tener en cuenta que la incubadora (habitación con código 0) no estará sujeta a dicho límite. 
c. Redefinir String toString() para que a la información sobre las madres y bebés a las que atiende el servicio de maternidad mostrada en la clase Maternidad, añada todos los mensajes contenidas en la lista de cambios.

5) (1.5 ptos.) La clase ControladorMaternidad controla e interactúa con el modelo (clases Maternidad y Persona) y la vista (se proporcionan en el campus virtual la interfaz VistaMaternidad y la clase PanelMaternidad). El constructor debe habilitar la parte de inicialización de la vista (introducción del fichero de pacientes, y el botón de inicio) y mostrar un mensaje en la parte baja de la misma indicando al usuario que introduzca el nombre del fichero y pulse el botón iniciar. El resto de la vista estará deshabilitado. La pulsación del botón “Inicio” hará que se cree un objeto de la clase Maternidad (pasándole el nombre del fichero introducido), se deshabilite la zona de inicialización y se habilite el resto de la vista. Cada vez que el usuario pulse algunos de los demás botones se procederá a realizar la acción correspondiente. El botón “Guardar” guarda la información sobre pacientes en el fichero indicado en el campo de texto a su derecha. En caso de que dicho campo contenga la cadena vacía, la información se imprime en el área de texto del panel. El botón “Buscar Madre” hará que se lea el código del bebé del campo de texto a su derecha y se muestre en el área de texto la habitación en que se encuentra su madre. El botón “Media” muestra en el área de texto el resultado de calcular la media de bebés. Tras cada operación se debe mostrar un mensaje de confirmación o error en la parte baja de la vista. 
Las clases Main y MainGUI se proporcionan en el campus virtual, para que se pueda probar el funcionamiento de las distintas clases a implementar.
Aquí os dejo las clases que deberían porporcionaos: VistaMaternidad PanelMaternidad
Y aquí os dejo ya las soluciones:
Empezamos con la clase MaternidadLimiteBebeHabitacion

package prMaternidad;

import java.io.FileNotFoundException;
import java.util.Collection;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeSet;

public class MaternidadLimiteBebesHabitacion extends Maternidad {
 private int maximo;
 private List<String> cambios;
 private SortedMap<Integer, Integer> ocupacion;//no he encontrado nada que me pida usarlo pero abajo
 //esta señalado donde lo utilizaria si fuese necesario

 public MaternidadLimiteBebesHabitacion(int maximo) {
  super();
  this.maximo = maximo;
 }

 public MaternidadLimiteBebesHabitacion(int maximo, String nombreFichero) throws FileNotFoundException {
  super(nombreFichero);
  this.maximo = maximo;

 }

 public void addMadreBebes(Persona madre, Collection<Persona> bebes) {
  int cont = 1;
  if (!pacientes.containsKey(madre))
   pacientes.put(madre, new TreeSet<Persona>());
  if(!ocupacion.containsKey(madre.getHabitacion())){
   ocupacion.put(madre.getHabitacion(),0);
  }

  for (Persona b : bebes) {
   pacientes.get(madre).add(b);
   if (b.getHabitacion() != 0) {
    cont++;
   }
   ocupacion.put(madre.getHabitacion(), cont+ocupacion.get(madre.getHabitacion()));
   //en cada habitacion a traves de ocupacion lo añadiria aqui
   if (ocupacion.get(madre.getHabitacion()) >= maximo) {
    cambios.add("habitacion " + madre.getHabitacion()
      + "se encuentra llena");
   }
   
  }
 }

 public String toString() {
  String std = "";
  for (Persona madre : pacientes.keySet()) {
   std = std + madre;
  //para poder concatenar un string con el toString de una clase, el string ha de estar inicializado
   //aunque sea un string vacio como en este caso
   for (Persona hijo : pacientes.get(madre)) {
    std = std + "#" + hijo;
   }
   
   
   std = std + "\n";

  }
  for(int i=0;i<cambios.size();i++){
  std=std+cambios.get(i)+"\n ";//meto la lista de las habitaciones que superan el limite
  //de pacientes en el string
  }
  return std;
 }

}

Y acabamos con la clase ControladorMaternidad
package prMaternidad;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;

public class ControladorMaternidad implements ActionListener {
 private Maternidad model;
 private VistaMaternidad vistamaternidad;

 public ControladorMaternidad(VistaMaternidad vm, Maternidad m) {
  this.vistamaternidad = vm;
  this.model = m;

  vistamaternidad.habilitarInit(true);
 }

 public void actionPerformed(ActionEvent ae) {
  String command = ae.getActionCommand();

  if (command.equals(VistaMaternidad.BUSCAR)) {
   try{
   int c = vistamaternidad.codigoBebe();
   try {
    int habit = model.encontrarMadre(c);
    vistamaternidad
      .entradaHistorial("La habitacion de la madre del bebe con codigo: "
        + c + "es: " + habit);
   } catch (MaternidadException e) {
    vistamaternidad.error("No se encuentra a la madre del bebe.");
   }
   }catch (NumberFormatException e){
    vistamaternidad.error("Hay un error con el codigo del bebe.");
   }
  } else if (command.equals(VistaMaternidad.GUARDAR)) {
   try {
    String ruta = vistamaternidad.fichSalida();
    model.escribirFichero(ruta);
   } catch (FileNotFoundException e) {

    vistamaternidad.entradaHistorial(model.toString());
   }
  } else if (command.equals(VistaMaternidad.INICIO)) {

   vistamaternidad.habilitarInit(true);
   try {
    model = new Maternidad(vistamaternidad.fichEntrada());
    vistamaternidad.habilitarInit(false);
    vistamaternidad.mensaje("Fichero cargado.");
   } catch (FileNotFoundException e) {
    vistamaternidad.error("Fichero no encontrado.");
   }

  } else if (command.equals(VistaMaternidad.MEDIA)) {
   double media = model.mediaBebes();
   vistamaternidad
     .entradaHistorial("La media de los bebes por cada madre en el hospital es: "
       + media);
  }

 }
}


Es trivial ver que ésto es más un trabajo duro que complejo... Por eso mismo me he demorado tanto en hacerlo, me daba demasiada pereza :P

Espero que os sea tan simple como a mí, pero sino ya sabéis que podeis preguntar las dudas aquí abajo;)

Saludos;)

domingo, 26 de julio de 2015

Examen POO Junio 2015 prMaternidad (Primera Parte)

Buenas gente. Ya estoy de nuevo por aquí, que recientemente uno de mis alumnos me ha pasado éste examen y yo, aburrido, he decidido hacerlo.
Os traigo los primeros 6.5 puntos porque estoy vago. Ya acabaré el resto otra tarde :)

El enunciado podéis descargarlo de aquí. De todos modos os lo pego por aquí por si queréis leerlo ;)

Se desea desarrollar una aplicación para la gestión de pacientes a los que atiende el servicio de maternidad de un hospital. Para ello, se creará un proyecto prMaternidad con las clases siguientes:
1) (0.25 ptos.) La clase MaternidadException se utilizará para tratar las diferentes situaciones excepcionales. Se trata de una excepción no comprobada. En general, se lanzará esta excepción si los parámetros de entrada de los métodos no contienen valores adecuados.
2) (2.25 ptos.) La clase Persona mantendrá información sobre un paciente ingresado en el área de maternidad del hospital. En concreto, su nombre (String), un código (int) que se considerará único y la habitación (int) asignada a ese paciente. La clase dispondrá de constructores y métodos necesarios para:
a. Construir un objeto de la clase dados los valores para las tres variables descritas anteriormente. Si el código proporcionado no es un número positivo mayor que cero o la habitación dada es negativa se debe lanzar una excepción de tipo MaternidadException informando de tal situación.
b. Obtener el nombre (String getNombre()), el código (int getCodigo()) y el número de habitación (int getHabitacion()).
c. La representación de una persona (String toString()) viene dada por su nombre, código y número de habitación separados por el carácter ‘:’.
Ej: García, Ana:1002:132
d. Dos objetos de la clase Persona son iguales si coinciden sus códigos, que recordemos que son únicos.
e. Los objetos de la clase Persona se ordenan de forma natural por código.
f. Se proporcionará una ordenación alternativa, que organice los objetos primero por nombre, ignorando mayúsculas y minúsculas, y, en caso de igualdad, por código. Esta ordenación deberá definirse en una clase aparte, llamada OrdAlt.
NOTAS PARA LA REALIZACIÓN DEL EJERCICIO:
 El ejercicio se almacenará en el directorio C:\POO. En caso de que no exista deberá crearse, y si ya existiese, deberá borrarse todo su contenido antes de comenzar.
 Al inicio del contenido de cada fichero deberá indicarse el nombre del alumno, titulación, grupo y código del equipo que está utilizando.
 La evaluación tendrá en cuenta la claridad de los algoritmos, del código y la correcta elección de las estructuras de datos, así como los criterios de diseño que favorezcan la reutilización.
 Los diferentes apartados tienen una determinada puntuación. Si un apartado no se sabe hacer, el alumno no debe pararse en él indefinidamente. Puede abordar otros.
 Está permitido:
o Consultar el API.
 No está permitido:
o Utilizar otra documentación electrónica o impresa.
o Intercambiar documentación con otros compañeros.
o Utilizar soportes de almacenamiento.
 Una vez terminado el ejercicio subir un fichero comprimido sólo con los ficheros .java que hayáis realizado a la tarea creada en el campus virtual para ello.
3) (4 ptos.) La clase Maternidad almacenará la información de los pacientes del servicio de maternidad en una estructura pacientes de tipo SortedMap<Persona, SortedSet <Persona>>, de tal manera que cada madre ingresada esté asociada al conjunto de bebés a los que ha dado a luz. La madre y los bebés suelen estar en la misma habitación, pero hay veces en qué ello no ocurre así. Por ejemplo, si alguno de los bebés debe ir a la incubadora (habitación con código 0).
La clase debe proporcionar los siguientes constructores y métodos públicos:
a. El constructor Maternidad() crea la estructura de datos. Se debe tener en cuenta que queremos ordenar las madres por nombre (orden alternativo mencionado anteriormente). Los bebés asociados a cada madre se ordenarán por código (orden natural).
El constructor Maternidad(String)recibe un nombre de fichero y, tras crear la estructura de datos, añade toda la información que contiene el fichero (ver apartados siguientes).
b. Los métodos addPacientesFichero(String) y addPacientes(Scanner) añaden información sobre pacientes a la estructura de datos. El primero lee la información de un fichero. El segundo desde el flujo de entrada proporcionado. Se supondrá que la información sobre cada madre y sus bebés se encuentra en una línea de texto, donde el carácter ‘#’ separa la información de distintas personas. Para cada persona, sus datos particulares se separan con el carácter ‘:’. Por ejemplo, la siguiente línea indica que la persona Ana García es madre de dos niños, Pedro y Nuria.
García,Ana:1002:132#López,Pedro:1034:132#López,Nuria:1036:0
Cualquier error de formato detectado (falta algún dato personal, o bien el dato no es del tipo correcto), provocará el lanzamiento de una excepción del tipo MaternidadException.
Se proporciona el fichero de datos pacientes.txt para probar el correcto funcionamiento de la solución implementada.
c. El método addMadreBebes(Persona madre, Collection<Persona> bebes) registra la madre y sus bebes en el servicio de maternidad. Nótese que la colección bebes puede estar vacía, lo que indica que dicha madre aún no ha dado a luz. Si la madre ya estuviese registrada se añadirán los bebés indicados por el segundo parámetro al conjunto de bebés que ya tenía previamente.
d. Se ha de redefinir el método String toString(). La representación de los objetos de la clase muestra toda la información contenida en la estructura de datos. El formato que se ha de utilizar es el que aparece en el fichero pacientes.txt. Es decir, en cada línea la información de una madre y sus bebés.
e. Los métodos escribirFichero(String) y escribir(PrintWriter) guardan la información de la estructura de datos en el fichero o en el flujo de salida dado respectivamente.
f. El método double mediaBebes() calcula el número medio de bebés por madre que están registrados en el sistema. Aquellas madres que no tienen hijos asociados no se tienen en cuenta en el cómputo.
g. El método int encontrarMadre(int codigoBebe) devuelve el número de habitación de aquella persona que es madre del bebé cuyo código se pasa como parámetro. En caso de no encontrarse la madre, se debe lanzar una excepción de tipo MaternidadException informando de tal situación.
Igualmente os aconsejo que lo descarguéis. Se verá mejor que aquí.
Aquí os dejo también las clases terminadas, pero no os limiteis a verlas. Intentad hacerlo vosotros y luego comparáis ;)
MaternidadException, Persona, OrdAlt, Maternidad.
Aquí os dejo pegado el código ;)
MaternidadException:
public class MaternidadException extends Exception {
    public MaternidadException() {
        super();
    }
    public MaternidadException(String e) {
        super(e);
    }
}

Persona:
public class Persona {
    private String nombre;
    private int codigo;
    private int habitacion;
    
    public Persona(String nombre, int codigo, int habitacion) throws MaternidadException{
        if(codigo <1 || habitacion<0)
            throw new MaternidadException("Codigo o habitacion incorrectos.");
        this.nombre = nombre;
        this.codigo = codigo;
        this.habitacion = habitacion;
    }
    
    public String getNombre() {
        return this.nombre;
    }
    public int getCodigo() {
        return this.codigo;
    }
    public int getHabitacion() {
        return this.habitacion;
    }
    
    public String toString() {
        return this.nombre+":"+this.codigo+":"+this.habitacion;
    }
    
    public boolean equals(Persona p) {
        return this.codigo==p.getCodigo();
    }
    public int compareTo(Persona p) {
        int cod = p.getCodigo();
        if(this.codigo<cod)
            return -1;
        else if(this.codigo>cod)
            return 1;
        else
            return 0;
    }
    
}

OrdAlt:
public class OrdAlt extends Persona{
    public OrdAlt(String nombre, int codigo, int habitacion) throws MaternidadException{
        super(nombre, codigo, habitacion);
    }
    
    public int compareTo(OrdAlt p) {
        String nombre1 = this.getNombre().toLowerCase();
        String nombre2 = p.getNombre().toLowerCase();
        int c = nombre1.compareTo(nombre2);
        
        if(c!=0)
            return c;
        
        /* Copiado tal cual de Persona*/
        int cod = p.getCodigo();
        if(this.getCodigo()<cod)
            return -1;
        else if(this.getCodigo()>cod)
            return 1;
        else
            return 0;
        
    }
}

Maternidad:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Scanner;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author NikNitro
 */
public class Maternidad {
    private final int incubadora = 0;
    private SortedMap<Persona, SortedSet<Persona>> pacientes;
    
    public Maternidad() {
        pacientes = new TreeMap<>();
    }
    public Maternidad(String std) {
        pacientes = new TreeMap<>();
        addPacientesFichero(std);
        
    }
    
    public void addPacientesFichero(String std){
        File f = new File(std);
        try {
            Scanner sc = new Scanner(f);
            sc.useDelimiter("\n");
            addPacientes(sc);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Maternidad.class.getName()).log(Level.SEVERE, null, ex);
        } catch (MaternidadException e ) {
            System.err.printf("Existe algún error con el archivo dado");
        } 
    }
    
    public void addPacientes(Scanner sc) throws MaternidadException{
        String linea, persona, nombre;
        int codigo, habitacion;
        boolean esMadre = true;
        OrdAlt madre= null;
        Persona bebe;
        Collection<Persona> bebes = null;

        while(sc.hasNext()) {   //Vemos cada línea
            linea =sc.next();
            Scanner separador = new Scanner(linea);
            separador.useDelimiter("#");
            
            while(separador.hasNext()) {    //Vemos cada persona en una línea
                try{
                    persona = separador.next();
                    Scanner dosPuntos = new Scanner(persona);   //Vemos los datos de cada persona
                    dosPuntos.useDelimiter(":");
                    nombre = dosPuntos.next();
                    codigo = Integer.parseInt(dosPuntos.next());
                    habitacion = Integer.parseInt(dosPuntos.next());
                    if(esMadre) {
                        madre = new OrdAlt(nombre, codigo, habitacion);
                        esMadre = false;
                        bebes = new TreeSet<>();
                    } else {
                        bebe = new Persona(nombre, codigo, habitacion);
                        bebes.add(bebe);
                        
                    }
                } catch(NumberFormatException | MaternidadException e) {
                    throw new MaternidadException();
                }
            }
            //Aquí ya hemos rellenado a la madre y el treeSet con una línea.
            addMadreBebes(madre, bebes);
            esMadre = true;
        }
    }
    
    public void addMadreBebes(Persona madre, Collection<Persona> bebes) {
        if(pacientes.containsKey(madre))
            
                //Es la forma nueva de java 8. La antigua sería "for(Persona b : bebes)"
            bebes.stream().forEach((b) -> {
                pacientes.get(madre).add(b);
            });
        else {
            SortedSet bebe = new TreeSet<>();
            bebes.stream().forEach((b) -> {
               bebe.add(b);
            });
            pacientes.put(madre, bebe);
        }
    }
    
    @Override
    public String toString() {
        String std="";
        for (Persona p : pacientes.keySet()) {
            std = std + p + "#";
            for(Persona b : pacientes.get(p)) {
                std = std + b + "#";
            }
            std = std+"\n";
        }
        return std;
    }
    
    public void escribirFichero(String s) {
        File f = new File(s);
        PrintWriter p;
        try {
            p = new PrintWriter(f);
            escribir(p);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Maternidad.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public void escribir(PrintWriter p) {
        p.append(this.toString());
    }
    
    public double mediaBebes() {
        double numMadres = 0, numBebes = 0;
        for(Persona p : pacientes.keySet()) {
            SortedSet bebes = pacientes.get(p);
            if(bebes.size()>0) {
                numMadres++;
                numBebes += bebes.size();
            }
                
        }
        return numBebes/numMadres;
    }
    
    public int encontrarMadre(int codigoBebe) throws MaternidadException{
        for(Persona m : pacientes.keySet()) 
            for(Persona b : pacientes.get(m)) {
                 if(b.getCodigo()== codigoBebe)
                     return m.getHabitacion();
            }
            
        throw new MaternidadException("Madre no encontrada");
        
    }
}

Os aviso de que el código aún no está probado, por lo que si veis cualquier cosilla que de error o que no cuadre, por favor avisadme para que lo arregle.

Saludos y gracias por visitarme;)

sábado, 21 de marzo de 2015

MIPS: Como calcular la siguiente fila a una dada en la pirámide de Tartaglia.

Buenas gente. Hace una semana se me ocurrió plantear éste ejercicio para mis alumnos de Computadores. Ya lo hemos hecho bien y os lo traigo aquí.
Decir que lo hemos desarrollado en forma de función para poder utilizarlo más adelante en otras funciones más complejas.
La función toma en $3 la dirección donde comienza el array, en $7 el tamaño del array y en $2 la dirección de memoria donde guardaremos el resultado (sería algo así como pasar un parámetro por referencia en C o C++).

He de decir, por último, que para que funcione bien con el primer elemento no hay que pasarle un [1], sino un [1, 1]. Ésto lo hemos hecho por temas de simplicidad, pero si hiciera falta cambiarlo, sería muy simple.

Dicho ésto, os dejo aquí el código ;)

.data
array: .word 1 3 3 1
tam: .word 4
res: .word -1

.text

 lw $7, tam($0) #Tamaño
 la $3,array
 la $2,res
 jal Tar
 li $2,10
 syscall
 
Tar: add $8,$0,$2 #Indice Mem. Res
 add $5,$3,$0 #Índice Mem. Array
 addi $6,,$0,1  #Constante 1
 sw $6,0($8) #res[0]=1
 addi $10,$0,1  #i del For 
loop: slt $4,$10,$7
 beq $4,$0,FinFor
 lw $12,0($5) #Array +$8 
 addi $5,$5,4 
 addi $8,$8,4  #Sumamos 4 al Índice
 lw $13,0($5) #Array +$8
 add $21,$12,$13 #Guarda en $21 la suma $12+$13
 sw $21,0($8) #Guarda en $21 en res $8
 addi $10,$10,1 #i++
 j loop  #Bucle
FinFor: addi $8,$8,4  #Suma 4 a lo que hay en $8
 sw $6,0($8) 
 jr $31

No es complicado, ¿verdad? Si no lo entendéis del todo escribidme y subo el código que se usaría en C++ o Java con la misma función, para que lo entendáis mejor.

Saludos;)

domingo, 8 de marzo de 2015

HTML POST PHP Tablas de multiplicar

Hola gente :)
He estado haciendo un par de pruebas con PHP y quería compartirlas. Aviso desde ya que son cosas muy básicas.

Para montar mi lugar de trabajo he instalado XAMPP, que es una aplicación gratuita que te permite montar en tu máquina un servidor con PHP, MySQL y un montón más de funcionalidades que espero usar :)

Para programar he usado NetBeans, que aunque traga muchos recursos, mi ordenador lo soporta de sobra y me ha gustado el funcionamiento que tiene.

Pues he empezado haciendo un formulario simple a más no poder en HTML para pasarle un número al PHP. Éste PHP se encargará de tomar el número y calcular la tabla de multiplicar del 1 al 10 del mismo número.
Luego probé (con un for) a que imprimiera todas las tablas entre 1 y 20. De ésta forma practicamos tanto la recogida de datos (por medio del método POST) y los bucles y el uso de variables.

Si veis que os sale feo o que hay etiquetas que no conocéis en el HTML, es porque estoy usando Bootstrap. Si queréis saber más sobre ello, preguntad ;)

Aquí el código (demasiado simple) del index.php (también puede ser index.html pero por comodidad les he puesto a todos la misma extensión):

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Tablas de multiplicar</title>
    </head>
    <body>
        
        <form method="POST" name="tabla" role="form" action="tablas.php" enctype="multipart/form-data">
            <div class="form-group">
                <label for="exampleInputNombre">Introduzca un número</label>
                <input name="number" type="text" class="form-control" id="numero" placeholder="Escribe un numero">
                <button type="submit" class="btn btn-default">Enviar</button>
            </div>
        </form>
    </body>
</html>
La web resultante tendría únicamente un formulario tal que así:

Como veis, la complejidad es nula. Vamos ahora con el "tablas.php":

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Tablas de multiplicar</title>
        <link href="css/bootstrap.min.css" rel="stylesheet">
        <script src="https://code.jquery.com/jquery.js"></script>
        <script src="js/bootstrap.min.js"></script>
    </head>
    
    <body>
        <!-- Botón para volver atrás -->
        <div class="row">
            <div class="col-md-12 well"><a href="index.php"><button class="btn btn-default">Atrás</button></a> </div>
        </div>
        <!-- Tabla del número elegido-->
        <table  class="table table-hover table-bordered ">
        <?php
        $num = $_POST["number"];
        echo ("<tr>");
        // Cabecera 
        for ($i = 1; $i < 11; $i++) {            
            echo ("<th>");
            echo "$i";
            echo ("</th>");
        }
        
        echo ("</tr>");
        
        // Resultados 
        echo ("<tr>");

        for ($i = 1; $i < 11; $i++) {            
            echo ("<td>");
            $aux = $num*$i;
            echo "$aux";
            echo ("</td>");
        }
        
        
        echo ("</tr>");
        
        
        ?>
            
            <!-- Tabla genérica, creada al ejecutar el php -->
        </table>
        <br><br>
        <p class="active"> 
            Ahora una tabla más genérica:
        </p>
        <br>
        <table  class="table table-hover table-bordered ">
        <?php
            
            echo ("<tr>");

            for ($i = 1; $i < 11; $i++) {            
                echo ("<th>");
                echo "$i";
                echo ("</th>");
            }

            echo ("</tr>");

            for($j=1; $j<21; $j++) {

            for ($i = 1; $i < 11; $i++) {            
                echo ("<td>");
                $aux = $j*$i;
                echo "$aux";
                echo ("</td>");
            }


            echo ("</tr>");
            }

        ?>
        </table>
    </body>
</html>

Espero que no lo veáis demasiado complejo. Si queréis imágenes de cómo queda o tenéis cualquier duda/sugerencia, no dudéis en escribirnos. Estaremos encantados de responderos.

Saludos y hasta otra ;)

viernes, 6 de marzo de 2015

Validación de formulario HTML5 con JavaScript

Os dejo un pequeño y simple formulario hecho mediante HTML5 con la correspondiente comprobación de sus campos mediante JavaScript.
Lo que se pretende hacer es que cuando el usuario pulse el botón de envío del formulario,se ejecute el código JavaScript que debe comprobar:

  1. que los campos nombre y apellidos no estén vacíos
  2. que la dirección de correo electrónico esté bien formada (aparece @ en un carácter que no es el primero, y tiene al menos un punto tras la arroba) 
  3. que la contraseña tiene al menos 8 caracteres y
  4. que la contraseña con su repetición.
Si no es así se muestra una alerta al usuario indicando el problema y se cancela el envío, limpiando los campos de contraseña. Si todo es correcto se procede con el envío.

Os dejo primero el código html (puede que haya algún error con el tema de formato por los < > y las etiquetas debido al copia y pega).

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <script src="codigo.js" type="text/javascript"></script> <!-- Para incluir el fichero JavaScript-->
  <title>Formulario</title> 
  <meta name="author" content="Aprendiendo a programar entre todos">
 </head>
 <body>
  <form method="post" action="mailto:aprendiendoaprogramarentretodo@gmail.com" name="formulario" enctype="text/plain" onsubmit="return validar();">
   <table>
    <tr>
     <td>Nombre</td>
     <td><input type="text" size="25" name="nombre"></td>
    </tr>
    
    <tr>
     <td>Apellidos</td>
     <td><input type="text" size="25" name="apellidos"></td>
    </tr>
    
    <tr>
     <td>Correo electrónico</td>
     <td><input type="text" size="25" name="email"></td>
    </tr>
    
    <tr>
     <td>Contraseña</td>
     <td><input type="password" size="25" name="pass"></td>
    </tr>
    
    <tr>
     <td>Repita contraseña</td>
     <td><input type="password" size="25" name="rpass"></td>
    </tr>

                                <tr>
                                        <td>Sexo (opcional) </td>
                                        <td>
                                             <input type="radio" name="sexo" value="mujer"> Mujer
                                                <input type="radio" name="sexo" value="hombre">Hombre<br>
                                        </td>
                                         
                                </tr>
                                <tr>
                                        <td><input type="checkbox" name="sesion" value="v_sesion">Deseo recibir ofertas</td>
                                        <td> </td>
                                </tr>                                                                

    
    <tr>
     <td><input type="reset" value="Reset"></td>
     <td><input type="submit" value="Enviar"></td>
    </tr>
    
   </table>
   
  </form>

 </body>
</html>


Y aquí el código JavaScript que valida los campos del formulario de la manera indicada anteriormente, comprobando de forma muy clara para que lo podáis ver bien cada una de las restricciones que se indican en el enunciado.
function resetPass (){
    document.formulario.pass.value = "";
    document.formulario.rpass.value = "";
    return false;
}

function validar (){
    var nombre = document.formulario.nombre.value;
    var apellidos = document.formulario.apellidos.value;
    var email = document.formulario.email.value;
    var pass =  document.formulario.pass.value;
    var rpass =  document.formulario.rpass.value;
    if(nombre === "" || apellidos === ""){
        alert("Error: nombre incompleto");
        return resetPass();
    }else if (email.indexOf('@') < 1){
        alert("Error en email (debe aparecer @)");
        return resetPass();
    }else if(email.lastIndexOf(".")  < email.indexOf('@') ){
        alert("Error en email (debe aparecer un .)");
        return resetPass();
    }else if(pass.length < 8){
        alert("Contraseña demasiado corta");
        return resetPass();     
    }else if(pass !== rpass){
       alert("Contraseñas no coinciden");
        return resetPass();
    }else{
       return true; 
    }
}

Está claro que es un ejemplo muy sencillo y realizado de forma muy básica, pero por algo se empieza ;)

jueves, 5 de marzo de 2015

LinkedArray en C

Hola gente, cuánto tiempo!! :)
Lo siento por mi desaparición pero estoy demasiado perdido entre estudiar y trabajar... Además estoy aprendiendo front-end en condiciones y.., le faltan horas a mi día. Creo que me voy a comprar un reloj de esos de 40 horas a ver...

Os traigo un código que les he puesto a mis alumnos de la academia. El enunciado es simple y tal que así:
Crea en C (con cabecera y código separados) una estructura de Array en Nodos, en la que cada Nodo tendrá
como atributos un entero (valor), un entero (tam) y un puntero al siguiente Nodo. Además debes crear las
siguientes funciones:
Crear(Primero* primero, int n) Crea todos los nodos inicializándolos a cero.
Destruir(Primero* primero) Borra todos los nodos, liberando el espacio de disco.
Obtener(Primero primero, int index, int *ok, int *valor) Devuelve en valor el valor de ese trozo de array. En
ok devuelve un 1 si se ha podido y un 0 en caso contrario.
Cambiar(Primero* primero, int index, int valor) Cambia el valor de la posición index por el nuevo valor
Mostrar(Primero primero) Imprime el array.

Aquí tenéis la cabecera:
#ifndef MAIN_H
#define MAIN_H

typedef struct Array* Primero;
struct Array {
    int valor;
    int tam;
    Primero sig;
};

void Crear(Primero* primero, int n);
void Destruir(Primero* primero);
void Obtener(Primero primero, int index, int *ok, int *valor);
void Cambiar(Primero* primero, int index, int valor);
void Mostrar(Primero primero);


#endif /* MAIN_H */


Y aquí os dejo el código:

#include <stdio.h>
#include <stdlib.h>
#include "main.h"

/*
 * 
 */

void Crear(Primero* primero, int n) {
     *primero = (Primero)malloc(sizeof(struct Array));
     (*primero)->tam = n;
     (*primero)->valor = 0;
     (*primero)->sig = NULL;
     Primero ant = *primero;
     int i;
     for(i=1; i<n; i++) {
         Primero nuevo;
         nuevo = (Primero)malloc(sizeof(struct Array));
         nuevo->valor=0;
         nuevo->tam = (*primero)->tam;
         nuevo->sig = NULL;
         ant->sig = nuevo;
         ant = ant->sig;
     }
     
}
void Destruir(Primero* primero) {
    Primero ptr;
    while (*primero != NULL) {
        ptr=(*primero)->sig;
        free((void *)*primero);
        *primero=ptr;
    }
}
void Obtener(Primero primero, int index, int *ok, int *valor) {
    
    if((*valor)<primero->tam) {
    int i;
    Primero aux = primero;
    for(i = 0; i < index; i++) {
        aux = aux->sig;
    }
    (*valor)=aux->valor;
    (*ok) = 1;
    } else {
        (*ok) = 0;
    }
}
void Cambiar(Primero* primero, int index, int valor) {
    int i;
    Primero aux = *primero;
    for(i = 0; i < valor; i++) {
        aux = aux->sig;
    }
    aux->valor = valor;
    
}
void Mostrar(Primero primero) {
    int ultimo = primero->tam;
    int i;
    printf("{");
    for(i=0; i < ultimo-1; i++) {
        printf("%d, ", primero->valor);
        primero = primero->sig;
    }
    printf("%d}", primero->valor);
    fflush(stdout);
}

int main() {
    printf("Vamos a crear un array\n");
    fflush(stdout);
    Primero p;
    Crear(&p, 5);
 //   int ok;
 //   int valor;
//    Obtener(p, 3, &ok, &valor);
//    printf("%d", valor);
 //   fflush(stdout);
   Cambiar(&p, 2, 1);
   Cambiar(&p, 3, 4);
    Mostrar(p);
    Destruir(&p);
    return (EXIT_SUCCESS);
}

Pues eso gente, si necesitáis ayuda con algo pedidla por aquí (no me metáis más de 2 faltas de ortografía por palabra por favor) y espero que os sigan sirviendo todas éstas cosillas ;)

Saludos

lunes, 9 de febrero de 2015

Ejercicios de ensamblador en MIPS

¿Qué pasa gente? Demasiado tiempo sin publicar nada...
Hoy traigo unos ejercicios en MIPS de unos alumnos de Electrónica, Robótica y Mecatrónica. Os los voy poniendo:

El primero dice asi:
Diseña un programa ensamblador que defina el vector de enteros de dos elementos V=(10,20) en la memoria de datos a partir de la dirección 0x10000000 y almacene su suma a partir de la dirección donde acaba el vector.
.data 0x10000000
vector: .word 10, 20 # Vector de elementos
res: .word 0  # Donde guardaremos el resultado
.text

 addi $8, $0, 4   # Guardo un 4 para pedir la segunda palabra del vector.
 lw $9, vector($0)
 lw $10, vector($8)
 
 add $11, $9, $10  # Sumamos en un temporal el resultado
 sw $11, res($0)   # Guardamos en memoria el resultado.
 
 li $2, 10
 syscall
Por aquí el segundo:
Diseña un programa ensamblador que divida los enteros 18,-1215 almacenados a partir de la dirección 0x10000000 entre el número 5 y que a partir de la dirección 0x10010000 almacene el cociente de dichas divisiones.

.data 0x10000000
entero1: .word 18
entero2: .word -1215
.data 0x10010000
res1: 0
res2: 0

.text
 addi $5, $0, 5
 # Primero un numero y luego el otro.
 lw $8, entero1($0)
 div $9, $8, $5
 sw $9, res1($0)
 
 # Ahora el segundo.
 lw $8, entero2($0)
 div $9, $8, $5
 sw $9, res2($0)
 
 li $2, 10
 syscall
 

El tercero lo he hecho usando una función AND y un número que en binario es todo unos excepto los bits que quiero poner a 0
Pon a cero los bits 3,7,9 del entero 0xabcd12bd almacenado en memoria a partir de la dirección 0x10000000, sin modificar el resto.
.data 0x10000000
valor: .word 0xabcd12bd
.text 
 addi $8, $0, 0xDD7FFFFF   
 lw $9, valor($0)
 and $10, $8, $9
 sw $10, valor($0)
 
 li $2, 10
 syscall

Y el cuarto ejercicio (es el sexto en la relación, pero los anteriores tampoco tenían mucha dificultad) dice tal que así:
Diseña un programa en ensamblador que defina un vector de enteros, V, inicializado según los siguientes valores (V=[2, -4, -6]). Y obtenga un vector de booleanos, tal que cada elemento será 1 si el correspondiente elemento en el vector de enteros es mayor o igual que cero y 0 en caso contrario.

.data 0x10000000
vector: .word 2, -4, -6
tam: .word 3
res: .word -1, -1, -1
.text 
 addi $2, $0, 1   # Constante 1 
 add $6, $0, $0  # Indice del array
 add $7, $0, $0  # Contador
 lw $8, tam($0)  # Tamaño a llegar
loop: 
 lw $9, vector($6) #Elemento del vector
 slt $10, $9, $0  # Si el segundo es menor que el tercero, el primero vale 1
 beq $10, $0, esPositivo
 # Si sigue por aquí es negativo
 sw $0, res($6)
 j vuelta
 
esPositivo:
 sw $2, res($6)
 j vuelta 
 
vuelta: addi $7, $7, 1
 addi $6, $6, 4
 bne $7, $8 loop
 
 li $2, 10
 syscall
 

Eso es todo. Espero que os sirvan. Si tenéis alguna duda comentadla.

Saludos;)