tutorial Posts

Variables

Aprende a programar desde cero: Variables

Esta es una serie de artículos donde discutimos los conceptos básicos de la programación de una forma intuitiva, por medio de ejemplos.

En esta ocasión aprenderemos sobre las variables, para que sirven y como usarlas en la practica.

[toc]

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 asignamos.

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

Variables

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 sitio.
  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 Pitágoras

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 permiso

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 DATO DESCRIPCIÓN
int Números enteros
float Números con decimales
boolean Valor logico (vardadero o falso)
string Texto
Arreglos Conjunto 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 escriben código que los humanos pueden entender. 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 proximo articulo hablaremos sobre las iteraciones.

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

Canvas desde cero: primeros pasos

El elemento canvas es una gran herramienta para crear juego, animaciones y manipular imágenes, aun así no todos los navegadores soportan esta etiqueta, por tanto, es necesario contar con alternativas para no dejar de lado a los usuarios de dichos navegadores.

En esta primera parte veremos dos de estas alternativas así como algunas particularidades de la etiqueta canvas.

Compatibilidad

En la actualidad los únicos navegador que no cuentan con soporte para el elemento canvas son Internet Explorer 6, 7 y 8; no obstante existen soluciones (polyfills) que emulan su funcionalidad, entre los que se destacan:

  • excanvas: utiliza VML, una tecnología propietaria de Microsoft similar al svg y no necesita de plugins, pero carece de algunos métodos (getImageData, toDataURL…).
  • flashcanvas: utiliza flash (duh), es mas rápido que excanvas (a mi parecer) y soporta mas características, pero hay que comprar una licencia para poder desarrollar aplicaciones de comerciales.

La etiqueta canvas

El elemento canvas cuenta con una etiqueta de apertura y una de cierre, pero a diferencia de otras etiquetas, su contenido solo es visible en navegadores antiguos (ya que estos ignoran las etiquetas desconocidas) lo cual nos permite mostrar un contenido alternativo a los usuarios de dichos navegadores.

<canvas height="150" id="canvas" width="300">
<!-- contenido a mostrar si el navegador no soporta canvas -->
<img src="/images/imagen-estatica.jpg" />
</canvas>

Otro hecho a destacar es que sus medidas se declaran mediante los atributos width/height y no a través css. al usar css se escala el elemento, así, si el canvas mide 300×150 y cambiamos sus medidas por 600×300 los pixeles “medirán el doble” y la imagen se verá borrosa.

Por ejemplo, los siguientes cuadros se dibujaron en la mismas posición (10, 10) y tienen las mismas medidas (30×30) pero el canvas de la derecha fue escalado 6x usando css.

Note el borde borroso el la segunda imagen 

Detectar soporte

Antes de empezar a usar el canvas necesitamos saber si el navegador siquiera soporta dicho elemento, para esto:

  1. Creamos un elemento canvas y comprobamos si cuenta con el método getContext
  2. De lo contrario verificamos que exista un Polyfill
if (! document.createElement("canvas").getContext || ! window.G_vmlCanvasManager )
alert("Actualize su navegador");

Accediendo desde javascript

Para poder acceder al elemento desde javascript hay esperar que el DOM este listo, para esto puedes utilizar la función ready de jQuery o colocar el script justo antes de </body>.

A continuación obtenemos una referencia al contexto de dibujo del canvas utilizando el método getContext:

var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");

Ahora si podemos empezar a dibujar:

ctx.fillStyle = "red";
ctx.fillRect(50, 50, 30, 20);

Utiliza un navegador moderno para poder ver el ejemplo

TIPS

Antes de poder acceder al contexto del canvas en IE<9 (usando excanvas/FlashCanvas) debemos inicializarlo, para esto, en lugar de usar el método getContext podemos usar la siguiente función:

function getContext(canvas) {
if (! canvas.getContext && window.GV_ContextCanvas) {
G_vmlCanvasManager.init(canvas);
} else {
throw new Error("El navegador no soporta el elemento canvas");
}

return canvas.getContext("2d");
}

Conclusión

Finalizando esta primera parte tenemos todo listo para empezar a trabajar con el canvas. con suerte ahora podrás mostrar contenido alternativo para usuarios con navegadores antiguos, detectar el soporte del elemento canvas ya sea de forma nativa o mediante un polyfill y obtener el contexto de dibujo.

