martes, 29 de agosto de 2023

PHP: Una arquitectura de aplicación personalizada

Intentando resolver el problema planteado en esta entrada, me había puesto a crear (con mucha ayuda) un sistema MVC personalizado para aplicaciones PHP tal como se muestra en esta otra entrada. Tambien consideré aprender a fondo Codeigniter e incluso Laravel. Después de darle vueltas al asunto me he propuesto crear una arquitectura parecida a la MVC pero un poco más sencilla, que permita implementar buenas practicas de programación. Las principales características de esta opción son las siguientes:

  • No usa POO. Me parece que con la programación estructurada se mantiene más sencillo el código y a efectos prácticos, para los proyectos que pienso manejar, funciona bien.
  • Se divide el proyecto en dos bloques: Del lado dl cliente y del lado del servidor.
  • Se elimina el controlador principal que se usa en la arquitectura MVC.
  • Básicamente solo quedan las vistas y los modelos, las cuales se encuentran en carpetas distintas pero tienen los mismos nombres. Los controladores individuales se ha fusionado con el modelo pero su presencia es casi inperceptible.
  • Siempre se invoca primero el modelo y luego la vista: siempre en ese orden.
Estructura de la carpeta

El siguiente código es mi versión personalizada de una aplicación hecha con la arquitectura personalizada que he planteado.

index.php

<a href="mo/estudiante_listar.php"> Listar </a>

mo/a_conectar.php

<?php 

if (!($link=mysqli_connect("localhost","root","9810402254"))) 
   
	{ 
      
	echo "Error conectando a la base de datos.";
  
      exit(); 
   
	} 

if (!mysqli_select_db($link,"colegio")) 
   
	{ 
      
	echo "Error seleccionando la base de datos.";
  
      exit(); 
  
	}
  
?>

mo/estudiante_listar.php

<?php 
$dato = array();

require("a_conectar.php");
$rs = mysqli_query($link," select * from estudiantes ");

while($f = mysqli_fetch_array($rs))
        {  
	$dato[] = $f;
	}

mysqli_free_result($rs);
mysqli_close($link); 

require("../vi/estudiante_listar.php");
?>

vi/estudiante_listar.php

<table>
<tr>
<td>ID</td>
<td>NOMBRES</td>
<td>APELLIDOS</td>
</tr>
 
<?php foreach ($dato as $d): ?>
   <tr>
   <td><?php echo $d['id'] ?></td>
   <td><?php echo $d['nombres'] ?></td>
   <td><?php echo $d['apellidos'] ?></td>
   </tr>
<?php endforeach; ?>

</table>

sábado, 26 de agosto de 2023

PHP: Creando una aplicación MVC personalizada con POO

El siguiente código es una versión personalizada de una aplicación hecha en PHP que permite realizar la misma acción que la de esta entrada. Precisamente la única diferencia es que se implementa en una arquitectura MVC y la mayoría ha sido adaptado de otros códigos encontrados en Internet.

Estructura de carpetas

index.php

<?php 

require_once 'conf/config.php';

if(!isset($_GET["c"])) $_GET["c"] = constant("DEFAULT_CONTROLLER");
if(!isset($_GET["a"])) $_GET["a"] = constant("DEFAULT_ACTION");

// Establece la ruta donde se encuentra el controlador
$controller_path = 'controladores/'.$_GET["c"].'.php';

// Pregunta si el archivo con el controlador existe.
if(!file_exists($controller_path)) $controller_path = 'controladores/'.constant("DEFAULT_CONTROLLER").'.php';

/* Load controller */
require_once $controller_path;
$controllerName = $_GET["c"].'Controlador';
$controller = new $controllerName();

// crea $dato como un arreglo vacío
$dato = array();
// Si el método existe lo ejecuta y recibe el resultado en el arreglo $dato
if(method_exists($controller,$_GET["a"])) $dato = $controller->{$_GET["a"]}(); 


// Carga las vistas
require_once 'vistas/plantillas/cabeza.php';
require_once 'vistas/'.$controller->vista.'.php';
require_once 'vistas/plantillas/pie.php';

?>

conf/config.php

<?php

/* Valores de conexión a la base de datos*/
define("DB_HOST", "localhost");
define("DB", "colegio");
define("DB_USER", "root");
define("DB_PASS", "9810402254");

