2 de diciembre de 2017

JavaScript - Juego TragaperraJS (práctica final módulo básico)

Después de haber visto todas las entradas anteriores sobre JS (desde fundamentos hasta eventos), se debe estar preparado para realizar una práctica sobre una máquina tragaperras.


Ésta fué la práctica final de los alumnos que recibieron un curso básico de JS que impartí hace poco.

He subido a GitHub el enunciado y código necesario para hacer la práctica, la solución final desde ese enunciado y el proyecto con una solución que no está orientada a realizar un examen si no a ir ampliando el juego posteriormente con una tabla de mejores puntuaciones o distintos temas por ejemplo.

Reglas:

  • Se puede apostar como máximo el saldo. Se comienza con 50 unidades. Se puede cambiar la cantidad para apostar cambiando el valor del cajetín.
  • Si se llega a 100 o más unidades se gana el juego. Si se llega a cero se pierde.
  • Cada apuesta permite un giro de toda la linea que se iniciará al apretar el botón de giro. La linea empezará a detenerse al soltar el botón de giro.
  • Una vez que se ha girado toda la linea se permite el giro de una casilla apretando la casilla que se quiere girar (se coloreará su fondo de amarillo) y se apostará la cantidad que se marque en ese momento. A la finalización de ese giro se deberá volver a apostar por un giro de linea completo para continuar.
  • Hay seis resultados distintos por casillas cuyos premios son:
    • Limón y Naranja: 0
    • Plátanos: 0.5
    • Sandía y Cerezas: 1
    • Estrella: 2
  • Para calcular el premio de la línea se usa lo siguiente:
    • Se empieza con premio 0 y se resuelven los premios de las casillas en el orden que se va deteniendo el giro (izquierda a drecha)
    • Si el premio que se está calculando tiene actualmente un valor de cero, cuando se alcance una casilla con premio mayor que cero el premio actual para a ser ese valor
    • Si el premio que se está calculando tiene actualmente un valor mayor de cero, se multiplica el premio actual por el valor del premio de la casilla
    • Si las tres casillas son iguales se multiplica el premio de la linea completa calculado previament por el número de casillas de la línea (en nuestro caso *3)
  • Las ganancias son el producto de la apuesta por el premio de la linea

Se mantiene un histórico de saldos en la parte de abajo para ver la evolución. Como máximo se muestran los 15 últimos.

Jugar:


Puedes encontrarlo todo en el proyecto tragaperrajs de mi cuenta de GitHub y jugarlo directamente en itch.io.



O probarlo directamente aquí abriéndolo a pantalla completa (pincha en el iconito de abajo a la derecha):

21 de noviembre de 2017

Guardar CD de Audio en mp3 - Rip Audio CD to mp3 files

El otro día tenía que descargar un CD de música para reproducirlo desde el mp3. No tenía a mano ninguna herramienta de las antiguas que tenía para ripear... ya ni tengo DVD en los ordenadores XD

Así que gracias a Dios pude enchufar una unidad antigua que todavía leía CDs y para no tener que instalar nada nuevo mi idea era ripear cada canción directamente con VLC hasta terminar con el CD. Por supuesto la idea era hacerlo por consola para no tener que estar pinchando cada canción en cada CD (en realidad eran 3 CDs ;P)

Busque por Internet y encontré curiosamente la respuesta en StackOverflow (votada para cerrar por no ser un tema a tratar allí)

Así que comparto por aquí el código para el .bat que os hará ese trabajo:

@ECHO OFF

    setlocal ENABLEDELAYEDEXPANSION

    SET /a x=0

    FOR /R D:\ %%G IN (*.cda) DO (CALL :SUB_VLC "%%G")
    GOTO :eof

    :SUB_VLC
    call SET /a x=x+1

    ECHO Transcoding %1
    REM Here's where the actual transcoding/conversion happens. The next line
    REM fires off a command to VLC.exe with the relevant arguments:
    CALL "C:\Program Files\VideoLAN\VLC\vlc" -I http cdda:///D:/ --cdda-track=!x! :sout=#transcode{vcodec=none,acodec=mp3,ab=128,channels=2,samplerate=44100}:std{access="file",mux=raw,dst="Track!x!.mp3"} vlc://quit

    :eof

Espero que os sirve igual que a mí. Simplemente revisar las rutas a vuestro ejecutable de VLC ("C:\Program Files\VideoLAN\VLC\vlc" en el ejemplo) y a vuestra unidad de Audio ("D:" en el ejemplo)

