Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Beginner 2

src/livebook/beginner2.livemd

Beginner 2

Forberedelse

Boolske udtryk

Vi har sandhedsværdier (aka boolske værdier):

true
false

En sammenligning skaber en sandhedsværdi:

page_count = 108
long_book = page_count > 100

Der er særlige operatorer til at regne med dem:

reached_top = true
first = false
winner = reached_top and first
best = true
winner = first or best
looser = not winner

Disse udtryk kan kombineres:

looser = not (first or best)

Konstruktionerne if-do-else og if

Lad os tage udgangspunkt i en cirkel:

r = 12

Radius kan være negativ, nul eller positiv. Vi har ofte et behov for at håndtere flere af disse situationer på forskellige måder. Det kan vi eksempelvis gøre med en if konstruktion:

{:success, area} =
  if r<0 do
    {:error, :negative_radius}
  else
    {:success, :math.pi * r*r}
  end

Noter:

  • Navne der starter med et kolon er det der kaldes atomer. Deres rolle er at være lig sig selv og intet andet. Man kunne have erstattet dem med et unikt heltal, men fordi vi som mennesker kan lægge en fortolkning i navnet er dette lettere at læse.
  • Her bruger vi pattern matching til – i tilfælde af en success – at binde variablen area til resultatet af regnestykket. Hvis matchet fejler får vi en MatchError. Indtil videre er det fint med os. Elixir har mekanismer til at håndtere dette.

En anden variant af if konstruktionen mangler else delen. Den gør således kun noget hvis sandhedsværdien evaluerer til true. Dette benytter man ofte til at printe noget ud på skærmen:

if area > 180 do
  IO.puts("That's a big circle!")
end

Tekststrenge

En tekststreng (eller bare streng) er grundlæggende en sekvens af bogstaver. Vi vil ofte printe den ud ved hjælp af IO.puts. Det ser sådan her ud:

IO.puts("Hello, World")

Tekststrenge kan lægges sammen:

"Hello"<>", World"

Men vi kan også komponere dem ud fra eksistere navne og udtryk:

"En cirkel med radius #{r} har arealet #{:math.pi * r*r}!"

Nogle gange ønsker man at lave strenge på flere linjer. Det gøres bedst således:

s =
  """
  En cirkel med radius #{r} har ...
  - Arealet #{:math.pi * r*r}, og
  - Omkredsen #{2 * :math.pi * r}
  """
IO.puts(s)

Konstruktionen case

En if konstruktion har maksimalt to udfald, og valget imellem disse foretages på baggrund af en boolsk værdi. Det kan godt være ret begrænsende.

Det hyppigst benyttede alternativ er case konstruktionen, hvor én værdi sammenlignes med en række mønstre:

result = {:error, {:reason, "incompetence"}}

case result do
  {:error, :paper_jam} -> {:result, "printer is jamming"}
  {:error, {:code, 12}} -> {:result, "house on fire"}
  {:error, {:reason, reason}} -> {:result, "error due to reason '#{reason}'"}
  {:success, value} -> {:result, "succeeded with value #{value}"}
  _ -> {:result, "This matches anything"}
end

Øvelse

Prøv at scroll op til cellen hvor variablen r er defineret. Justér værdien for denne variable til -3 og evaluér den efterfølgende celle. Hvad sker der?

Vi er til en fødselsdagsfest med nogle deltagere:

participant_count = 13

Der er blevet lavet en lagkage. Det er lettest at skære lagkager ud hvis den skal fordeles på et lige antal tallerkener. Med udgangspunkt i variablen participant_count, tildel variablen easy en sandhedsværdi der reræsenterer om det er let at skære lakagen ud.

Bemærk: Funktionen rem returnerer resten af en division. rem(value, 2) returner derfor $1$ hvis value er ulige.

Brug en if konstruktion til enten at printe “Det er let” eller “Det er sværk” ud fra værdien af variablen easy:

Gør det samme med en case konstruktion:

Næste trin …

Når du er færdig går du til næste øvelse her.