Expresiones regulares. RegEx

Aprender sobre manejar expresiones regulares fue de las primeras cosas a las que tuve que enfrentarme, casi desde cero.

Les dejo una explicación de la esencia de este tema, que espero que a más de uno le sirva de ayuda.

Una expresión regular (RegEx) es una secuencia de caracteres que define un patrón de búsqueda.

En su modo mas simple digamos que una expresión regular del tipo :

^t…o$

Corresponde a cualquier palabra de cinco letras que comience con t y termine en o, como «tanto», «tonto», «tengo», «trillo», o «talio» por ejemplo, entre muchas otras .

En cambio, palabras como «tampoco», «tantísimo», o «tranco», por ejemplo no cumplirían los requisitos para coincidir , con esa búsqueda.

Las expresiones regulares, conocidas como RegEx, es una herramienta medianamente compleja, que nos permite identificar caracteres específicos de texto dentro de cadenas, para operar con ellos.

Conocer todas las expresiones regulares, es algo que lleva tiempo y practica, pero intentaré explicarlo sucintamente.

Metacaracteres

La lista de abajo muestra los metacaractéres, estos tienen un significado especial dentro de las RegEx

[] . ^ $ * + ? {} () \ |

Veamos cada uno

Los corchetes []

Los caracteres individuales que queremos encontrar se encierran entre [] .
por ejemplo [abc], devolverá coincidencias, con cualquier cadena que contenga esas tres letras como “a”, “a veces”,“obcecado”

A esta búsqueda se puede añadir otros elementos para hacerla mas especifica por ejemplo :

[a-d] es lo mismo que  [abcd].

[1-4] es lo mismo [1234].

[0-39] es lo mismo [01239]

Aunque en los dos primeros casos muestra intervalo, en el último indica intervalo igualmente, pero no así para el ultimo dígito que se indica específicamente.

 Contrario a esto, el símbolo ^ , cuando se inserta entre los corchetes al inicio de la expresión, indica excepción por ejemplo [^abc], nos dice que cualquier carácter excepto 'a' o 'b‘ o 'c

Por tanto  si escribimos por ejemplo [^a-z], estamos hablando de cualquier carácter  que no se encuentre en el rango de la ‘a’ a la ‘z’ .

[^0-9] indica cualquier carácter menos los dígitos, …

y [^123], cualquier carácter excepto 1 ó 2 ó 3.

El punto .  

El punto equivale a cualquier carácter individual, menos un salto de línea '\n'.

Por ejemplo la expresión, encontrará coincidencias con cualquier cadena que contenga como mínimo tres caracteres. Una cadena de tres caracteres devolverá un coincidencia, al igual que una de 5, pero una de seis encontrará dos y una de 9, tres

Intercalado o caret (inglés) ^

Cuando se coloca solo, se utiliza para conocer si una cadena comienza con determinado carácter.

Por ejemplo ^b, hallara coincidencias en ‘brillo’ y ‘bandera’, pero no en ‘abanderado’  

Símbolo  dollar $

Se emplea para saber si una cadena termina en un determinado carácter.

$r, buscara coincidencias para cadenas que terminen en ‘r’

Símbolo asterisco *, símbolo suma + y símbolo de interrogación ?

Estos tres signos buscan coincidencias en cadenas, siguiendo una lógica de unión entre los caracteres.

La diferencia de su comportamiento esta en que * busca 0 o mas coincidencias, mientras + busca una o más y   '?' busca 0 o una

Si tomamos como  expresión búsqueda , «te*n»,  esta nos dice que buscamos cualquier cadena donde no este completa, o este esta condición  que exista una»t» ,  y una «n», y si existe una «e», este obligatoriamente seguida de la «n”.

Hallaremos  coincidencias en «tn», «ten», «teen», y «manten», pero no en «tean», porque la «e» no va seguida inmediatamente de la «n»,

La expresión te+n, sigue la misma lógica pero espera encontrar una o más coincidencias, por tanto tn, no devolverá coincidencias, porque no hay una «e», ni tampoco «tean», porque la «e» no va seguida de la «n».

