We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Act on It
So now we want to add in more functionality for the Ride and Patron.
For a Patron context we want to have a recommended that will check for rides to avoid, and rides they want to ride on. It will use the tags from Patron.likes and Patron.dislikes.
# lib/fun_park/patron.ex
def get_likes(%__MODULE__{likes: likes} = patron), do: likes
def get_dislikes(%__MODULE__{dislikes: dislikes} = patron), do: dislikes
def add_likes(%__MODULE__{} = patron, likes) when is_list(likes) do
updated_likes = List.union(likes, get_likes(patron))
updated_dislikes = List.difference(get_dislikes(patron), likes)
change(patron, %{likes: updated_likes, dislikes: updated_dislikes})
end
def add_dislikes(%__MODULE__{} = patron, dislikes) when is_list(dislikes)do
updated_likes = List.union(dislikes, get_dislikes(patron))
updated_dislikes = List.difference(get_likes(patron), dislikes)
change(patron, %{likes: updated_likes, dislikes: updated_dislikes})
end
def remove_likes(%__MODULE__{} = patron, likes) when is_list(likes) do
updated_likes = List.difference(get_likes(patron), likes)
change.(patron, %{likes: updated_likes})
end
def remove_dislikes(%{__MODULE__} = patron, dislikes) when is_list(dislikes) do
updated_dislikes = List.difference(get_dislikes(patron, dislikes))
change(patron, %{dislikes: dislikes})
end
def likes_ride(%__MODULE__{likes: likes}, %Ride{} = ride) do
Ride.has_any_tag?(ride, dislikes)
end
def dislikes_ride(%__MODULE__{dislikes: dislikes}, %Ride{} = ride) do
Ride.has_any_tag(ride, dislikes)
end
def recommended?(%__MODULE__{} = patron, %Ride{} = ride) do
p_all([
curry(&likes_ride?/2).(patron),
p_not(curry(&dislikes_ride?/2).(patron)),
curry(&Ride.suggested?/2).(patron)
]).(ride)
end
For the Ride context, not much will change we will need to check against online? and not long_wait? which we already do.
So I added in some functionality for this new set of codes that will work to add and remove dislikes, also added in some functionality that will help to determine if there is any tags in the ride that person wants to ride. Let’s test it out.
Test It
iex(26)> family_ride = FunPark.Ride.make("family_ride", [min_age: 10, min_height: 40, wait_time: 40, online: true, tags: [:family]])
%FunPark.Ride{
id: 143,
name: "family_ride",
min_age: 10,
min_height: 40,
wait_time: 40,
online: true,
tags: [:family]
}
iex(27)> scary_ride = FunPark.Ride.make("scary_ride", [min_age: 10, min_height: 40, wait_time: 40, online: true, tags: [:scary]])
%FunPark.Ride{
id: 207,
name: "scary_ride",
min_age: 10,
min_height: 40,
wait_time: 40,
online: true,
tags: [:scary]
}
iex(28)> long_ride = FunPark.Ride.make("long_ride", [min_age: 10, min_height: 40, wait_time: 110, online: true, tags: []])
%FunPark.Ride{
id: 78,
name: "long_ride",
min_age: 10,
min_height: 40,
wait_time: 110,
online: true,
tags: []
}
iex(29)> beth = FunPark.Patron.make("beth", 15, 50, [likes: [:family], dislikes: [:scary]])
%FunPark.Patron{
id: 142,
name: "beth",
age: 15,
height: 50,
ticket_tier: :basic,
fast_passes: [],
reward_points: 0,
likes: [:family],
dislikes: [:scary]
}
iex(30)> alice = FunPark.Patron.make("alice", 15, 50, [likes: [:scary], dislikes: [:family]])
%FunPark.Patron{
id: 206,
name: "alice",
age: 15,
height: 50,
ticket_tier: :basic,
fast_passes: [],
reward_points: 0,
likes: [:scary],
dislikes: [:family]
}
iex(31)> too_short = FunPark.Patron.make("2 short", 15, 20, [likes: [:scary, :family]])
%FunPark.Patron{
id: 270,
name: "2 short",
age: 15,
height: 20,
ticket_tier: :basic,
fast_passes: [],
reward_points: 0,
likes: [:scary, :family],
dislikes: []
}
ex(34)> rides = [
...(34)> scary_ride,
...(34)> family_ride,
...(34)> long_ride
...(34)> ]
[
%FunPark.Ride{
id: 207,
name: "scary_ride",
min_age: 10,
min_height: 40,
wait_time: 40,
online: true,
tags: [:scary]
},
%FunPark.Ride{
id: 143,
name: "family_ride",
min_age: 10,
min_height: 40,
wait_time: 40,
online: true,
tags: [:family]
},
%FunPark.Ride{
id: 78,
name: "long_ride",
min_age: 10,
min_height: 40,
wait_time: 110,
online: true,
tags: []
}
]
iex(35)> FunPark.Patron.recommended?(alice, long_ride)
false
iex(36)> FunPark.Patron.recommended?(alice, scary_ride)
false
iex(37)> FunPark.Patron.recommended?(alice, family_ride)
false
iex(38)> FunPark.Patron.recommended?(beth, long_ride)
false
iex(39)> FunPark.Patron.recommended?(beth, scary_ride)
false
iex(40)> FunPark.Patron.recommended?(beth, family_ride)
false
iex(55)> family_ride = FunPark.Ride.change(family_ride, %{wait_time: 20})
%FunPark.Ride{
id: 143,
name: "family_ride",
min_age: 10,
min_height: 40,
wait_time: 20,
online: true,
tags: [:family]
}
iex(56)> scary_ride = FunPark.Ride.change(scary_ride, %{wait_time: 20})
%FunPark.Ride{
id: 207,
name: "scary_ride",
min_age: 10,
min_height: 40,
wait_time: 20,
online: true,
tags: [:scary]
}
iex(57)> FunPark.Patron.recommended?(beth, long_ride)
false
iex(58)> FunPark.Patron.recommended?(beth, family_ride)
true
iex(59)> FunPark.Patron.recommended?(beth, scary_ride)
false
iex(60)> FunPark.Patron.recommended?(alice, long_ride)
false
iex(61)> FunPark.Patron.recommended?(alice, family_ride)
false
iex(62)> FunPark.Patron.recommended?(alice, scary_ride)
true
iex(63)> FunPark.Patron.recommended?(too_short, long_ride)
false
iex(64)> FunPark.Patron.recommended?(too_short, family_ride)
false
iex(65)> FunPark.Patron.recommended?(too_short, scary_ride)
false
That works for all the rides tested singularly, let’s add in recommended_rides/2 that will test a list of rides.
def recommended_rides(%___MODULE__{} = patron, rides) do
Enum.filter(rides, &recommended?(patron, &1))
end
Now we can test the new function
iex(68)> rides = [
...(68)> scary_ride,
...(68)> family_ride,
...(68)> long_ride
...(68)> ]
[
%FunPark.Ride{
id: 207,
name: "scary_ride",
min_age: 10,
min_height: 40,
wait_time: 20,
online: true,
tags: [:scary]
},
%FunPark.Ride{
id: 143,
name: "family_ride",
min_age: 10,
min_height: 40,
wait_time: 20,
online: true,
tags: [:family]
},
%FunPark.Ride{
id: 78,
name: "long_ride",
min_age: 10,
min_height: 40,
wait_time: 110,
online: true,
tags: []
}
]
iex(69)> FunPark.Patron.recommended_rides(beth, rides)
[
%FunPark.Ride{
id: 143,
name: "family_ride",
min_age: 10,
min_height: 40,
wait_time: 20,
online: true,
tags: [:family]
}
]
iex(70)> FunPark.Patron.recommended_rides(alice, rides)
[
%FunPark.Ride{
id: 207,
name: "scary_ride",
min_age: 10,
min_height: 40,
wait_time: 20,
online: true,
tags: [:scary]
}
]
iex(71)> FunPark.Patron.recommended_rides(too_short, rides)
[]