También podéis cambiar el formato o calidad del fichero de salida modificando los parámetros (por ejemplo cambiado el bitrate de ab=128 a ab=192, cambiando el códec de mp3 a flac o a ogg, etc...).

6 de noviembre de 2017

JavaScript - Eventos

JS es el lenguaje que usamos un nuestro trio famoso (HTML, CSS y JS) que define el comportamiento de una página web. Este comportamiento, como es lógico, debe manifestarse con las acciones del usuario. Por ese motivo existen los Eventos como parte del DOM.

Aunque ya hice una entrada acerca de DOM, he querido separar los eventos DOM por su singularidad a la hora de manejarlos. DOM tiene una serie de eventos que van desde acciones típicas del usuario como hacer click a los propios de la carga de la página o sus elementos sin que el usuario haya pedido conscientemente nada.

Cada Event (evento) tiene un EventHandler (manejador) que creará un objeto evento del tipo correspondiente en un elemento objetivo y notificará convenientemente a los EventListener (escuchadores)/función marcada. Este proceso es lo que se conoce como propagación de eventos DOM.

Veámos un ejemplo práctico (ver fiddle):
<script>
  function ejemplo() { alert("Gracias, vuelve a hacerlo"); }
</script>

<div onclick="ejemplo()">Haz click por favor</div>

¿Qué está pasando para que ocurra esto?

En este caso el Handler del evento onclick del div, genera un Event (en este caso un Mouse Event) y llama a la funcion ejemplo(). Hasta ahora no parece nada demasiado nuevo en la prática: es asignar un valor a un atributo de un elemento como ya hemos hecho antes. Pero incluso ya tenemos una conclusión: de todo el arbol DOM sólo los elementos HTML pueden manejar eventos pues son los que tienen atributos.

¿Pero para qué sirve que se genere un objeto de tipo Event?

El objeto Event generado va a contener información acerca del evento que ha ocurrido y del que podemos sacar información para reaccionar adecuadamente.

Cambiemos un poco el ejemplo anterior (ver fiddle):
<script>
  //Mensaje con las coordenadas del cursor dentro de la página 
  function ejemplo2 (evento) {
    alert('Hiciste click en coordenadas: ' 
      + evento.clientX + ', ' + evento.clientY
      + ' con botón ' + evento.button);
  }

  //Nos informa de las coordenadas del cursor DENTRO de "elemento" 
  function ejemplo3 (evento, elemento) {
    escribirEtiqueta ('Ahora estás en coordenadas: '
      + (evento.clientX - elemento.offsetLeft) + ', ' 
      + (evento.clientY - elemento.offsetTop));
  }

  //Funciones auxiliares para mensajes en pantalla 
  function resetearEtiqueta () { escribirEtiqueta('Pincha en lo verde'); }
  function escribirEtiqueta (texto) { document.querySelector('#texto').innerHTML = texto; }
</script> 

<div
style='background-color:green; color:white; width:50%; height:50%; margin:auto; text-align:center; display: flex; justify-content: center; align-items: center;'
  onmousedown='ejemplo2(event)'
  onmousemove='ejemplo3(event, this)'
  onmouseleave='resetearEtiqueta()'>

  <span id='texto'><script>resetearEtiqueta()</script></span>

</div>
Hemos creado un cuadrado interactivo donde hemos especificado tres eventos que vamos a manejar:
  1. onmousedown: que nos presentará un mensaje con las coordenadas de dónde hemos hecho click.
  2. onmousemove: que nos dice las coordenadas de nuestor cursor dentro del cuadrado verde.
  3. onmouseleave: resetea el texto del cuadrado incitándonos a pinchar.
Esto es posible porque ahora el argumento predeterminado event se le pasa a la función que vamos a ejecutar. Para nuestro caso, este objeto tiene los miembros del tipo Mouse Event que entre otros tiene las propiedades clientX, clientY y button como vemos en la función ejemplo2.
En la función ejemplo3 también podemos ver que le pasamos una referencia al elemento que ha producido el evento (lo hacemos con this), y al ser un HTML Element podemos saber la posición que ocupa (offsetLeft y offsetTop) en la página para calcular las coordenadas dentro del cuadrado verde.

Recordemos que los atributos se pueden asignar con JS a los elementos DOM. De esta forma podemos cambiar el ejemplo anterior por:
var capa = document.querySelector("div");
capa.onmousedown = function(event){ ejemplo2(event) };
capa.onmousemove = function(event){ ejemplo3(event, this) };
capa.onmouseleave = resetearEtiqueta; //Pasamos la función, NO la invocamos
Si queremos pasar argumentos lo mejor es encapsular la función dentro de una función anónima function(event){ ... }. La función anónima recibe event, pero this se pasa desde dentro del bloque de código. Así mismo se pueden usar funciones flecha (arrow =>).

