O Crystal tem aquilo a que se chama expressões de controlo. Estas servem para controlar a forma como o programa corre e assumem um valor verdadeiro ou falso. Existem operadores que podem ser usados para criar valores verdadeiros ou falsos: os operadores de igualdade e de comparação.
Existem duas expressões de controlo principais que determinam que código é executado e que código não é. Por outras palavras, que ramo é que corre.
Essas duas são: a expressão if e a expressão unless.
Os operadores de comparação são usados para comparar valores e devolver um valor true ou false.
Estes operadores exigem que sejam comparados dois valores do mesmo tipo.
Se os valores não forem do mesmo tipo, o compilador dá um erro.
Aqui está uma lista dos operadores de comparação e um exemplo de quando devolvem um valor true:
| Método | Descrição | Exemplo |
|---|---|---|
| < | menor que | 4 < 5 |
| <= | menor ou igual que | 4 <= 4 |
| > | maior que | 3 > 1 |
| >= | maior ou igual que | 2 >= 2 |
Os operadores de igualdade são semelhantes aos operadores de comparação, mas são usados para verificar se dois valores são iguais ou não.
O operador == verifica se dois valores são iguais, incluindo o tipo do valor.
Se os valores forem iguais, devolve true; caso contrário, devolve false.
O operador == pode comparar qualquer tipo de valor com qualquer outro tipo de valor.
O != funciona da mesma forma, mas devolve true se os valores não forem iguais e false se forem iguais.
A condicional if é usada para verificar se uma determinada condição é verdadeira ou falsa.
Se a condição for verdadeira, o código dentro da condicional if é executado.
Uma condicional if termina com a palavra-chave end.
if 1 == 1
puts "1 is equal to 1"
end
# => 1 is equal to 1
if 1 > 2
puts "1 is greater than 2"
end
# => no output
A condicional unless funciona de forma muito semelhante à condicional if, mas executa o código dentro da condicional unless se a condição for falsa.
unless 1 == 1
puts "1 is not equal to 1"
end
# => no output
unless 1 > 2
puts "1 is not greater than 2"
end
# => 1 is not greater than 2
A instrução else pode ser usada em conjunto com as condicionais if e unless.
A instrução else é executada se o ramo do if ou o ramo do unless não for executado.
Embora um ramo `else` possa ser usado em conjunto com `unless,` isso é desaconselhado porque prejudica a legibilidade.
Em vez disso, recomenda-se usar `if !condition` com um ramo else.
if 1 == 1
puts "1 is equal to 1"
else
puts "1 is not equal to 1"
end
# => 1 is equal to 1
unless 1 < 2
puts "1 is not greater than 2"
else
puts "1 is greater than 2"
end
# => 1 is greater than 2
A instrução elsif pode ser usada em conjunto com a condicional if.
A instrução elsif é executada se o ramo do if não for executado e a condição da instrução elsif for verdadeira.
As instruções elsif podem ser encadeadas e a primeira condição verdadeira é a que é executada.
Também pode haver uma instrução else no fim da condicional if, que corre se nenhuma das instruções anteriores tiver sido verdadeira.
if 1 != 1
puts "1 is not equal to 1"
elsif 1 > 2
puts "1 is greater than 2"
else
puts "1 is not equal to 1 and 1 is not greater than 2"
end
# => 1 is not equal to 1 and 1 is not greater than 2
Quando é atribuída a tipos diferentes, a variável passa a ter os dois tipos. Isto acontece porque o compilador não sabe que ramo será executado. Esta atribuição múltipla, também conhecida como união, será explicada em conceitos posteriores. Podes ver isto no exemplo seguinte:
if 1 == 1
a = 1
else
a = "1"
end
typeof(a) # => Int32 | String
O Crystal tem um operador ternário, uma instrução if-else de uma só linha: condition ? expression_if_truthy : expression_if_falsey
1 == 1 ? puts("1 is equal to 1") : puts("1 is not equal to 1")
# => 1 is equal to 1
Neste exercício, vamos desenvolver um sistema de controlo simples para um reator nuclear.
Para um reator produzir potência, tem de estar num estado de criticidade. Se o reator estiver num estado abaixo da criticidade, pode ficar danificado. Se o estado do reator ultrapassar a criticidade, pode sobrecarregar e provocar uma fusão do núcleo. Queremos reduzir a probabilidade de fusão do núcleo e gerir corretamente o estado do reator.
As três tarefas seguintes estão todas relacionadas com a escrita de código para manter o estado ideal do reator.
A primeira coisa que um sistema de controlo tem de fazer é verificar se o reator está equilibrado na criticidade. Diz-se que um reator está crítico se cumprir as seguintes condições:
Implementa o método Reactor.criticality_balanced?, que recebe temperature, medida em kelvin, e neutrons_emitted como parâmetros, e devolve true se as condições de criticidade forem cumpridas, e false caso contrário.
Reactor.criticality_balanced?(750, 600)
# => true
Assim que o reator começa a produzir potência, é preciso determinar a sua eficiência. A eficiência pode ser agrupada em 4 faixas:
green -> eficiência de 80% ou mais,orange -> eficiência inferior a 80%, mas de pelo menos 60%,red -> eficiência abaixo de 60%, mas ainda 30% ou mais,black -> eficiência inferior a 30%.O valor percentual pode ser calculado como (generated_power/theoretical_max_power)*100, em que generated_power = voltage * current.
Tem em atenção que o valor percentual normalmente não é um número inteiro, por isso certifica-te de que usas corretamente as comparações < e <=.
Implementa o método Reactor.reactor_efficiency, com três parâmetros: voltage, current e theoretical_max_power.
Esta função deve devolver a faixa de eficiência do reator: "green", "orange", "red" ou "black".
Reactor.reactor_efficiency(200,50,15000)
# => "orange"
A tua última tarefa consiste em criar um mecanismo à prova de falhas para evitar a sobrecarga e a fusão do núcleo. Este mecanismo vai determinar se o reator está abaixo, no, ou acima do limiar ideal de criticidade. A criticidade pode então ser aumentada, diminuída ou interrompida inserindo (ou removendo) barras de controlo do reator.
Implementa o método Reactor.fail_safe(), que recebe 3 parâmetros: temperature, medida em kelvin, neutrons_produced_per_second e threshold, e devolve um código de estado para o reator.
Se temperature * neutrons_produced_per_second for inferior a 90% de threshold, devolve o código de estado "LOW", que indica que é preciso remover as barras de controlo para produzir potência.
Se temperature * neutrons_produced_per_second estiver dentro de mais ou menos 10% de threshold, o reator está em criticidade e deve ser devolvido o código de estado "NORMAL", que indica que o reator está em condições ótimas e que as barras de controlo estão numa posição ideal.
Se temperature * neutrons_produced_per_second não estiver dentro dos intervalos acima indicados, o reator vai entrar em fusão do núcleo e é preciso passar o código de estado "DANGER" para desligar imediatamente o reator.
temperature = 1000
neutrons_produced_per_second = 30
threshold = 5000
Reactor.fail_safe(temperature, neutrons_produced_per_second, threshold)
# => "DANGER"
Inscreve-te no Exercism para aprenderes e dominares Crystal com 26 conceitos142 exercícios, e mentoria humana real, tudo grátis.