Si utilizamos con esta mismo texto de búsqueda, pero sustituyendo la RegEx por un signo de interrogación te?n, este busca 0 o una coincidencia, en tn hallará una, al igual que en «ten» y «manten».

No sucederá lo mismo  en «teen» o «tean», primero porque en «teen» no existe más de un carácter e y en «tean», la e no va seguida de la n.

Llaves {}

Las llaves {}, se emplean para indicar un rango, de ocurrencia, donde el primer elemento es el mínimos esperado y el segundo, el máximo.

O se n{x,y}, espera que exista como mínimo una ocurrencia x y cómo máximo una y del patrón n.

Si tomamos como patrón de búsqueda a {1,9}, estamos esperando hallar como mínimo una a y como máximo 9.

Un ejemplo común, es que un patrón como [0-9]{3, 6}, buscara al menos tres dígitos seguidos y como máximo 6.

Por tanto hallara coincidencias en las siguientes cadenas 1234, 234567, 333; sin embargo no hallará en 22, 3456878,  o 1

Barra vertical |

Esta es más conocida de otros lenguajes de progrmacion y se usa para alternar entre valores.

De este modo a|b, busca a o b y en una cadena como «babilonia», hallará cuatro coincidencias

Parentesis ()

Se emplean para agrupar varios patrones.

Un agrupamiento de (a|e|i)r, buscará coincidencias de cualquier subcadena , a, e i que vayan seguidas inmediatamente del carácter r.

De este modo hallara ocurrencias en ‘balar’, ‘correr’, ‘reir’, ‘harto’, verde, ‘irina’, ‘subir’ o ‘bajar’, pero no en ‘a’, ‘ r’, ‘eleonor’, u ‘orina’.

Backslah \

Se emplea como señal de escape de varios caracteres y esto incluye también a los meta caracteres.
Por ejemplo si lo usamos antes de un metacaracter alterará o anulará su significado.

Si escribimos \$n,  se encontraran coincidencias, en aquellos casos  donde después del símbolo de dólar aparezca una ‘n‘,  y dejará de verlo como una expresión regular que indica final de la cadena.

Backslah también se utiliza para indicar otras cuestiones, usándolo con otros caracteres. Veamos

\A encuentra coincidencias con caracteres específicos que se encuentran al comienzo de una cadena.\Aes, hallará ocurrencias en cadenas que comiencen con es.

\b encuentra coincidencias con caracteres específicos al comienzo o terminación de una palabra. \bfía, coincidirá con «ecografía» y «con fiabilidad», y no con «confiabilidad»

\B encuentra coincidencias donde no se cumple la condición o sea, que no aparezcan al inicio o comienzo de la palabra los caracteres dados. Es la oposición al \b anterior asi que ahora si coincidirá con confiabilidad

\d halla coincidencias con cualquier dígito decimal. Esta expresión es lo mismo que escribir [0-9].

\D, se opone al anterior y por tanto buscará concurrencias de cualquier elemento que no sea un dígito

\s coincide con cualquier cadena, que posea un espacio en blanco.

\S coincide con cualquier cadena, donde no exista un espacio en blanco.

\w hallará coincidencias con cualquier cadena, donde existan caractéres alfanuméricos (o sea números y letras, incluidos _). Sería lo mismo que escribir [a-zA-Z0-9_].

\W busca cualquier carácter que no sea alfanumérico. Tendriamos el mismo resultado que si escribimos [^a-zA-Z0-9_]

\Z, coincidirá con caracteres específicos al final de una cadena. \Zión hallará una ocurrencia en ‘sanción’.

De forma bastante resumida,  estas son las expresiones regulares. Existen múltiples herramientas en internet, para agilizar el trabajo con ellas de forma online, y que pueden ayudarte a construirlas de manera efectiva.

«En total oscuridad cualquier cosa, puede ser luz»

Usando Google Analytics

La herramienta Google Analytics, una de las más conocidas de Google, para aquellos interesados en el tema de posicionamiento de  webs, y aunque  no es la única de la que podemos valernos,  si es quizás la que nos ofrece una interfaz más amigable, amplia y gratis, para implementar campañas y estrategias en cualquier sitio web, de que dispongamos y deseemos obtener un comportamiento.

