septiembre 2017

Pequeña shell interactiva para sqlite3 en Python

Ayer estaba haciendo unas pruebas con sqlite3 y python, pero tenía que escribir cada sentencia, guardar el archivo y ejecutarlo… cosa que se me hizo muy tardada.

Así que decidí hacer un pequeño script interactivo muy simple pero que permite ejecutar cualquier cosa y abrir cualquier base de datos. El código se explica por sí mismo.

"""
	Abre una base de datos de sqlite3 e interactúa con ella.
	Útil para hacer pruebas

	@author parzibyte
"""
import sqlite3
while True:
	try:
		"""
			Tratar de abrir la base de datos e imprimir
			cualquier error que pase al hacerlo
			Comprobar también si el usuario quiere salir completamente
			del programa
		"""
		nombre_base_de_datos = input("Escribe el nombre de la base de datos: [-1 para salir]\t")
		if nombre_base_de_datos == "-1":
			break
		conexion = sqlite3.connect(nombre_base_de_datos)
		cursor = conexion.cursor()
		print("Base de datos abierta!")
		while True:

			"""
				Leer la entrada del usuario y salir si así lo desea.
				Si no, ejecutar la consulta, mostrar los resultados
				y si hay algún error imprimirlo
			"""
			try:
				sentencia = input("Escribe la consulta que deseas ejecutar: [-1 para cambiar la base de datos]\n\t")
				if sentencia == "-1":
					break
				resultado = cursor.execute(sentencia)
				datos = cursor.fetchall()
				conexion.commit()
				print("Los datos que trajo la consulta son: ")
				for dato in datos:
					print(dato)
			except sqlite3.OperationalError as error:
				print("Error al ejecutar la consulta: ", error)
	except sqlite3.OperationalError as error:
		print("Error al abrir la base de datos: ", error)

Aquí pongo unas pequeñas capturas de cómo se ve:

Finalmente tengo mencionar dos cosas importantes:

  • Está escrito para Python 3, y no creo que funcione en otras versiones, aunque sólo se tendrían que hacer unas pequeñas modificaciones
  • Está abierto a inyecciones de SQL ya que no usa sentencias preparadas. ¿Por qué? porque se supone que es para pruebas, es como interactuar con sqlite directamente

Aquí algunos enlaces

Documentación de sqlite3 para Python

Sitio oficial de SQLite

 

Generar nombres aleatorios en PHP

Hace poco hice un post para generar fechas aleatorias. Ahora se me ocurrió hacer uno para generar nombres de personas de manera aleatoria. Es un método poco eficaz y requiere que nosotros pongamos los datos, pero es lo único que se me ocurre. Si queremos algo que sea más fácil que esto, podemos echarle un ojo a Faker, una librería para generar muchos datos de todos los tipos… fechas, nombres, html, números de teléfono, números, etcétera.

Para hacer esto necesitamos dos arreglos, o en el peor de los casos uno. El primero para nombres, y el segundo para apellidos. Por ejemplo, podemos tener dos arreglos así:

<?php
$nombres = ["josé", "pedro", "raúl", "maría", "luisa", "adriana", "angela", "alan"];
$apellidos = ["pérez", "rodriguez", "hernández", "martínez", "garcía", "marín", "sánchez", "smith", "rivera", "alderson"];
?>

Para generar un nombre aleatorio, el algoritmo es sencillo:

  1. Generar un número aleatorio entre 0 y el número de elementos del arreglo – 1 y usar ese número como índice para elegir un elemento. Es decir, si nuestro arreglo tiene 5 elementos, hay que generar un número entre 0 y 4 (recordemos que los arreglos empiezan desde el 0)
  2. Generar otro número aleatorio como el anterior, pero esta vez para el arreglo de apellidos
  3. Volver a generar otro número para el segundo apellido. Podemos tomar el apellido del mismo arreglo
  4. Concatenar el nombre, el primer apellido y el segundo
  5. Devolver el resultado

Para generar un número aleatorio podemos usar mt_rand que toma como argumentos un límite inferior y un límite superior, y devuelve un número entre esos límites.

Así que podemos a llamar a mt_rand y pedirle que nos devuelva un número entre 0 y la longitud del arreglo menos 1.