¿Qué son los Event Listener?

Por ahora hemos asignado funciones a los manejadores, pero también admiten objetos Event Listener. Añadiremos EventListeners usando el método addEventListener en los objetivos de eventos, que incluye además de a los HTML Elements, los tipos que implementan la interfaz EventTarget como Document o Window.

¿Para qué usar addEventListener?

Asignar escuchadores a un manejador nos permite las siguientes ventajas:
  1. Permite tener varios escuchadores para un mismo evento (flexibilidad)
  2. Se pueden añadir a objetos que no son Element (document y window implementan EventTarget)
  3. Añade mayor control en la activación del escuchador
Un ejemplo del código anterior usando addEventListener quedaría así (para abreviar sólo onmousemove, puede ver fiddle con ejemplo):
var divPrimera = document.querySelector("div");
divPrimera.addEventListener("mousemove", function(event){ejemplo3(event, this);});
Hay que prestar atención pues el primer parámetro es el tipo de evento SIN el "on" delante (mousemove sólo).

Si queremos pasar argumentos en la función del segundo parámetro lo haremos igual que lo hicimos en el ejemplo anterior (encapsulando con una función anónima el código).
El método addEventListener admite un tercer parámetro opcionalmente, que es el que nos permite añadir mayor control a cómo activar el listener (propagación, si se activa sólo una vez, etc...)

Relación entre event y this

Cualquier evento tiene una referencia a su fuente. En JS se accede a esta referencia por las propiedades target (generador del evento) y currentTarget (propietario del listener). De esta forma en el ejemplo anterior podríamos reducir la firma de la función y quedarse así (ver fiddle):
function ejemplo3 (evento) {
  var elemento = evento.target;
  escribirEtiqueta ('Ahora estás en coordenadas: ' + (evento.clientX - elemento.offsetLeft) + ', ' + (evento.clientY - elemento.offsetTop));
}
...
divPrimera.addEventListener("mousemove", function(event){ejemplo3(event);});
La diferencia entre target y currentTarget se puede apreciar fácilmente en la siguiente respuesta de SO.

Relación entre event y window.event

Si probamos a usar la variable window.event veremos que generalmente tendremos acceso al event que se pasaría como argumento. Esto no es un estándar y algunos navegadores (antiguos) no funcionará correctamente. Para mayor compatibilidad, se recomienda pasar event como argumento en el navegador.

Espero que con esto y unas prácticas se comprenda cómo usar los eventos.

Práctica js-eve-1

31 de octubre de 2017

JavaScript - BOM (Modelo de Objetos del Navegador)

BOM es el acrónimo de Browser Object Model (Modelo de Objetos del Navegador). Este modelo permite a JS comunicarse con el navegador que ha cargado la página.

No hay un estándar oficial para BOM, aunque los navegadores modernos implementan casi los mismos métodos y propiedades.

Nos ofrece una serie de objetos al nivel de document y superior para poder manipular parecido al siguiente árbol:


Window

En el nivel más alto tenemos al objeto window que implementan todos los navegadores. Este objeto representa una ventana/pestaña abierta del navegador (y otra por cada <iframe> que contenga).

Todos los objetos, funciones y variable globales pasan a ser miembros de window automáticamente. El objeto document del HTML DOM es una propiedad de window: window.document.

Para utilizar un miembro de window se puede obviar ésta palabra, pues es el acceso por defecto (como si hubiera un import de window.*). De hecho los métodos alert() y prompt() ya utilizados son métodos de window y los hemos llamado de esta forma.

Con window podemos abrir una nueva ventana, cerrarla, moverla, hacer scrolls, cambiar el tamaño, pasar/quitar el foco, etc...

Obtendremos un objeto window cuando abramos una dirección con window.open(url, nombre, specs, reemplazar). Si queremos una referencia a la ventana actual podremos obtenerla con self y comparándola con top podemos trabajar con los iframes.

Una utilidad importante de window es que se pueden almacenar pares "clave/valor" para personalizar la experiencia del usuario con la propiedad window.sessionStorage para una sesión o window.localStorage para obtener persistencia después de cerrar el navegador.

Window permite ejecutar código con un temporizador (en milisegundos) usando setInterval(funcion, intervalo) para llamadas separadas por el intervalo o setTimeout(func, interv) para ejecutarse una vez trascurrido un tiempo. Estos temporizadores seguirán ejecutándose hasta que no se reseteen con clearInterval(id) o clearTimeout(id) respectivamente. El id que hay que usar con estas últimas es el identificador que devuelven los métodos setInterval y setTimeout.