Desde mi modesta experiencia,  no todo en GA es perfecto, y el uso de su herramienta requiere una curva de aprendizaje que aunque no es alta, necesita mantenerse actualizada, entre otras cuestiones por las propias variaciones que hace Google.

Un uso adecuado de GA, incluye la combinación de otras herramientas que también forman parte de Google Marketing Platform, como Google Data Studio o Google Tag Manager, sobre todo si se pretende trabajar con informes ampliados.

En esta ocasión, hablaré del tema de los informes que Google entrega, por lo que este articulo, será mas entendible para aquellos que ya disponen  y usan cuentas de GA.

Los informes que pone a nuestro alcance Google Analytics, son dos  : Estándar y Mejorado.

Ambos se basan,  en el supuesto de que usted necesita conocer: a quien, que, cuanto y como vende, lo que ofrece en su tienda;  y  para ello le ofrecen diferentes opciones de configuración.

Los elementos básicos que nos brindan son entre otros:

  • Cuántos visitantes únicos hacen clic en el sitio y  en que páginas específicas dentro de él.
  • Cuántas vistas de página en general,  llevan  a  determinadas páginas
  • Cuánto tiempo pasan los visitantes en cada página durante su visita.
  • Cuál es su tasa de rebote
  • Datos demográficos de sus visitantes,  y su origen.

Dicho esto podemos decir que :

El punto de partida para obtener un informe Google Analytics útil,   radica en que esté bien configurado.

Informe Standard

Ofrece varios elementos:

Visión General de Ecommerce: Muestra aquellos datos imprescindibles: el número de transacciones realizadas, la tasa de conversión, y la cantidad de ingresos.

Desempeño del Producto: Permite observar los productos que aparecen en su tienda, los que han sido vendidos, y los ingresos que ha obtenido con ellos, así como el precio promedio de su tienda y la cantidad media de productos.

El Informe de rendimiento de ventas: Recopila, la misma información que el informe de rendimiento de productos, pero hace hincapié en los niveles de ingreso hasta la fecha y establece comparativas, en fechas diferentes.

El informe Transacciones: nos da el comportamiento de los pedidos, listándolos según su ID.

El informe de Tiempo de Compra, indica la demora en que tarda en ejecutarse una transacción desde que se inicia hasta que se ejecuta totalmente la conversión.

Informe mejorado

Como indica su nombre se diferencia del informe estándar al ofrecer detalles adicionales, que debidamente usados y comprendidos , lo ayudaran a mejorar la gestión de su tienda.

La principal diferencia radica en que el informe mejorado, aporta una visión relacionada con el marketing, centrándose en la experiencia de usuario de los visitantes de la tienda, lo cual construye una opción mas profesional y completa del comportamiento de una tienda online.

El informe desempeño del producto mejorado: muestra además de los mismos elementos que su versión estándar, detalles del carrito y los reembolsos.

Esta información como explicaba antes nos dota del conocimiento para una análisis más profundo, acerca de  cómo se comportan, sus clientes dentro de la tienda, el interés generado por su web y en que medida  su diseño es lo suficientemente efectivo para llevar a los clientes hasta la compra real.

El informe de Comportamiento de Compras: requiere un conocimiento básico de conceptos de marketing online, como funnels, conversión y embudo, para comprender como funciona nuestra estructura online, en su objetivo de   conseguir una venta y cuan efectiva es.

Uno de sus elementos más importantes  es que muestra las capas o etapas que componen el embudo y el número de sesiones en cada una.

El informe de comportamiento de pago: detalla  el proceso de pago,  los pasos que esta contiene y las personas que retiene.

El informe de rendimiento de ventas: se extiende con respecto a su versión estándar al mostrar información relacionada con los impuestos, envíos,  y reembolsos.

El Informe de rendimiento del listado de productos de la tienda, nos facilita realizar análisis individuales dentro de un conjunto de productos dado.

Otros informes como las Promociones internas: Ofrecen el rendimiento detallado de las promociones para una categoría.

El informe ampliado también ofrece información sobre la gestión del marketing de afiliados y la efectividad del cuponeo como parte de la estrategia de marketing online que hayamos escogido.