Para obtener la longitud de un arreglo podemos usar count. De esta forma, podríamos elegir un elemento aleatorio así:

<?php
$elementoAleatorio = $arreglo[ mt_rand(0, count($arreglo) - 1) ];
?>

Ahora apliquemos esto a los arreglos que tenemos para generar un nombre completo:

<?php
$nombres = ["josé", "pedro", "raúl", "maría", "luisa", "adriana", "angela", "alan"];
$apellidos = ["pérez", "rodriguez", "hernández", "martínez", "garcía", "marín", "sánchez", "smith", "rivera", "alderson"];
$nombreAleatorio = $nombres[ mt_rand(0, count($nombres) -1) ];
$apellidoAleatorio = $apellidos[ mt_rand(0, count($apellidos) -1) ];
$otroApellidoAleatorio = $apellidos[ mt_rand(0, count($apellidos) -1) ];
echo "$nombreAleatorio $apellidoAleatorio $otroApellidoAleatorio";
?>

La salida será aleatoria, pero puede parecerse a:

angela hernández pérez

Si añadimos más nombres y apellidos, podremos generar una mayor cantidad de nombres. Ahora que ya lo tenemos, vamos a encapsular todo en una función.

<?php
/**
	Generar nombres completos aleatorios alimentándose de
	dos arreglos: uno para nombres y otro para apellidos

	Los arreglos se pasan por referencia

	@author parzibyte

	@param array $nombres Un arreglo con nombres

	@param array $apellidos Un arreglo con apellidos, de donde se sacarán el primer y el segundo apellido

	@return string El nombre completo generado de manera aleatoria
*/
function generar_nombre_aleatorio(&$nombres, &$apellidos){
	$nombreAleatorio = $nombres[ mt_rand(0, count($nombres) -1) ];
	$apellidoAleatorio = $apellidos[ mt_rand(0, count($apellidos) -1) ];
	$otroApellidoAleatorio = $apellidos[ mt_rand(0, count($apellidos) -1) ];
	return "$nombreAleatorio $apellidoAleatorio $otroApellidoAleatorio";
}
?>

Para llamar a la función tenemos que pasarle dos arreglos que nosotros mismos hayamos definidos. Sería más fácil definirlos dentro de la función, pero no sería bueno para el rendimiento. Además, de esta forma podemos pasarle un arreglo que hayamos recuperado de una base de datos, o cualquier arreglo que nosotros definamos con nuestros propios nombres. Un ejemplo de llamar a la función sería:

<?php
$nombres = ["josé", "pedro", "raúl", "maría", "luisa", "adriana", "ángela", "alan"];
$apellidos = ["pérez", "rodriguez", "hernández", "martínez", "garcía", "marín", "sánchez", "smith", "rivera", "alderson"];

$nombre = generar_nombre_aleatorio($nombres, $apellidos);
echo $nombre; // Salida de ejemplo -> pedro smith pérez
?>

Y así es como llegamos al final de esto.

Generar fechas aleatorias en un rango usando PHP y mt_rand

Tal vez en alguna ocasión tengamos que generar fechas aleatorias en PHP. En este post explicaré resumidamente cómo podemos hacerlo.

PHP tiene la función date que toma como primer argumento el formato (por ejemplo Y-m-d nos daría algo como 2017-01-25) y como segundo (opcional) el número de milisegundos de los que queremos que nos devuelva la fecha. Es decir, como segundo parámetro podemos poner los milisegundos transcurridos desde el 1 de enero de 1970 para formatearlos como cadena. Para entender mejor, veamos este ejemplo:

<?php
echo date("Y-m-d", 0);
//Salida -> 1969-12-31
?>

Como en este caso le pasamos un 0 como argumento, nos devolvió la fecha del 31 de diciembre de 1969. Se supone que debería devolver la fecha del 1 de enero de 1970, ¿no? pues sí, pero como el tiempo unix está basado en UTC, y nosotros no estamos en la misma zona horaria a veces nos devolverá diferentes resultados. Más información aquí

Entonces, si le ponemos 1000 milisegundos nos dará la fecha del 1 de enero mas un segundo, si le ponemos 3,600,000 ( 1000 * 60 * 60) nos dará la fecha del 1 de enero mas una hora, y así.