Hay una serie de propiedades que nos dan acceso a objetos importantes del navegador y que se detallan más abajo.

Navigator

La propiedad navigator proporciona el objeto que contiene la información del navegador: nombre de la aplicación, versión, plataforma, lenguaje, localización, etc...

Screen

La propiedad screen proporciona el objeto que contiene información de la pantalla del usuario: alto, ancho, profundidad de color y resolución.

History

La propiedad history proporciona el objeto que contiene las URLs visitadas por el usuario dentro del objeto window al que pertenece. Permite moverse hacia delante y atrás o ir directamente a una URL visitada.

Location

La propiedad location proporciona el objeto que contiene información acerca de la URL actual: nombre del host, ruta, puerto, hash, query string, etc...

Práctica js-bom-1

Práctica js-bom-2

Práctica js-bom-3

26 de octubre de 2017

JavaScript - DOM (Modelo de Objetos del Documento)

Cuando una página web es cargada, el navegador crea un Document Object Model (DOM) = Modelo de Objetos del Documento.
Se suele conocer también como árbol DOM, ya que todos los nodos se mapean descendiendo escalonadamente del nodo raíz (document)


DOM es un standard del W3C define una interfaz de programación independiente del lenguaje y plataforma que permite acceder y modificar cada uno de los nodos que lo forman (manejar el contenido, estructura y estilo de un documento) Se divide en múltiples interfaces, pero nos vamos a centrar en HTML DOM.

Mediante lenguajes como Java, XPath y ECMAScript (JavaScript), entre otros, se utiliza el HTML DOM para manipular los elementos HTML como objetos con sus métodos, propiedades y eventos.
NOTA: Ejemplos famosos de estos son el método getElementById(id), la propiedad innerHTML o el evento onclick

En DOM todo es un nodo (tipo Node):
  • El documento es un nodo document
  • Todos los elementos HTML son nodos element (tipo Element)
  • Todos los atributos HTML son nodos attribute (tipo Attr)
  • El texto dentro de elementos HTML son nodos text
  • Los comentarios son nodos comment
Podremos conocer el tipo de nodo que tenemos con la propiedad nodeType.

Node

Los nodos son los elementos sobre los que se contruyen las conexiones del árbol DOM. Pueden tener relación de padre, hijo o hermano:


Básicamente se puede crear un nodo, añadir un nodo a otro en una posición concreta entre el resto de nodos que contiene, eliminar un nodo o reemplazarlo por otro. Veamos un ejemplo:
  1. Creamos un nodo en el documento con document.createElement("div") para crear un nodo elemento con etiqueta div o con document.createTextNode("Mi Texto") para crear un nodo de texto. Estos métodos devuelven los nodos creados.
  2. Si almacenamos las referencias anteriores en las variable "capa" y "texto" respectivamente, podemos añadir un nodo a un elemento creado para que pase a ser su último hijo con capa.appendChild(texto). Si queremos colocarlo en otra posición usariamos capa.insertBefore(otroTexto, texto).
  3. De la misma forma que añadimos podemos eliminar un nodo hijo con el método capa.removeChild(texto), o reemplazarlo con otro de sus hijos capa.replaceChild(document.createTextNode("Nuevo texto"), texto).
El ejemplo completo sería
//Creamos un nodo en el documento
var capa = document.createElement("div");
var texto = document.createTextNode("Mi Texto");

//Añadimos un nodo a un elemento
capa.appendChild(texto); //pasa a ser su último hijo (lastChild)
//Si queremos colocarlo en otra posición
capa.insertBefore(texto, otroNodo); //colocado delante de otroNodo(nextSibling)

//De la misma forma que añadimos podemos eliminar un nodo hijo
capa.removeChild(texto);
//O reemplazarlo con otro de sus hijos
capa.replaceChild(document.createTextNode("Nuevo texto"), texto);
Con estas operaciones podemos modificar todo el contenido de un documento HTML, pero hay que tener cuidado con los métodos que se usan ya que hemos utilizado nodos de distintos tipos (document, element y text), pero tienen diferencias que hay que tener en cuenta (element puede tener hijos pero text o attribute no) y al no ser un lenguaje tipado debemos controlarlo nosotros.

Document

Un documento HTML que se carga en el navegador se convierte en un objeto document. Éste objeto es el nodo raíz y propietario de los otros nodos.
NOTA: En la entrada anterior facilitaba una guía de consulta rápida para hacernos una idea de los métodos y propiedades con los que cuenta cada tipo en JS. También nos puede servir el tema HTML DOM Document Object de w3school.