/* Controlador y acción (método) por defecto. */
define("DEFAULT_CONTROLLER", "estudiante");
define("DEFAULT_ACTION", "listar");

?>

controladores/estudiante.php

<?php 

// Este controlador usa un modelo 
require_once 'modelos/estudianteModelo.php';


class estudianteControlador 
	{
	//la variable vista contiene el archivo que mostrará la vista al usuario 
	public $vista ;

	public function __construct() 
		{
		
		}

		public function listar()
		{
		// Se asigna el nombre de la vista que se mostrará al usuario como resultado de esta acción 
		$this->vista = "estudianteListar";
		//Creación del modelo que accederá a la base de datos. 
		$m = new estudianteModelo();
		// Se ejecuta el método para listar y se obtiene el resultado en la variable rs
		$rs = $m->obtenerEstudiantes();
		// Se devuelve el arreglo obtenido. 
		return $rs;
		}

	}


?>

modelos/bd.php

<?php 

// Establece una conexión con la base de datos usando PDO y de acuerdo a los valores que se encuentran en el archivo de configuración.

require_once 'conf/config.php';

class bd {

	private $host;
	private $db;
	private $user;
	private $pass;
	public $conection;

	public function __construct() {		

		$this->host = constant('DB_HOST');
		$this->db = constant('DB');
		$this->user = constant('DB_USER');
		$this->pass = constant('DB_PASS');

		try {
           $this->conection = new PDO('mysql:host='.$this->host.'; dbname='.$this->db, $this->user, $this->pass);
        } catch (PDOException $e) {
            echo $e->getMessage();
            exit();
        }

	}

}

?>

modelos/estudianteModelo.php

<?php 

require_once 'modelos/bd.php';

class estudianteModelo {

	// la variable con guardará la conexión.
	private $con;

	public function __construct() 
			{

			}

	// Establece y guarda el valor de la conexión.
	public function establecerConeccion(){
		$dbObj = new bd();
		$this->con = $dbObj->conection;
	}


	public function obtenerEstudiantes(){
		
		// Establece la conexión.
		$this->establecerConeccion();
		// Realiza la consulta y guarda el resultado.
		$sql = "SELECT * FROM ESTUDIANTES";
		$s = $this->con->prepare($sql);
		$s->execute();
		// fetchAll — Devuelve un array que contiene todas las filas del conjunto de resultados.
		$rs = $s->fetchAll();
		// Retorna el valor del resutado.
		return $rs;
	}

// Considerar establecer un destructor para cerrar la conexión a la base de datos. Aunque el recolector de basura de PHP también se encargrá de esta operación.
	
}

?>

vistas/estudianteListar.php

<table>
    <tr>
        <th>Id</th>
        <th>Nombres</th>
        <th>Apellidos</th>

    </tr>
    <?php foreach ($dato as $r): ?>

        <tr>
            <td><?php echo $r["id"] ?></td>
            <td><?php echo $r["nombres"] ?></td>
            <td><?php echo $r["apellidos"] ?></td>

        </tr>

     <?php endforeach; ?>
</table>

vistas/plantillas/cabeza.php

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title></title>
</head>
<body>

vistas/plantillas/pie.php

</div>
</body>
</html>

miércoles, 19 de julio de 2023

La increíble vida de Walter Mitty

No es ni de cerca mi actor ni director favorito. Sus películas, por lo general perteneciente al genero cómico, siempre me han parecido banales. Pero a cada quien lo suyo. Esta pelicula es una joya: construccion de personajes, banda sonora, fotografía, su trama y su mensaje por mencionar algunos aspectos. En pocas palabras: es una de las mejores peliculas bien hecha que he podido ver. No tiene presa mala. He aquí una de sus escenas más memorables.

Arte Pixel

  CORAZÓN 1 
Ancho: 11

  MUJER  
Ancho: 34

  PINGUINO 
Ancho: 10

  CORAZÓN 2 
Ancho: 13

En el siguiente script se puede probar las instrucciones para generar Arte Pixel:

Ancho:

Instrucciones:

Código fuente del generador de Arte Pixel en JavaScript:

