Introducción al módulo aleatorio de Python

Incluso para alguien que no esté interesado en la programación de computadoras, la utilidad de generar números aleatorios en ciertas circunstancias es algo obvio. En la mayoría de boa...

Introducción

Incluso para alguien que no esté interesado en la programación de computadoras, la utilidad de generar números aleatorios en ciertas circunstancias es algo obvio. En la mayoría de los juegos de mesa lanzamos dados para generar un número impredecible que define el próximo movimiento del jugador. Además, todos podemos estar de acuerdo en que jugar cualquier juego de cartas no tendría sentido sin una mezcla adecuada entre rondas.

Pero los números aleatorios no solo son importantes en campos relativamente triviales como el entretenimiento o las apuestas. Son especialmente cruciales en el campo de la criptografía. Para garantizar una transmisión segura de datos, cada vez que se necesita una conexión segura, se debe generar una clave aleatoria. Muchos tipos diferentes de comunicación electrónica utilizan este tipo de seguridad. Es muy importante que la clave sea difícil de adivinar; la mejor manera de garantizarlo es haciéndola aleatoria, ya que en el momento en que alguien adivina la clave, puede descifrar el mensaje y la comunicación deja de ser segura.

Aleatoriedad verdadera frente a pseudoaleatoriedad {#aleatoriedad verdadera frente a aleatoriedad verdadera}

Los números aleatorios se pueden obtener como resultado de la aplicación de métodos llamados generadores de números aleatorios (RNG), que se pueden dividir en dos categorías: generadores de números aleatorios verdaderos (TRNG, también llamados generadores de números aleatorios de hardware) y generadores de números pseudoaleatorios ( PRNGS).

Generadores de números aleatorios verdaderos

Los verdaderos generadores de números aleatorios son métodos que derivan la aleatoriedad, o imprevisibilidad, de aspectos impredecibles de los procesos físicos. Estos métodos no producen números directamente, sino estados, que luego pueden interpretarse como números; es por eso que generalmente se los llama generadores de eventos aleatorios (REGs). Algunos de ellos, que utilizan eventos macroscópicos, son comúnmente conocidos: métodos como lanzar dados, lanzar monedas o barajar cartas.

Estos verdaderos generadores de números aleatorios a menudo usan fenómenos físicos más complicados. Algunos de ellos, como la desintegración radiactiva, el ruido térmico o el ruido de radio, derivan su imprevisibilidad de las peculiaridades de la mecánica cuántica. Otros métodos utilizan la imprevisibilidad del ruido atmosférico o incluso el [comportamiento de las lámparas de lava](https://www.fastcompany.com/90137157/the -el-diseño-de-oficina-más-trabajador-en-Estados Unidos-encripta-sus-datos-con-lámparas-de-lava).

Generadores de números pseudoaleatorios

La verdad es que, muy a menudo, no es necesario generar números que sean realmente aleatorios. En muchos casos, todo lo que necesitamos son conjuntos de números que parecen aleatorios. Este tipo de datos se puede derivar de generadores de números pseudoaleatorios. Estos son algoritmos que utilizan una pequeña porción de información (llamada semilla) y luego aplican fórmulas matemáticas complicadas para generar conjuntos deterministas de números que se asemejan a conjuntos verdaderamente aleatorios. La semilla puede ser un valor derivado de un verdadero generador de números aleatorios u otra fuente, como el reloj del sistema o la fecha y hora actual.

Ejecutar el generador varias veces usando la misma semilla dará como resultado la misma salida cada vez. Los números resultantes son en su mayoría irreconocibles a partir de números derivados de verdaderos generadores de números aleatorios, aunque en realidad hay algunas regularidades ocultas en su distribución. Aún así, para muchas aplicaciones, este tipo de pseudoaleatoriedad determinista es absolutamente suficiente.

Módulo aleatorio de Python

Python, obviamente ofrece un conjunto de herramientas súper fácil de usar para manejar números aleatorios. Un módulo, por alguna razón llamado “aleatorio”, implementa un generador de números pseudoaleatorios y contiene métodos que nos permiten resolver directamente muchos problemas de programación diferentes donde entra en juego la aleatoriedad.

El módulo random se basa en marsenné tornado, un algoritmo muy popular, que es el generador de números pseudoaleatorios predeterminado no solo para Python, sino también para muchos otros sistemas de software populares como Microsoft Excel, MATLAB, R o PHP. Sus ventajas importantes incluyen licencias permisivas, semejanza aleatoria confirmada por muchas pruebas estadísticas y velocidad relativamente alta en comparación con otros PRNG.

El método aleatorio()

El método más importante del módulo random es el método random(). La mayoría de las otras funciones dependen de él. El método random() genera un flotante aleatorio en el rango (0.0, 1.0).

1
2
3
>>> import random
>>> random.random()
0.8474337369372327

El método seed()

Si no establecemos una semilla para nuestra generación de números pseudoaleatorios, la semilla predeterminada es la hora actual del sistema. Sin embargo, podemos establecer el valor exacto de la semilla manualmente, lo que resulta útil especialmente si queremos replicar nuestros resultados pseudoaleatorios en el futuro. Para este propósito, podemos usar el método random.seed().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> random.seed(5)
>>> random.random()
0.6229016948897019
>>> random.random()
0.7417869892607294
>>> random.random()
0.7951935655656966
>>> random.seed(5)
>>> random.random()
0.6229016948897019

El método random.seed() influye en todos los métodos del módulo random que usamos después de llamarlo. En el ejemplo que se muestra arriba, configuramos la semilla en 5 y luego ejecutamos la función random.random() varias veces. Es importante tener en cuenta que la semilla definida por el usuario se usa solo la primera vez que se ejecuta otro método “aleatorio”; después de eso, las semillas para los siguientes métodos se modifican usando los valores aleatorios generados previamente.

Esto le permite a Python generar nuevos números cada vez. Pero aun así, después de restablecer la semilla usando el método random.seed(), podemos reproducir exactamente la misma secuencia de números pseudoaleatorios en cualquier momento. Esto es muy útil para cosas como ejecutar pruebas. Si proporciona la misma semilla cada vez que ejecuta una prueba que utiliza uno de los métodos aleatorios, aún podrá saber cuál debería ser la salida para las pruebas.

Otros ejemplos del módulo aleatorio

El método random.random(), que nos da un valor flotante aleatorio de un cierto rango, sería suficiente incluso para que un desarrollador de Python sin experiencia diseñe cualquier tipo de manipulaciones aleatorias a su alrededor. Probablemente puedas imaginarte agregando un si o dos para escribir una función que extraiga aleatoriamente un valor de una lista o devuelva un número entero aleatorio en lugar de un flotante. Bueno, el módulo random también nos permite encargarnos de esas tareas automáticamente. A continuación, muestro un par de métodos geniales que simplifican las operaciones aleatorias comunes. Puedes conocer todo el potencial del módulo random en Documentación oficial de Python.

1
2
>>> random.randint(1,10)
4

El método random.randint() toma dos argumentos que describen el rango del cual el método extrae un entero aleatorio.

1
2
3
4
5
6
7
8
>>> random.randrange(2,10,2)
2
>>> random.randrange(2,10,2)
4
>>> random.randrange(2,10,2)
8
>>> random.randrange(2,10,2)
6

En el script anterior, el método random.randrange() es similar a random.randint() pero también nos permite definir el tercer argumento, que es el punto de paso del rango definido. En el ejemplo anterior, solo requerimos números pares de un rango entre 2 y 10.

1
2
3
>>> cards = ['ace_spades','10_hearts','3_diamonds','king_hearts']
>>> random.choice(cards)
'10_hearts'

En el script anterior, el método random.choice() elige un elemento aleatorio de una lista.

1
2
3
4
>>> cards = ['ace_spades','10_hearts','3_diamonds','king_hearts']
>>> random.shuffle(cards)
>>> print(cards)
['king_hearts', '3_diamonds', 'ace_spades', '10_hearts']

En el script anterior, el método random.shuffle() mezcla una lista de elementos. Es importante tener en cuenta que altera la lista en el lugar, lo que significa que devuelve Ninguno y en realidad modifica nuestra variable cards.

Conclusiones

Obtener buenos números aleatorios, para aplicaciones serias como la criptografía, no es tarea fácil. Pero cuando un número pseudoaleatorio sólido es suficiente para nuestra aplicación, Python, como siempre, viene con varias formas súper simples de alcanzar rápidamente nuestro objetivo.

Licensed under CC BY-NC-SA 4.0