Los más importantes para acceder al resto de nodos son:
Una diferencia importante entre ellos es si queremos conseguir un único nodo o una lista de nodos (HTML Collection o NodeList)

Merece la pena mencionar una vez más el método write(mensaje), ya utilizado antes, que es una de las formas de producir salidas que podemos apreciar. Pero hay muchos más que nos permiten acceder a la URL, título, codificación, scripts, cookies, formularios, enlaces, imágenes, quién lo cargó (referrer), etc...

Como dijimos antes, hay que tener cuidado con no utilizar métodos que document hereda de Node y que no tiene sentido usar como los atributos o el nodo padre, porque document no tiene valores para ellos.

Element

Cada componente HTML forma un nodo element. Puede contener y ser hijo de otros elementos como vimos antes, pero además puede poseer atributos (Attr) y estilo que no posee document.
  • Para obtener un mapa con todos los atributos que posee un elemento se usa la propiedad element.attributes que devuelve un NamedNodeMap. Los valores se pueden obtener por el índice con item(indice) o por nombre de atributo con getNamedItem("nombre").
  • Para obtener el estilo se usará la propiedad element.style, que nos permitirá leer y establecer cada propiedad CSS. DOM Style es una propiedad de sólo lectura, permite cambiar cada atributo de ella (como backgroundColor por ejemplo) pero no asignar un atributo estilo. Si se quiere manipular el estilo completo, se recomienda hacerlo por su texto CSS usando la propiedad cssText.
  • Podemos acceder al id del elemento con element.id
  • Por útimo es habitual modificar el contenido de un elemento usando su propiedad element.innerHTML que contiene el valor de todo el contenido HTML del elemento. Sin embargo se recomienda modificar el contenido alterando los nodos DOM por rendimiento.
Hay muchos más métodos y propiedades para acceder al tamaño del elemento, posición, eventos, etc... Lo mejor es ir practicando con ellos para conocerlos todos.
Realiza estos ejercicios para practicar:


Práctica js-dom-1

Práctica js-dom-2

Práctica js-dom-3

Práctica js-dom-4

18 de octubre de 2017

JavaScript - Sintaxis

La sintaxis de JS es muy parecida a la de Java, pero tiene sus particularidades que describiremos a continuación. Esta entrada no pretende ser extensiva y sólo se mencionarán las diferencias o métodos más básicos (y antiguos).

Generalidades

  • No se tiene en cuenta los espacios en blanco y nuevas líneas (como en HTML)
  • Es Case sensitive (distingue mayúsculas y minúsculas: miVariable ≠ mivariable)
  • Terminar las sentencias con ';' (buena práctica)
  • Comentarios empiezan con '//' o un bloque entre '/* ... */' (como Java y CSS). Es importante resaltar que esto sólo sirve en bloques JS (como el código encerrado entre etiquetas <script> o nuestro fichero .js), no en el resto del documento HTML en el que pudiéramos tener código incrustado.

Variables

No se define el tipo de variables (mejor se usa palabra clave 'var')
Se puede usar letras, números, '$' y '_', pero no puede empezar un por número
var miVariable = 0;
var mivariable = "1";
miVariable == mivariable; //false

Tipos predefinidos

Numérico (enteros y reales)
  • Enteros: en formatos decimal (n10), hexadecimal (0xn16) y octal (0n8) => NO escribir números con un cero al principio o pueden ser interpretados como en octal
  • Reales: parte entera y parte decimal: 25.478, 2.3e-45, -3e3
Texto (literal)
  • Entre comillas simples o dobles. Si pueden cerrar dentro con comillas distintas a las que las rodean.
  • Uso de carácter de escape '\' + carácter, código ASCII en octal o hexadecimal
Booleano
  • Sólo dos valores: true / false

Objetos

JS tiene en la actualidad una serie de tipos de objetos genéricos y un gran número de métodos que han ido creciendo según se van desarrollando nuevas funcionalidades. Lo mejor es hacerse con una guía de referencia rápida (cheatsheet) en papel para su consulta hasta que estemos familiarizados con todas ellas. Puedes descargarte la referencia de @Manz en github. Tiene más sobre HTML y CSS. Si te son útiles piensa en colaborar con un donativo para que se sienta estimulado a seguir ayudando. Si prefieres una referencia en línea, es muy práctica la referencia de w3schools que podría tomarse como nuestra Biblia en este asunto.

