Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
elm-stuff
83 changes: 83 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,86 @@ We want to see:
## Submitting your solution

Please submit your solution as a PR including some nice commits for challenge 1 and the rest in Markdown.

# Answers - Suzanne Wood

# 1. Deduplicate

To run tests:
`npx elm-test`

# 2. Cars

Schema for tables:

CREATE TABLE `car` (
`id` int not null PRIMARY KEY,
`lender_id` int not null
);
CREATE TABLE `car_availability` (
`id` int not null PRIMARY KEY,
`car_id` int not null,
`from` datetime not null,
`to` datetime not null
);
CREATE TABLE `user` (
`id` int not null PRIMARY KEY
);
CREATE TABLE `user_bookings` (
`id` int not null PRIMARY KEY,
`user_id` int not null,
`car_id` int not null,
`from` datetime not null,
`to` datetime not null
);

I would also add indices depending on what common queries are needed.




Relations:
- each card belongs to a lender, a lender can lend multiple cars
- car availability has slots which do not touch or overlap (these can be combined if they come up when adding)
- no two user bookings for the same car_id can overlap

Query for finding available cars for a timeslot 'from', 'to' (pseudocode)

select c.id as car_id, count(ub.id where ub.id is not null) as overlapping_bookings
from cars c join
car_availability ca on c.id = ca.car_id join
user_bookings ub on (
ub.id = ca.user_id and
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ub.car_id = ca.id ?

!((ub.from <= {from} and ub.to <= {to}) or
(ub.from >= {from} and ub.to >= {to})) # excluding non-overlapping slots
)
where
ca.from <= {from} and ca.to >= {to}
group by c.id
having count(ub.id) = 0

Comparison with other solutions:
You could simplify the approach using discrete timeslots whether by hour, by day etc - but the one I outlined allows high flexibility of timeslots. I also considered storing available timeslots with bookings subtracted, already showing a complete availability picture but it becomes messy to manage, makes more sense to keep availability and bookings seperate and then layer them up when querying



# 3. Frontops

I would use a docker file with two FROM statements e.g.

FROM xxxx as staging
WORKDIR xxx
RUN xxx
COPY xxx
RUN xxx

FROM xxxx as production
WORKDIR xxx
RUN xxx
COPY --from=staging
RUN xxx

This also enables deploying just staging by e.g. running `docker build --target staging `
I would have config files with ENV variables for each environment so when running for a different FQDN in eg staging I would change in the staging config file

For a change in API, it depends how the API change is rolled out. For example, if it was via a new FQDN I'd change that and any code changes needed for staging only and once tested move to production. If the API change is known to be sudden with no way to roll over, if possible I'd make the code be able to handle both versions for the transition.
28 changes: 28 additions & 0 deletions elm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.2"
}
},
"test-dependencies": {
"direct": {
"elm-explorations/test": "1.2.2"
},
"indirect": {
"elm/random": "1.0.0"
}
}
}
15 changes: 15 additions & 0 deletions src/Deduplicator.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Deduplicator exposing (deduplicate)


deduplicate : List String -> List String
deduplicate words =
List.foldl addToListIfNotMatch [] (List.sort words)

addToListIfNotMatch : String -> List String -> List String
addToListIfNotMatch element partialList =
if Just element /= List.head partialList then
element :: partialList

else
partialList

35 changes: 35 additions & 0 deletions tests/DeduplicatorTest.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module DeduplicatorTest exposing (..)

import Deduplicator
import Expect
import Test exposing (..)


suite : Test
suite =
describe "The Deduplicator module"
[ describe "Deduplicator.deduplicate"
-- Nest as many descriptions as you like.
[ test "returns an identical list for an list of length 1" <|
\_ ->
let
words =
[ "fish" ]
in
Expect.equal words (Deduplicator.deduplicate words)
, test "returns an identical list for an list of length 0" <|
\_ ->
let
words =
[]
in
Expect.equal words (Deduplicator.deduplicate words)
, test "returns a deduplicated list" <|
\_ ->
let
words =
[ "fish", "chip", "egg", "fish", "egg" ]
in
Expect.equal [ "fish", "egg", "chip" ] (Deduplicator.deduplicate words)
]
]