Neste capitulo iremos nos aprofundar em Estruturas de Controle.
'if' e 'unless' são estruturas de controle que você pode usar no Elixir. Eles funcionam de maneira semelhante ao condicional 'if' e 'unless' em outras linguagens de programação. Aqui está como você pode usá-los:
A estrutura 'if' é usada para executar um bloco de código se uma condição for avaliada como verdadeira ou algum valor 'truthy'. Se a condição for avaliada como falsa ou algum valor 'falsy', o bloco de código não será executado.
if condition do
# Código a ser executado se a condição for verdadeira
end
Exemplo:
age = 25
if age >= 18 do
"Você é maior de idade."
end
age = 25
if age do
"Você é maior de idade."
end
condicao = false
if condicao do
"Você é maior de idade."
end
condicao = nil
if condicao do
"Você é maior de idade."
end
Observe que, se a condição for 'false' ou 'nil', o comando retorna 'nil', na ausência de uma cláusula 'else' (que veremos depois).
A estrutura 'unless' é mais ou menos o oposto do if. Ela é usada para executar um bloco de código se a condição for avaliada como falsa ou 'falsy'. Se a condição for avaliada como verdadeira ou 'truthy', 'nil' será retornado.
unless condition do
# Código a ser executado se a condição for falsa
end
Exemplo:
raining = false
unless raining do
"Não está chovendo."
end
raining = nil
unless raining do
"Não está chovendo."
end
raining = true
unless raining do
"Não está chovendo."
end
raining = :oi
unless raining do
"Não está chovendo."
end
Você também pode usar 'else' com 'if' e 'unless' para executar um bloco de código alternativo quando a condição não for atendida.
if condition do
# Código a ser executado se a condição for verdadeira
else
# Código a ser executado se a condição for falsa
end
Exemplo:
temperature = 28
if temperature > 30 do
"Está quente lá fora."
else
"Não está tão quente lá fora."
end
temperature = 35
if temperature > 30 do
"Está quente lá fora."
else
"Não está tão quente lá fora."
end
A mesma lógica se aplica ao 'unless' com 'else'.
temperature = 28
unless temperature > 30 do
"Está quente lá fora."
else
"Não está tão quente lá fora."
end
temperature = 35
unless temperature > 30 do
"Está quente lá fora."
else
"Não está tão quente lá fora."
end
No Elixir, você pode usar a macro 'cond' para criar uma estrutura de controle condicional que permite avaliar múltiplas condições e executar código com base na primeira condição verdadeira encontrada. A sintaxe básica do cond é a seguinte:
cond do
condition1 ->
# Código a ser executado se condition1 for verdadeira
condition2 ->
# Código a ser executado se condition2 for verdadeira
condition3 ->
# Código a ser executado se condition3 for verdadeira
true ->
# Código a ser executado se nenhuma das condições anteriores for verdadeira
end
Aqui estão alguns pontos-chave a serem observados sobre o cond no Livebook:
O cond avaliará as condições na ordem em que são declaradas e executará o código associado à primeira condição verdadeira encontrada. Se nenhuma das condições for verdadeira, o bloco de código associado a true será executado, se presente.
As condições são seguidas por uma seta (->) e, em seguida, o código a ser executado se a condição for verdadeira.
A última cláusula com true é opcional, mas é uma boa prática incluí-la para tratar casos em que nenhuma das condições anteriores é verdadeira.
Aqui está um exemplo de uso do cond no Livebook:
x = 5
cond do
is_number(x) and x == 0 ->
"x é igual a 0"
is_number(x) and x > 0 ->
"x é maior que 0"
is_number(x) and x < 0 ->
"x é menor que 0"
true ->
"Nenhuma das condições anteriores foi atendida"
end
Neste exemplo, o código verificará a condição x == 0 primeiro, que não é verdadeira, e, em seguida, verificará x > 0, que é verdadeira, portanto, imprimirá "x é maior que 0". Como a última cláusula com true está presente, ela não será executada neste caso.
Mude o valor de 'x' no código acima para 0 e -1 e reavalie, para ver o que acontece. Depois, mude 'x' para o átomo ':a' e reavalie.
Elixir fornece uma sintaxe alternativa para representar e trabalhar com literais. Um sigil (símbolo especial) vai começar com um til ~ seguido por um caractere. O núcleo do Elixir fornece-nos alguns sigils, no entanto, é possível criar o nosso próprio sigil quando precisamos estender a linguagem.
Uma lista de sigils disponíveis incluem:
- ~C Gera uma lista de caracteres sem escape ou interpolação
- ~c Gera uma lista de caracteres com escape e interpolação
- ~R Gera uma expressão regular sem escape ou interpolação
- ~r Gera uma expressão regular com escape e interpolação
- ~S Gera strings sem escape ou interpolação
- ~s Gera string com escape e interpolação
- ~W Gera uma lista sem escape ou interpolação
- ~w Gera uma lista com escape e interpolação
- ~N Gera uma NaiveDateTime struct
Uma lista de delimitadores inclui:
- <...> Um par de brackets
- {...} Um par de chaves
- [...] Um par de colchetes
- (...) Um par de parênteses
- |...| Um par de pipes
- /.../ Um par de barras
- "..." Um par de aspas duplas
- '...' Um par de aspas simples
Aqui estão alguns exemplos de como usar sigils no Livebook:
Você pode usar o sigil ~s para criar strings. O texto deve ser colocado entre colchetes {}. Por exemplo:
~s{Isso é uma string criada com sigil}
Isso retornará "Isso é uma string criada com sigil" na saída.
O sigil ~r permite criar expressões regulares. Você pode delimitar a expressão regular com barras /. Por exemplo:
# Esta expressão regular corresponde a um ou mais dígitos.
regex = ~r/\d+/
texto = "123 ABC 45 CDE"
Regex.scan(regex, texto)
Isso irá retornar uma lista de resultados. Cada resultado será uma lista contendo uma string que satisfaz à expressão regular, que espera caraceteres numéricos.
O sigil ~c permite criar caracteres. Você pode especificar um único caractere entre aspas simples '. Por exemplo:
~c'A'
Isso retornará "A".
O sigil ~w permite criar listas de palavra (strings) a partir de átomos, expressos sem os ":" iniciais. Você pode delimitar as palavras com espaços. Por exemplo:
~w(apple banana cherry)
No Elixir, você pode usar compreensões para criar listas ou outras estruturas de dados de maneira concisa e expressiva. Compreensões são uma característica poderosa em Elixir e podem ajudar a simplificar a criação e transformação de coleções de dados. Aqui estão algumas formas de usar compreensões:
Você pode criar listas usando compreensões de lista. A estrutura básica de uma compreensão de lista é a seguinte:
for pattern <- enumerable, filter, do: expression
- 'pattern' é uma variável que representa cada elemento da coleção 'enumerable'.
- 'enumerable' é uma coleção de dados, como uma lista, um mapa ou um conjunto.
- 'filter' (opcional) é uma condição que filtra os elementos da coleção.
- 'expression' é o valor que será incluído na lista resultante.
Exemplos:
lista = [1, 2, 3, 4, 5]
for x <- lista, do: x * x
lista = [1, 2, 3, 4, 5]
for x <- lista, x < 4, do: x * x
lista = [10, 2, 30, 4, 50]
for x <- lista, x > 3, x < 40, do: "#{x + 3}"
Você também pode usar compreensões para criar mapas. A estrutura básica de uma compreensão de mapa é semelhante à compreensão de lista:
for {key, value} <- enumerable, filter, do: {key, expression}
Exemplo:
mapa = %{"a" => 1, "b" => 2, "c" => 3}
triplica_valores = for {chave, valor} <- mapa, into: %{}, do: {chave, valor * 3}
Você pode aninhar compreensões dentro de outras compreensões para trabalhar com coleções mais complexas. Por exemplo, você pode criar uma lista de listas usando uma compreensão aninhada.
Exemplo:
matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
elementos_pares = for linha <- matriz, valor <- linha, rem(valor, 2) == 0, do: valor
Você pode usar guard clauses nas compreensões para aplicar condições adicionais aos elementos.
Exemplo:
lista = [1, 2, 3, 4, 5, 6]
pares_maiores_que_tres = for x <- lista, rem(x, 2) == 0, x > 3, do: x
Você é um desenvolvedor Elixir que trabalha para uma empresa de jogos chamada "ElixGames". A empresa está criando um jogo de aventura em que os jogadores exploram um mundo mágico cheio de criaturas misteriosas. Como parte do jogo, você precisa implementar uma função que determina o resultado de um encontro aleatório com uma criatura.
Aqui estão as regras para determinar o resultado do encontro:
- Se o jogador estiver em um "Bosque Encantado", ele tem 90% de chance de encontrar uma criatura amigável e 10% de chance de encontrar uma criatura hostil.
- Se o jogador estiver em uma "Caverna Escura", ele tem 60% de chance de encontrar uma criatura amigável e 40% de chance de encontrar uma criatura hostil.
- Se o jogador estiver em uma "Torre Misteriosa", ele tem 30% de chance de encontrar uma criatura amigável e 70% de chance de encontrar uma criatura hostil.
Sua tarefa é implementar um módulo em Elixir chamado ElixGames.Encontro
que forneça a função determina_encontro/2
, que aceita o local onde o jogador está e um número aleatório entre 1 e 100 (representando a probabilidade) como argumentos e retorna o resultado do encontro com a criatura com base nas regras acima.
Para completar esta tarefa, você precisará usar estruturas condicionais, como if
, unless
e cond
, para aplicar as regras corretamente e determinar se o jogador encontrará uma criatura amigável ou hostil com base no local e na probabilidade gerada aleatoriamente. Certifique-se de que a API (o nome do módulo, da função e suas assinaturas) seja respeitada, conforme especificado pela empresa "ElixGames".
defmodule ElixGames.Encontro do
def determina_encontro(localizacao, probabilidade) do
# Implemente a lógica de determinação do resultado do encontro aqui
end
end
Você recebeu uma lista de informações de clientes em formato de string, mas elas estão desorganizadas e precisam ser formatadas corretamente. Cada informação de cliente é separada por um ponto e vírgula (;) e contém os seguintes campos:
- Nome do cliente (entre aspas duplas).
- Idade do cliente (um número).
- Endereço de e-mail do cliente.
- Número de telefone do cliente.
A seguir está um exemplo de como as informações dos clientes estão atualmente:
"Fulano Tal",30,fulano@email.com,+5511995236587;"Ciclano Outro",25,ciclano@email.com,5545996578452
Dê uma olhada como sigils funcionam. Principalmente
~s
e~r
, leia também sobre expressões regulares.
Tarefas:
- Crie uma função chamada
parsear_clientes/1
que receba a string de informações de clientes e a divida em uma lista de informações de clientes formatadas. Use o sigil~s
para fazer isso.
def parsear_clientes(informacao) do
# A fazer
end
- Crie outra função chamada
extrair_nomes/1
que receba a lista de informações de clientes e retorne uma lista com os nomes dos clientes.
def extrair_nomes(clientes) do
# A fazer
end
# Caso a entrada fosse o exemplo na descrição deve imprimir ["Fulano Tal", "Ciclano Outro"]
- Crie uma terceira função chamada
filtrar_clientes_por_idade/2
que receba a lista de informações de clientes e uma idade mínima e retorne uma lista com as informações dos clientes que têm pelo menos a idade especificada.
def filtrar_clientes_por_idade(clientes, idade_minima) do
# A fazer
end
# Deveria imprimir [["Fulano Tal", 30, "[email protected]", "+5511995236587"]]
Você está trabalhando em uma empresa de e-commerce que vende produtos para pets. Você recebeu a tarefa de implementar uma função que calcula o valor total de uma compra, aplicando possíveis descontos de acordo com as regras de negócio. As regras são as seguintes:
- Se a compra for acima de R$ 200,00, o cliente ganha 10% de desconto.
- Se a compra for acima de R$ 500,00, o cliente ganha 15% de desconto.
- Se a compra for acima de R$ 1000,00, o cliente ganha 20% de desconto.
- Se o cliente for um membro do clube de fidelidade, ele ganha mais 5% de desconto em qualquer compra.
- Se o cliente usar o cupom "UBL10", ele ganha mais 10% de desconto em qualquer compra.
Você deve implementar uma função chamada calcula_total
que recebe uma lista de produtos e um mapa com as informações do cliente (se ele é membro do clube, se ele usou o cupom, etc) e retorna o valor total da compra com os descontos aplicados. Você pode usar funções de alta ordem para criar funções auxiliares que representam as regras de desconto e aplicá-las na lista de produtos. Cada produto é representado por um mapa com os campos :nome
, :preco
e :quantidade
. Por exemplo:
produtos = [
%{nome: "Ração para gatos", preco: 50.00, quantidade: 2},
%{nome: "Brinquedo para cachorro", preco: 30.00, quantidade: 1},
%{nome: "Aquário", preco: 200.00, quantidade: 1}
]
cliente = %{
membro_clube: true,
cupom: "UBL10"
}
calcula_total(produtos, cliente) # deve retornar 247.50
defmodule Ecommerce do
# A fazer
end