Arrays
Se definen como una enumeración de elementos de cualquier tipo y valor, separados por comas y encerrados entre corchetes:
var miArray = [ "Uno", 2, true ]; //Texto, número y booleano
Se puede acceder a una posición usando su índice (en base cero): miArray[0]
Se puede conocer su número de elementos con su propiedad length.

Tienen varios métodos para trabajar con ellos:
  1. slice(): devuelve una copia del array
  2. concat(): devuelve la unión dos arrays
  3. join(separador)
    1. función "contraria" a split()
    2. une los elementos de un array para formar una cadena de texto separados por el carácter pasado como argumento
  4. pop(): elimina el último elemento del array y lo devuelve
  5. push(valor): añade un elemento al final del array
  6. shift() / unshift(valor): lo mismo que los dos anteriores pero con el principio del array
  7. reverse(): coloca los elementos en orden inverso
Cadena
Es cualquier texto entre comillas.
Aunque se pueda usar como un objeto de tipo String es mejor evitarlo. Ejemplo, no usar: var cadena = new String('Hola Mundo');

Para comparar cadenas hay que tener en cuenta que:
Tiene los típicos métodos para separar, unir, recortar, pasar a mayúsculas/minúsculas, comparar el comienzo, el fin, etc... se puede ver fácilmente en la referencia.

Operadores

Son los típicos que podemos encontrar en Java, C++, etc...:
  • Asignación: var miVariable = 0;
  • Aritméticos: +, -, *, / y % (resto de la división). Se puede combinar con el de asignación:
    miVariable += 3;
    // es igual que
    miVariable = miVariable + 3;
    
  • Lógicos: && (AND), || (OR) y ! (negación)
  • Comparación: <, >, <=, >=, ==, !=. También existe === que comparar valor y tipo de objetos.

Estructuras de Control

De igual forma tenemos las estructuras habituales de Java:

Sentencia condicional if:
if (condicion){...}
else {...}

Bucle for y for...in(lo usamos cuando sabemos el número de elementos a recorrer):
for (inicializacion; condicion; actualizacion) {...}
// O también
for (indice in coleccion) {...}

Ojo, ver documento "for in" de MDN al respecto (itera sobre las propiedades del objeto) para recorrer los objetos de un iterable se usa for...of:
for (elemento of coleccion) {...} //Experimental

Bucle while (cuando no sabemos el número, sólo la condición):
while (condicion) {
  ...
}

Bucle do...while (igual que antes pero al menos tenemos que hacerlo una vez):
do {
  ...
} while (condicion);

Sentencia switch:
switch (valor) {

  case valor1:
    ...
    break;
    ...
  default:
    ...
    break;
}


Interrupción de bucles:
  • continue: interrumpe la ejecución y continua con el siguiente elemento.
  • break: aborta la ejecución del bucle y lo abandona.

Funciones

  • Las funciones encapsulan código JS que realiza una tarea (procedimiento), pueden reutilizarse y pueden devolver un valor.
    function nombreFuncion (parametro1, parametro2, ...) {
      ...
      return resultado;
    }
    
  • Crean un ámbito (scope) propio. Las variables locales se destruyen al abandonar la función.
  • La función se ejecuta cuando se llama con () y los parámetros necesarios en su caso, si no, devuelve la definición de la función (no su resultado)
    var resultado = nombreFuncion;
    // no ejecuta la función, asigna la función ala variable resultado
    resultado = nombreFuncion();
    // ahora sí asignará el resultado porque se ha invocado
    
  • Los parámetros son opcionales, no necesitan encajar perfectamente con una firma como en Java.

Funciones predefinidas
  • eval(expresión): sirve para evaluar una expresión matemática que está en formato texto.
  • isNaN(valor): devuelve 'true' si valor NO es un número válido (Not a Number). Cualquier operación aritmética con NaN resulta en NaN.
  • parseInt(numero, base): transforma el argumento en la base pasada.
  • parseFloat(numeroReal): transforma el argumento en un número en coma flotante.
  • toString(numero): devuelve el número en formato cadena.
  • toFixed(decimales): devuelve el número con el redondeo necesario para las posiciones decimales solicitadas.
  • escape(cadena) / unscape(dirección URL): sirve para transformar caracteres no válidos en formato URL a sus equivalentes y viceversa. Están obsoletas (deprecated)

Realiza estos ejercicios para practicar:

Práctica js-sin-1

Práctica js-sin-2

Práctica js-sin-3

Práctica js-sin-4

Referencias:
Mozilla Developer Network (MDN): Sintaxis
w3schools: Sintaxis
Recomendado: Usa los tutoriales de Mozilla.

17 de octubre de 2017