<div>
<form  style="background-color: lightgrey;" > 
Ancho:<br> <input type = text id =ancho placeholder="Ancho"  /> <br>
Instrucciones:<br> <textarea rows="30" cols="20" id="texto" placeholder="Instrucciones">


</textarea>
<p> <button onclick="armar()" type="button">Armar</button> </p>   
<p> <button onclick="borrar()" type="button">Borrar</button> </p>   
</form>
</div>

<div id ="tabla">

</div>

<script>  

function armar() 
 {  
  var s,text,a,color,pasos,linea,i,ancho,anchoactual,j,canlineas,colorcelda;
  s = document.getElementById("texto").value;
  ancho = parseInt(document.getElementById("ancho").value);
  a = s.split(/\n/);
  text = "<table border = 1  cellpadding= 0 cellspacing = 0>";
   i=0;
   anchoactual = 0;
   canlineas = a.length;
   while (i < canlineas)
   {
    linea = a[i];
    color = linea[0];
    pasos = parseInt(linea.slice(1));
    for (j=1;j<=pasos;j++)
    {
      
      if (anchoactual==0)
      {
        text = text + "<tr>";        
      }

      colorcelda = " ";
      if (color == "N" || color == "n" )
        {
          colorcelda = " bgcolor = black ";
        }
        else if (color == "A" || color == "a" )
        {
          colorcelda = " bgcolor = blue ";
        }
        else  if (color == "J" || color == "j" )
        {
          colorcelda = " bgcolor = orange ";
        }
        else if (color == "M" || color == "m" )
        {
          colorcelda = " bgcolor = brown ";
        }
        else if (color == "V" || color == "v" )
        {
          colorcelda = " bgcolor = green ";
        }
        else if (color == "R" || color == "r" )
        {
          colorcelda = " bgcolor = red ";
        }
        else if (color == "G" || color == "g" )
        {
          colorcelda = " bgcolor = gray ";
        }
        else
        {
          colorcelda = "  ";
        }

      text = text + "<td "+colorcelda+">    </td>";
      anchoactual++;
      if (anchoactual>=ancho)
      {
        text = text + "</tr>";
        anchoactual=0;
      }
    }
    i++;  
   }
   text = text+"</table>";
   document.getElementById("tabla").innerHTML = text;  
 }  

function borrar() 
 {  
  var text;
  text = "";
   document.getElementById("tabla").innerHTML = text;  
 }  


</script>  

martes, 9 de mayo de 2023

Introducción a Appinventor 2 (Offline)

Para mí, App Inventor 2 es la manera más fácil y sencilla de crear aplicaciones para Android. Existe una forma de trabajar on-line que es la que normalmente uso y tambien la forma off-line la cual uso en entornos donde no es posible o es muy dificil el accesso a Internet.

domingo, 30 de abril de 2023

Software para Aplicación de Pruebas (SAP)

SAP for Android 2.5

SAP for Windows 1.0

La aplicación SAP fue concebida para realizar evaluaciones tipo test a partir de lecturas. Se creó una versión para Windows usando Visual Studio 2018 (Visual Basic) y una versión para Android usando AppInventor 2. En la actualidad he decidido usarla en el último grado como material para el refuerzo de las pruebas Saber.

PRUEBA ÁREA TEMA CANT. PREG.
O6HC01 Tecnología  Historia del computador (1) 10
O6HC02 Tecnología  Historia del computador (2) 10
O6MATE01 Matemáticas  Gráficas 20
06ME01 Tecnología  Metales 10
06PA01 Tecnología  Papel 10
07AL01 Tecnología  Escritura (1) 10
07AL02 Tecnología  Escritura (2) 10
07QM01 Tecnología  Productos para el aseo 10
08FF01 Tecnología  Ofimática 10
09MB01 Tecnología  Preguntas "Mentes Brillantes: Von Braun vs Korolev" 5
SB11CC01 Pre-Saber 11 Competencias ciudadanas (1) 10
SB11CC02 Pre-Saber 11  Competencias ciudadanas (2) 20
SB11CC03 Pre-Saber 11  Competencias ciudadanas (3) 30
SB11LC01 Pre-Saber 11  Lectura Crítica (1)  10
SB11LC02 Pre-Saber 11  Lectura Crítica (2) * 10
SB11LC03 Pre-Saber 11  Lectura Crítica (3) * 15
SB11LC04 Pre-Saber 11  Lectura Crítica (4) * 15
SB11LC05 Pre-Saber 11  Lectura Crítica (5) 15
SB11LC06 Pre-Saber 11  Lectura Crítica (6) * 15

