Lasanha

Lasanha

Exercício de aprendizagem

Introdução

Variáveis

Lembra-te de que um programa jq é um pipeline de expressões. A atribuição de variáveis segue esta regra: uma atribuição de variável é uma expressão com este aspeto:

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

O filtro devolve a entrada

Tal como a expressão de identidade ., a saída da atribuição de variável é igual à sua entrada. Definir o valor da variável é um efeito secundário.

Exemplo que mostra que ., depois da atribuição, é igual à entrada inicial:

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

Âmbito das variáveis

O âmbito da variável é «lexical»: a variável permanece no âmbito até ao fim do pipeline. As variáveis definidas em funções (falaremos de funções mais adiante) são «locais» à função.

Nomes das variáveis

A variável tem de começar por $. O resto do nome da variável é um identificador: começa por uma letra ou um underscore, seguido de letras, números ou underscores.

Atribuição com desestruturação

Do manual:

É possível declarar várias variáveis com uma única expressão as, fornecendo um padrão que corresponda à estrutura da entrada (isto é conhecido como «desestruturação»).

Exemplos:

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

Fazer corresponder o nome da variável à chave do objeto oferece um atalho:

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

O mesmo atalho funciona no sentido inverso para a construção de objetos

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

Constantes

Como se vê no exemplo acima, as variáveis são úteis para guardar constantes. É melhor dar um nome às constantes do que deixar «números mágicos» aparecerem no código.

Muitas vezes, as variáveis não são necessárias

Muitas vezes, omitir variáveis torna o código mais legível.

Considera o cálculo da média de uma lista de números

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

em comparação com

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

Isto realça um dos aspetos mais poderosos do jq: a entrada de um filtro é disponibilizada a todas as subexpressões:

  • o array de entrada [2,4,8,7] é passado a add (que soma os números aplicando o operador + a todos os elementos)
  • em paralelo, [2,4,8,7] também é passado a length
  • quando estas subexpressões terminam, os seus resultados são divididos, devolvendo o valor médio dos números do array de entrada.

Operadores de jq necessários para o exercício de aprendizagem

Operador alternativo: //

A expressão a // b produz b se a for false ou null; caso contrário, produz a. No contexto de definir uma variável, isto é muito útil para fornecer um valor por omissão:

(.input.theAnswer // 42) as $answer | ...
Operadores aritméticos
  • +, -, * são os habituais operadores numéricos de adição, subtração e multiplicação.

Instruções

Neste exercício vais escrever algum código para te ajudar a fazer uma lasanha fantástica a partir do teu livro de receitas preferido.

Tens quatro tarefas, todas relacionadas com o tempo gasto a cozinhar a lasanha.

1. Define o tempo esperado no forno em minutos

Define uma constante chamada $expected_minutes_in_oven. De acordo com o livro de receitas, o tempo esperado no forno é de 40 minutos:

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

2. Calcula o tempo restante no forno em minutos

Este valor recebe como valor de entrada os minutos reais que a lasanha já passou no forno e devolve quantos minutos a lasanha ainda tem de ficar no forno, com base no tempo esperado no forno em minutos da tarefa anterior.

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

3. Calcula o tempo de preparação em minutos

O tempo de preparação é quanto demora a preparar a lasanha antes de a colocar no forno. Demora 2 minutos a preparar cada camada.

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

4. Calcula o tempo total de trabalho em minutos

Calcula quantos minutos, no total, dedicaste a cozinhar a lasanha. É a soma do tempo de preparação em minutos com o tempo, em minutos, que a lasanha já passou no forno até agora.

$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
  ...
  "total_time": 14,
  ...
Editar via GitHub A ligação abre numa nova janela ou separador
jq Exercism

Estás pronto para começar Lasanha?

Inscreve-te no Exercism para aprenderes e dominares jq com 12 conceitos75 exercícios, e mentoria humana real, tudo grátis.