Podés encontrar una versión más extensa de esta introducción en esta Guía de Estudio.
Las computadoras son una parte esencial de nuestra vida cotidiana. Casi todos los aparatos que usamos tienen algún tipo de computadora capaz de ejecutar ciertas tareas: lavarropas con distintos modos de lavado, consolas de juegos para momentos de entretenimiento, calculadoras súper potentes, computadoras personales que se usan para un montón de propósitos, teléfonos celulares con un sinfín de aplicaciones y miles de cosas más.
Todos estos dispositivos con computadoras de distinto tipo tienen algo en común: alguien “les dice” cómo funcionar, es decir, les indica cuáles son los pasos que deben seguir para cumplir una tarea. De eso se trata la programación: es la actividad mediante la cual las personas le entregan a una computadora un conjunto de instrucciones para que, al ejecutarlas, ésta pueda resolver un problema. Quienes realizan esta actividad reciben el nombre de programadores. Sin las personas que las programen, las computadoras dejan de ser útiles, por más complejos que sean estos aparatos. Los conjuntos de instrucciones que reciben las computadoras reciben el nombre de programas.
La programación es un proceso creativo: en muchas ocasiones la tarea en cuestión puede cumplirse siguiendo distintos caminos y el programador es el que debe imaginar cuáles son y elegir uno. Algunos de estos caminos pueden ser mejores que otros, pero en cualquier caso la computadora se limitará a seguir las instrucciones ideadas por el programador.
Desafortunadamente, las computadoras no entienden español ni otro idioma humano. Hay que pasarles las instrucciones en un lenguaje que sean capaces de entender. Para eso debemos aprender algún lenguaje de programación, que no es más que un lenguaje artificial compuesto por una serie de expresiones que la computadora puede interpretar. Las computadoras interpretan nuestras instrucciones de forma muy literal, por lo tanto a la hora de programar hay que ser muy específicos. Es necesario respetar las reglas del lenguaje de programación y ser claros en las indicaciones provistas.
Ahora bien, ¿por qué debemos estudiar programación en si nos dedicamos a la Estadística? La actividad de los profesionales estadísticos está atravesada en su totalidad por la necesidad de manejar con soltura herramientas informáticas que nos asisten en las distintas etapas de nuestra labor, desde la recolección y depuración de conjuntos de datos, pasando por la aplicación de distintas metodologías de análisis, hasta la comunicación efectiva de los resultados. Por eso, en este tutorial estudiaremos los conceptos básicos de esta disciplina, fomentando la ejercitación del pensamiento abstracto y lógico necesario para poder entendernos hábilmente con la computadora y lograr que la misma realice las tareas que necesitamos. El lengua de programación en el que se basa este tutorial es R, ampliamente empleado en el ámbito de la ciencia de datos. Sin embargo, debemos resaltar que éste no es un tutorial sobre R, es decir, no nos dedicaremos a aprender las herramientas que este lenguaje brinda para el análisis de datos.
Para incorporar algunas nociones básicas de programación vamos a valernos de la ayuda de Karel, una robot que vive y camina por mundos rectangulares. Vamos a pedirle a Karel que realice ciertas actividades y para esto tenemos que programar en R, de modo que Karel nos acompañará en los primeros pasos que demos con este lenguaje.
Karel the Robot es un lenguaje de programación creado con fines educativos por el Dr. R. E. Pattis de la Universidad de Stanford (California, EEUU), quien también escribió el libro Karel the Robot: A Gentle Introduction to the Art of Programming en 1981. Su nombre es un homenaje a Karel Capek, el escritor sueco que inventó la palabra robot en su obra de ciencia ficción R.U.R. (Rossum’s Universal Robots). Su sintaxis se basaba en Pascal, un lenguaje de programación muy importante en aquellos tiempos. A lo largo de las décadas, esta estrategia de enseñanza fue utilizada en muchos lugares alrededor del mundo, implementando Karel en distintos lenguajes como Java, C++, Ruby y Python. Muchos de los ejemplos presentados en esta guía fueron tomados de Karel the robot learns Java (Eric Roberts, 2005). Hasta donde sabemos, Karel no había sido desarrollado en R. Nuestro paquete es la primera implementación, ¡ayudanos a mejorarlo avisándonos cualquier cosa que notes que necesite revisión!
Pero antes de meternos de lleno a jugar con Karel, vamos a repasar algunos conceptos relativos a la Programación que viene bien tener presentea.
Mencionamos anteriormente que la programación consistía en instruir a una computadora para que resuelva un problema y que la comunicación de esas instrucciones debe ser realizada de forma clara. Es por eso que, ante un problema que debe ser resuelto computacionalmente, el primer paso es pensar detalladamente cuál puede ser una forma de resolverlo, es decir, crear un algoritmo. Un algoritmo es una estrategia consistente de un conjunto ordenado de pasos que nos lleva a la solución de un problema o alcance de un objetivo. Luego, hay que traducir el algoritmo elegido al idioma de la computadora.
Entonces, podemos decir que la resolución computacional de un problema consiste de dos etapas básicas:
Al aprender sobre programación, comenzamos enfrentándonos a problemas simples para los cuales la primera etapa parece sencilla, mientras que la codificación se torna dificultosa ya que hay que aprender las reglas del lenguaje de programación. Sin embargo, mientras que con práctica rápidamente podemos ganar facilidad para la escritura de código, el diseño algorítmico se torna cada vez más desafiante al encarar problemas más complejos. Es por eso que haremos hincapié en el planteo y desarrollo de algoritmos como una etapa fundamental en la programación.
Frente a cada problema, el primer paso es idear un algoritmo para su solución y expresarlo por escrito, por ejemplo, en español, pero adaptando el lenguaje humano a formas lógicas que se acerquen a las tareas que puede realizar una computadora. En programación, el lenguaje artificial e informal que usan los desarrolladores en la confección de algoritmos recibe el nombre de pseudocódigo. Es la herramienta que utilizamos para describir los algoritmos mezclando el lenguaje común con instrucciones de programación. No es en sí mismo un lenguaje de programación, es decir, la computadora no es capaz de entenderlo, sino que el objetivo del mismo es que el programador se centre en la solución lógica y luego lo utilice como guía al escribir el programa. En este tutorial no vamos a estar presentando ejemplos de escritura con pseudocódigo. Sin embargo, tenemos que tener en claro que antes de intentar programar, es importante pensar con anticipación el algoritmo, es decir, todos los pasos para llegar a la solución y anotarlos en papel y birome mientras ideamos una estrategia puede ser una gran ayuda.
Un algoritmo presentado en pseudocódigo podría utilizar términos tomados del lenguaje español, una opción razonable para compartir esta estrategia entre personas que se comuniquen con este idioma. Claramente, si queremos presentarle nuestro algoritmo a alguien que sólo habla francés, el español ya no sería una buena elección y mucho menos si queremos presentarle el algoritmo a una computadora. Para que una computadora pueda entender nuestro algoritmo, debemos traducirlo en un lenguaje de programación, que, como dijimos antes, es un idioma artificial diseñado para expresar cómputos que puedan ser llevados a cabo por equipos electrónicos, es decir es un medio de comunicación entre el humano y la máquina.
Cada una de las acciones que componen al algoritmo son codificadas con una o varias instrucciones, expresadas en el lenguaje de programación elegido, y el conjunto de todas ellas constituye un programa. El programa se guarda en un archivo con un nombre generalmente dividido en dos partes por un punto, por ejemplo: mi_primer_programa.R
. La primera parte es la raíz del nombre con la cual podemos describir el contenido del archivo. La segunda parte es indicativa del uso del archivo, por ejemplo, .R
indica que contiene un programa escrito en el lenguaje R. El proceso general de ingresar o modificar el contenido de un archivo se denomina edición.
Apenas iniciemos nuestro camino en el mundo de la programación nos daremos cuenta que tendremos siempre ciertos compañeros de viaje: los errores. Muchas veces nos pasará que queremos ejecutar nuestro código y el mismo no anda o no produce el resultado esperado. No importa cuán cuidadosos seamos, ni cuánta experiencia tengamos, los errores están siempre presentes. Con el tiempo y práctica, vamos a poder identificarlos y corregirlos con mayor facilidad, pero probablemente nunca dejemos de cometerlos. Esto no es para amargarse, puesto que a través de la solución de los errores cometidos muchas veces se producen grandes aprendizajes.
A los errores en programación se los suele llamar bugs (insecto o bicho en inglés) y el proceso de la corrección de los mismos se conoce como debugging (depuración)1. Se dice que esta terminología proviene de 1947, cuando una computadora en la Universidad de Harvard (la Mark II) dejó de funcionar y finalmente se descubrió que la causa del problema era la presencia de una polilla en un relé electromagnético de la máquina. Sin embargo, otros historiadores sostienen que el término ya se usaba desde antes.
Hemos definido a un algoritmo como una lista de instrucciones para resolver un problema. En este contexto, se entiende por procesador a todo agente capaz de comprender los pasos de un algoritmo y ejecutar el trabajo indicado por el mismo. Para cumplir con el objetivo, el procesador emplea ciertos recursos que tiene a disposición. Todos los elementos disponibles para ser utilizados por el procesador constituyen su entorno o ambiente. Cada una de las instrucciones que componen el algoritmo modifican el entorno de alguna manera y se denominan acciones.
Como dijimos anteriormente, pondremos en práctica los conceptos sobre programación utilizando R. A diferencia de muchos otros, este es un software libre y gratuito: se distribuye bajo la licencia GNU GPLv2 que establece la libertad de usarlo con cualquier propósito, de ver cómo fue hecho, cómo funciona y modificarlo, de distribuir copias y crear contribuciones y agregados para que estén disponibles para otros 2.
Si bien R será nuestro medio de comunicación con la computadora, vamos a usar otro programa que brinda algunas herramientas para facilitar nuestro trabajo de programación, es decir, vamos a usar un entorno de desarrollo integrado (o IDE, por integrated development environment). Un IDE es un programa que hace que la codificación sea más sencilla porque permite manejar varios archivos de código, visualizar el ambiente de trabajo, utilizar resaltado con colores para distintas partes del código, emplear autocompletado para escribir más rápido, explorar páginas de ayuda, implementar estrategias de depuración e incluso intercalar la ejecución de instrucciones con la visualización de los resultados mientras avanzamos en el análisis o solución del problema. El IDE más popularmente empleado para programar con R es RStudio y será el programa que estaremos usando todo el tiempo.
Para instalar estos programas, se debe visitar las páginas oficiales de R y de RStudio, descargar los instaladores y ejecutarlos. En este enlace se presenta un video con la instalación completa.
Cuando se abre RStudio se pueden visualizar cuatro paneles:
A la izquierda:
File > New File > R Script
, con el atajo Ctrl + Shift + N
o haciendo clic en el primer ícono de la barra de herramientas. Podemos abrir varios archivos a la vez.Arriba a la derecha hay un panel con algunas pestañas:
Abajo a la derecha hay otro panel con más pestañas:
Podemos usar la consola de R que encontramos en el panel de la izquierda para introducir allí nuestras instrucciones y al hacer Enter
serán evaluadas, produciendo algún resultado. Por ejemplo, podemos hacer algunos cálculos matemáticos como dividir, multiplicar, sumar, restar, calcular potencias, logaritmos, raíces y mucho más:
1 + 2
#> [1] 3
5 * 3
#> [1] 15
exp(2)
#> [1] 7.389056
sqrt(100)
#> [1] 10
1 / 0
#> [1] Inf
2 + 3i) * (3 + 6i)
(#> [1] -12+21i
^ 2
1i #> [1] -1+0i
Si bien podemos escribir nuestras instrucciones en la consola y dar Enter
para que se ejecuten, en general queremos que queden escritas y guardadas en el archivo de código, por eso vamos a escribir nuestros programas en el panel de arriba a la izquierda. Una vez que escribimos una instrucción en el script, podemos correrla (es decir, enviarla a la consola para que se ejecute) haciendo clic en el ícono Run o con el atajo Ctrl + Enter. De esta forma, se corre la línea en la cual está el cursor o las líneas que hayamos seleccionado.
En todo lenguaje de programación existe un caracter especial que, al ser colocado al comienzo de una línea de código, le indica al software que dicha línea no debe ser evaluada. Esto se utiliza para incluir comentarios, es decir, líneas que expresan en español explicaciones o aclaraciones para nosotros mismos u otros que puedan utilizar nuestro código. También se utiliza para añadir encabezados con descripciones sobre el script, o indicar distintas secciones o partes en el programa. En R, este caracter especial es el símbolo numera (#
). Si corremos líneas que empiezan con #
, R no hará nada con ellas, las salteará. Por ejemplo
5^1
#> [1] 5
# 5^2
5^3
#> [1] 125
R se divide en dos partes:
La base (R Base), que se instala cuando descargamos el programa desde CRAN (“Comprehensive R Archive Network”). Contiene, entre otras cosas, una serie de herramientas básicas y fundamentales de R.
Paquetes adicionales. Un paquete es un conjunto de archivos que se descarga de forma opcional desde CRAN u otros repositorios y que sirven para hacer alguna tarea especial. Por ejemplo, para poder jugar con Karel deberemos instalar el paquete que contiene su implementación, llamado karel
.
Como dijimos antes, en la pestaña Packages del panel de abajo a la derecha tiene el listado de todos los paquetes que ya están instalados (muchos vienen con R Base). Allí también hay un botón para instalar nuevos desde CRAN, aunque otra opción es correr la instrucción install.packages("nombredelpaquete")
:
# Instalar desde CRAN el paquete karel
install.packages("karel")
También es posible instalar paquetes publicados en otros repositorios. Por ejemplo, es muy común descargar paquetes en desarrollo o en experimentación que estén disponibles en la plataforma Github. Estos paquetes se instalan especificando el nombre de la cuenta de Github de quien lo haya publicado y el nombre del paquete. Si queremos instalar la versión en desarrollo del paquete karel
(no es necesario) deberíamos hacer:
# Instalar desde CRAN el paquete devtools
install.packages("devtools")
# Instalar desde GitHub el paquete karel
::install_github("mpru/karel") devtools
Un paquete se instala una sola vez, pero cada vez que lo queramos usar debemos cargarlo para que las herramientas que trae queden a nuestra disposición. Eso se hace con la instrucción library("nombredelpaquete")
, por ejemplo, library("karel")
.