La necesidad el quid de la cuestión

Antes de decidir que análisis usar, o incluso si usarlos ambos, hay que partir de saber que quieres conocer.

Como todas las cosas complejas de este mundo, todo empieza por una pregunta sencilla:

¿qué información quieres obtener?

Esta respuesta dependerá, según mi criterio de tres cuestiones básicas:

  • El conocimiento que tengas de tus clientes y tu entorno de mercado,
  •  tu conocimiento de Google Analytics, 
  • ….y del tiempo de que dispongas para estudiar métrica y trabajar con ella, 

No ahondaré en este tema, pero explicado de un modo suscinto, podríamos decir que si llevas una pequeña tienda de corbatas física y online, donde lo haces todo, y tu mercado objetivo son los caballeros de tu ciudad, debería bastarte con un análisis standard, de cómo marcha tu tienda; pero si tu negocio crece, intentas vender a todo el país, e incluso internacionalmente y comienzas a tener trabajadores que atiendan diferentes áreas del negocio, dejándote el tiempo necesario para poder estudiar y comprender mejor a tus clientes, el informe ampliado comienza a ser una oportunidad que no debes dejar pasar de largo.

La complejidad.

El diseño del informe responde a estas mismas preguntas, y debemos evitar llenarnos de información que no necesitamos ni utilizamos, porque convertirá en poco relevante, complejizando innecesariamente una tarea que debes ser fácil de entender y de llevar a cabo periódicamente .

Un informe debe ser tan sencillo de comprender que hasta nuestra abuela lo entienda, sino logramos esto, no estamos en el camino correcto  y hay que trabajarlo hasta que lo simplifiquemos lo suficiente, para que sea entendible y útil.

Lamentablemente en este sentido Google, no lo pone del todo fácil.

El informe estándar es por supuesto más fácil de configurar y existen herramientas adicionales (plugins) para integrarlo a Woocommerce, UltraCart , Shopify,  y Prestashop, en otros casos será necesario la ayuda de especialistas en programación.

No obstante es necesario configurar adecuadamente  lo que queremos recibir desde  nuestra cuenta en GA.

El informe mejorado es mucho más complejo de configurar, lo cual es lógico ya que siguen más comportamientos y por tanto incluyen mas variables en los procesos de compra.

No obstante, esa complejidad  se minimiza si tenemos claro que deseamos obtener, y se  convierte en bastante intuitiva la operación, al margen de modificaciones que Google puede hacer sobre el modo en que se obtienen o se configuran sus herramientas

Lo recomendable si se usa el informe mejorado, es usar otras herramientas que redondeen y complementen su información como el Google Data Studio.

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

….un sueño es casi todo  y más que  nada, más que todo al soñarlo, casi nada después……

Git, comandos mas importantes

Los comandos  más  importantes de Git, son aquellos que nos ayudan a crear nuestro repositorio, actualizarlo y publicarlo, permitiéndonos su total control, seamos freelance o un equipo de trabajo.

Resumiendo como trabaja git, diré que :

Git controla versiones  en un repositorio local, siguiendo una estructura de edición, preparación y confirmación de acciones sobre el.

Cuando estas programando y estas listo para añadir cambios los preparas con git add . que los coloca en estado stage, o sea  como una copia instantánea lista, la cual solo valdrá si la confirmas con git commit, o será rechazada si la deshaces con git reset. Esta confirmación se guardará  en el historial de proyecto y será entonces si tienes un repositorio remoto cuando usaras git push para enviarlo allí.

No voy a ahondar mucho mas en el tema teorico de que  es git, ni porque se necesitas, o no.

Lo cierto es que si trabajas  en proyectos cortos, tu solo, y manejas bien las versiones de lo que haces con las carpetas en tu ordenador,  bien documentadas,  no lo necesitas obligatoriamente, sin embargo si desarrollas junto a un grupo de desarrolladores, con muchos cambios y participación en el código, manejos de variantes,  etc , git es una excelente opción.

Los comandos que muestro aquí son solo unos pocos, pero que te permitirán saber como funciona git  de modo básico y espero que útil.

Asumo que has instalado git que no tiene mayores complicaciones y estás en la consola.

