Aprende a programar desde cero: Variables

Esta es una serie de artículos donde discutimos los conceptos básicos de la programación desde cero. por lo que si ya sabes programar puede que te parezca demasiado simple.

En esta ocasión aprenderemos qué son las variables, para que sirven y cómo usarlas en la práctica.

Que son las variables

Las variables son una especie de contenedor que nos permite guardar un dato para luego poder recuperarlo de forma fácil y rápida por medio del nombre que le demos.

En este sentido las variables se asemejan mucho a una caja con una etiqueta.

Las variables son como cajas

Imagina lo siguiente: Tu cuarto es un desorden y hay un montón de cosas que ya no usas, así que decides guardarlas.

Tienes dos alternativas:

  1. Amontonar todo en un solo lugar.
  2. Usar cajas marcadas según su contenido

El problema con la primera opción es que si luego quieres volver a utilizar, por ejemplo, tu viejo gameboy, tendrás que sacar cosa por cosa para encontrar lo que deseas.

Si en lugar de eso acomodas las cosas en cajas marcadas, luego sera mucho mas fácil encontrarlas lo que deseas.

Las variables guardan datos y se identifica por medio de un nombre.

Para que sirven

Las variables nos permiten reutilizar una solución.

Una vez encontramos la solución a un problema, muy seguramente podemos aplicar la misma solución a problemas similares si identificamos las partes que cambian (varían) y las sustituimos.

Un ejemplo de esto son las formulas matemáticas. Pitagoras halló la forma de calcular la hipotenusa de un triangulo rectángulo, con su teorema podemos resolver cualquier triangulo rectángulo con solo sustituir las variables con nuevos valores.

Teorema de Pitagoras

Un ejemplo “mas practico” son los formatos de documentos, donde solo debemos sustituir los campos en blanco con los datos requeridos.

Aquí podemos identificar otra parte importante de las variables: el tipo de dato.

El tipo de dato es el conjunto de valores que una variable puede tomar. Si vemos el siguiente formato de permiso, solo ciertos valores tienen sentido en cada campo.

Formato de documento

En los campos de nombres y motivo no tiene sentido escribir puros números, así como en los de día, año curso y teléfono puras letras.

Las variables solo tienen un conjunto de valores posibles (tipo de dato)

Una definición informal

Con lo visto anteriormente podemos decir que:

Una variable nos permite almacenar un valor de cierto tipo para su posterior recuperación por medio de su nombre.

Variables en la practica

Ahora que tenemos una idea mas clara sobre que es una variable, es momento de ponerlo en practica.

Como crear una variable

La creación de una variable se divide en:

  • Definición: le damos un nombre y especificamos el tipo de dato.
  • Inicialización: Asignamos un valor a la variable.

Como crear una variable

En los lenguajes de tipado dinámico no se especifica un tipo de dato he incluso podemos cambiar el contenido de una variable de un entero a un float o un string – Aunque no deberíamos hacerlo, ya que ésto genera confusión.

Ejemplos de lenguajes de tipado dinámico son son javascript, php y python.

Tipos de datos

Si bien los tipos de datos dependen del lenguaje que estemos utilizando, existen algunos tipos básicos que siempre encontraremos:

TIPO DE DATODESCRIPCIÓN
intNúmeros enteros
floatNúmeros con decimales
booleanValor logico (vardadero o falso)
stringTexto
ArreglosConjunto de datos del mismo tipo

En lenguajes con tipado estático es necesario especificar que tipo de dato deseamos guardar en la variable y no es posible almacenar un dato que no sea del tipo que especificamos:

int entero = 10;
float decimal = 1.3;
String texto = "hola mundo!"
// Esto genera un error
texto = 10;

En lenguajes de programación con tipado dinámico no es necesario especificar el tipo de variable.

// javascript
var entero = 10;
var decimal = 1.23
var texto = "hola mundo!"
// es posible cambiar el tipo de dato, pero no deberíamos hacerlo
texto = 10;

Nombres de las variables

Las reglas para la creación de nombre de variables dependen del lenguaje, por lo que debes consultar la documentación del mismo para estar seguro; pero por lo general:

  • Tienen que empezar con una letra o un guion bajo. Algunas excepciones:
    • En PHP tienen que empezar con el signo $
    • En javascript pueden empezar con el signo $.
  • No pueden contener espacios
  • Solo puede contener letras, números y el guion bajo (_)
    • En javascript también pueden contener el signo $

Ejemplo:

// lenguaje java
int edad = 10;
String nombre_completo = "John Smith";
// Incorrecto
String Nombre completo = "foo"; // contiene espacios
float 3pedro = 10.1; // empieza con un numero

Buenas practicas

Cualquier tonto puede escribir código que un ordenador entienda. Los buenos programadores. Martin Fowler

Gran parte de nuestra vida como desarrolladores la pasaremos corrigiendo errores (bugs), agregando nuevas características y en general manteniendo programas existentes. Es por esto que debemos hacer que nuestros programas sean fáciles de entender.

  • Los nombres de las variables deben ser descriptivos, incluso si esto significa que sean largos (sin excederse).
// que ~%$*#@ hace esta función
function f(a, c, m) {
	return a * Math.pow(1 + c, m);
}

Puede que en el momento nos parezca obvio lo que hace esta función, pero ¿lo seguirá siendo 1 mese después?, ¿que tal 10 meses después? o ¿seguiremos siendo nosotros los que mantengamos el código?.

Recuerda:

Codifica siempre como si la persona que fuera a mantener tu código fuera un asesino en serie maníaco que sabe donde vives
// mucho mejor
function interesCompuesto(capital_inicial, porcentaje, tiempo) {
	return capital_inicial * Math.pow(1 + porcentaje, tiempo);
}
  • Ser consistentes a la hora de nombrar nuestras variables. Si los nombres de nuestras variables siguen un patrón predecible, serán mucho mas fácil de recordar y disminuiremos la posibilidad de cometer errores.
int Mi_Entero = 10;
String miString = "Hola ";
float mifloat = 10.1;
// varias lineas mas abajo o incluso en otro archivo
// no recordamos como llamamos a nuestra variable
mostrarMensaje(mistring + " Juan");

Conclusión

Con esto concluimos la primera parte de este “mini-curso” sobre programación, en el próximo articulo hablaremos sobre las iteraciones.

Si te gusto no olvides compartirlo, y si tienes alguna pregunta déjala en los comentarios.

Tablet nueva, juegos rotos.

Hace pocos días llego por fin mi tableta (una gallaxy tab 2) y como podrán imaginar lo primero que hice fue probar los juegos que he desarrollado y para mi sorpresa varios de ellos no funcionaban correctamente; en algunos se veía un segundo canvas con la misma imagen y en otros el contenido previo no se borraba. Al parecer es un problema ya viejo con clearRect que afecta a android 4.1. Lo primero que se me ocurrió para solucionar el problema fue el viejo truco de re-definir el tamaño del canvas:
canvas.width = canvas.width;
Ahora si que funcionaban, pero algunas acciones como el arrastrar eran realmente lentas (especialmente al arrastrar y soltar); el problema con este método es que ademas de borrar el contenido del canvas, también restablece su estado (fillStyle, clearStyle, scale, translate, shadowColor….) lo que al parecer influye en el rendimiento (al menos en el gallaxy tab – único dispositivo que tengo para hacer pruebas). Otra de las soluciones sugeridas para eliminar el problema del canvas duplicado que encontré era el quitar el estilo overflow: hidden de todos los elementos padres del canvas, aunque el problema desapareció al igual que en el método anterior el rendimiento era pésimo.

Solución

Hasta el momento la solución con los mejores resultados es la de usar un color solido como fondo para el canvas y al momento de borrar el contenido usar fillRect en lugar de clearRect
<canvas style="background: #fff;"></canvas>
function clear(ctx) {
    ctx.fillStyle = "#fff";
    ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}
El aumento en rendimiento es considerable, sobre todo en juegos que requieren arrastrar y soltar (como el solitario). Aun así esta no es una solución definitiva ya que al usar un color solido no es posible apilar canvas para crear capas.
¿Conoces alguna mejor solución? déjala en los comentarios.

Easy QR Code: Mi primera extensión para chrome


tltr: Hice una extensión para chrome que genera códigos QR con tan solo dos clics (descarguen aquí). Si les gusta compartan/comenten en twitter/facebook (quiero ser famoso *¬*).

Los códigos QR son una forma de almacenar información en un código de barras en dos dimensiones, y son una muy buena forma de copiar enlaces y texto a nuestros dispositivos móviles en lugar de tener que copiarlos a mano.

En la tienda de extensiones de chrome no encontré ninguna que cumpliera mis necesidades (rápido y simple de usar), mucha de las “extensiones” son simples enlaces a paginas y requieren muchos pasos:
  1. Copiar texto/enlace
  2. Clic para abrir la “Extensión”
  3. Pegar texto en un formulario
  4. Clic para generar el código
Demasiado extenuante para un simple código, en mi extensión ideal solo se necesita:
  1. Clic derecho sobre texto/enlace
  2. Seleccionar generar código
Listo. adicionalmente el código debe generarse rápidamente. con estas especificaciones y armado con una librería para generar códigos QR y la documentación del API de extensiones de chrome y dos cojones nació mi primera extensión para google chrome: Easy QR Code.