Los siguientes son algunos ajustes y anotaciones para tener en cuenta en versiones posteriores, si se llegan a implementar:

  • Las pruebas marcadas con asterisco * contienen imágenes con texto que no se alcanzan a visualizar bien. Es necesario implementar el zoom para las imágenes.
  • La versión para Android no funcionará en un sistema Android Superior a la versión 11. Esto se debe al uso del valor Legacy en la propiedad FileScope.
  • La versón para Android muestra las preguntas y las opciones de manera aleatoria. La versión para windows no lo hace.
  • En la versón para Android, al instalarla, se debe copiar la carpeta sap en la ubicación /storage/emulated/0/ .Para evitar este paso adicional se pretende en una futura versión empaquetar el contenido de esta carpeta dentro del mismo archivo APK.

miércoles, 26 de abril de 2023

¿Qué evalúa la prueba de Lectura Crítica Saber 11?

1. Identificar y entender los contenidos locales que conforman un texto.

Comprender el significado de palabras y frases y oraciones que aparecen explicitamente (clara y directa) en el texto.

  • Manejo de conectores.
  • Función de los conectores.
  • Sinonimos y antonimos.
  • Significados.
  • Analogías.

  • 2. Comprender cómo se articulan las partes de un texto para darles un sentido global.

    La capacidad de entender cómo las frases, oraciones y parrafos se relacionan entre sí para formar diferentes tipos de texto y sus respectivas partes.

  • Inferencias globales.
  • Estructura del texto (argumentativo, narrativo, expositivo).
  • Relación entre párrafos.
  • Tipos de texto.
  • Inferir, cocluir, deducir (obtener información implicita)

  • 3. Capacidad para reflexionar a partir de un texto y evaluar su contenido.

    La capacidad de enfrentar un texto criticamente para evaluar la validez de argumentos, derivar implicaciones y reconocer estrategias , entre otras.

  • Conclusión y premisa.
  • Validez de conclusiones.
  • Estrategias de argumentación (lo que hace que un argumento sea más fuerte).
  • Juicios de valor.
  • Diferenciar hechos de opiniones.
  • martes, 25 de abril de 2023

    Orgullo y prejuicio

    "Es una verdad mundialmente reconocida que un hombre soltero, poseedor de una gran fortuna, necesita una esposa.

    Sin embargo, poco se sabe de los sentimientos u opiniones de un hombre de tales condiciones cuando entra a formar parte de un vecindario. Esta verdad está tan arraigada en las mentes de algunas de las familias que lo rodean, que algunas le consideran de su legítima propiedad y otras de la de sus hijas".

    Así empieza la novela "Orgullo y prejuicio" de la escritora inglesa Jane Austen. Se trata de una de mis novelas favoritas, seguramente la más favorita. Me encanta la forma como están construidos los personajes. También su lenguaje inteligente y que está totalmente alejado de las obsenidad y falta de decoro que abunda en la actualidad en las obras literarias.

    Si el lector aún no se ha enterado de su contenido, recomiendo leer o escuchar la novela. Luego puede ver la miniserie de la BBC y la película de 2005.

    Lista de reproducción Audiolibro "Orgullo y prejuicio" de el canal de YouTube "El cuenterero"

    lunes, 10 de abril de 2023

    PHP: ¡No quiero volver a programar así!

    Uno de mis lenguajes favoritos de programación es PHP (si acaso el que más me gusta). Cuando tuve el primer contacto con él, por allá en el 2004 me gustó mucho lo fácil que era crear aplicaciones web; y además con AppServ que instalaba y dejaba todo listo: PHP, MySQL,phpyAdmin y el servidor Apache.

    Si se tiene una base de datos llamada colegio y una tabla estudiantes con tres campos: id, nombres y apellidos, crear un script para listar la tabla usando PHP es tan fácil como escribir esto:

    <?php 
    if (!($link=mysqli_connect("localhost","root","9810402254"))) 
       { 
          echo "Error conectando a la base de datos."; 
          exit(); 
       } 
    
    if (!mysqli_select_db($link,"colegio")) 
       { 
          echo "Error seleccionando la base de datos."; 
          exit(); 
      }
    
    $rs = mysqli_query($link," select * from estudiantes ");
    
    echo "<table>";
    echo "<tr>";
    echo "<td>ID</td>";
    echo "<td>NOMBRES</td>";
    echo "<td>APELLIDOS</td>";
    echo "</tr>";
    
    while($f = mysqli_fetch_array($rs))
             {  
                echo "<tr>";
                echo "<td>". $f["id"]."</td>";
                echo "<td>". $f["nombres"]."</td>";
                echo "<td>". $f["apellidos"]."</td>";
                echo "</tr>";
             }
    
    echo "<table>";
    
    mysqli_free_result($rs);
    mysqli_close($link); 
    
    ?>
    
    

    El gran problema es que esta forma de programar en PHP, que se usó extensivamente en los noventas y parte de la década de los dosmil, conllevaba muy malas prácticas de programación. El asunto llegó a un punto en el que algunos renegaron del lenguaje.

    Lo estoy viviendo en la actualidad. hace años creé una aplicación web con PHP que ha ido creciendo hasta el punto de volverse muy dificil de mantener, precisamente por la forma como fue escrita. Es una aplicación en la que ha trabajado una sola persona, pero si se tratase de un trabajo colaborativo sería un caos por no decir casi imposible de mantener. 

    La solución: El programador puede usar una arquitectura como la MVC (modelo, vista, programador) o puede usar frameworks, los cuales ya trabajan con una arquitectura especifíca y "obligaban" a los programadores a tener buenas prácticas.

    Por ello me digo: ¡Ya quiero programar más así en PHP! De ahora en adelante o implemento yo mismo la arquitectura MVC o aprendo a usar uno de los framework existentes.

    domingo, 2 de abril de 2023

    Stargate: puerta a las estrellas

    Unos meses antes del inicio de la pandemía ya había visto la pelicula que dió inicio a la franqucia y luego durante la parte más crítica de la pandemia, durante el aíslamiento, quedé cautavado con las series y peliculas.

    Me gustan mucho las películas y series de ciencia ficción y aventura. Stargate es especial porque presentó elementos que eran innovadores, ideas originales y personajes entrañables.

    En el piloto de la serie Stargate SG-1 se encuentra la única escena cuestionable que dura solo unos segundos: totalmente innecesaria y, por supuesto, no aporta nada. No recuerdo ninguna otra escena en todas las peliculas y series con alguna otra escena de ese tipo.

    Lástima que, al parecer, la franquicia ya ha muerto. Sin embargo, ha quedado en mi memoria como una de las mejores. No es la que ocupa el primer lugar pero está muy cerca.

    Información completa sobre esta franquicia: Stargate en Wikipedia

    SG-1 Temporada 1 en INTERNET ARCHIVES: Stargate SG-1 - Temporada 1 - (Audio Latino) IA

    sábado, 18 de marzo de 2023

    Aprende inglés cantando con Sing 2

    'Cause you're a sky, 'cause you're a sky full of stars
    I'm gonna give you my heart

    'Cause you're a sky, 'cause you're a sky full of stars
    'Cause you light up the path
    I don't care, go on and tear me apart

    I don't care if you do, ooh-ooh, ooh
    'Cause in a sky, 'cause in a sky full of stars
    I think I saw you


    The moment I wake up
    Before I put on my makeup (makeup)
    I say a little prayer for you
    And while combing my hair, now
    And wondering what dress to wear, now (wear, now)
    I say a little prayer for you

    Forever (forever), forever ('ever)
    You'll stay in my heart and I will love you
    Forever (forever), and ever (ever)
    We never will part, oh, how I love you
    Together (together), together (together)
    That's how it must be
    To live without you would only mean heartbreak for me


    sábado, 4 de marzo de 2023

    Entrenador del teclado

    El objetivo de esta actividad consiste en que el estudiante se familiarice con la escritura de texto usando el teclado del computador.

    Enlace de descarga
    EntrenadorTeclado.zip

    martes, 21 de febrero de 2023

    Práctica con el ratón

    El objetivo de esta actividad es familiarizar al estudiante con el uso del ratón: al hacer clic, doble clic, clic sostenido y clic con el botón derecho.

    Enlace de descarga
    PracticaRaton.zip

    sábado, 18 de febrero de 2023

    T-KLA

    El objetivo de esta actividad es familiarizar al estudiante con cada una de las teclas que componen el teclado del computador

    Enlace de descarga
    T-KLA.zip

    domingo, 15 de enero de 2023

    Videojuego Educativo "Gimnasio del saber"

    El videojuego "Gimnasio del saber" está creado con el objetivo de reforzar competencias en el área de lectura crítica y en matemáticas.

    Se puede programar una práctica con varias sesiones en la sala de informática a comienzo del año escolar. Resulta adecuado porque, al ser una actividad que abarcará varias sesiones, permitirá que los estudiantes que llegan tarde al inicio de clases puedan incorporarse de manera menos traumatica.

    Presenta dos niveles: lectura critica y matemáticas. En cada uno de estos niveles se deben recoger siete llaves. Si la máxima calificación es 5.0 cada llave tendrá un valor de 0.72 aproximadamete.







    Para salir se debe presionar la combinación de teclas ALT + F4 (Presionar la tecla ALT, se mantiene presionada y se pulsa la tecla de función F4).

    domingo, 20 de noviembre de 2022

    COBOL: suma de dos números

    COBOL no estaba muerto, solo andaba de parranda. En algún momento tuve la oportunidad de aprender un poco sobre COBOL, luego me olvidé de este lenguaje. Llegué a pensar que había quedado en desuso. Si bien no es un lenguaje muy conocido hoy en día, los grandes sistemas informáticos bancarios del planeta lo usan. El siguiente código fue probado en OpenCobolIDE.

    IDENTIFICATION DIVISION.
    PROGRAM-ID. SUMA.
    DATA DIVISION.
    FILE SECTION.
    WORKING-STORAGE SECTION.
    01 NUM1 PIC 9(4).
    01 NUM2 PIC 9(4).
    01 RESULTADO PIC 9(5).
    PROCEDURE DIVISION.
    MAIN-PROCEDURE.
    	DISPLAY "Introduce el primer número: ".
    	ACCEPT NUM1.
    	DISPLAY "Introduce el segundo número: ".
    	ACCEPT NUM2.
    	ADD NUM1 TO NUM2 GIVING RESULTADO.
    	DISPLAY "El resultado es " RESULTADO.
    	STOP RUN.
    END PROGRAM SUMA.
    

    jueves, 3 de noviembre de 2022

    PHP: suma de dos números

    PHP es un lenguaje de programación del lado del servidor. El siguiente ejemplo suma dos números que se han introducido en un formulario HTML. El código HTML se ha escrito junto al código PHP en el mismo archivo, lo cual viene a ser una mala práctica de programación. Sin embargo, en esta ocasión la pasamos por alto puesto que se trata de un ejemplo básico.

    <html>
    <head>
    <title>Suma de números en PHP</title>
    </head>
    <body>
    <form method="POST">
    Primer número:   <input type="text" name="numero1"> <br>
    Segundo número: <input type="text" name="numero2"> <br>
    <input type="submit" value="sumar"> <br>
    </form>
    </body>
    </html>
    
    <?php
    	if($_POST)
    	{	
    		$num1 = $_POST['numero1'];
    		$num2 = $_POST['numero2'];
    		$suma = $num1 + $num2;
    		echo "<p>La suma de ".$num1." y ".$num2." es ".$suma."</p>"; 
    	}
    ?>
    
    

    miércoles, 2 de noviembre de 2022

    C++: suma de dos números

    Mientras que el lenguaje C maneja el paradigma de programación estructurada, C++ incorpora programación orientada a objetos. El siguiente código muestra la suma de dos números enteros en C++ usando programación estructurada. Por supuesto, se podría implementar una versión con POO.

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
       int num1, num2, suma;
       cout << "Primer número: " ;
       cin >> num1;
       cout << "Segundo número: " ;
       cin >> num2;
       suma = num1 + num2;
       cout <<" la suma es : " <<suma;
    }