Track
/
jq
jq
/
Esercizi
/
Lasagna
Lasagna

Lasagna

Esercizio di apprendimento

Introduzione

Variabili

Ricorda che un programma jq è una pipeline di espressioni. L'assegnazione di variabile segue questa regola: un'assegnazione di variabile è un'espressione che ha questa forma:

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

L'output del filtro è l'input

Come per l'espressione di identità ., l'output dell'assegnazione di variabile è uguale al suo input. Impostare il valore della variabile è un effetto collaterale.

Ecco un esempio che mostra come . dopo l'assegnazione sia uguale all'input iniziale:

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

Lo scope delle variabili

Lo scope della variabile è «lessicale»: la variabile resterà nello scope per il resto della pipeline. Le variabili definite all'interno delle funzioni (arriveremo alle funzioni più avanti) sono «locali» alla funzione.

I nomi delle variabili

Il nome di una variabile deve iniziare con $. Il resto del nome della variabile è un identificatore: inizia con una lettera o un underscore, seguito da lettere, numeri o underscore.

Assegnazione destrutturante

Dal manuale:

Più variabili possono essere dichiarate con una singola espressione as, fornendo un pattern che corrisponde alla struttura dell'input (questa operazione è nota come «destrutturazione»).

Esempi:

[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]

Far coincidere il nome della variabile con la chiave dell'oggetto offre una scorciatoia:

{"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

La stessa scorciatoia funziona anche al contrario per la costruzione di oggetti

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

Le costanti

Come mostra l'esempio qui sopra, le variabili sono comode per memorizzare costanti. È meglio dare un nome alle costanti invece di lasciare che dei «numeri magici» compaiano nel codice.

Spesso le variabili non servono

Spesso è più leggibile omettere le variabili.

Prendiamo il calcolo della media di un array di numeri

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

rispetto a

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

Questo mette in luce uno degli aspetti più potenti di jq: l'input di un filtro viene fornito a ogni sottoespressione:

  • l'array di input [2,4,8,7] viene passato ad add (che somma i numeri applicando l'operatore + a tutti gli elementi)
  • in parallelo, [2,4,8,7] viene passato anche a length
  • quando queste sottoespressioni terminano, i loro risultati vengono divisi, restituendo il valore medio dei numeri nell'array di input.

Gli operatori di jq che ti serviranno per l'esercizio di apprendimento

L'operatore alternativo: //

L'espressione a // b produce b se a è false o null, altrimenti produce a. Nel contesto dell'assegnazione di una variabile, è molto comoda per fornire un valore predefinito:

(.input.theAnswer // 42) as $answer | ...
Gli operatori aritmetici
  • +, -, * sono i soliti operatori numerici di addizione, sottrazione e moltiplicazione.

Istruzioni

In questo esercizio scriverai un po' di codice per aiutarti a preparare una lasagna eccezionale, seguendo il tuo libro di ricette preferito.

Hai quattro compiti, tutti legati al tempo impiegato per cucinare la lasagna.

1. Definire il tempo di cottura previsto in minuti

Definisci una costante chiamata $expected_minutes_in_oven. Secondo il libro di ricette, il tempo di cottura previsto in minuti è 40:

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

2. Calcolare il tempo di cottura rimanente in minuti

Questo valore prende come input i minuti effettivi in cui la lasagna è rimasta nel forno e restituisce quanti minuti deve ancora rimanere la lasagna nel forno, in base al tempo di cottura previsto in minuti del compito precedente.

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

3. Calcolare il tempo di preparazione in minuti

Il tempo di preparazione è quanto ci vuole per preparare la lasagna prima di metterla nel forno. Servono 2 minuti per preparare ogni strato.

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

4. Calcolare il tempo di lavoro totale in minuti

Calcola quanti minuti in totale hai lavorato per cucinare la lasagna. È la somma del tempo di preparazione in minuti e del tempo in minuti che la lasagna ha trascorso nel forno fino a questo momento.

$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
  ...
  "total_time": 14,
  ...
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
jq Exercism

Vuoi iniziare Lasagna?

Iscriviti a Exercism per imparare e padroneggiare jq con 12 concetti75 esercizi e il mentoring di persone reali, tutto gratis.