Lasaña

Lasaña

Ejercicio de aprendizaje

Introducción

Variables

Recuerda que un programa de jq es un pipeline de expresiones. La asignación de variables sigue esta regla: una asignación de variable es una expresión que se ve así:

... | expr as $varname | ...

La salida del filtro es la entrada

Al igual que la expresión de identidad ., la salida de la asignación de variable es la misma que su entrada. Establecer el valor de la variable es un efecto secundario.

Ejemplo que muestra que . después de la asignación es igual que la entrada inicial:

$ jq -c -n '42 | (. * 2) as $double | [., $double]'
[42,84]

Ámbito de las variables

El ámbito de la variable es «léxico»: la variable seguirá estando en el ámbito durante el resto del pipeline. Las variables definidas en funciones (ya llegaremos a las funciones más adelante) son «locales» a la función.

Nombres de variables

El nombre de la variable debe comenzar con $. El resto del nombre de la variable es un identificador: comienza con una letra o un guion bajo, seguidos de letras, números o guiones bajos.

Asignación por desestructuración

Del manual:

Se pueden declarar varias variables con una sola expresión as si proporcionas un patrón que coincida con la estructura de la entrada (esto se conoce como «desestructuración»).

Ejemplos:

[1, 2, 3] as [$a, $b, $c]
| [$a, $b, $c]     # => [1, 2, 3]
{"foo": "bar", "len": [10, 20]} as {foo: $f, len: [$h, $w]}
| [$f, $h, $w]     # => ["bar", 10, 20]

Hacer coincidir el nombre de la variable con la clave del objeto ofrece un atajo:

{"x": 4, "y": 7} as {$x, $y}
| [$x, $y]         # => [4, 7]
{"foo": "bar", "len": [10, 20]} as {$foo, $len}
| [$foo, $len]     # => ["bar", [10, 20]]
Note

El mismo atajo funciona en el sentido inverso para la construcción de objetos.

4 as $x | 7 as $y | {$x, $y}    # => {"x":4, "y": 7}

Constantes

Como se muestra en el ejemplo anterior, las variables son útiles para guardar constantes. Es mejor darle un nombre a las constantes en lugar de dejar que aparezcan «números mágicos» en el código.

Muchas veces las variables no son necesarias

A menudo es más legible omitir las variables.

Piensa en calcular el promedio de un array de números

[2, 4, 8, 7]
| add as $sum
| length as $len
| $sum / $len

en comparación con

[2, 4, 8, 7] | add / length

Esto resalta uno de los aspectos más potentes de jq: la entrada de un filtro se proporciona a todas las subexpresiones:

  • el array de entrada [2,4,8,7] se pasa a add (que suma los números aplicando el operador + a todos los elementos)
  • en paralelo, [2,4,8,7] también se pasa a length
  • cuando estas subexpresiones terminan, sus resultados se dividen, devolviendo el valor promedio de los números del array de entrada.

Operadores de jq que necesitarás para el ejercicio de aprendizaje

Operador alternativo: //

La expresión a // b da como salida b si a es false o null; en caso contrario, da como salida a. En el contexto de asignar una variable, esto es muy útil para proporcionar un valor predeterminado:

(.input.theAnswer // 42) as $answer | ...
Operadores aritméticos
  • +, -, * son los operadores habituales de suma, resta y multiplicación.

Instrucciones

En este ejercicio vas a escribir algo de código para ayudarte a preparar una lasaña espectacular usando tu libro de recetas favorito.

Tienes cuatro tareas, todas relacionadas con el tiempo que se tarda en cocinar la lasaña.

1. Define el tiempo esperado en el horno en minutos

Define una constante llamada $expected_minutes_in_oven. Según el libro de recetas, el tiempo esperado en el horno en minutos es 40:

$ jq -n -f lasagna.jq
{
  "expected_minutes_in_oven": 40,
  ...

2. Calcula el tiempo restante en el horno en minutos

Este valor toma como argumento los minutos reales que la lasaña ha estado en el horno y devuelve cuántos minutos le quedan aún por permanecer en el horno, según el tiempo esperado en el horno de la tarea anterior.

$ echo '{"actual_minutes_in_oven": 18}' | jq -f lasagna.jq
{
  "expected_minutes_in_oven": 40,
  "remaining_minutes_in_oven": 22,
  ...

3. Calcula el tiempo de preparación en minutos

El tiempo de preparación es lo que se tarda en dejar la lasaña lista antes de meterla en el horno. Se tarda 2 minutos en preparar cada capa.

$ echo '{"number_of_layers": 3}' | jq -f lasagna.jq
{
  ...
  "preparation_time": 6,
  ...

4. Calcula el tiempo total de trabajo en minutos

Calcula cuántos minutos en total has trabajado en cocinar la lasaña. Es la suma del tiempo de preparación en minutos y el tiempo en minutos que la lasaña ha pasado en el horno hasta el momento.

$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
  ...
  "total_time": 14,
  ...
Editar en GitHub El enlace se abre en una ventana o una pestaña nuevas
jq Exercism

¿Todo listo para empezar Lasaña?

Regístrate en Exercism para aprender y dominar jq con 12 conceptos75 ejercicios y mentoría humana real, todo gratis.