Bucles en AppleScript

AppleScript, al igual que otros lenguajes de programación, nos permite utilizar una serie de estructuras de código para repetir una serie de comandos un número determinado de veces. Esto resulta muy úl para evitar tener que escribir demasiado código repetido

Por ejemplo imaginemos que queremos realizar un script que cuente desde 1 hasta 10. Si no supiesemos utilizar ninguna estructura de bucle o para repetir un trozo de código nuestro script debería ser algo parecido a lo siguiente:


on run
set valor to 1
say valor
set valor to valor + 1
say valor
set valor to valor + 1
say valor
set valor to valor + 1
say valor
set valor to valor + 1
say valor
set valor to valor + 1
say valor
set valor to valor + 1
say valor
set valor to valor + 1
say valor
set valor to valor + 1
say valor
set valor to valor + 1
say valor
end run

El código escrito es repetitivo, poco elegante y poco eficiente a la hora de ser mantenido o modificado en el futuro.

Para poder solucionar este problema AppleScript nos proporciona la estructura repeat que repite un número de veces determinado el código situado entre la orden repeat y end repeat. Nuestro script anterior podría quedar así:


on run
set valor to 1
repeat 10 times
say valor
set valor to valor + 1
end repeat
end run

Al ejecutar el script obtendremos el mismo resultado pero habremos escrito menos líneas de código y además queda más claro que existe una acción repetida varias veces dentro del script.

Si en el comando repeat no indicamos el número de veces que debe repetirse el bloque de código se entrará en un bucle infinito. Por ejemplo, si cambiamos nuestro ejemplo anterior dejando la línea repeat 10 times por sólo repeat y lo ejecutamos el script no parará de contar hasta que nosotros interrumpamos la ejecución del script.

Un bucle de ejecución infinita es muy peligroso ya que provocará que nuestro ordenador entre en un proceso sin fin y cada vez haya menos recursos disponibles para la máquina. Es muy probable que hayamos visto comportamientos similares cuando nuestro teléfono u ordenador personal realiza un proceso que provoca que la temperatura del dispositivo aumenta, se ralentiza la ejecución de todo el sistema operativo y cualquier acción que intentemos se realizará de forma muy pausada y con interrupciones. Esto puede deberse a que una aplicación está ejecutando un bucle infinito o de muy larga duración, por ejemplo convertir un fichero de vídeo o un proceso que requiera de muchos minutos para completarse.

Por todo esto siempre debemos incluir cláusulas de interruptción de un bucle en cualquier lenguaje de programación que utilicemos, incluido AppleScript.

Para salir de una estructura repeat AppleScript nos proporciona el comando exit. Veamos nuestro ejemplo inicial pero utilizando un bucle infinito con su cláusula de ejecución controlada para que se termine cuando hayamos verbalizado el valor 10. El código sería el siguiente:


on run
set valor to 1
repeat
say valor
set valor to valor + 1
if valor = 11 then
exit repeat
end if
end repeat
end run

Pero este código sigue sin ser del todo apropiado. En nuestro ejemplo sabemos que queremos ir desde el valor 1 hasta el 10. En los casos en que sabemos el valor de inicio y de finalización y además necesitamos una variable que nos indique en qué número de la iteración del bucle nos encontramos el comando repeat nos permite declarar una variable para controlar el bucle e indicar el valor de comienzo y el valor de finalización para el bucle. Veamos un ejemplo para que nos diga los números entre el 10 y el 20. El código sería el siguiente:


on run
repeat with valor from 10 to 20
say valor
end repeat
end run

Es necesario tener en cuenta que la estructura repeat with from to sólo se ejecutará si el valor indicado en from es menor que el indicado en to, lo que significa que el bucle se ejecutará si se va de un número hacia otro número mayor. Por ejemplo, si intentamos hacer una cuenta atrás el script siguiente no se ejecutará:


on run
repeat with valor from 10 to 1
say valor
end repeat
end run

Para solucionar este problema debemos usar nuestro ingenio para superar las limitaciones del lenguaje de programación que estemos utilizando. Una posible solución sería la siguiente:


on run
repeat with valor from 1 to 10
set cuentaAtras to 11 - valor
say cuentaAtras
end repeat
say "¡Boom!"
end run

AppleScript proporciona otras variantes de la estructura de bucle repeat pero pueden resultar menos eficientes o más complejas de controlar. Más adelante veremos algunas de ellas.

Conoce el estado de tu batería en MacOS Sierra gracias a AppleScript

Con las últimas versiones de MacOS Sierra, el sistema operativo de Apple para sus ordenadores portátiles y de sobremesa, los usuarios han encontrado que el indicador de batería es confuso y ofrece información insuficiente.

Muchos usuarios no encuentran una solución para volver a obtener toda la información de sus baterías y desconocen que el propio sistema operativo les ofrece una solución utilizando una de las herramientas del sistema MacOS que lo convierten en uno de los sistemas ooperativos más versátiles del mercado, nos referimos a Apple script

Aprender Apple script no es demasiado complicado pero puede que no tengas tiempo para ello. Por esa razón Tyflos Accessible Software ha desarrollado un script que verbaliza bien con la voz del sistema o la voz de VoiceOver, el lector de pantallas para MacOS, el estado actual de la batería de tu equipo Apple.

Puedes descargar el archivo comprimido del
script para conocer el estado de la batería(Español)
e instalarlo en tu sistema MacOS.

Una vez descomprimido el archivo copia el fichero appleScript en la carpeta para scripts de tu carpeta biblioteca de usuario. Una vez allí puedes crear un flujo de Automator para que se ejecute con una pulsación de teclas.

Si eres usuario de VoiceOver es más sencillo de utilizar. Descomprime el archivo dentro de la carpeta de scripts de tu biblioteca, es necesario activar el soporte de scripts de VoiceOver y añadir un comando para VoiceOver asociado a este script. Para ello, dentro de las opciones de VoiceOver, encontrarás el mecanismo para asociar un atajo de teclado a un comando de VoiceOver en la categoría comandos de la ventana de configuración de VoiceOver.

Cambiar rápidamente de idioma para el dictado en OSX

La nueva función de dictado para OSX permite al usuario dictar textos en más de 20 idiomas. Su uso es muy sencillo al igual que su configuración.

El problema aparece cuando el usuario quiere dictar en más de un sólo idioma. Aunque el cambio de idioma es sencillo puede resultar engorroso y lento y lo digo por experiencia. Durante un día normal de uso de este servicio puedo cambiar esta configuración unas 8 veces.

Para facilitar la operación de cambio de idioma he realizado un script de AppleScript que nos permite conmutar el idioma de dictado entre español de España e inglés de Estados unidos.

Este script, junto a la posibilidad de ejecución de scripts por atajos de teclado de VoiceOver, habilitan un cambio rápido de este servicio para adaptarse a nuestras necesidades en todo momento.

Puedes descargar el script de cambio de idioma e instalarlo en tu sistema OSX Mountain Lion.

Requisitos del script

Para un correcto funcionamiento del script es necesario cumplir los siguientes requisitos:

  • Utilizar OSX Mountain Lion 10.8.2 o superior
  • Tener instaladas las voces de Alex y Diego en el sistema. Estas voces se utilizan para la notificación de cambio de idioma.
  • Utilizar OSX en español. El script no funcionará de forma apropiada en un entorno OSX configurado para otro idioma.
  • El script sólo cambia entre español de España e inglés de Estados unidos. Para modificar estos valores es necesario modificar el código fuente del script.
  • Este script se distribuye de forma gratuita. Si vas a modificarlo o distribuirlo respeta su autoría y recuerda mencionar la fuente original de donde lo obtuviste.

Estructuras condicionales en AppleScript

En AppleScript, al igual que en otros lenguajes de programación, existen ciertas estructuras de código para controlar el flujo de ejecución de nuestro programa. Recordemos que un script es un programa con ciertas características especiales.

La estructura más simple es la sentencia que se puede resumir como una orden que indica al programador a su programa. Un ejemplo sería la línea de código con la sentencia say que hemos visto en el ejemplo de Hola mundo de esta serie de artículos.

Otro ejemplo sería la línea de asignación de un valor a una variable.

Estructuras condicionales

Hasta ahora sólo sabemos crear AppleScripts que ejecuten una sentencia detrás de otra, almacenando información y manipulándola. ¿Pero podemos controlar aún más el flujo de ejecución?

Imaginemos que un trozo de nuestro script se ejecute a partir de una hora determinada, por ejemplo, un aviso para el usuario. Lo primero que debemos hacer es obtener la hora actual. Este ejemplo nos explica cómo hacerlo:


(*
Ejemplo para obtener la hora actual
*)
on run
set fecha to current date
set hora to fecha's hours
end run

En la variable hora se almacena el valor numérico de la hora actual.

Estructura if then

Para poder ejecutar un trozo de código si se cumple una condición debemos utilizar una estructura condicional. La estructura condicional más básica, y común a muchos lenguajes de programación, es la estructura if-then. La traducción al castellano de if, then es si, entonces….

Veamos su sintaxis en AppleScript para entenderla mejor:

if condición a cumplir then
código a ejecutar
end if

En la condición a cumplir se debe indicar una comparación u operación que devuelva un valor verdadero o falso. Ejemplo de esto son operaciones comparativas del tipo A < B, A = B, Nombre = «Jonathan»

Ampliemos nuestro ejemplo anterior para dar un mensaje por voz si la hora es mayor o igual a siete. El ejemplo quedaría así:


(*
Ejemplo para dar un aviso según la hora
*)
on run
-- obtenemos la fecha
set fecha to current date
set hora to fecha's hours
-- según la hora damos el aviso
if hora >= 7 then
say "¡Despierta! Ya es tarde"
end if
end run

En este ejemplo vemos otra forma de incluir comentarios: escribiendo dos caracteres de guión consecutivos (-) indicamos que lo que hay a la derecha de esa línea es un comentario de código. Es una forma de incluir comentarios de forma rápida.

Estructura if then else

El ejemplo anterior sólo nos avisará si son las 7 o más tarde pero no hará nada si es antes de las siete. A veces nos interesa realizar operaciones distintas tanto si se cumple la condición como si se cumple lo contrario. Una forma de hacer esto sería declarar dos estructuras if then con condiciones contrarias. Un ejemplo de esto sería:


(*
Ejemplo 2 para dar un aviso según la hora
*)
on run
-- obtenemos la fecha
set fecha to current date
set hora to fecha's hours
-- según la hora damos el aviso
if hora >= 7 then
say "¡Despierta! Ya es tarde"
end if
if hora < 7 then say "Todavía es temprano. Aprovecha." end if end run

Aunque esta solución pueda considerarse válida resulta poco eficiente y complica el código. Es poco eficiente porque para hacer una acción u otra realiza dos comparaciones. El código resulta más confuso porque ambas estructuras resultan iguales salvo por un signo matemático pudiendo provocar la confusión del programador.

AppleScript, como otros lenguajes, proporciona una solución elegante para cuando queremos ejecutar un trozo de código tanto para cuando se cumple una condición como para cuando se cumple la contraria. Veamos el ejemplo con esta nueva estructura condicional mejorada:


(*
Ejemplo 3 para dar un aviso según la hora
*)
on run
-- obtenemos la fecha
set fecha to current date
set hora to fecha's hours
-- según la hora damos el aviso
if hora >= 7 then
say "¡Despierta! Ya es tarde"
else
say "Todavía es temprano. Aprovecha."
end if
end run

Como se ve en el código aparece la palabra reservada del lenguaje else. Esta partícula nos permite incluir una separación en la estructura condicional para indicar que el código a continuación se ejecutará sólo si no se cumple la condición. La sintaxis completa es:

if condición a cumplir then
código a ejecutar cuando se cumple la condición
else
código a ejecutar si no se cumple la condición
end if

Ahora podemos crear scripts más complejos que realicen operaciones según se cumplan o no ciertas condiciones.

Variables en AppleScript

AppleScript, al igual que en otros lenguajes de programación, nos permite utilizar variables para almacenar y manipular información.
Su uso es muy sencillo. Para declarar y asignar un valor a una variable debemos seguir la siguiente sintaxis:

set nombreDeVariable to valorParaLaVariable

Veamos un ejemplo simple:


on run
set mensaje to "Hola mundo!"
say mensaje
end run

Para reasignar el valor de una variable se sigue la misma sintaxis. En la asignación podemos realizar encadenamiento de cadenas de texto, operaciones matemáticas, etc.

Veamos un ejemplo en la que asignamos el valor 1 a la variable valor, pronunciamos su valor, reasignamos el valor de la variable al valor que tenía antes más una unidad y volvemos a pronunciarlo:


on run
set valor to 1
say valor
set valor to valor + 1
say valor
end run

Problemas de formatos y tipos

Las variables pertenecen a distintos formatos (texto, números enteros, números decimales, estructuras de datos, etc) y formatos (UTF-8, UTF-16, Unicode, etc). Si intentamos manipular variables entre si con tipos o formatos distintos podemos obtener un error. Por ejemplo, la función say, que pronuncia un texto, espera que le pasemos una variable de texto o de números enteros.

Veamos un ejemplo en el que intentamos hacer un script para que nos pronuncie la fecha de hoy:


on run
set fecha to current date
say fecha
end run

Si intentamos ejecutarlo obtendremos el siguiente mensaje de error: No es posible convertir date «sábado 18 de agosto de 2012 09:44:04″ en tipo «class utf8».

Para solucionar este problema deberemos convertir el valor de fecha, que está en el formato de fecha del sistema, a un valor de cadena de texto.

Para convertir el valor de una variable a otro formato debemos realizar una conversión. La conversión en appleScript sigue la siguiente sintaxis:

( variable as tipoAConvertir )

Necesitamos convertir el tipo fecha de la variable fecha a un tipo de cadena de texto. El ejemplo quedaría así:


on run
set fecha to current date
set fechaEnTexto to (fecha as text)
say fechaEnTexto
end run

Script para identificar nivel de indentación con VoiceOver

A la hora de escribir textos para desarrollar aplicaciones en un lenguaje de programación se utilizan una serie de caracteres para indentar el texto separándolo una distancia determinada con respecto al margen izquierdo del documento. Esto se utiliza para estructurar el código del proyecto software y obtener una mejor visualización de las diversas estructuras y áreas del archivo de código. Algunos lenguajes de programación, como Python, utilizan estos caracteres de indentación para definir bucles o subrutinas por lo que la indentación pasa a tomar mayor importancia.

Para indentar un texto se suele utilizar el caracter de espacio o el caracter de tabulación. De esta forma se pueden definir distintos niveles de indentación de forma homogénea.

Los desarrolladores con discapacidad visual que utilizan un lector de pantallas no pueden acceder a esta información de forma habitual. Aunque algunos lectores de pantallas, como las últimas versiones de Jaws, incorporan funciones para identificar cambios en la indentación del texto la mayoría de estos productos de apoyo carecen de herramientas para gestionar este atributo del texto. VoiceOver para OSX carece de esta funcionalidad pero podemos incorporar algo que nos permita consultar el nivel de indentación de una línea de texto gracias a la ampliación de funcionalidad de VoiceOver mediante Apple script.

Script para verificar el nivel de indentación de una línea de texto

Tyflos Accessible Software ha desarrollado un script para VoiceOver el cual devuelve el número de indentación del último texto verbalizado por VoiceOver.

Esta primera versión del script sólo soporta caracteres de tabulación. En futuras versiones se aportará mayor soporte para otros caracteres de indentación.

Puedes descargar el archivo comprimido del script de verificación del nivel de indentación e instalarlo en tu sistema OSX.

Para utilizarlo es necesario activar el soporte de scripts de VoiceOver y añadir un comando para VoiceOver asociado a este script.