Escribiendo tu primer programa
Cuando hablamos de programación hablamos de un concepto derivado de la informática, ambos por supuesto, muy abstractos aún hoy en día para la mayoría de la gente. De acuerdo a Wikipedia, la programación se define como el proceso de diseñar, codificar, depurar y mantener un código fuente de programas de computadora, es decir?? una cosa rara del mundo de los informaticos.
Cabe destacar que la programación es un concepto que ha evolucionado a lo largo de los años, y este rango no acarrea decenas, sino cientos de años e incluso miles cuando nació el concepto de algoritmo, el cual se definió como una secuencia de pasos lógicos que solucionan un determinado problema.
Para dejarnos de abstracción te pedire que instales nodejs en tu computadora, el cual servirá para poder ejecutar algorimos que desarrollaremos en javascript, un lenguaje de programación creado a mediados de los 90' y que hoy en día es considerado el lenguaje de programación más revolucionario de la historia, porqué? por muchos motivos.
Descargaló e instalalo como cualquier programa que hayas instalado antes, doble click, siguiente, siguiente y siguiente, hasta ahora nada del otro mundo.
Lo hiciste? asumo que no fue dificil, ahora continuemos con un ejemplo básico.
Para ponernos en contexto, diremos que eres un oficinista que tiene que interactuar con 3 archivos diarios, siempre debes hacer lo mismo, abrir el archivo (1) que lista los documentos pendientes, abrir el archivo (2) que lista los documentos procesados y crear un nuevo archivo (3) donde se listan los documentos pendientes actualizados, es decir, el archivo 1 sin el archivo 2, se entiente??.
Cuando hablamos de 10 a 100 documentos puede ser algo no tan tedioso, pero cuando hablamos de varios cientos e incluso miles, no será tan entretenido actualizar el archivo final no? (espero que no exista este tipo de trabajo, recuerda que es solo un ejemplo para entender la programación).
Analicemos la situación como oficinista. Debo abrir el archivo 1, leer linea por línea y revisar si existe el documento en el archivo 2, si no existe es porque no ha sido procesado y por ende debo registrarlo en el archivo de salida para que otros continúen otro día.
Analicemos la situación como informático, estamos recibiendo 2 archivos de entrada y debemos entregar un archivo de salida, debemos leer ambos archivos de entrada, recorrer el primero y por cada línea revisar si el registro existe en el archivo 2, si no existe entonces acumular en una lista el registro en proceso y por ultimo guardar toda esta lista en un archivo final, osea, lo mismo no?. Comencemos!
Abre un editor de texto como un block de notas o si quieres algo más pro, instala notepad++ o sublimetext. Te espero.
Antes de iniciar crearemos algo sencillo, es probable que ya sepas como abrir una consola de comandos y navegar por las carpetas a travez de ella pero si no sabes, o aún así, prefieres seguir estos pasos, con el editor de texto abierto crea un nuevo archivo, escribe cmd y guardalo como "consola.bat" en alguna carpeta. Esto creara un archivo ejecutable que al hacerle doble click abrira la típica pantalla negra, ¿comienzas asustarte?.
Una vez creado y ejecutado el archivo .bat crearemos un nuevo archivo de texto al que llamaremos "mipegaensegundos.js", asegurate de guardarlo en la misma carpeta del archivo .bat. Como resumen solo diré que el punto especifíca el fin del nombre de un archivo y lo que viene despúes hace referencia a la extensión de éste, el "bat" hace referencia a los archivos por lotes de windows y el "js" significa Javascript, el lenguaje en el que programaremos :D.
Para probar necesitaremos los archivos a procesar, por ende descarga y guarda los siguientes archivos de prueba en la misma carpeta donde esta el archivo .bat y el archivo .js:
Ya con los archivos descargados comenzaremos a escribir el código fuente necesario para realizar este trabajo. Para asegurarnos de que vamos por buen camino te pedire que escribas en el archivo js lo siguiente:
console.log("hola mundo! esto es programación en Javascript :D");
Guarda el archivo y ejecutalo. ¿como se hace? ejecuta nuevamente el archivo .bat y escribe en la consola de comandos el siguiente comando:
node mipegaensegundos
Si todo ha salido bien veras en la pantalla negra el mensaje hola mundo! esto es programación en Javascript :D. Por ende, console.log podríamos definirlo como la forma de imprimir un mensaje en la pantalla. En estricto rigor "console" es un objeto javascript que contiene multiples funciones en su interior, como por ejemplo "log" el cual recibe un parámetro y lo imprime por pantalla. Objeto, funcion, parámetro ¿se va entendiendo?
Ahora es probable que te preguntes que es "node", pues node es el programa que instalamos al inicio "nodejs". Al momento de instalar, éste habilita en tu computadora el objeto llamado "node" el cual es necesario para ejecutar multiples comandos, en este caso básico, solo queremos ejecutar un archivo de javascript, por ende al hacer "node mipegaensegundos" le estamos diciendo a nodejs que ejecute el archivo mipegaensegundos.js.
Bien, entendiendo esta primera parte comenzaremos a escribir el código real del problema especificado anteriormente:
Como primer paso dijimos que debíamos leer 2 archivos de entrada cierto?, para hacer esto en nodejs/javascript hay que importar una librería que procesa los archivos del sistema, de lo contrario, deberíamos buscar una forma más nativa y complicada para acceder a los archivos. Gracias a los programadores, estos códigos ya estan estandarizados y compartidos para llegar y utilizar. Para esto escribe la siguiente línea debajo del console.log:
var sistema_de_archivos = require("fs");
Con esta línea estamos declarando una variable (algo que existirá a lo largo de la ejecución del código fuente) llamada sistema_de_archivos (puede tener cualquier nombre alfanumérico pero siempre iniciando con una letra) el cual almacenará el objeto "fs" (librería nativa de nodejs para procesar archivos). El "require" se podría definir como otra función nativa de nodejs para importar recursos externos al código fuente. El ";" indíca el final de la línea a procesar. ¿lógico y simple no?.
Ahora que tenemos a "fs" en nuestro código fuente realizaremos la lectura del archivo 1, para esto escribiremos debajo de la línea ingresada el siguiente código:
var archivo_1 = sistema_de_archivos.readFileSync("./archivo_1.txt","utf-8");
Con esta nueva línea estamos declarando otra variable, esta vez llamada archivo_1 la cual tendrá el contenido del archivo. "readFileSync" es una función de "fs" que recibe 2 parámetros: la ruta del archivo a leer y la codificación con la que se leerá, en nuestro caso utf-8 siempre! (esto es algo muy complejo de entender pero siempre será utf-8).
Agregando un "console.log(archivo_1);" estarás viendo el contenido del archivo en la pantalla negra, prueba y continúa.
Bueno, ya estamos leyendo el archivo 1, haremos lo mismo con el archivo 2 con el siguiente código:
var archivo_2 = sistema_de_archivos.readFileSync("./archivo_2.txt","utf-8");
Necesitas una explicación para esta línea? solo se creó una nueva variable y obviamente con el archivo a leer. Lo que debemos hacer ahora, es recorrer el archivo 1, pero cómo podemos recorrerlo línea por línea? existen muchas formas, pero para hacerlo simple diremos que el "texto" del archivo 1 debemos dividirlo por cada salto de línea, de esta forma en vez de tener un "texto" tendremos una "lista". Para esto escribiremos lo siguiente:
var lista_archivo_1 = archivo_1.split("\n");
Con esta nueva línea estamos creando la variable lista_archivo_1 que sera igual al texto del archivo 1, pero! dividido (split) por línea ("\n")...el texto podría dividirse por espacios en blanco, por alguna palabra específica, por algun carácter específico o por lo que sea, pero en nuestro caso sabemos que cada línea representa un documento único y por ende el "\n" es lo que hace referencia al salto de línea (en la mayoría de los lenguajes de programación). ¿se complica un poco no?
Agrega un "console.log(lista_archivo_1.length);" y ejecuta el programa, deberías ver el total de documentos o líneas que quedaron registradas en el archivo 1 (length es una función de toda variable que entrega el total de caracteres de un texto o el total de registros de una lista).
Ahora haremos lo mismo con el archivo 2:
var lista_archivo_2 = archivo_2.split("\n");
Como siguiente paso, declararemos una variable de tipo lista inicialmente vacía la cual servirá para ir llenando de información a medida que se recorren los registros. Para esto agrega la siguiente línea:
var lista_actualizada = [];
De esta forma, "lista_actualizada" será una lista "[]" inicialmente vacía. Ahora con nuestras 3 variables declaradas comenzaremos a recorrer la lista 1.
for(var indice=0 ; indice < lista_archivo_1.length ; indice++){ }
Que es esto!!!??? pues como hemos visto hasta ahora, el código se ejecuta línea por línea cierto? primero importamos la librería fs, luego leímos el archivo 1, luego el archivo 2, luego dividimos el archivo 1, luego dividimos el archivo 2 no?. Con esta nueva línea estamos creando un ciclo iterativo, decir, un proceso que se repetira una cantidad determinada de veces.
El código "for" recibe 3 parámetros de entrada los cuales de describen a continuación:
- var indice=0 declara una variable llamada índice la cual iniciará en 0 (puede ser mayor pero en la mayoría de los casos cuando necesitemos recorrer algo, será desde el inicio, por ende 0).
- indice < lista_archivo_1.length declara la condición por la que se regirá el ciclo iterativo, en este caso mientras el índice sea menor al largo de la lista del archivo 1.
- indice++ significa que por cada iteración el índice se incrementará en 1. Podría ser índice + 2 o índice + 5, en fín. Como queremos avanzar de 1 en 1 será índice++ o índice +1.
Cabe destacar que despues de definir el objeto for, se abren y cierran unas llaves "{}", esto abre y cierra el bloque donde todo lo que se escriba dentro de su interior será ejecutado en cada ciclo de iteración del for, se entiende?...¿no? pues ingresa en su interior un "console.log(indice);" y ejecuta el programa para entender.
Ya declarado el ciclo iterativo debemos comenzar a desarrollar el código necesario que será ejecutado en su interior. Ya tenemos ambas listas en "memoria" y estamos recorriendo la lista del archivo 1 ¿que debemos hacer ahora? primero sería obtener el contenido de la línea en proceso, revisar si existe el contenido en la lista 2, acumular en la lista actualizada en caso de no existir y nada más.
Dentro del ciclo for escribiremos lo siguiente:
var contenido_en_proceso = lista_archivo_1[indice];
Con esta línea estamos guardando en "contenido_en_proceso" el valor de la línea en proceso. Haz un console.log(contenido_en_proceso); y verás como las líneas se van imprimiendo una a una ¿lo viste? ¿rápido no?
Ahora con este dato en memoria necesitaremos consultar si existe o no, el registro en la lista 2 y para esto haremos lo siguiente:
if(lista_archivo_2.indexOf(contenido_en_proceso)==-1){ }
Con esta estructura estamos declarando un bloque selectivo que sólo sera ejecutado si lo que está como parámetro resulta ser verdadero. Para esto estamos preguntando cual es el valor del índice (indexOf) del contenido_en_proceso dentro de la lista_archivo_2. Si es igual a -1 significa que no lo encontró. Si es mayor significa que sí lo encontró. Como en este caso necesitamos hacer algo en caso de no encontrarlo podemos entender que si no lo encuentra entonces ejecutará todo lo que está dentro de las llaves "{}" lo cual será lo siguiente:
lista_actualizada.push(contenido_en_proceso);
Aquí podemos ver uno de los pasos más importantes: acumular en la lista actualizada los datos que no fueron encontrados. Con "push" estamos insertando a la lista_actualizada un valor x, en este caso, lo que contiene contenido_en_proceso. Lo crees? agrega al final del archivo un "console.log(lista_actualizada.length);" y al ejecutarlo deberías ver el total de la lista actualizada.
Por último solo quedaría pendiente escribir un nuevo archivo con los datos actualizados, y esto se hará con la siguiente línea al final de todo el código fuente:
sistema_de_archivos.writeFileSync("./archivo_salida.txt", lista_actualizada.join("\n"));
Con esta última línea le estamos diciendo a "fs" (sistema de archivos) que escriba un nuevo archivo (writeFileSync) en la ruta "./archivo_salida.txt" y que escriba en su interior lo que hay en la lista_actualizada pero! que lo una (join) con una línea de separación (\n).
Ejecuta el programa, maravillate por la velocidad del procesamiento y cuestiona todo el mundo digital ;) todo funciona de esta forma, importación de códigos externos, declación de variables, procesamientos de datos, ciclos selectivos, ciclos iterativos y mucho más.
Espero que hayas podido seguir paso a paso esta nota y hayas ejecutado el programa sin problemas. La programación si bien es la base de la informática, la informática no se limita a los informáticos. Todos hemos necesitado alguna vez automatizar un proceso digital que nos toma mucho tiempo o simplemente queremos evitarlo, la programación se creo para esto por ende si ya te picó el bicho de aprender, no te contengas, no te limítes y no tengas miedo.
Comparte el conocimiento, comparte las ganas de aprender y cualquier cosa nos vemos en otra nota ;)
El código final sería este:
console.log("hola mundo! esto es programación en Javascript :D");
var sistema_de_archivos = require("fs");
var archivo_1 = sistema_de_archivos.readFileSync("./archivo_1.txt","utf-8");
var archivo_2 = sistema_de_archivos.readFileSync("./archivo_2.txt","utf-8");
var lista_archivo_1 = archivo_1.split("\n");
var lista_archivo_2 = archivo_2.split("\n");
var lista_actualizada = [];
for(var indice=0 ; indice < lista_archivo_1.length ; indice++){
var contenido_en_proceso = lista_archivo_1[indice];
console.log(contenido_en_proceso);
if(lista_archivo_2.indexOf(contenido_en_proceso)==-1){
lista_actualizada.push(contenido_en_proceso);
}
}
sistema_de_archivos.writeFileSync("./archivo_salida.txt", lista_actualizada.join("\n"));
Descarga todo el proyecto aquí
Escrito por Jcalderon