Git init

Ve hastas la carpeta  donde esta tu código y escribe

git  init 

Te creará un repositorio creará un repositorio local vacio,  dentro de la carpeta donde tenemos el proyecto, con un mensaje como este

 Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra
 $ git init 
 Initialized empty Git repository in H:/desarrollo/sierra_maestra/.git/ 

Al mismo tiempo se habrá creado una  carpeta oculta llamada .git, que  es la encargada de gestionar el repositorio que acabamos de crear. Si quieres dejar de utilizar git, borra esa carpeta y listo, si quieres volver a utilizarlo vuelve a crear el repositorio con : git init

Para ver las carpetas ocultas utiliza el comando:  ls -a.

 Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ ls -a
  ./.git/js/'plantilla sierra maestra V1.html' 
 ../css/'Plantilla pag web 1.psd'   plantilla-sierra-maestra-1.jpg 

Para conocer el estado del repositorio, los commit realizados , escribe

git status

El resultado como no has hecho nada aun en el repositorio será:

  Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ git status
 On branch master
  
 No commits yet
  
 Untracked files:
   (use "git add <file>..." to include in what will be committed)
         Plantilla pag web 1.psd
         css/
         js/
         plantilla sierra maestra V1.html
         plantilla-sierra-maestra-1.jpg
  
 nothing added to commit but untracked files present (use "git add" to track) 

Lo primero que vemos es “On branch master” esto significa que estamos en la rama principal, es la rama por defecto cuando creamos un repositorio.Git tiene dos procesos para gestionar nuestros archivos. Primero los tenemos que añadir a una zona intermedia conocida como stage y después tenemos que confirmar el paso  definitivo de los archivos al repositorio.

Nota:

Branch : rama de proyecto, puedes crear tantas como desees, y después desecharlas o llevarlas  al proyecto

Master: rama original  y principal del proyecto y la que ese establece por defecto.

git add

git add .

Importante: Hay que dejar un espacio entre add y el punto”

Con este comando le decimos a git que pase todos los archivos que estén sin pasar al estado stage.

 Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ git add .
 warning: LF will be replaced by CRLF in css/bootstrap-grid.css. The file will have its original line endings in your working directory
 warning: LF will be replaced by CRLF in css/bootstrap-grid.min.css.
 The file will have its original line endings in your working directory
 warning: LF will be replaced by CRLF in css/bootstrap-reboot.css.
 The file will have its original line endings in your working directory
 warning: LF will be replaced by CRLF in css/bootstrap-reboot.min.css. ...........

Si ahora volvemos ejecutar el comando git status obtendremos algo como esto:

  Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ git status
 On branch master
  
 No commits yet
  
 Changes to be committed:
   (use "git rm --cached <file>..." to unstage)
         new file:   Plantilla pag web 1.psd
         new file:   css/bootstrap-grid.css
         new file:   css/bootstrap-grid.css.map
         new file:   css/bootstrap-grid.min.css
         new file:   css/bootstrap-grid.min.css.map
         new file:   css/bootstrap-reboot.css
         new file:   css/bootstrap-reboot.css.map
      .............

git commit  

Para confirmar estos archivos y que pasen  definitivamente al  repositorio,  utilizamos como ya dijimos  commit .

Utilizamos el parámetro -m para indicarle una descripción del commit que vamos a hacer, en este caso le decimos que es el commit inicial del proyecto.

 Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ git commit -m "Commit inicial del proyecto"
 [master (root-commit) 9e33f1e] Commit inicial del proyecto
  25 files changed, 36210 insertions(+)
  create mode 100644 Plantilla pag web 1.psd
  create mode 100644 css/bootstrap-grid.css
  create mode 100644 css/bootstrap-grid.css.map
  create mode 100644 css/bootstrap-grid.min.css
  create mode 100644 css/bootstrap-grid.min.css.map
  create mode 100644 css/bootstrap-reboot.css
  create mode 100644 css/bootstrap-reboot.css.map
  create mode 100644 css/bootstrap-reboot.min.css
  create mode 100644 css/bootstrap-reboot.min.css.map
  create mode 100644 css/bootstrap.css
  create mode 100644 css/bootstrap.css.map
