Percursos
/
jq
jq
/
Exercícios
/
Compra de veículo
Compra de veículo

Compra de veículo

Exercício de aprendizagem

Introdução

Comparar

Comparar números

Em jq, os números podem ser comparados com os seguintes operadores relacionais e de igualdade.

Comparação Operador
Maior que a > b
Maior ou igual a a >= b
Menor que a < b
Menor ou igual a a <= b
Igual a a == b
Diferente de a != b

O resultado da comparação é sempre um valor boolean, ou seja, true ou false.

1 < 3,      # => true
2 != 2,     # => false
1 == 1.0    # => true
            # All numbers are floating-points, so this is different syntax
            # for the exact same value.

Comparar strings

Os operadores de comparação acima também podem ser usados para comparar strings. Nesse caso, aplica-se uma ordem de dicionário (lexicográfica). A ordenação é pelo valor do ponto de código Unicode.

"Apple" > "Pear",   # => false
"a" < "above",      # => true
"a" == "A"          # => false

Tens de ter cuidado quando comparas duas variáveis que parecem conter valores numéricos mas são do tipo string. Devido à ordem de dicionário, o resultado não será o mesmo que comparar valores do tipo number.

10 < 2,     # => false
"10" < "2"  # => true (because "1" comes before "2")

Igualdade "estrita"

O operador == do jq é como o === do Javascript, no sentido em que coisas que "parecem" iguais mas são de tipos diferentes não são iguais.

"3" == 3    # => false
            # the value on the left has type string,
            # the value on the right has type number.

Comparar arrays

Dois arrays são iguais se todos os elementos correspondentes forem iguais.

[1, 2, 3] == [1, 2, 3]      # => true
[1, 2, 3] == [1, 3, 2]      # => false, different order
[1, 2, 3] == [1, 2, "3"]    # => false, different types

Comparar objetos

Dois objetos são iguais se tiverem os mesmos pares chave-valor.

{name: "Joe", age: 42} == {age: 42, name: "Joe"}                # => true
{name: "Joe", age: 42} == {age: 42, name: "Jane"}               # => false
{name: "Joe", age: 42} == {age: "42", name: "Joe"}              # => false
{name: "Joe", age: 42} == {age: 42, name: "Joe", height: 175}   # => false

# comparisons will drill down as deeply as required
{a: {b: {c: [1, 2]}}} == {a: {b: {c: [1, 2]}}}                  # => true
{a: {b: {c: [1, 2]}}} == {a: {b: {c: [1, 2, 3]}}}               # => false

Condicionais

Expressão if

A expressão condicional do jq é if A then B else C end.

O if-then-else é um filtro, como todos os builtins do jq: recebe um valor e produz um valor.

Se a expressão A produzir um valor "truthy", o filtro if avalia B. Caso contrário, avalia C. O valor de entrada do filtro if é passado a B ou a C.

42 | if . < 50 then "small" else "big" end      # => "small"
5 | if . % 2 == 0 then . / 2 else . * 4 end     # => 20
Note

A cláusula else é opcional; as duas instruções seguintes são equivalentes.

if A then B else . end
if A then B end

Condicionais aninhados

Podes acrescentar mais condições com elif.

42 | if . < 33 then "small"
     elif . < 66 then "medium"
     else "big"
     end
# => "medium"

Usa tantas cláusulas elif quantas precisares.

Veracidade

Os únicos valores "falsos" em jq são: false e null. Tudo o resto é "verdadeiro", até mesmo o número zero e a string, o array e o objeto vazios.

Operadores Boolean

Os operadores Boolean and e or podem ser usados para construir consultas complexas.

42 | if . < 33 or . > 66 then "big or small"
     else "medium"
     end

Para negar, usa not. Isto é um filtro, não um operador.

42 | if (. < 33 or . > 66 | not) then "medium"
     else "big or small"
     end

Operador alternativo

O operador alternativo permite-te especificar um valor "por omissão" se uma expressão for false ou null.

A // B

# This is identical to
if A then A else B end

Para demonstrar:

[3, 5, 18] | add / 2       # => 13
[]         | add / 2       # => error: null (null) and number (2) cannot be divided
[]         | add // 0 / 2  # => 0

Instruções

Neste exercício, vais escrever algum código para te ajudar a preparar-te para comprar um veículo.

Tens três tarefas: determinar se vais precisar de tirar a carta de condução; escolher entre dois veículos; e estimar o preço aceitável para um veículo usado.

1. Determina se vais precisar de carta de condução

Alguns tipos de veículos exigem carta de condução para os conduzir. Assume que apenas os tipos "car" e "truck" exigem carta; tudo o resto pode ser conduzido sem carta.

Implementa a função needs_license, que recebe o tipo de veículo e devolve um Boolean que indica se precisas de carta para esse tipo de veículo.

"car" | needs_license
# => true

"bike" | needs_license
# => false

2. Escolhe entre dois veículos potenciais para comprar

Já avaliaste as opções de veículos que tens disponíveis. Conseguiste reduzi-las a duas opções, mas precisas de ajuda para tomar a decisão final. Implementa a função choose_vehicle, que recebe como parâmetro de entrada um array de dois veículos e devolve uma decisão, que é a opção que vem primeiro na ordem alfabética.

["Wuling Hongguang", "Toyota Corolla"] | choose_vehicle
# =>  "Toyota Corolla is clearly the better choice."

["Volkswagen Beetle", "Volkswagen Golf"] | choose_vehicle
# =>  "Volkswagen Beetle is clearly the better choice."

3. Calcula uma estimativa para o preço de um veículo usado

Agora que tomaste a tua decisão, queres garantir que consegues um preço justo no concessionário. Como estás interessado em comprar um veículo usado, o preço depende da idade do veículo. Para uma estimativa aproximada, assume que, se o veículo tiver menos de 3 anos, custa 80% do preço original que tinha quando era novo. Se tiver mais de 10 anos, custa 50%. Se o veículo tiver pelo menos 3 anos, mas não mais de 10, custa 70% do preço original.

Implementa a função resell_price, que aplica esta lógica com if, elif e else. Recebe um objeto com o preço original e a idade do veículo e devolve o preço estimado no concessionário.

{"original_price": 1000, "age": 1} | resell_price
# => 800

{"original_price": 1000, "age": 5} | resell_price
# => 700

{"original_price": 1000, "age": 15} | resell_price
# => 500
Editar via GitHub A ligação abre numa nova janela ou separador
jq Exercism

Estás pronto para começar Compra de veículo?

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