Javascript - Fundamentos

¿Qué es JavaScript?

JavaScript (JS) es un lenguaje de programación interpretado, dialecto del estándar ECMAScript. Se define como:
  1. Orientado a objetos
  2. Basado en prototipos => No se instancian Clases, clona objetos existentes (prototipos) o código
  3. Imperativo
  4. Débilmente tipado y dinámico (tipo asociado al valor, no a la variables)
Principalmente es utilizado del lado del cliente (client-side) interpretado por un navegador web permitiendo mejoras en la interfaz de usuario y páginas web dinámicas al mismo tiempo que las sentencias van descargándose junto con el código HTML (propósito original).
También se utiliza en aplicaciones externas a la web, por ejemplo en documentos PDF, y aplicaciones de escritorio (mayoritariamente widgets).
Actualmente también se usa del lado del servidor (Server-side JavaScript o SSJS) como en Node.js o Apache Couch DB.

JS NO es Java (las dos marcas pertenecen a Oracle), aunque adopta nombres y convenciones de este lenguaje, tienen semánticas y propósitos diferentes.
JS implementa Document Object Model (DOM) para interactuar con una página web.
Actualmente es ampliamente utilizado para enviar y recibir información del servidor junto con ayuda de otras tecnologías como AJAX.

JS es conocido como el lenguaje de script para la Web, ofreciendo funcionalidades completas al usuario con el resto de componentes habituales que podemos encontrar en cualquier página web:
  1. HTML define el contenido de las páginas
  2. CSS especifica el diseño (layout)
  3. JavaScript programa el comportamiento

¿Cómo se relacionan HTML, CSS y JS?

El código JS se descargará junto con el resto de código de una página web. Hay varias opciones para añadir JS a una página web:
  1. puede incrustarse en un elemento,
  2. definirse en un elemento style en la cabecera o
  3. enlazarse con un archivo JS externo
<!DOCTYPE html>
<html>
<head>
 <script type="text/javascript">
  //Definido en cabecera (Caso 2, Funcionalidad 2a)
  function getTexto() {
    return 'Texto incrustado';
  }
 </script>
 <script type="text/javascript">
  //Llamada al leer la invocacion (Caso 2, Funcionalidad 2b)
  document.write(getTexto() + ' (Caso 2, Funcionalidad 2b)');
 </script>
 <script type="text/javascript"
         src="https://sites.google.com/site/awes0mem4nfiles/codigoJS.js">
  //Referencia a Codigo JS (Caso 3, Funcionalidad 3)
 </script>
</head>
<body>
 <noscript> No tengo activado JS (Funcionalidad 1) </noscript>
 <script type="text/javascript">
  //Llamada al leer la invocacion (Caso 1 y 3, Funcionalidad 4)
  document.write('<br>' + getTexto() + ' (Caso 1 y 3, Funcionalidad 4)');
 </script>
 <p onclick="alert('JS dentro atributo de elemento')">
  Pincha para ver un mensaje incrustado en un elemento (Caso 1, Funcionalidad 5)
 </p>
 <button type="button" onclick="escribirTextoArchivo()">
  Llama a función en archivo .js (Caso 3, Funcionalidad 6)
 </button>
</body>
</html>
En este fragmento de código podemos ver todas las opciones para usar código JS enumeradas anteriormente (lo importante ahora mismo no es conocer la sintaxis de JS, sólo es una muestra de cómo se introduce y se comporta el código JS).
Este ejemplo implementa las siguientes funcionalidades:
  1. Muestra un mensaje si no se tiene activada la ejecución de JS en el navegador.
  2. Si está activado se añade al documento el texto de la función "getTexto()"
  3. Enlaza un archivo .js externo
  4. Se añade el texto de la función "getTexto()". Ha cambiado porque se ha sobreescrito (override)al enlazarse código JS donde hay una función con el mismo nombre
  5. Añade un párrafo que al recibir el evento "onclick" ejecuta código incrustado en él
  6. Añade un botón que llama a una función con el evento "onclick"
La mejor opción es usar un enlace a un archivo con el código JS, ya que nos facilitará enormemente el mantenimiento (si no habría que retocar cada página con código incrustado y no es una buena idea)
Además podemos utilizar una gran cantidad de librería de terceros que nos proporcionarán muchas funcionalidades enlazándolas de esta forma.

Dejaremos el código declarado en la página para hacer modificaciones que sólo afecten a la página que lo contiene (por ejemplo para crear una nueva función/variable que no se reutilizará, o para modificar una existente pero que debe variar su comportamiento) .

Incrustar código en un elemento nos servirá normalmente para personalizar una llamada (por ejemplo para pasarle un argumento a una función)

Ninguno de los casos tiene una mejora respecto a la conexión de red ya que podemos alojar los scripts externos en nuestro propio servidor (los mismos que sirven el HTML) para no depender de terceros.

En el siguiente artículo veremos la sintaxis básica.
Realiza estos ejercicios para practicar:

Práctica fundamentos 1

Práctica fundamentos 2

Profundiza más en las referencias:

1 de abril de 2017

NAS 2big LACIE - Apagado Reforzado (Deep Sleep)

Soy un usuario de un LACIE 2-BIG-NAS. Estoy bastante contento con él por su chasis, su rendimiento, su sistema operativo, etc... Llevo ya varios años con él y lo considero una buena compra. También por mi trabajo lo he visto la versión de cinco discos dando servicio en algunos sistemas algo delicados así que considero que debe rendir bien a nivel de sistemas profesionales.




Es muy ligero y ya sabe mi mujer que en caso de incendio es lo que hay que salvar :)

El caso es que cuando lo adquirí viene preparado para que se instalé el sistema operativo NAS OS 3. LACIE mantiene actualizado el sistema con sólo disponer de una conexión a Internet y autorizar la instalación. Siempre te avisan que hagas una copia de seguridad pero nunca he tenido problemas, esto me hace gracia porque ¿Quién tiene un NAS en espejo con capacidad para meter todas sus cosas y además tiene que tener otro disco para guardar cada vez que se actualiza?

También se pueden programar las horas de funcionamiento y tiene la capacidad de Wake On LAN que para un NAS es muy útil obviamente. Hace casi un año se podía actualizar a la versión 4 del NAS OS. Parece que es mantenida por Seagate y tuvo un cambio bastante importante en la interfaz web para la administración del servidor. Tenía entre las opciones del menú principal un modo de "Apagado Reforzado" que viene a ser lo que en inglés denominan "Deep Sleep" y que a título práctico apaga el NAS por software (el interruptor de la fuente se mantiene en la posición de encendido) pero mantiene la red conectada para poder ser encendido por Wake On LAN.

Lamentablemente desde la versión NAS OS 4.1.9.2 esa funcionalidad ha sido eliminada y al ver que en las sucesivas actualizaciones no se añadía, ni fue un bug, ni la gente daba la tabarra por Internet, y tras intentar instalar la versión anterior (pero que se ve que no permite "downgradear" el sistema siguiendo las instrucciones de instalación manual off-line) envíe la consulta al servicio técnico de LACIE para que me contarán la situación, si podía recuperarla o cómo podía apagarlo por otras vías tipo SSH.

La solución que me dieron es que hiciera una copia de seguridad, formateara todo para que se instalase el SO que viene inicialmente en el servidor y que no actualizara hasta la citada versión... se me quedo un poco cara de haba así que busque el comando que haría que se apagara por software ya que la programación de encendido y apagado sigue existiendo con lo que seguro que el script se puede lanzar de manera manual por SSH.

También puse la pregunta en Stack Over Flow que al final me respondí a mi mismo.

Buscando en el servicio cron al final pude encontrarlo y ya puedo apagar el sistema para arrancarlo vía Wake On LAN con su paquete mágico.

El script que hay que lanzar esta en "/sbin/smart_shutdown" así que sólo hay que ejecutarlo con permisos de administrador y nuestro NAS se quedará "profundamente dormido" hasta que queramos despertarlo.

sudo /sbin/smart_shutdown

Espero que os ayude.

12 de marzo de 2017

Recortar y convertir un video por línea de comandos con VLC

Reconozco que me gustan los comandos. Me permiten hacer más cosas, con más detalle y con menos trabajo que ir haciendo clicks en una GUI. Su único inconveniente es saber cómo hacerlo.


Esta entrada es un comando que permitirá recortar y convertir un fichero de video en otro en H264/mp3.

Éste es el comando (formateado un poco para ver los detalles):

"C:\Program Files (x86)\VideoLAN\VLC\vlc.exe"
   C:\origen.avi --start-time="5" --stop-time="30"
   :sout="#transcode{
      vcodec=h264,
      acodec=mp3,
      ab=128,
      scale=1,
      channels=2,
      samplerate=44100}
   :std{
      access=file,
      mux=mp4,
      dst=C:\destino.mp4}"

Lo que hace es abrir VLC con el fichero "origen.avi" que se convertirá según las opciones de codificación marcadas desde segundo 5 al 30 del vídeo (hace un recorte)

Compárteme

Entradas populares