.............

Si no indicamos el parámetro -m se abrirá un editor de código de terminal  que hayamos definido como editor por defecto puede ser Vim u otro, deberemos escribir  el mensaje Si volvemos a ejecutar el comando git status obtendremos este mensaje:

 Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ git status
 On branch master
 nothing to commit, working tree clean 

Esto significa que no hay nada para confirmar, es decir que todos los archivos se encuentran ya en el repositorio.

En resumen

git  add: Añade modificaciones al codigo

commit:  Confirma las modificaciones en el código.

Usa: git commit -m”comentarios sobre el commit”  como buena practica

Push:  añadir un proyecto, código o modificación al repositorio externo, por ejemplo github

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

…., si avanzo sígueme, si me detengo empújame, si retrocedo mátame…….

Algunos comandos en mac

mac

Algunos de los comandos que uso para navegar desde la consola en el mac

Listar todos las  carpetas y archivos de la carpeta donde te encuentras

ls 

Listar todos archivos  y carpetas ocultos

ls –a

Crear una carpeta con un nombre dado

mkdir nombreCarpeta

Entrar a una carpeta

cd nombreCarpeta

Salir de una carpeta

cd ..

Eliminar una carpeta

rm –m nombreCarpeta

Limpiar los comandos usados de la consola

clear

Reescribir un comando recién escrito  en consola, durante la sesión

teclas de flechas, hacia arriba o hacia abajo en dependencia del orden que se desee.

Crear un archivo

touch documentoNuevo.doc

Guardar un archivo desde sublime text

A veces queremos guardar un archivo recién creado y no nos aparece la ubicación al desplegar save as. Basta con abrir guardar como desplegara las carpetas y podrás escoger donde guardar

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

….subir montañas hermana hombres…..

Números de base N y su precisión.

Todos los sistemas numéricos posicionales (números de base-N) comparten el mismo problema de  precisión

La mayoría de los lenguajes de programación, se basan en el estándar IEEE 754.

La cuestión,  es que los números se representan en este formato como un número entero multiplicado por una potencia de dos; los números racionales (como 0.1, que es 1/10) cuyo denominador no es una potencia de dos, no se pueden representar de forma exacta.

Para 0.1 en el formato estándar binario64, la representación se puede escribir en decimal exactamente como 0.1000000000000000055511151231257827021181583404541015625, o 0x1.999999999999ap-4 en notación C99 hexfloat.

Sin embargo, el número racional 0.1, que es 1/10, se puede escribir exactamente como 0,1 en decimal, o 0x1.99999999999999 … p-4, en un análogo de la notación hexfloat C99, donde … representa una secuencia interminable de 9.

Las constantes 0.2 y 0.3  por ejemplo, también tendrán aproximaciones a sus valores verdaderos.

Pero sucede que el doble más cercano a 0.2 es mayor que el número racional 0.2, mientras  que el doble más cercano a 0.3 es menor que el número racional 0.3.

La suma de 0.1 y 0.2 termina siendo mayor que el número racional 0.3.

Un tratamiento bastante completo de las cuestiones de la aritmética de coma flotante puede leerse en What Every Computer Scientist Should Know About Floating-Point Arithmetic, o en floating-point-gui.de, ambos en ingles.

Los números decimales con base 10, tienen los mismos problemas, por ejemplo  números como 1/3 terminan como 0.333333333 .

En la práctica, este problema de precisión significa que se necesita usar funciones de redondeo para redondear sus números de coma flotante a la cantidad de decimales que le interesen antes de mostrarlos.

También debe reemplazar las pruebas de igualdad con comparaciones que permitan cierta tolerancia, lo que significa:

No hacer si (x == y) {...}

En su lugar, haga if (abs (x - y) <mi valor de tolerancia) {...}.

Donde abs es el valor absoluto.,mi valor de tolerancia es un valor que eliges  para tu aplicación,  ( no debe ser una constante de estilo «épsilon») y tendrá mucho que ver con el «margen de maniobra» que estés dispuesto a permitir y cuál será el número más grande que va a comparar.

Mas de cien pupilas, donde vernos vivos …..

J. Sabina
Translate »