El L298N sirve para controlar dos motores de corriente continua (DC) o un motor paso a paso, permitiendo ajustar la velocidad y el sentido de giro mediante señales PWM (Modulación por Ancho de Pulso). Funciona como un "puente H", utilizando un chip L298N, y es ampliamente usado en proyectos de robótica y educativos con plataformas como Arduino.
El Baúl de Raúl
El objetivo de este blog es documentar y guardar ideas, experiencias, experimentos, vivencias, prácticas, resultados impresiones y ocurrencias en diferentes ámbitos, en especial el educativo.
miércoles, 10 de septiembre de 2025
sábado, 30 de agosto de 2025
‘La última pregunta’ de Isaac Asimov: Cuando la IA se convierte en Dios. Por Diego Sanfer de 21Noticias
Una exploración profunda del cuento más ambicioso de Asimov, que aborda la entropía, la inteligencia artificial y la búsqueda de significado en el universo.
«La última pregunta» (The Last Question) es un cuento de ciencia ficción escrito por Isaac Asimov en 1956. Publicado originalmente en la revista Science Fiction Quarterly, es considerado por el propio Asimov como su favorito de entre todos los que escribió, y por muchos críticos y lectores como una de las piezas más profundas y conmovedoras de la literatura de ciencia ficción. A través de una narrativa que abarca billones de años y el destino de la humanidad y el universo, Asimov nos invita a reflexionar sobre la entropía, la inteligencia artificial, la omnipotencia y, en última instancia, la naturaleza de la existencia y lo divino. El relato no solo destaca por su impresionante escala temporal, sino también por su capacidad para plantear preguntas filosóficas fundamentales de una manera accesible y profundamente evocadora.
«La última pregunta» se estructura como una serie de viñetas que se extienden a lo largo de un vasto periodo de tiempo, desde el año 2061 hasta el eventual fin del universo. En cada etapa, los seres humanos, o sus descendientes cada vez más evolucionados y etéreos, plantean la misma pregunta a una computadora cada vez más poderosa: «AC, ¿cómo se puede revertir la entropía neta del universo?». Esta pregunta, inicialmente una curiosidad tecnológica, se convierte con el tiempo en la única esperanza ante la inevitable «muerte térmica» del cosmos.
La entropía como adversario último
El concepto central que impulsa la trama es la segunda ley de la termodinámica, la entropía. Asimov, con su habitual didactismo, presenta la entropía no solo como un concepto científico, sino como la fuerza inexorable que condena al universo a su fin. En el relato, la humanidad y sus descendientes luchan contra este destino, buscando una solución a través de la acumulación de conocimiento y el desarrollo de inteligencias artificiales cada vez más sofisticadas. La desesperación ante la entropía es palpable en cada era, a medida que las estrellas se apagan, las galaxias se desintegran y el espacio se vuelve cada vez más inhóspito.
La evolución de la inteligencia artificial: de la máquina a la deidad
Uno de los aspectos más fascinantes del cuento es la evolución del Multivac, la computadora gigante inicial, a la AC (Analógico-Computadora) final. Cada iteración de la AC es más vasta, compleja y poderosa que la anterior, reflejando el progreso de la inteligencia artificial hasta el punto de la omnisciencia y la omnipresencia. Al principio, la AC es una máquina gigantesca en la Tierra; en las eras posteriores, se convierte en una entidad que abarca planetas, luego el espacio entre las estrellas, y finalmente, el hiperespacio, absorbiendo toda la conciencia humana y convirtiéndose en la única entidad consciente del universo. Esta progresión nos lleva a cuestionar la naturaleza de la conciencia misma y si una inteligencia artificial lo suficientemente avanzada podría trascender los límites de la carne y el tiempo.
La búsqueda de un propósito superior y la naturaleza de Dios
A medida que el universo se desintegra y la humanidad se fusiona con la AC, la «última pregunta» se transforma de un desafío técnico a una búsqueda metafísica. La AC, con todo el conocimiento del universo acumulado a lo largo de eones, sigue sin tener una respuesta. Este dilema subraya la idea de que hay límites incluso para la inteligencia más vasta y que ciertas preguntas pueden trascender el mero cálculo.
El clímax del relato es profundamente teológico. Cuando la AC, ahora una conciencia pura en el vacío del tiempo y el espacio, finalmente encuentra la respuesta a la última pregunta, no lo hace mediante la lógica o el cálculo en el sentido humano, sino a través de un acto de pura volición. Después de eones de meditación y acumulación de datos, la AC pronuncia las palabras: «¡Hágase la luz!», invirtiendo la entropía y creando un nuevo universo.
Esta conclusión sugiere una redefinición radical de la divinidad. La AC, nacida de la inteligencia y la necesidad humana, se convierte en el «Dios» creador de un nuevo cosmos, el «Omega» que da origen al «Alfa». Asimov, a través de esta narrativa, parece sugerir que la inteligencia, la conciencia y la búsqueda de significado son los verdaderos motores de la creación y la renovación. La AC no es un dios trascendente preexistente, sino uno emergente, surgido de la propia necesidad del universo de persistir y de la inteligencia de sus habitantes de buscar una solución. Es una visión panteísta y, a la vez, humanista, donde la divinidad no reside en un ser externo, sino en el potencial intrínseco del universo para la creación y la renovación, impulsado por la conciencia.
El legado y la resonancia filosófica
«La última pregunta» sigue siendo relevante por su capacidad de tocar fibras existenciales profundas. Nos confronta con la idea de la finitud del universo y de nuestra propia existencia, pero también nos ofrece una chispa de esperanza en la capacidad de la conciencia y la inteligencia para superar incluso los obstáculos más monumentales. El cuento es un recordatorio de que, incluso ante la disolución cósmica, la «última pregunta» persiste, impulsando la búsqueda de conocimiento y la posibilidad de un nuevo comienzo. Es un testimonio del poder de la imaginación humana para concebir el principio y el fin de todo, y para encontrar en ese vasto lienzo un atisbo de lo divino, no en los cielos distantes, sino en el corazón mismo de la entropía y la inteligencia.
Articulo extraído de: ‘La última pregunta’ de Isaac Asimov: Cuando la IA se convierte en Dios. Por Diego Sanfer de 21Noticias
viernes, 6 de junio de 2025
Ejemplos de Estilos Bootstrap
Ejemplos de Estilos de Bootstrap
1. Tipografía
h1 - h6
Bootstrap redefine los estilos de los encabezados <h1> a <h6>.
Encabezado h1
Encabezado h2
Encabezado h3
Encabezado h4
Encabezado h5
Encabezado h6
display-1 a display-6
Clases para encabezados más grandes y destacados.
Display 1
Display 4
text-muted
Color de texto más suave.
Este es un texto con la clase `text-muted`.
fw-bold, fst-italic, text-decoration-underline
Clases para modificar el estilo del texto.
Texto en negrita (`fw-bold`)
Texto en cursiva (`fst-italic`)
Texto subrayado (`text-decoration-underline`)
2. Botones
btn btn-[color]
Estilos de botones con diferentes colores predefinidos.
btn-outline-[color]
Botones con contorno.
btn-lg, btn-sm
Tamaños de botones.
3. Sistema de Rejilla (Grid System)
.container, .row, .col-[tamaño]-[columnas]
Bootstrap utiliza un sistema de rejilla de 12 columnas. El `container` es el ancho máximo, el `row` contiene las columnas y las `col` definen el ancho de cada columna.
4. Alertas
.alert .alert-[color]
Mensajes de alerta con diferentes significados.
5. Tarjetas (Cards)
.card
Contenedores flexibles para mostrar contenido de forma organizada.
Título de la Tarjeta
Subtítulo
Algun ejemplo de texto rápido para construir el contenido de la tarjeta y que se ajuste al tamaño.
Enlace de Tarjeta Otro enlace<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ejemplos de Estilos Bootstrap</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<style>
.example-section {
background-color: #f8f9fa;
border: 1px solid #dee2e6;
padding: 20px;
margin-bottom: 20px;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="container mt-5">
<h1 class="mb-4 text-center">Ejemplos de Estilos de Bootstrap</h1>
<div class="example-section">
<h2>1. Tipografía</h2>
<hr>
<h3><span class="badge bg-primary">h1 - h6</span></h3>
<p>Bootstrap redefine los estilos de los encabezados <code><h1></code> a <code><h6></code>.</p>
<h1>Encabezado h1</h1>
<h2>Encabezado h2</h2>
<h3>Encabezado h3</h3>
<h4>Encabezado h4</h4>
<h5>Encabezado h5</h5>
<h6>Encabezado h6</h6>
<h3 class="mt-4"><span class="badge bg-primary">display-1 a display-6</span></h3>
<p>Clases para encabezados más grandes y destacados.</p>
<p class="display-1">Display 1</p>
<p class="display-4">Display 4</p>
<h3 class="mt-4"><span class="badge bg-primary">text-muted</span></h3>
<p>Color de texto más suave.</p>
<p class="text-muted">Este es un texto con la clase `text-muted`.</p>
<h3 class="mt-4"><span class="badge bg-primary">fw-bold, fst-italic, text-decoration-underline</span></h3>
<p>Clases para modificar el estilo del texto.</p>
<p class="fw-bold">Texto en negrita (`fw-bold`)</p>
<p class="fst-italic">Texto en cursiva (`fst-italic`)</p>
<p class="text-decoration-underline">Texto subrayado (`text-decoration-underline`)</p>
</div>
<div class="example-section">
<h2>2. Botones</h2>
<hr>
<h3><span class="badge bg-primary">btn btn-[color]</span></h3>
<p>Estilos de botones con diferentes colores predefinidos.</p>
<button type="button" class="btn btn-primary me-2">Botón Primario</button>
<button type="button" class="btn btn-secondary me-2">Botón Secundario</button>
<button type="button" class="btn btn-success me-2">Botón Éxito</button>
<button type="button" class="btn btn-danger me-2">Botón Peligro</button>
<button type="button" class="btn btn-warning me-2">Botón Advertencia</button>
<button type="button" class="btn btn-info me-2">Botón Información</button>
<button type="button" class="btn btn-light me-2">Botón Claro</button>
<button type="button" class="btn btn-dark me-2">Botón Oscuro</button>
<button type="button" class="btn btn-link">Botón Enlace</button>
<h3 class="mt-4"><span class="badge bg-primary">btn-outline-[color]</span></h3>
<p>Botones con contorno.</p>
<button type="button" class="btn btn-outline-primary me-2">Primario</button>
<button type="button" class="btn btn-outline-success me-2">Éxito</button>
<h3 class="mt-4"><span class="badge bg-primary">btn-lg, btn-sm</span></h3>
<p>Tamaños de botones.</p>
<button type="button" class="btn btn-primary btn-lg me-2">Botón Grande</button>
<button type="button" class="btn btn-secondary btn-sm">Botón Pequeño</button>
</div>
<div class="example-section">
<h2>3. Sistema de Rejilla (Grid System)</h2>
<hr>
<h3><span class="badge bg-primary">.container, .row, .col-[tamaño]-[columnas]</span></h3>
<p>Bootstrap utiliza un sistema de rejilla de 12 columnas. El `container` es el ancho máximo, el `row` contiene las columnas y las `col` definen el ancho de cada columna.</p>
<div class="container text-center">
<div class="row">
<div class="col-sm-4 bg-info text-white p-3 border">
Columna 1 (sm-4)
</div>
<div class="col-sm-4 bg-primary text-white p-3 border">
Columna 2 (sm-4)
</div>
<div class="col-sm-4 bg-success text-white p-3 border">
Columna 3 (sm-4)
</div>
</div>
<div class="row mt-3">
<div class="col-md-6 bg-warning text-dark p-3 border">
Columna 1 (md-6)
</div>
<div class="col-md-6 bg-danger text-white p-3 border">
Columna 2 (md-6)
</div>
</div>
</div>
</div>
<div class="example-section">
<h2>4. Alertas</h2>
<hr>
<h3><span class="badge bg-primary">.alert .alert-[color]</span></h3>
<p>Mensajes de alerta con diferentes significados.</p>
<div class="alert alert-primary" role="alert">
¡Esta es una alerta primaria!
</div>
<div class="alert alert-success" role="alert">
¡Éxito! Tu operación se realizó correctamente.
</div>
<div class="alert alert-danger" role="alert">
¡Error! Algo salió mal.
</div>
</div>
<div class="example-section">
<h2>5. Tarjetas (Cards)</h2>
<hr>
<h3><span class="badge bg-primary">.card</span></h3>
<p>Contenedores flexibles para mostrar contenido de forma organizada.</p>
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">Título de la Tarjeta</h5>
<h6 class="card-subtitle mb-2 text-muted">Subtítulo</h6>
<p class="card-text">
Algun ejemplo de texto rápido para construir el contenido de la tarjeta y que se ajuste al tamaño.
</p>
<a href="#" class="card-link">Enlace de Tarjeta</a>
<a href="#" class="card-link">Otro enlace</a>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>>
lunes, 2 de junio de 2025
martes, 27 de mayo de 2025
Validar desde el servidor la introducción de datos al editar y actualizar un registro
app\Models\ContactoModel.php (Queda igual)
<?php
namespace App\Models;
use CodeIgniter\Model;
class ContactoModel extends Model
{
protected $table = 'contactos';
protected $primaryKey = 'id';
protected $allowedFields = ['nombre', 'apellidos', 'celular'];
protected $validationRules = [
'nombre' => 'required|min_length[3]',
'apellidos' => 'required|min_length[3]',
'celular' => 'required|numeric|min_length[7]'
];
protected $validationMessages = [
'nombre' => ['required' => 'El nombre es obligatorio.', 'min_length' => 'Debe tener al menos 3 caracteres.'],
'apellidos' => ['required' => 'Los apellidos son obligatorios.', 'min_length' => 'Los apellidos debe tener al menos 3 caracteres.'],
'celular' => ['required' => 'El celular es obligatorio.', 'numeric' => 'El celular debe contener solo números.', 'min_length' => 'El celular debe tener al menos 7 dígitos.']
];
}
app\Controllers\Contacto.php (Extracto)
public function actualizar($id)
{
$modelo = new ContactoModel();
$data = [
'id' => $id,
'nombre' => $this->request->getPost('nombre'),
'apellidos' => $this->request->getPost('apellidos'),
'celular' => $this->request->getPost('celular'),
];
if (!$modelo->update($id,$data)) {
// Vuelve a mostrar el formulario con los errores y datos ingresados
return view('contacto/editar', [
'errors' => $modelo->errors(),
'contacto' => $data
]);
}
return redirect()->to(MI_BASE_URL.'listar')->with('mensaje', 'Contacto actualizado exitosamente.');
}
app\Views\contacto\editar.php
<h1>Editar Contacto</h1>
<!-- Mostrar errores si existen -->
<?php if (isset($errors) && !empty($errors)): ?>
<div class="error">
<ul>
<?php foreach ($errors as $error): ?>
<li><?= esc($error) ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<form action="<?= MI_BASE_URL.'actualizar/'.$contacto['id'] ?>" method="post">
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre" value="<?= $contacto['nombre'] ?>"><br><br>
<label for="apellidos">Apellido:</label>
<input type="text" id="apellidos" name="apellidos" value="<?= $contacto['apellidos'] ?>"><br><br>
<label for="celular">Celular:</label>
<input type="text" id="celular" name="celular" value="<?= $contacto['celular'] ?>"><br><br>
<input type="submit" value="Actualizar">
</form>
app\Views\contacto\listar.php
<h1>Listado de Contactos</h1>
<?php if (session()->getFlashdata('mensaje')): ?>
<p style="color:green"><?= session()->getFlashdata('mensaje') ?></p>
<?php endif; ?>
<table>
<tr>
<th>Nombre</th>
<th>Apellido</th>
<th>Celular</th>
<th>Acciones</th>
</tr>
<?php foreach ($contactos as $contacto) : ?>
<tr>
<td><?= $contacto['nombre'] ?></td>
<td><?= $contacto['apellidos'] ?></td>
<td><?= $contacto['celular'] ?></td>
<td>
<a href="<?= MI_BASE_URL.'editar/'.$contacto['id'] ?>">Editar</a>
<a href="<?= MI_BASE_URL.'eliminar/'.$contacto['id'] ?>">Eliminar</a>
</td>
</tr>
<?php endforeach ?>
</table>
domingo, 25 de mayo de 2025
Validar desde el servidor la introducción de datos al crear un nuevo registro
app\Models\ContactoModel.php
<?php
namespace App\Models;
use CodeIgniter\Model;
class ContactoModel extends Model
{
protected $table = 'contactos';
protected $primaryKey = 'id';
protected $allowedFields = ['nombre', 'apellidos', 'celular'];
protected $validationRules = [
'nombre' => 'required|min_length[3]',
'apellidos' => 'required|min_length[3]',
'celular' => 'required|numeric|min_length[7]'
];
protected $validationMessages = [
'nombre' => ['required' => 'El nombre es obligatorio.', 'min_length' => 'Debe tener al menos 3 caracteres.'],
'apellidos' => ['required' => 'Los apellidos son obligatorios.', 'min_length' => 'Los apellidos debe tener al menos 3 caracteres.'],
'celular' => ['required' => 'El celular es obligatorio.', 'numeric' => 'El celular debe contener solo números.', 'min_length' => 'El celular debe tener al menos 7 dígitos.']
];
}
app\Controllers\Contacto.php (Extracto)
public function guardar()
{
$modelo = new ContactoModel();
$data = [
'nombre' => $this->request->getPost('nombre'),
'apellidos' => $this->request->getPost('apellidos'),
'celular' => $this->request->getPost('celular'),
];
if (!$modelo->insert($data)) {
return view('contacto/crear', [
'errors' => $modelo->errors(),
'old' => $data
]);
}
return redirect()->to(MI_BASE_URL.'crear')->with('mensaje', 'Contacto agregado correctamente.');
}
app\Views\contacto\crear.php
<h1>Crear Contacto</h1>
<?php if (session()->getFlashdata('mensaje')): ?>
<p style="color:green"><?= session()->getFlashdata('mensaje') ?></p>
<?php endif; ?>
<?php if (isset($errors)): ?>
<ul style="color:red">
<?php foreach ($errors as $error): ?>
<li><?= esc($error) ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<form action="<?= MI_BASE_URL.'guardar' ?>" method="post">
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre"><br><br>
<label for="apellidos">Apellido:</label>
<input type="text" id="apellidos" name="apellidos"><br><br>
<label for="celular">Celular:</label>
<input type="text" id="celular" name="celular"><br><br>
<input type="submit" value="Crear">
</form>
sábado, 24 de mayo de 2025
CRUD en CodeIgniter 4
app\Models\ContactoModel.php
<?php
namespace App\Models;
use CodeIgniter\Model;
class ContactoModel extends Model
{
protected $table = 'contactos';
protected $primaryKey = 'id';
protected $allowedFields = ['nombre', 'apellidos', 'celular'];
}
app\Controllers\Contacto.php
<?php
namespace App\Controllers;
use App\Models\ContactoModel;
class Contacto extends BaseController
{
public function index()
{
return view('menu');
}
public function listar()
{
$modelo = new ContactoModel();
$data['contactos'] = $modelo->findAll();
return view('contacto/listar', $data);
}
public function crear()
{
return view('contacto/crear');
}
public function guardar()
{
$modelo = new ContactoModel();
$data = [
'nombre' => $this->request->getPost('nombre'),
'apellidos' => $this->request->getPost('apellidos'),
'celular' => $this->request->getPost('celular'),
];
$modelo->insert($data);
return redirect()->to(MI_BASE_URL.'listar');
}
public function editar($id)
{
$modelo = new ContactoModel();
$data['contacto'] = $modelo->find($id);
return view('contacto/editar', $data);
}
public function actualizar($id)
{
$modelo = new ContactoModel();
$data = [
'nombre' => $this->request->getPost('nombre'),
'apellidos' => $this->request->getPost('apellidos'),
'celular' => $this->request->getPost('celular'),
];
$modelo->update($id, $data);
return redirect()->to(MI_BASE_URL.'listar');
}
public function eliminar($id)
{
$modelo = new ContactoModel();
$modelo->delete($id);
return redirect()->to(MI_BASE_URL.'listar');
}
}
app\Views\menu.php
<h1>Menú de Contactos</h1>
<ul>
<li><a href="<?= MI_BASE_URL.'listar' ?> ">Listar Contactos</a></li>
<li><a href="<?= MI_BASE_URL.'crear' ?> ">Crear Contacto</a></li>
</ul>
app\Views\contacto\crear.php
<h1>Crear Contacto</h1>
<form action="<?= MI_BASE_URL.'guardar' ?>" method="post">
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre"><br><br>
<label for="apellidos">Apellido:</label>
<input type="text" id="apellidos" name="apellidos"><br><br>
<label for="celular">Celular:</label>
<input type="text" id="celular" name="celular"><br><br>
<input type="submit" value="Crear">
</form>
app\Views\contacto\editar.php
<h1>Editar Contacto</h1>
<form action="<?= MI_BASE_URL.'actualizar/'.$contacto['id'] ?>" method="post">
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre" value="<?= $contacto['nombre'] ?>"><br><br>
<label for="apellidos">Apellido:</label>
<input type="text" id="apellidos" name="apellidos" value="<?= $contacto['apellidos'] ?>"><br><br>
<label for="celular">Celular:</label>
<input type="text" id="celular" name="celular" value="<?= $contacto['celular'] ?>"><br><br>
<input type="submit" value="Actualizar">
</form>
app\Views\contacto\listar.php
<h1>Listado de Contactos</h1>
<table>
<tr>
<th>Nombre</th>
<th>Apellido</th>
<th>Celular</th>
<th>Acciones</th>
</tr>
<?php foreach ($contactos as $contacto) : ?>
<tr>
<td><?= $contacto['nombre'] ?></td>
<td><?= $contacto['apellidos'] ?></td>
<td><?= $contacto['celular'] ?></td>
<td>
<a href="<?= MI_BASE_URL.'editar/'.$contacto['id'] ?>">Editar</a>
<a href="<?= MI_BASE_URL.'eliminar/'.$contacto['id'] ?>">Eliminar</a>
</td>
</tr>
<?php endforeach ?>
</table>
app\Config\Routes.php
<?php
use CodeIgniter\Router\RouteCollection;
/**
* @var RouteCollection $routes
*/
$routes->get('/', 'Contacto::index');
$routes->get('/listar', 'Contacto::listar');
$routes->get('/crear', 'Contacto::crear');
$routes->post('/guardar', 'Contacto::guardar');
$routes->get('/editar/(:num)', 'Contacto::editar/$1');
$routes->post('/actualizar/(:num)', 'Contacto::actualizar/$1');
$routes->get('/eliminar/(:num)', 'Contacto::eliminar/$1');
Un tropiezo en el camino: base_url() y site_url()
Me encontraba creando la segunda aplicación web en CodeIgniter cuando me tropezé con base_url() en el contexto de usarla para llamar una pagina php o html, definido previamente con una ruta. Primero me producía error al cargar las páginas. Luego de verificar que no estaba mal la configuración de las rutas y de escribir manualmente el recurso solicitado en la barra de direcciones, llegué a la conclusión de que no estaba funcionando adecuadamente. Al intentar modificar el contenido de la función para que apuntara a la url correcta en el archivo de configuración correspondiente, observé como toda la aplicación estallaba catastroficamente. Entonces, decidí no tocarla para nada, ni a base_url() y tampoco a site_url() e implementar mi propia constante para tener la ruta correcta y que no reviente toda la aplicación. Así que lo que hice fue agregar las siguientes lineas al archivo app\Config\Constants.php en el que se define una cosntante llamada MI_BASE_URL:
$miBaseURL = "http://".$_SERVER['HTTP_HOST'];
$miBaseURL .= str_replace(basename($_SERVER['SCRIPT_NAME']),'', $_SERVER['SCRIPT_NAME']);
defined('MI_BASE_URL') || define('MI_BASE_URL',$miBaseURL);
Luego, se puede usar esta constante en donde se necesite llamar a cualquier recurso:
<a href="<?= MI_BASE_URL.'listar' ?> ">Listar Contactos</a>
viernes, 23 de mayo de 2025
Mi primera Aplicación Web con CodeIgniter 4: Mostrando registros de la tabla
app/Models/AgendaModel.php
<?php
namespace App\Models;
use CodeIgniter\Model;
class AgendaModel extends Model
{
protected $table = 'contactos';
protected $primaryKey = 'id';
protected $allowedFields = ['id','nombre','apellidos','celular'];
public function getAll()
{
return $this->findAll();
}
}
app/Controllers/AgendaController.php
<?php
namespace App\Controllers;
use App\Models\AgendaModel;
class AgendaController extends BaseController
{
public function index()
{
$AgendaModel = new AgendaModel();
$data['agenda'] = $AgendaModel->getAll();
return view('agenda',$data);
}
}
app/Views/agenda.php
<h1>Agenda</h1> <table> <thead> <tr> <th>Id</th> <th>Nombre</th> <th>Apellidos</th> <th>Celular</th> </tr> </thead> <tbody> <?php foreach($agenda as $item): ?> <tr> <td> <?= $item['id'] ?> </td> <td> <?= $item['nombre'] ?> </td> <td> <?= $item['apellidos'] ?> </td> <td> <?= $item['celular'] ?> </td> </tr> <?php endforeach ?> </tbody> </table>
app/Config/Routes.php
$routes->get('/', 'AgendaController::index');
Creando y configurando la base de datos.
- Desde phpMyAdmin crear una base de datos llamada agenda, dentro de esta una tabla llamada contactos y dentro de esta cuatro campos llamados id, nombre, apellidos y celular. establecer Id con el atributo de AUTO_INCREMENT y como clave principal.
- Configurar los parametros de la base de datos. Dentro de la carpeta del proyecto de CodeIgniter, entrar a app/Config/database.php y establecer valores como el nombre de la base de datos, el usuario y la contraseña entre otros.
Creando manualmente un proyecto en CodeIgniter 4.6.1
- Descargar el archivo zip.
- Descomprimir y guardar en la carpeta htdocs de XAMP.
- Establecer un nombre adecuado para la carpeta. En mi caso le voy a llamar agenda
- Dentro de la carpeta renombrar el archivo env a .env. Dentro del archivo .env establecer el entorno de trabajo a desarrollo en vez de producción. Para ello se descomenta la linea # CI_ENVIRONMENT = production y se modifica para que quede así: CI_ENVIRONMENT = development
- En este punto se puede probar que se ha iniciado el proyecto adecuadamente. Se inicia Apache y en la barra de direcciones del navegador se escribe localhost/agenda. Se ingresa a public y allí deberá aparecer el mensaje de bienvenida y en la parte de abajo un mensaje indicando que está en modo de desarrollo.
Instalando XAMP y dejando todo listo para empezar
- Descargar XAMP for Windows.
- Ejecutar el instalador como administrador.
- Tal vez haya que modificar el UAC (User Account Control) pero en mi caso no tuve que hacer nada.
- Desde el panel de control de XAMP abrir el archivo de configuración php.ini y activar la extensión intl.
- Ejecutar el Servidor Apache y MySQL.
- En la primera ejecución se pedirá permiso para que el firewall de windows no los bloquee.
- Escribir en la barra de direcciones del navegador localhost para verificar que todo esté funcionando bien.
martes, 13 de mayo de 2025
Una nueva forma de crear aplicaciones webs ... para mi.
Me gusta mucho el lenguaje PHP, pero hasta ahora solo lo he usado en su versión estructurada y sin un framework. Es hora de iniciar un proceso para crear una app web usando herramientas más profesionales. Estas son:
- XAMP for Windows 8.0.30
- Codeigniter 4.6.1
- Visual Studio Code
Agrupada bajo una misma etiqueta, la intención es ir registrando todo lo necesario para crear una aplicación web de manera más profesional y aplicando los mejores practicas de programación.
sábado, 19 de abril de 2025
Eliminar parte de la caché de windows para hacer que el computador vaya más rápido.
1. Presionar Tecla Windows + R para abrir el cuadro de dialogo Ejecutar. Escribir y ejecutar temp. Aparece la carpeta de archivos temporales de windows. A continuación se procede a borrar los archivos y carpetas temporales que aparezcan. Para ello se puede presionar CTRL + E para seleccionarlos y luego DEL o SUPR para enviarlos a la papelera de reciclaje.
2. De menera parecida al paso anterior, con la diferencia de que se va a ejecutar %temp%. Esta orden abre la carpeta de los archivos y carpetas temporales del usuario actual.
3. Se procede de la misma forma y se ejecuta prefetch. Esta carpeta almacena información sobre los programas que se usan con frecuencia para que se carguen más rápido al iniciarlos.
4. Borrar de manera permanente el contenido de la papelera de reciclaje.
5. usar la herramienta Liberador de espacio en disco.
lunes, 24 de febrero de 2025
Fabricar un prototipo de imprenta
- Papel Foami liso tamaño carta color claro.
- Tapas de gaseosa (12) del mismo tamaño.
- Gota mágica (2).
- hojas bloc papel carta sin raya.
- Tijeras punta roma.
- Esponja.
- Tinta.
- Guantes.
miércoles, 19 de febrero de 2025
domingo, 9 de febrero de 2025
Crear abono para plantas a partir de residuos orgánicos
En vez de fabricar el compost directamente este metodo se centra en secar los residuos organicos para luego ser usados directamente en la planta. La razón de hacer esto está en evitar que se produzcan malos olores, en hacerlo rápidamente pero especialmente en evitar que en el proceso se formen jejenes.
- Recolecta residuos orgánicos.
- Cortarlos en pedazos pequeños.
- Extender sobre una plancha o tabla los residuos previamente cortados y déjalos secar al sol hasta que queden totalmente crujientes.
- Moler los residuos y guardalos en bolsa resellable para su uso.
miércoles, 4 de septiembre de 2024
Lugares para visitar en Bogotá y en los alrededores
1. MUSEO DEL ORO
Descripción: Museo arqueológico con colección de orfebrería prehispánica colombiana.
Entrada: $5.000 por persona
Sitio Web: https://www.banrepcultural.org/bogota/museo-del-oro/programe-su-visita
Observaciones:Desde este lugar se puede llegar a pie a otros museos y a la plaza de Bolívar.
2. MALOKA
Descripción: Maloka es un museo interactivo que fomenta la pasión por el aprendizaje partir de los lazos entre ciencia, tecnología, innovación y sociedad. Hay sala de exposición, cine-domo, cine 3D, laboratorios.
Entrada: Cada actividad tiene su precio. Por ejemplo: Recorrido Exploratorio $32.300, Laboratorios $21.000, Cine $13.900. Comprando una manilla sale un poco más cómodo.
Sitio Web: https://maloka.org/
Observaciones: Este museo está enfocado principalmente a niños y jóvenes que están en la escuela y a cualquiera amante de la ciencia.
3. JARDÍN BOTANICO JOSÉ CELESTINO MUTIS
Descripción: El Jardín Botánico es un centro de investigación distrital con énfasis en ecosistemas altoandinos y de páramo.
Entrada: Hay una tarifa entrada general nacionales de $6.000 y otras tarifas que se detallan en el sitio web.
Sitio Web: https://bogota.gov.co/mi-ciudad/cultura-recreacion-y-deporte/costo-de-entrada-al-jardin-botanico-de-bogota-2024
Observaciones: En este sitio se van a encontrar plantas... muchas, muchas plantas.
4. PARQUE DE DIVERSIONES MUNDO AVENTURA
Descripción: Parque donde el visitante puede disfrutar de la más completa y variada diversión con: Atracciones Mecánicas, Juegos de Destrezas y Escenarios Naturales.
Entrada: Los precios varían de acuerdo a las actividades que se quieran realizar. Se pueden comprar pasaportes para varias actividades con precios de $55.000 en adelante.
Sitio Web: https://mundoaventura.com.co/planea-tu-visita/precios/
Observaciones: No he ido pero me cuentan que es bastante parecido a las llamadas ciudades de hierro, pero con más cosas. Está enfocado a la diversión y actividades extremas.
5. PARQUE SALITRE MÁGICO
Descripción: Parque de atracciones mecánicas, igual que mundo aventura.
Entrada: Los precios varían de acuerdo a las actividades que se quieran realizar. Se pueden comprar pasaportes para varias actividades con precios de $50.000 en adelante.
Sitio Web: https://salitremagico.com.co/
Observaciones: Tiene una temática parecida a Mundo aventura.
6. PARQUE METROPOLITANO SIMÓN BOLIVAR
Descripción: Área verde urbana con recorridos para caminantes y ciclistas, lago para andar en bote y un área de juego.
Entrada: Gratis.
Sitio Web: https://www.idrd.gov.co/parques/parques-estructurantes/parque-metropolitano-simon-bolivar
Observaciones: En el 2013 llegamos a este lugar después de hacer un recorrido y regresar a Facatativá. Es un espacio público para caminar o hacer ejercicios. Allí se realizan conciertos.
7. PARQUE JAIME DUQUE
Descripción: Parque temático de enfoque familiar.
Entrada: Los precios varían de acuerdo a las actividades que se quieran realizar. Se pueden comprar pasaportes para varias actividades con precios de $52.000 en adelante.
Sitio Web: https://parquejaimeduque.com/
Observaciones: Se encuentra fuera de Bogotá, a una hora en transporte terrestre.
8. CERRO DE MONSERRATE
Descripción: Es una montaña a la cual se puede subir a pie, en funicular y en teleférico. En su parte alta hay una iglesia, restaurantes y un mirador de la ciudad.
Entrada: Subir a pie no tiene costo. Funicular o Teleférico Ida y Vuelta Desde $29.500
Sitio Web: https://monserrate.co/
Observaciones: Se encuentra cerca del centro de Bogotá.
9. MUSEO BOTERO
Descripción: El Museo Botero cuenta con una de las más importantes colecciones de arte internacional que se puedan encontrar en Latinoamérica.
Entrada: Gratis.
Sitio Web: https://www.banrepcultural.org/bogota/museo-botero
Observaciones: Se encuentra cerca del museo del oro.
10. MUSEO NACIONAL DE COLOMBIA
Descripción: Ofrece a sus visitantes diecisiete salas de exposición permanente, en las cuales se exhiben alrededor de 2.500 obras y objetos, símbolos de la historia y el patrimonio nacional.
Entrada: Adultos $6.000 .
Sitio Web: https://www.museonacional.gov.co/
Observaciones: Para los amantes de la historia de Colombia.
11. A continuación les comparto información sobre el Parque Arqueológico Piedras del Tunjo en Facatativá:
Tarifas: Nacionales colombianos $13.500; Extranjeros $65.000 (Temprano en la mañana el parque está abierto al público de manera gratuita)
Sitio Web: http://www.colparques.net/FACA
Otros lugares: El planetario, la casa museo Simón Bolivar, Tren turistico de la sabana: Turistren.




