Powered by AppSignal & Oban Pro

Build FunPark: Model Real-World Data

chapters/chap_01_funpark.livemd

Build FunPark: Model Real-World Data

Mix.install([
  {:fun_park,
    git: "https://github.com/JKWA/funpark_notebooks.git",
    branch: "main"
  }
])

Advanced Functional Programming with Elixir

https://www.joekoski.com/assets/images/jkelixir_small.jpg” alt=”Book cover” width=”120” /> Interactive Examples from Chapter 1
Advanced Functional Programming with Elixir.

Define the Ride Model

Rides have core attributes: unique ID, name, height/age requirements, and can go offline. They also have experience tags like :dark, :thrill, or :water.

```elixir
defmodule FunPark.Ride do
  defstruct id: nil,
            name: "Unknown Ride",
            min_age: 0,
            min_height: 0,
            wait_time: 0,
            online: true,
            tags: []

  def make(name, opts \\ []) when is_binary(name) do
    %__MODULE__{
      id: :erlang.unique_integer([:positive]),
      name: name,
      min_age: Keyword.get(opts, :min_age, 0),
      min_height: Keyword.get(opts, :min_height, 0),
      wait_time: Keyword.get(opts, :wait_time, 0),
      online: Keyword.get(opts, :online, true),
      tags: Keyword.get(opts, :tags, [])
    }
  end
end
```

Create a family-friendly ride:

FunPark.Ride.make("Tea Cup", wait_time: 10, tags: [:family_friendly])

Create a more restricted ride:

dark_mansion = FunPark.Ride.make(
  "Dark Mansion",
  min_age: 14, 
  tags: [:dark]
)

Implement Fast Passes for Priority Access

FastPasses manage demand for popular rides. Each pass is tied to a specific ride and time.

```elixir
defmodule FunPark.FastPass do
  alias FunPark.Ride

  defstruct id: nil,
            ride: nil,
            time: nil

  def make(%Ride{} = ride, %DateTime{} = time) do
    %__MODULE__{
      id: :erlang.unique_integer([:positive]),
      ride: ride,
      time: time
    }
  end
end
```

Create a time:

datetime = DateTime.new!(~D[2025-06-01], ~T[13:00:00])

Create a fast pass for the Dark Mansion:

fast_pass = FunPark.FastPass.make(dark_mansion, datetime)

Model the Patrons

These are called “patrons”. Patrons have personal attributes, ticket tiers, fast passes, reward points, and preferences.

```elixir
defmodule FunPark.Patron do
  defstruct id: nil,
            name: nil,
            age: 0,
            height: 0,
            ticket_tier: :basic,
            fast_passes: [],
            reward_points: 0,
            likes: [],
            dislikes: []

  def make(name, age, height, opts \\ [])
      when is_bitstring(name) and
             is_integer(age) and
             is_integer(height) and
             age > 0 and
             height > 0 do
    %__MODULE__{
      id: :erlang.unique_integer([:positive]),
      name: name,
      age: age,
      height: height,
      ticket_tier: Keyword.get(opts, :ticket_tier, :basic),
      fast_passes: Keyword.get(opts, :fast_passes, []),
      reward_points: Keyword.get(opts, :reward_points, 0),
      likes: Keyword.get(opts, :likes, []),
      dislikes: Keyword.get(opts, :dislikes, [])
    }
  end
end
```

Create a patron named Alice with a FastPass:

FunPark.Patron.make("Alice", 15, 120, fast_passes: [fast_pass])