No te pierdas la siguiente parte en la que veremos el sistema de coordenadas y como dibujar formas básicas.

Si te gusto el tutorias compartelo en twitter o subscribete y te avisare cuando esté disponible la siguiente parte.

Canvas desde cero

Si llevas tiempo con ganas de aprender a usar el canvas o quieres refrescar tus conocimientos,
no puedes perderte esta serie de tutoriales que arranca el día de hoy, donde no solo se explicara
como usar x función sino que desarrollaremos programas reales donde podrás aplicar lo aprendido.

y quien es usted para decirme que hacer

Soy un tipo al que le gusta la programación, en especial todo lo relacionado con la web (javascript *¬*)
y desde que conocí el elemento canvas quede fascinado con la idea de poder dibujar en navegador.
si bien no soy un experto y aun sigo aprendiendo, ya llevo tiempo trabajando con este elemento
y he aprendido mucho gracias a la comunidad y esta es mi forma de contribuir en algo.
algunos de los trabajos que he hecho:

P.D.: Si ven que me estoy colgando en la actualización del blog no duden en jalarme las orejas en twitter XD.

Creando un blog con django – parte 4

Después de una eternidad sin escribir y casi abandonar el tema de django, hoy por fin retomo el asunto. Hasta el momento tenemos los post clasificado por tags, pero un blog sin comentarios no es nada, así que hoy veremos como crear el formulario de comentarios.

En django existen dos formas de crear un formulario, una es crear cada campo manualmente y la otra es crearlos automáticamente basados en el modelo de datos.

Ya que casi siempre los formulario se usan para agregar/editar una tabla en una BD, y los campos del formulario reflejan los campos de la tabla, seria un desperdicio de tiempo crearlos manualmente.

Dejemos de hablar y empecemos a escribir código, editemos el archivo forms.py en el directorio de nuestra aplicación:

from django.forms import ModelForm #1
from blog.models import Comment #2

class CommentForm(ModelForm): #3
"""Formulario de comentarios"""
class Meta: #4
model = Comment #5
exclude = ("post","deleted") #6

Hora de explicar lo que hemos hecho:

  1. Importamos ModelForm, la base para los formularios basados en modelos de datos.
  2. Importamos el modelo para el que se creará el formulario
  3. Creamos una subclase de ModelForm.
  4. En la clase Meta especificamos como crear el formulario
  5. model: modelo en el que se basa el formulario.
  6. exclude: campos a excluir, en este ejemplo post lo asignamos según el articulo desde el que se envió el comentario y deleted lo decidimos en la pagina de administración si es un comentario insultante. Si son muchos los campos a excluir podemos hacer lo contrario y especificar los que se deben incluir.

    Ahora podemos incluir el formulario en la vista single:

    # Archivo views.py
    from blog.models import Post, Tag, Comment
    from blog.forms import CommentForm
    ...
    # la función recibe el numero capturado
    def single(request, id=0):
    # recuperar post según id
    post = Post.objects.get(id=int(id))
    # Crear formulario
    form = CommentForm()

    return render_to_response("single.html", locals())

    Para crear el formulario se instancia el objeto adecuado y en la vista se usa esta instancia para mostrar el formulario:

    {# plantilla single.html #}
    {% extends 'base.html' %}

    {% block main_content %}
    {% include 'include/article.html' %}
    {# necesitamos crear el tag form #}
    &lt;form action="" method="form"&gt;
    {{ form }}
    &lt;/form&gt;
    {% endblock %}

    Con esto veremos el formulario en nuestro blog, lo llenamos y enviamos…

    Wow un error. Django requiere que incluyamos protección contra ataques csrf, este tipo de ataque permite que alguien engañe a un usuario registrado para enviar datos a nuestro sitio usando un formulario en otra pagina web. Afortunadamente django tiene todo lo necesario para protegernos con unas cuantas lineas de código.

    # Archivo views.py
    from blog.models import Post, Tag, Comment
    from blog.forms import CommentForm
    # importamos el decorador
    from django.views.decorators.csrf import csrf_protect
    # importamos render
    from django.shortcuts import render

    ...
    # aplicamos el decorador función que recibe datos de formulario
    @csrf_protect
    def single(request, id=0):
    # recuperar post según id
    post = Post.objects.get(id=int(id))
    form = CommentForm()

    # usamos render en lugar de render_to_response
    return render(request, "single.html", locals())

    Ahora incluimos el tag {% csrf_token %} dentro del formulario en la plantilla single.html. Esto crea un elemento input oculto con un token único que se verifica al enviar datos al servidor, si este no coincide, se produce un error 403 (prohibido) y tenemos una app algo mas segura.

    Ok, ya podemos enviar datos del formulario al servidor, hora debemos validarlos y guardarlos en la BD.

    # Archivo views.py
    @csrf_protect
    def single(request, id=0):
    # recuperar post según id
    post = Post.objects.get(id=int(id))
    # recuperar comentarios de este post
    comments = Comment.objects.filter(post=post)

    # Si la petición es POST es porque enviaron el formulario
    if request.method == "POST":
    # Creamos una instancia del modelo Comment asignado el post actual
    comment = Comment(post=post)
    # Creamos una instancia del formulario con los datos recibidos
    form = CommentForm(request.POST, instance=comment)

    # Validamos los datos
    if form.is_valid():
    # Guardamos el comentario en la BD
    form.save()
    # Enviamos al usuario de nuevo al post
    return HttpResponseRedirect("/post/{0}".format(slug))

    # De lo contrario creamos un formulario vacío
    else:
    form = CommentForm()

    return render(request, "single.html", locals())

    Podemos notar algunas cosas:

    1. Validamos el formulario con el método is_valid que no definimos. ¿como es esto posible?; Al crear el modelo Comment especificamos el tipo de datos admitidos, el formulario “sabe” que si esto datos no corresponden, el formulario contiene errores.
    2. Para guardar los datos usamos form.save y no comment.save. Esto se debe a que hay datos que no están incluidos en el formulario (post) pero si en la instancia comment y viceversa, por esto pasamos comment al formulario en el momento de crearlo.

    Solo resta mostrar los comentarios, editamos la plantilla single.html:

    {# plantilla single.html #}
    {% extends 'base.html' %}

    {% block main_content %}
    {% include 'include/article.html' %}
    {% for comment in comments %}
    &lt;div class="comment"&gt;
    &lt;div class="user"&gt;{{ comment.name }} dijo:&lt;/div&gt;
    &lt;div class="body"&gt;{{ comment.body }}&lt;/div&gt;
    &lt;small&gt;{{ comment.date|date:"d-m-Y" }}&lt;/small&gt;
    &lt;/div&gt;
    {% endfor %}
    {# necesitamos crear el tag form #}
    &lt;form action="" method="form"&gt;
    {{ form }}
    &lt;/form&gt;
    {% endblock %}

    Con esto solo falta crear el sitio de administración para agregar post y moderar los comentarios y tendremos un blog terminado. Estén pendientes por la ultima parte de esta serie que seguro saldrá antes que se acabe el mundo este 21 de diciembre XD.

    Creando un blog con django – parte 3

    En la parte anterior dejamos la base de datos lista, es momento de crear las plantillas para visualizar estos datos.
    Lo primero que haremos es configurar el directorio donde estaran guardas las plantillas. Creamos el directorio templates en la raíz del proyecto y editamos el archivo settings.py.

    .....
    import os

    TEMPLATE_DIRS = (
    os.path.join(os.path.dirname(__file__) ,"templates"),
    )
    ....

    Así el script puede encontrar el directorio templates aun cuando cambiemos de ubicación la carpeta del proyecto. Ahora editamos el archivo urls.py para incluir la url a la pagina.

    ....
    urlpatterns = patterns('',
    (r'^$', 'blog.views.index'),
    ....
    )

    Con esto le decimos a django que toda petición hecha a la raíz del blog sera manejada por la función index ubicada en el archivo views, la cual luce así:

    from django.shortcuts import render_to_response

    def index(request):
    return render_to_response("index.html")

    Al visitar la raíz del sitio, django llamara la función index pasando como argumento un objeto request que contiene información sobre la solicitud (datos POST y GET entre otros). La función index realizar algún proceso y retornar un objeto response.

    Si iniciamos el servidor de desarrollo y entramos a la dirección localhost:8000 veremos un mensaje de error como el de la imagen ya que la plantilla index.html aun no existe, así que manos a la obra.

    <!DOCTYPE HTML>
    <html lang="es-ES">
    <head>
    <title>Mi Blog</title>
    </head>
    <body>
    <!-- hasta aquí siempre es igual -->
    <h1>Hola Django</h1>
    </body>

    No muy útil, pero por el momento es todo lo que necesitamos. Imagine que creamos otras plantillas para post individuales, contacto, faq, quejas… debemos repetir la cabecera en cada una de ellas.

    El sistema de plantillas de django permite crear plantillas base con bloques que luego pueden ser reemplazados por las plantillas que heredan de ésta; para tal efecto creamos la plantilla base.html:

    <!DOCTYPE HTML>
    <html lang="es-ES">
    <head>
    <title>Mi Blog</title>
    </head>
    <body>
    {% block content %}
    {% endblock %}
    </body>

    Y editamos la plantilla index.html para que extienda base.html:

    {% extends "base.html" %}
    {% block content %}
    <h1>Hola Django</h1>
    {% endblock %}

    Ok, teniendo una idea general del sistema de plantillas, seguimos con la pagina inicial del blog empezando por editar el archivo views.py.

    from django.shorcuts import render_to_response
    from blog.models import Post

    def index(request):
    # recuperamos 5 primeras entradas
    posts = Post.objects.filter()[:5]
    return render_to_response("index.html", locals())

    Cada vez que visitemos a la raíz del blog se consultaran los primeros 5 post y se pasaran a la plantilla index.

    {# plantilla index.html #}
    {% extends "base.html" %}

    {% block content %}
    {% for post in posts %}
    <h1><a href="/{{ post.id }}">{{ post.title }}</a></h1>
    <p>{{ post.pub_date}}</p>
    {{ post.body }}
    {# esto no es muy eficiente* #}
    {% for tag in post.tags.filter %}
    <a href="/tags/{{ tag.tag }}">{{ tag.tag }}</a>
    {% endfor %}
    {% endfor %}
    {% endblock %}

    * Extraer las etiquetas de esta forma no es eficiente ya que al llamar a filter (5 veces) se hace una nueva consulta a la base de datos, algunas soluciones se pueden encontrar aquí.

    Con esto la pagina principal esta lista. Sigamos con la pagina individual, veremos que al trabajar con django se sigue mas o menos el mismo patrón:

    # archivo urls.py
    urlpatterns = patterns('',
    (r'^$', 'blog.views.index'),
    # expresión regular que captura el numero después de post/
    (r'^post/(?P<id>d+)$', 'blog.views.single'),
    )
    # Archivo views.py
    ...
    # la funcion recibe el numero capturado
    def single(request, id=0):
    # recuperar post según id
    post = Post.objects.get(id=int(id))

    return render_to_response("single.html", locals())
    {# plantilla single.html #}
    {% block content %}
    <h1><a href="/{{ post.id }}">{{ post.title }}</a></h1>
    <p>{{ post.pub_date}}</p>
    {{ post.body }}
    {# esto no es muy eficiente* #}
    {% for tag in post.tags.filter %}
    <a href="/tags/{{ tag.tag }}">{{ tag.tag }}</a>
    {% endfor %}
    {% endblock %}

    Notan algo raro? el código de single.html e index.html luce muy similar; podemos eliminar el código repetido moviéndolo a otra plantilla (article.html) que luego incluimos en estas.

    {# plantilla article.html #}
    </div>
    <h1><a href="/{{ post.id }}">{{ post.title }}</a></h1>
    <p>{{ post.pub_date}}</p>
    {{ post.body }}
    {# esto no es muy eficiente* #}
    {% for tag in post.tags.filter %}
    <a href="/tags/{{ tag.tag }}">{{ tag.tag }}</a>
    {% endfor %}
    </div>

    Ahora editamos las plantillas index.html y single.html para que utilicen article.html.

    {# plantilla inde.html #}
    {% extends 'base.html' %}

    {% block main_content %}
    {% for post in posts %}
    {# pasamos la variable post como argumento #}
    {% include 'include/article.html' with post=post %}
    {% endfor %}

    {% endblock %}
    {# plantilla single.html #}
    {% extends 'base.html' %}

    {% block main_content %}
    {% include 'include/article.html' %}
    {% endblock %}

    Con esto damos por terminado esta parte. No se olviden de comentar.

    P.D.: Procurare tener la próxima parte mas rápido.