Saltar al contenido principal

El generador number

Úselo cuando necesite un entero —un id, un código, un precio, una edad— dentro de un rango; o una cadena de exactamente N dígitos (incluso cientos o miles de ellos, mucho más allá de lo que cabe en un tipo numérico común).

El generador number tiene varios modos, y se elige según cuál de value y length se le dé. Esta página recorre cada uno.

De un vistazo

AtributoObligatorioQué hace
valuenobit, un número "50", una lista "10,20,35", un rango "100..999", o una mezcla
lengthnoAncho fijo "10", un rango "2-10", o grupos "2,10-12"
percentnoProporciones para los grupos de length, p. ej. length="2,10-12" percent="85,15"
first_zeronotrue / false — si se permite un cero inicial
includenoAgrega números o rangos a value
excludenoQuita números o rangos de value
decimalsnoDígitos después del punto decimal, 010 — vuelve fraccionaria la columna

Sin value y sin length, number emite un solo dígito aleatorio del 0 al 9.

./run demo.tdc
7
2
9
0
4

Un solo bit

value="bit" da un 0 o un 1 al azar — práctico para banderas tipo booleano.

<gen type="number" value="bit"/>
./run demo.tdc
1
1
1
1
0

Un número, o unos pocos

value acepta un único número cuando la columna siempre lo contiene, y una lista separada por comas cuando contiene uno de varios:

<gen type="number" value="50"/> <!-- siempre 50 -->
<gen type="number" value="10,20,35"/> <!-- uno de los tres -->
./run demo.tdc
50        35
50        20
50        35
50        20
50        10

Ambas formas existen para que una constante o un pequeño conjunto de números se quede dentro del generador numérico, donde los atributos numéricos significan lo que dicen. Antes no se aceptaba ninguna de las dos, y la única manera de escribir «siempre 50» era <gen type="text" value="50"/> — una lista de cadenas que parecen un número. Eso funciona, y sigue funcionando, pero la comprobación es distinta de una forma que importa: una lista de texto se comprueba leyéndola, así que value="hello,50" con anomaly= pasa y luego genera picos solo la mitad de las veces pedidas, porque una palabra no se puede multiplicar. En number cada valor es un número por construcción, así que la tasa declarada es la tasa entregada.

Un rango

Déle a value un rango en la forma from..to (inclusivo) y obtiene un entero aleatorio dentro de él.

<gen type="number" value="1000..9999"/>
./run demo.tdc
7990
6325
8602
6092
3258

Dos reglas sobre la sintaxis:

  • El separador es siempre .., nunca un guion solo.
  • Un - solo dentro de value es el signo de menos de un número negativo, así que los rangos negativos funcionan sin más:
<gen type="number" value="-500..-200"/>
./run demo.tdc
-267
-322
-246
-330
-425

Los ceros a la izquierda se conservan

Si el rango se escribe con ceros a la izquierda, el ancho se preserva — excelente para códigos de ancho fijo:

<gen type="number" value="0000..9999"/>
./run demo.tdc
7767
5916
8446
5658
2509

Varios rangos a la vez

Pase una lista separada por comas de rangos entre corchetes y TDC elige primero un rango al azar, y luego un número dentro de él.

<gen type="number" value="[0..100],[345..678],[1934..2026]"/>
./run demo.tdc
1952
662
1975
664
85
Detalle de la distribución

Con una lista de rangos, cada rango es igual de probable, y luego un número dentro del rango elegido es igual de probable — de modo que los números individuales no quedan uniformes sobre el conjunto completo. Si quiere una elección genuinamente uniforme sobre un rango al que le faltan unos cuantos huecos, use exclude (más abajo) en su lugar.

Ancho fijo con length (relleno)

Cuando da ambos, value y length, length funciona como ancho de presentación: los números cortos se rellenan con ceros a la izquierda y los más largos se imprimen tal cual. Misma semilla, así que los números son idénticos — lo único que cambia es el ancho:

<gen type="number" value="1..999"/> <!-- valor crudo -->
<gen type="number" value="1..999" length="4"/> <!-- misma serie, ancho 4 -->
./run demo.tdc
raw    length="4"
770  →  0770
350  →  0350
79   →  0079
959  →  0959
208  →  0208

Los números no cambiaron — nada más se rellenaron a cuatro dígitos. En este modo de relleno se permite un cero inicial por omisión (para que un valor corto pueda alcanzar el ancho).

decimals — una columna fraccionaria

Problema. Un precio, una tasa, una medición. value="1..999" da números enteros; decimals="2" da el mismo rango con dos dígitos después del punto.

<gen type="number" value="1..999" decimals="2"/>
./run price.tdc
776.15
591.50
843.99

decimals toma un entero de 0 a 10. Cualquier otra cosa detiene la corrida:

./run price.tdc (decimals="11")
tdcv2: number decimals must be an integer 0..10, got "11"