Ahora, para sacar una fecha aleatoria podemos simplemente llamar a la función date y pasarle como milisegundos un número aleatorio generado con mt_rand así:

<?php
echo date("Y-m-d", mt_rand(0, 500000000));
//Salida -> 1979-08-08, o una fecha como esas, ya que será aleatoria
?>

Llamamos a date con el mismo formato, pero en lugar de un número definido por nosotros, dejamos que mt_rand se encargue. mt_rand recibe un mínimo y un máximo, y nos devuelve un número que se encuentre entre esos límites.

De esa forma podemos generar una fecha aleatoria. Ahora, ¿qué pasa si queremos generar una fecha aleatoria entre dos fechas? es decir, llamar a la función y decirle “quiero que me des una fecha aleatoria entre el 1 de septiembre del 2017 y el 15 de septiembre del 2018”

Aquí entra otra función, strtotime que convierte una cadena a milisegundos. Es decir, la llamamos así:

<?php
echo strtotime("2017-09-18");
//Salida -> 1505707200
?>

Y dependiendo de la fecha que le pasemos como string, nos dará el número de milisegundos. Obviamente podemos especificar más formatos. Veamos el siguiente ejemplo:

<?php
echo strtotime("2017-09-18 15:52:55");
//Salida -> 1505764375
?>

Aquí le pasamos una fecha junto con la hora. Y nos devuelve el número de milisegundos exactos.

Entonces si combinamos todas estas funciones, al final podremos crear una función que devuelva una fecha aleatoria entre dos fechas que el usuario defina. Vamos a crearla

<?php
/**
	@author parzibyte

	@param string $formato El formato en el que deseamos que devuelva la fecha.
	por defecto es Y-m-d (2017-01-01)

	@param string $limiteInferior Límite inferior desde donde queremos que tome la fecha.
	Por defecto es el 1 de enero de 1970

	@param string $limiteSuperior Límite superior. Por defecto es el 1 de enero del 2038

	@return string La fecha aleatoria
*/
function fecha_aleatoria($formato = "Y-m-d", $limiteInferior = "1970-01-01", $limiteSuperior = "2038-01-01"){
	// Convertimos la fecha como cadena a milisegundos
	$milisegundosLimiteInferior = strtotime($limiteInferior);
	$milisegundosLimiteSuperior = strtotime($limiteSuperior);

	// Buscamos un número aleatorio entre esas dos fechas
	$milisegundosAleatorios = mt_rand($milisegundosLimiteInferior, $milisegundosLimiteSuperior);

	// Regresamos la fecha con el formato especificado y los milisegundos aleatorios
    return date($formato, $milisegundosAleatorios);
}
?>

Veamos algunos ejemplos de cómo podemos usar esta función.

<?php
echo fecha_aleatoria(); // Salida -> Algo como 2023-08-29

echo fecha_aleatoria("Y-m-d H-i-s"); // Salida -> Algo como 2024-03-18 18-20-48

echo fecha_aleatoria("Y-m-d", "2017", "2018"); // Salida -> Algo como 2017-09-19

echo fecha_aleatoria("Y-m-d H:i:s", "2017-09", "2017-10"); // Salida -> Algo como 2017-09-28 19:21:41
?>

Y así podemos jugar mientras el formato sea válido. Si queremos ver más opciones para formatear la fecha, abajo dejo los links a la documentación oficial en donde me guié e inspiré.

 

Imprimir ticket en impresora térmica desde PHP

Introducción

Nota: te invito a leer cómo imprimir en impresora térmica usando Javascript, es un poco más fácil aunque tiene desventajas como no poder cortar el papel al gusto. Pero funciona sin tener que instalar librerías.

Las impresoras de tickets son muy populares y útiles en los establecimientos donde se necesita entregar un comprobante.

Puede que en alguna ocasión nos toque desarrollar un pequeño sistema en PHP y que tengamos que imprimir tickets.

Para ello es que escribo este tutorial; que al final nos dará un resultado parecido al siguiente:

Si quieres descargar un ejemplo rápido y funcional, mira el repositorio de GitHub. Solo tienes que descargar el código, cambiar el nombre de tu impresora y probar.

Continue reading…