Crachás

Crachás

Exercício de aprendizagem

Introdução

Muitas linguagens têm uma forma, como null ou none, de indicar um valor inexistente. Como a Julia foi concebida para lidar com grandes volumes de dados (muitas vezes desorganizados), tem várias formas de representar o nada.

O objetivo geral é assinalar valores em falta ou suspeitos à medida que vão aparecendo e, depois, continuar sem lançar uma exceção.

nothing

Se um valor realmente não existe, é representado por nothing. É provavelmente o mais próximo do que o C (NULL) ou o Python (None) fazem.

julia> n = nothing

julia> isnothing(n)
true

julia> typeof(n)
Nothing

Assim, nothing é um valor singleton do tipo Nothing, e podemos testá-lo.

Um uso comum de nothing é como valor devolvido (ou não valor) para funções usadas apenas pelos seus efeitos secundários (imprimir, configurar a rede, ou o que quer que seja).

missing

Nas situações em que um valor existe em teoria, mas não sabemos qual é, usa-se missing. Por exemplo, ao contar veículos que circulam numa estrada, os observadores humanos podem precisar de uma pausa ou os sensores automáticos podem avariar, mas o trânsito continua a fluir.

Por isso, missing é um marcador de posição que avisa que é preciso decidir como lidar com essa falha nos dados.

julia> mv = [1, 2, missing]
3-element Vector{Union{Missing, Int64}}:
 1
 2
  missing

julia> typeof(mv)
Vector{Union{Missing, Int64}} (alias for Array{Union{Missing, Int64}, 1})

julia> ismissing.(mv)  # broadcast function, displays as 1 for true, 0 for false
3-element BitVector:
 0
 0
 1

Poucas outras linguagens têm esta funcionalidade incorporada, mas NA em R ou NULL em SQL são equivalentes próximos.

As expressões devolvem normalmente missing por predefinição se estiverem presentes valores missing. Se quiseres que estes valores sejam ignorados, usa a função skipmissing() para tornar isso explícito:

julia> mv = [1, 2, missing]
3-element Vector{Union{Missing, Int64}}:
 1
 2
  missing

julia> sum(mv)  # missing in, missing out
missing

julia> skipmissing(mv)
skipmissing(Union{Missing, Int64}[1, 2, missing])

julia> collect(skipmissing(mv))
2-element Vector{Int64}:
 1
 2

julia> sum(skipmissing(mv))  # functions like sum() can work with iterators
3

Como skipmissing cria um iterador, envolve-o em collect() se precisares de um vetor.

Por vezes, é útil substituir valores missing por um valor predefinido. A macro @coalesce() é útil para isto, pois devolve o primeiro valor não missing (ou missing se não houver mais nenhum).

julia> str = ["I", "exist", missing]
3-element Vector{Union{Missing, String}}:
 "I"
 "exist"
 missing

julia> [@coalesce(s, "-") for  s in str]
3-element Vector{String}:
 "I"
 "exist"
 "-"

NaN

Abreviatura de «não é um número», NaN assinala um problema de cálculo em situações em que se esperava um número.

julia> v = [0, 1, -1]
3-element Vector{Int64}:
  0
  1
 -1

julia> v / 0
3-element Vector{Float64}:
 NaN
  Inf
 -Inf
 
julia> sum(v / 0)
NaN

Qualquer tipo de cálculo sobre dados que incluam um NaN dá um resultado NaN.

Atualmente não existe uma função especial para remover valores NaN, mas a função padrão filter() consegue fazê-lo de forma bastante simples. Só os valores para os quais uma determinada condição é true são copiados para o array de resultado:

julia> filter(!isnan, [1, 2, NaN])
2-element Vector{Float64}:
 1.0
 2.0

Instruções

Neste exercício vais escrever código para criar crachás que os funcionários da fábrica vão usar. Os funcionários têm um ID, um nome e o nome do departamento. Os rótulos dos crachás dos funcionários têm o seguinte formato: "[id] - name - DEPARTMENT".

1. Criar um crachá para um funcionário

Implementa a função print_name_badge. Deve receber um ID, um nome e um departamento. Deve devolver o rótulo do crachá, com o nome do departamento em maiúsculas.

julia> print_name_badge(67, "Katherine Williams", "Strategic Communication")
"[67] - Katherine Williams - STRATEGIC COMMUNICATION"

2. Criar um crachá para um novo funcionário

Devido a uma particularidade do sistema informático, os novos funcionários às vezes ainda não têm um ID quando começam a trabalhar na fábrica. Como os crachás são obrigatórios, recebem um crachá temporário sem o prefixo do ID.

Estende a função print_name_badge. Quando o ID está em falta, deve criar um crachá sem ID.

julia> print_name_badge(missing, "Robert Johnson", "Procurement")
"Robert Johnson - PROCUREMENT"

3. Criar um crachá para o proprietário

Até o proprietário da fábrica tem de usar um crachá a toda a hora. No entanto, um proprietário não tem departamento, e nunca terá: está acima de todos os departamentos. Neste caso, o rótulo deve devolver "OWNER" em vez do nome do departamento.

Estende a função print_name_badge. Quando o departamento é nothing, assume que o crachá pertence ao proprietário da empresa.

julia> print_name_badge(204, "Rachel Miller", nothing)
"[204] - Rachel Miller - OWNER"

Repara que também é possível que o proprietário seja um novo funcionário.

julia> print_name_badge(missing, "Rachel Miller", nothing)
"Rachel Miller - OWNER"

4. Calcular o salário total dos funcionários sem ID

Como medida aproximada de quão bem estão a ser emitidos os IDs, queres ver o salário combinado dos funcionários sem ID. Um valor elevado significa que há muitos à espera, ou que o problema está a afetar funcionários mais antigos: as duas situações são más.

Implementa a função salaries_no_id, que recebe um vetor de IDs e um vetor correspondente de salários, e devolve a soma dos salários das pessoas que ainda não têm ID. Os dois vetores têm o mesmo comprimento.

julia> ids = [204, missing, 210, 352, missing, 263]
julia> salaries = [23, 21, 47, 35, 17, 101] * 1000
julia> salaries_no_id(ids, salaries)
38,000
Editar via GitHub A ligação abre numa nova janela ou separador
Julia Exercism

Estás pronto para começar Crachás?

Inscreve-te no Exercism para aprenderes e dominares Julia com 35 conceitos128 exercícios, e mentoria humana real, tudo grátis.