Skip to content

Instantly share code, notes, and snippets.

@napcs
Last active June 17, 2016 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save napcs/ab2b3b8b9abd838eddf1577df95933fe to your computer and use it in GitHub Desktop.
Save napcs/ab2b3b8b9abd838eddf1577df95933fe to your computer and use it in GitHub Desktop.
EFP #8
import Html.App exposing (beginnerProgram)
import Html exposing(Html, Attribute, button, div, text, span, label, input, p)
import Html.Attributes exposing(value, style, placeholder)
import Html.Events exposing(onClick, onInput)
import String exposing(toFloat)
main =
beginnerProgram {model = model, view = view, update = update}
-- types
type Msg =
NoOp
| NumberOfPeople String
| NumberOfPizzas String
| NumberOfSlicesPerPizza String
| CalculatePiecesPerPerson
type alias Model =
{ numberOfPeople: String
, numberOfPizzas: String
, numberOfSlicesPerPizza: String
, piecesPerPerson: Int
, leftovers: Int
}
-- model
model: Model
model =
{ numberOfPeople = "2"
, numberOfPizzas = "2"
, numberOfSlicesPerPizza = "8"
, piecesPerPerson = 0
, leftovers = 0
}
-- view
view: Model -> Html Msg
view model =
div [] [
div [] [
label [labelStyle] [text "Number Of People"]
, input [placeholder "0", onInput NumberOfPeople, value model.numberOfPeople] []
]
, div [] [
label [labelStyle] [text "Number of pizzas"]
, input [placeholder "0", onInput NumberOfPizzas, value model.numberOfPizzas] []
]
, div [] [
label [labelStyle] [text "Number of slices per person"]
, input [onInput NumberOfSlicesPerPizza, value model.numberOfSlicesPerPizza] []
]
, p [] [
text "Each person gets "
, text (toString model.piecesPerPerson)
]
, p [] [
text (toString model.leftovers)
, text " left over"
]
, button [onClick CalculatePiecesPerPerson] [text "Calculate"]
]
-- update
update: Msg -> Model -> Model
update message model =
case message of
NoOp -> model
NumberOfPeople p ->
{ model | numberOfPeople = p }
NumberOfPizzas p ->
{ model | numberOfPizzas = p }
NumberOfSlicesPerPizza s ->
{ model | numberOfSlicesPerPizza = s }
CalculatePiecesPerPerson ->
let
(pieces, leftovers) = calculateSlices model
in
{ model | piecesPerPerson = pieces, leftovers = leftovers }
-- work
calculateSlices: Model -> (Int, Int)
calculateSlices model =
let
numberOfPeople = convertToInt model.numberOfPeople
numberOfPizzas = convertToInt model.numberOfPizzas
numberOfSlicesPerPizza = convertToInt model.numberOfSlicesPerPizza
in
-- return (piences, leftovers)
( ((numberOfPizzas * numberOfSlicesPerPizza) // numberOfPeople)
, ((numberOfPizzas * numberOfSlicesPerPizza) % numberOfPeople)
)
-- Custom label style. Can be used as an attribute in HTML.
labelStyle: Attribute Msg
labelStyle =
style
[ ("width", "200px")
, ("padding", "10px")
, ("text-align", "right")
, ("display", "inline-block")
]
convertToInt: String -> Int
convertToInt number =
case String.toInt number of
Err msg -> 0
Ok val -> val
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment