Cómo reproducir un sonido en AppleScript utilizando comandos de Terminal

Con AppleScript, al igual que vimos en el artículo de Cómo reproducir un sonido al iniciar sesión en OSX podemos ejecutar comandos del terminal de forma sencilla para realizar operaciones.

En este artículo vamos a seguir con el ejemplo que seguimos con Automator y vamos a reproducir un sonido utilizando el comando de terminal afplay.

En AppleScript para ejecutar una orden en el terminal debemos utilizar la orden do shell script seguida de una cadena de texto entre dobles comillas (").

En AppleScript el ejemplo que hicimos con Automator quedaría así:


on run
do shell script "afplay /System/Library/Sounds/Blow.aiff"

A diferencia de Automator en este caso conseguimos el mismo efecto de forma más sencilla y con menos trabajo. Pero AppleScript no es siempre más sencillo de utilizar que Automator. Es más, desde Automator podemos ejecutar diversos scripts de AppleScript para realizar flujos de trabajo más complejos. Debemos decidir en cada caso qué opción es la más apropiada dependiendo qué función queremos crear.

Control de flujo de la aplicación usando estructuras condicionales en Swift

En Swift al igual que en otros lenguajes de programación la ejecución de un programa cambia según se vayan cumpliendo una serie de condiciones. Por esta razón todos los lenguajes de programación incluyen algún tipo de estructura condicional para poder controlar el flujo de ejecución de nuestro programa.

La mayoría de estructuras condicionales cumplen esta estructura:

Si se cumple una condición
entonces haz algo

Esto en Swift se consigue con la sentencia if y su sintáxis es la siguiente:


if condicionVerdadera {
// Codigo a ejecutar si se cumple la condicion
}

La condición siempre será una comparación booleana (devolverá verdadero o falso) y sólo se ejecutaría el código entre llaves si la comparación es verdadera.

Veamos un ejemplo sencillo.


/*
Playground de ejemplo de condicionales
*/
let num1 = 23
let num2 = 33

if num1 < num2 { print("Num1 es menor que num2") } if num1 > num2 {
print("Num1 es mayor que num2")
}
if num1 == num2 {
print("Num1 es igual que num2")
}

Comparaciones en Swift

La mayoría de comparaciones que se realizan en Swift son comparaciones de valores almacenados por variables u objetos. En Swift tenemos inicialmente las siguientes operaciones de comparación:

==
Igual a
!=
distinto de
<
Menor que
>
mayor que
<=
Menor o igual que
>=
mayor o igual que

Con este conjunto de comparaciones podemos resolver la mayoría de progremas de cualquier aplicación.

Ámbitos en Swift

En Swift el uso de las llaves ({ }) se utiliza para agrupar un trozo de código que pertenecerá a un mismo ámbito.

Los ámbitos no sólo se utilizan para determinar qué conjunto de órdenes pertenecen a una función, parte de código a ejecutar si se cumple una condición o qué funciones y propiedades pertenecen a una clase. Un ámbito también determina qué recursos están fuera y dentro del ámbito. Esto significa que podemos usar variables y constantes que estén por encima del ámbito pero todo aquello que declaremos dentro del ámbito no podrá ser utilizado fuera de él.

Veamos esto en un ejemplo de código.


/*
Playground de ejemplo de ambitos en Swift
*/

let numFuera = 3
do {
let numDentro = 5
print("fuera= \(numFuera) dentro = \(numDentro)")
}
print("fuera= \(numFuera) dentro = \(numDentro)")

Si intentamos ejecutar el código anterior obtendremos el siguiente error:

Playground execution failed:

error: PlayGroundTest.playground:4:38: error: use of unresolved identifier 'numDentro'
print("fuera= \(numFuera) dentro = \(numDentro)")
                                     ^~~~~~~~~

Esto se debe a que en la última línea de código, en el segundo uso de la función print() estamos haciendo referencia a la constante numDentro que está declarada dentro de un ámbito y esa función print() está siendo ejecutada fuera de ese ámbito.

Veremos más adelante más detalles de los ámbitos. Por ahora sólo nos interesa saber que las llaves nos permiten crear bloques de código agrupado y que los recursos creados y declarados dentro de un bloque son para ser utilizados dentro de ese bloque o dentro de los sub bloques que contenga.

Encadenando y anidando condicionales

Relacionada con la sentencia if tenemos la sentencia else que nos permite ejecutar un bloque de código si no se cumple la condición que estamos evaluando. Sería algo como:

Si se cumple una condición
  entonces haz algo
Si no 
  entonces haz otra cosa

Con la sintáxis de Swift el ejemplo sería el siguiente:


if condicionVerdadera {
// Codigo a ejecutar si se cumple la condicion
} else {
// Codigo a ejecutar si no se cumple la condicion
}

Un ejemplo práctico podría ser este:


/*
Playground de ejemplo de condicionales
*/
let num1 = 23
let num2 = 33

if num1 < num2 { print("Num1 es menor que num2") } else { print("Num1 no es menor que num2") }

Podemos encadenar varios else if para optimizar nuestro código. Nuestro ejemplo inicial quedaría de la siguiente forma:


/*
Playground de ejemplo de condicionales
*/
let num1 = 23
let num2 = 33

if num1 < num2 { print("Num1 es menor que num2") } else if num1 > num2 {
print("Num1 es mayor que num2")
}
else if num1 == num2 {
print("Num1 es igual que num2")
}

Además dentro de un dominio de una condición podemos incluir nuevas condiciones creando condiciones anidadas. Veamos un ejemplo práctico


/*
Playground de ejemplo de condicionales
*/
let num1 = 23
let num2 = 33

if num1 < num2 { if num1 == 23 { print("Num1 es menor que num2 y num1 tiene el valor 23") } else { print("Num1 es menor que num2") } } else { print("Num1 no es menor que num2") }

Realizando varias comparaciones a la vez

En algunas ocasiones puede que una condición consista en el resultado de varias comparaciones. Swift, al igual que otros lenguajes de programación nos permite conjuntar comparaciones para crear una condición compuesta.

Para poder crear estas uniones entre comparaciones tenemos las palabras AND y OR qe nos permiten crearr combinaciones más complejas. Pero en Swift en lugar de utilizar la palabra AND debemos usar el doble símbolo de ampersand (&&) y para la palabra OR debemos usar el doble símbolo de línea vertical (||).

Si utilizamos el AND indicamos que ambas comparaciones deben cumplirse para que la condición sea verdadera. Pero si utilizamos el OR sólo necesitamos que se cumpla una de las comparaciones para considerar que la condición se cumple.

Veamos un ejemplo de código


/*
Playground de ejemplo de condiciones compuestas
*/

let num1 = 10
let num2 = 20
var num3 = num2 / num1
var num4 = 2

if num1 < num2 && num3 == num4 { print("num1 es menor que num2 y num3 es igual que num4") } else { print("No se cumple la condición de num1 es menor que num2 y num3 es igual que num4") } // cambiamos el valor de num4 num4 = 4 if num1 < num2 && num3 == num4 { print("num1 es menor que num2 y num3 es igual que num4") } else { print("No se cumple la condición de num1 es menor que num2 y num3 es igual que num4") } // Cambiamos and por or if num1 < num2 || num3 == num4 { print("num1 es menor que num2 o num3 es igual que num4") } else { print("No se cumple la condición de num1 es menor que num2 o num3 es igual que num4") }

Al ejecutar este código obtendremos este resultado:

num1 es menor que num2 y num3 es igual que num4
No se cumple la condición de num1 es menor que num2 y num3 es igual que num4
num1 es menor que num2 o num3 es igual que num4

Conclusiones

En este artículo hemos aprendido lo siguiente:

  • Qué es un control de flujo
  • Qué es un ámbito en Swift
  • Cómo podemos comparar variables y valores
  • Cómo anidar y encadenar controles de flujo

El uso de los bloques de control de flujo son indispensables para poder crear aplicaciones que hagan algo más que mostrar valores por pantalla por lo que es muy importante dominar bien este aspecto de la programación.

Comentarios en AppleScript

La mayoría de lenguajes de programación incluyen algún mecanismo para que el programador pueda incluir anotaciones o comentarios en el código. Esto es necesario sobre todo si ese código va a crecer mucho, se va a compartir con otros programadores o se va a trabajar de nuevo en él tras cierto tiempo y tenemos que recordar qué hacía el código y por qué decidimos hacerlo así.

Ya vimos en el artículo de Hola mundo en AppleScript al detalle que AppleScript permite incluir comentarios. En este artículo lo veremos más en detalle.

En AppleScript podemos crear un comentario de una sola línea o un comentario que agrupe un conjunto de líneas consecutivas.

Para escribir un comentario de una sola línea debemos emplear el prefijo doble guión (--) delante del comentario. Todo lo que haya a la derecha de -- se ignorará por el intérprete de AppleScript.

Para escribir un bloque de comentario en AppleScript debemos encerrar el bloque de comentario con los símbolos abre paréntesis y asterisco ((*) y cierra paréntesis y asterisco (*)). Todo lo que esté entre (* y *) se ignorará por el intérprete de AppleScript.

Ejemplo de comentarios

En el siguiente ejemplo veremos los dos tipos de comentarios que podemos realizar dentro de un script de AppleScript.


(*
AppleScript de ejemplo
(CopyLeft) Tyflos Accessible Software 2018.

Este AppleScript no hace nada importante y es una excusa para enseñar cómo funcionan los comentarios en este lenguaje de scripting.

*)

on run
-- Comienzo del script
say "Hola a todos"
-- Una pequeña pausa y nos despedimos
delay 2
say "Esto no hace nada más"
-- Fin del script""
end run

Comentarios en Swift

Cuanto más conocemos Swift más complicado se vuelven nuestros Playgrounds. Es necesario ir incluyendo anotaciones o aclaraciones en nuestro código. Veamos el siguiente ejemplo.


let num1 = 54
let num2 = 235
var resultado = 0

// Almacenamos la multiplicacion de num1 y num2 en rsultado
resultado = num1 * num2
// y lo mostramos por consola
print("El resultado de \(num1) * \(num2) es \(resultado)")

El ejemplo mostrará el siguiente resultado:

El resultado de 54 * 235 es 12690

En el código anterior hemos encontrado unas líneas de código que comienzan por dos barras inclinadas (//) esto indica que todo lo que haya a la derecha de esas dos barras inclinadas es un comentario para ayudar a comprender mejor el código.

Los programadores usamos los comentarios para multitud de funciones: describir que hace o va a hacer un trozo de código, incluir un Copyright o copyleft en el código, añadir marcas o secciones en el fichero de código para marcar zonas y movernos más rápido por un fichero de código grande, etc.

Con las dos barras inclinadas (//) sólo podemos comentar una línea de código pero en Swift podemos comentar un bloque de líneas de código si las encerramos entre los símbolos /* y */. Veamos este código de ejemplo.


/*
Playground de pruebas
w≤ww.programaraciegas.net

(Copyleft) Tyflos Accessible Software 2017
*/

// Escribimos un saludo
print("Hola mundo!")

Si ejecutamos el código anterior en un Playground se ignorarán todas las líneas de comentario y sólo se ejecutará la función print().

Conclusiones

Es muy recomendable utilizar comentarios en nuestro código tanto para nosotros mismos por si visitamos nuestro código tras mucho tiempo o por si lo compartimos con otros desarrolladores.

También podemos utilizar los comentarios para desactivar o activar zonas de código que estemos probando.

Por estas y otras razones es muy necesario que tengamos el hábito de comentar nuestro código y saber utilizar las diversas formas de incluir comentarios en nuestro código.

Listas en AppleScript

En un artículo anterior ya vimos qué eran las variables en AppleScript y que, a semejanza de otros lenguajes de programación las había de varios tipos.

En este artículo nos centraremos en un tipo de variable que nos permite almacenar varios valores relacionados. Son las variables de tipo lista o conocidos en otros lenguajes de programación como array, vector o matriz de una dimensión.

Una lista es un conjunto de valores agrupados en un orden determinado. Este orden viene definido por el lugar que ocupa el elemento, llamado item, dentro de la lista.

Cada uno de los items de una lista puede ser de un tipo distinto. Esto significa que en una lista de 4 elementos el primero puede ser un texto, el segundo un número, el tercero otro texto y el cuarto el tipo que decidamos.

Para crear una lista se declara como una variable normal de AppleScript pero el conjunto de valores se agrupan entre llaves { (abre llave) y } (cierra llave) y separando los items con comas (,).

Veamos esto con un ejemplo. Vamos a almacenar en una variable todos los datos de contacto de una persona, para ello utilizamos una lista, y luego verbalizaremos toda la información del contacto. El código de nuestro script sería algo así:


on run
set contacto to {"Fulano", "de tal", 5.55123123E+8, "Calle falsa, 123, piso 4"}
say contacto as text
end run

La declaración de la lista es tan simple como la declaración de una variable en AppleScript.

En el ejemplo a la hora de verbalizar la información del contacto debemos convertir la variable de tipo lista a variable de tipo texto. Esto lo conseguimos con la sentencia as text. Si no lo hiciesemos así al intentar ejecutar el script optendríamos un error con un mensaje parecido a Error de script. No es posible convertir {«Fulano», «de tal», 5.55123123E+8, «Calle falsa, 123, piso 4»} en tipo text..

Accediendo a los items de una lista

Ya hemos indicado que los elementos de una lista se conocen como item y es así como nos vamos a referir en nuestro código para interactuar de forma individual con un elemento de una lista.

En AppleScript para acceder al valor de una propiedad de un objeto o a los items de una lista utilizamos el comando get indicando qué queremos obtener y de donde. El valor devuelto por get debe ser almacenado en una variable.

Veamos un ejemplo en el que en una lista de 5 números queremos obtener el que está en la cuarta posición de la lista. El código sería el siguiente:


on run
-- Declaramos una lista de 5 nmeros
set lista to {9, 2, 33, 1, 100}
-- Verbalizamos la lista
say lista as text
set valor to get item 4 of lista
say valor
end run

En una lista cuyos items sean de distinto tipo podemos usar el comando get para referenciar el item por su tipo y posición. Veamos esto mejor con un ejemplo: en una lista donde almacenamos el nombre y la edad de 3 personas queremos obtener el nombre de la tercera persona. Bien podríamos preguntar por el quinto elemento de la lista o por el tercer texto almacenado en la lista. El código sería el siguiente para este segundo caso:


on run
-- Declaramos una lista de 3 personas con su nombre y edad
set lista to {"Juan", 23, "Antonio", 38, "Manuel", 18}
-- Verbalizamos la lista
say lista as text
-- Obtenemos el tercer nombre de la lista
set valor to get text 3 of lista
say valor
-- Obtenemos la tercera edad de la lista
set valor to get integer 3 of lista
say valor
end run

Propiedades de las listas

Las listas al tratarse de un tipo especial de variable tiene una serie de propiedades y elementos para poder utilizarlas con comodidad. Estas propiedades nos permiten conocer, por ejemplo, el número de elementos que hay en la lista. En un artículo posterior hablaremos en más detalle sobre las propiedades en AppleScript

En el siguiente ejemplo veremos las propiedades length, rest, reverse y class.


on run
-- Declaramos una lista de 5 elementos
set lista to {1, 2, 3, 4, 5}
-- Verbalizamos la lista
say lista as text
-- Obtenemos la clase o tipo de variable que es lista
set tipo to get class of lista
say tipo
-- obtenemos cuantos elementos hay en la lista
set numElementos to get length of lista
say "La lista tiene"
say numElementos
say "elementos"
-- Damos la vuelta a la lista y la almacenamos en otra variable
set listaInversa to get reverse of lista
say listaInversa as text
-- Creamos una nueva lista pero sin el primer elemento de la lista inicial
set miniLista to get rest of lista
say miniLista as text
end run

En próximos artículos veremos más cosas sobre las listas en AppleScript.

Variables en Swift

A la hora de crear un programa o aplicación informática necesitamos poder almacenar, manipular, comparar y actualizar información. Para todas estas operaciones los lenguajes de programación utilizan un elemento conocido como variable. Una variable es una porción de memoria donde el programa almacena un valor indicado por el programador.

Las variables poseen un nombre con el que identificarlas y un tipo. El tipo define qué clase de información podrá almacenar la variable. A modo de ejemplo, imaginemos que tenemos diversos productos: agua, zapatos y naranjas y tenemos varios tipos de contenedores: caja de cartón, bolsa de plástico y botella de cristal. Cada contenedor es idóneo para un tipo de elemento concreto y podría ser perjudicial si introdujésemos un elemento en un contenedor no apropiado como meter agua en la caja de cartón o en la bolsa de plástico con algún posible agujero.

Declarando variables en Swift

En Swift, al igual que otros muchos lenguajes de programación necesitamos declarar las variables que vamos a utilizar para que el sistema pueda preparar la memoria del ordenador para almacenar la información que va a contener la variable. La forma de declarar una variable en Swift es utilizando la palabra var. La sintaxis completa es:

var nombreDeVariable : tipo = valorInicial

Ese valor inicial es obligatorio a menos que hagamos que nuestra variable sea de tipo opcional pero los tipos opcionales implican un concepto un poco complejo que se explicará más adelante en otros artículos donde tratemos con clases, objetos e instancias.

El tipo de la variable indica qué clase de información va a almacenar dicha variable: texto, números decimales, números enteros, un botón de nuestra interfaz, el dato de un contacto de nuestra agenda o un tipo que hayamos creado nosotros mismos.

Los tipos básicos en Swift son los siguientes:

String
Cadena de texto
Int
Número entero
Float
Número decimal
Double
Número decimal con más de 6 decimales
Bool
Valor booleano que almacena verdadero o falso

En Swift podemos dejar que el propio lenguaje deduzca el tipo de la variable, es lo que se denomina inferencia. Esto lo podemos hacer al declarar la variable y asignarle un valor sin indicar su tipo.

var miNombre = "Fulano de tal"

Una vez definido el tipo de una variable no podemos cambiar su tipo posteriormente por lo que hay que tener esto en cuenta a la hora de manipular las variables para cambiar sus valores.

Constantes en Swift

Una constante en programación es una variable que una vez declarada con su valor dicho valor no cambia en ningún momento. Ejemplos como el valor del número PI, la aceleración de la gravedad en la Tierra o el número máximo del nivel de vida del personaje jugador del juego que estamos programando son ejemplos de constantes en Swift.

Para declarar una constante se utiliza la palabra let y la sintaxis es la misma que para una variable.

let nombreDeConstante : tipo = valorParaLaConstante

También podemos utilizar la inferencia a la hora de declarar una constante.

let aceleracionGravedad = 9.8

En Swift, como en otros muchos lenguajes de programación el símbolo de coma numérica se indica con el signo . (punto) esto tanto para Float como Double como otros posibles tipos de números decimales

Utilizando variables

Una vez hemos declarado la variable podemos operar con ella simplemente nombrándola y realizando operaciones con ella. Por ejemplo:

Cambiando su valor:


var miVariable = 3
miVariable = 5

Combinando matematicamente varias variables:


var num1 = 3
var num 2 = 5
var num 3 = num1 + num2

Modificando una variable a partir de su valor anterior


var num1 = 5
num1 = num1 + 100

Visualizando el valor de una variable

Ya vimos en el artículo de primeros pasos con Swift el comando print. Por ahora utilizaremos dicho comando para ir viendo los diferentes valores de las variables en nuestros ejemplos.

La función print() nos permite mostrar una cadena de texto por la consola de depuración de xCode. Su sintaxis es muy sencilla:

print(variableDeTextoParaMostrar)

Ahora sólo debemos conocer cómo poder incluir en una variable de texto el valor de otras variables. La forma es muy sencilla. Recordemos que para poder declarar una cadena de texto debemos encerrar el valor de texto de nuestra variable entre los símbolos de dobles comillas ("). por ejemplo:


var miTexto = "Esto es un texto de prueba"
print(miTexto)

Si en nuestro Playground escribiesemos el código anterior obtendríamos el siguiente resultado por la consola de depuración:

Esto es un texto de prueba

Para incluir el valor de una variable dentro de una cadena de texto debemos utilizar una secuencia de escape que permita a xCode conocer nuestra intención de insertar en una posición concreta de la cadena de texto el valor de una variable. Esa secuencia de escape consiste en escribir barra invertida seguida de abre paréntesis y cierra paréntesis (\()). Por ejemplo, veamos el siguiente código:


var numero = 33
var texto = "Diga \(numero)"
print(texto)

Ejercicio de manipulación de variables

Vamos a poner en prática los conocimientos aprendidos hasta ahora y vamos a escribir un código en nuestro Playground que realice las siguientes operaciones:

  • Declarar 3 constantes con 3 valores numéricos distintos
  • Declarar una variable numérica para almacenar el resultado de las distintas operaciones
  • Sumar las dos primeras constantes y mostrar el resultado por consola
  • Al resultado anterior restarle la tercera constante y mostrarlo por consola
  • Al resultado anterior multiplicarlo por 100

Es muy recomendable que antes de ver la solución propuesta intentéis crear vuestro propio código.

La solución propuesta es la siguiente:


let num1 : Int = 3
let num2 : Int = 5
let num3 : Int = 6
var resultado = 0

resultado = num1 + num2
print("Operación 1 = \(resultado)")
resultado = num1 + num2 - num3
print("Operación 2 = \(resultado)")
resultado = resultado * 100
print("Operación 3 = \(resultado)")

El resultado que saldrá por consola será:

Operación 1 = 8
Operación 2 = 2
Operación 3 = 200

Si os fijáis para las constantes si hemos indicado el tipo pero para la variable de resultado hemos utilizado la inferencia.

Conclusiones

En este artículo hemos visto:

  • Cómo hacen las aplicaciones para almacenar y manipular información
  • Los requisitos de tipo a la hora de manipular información con variables
  • Las diferencias entre variables y constantes
  • Realizar operaciones matemáticas y almacenar los resultados
  • Introducir el valor de una variable dentro de una cadena de texto
  • Usar la función print() para algo más que saludar

Es necesario familiarizarse con el uso de variables en Swift si queremos progresar en este lenguaje de programación por lo que es muy recomendable que hagáis vuestros propios experimentos y recordad que dentro de un Playground no se romperá nada en tu ordenador por lo que podéis hacer todas las pruebas que queráis.