A continuación el enlace a la extensión y un corto vídeo de su funcionamiento.


Mi obsesión con el anime


Los que me conocen saben que estoy interesado en una variedad de cosas, pero suelo distraerme con facilidad, y lo que mas me distrae (o ¿en lo que mas me concentro?) es el anime.

De tiempo en tiempo me engancho tanto con alguna serie que termino buscando de todo sobre ésta: Fondos de pantalla, openings/endings, AMV, posters motivacionales (tengo alrededor de 20.000 en mi pc) y noticias entre otros. El problema es que no se de ningún sitio que contenga todo este material, todo lo recolecto de diferentes lugares como foros, youtube, google images… y esto me quita mucho tiempo.

Alguien dirá que la solución es muy simple: que deje de buscar pendejadas y me ponga a trabajar. Pero el anime es una forma de distraerme del día a día, ademas el contenido de estos (historia/humor/personajes…) es mucho mas rico que el de muchas películas y programas de televisión, incluso hay algunos que dejan enseñanzas sobre la vida y esas cosas u_u.

Si saben de algún un sitio donde se pueda encontrar este contenido concentrado, con animes/manga clasificados por géneros (gore, echi, shounen…) Dejen el link en los comentarios.

Dividir correctamente un string en caracteres. No con string.split(“”)


Dividir un string en caracteres parece una tarea sencilla, y lo es. mientras un carácter sea solo un carácter.

Como así?

En unicode existen caracteres que se combinan con otros, ejemplo de estos son los caracteres de acento. De esta forma a simple vista un carácter puede parecer un solo símbolo pero estar formado por dos o mas.

Por ejemplo la letra “a” con tilde puede ser un solo carácter (u+00e1), pero puede darse el caso que sea una letra a + una tilde (a+’) que son dos caracteres (u+0061 y u+0301 respectivamente).

Esto es un problema, en especial para una aplicación que necesite acceder a cada uno de los caracteres de una palabra como en los crucigramas, ahorcado, sopas de letras, etc.

Por ejemplo en mi juego de sopa de letras a veces las palabras en la cuadricula quedaban en la posición incorrecta. El problema, algunas palabras usaban mas espacio debido a los caracteres de combinación (eje. “mamá” ocupando 5 cuadros = m | a | m | a | ‘ |).

Que puede salir mal

Para conocer el largo de una cadena de texto normalmente usamos la propiedad length… error, ésta solo da resultados correctos si cada carácter en el texto esta formado por un solo codepoint.
alert("mamá".length)

Gracias a un enlace en MDN (Mozilla Developer Network) encontre esta solución.  para obtener el largo correcto del string contamos los caracteres que no son marcas de combinación. a continuación la función (con algunas modificaciones).
// regexp = rangos de caracteres correspondientes a marcas de combinación
rCombiningMarks = /[u0300-u036Fu1DC0-u1DFFu20D0-u20FFuFE20-uFE2Fu0483-u0489u0591-u05BD]/g;

function stringLength(string) {
// iniciar un contador de caracteres en 0
var length = 0;

// por cada caracter en string
for (var i = 0, l = string.length; i < l; i++) {
// si no es una marca de combinación
if (! rCombiningMarks.test(string.charAt(i)) )
// incrementar el contador de caracteres
length += 1
}

return length;
}
Probamos nuestra función.
alert(stringLength("mamá"));


Como dividir un string?

Podemos usar un método similar al anterior para dividir un string:
// regexp = rangos de caracteres correspondientes a marcas de combinación
rCombiningMarks = /[u0300-u036Fu1DC0-u1DFFu20D0-u20FFuFE20-uFE2Fu0483-u0489u0591-u05BD]/g;

function splitString(string) {
// iniciar un array de caracteres
var chars = [],
lastChar;

// por cada caracter en string
for (var i = 0, l = string.length; i < l; i++) {
// si no es una marca de cominación
if (! rCombiningMarks.test(string.charAt(i)) ) {
// Agregar al array de caracteres
chars.push(string.charAt(i));
}
// de lo contrario
else {
// Concatenar con ultimo caracter en el array
var lastChar = chars[chars.length - 1];
chars[chars.length - 1] = lastChar + string.charAt(i);
}
}

return chars;
}

// TEST
alert("con string.split: "+("mamá".split("").join(" | ")));
alert("con splitString: " + splitString("mama").join(" | "));


Conclusión

Aun cuando javascript nos provee varios métodos útiles para el manejo de strings, números, arrays y objetos, estos no siempre nos darán los resultados deseados. debemos probar nuestro código para estar seguros que se comporta de la forma correcta.

Algún otro método/función nativa de javascript de la que no hay que confiar. Déjalo en los comentarios.