Lasagnes

Lasagnes

Exercice d'apprentissage

Introduction

Variables

Rappelle-toi qu'un programme jq est un pipeline d'expressions. L'affectation de variable suit cette règle : une affectation de variable est une expression qui ressemble à :

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

Le filtre renvoie l'entrée

Comme l'expression d'identité ., la sortie de l'affectation de variable est identique à son entrée. Définir la valeur de la variable est un effet de bord.

Exemple qui montre que . après l'affectation est identique à l'entrée initiale :

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

La portée des variables

La portée de la variable est « lexicale » : la variable reste dans la portée pour le reste du pipeline. Les variables définies dans des fonctions (on verra les fonctions plus tard) sont « locales » à la fonction.

Les noms de variables

Le nom de la variable doit commencer par $. Le reste du nom de la variable est un identifiant : il commence par une lettre ou un tiret bas, suivi de lettres, de chiffres ou de tirets bas.

L'affectation par déstructuration

D'après le manuel :

On peut déclarer plusieurs variables avec une seule expression as en fournissant un motif qui correspond à la structure de l'entrée (c'est ce qu'on appelle la « déstructuration »).

Exemples :

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

Faire correspondre le nom de la variable à la clé de l'objet offre un raccourci :

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

Le même raccourci fonctionne dans le sens inverse pour la construction d'objets

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

Les constantes

Comme le montre l'exemple ci-dessus, les variables sont pratiques pour stocker des constantes. Il vaut mieux donner un nom aux constantes plutôt que de laisser des « nombres magiques » apparaître dans le code.

Souvent, les variables ne sont pas nécessaires

Il est souvent plus lisible d'omettre les variables.

Prenons le calcul de la moyenne d'un tableau de nombres

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

comparé à

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

Cela met en évidence l'un des aspects les plus puissants de jq : l'entrée d'un filtre est fournie à chaque sous-expression :

  • le tableau d'entrée [2,4,8,7] est transmis à add (qui additionne les nombres en appliquant l'opérateur + à tous les éléments)
  • en parallèle, [2,4,8,7] est aussi transmis à length
  • quand ces sous-expressions se terminent, leurs résultats sont ensuite divisés, ce qui renvoie la moyenne des nombres du tableau d'entrée.

Les opérateurs jq dont tu auras besoin pour l'exercice d'apprentissage

L'opérateur alternatif : //

L'expression a // b renvoie b si a vaut false ou null, sinon elle renvoie a. Dans le contexte de l'affectation d'une variable, c'est très pratique pour fournir une valeur par défaut :

(.input.theAnswer // 42) as $answer | ...
Les opérateurs arithmétiques
  • +, - et * sont les opérateurs habituels d'addition, de soustraction et de multiplication numériques.

Instructions

Dans cet exercice, tu vas écrire du code pour t'aider à préparer une excellente lasagne tirée de ton livre de recettes préféré.

Tu as quatre tâches, toutes liées au temps passé à cuisiner la lasagne.

1. Définis le temps de cuisson prévu au four en minutes

Définis une constante nommée $expected_minutes_in_oven. D'après le livre de recettes, le temps de cuisson prévu au four est de 40 minutes :

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

2. Calcule le temps de cuisson restant en minutes

Cette valeur prend en entrée les minutes que la lasagne a déjà passées au four et renvoie le nombre de minutes qu'il lui reste à y passer, d'après le temps de cuisson prévu au four de la tâche précédente.

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

3. Calcule le temps de préparation en minutes

Le temps de préparation correspond au temps nécessaire pour préparer la lasagne avant de la mettre au four. Il faut 2 minutes pour préparer chaque couche.

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

4. Calcule le temps de travail total en minutes

Calcule le nombre total de minutes que tu as passées à cuisiner la lasagne. C'est la somme du temps de préparation en minutes et du temps que la lasagne a passé au four jusqu'à présent.

$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
  ...
  "total_time": 14,
  ...
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
jq Exercism

Prêt à commencer Lasagnes ?

Inscris-toi sur Exercism pour apprendre et maîtriser jq avec 12 concepts75 exercices, et un vrai mentorat humain, le tout gratuitement.