Reemplaza a length en vez de sumarse a él — un valor fraccionario no tiene ancho entero que rellenar, así que el par es TDC278:

tdcv2 check price.tdc
error[TDC278]: length="8" is not read beside decimals="2" — a fractional value has no integer width to pad

Tampoco se combina con include / exclude. Para una columna fraccionaria sacada de una forma y no de un rango plano, vea Distribuciones estadísticas.

Modo cadena de dígitos

Déle length sin value y el generador cambia de modo: arma el resultado dígito por dígito y siempre devuelve una cadena de exactamente ese largo. Esto no es un número de JavaScript — es texto —, así que puede generar identificadores de cientos o miles de dígitos.

<gen type="number" length="10" first_zero="true"/>
./run demo.tdc
7299399441
5929481897
8462586083
5905900972
2876831899

Aquí first_zero="true" permite un cero inicial. Ninguna de estas cinco empieza por uno — un cero inicial sale una vez de cada diez, así que una muestra corta a menudo no lo tiene. Sobre 200 filas aparece 16 veces; sin el atributo, 0 veces. Eso es todo lo que hace: sin él, el primer dígito en este modo nunca es cero.

Largo variable

length puede ser a su vez un rango, o grupos con proporciones:

<gen type="number" length="2-10"/> <!-- largo aleatorio de 2 a 10 -->
<gen type="number" length="2,10-12" percent="85,15"/> <!-- 85 % cortos, 15 % largos -->
./run demo.tdc
length="2-10"            → 70270136
length="2,10-12" 85/15   → 77

El percent de aquí funciona exactamente igual que en text: sobre count="100", exactamente 85 valores son de largo 2 y 15 son de largo 10 a 12.

first_zero — controlar el cero inicial

first_zero decide si el primer dígito puede ser 0. El valor por omisión depende del modo:

  • Modo relleno (con value): el cero inicial está permitido por omisión, para que el relleno alcance el ancho. first_zero="false" lo prohíbe — TDC entonces saca un valor que ya trae suficientes dígitos:
<gen type="number" value="0..9999" length="4"/> <!-- cero permitido -->
<gen type="number" value="0..9999" length="4" first_zero="false"/> <!-- sin cero -->
./run demo.tdc
default        first_zero="false"
7701      →     7701
3494      →     3494
0785      →     2379
9597      →     9597
2078      →     2078

Solo 0785 (el único valor que empezaba con cero) se reemplaza por un 2379 de cuatro dígitos completos; todo lo demás ya no tenía cero inicial y queda intacto.

  • Modo cadena de dígitos (sin value): el cero inicial está prohibido por omisión. Pase first_zero="true" cuando la cadena pueda empezar con cero (el ejemplo de diez dígitos de arriba).

Agregar y quitar números: include / exclude

Para abrirle un par de huecos a un rango sin tener que deletrear una lista de subrangos, use exclude (quitar) e include (agregar). Los valores son números o rangos a..b, separados por comas.

<gen type="number" value="0..9" exclude="3"/> <!-- del 0 al 9 menos el 3 -->
<gen type="number" value="1000..9999" exclude="1234,5678"/> <!-- ids menos dos -->
<gen type="number" value="0..100" exclude="40..60"/> <!-- sin la parte de en medio -->
<gen type="number" value="0..9" include="100"/> <!-- del 0 al 9 y también el 100 -->
./run demo.tdc
value="0..9" exclude="3"               → 7
value="1000..9999" exclude="1234,5678" → 7931
value="0..100" exclude="40..60"        → 82
value="0..9" include="100"             → 8

Dos cosas que vale la pena saber:

  • La elección sí es genuinamente uniforme sobre todo lo que queda. value="0..9" exclude="3" da exactamente 1/9 para cada uno de los nueve números sobrevivientes — a diferencia de una lista de rangos, donde lo que pesa igual son los rangos, no los números.
  • Un conjunto no tiene decimales. include/exclude forman un conjunto de números enteros y eligen uno uniformemente, así que decimals= no tiene nada que redondear. Juntos se rechazan (TDC255) — antes el motor descartaba decimals y emitía enteros sin decir nada.
  • exclude tiene la última palabra. El conjunto final es (base ∪ include) − exclude, así que un número agregado por include y quitado por exclude desaparece. Si no queda nada después de los modificadores, eso es el error TDC087.

Estos modificadores necesitan un value de tipo rango; no aplican al modo cadena de dígitos (solo con length).

Detalles a tener presentes, todos juntos

  • Los rangos usan .., nunca - (un - solo es un signo de menos).
  • El ancho con ceros a la izquierda se conserva: value="0000..9999""0034".
  • El modo cadena de dígitos devuelve texto, no un número — seguro para ids enormes.
  • En una lista de rangos, lo uniforme son los rangos, no los números individuales — use exclude para una elección uniforme con huecos.

Vea también

  • length y first_zero en la referencia de atributos.
  • Text — la misma maquinaria de percent exacto, para listas.