Skip to content

Instantly share code, notes, and snippets.

@art-solopov
Created June 9, 2020 21:47
Show Gist options
  • Save art-solopov/3371e5896a3cb096e3f19734c5e79ae7 to your computer and use it in GitHub Desktop.
Save art-solopov/3371e5896a3cb096e3f19734c5e79ae7 to your computer and use it in GitHub Desktop.
My first foray into Elm - a lap counter for timed races (format of N minutes + 1 lap to go)
module Main exposing (..)
import List exposing (range, map)
import Browser
import Html exposing (Html, button, div, text, input)
import Html.Attributes exposing (id, class, style, type_, value, step)
import Html.Events exposing (onInput)
-- MAIN
main =
Browser.sandbox { init = init, update = update, view = view }
type alias Model =
{ raceTime: Int
, timePerLap: Float
}
init: Model
init =
{ raceTime = 10, timePerLap = 1.0 }
type Msg
= NewRaceTime String
| NewTimePerLap String
update: Msg -> Model -> Model
update msg model =
case msg of
NewRaceTime raceTime ->
case String.toInt(raceTime) of
Just rt -> { model | raceTime = rt }
Nothing -> model
NewTimePerLap timePerLap ->
case String.toFloat(timePerLap) of
Just tpl -> { model | timePerLap = tpl }
Nothing -> model
lapsNumber: Model -> Int
lapsNumber model = (ceiling ((toFloat (.raceTime model)) / (.timePerLap model))) + 1
totalTime: Model -> Float
totalTime model = (.timePerLap model) * (toFloat (lapsNumber model))
makeCell: Int -> Html msg
makeCell idx =
div [ class "cell", id ("cell_" ++ (String.fromInt idx)) ] []
getMinutes: Float -> Int
getMinutes time = time |> truncate
getSeconds: Float -> Float
getSeconds time = (time - (time |> getMinutes |> toFloat)) * 60
getSecondsStr: Float -> String
getSecondsStr secs =
secs |> String.fromFloat |> (\n -> if secs < 10 then "0" ++ n else n)
formatTime: Float -> String
formatTime time =
(time |> getMinutes |> String.fromInt) ++
":" ++ (time |> getSeconds |> getSecondsStr)
timeWidth: Model -> Float
timeWidth model =
(100 * (model |> .raceTime |> toFloat) / (model |> totalTime))
view: Model -> Html Msg
view model =
div []
[ div [class "inputs-container"]
[ input [ type_ "number"
, Html.Attributes.min "1"
, Html.Attributes.max (String.fromInt (24 * 60))
, step "1"
, value (model |> .raceTime |> String.fromInt)
, onInput NewRaceTime
] []
, input [ type_ "number"
, Html.Attributes.min "0.5"
, step "0.01"
, value (model |> .timePerLap |> String.fromFloat)
, onInput NewTimePerLap
] []
]
, div [class "results-container"]
[div [ class "cell-container" ]
((map makeCell (range 0 ((lapsNumber model) - 1))) ++
[div [class "race-time"
, style "width" ((model |> timeWidth |> String.fromFloat) ++ "%")
]
[text (model |> .raceTime |> toFloat |> formatTime)]])
, div [class "laps-count"] [text (String.fromInt (lapsNumber model)), text " laps"]
, div [class "total-time"] [text (formatTime (totalTime model))]
]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment