Skip to content

Instantly share code, notes, and snippets.

@ilyazub
Last active October 6, 2020 09:55
Show Gist options
  • Save ilyazub/5f999e8ec5b2d4661abe92494076cb50 to your computer and use it in GitHub Desktop.
Save ilyazub/5f999e8ec5b2d4661abe92494076cb50 to your computer and use it in GitHub Desktop.
Elm practice

Elm practice

Going through Elm guide and doing exercises.

Maybe type

Converter.elm

Preview

-- https://ellie-app.com/3P9hcDhdsc5a1
module Main exposing (Model, Msg(..), init, main, update, view, viewConverter)
import Browser
import Html exposing (Attribute, Html, div, input, span, text)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
-- MAIN
main =
Browser.sandbox { init = init, update = update, view = view }
-- MODEL
type alias Model =
{ celsius : String
, fahrenheit : String
, inches : String
}
init : Model
init =
{ celsius = "", fahrenheit = "", inches = "" }
-- UPDATE
type Msg
= ChangeCelsius String
| ChangeFahrenheit String
| ChangeInches String
update : Msg -> Model -> Model
update msg model =
case msg of
ChangeCelsius newInput ->
{ model | celsius = newInput }
ChangeFahrenheit newInput ->
{ model | fahrenheit = newInput }
ChangeInches newInput ->
{ model | inches = newInput }
-- VIEW
view : Model -> Html Msg
view model =
div [ style "display" "flex", style "flex-direction" "column" ]
[ viewCelsius model
, viewFahrenheit model
, viewInches model
]
viewCelsius : Model -> Html Msg
viewCelsius model =
case String.toFloat model.celsius of
Just celsius ->
viewConverter model.celsius ChangeCelsius "°C" "°F" "blue" (celsiusToFahrenheit celsius)
Nothing ->
viewConverter model.celsius ChangeCelsius "°C" "°F" "red" "???"
viewFahrenheit : Model -> Html Msg
viewFahrenheit model =
case String.toFloat model.fahrenheit of
Just fahrenheit ->
viewConverter model.fahrenheit ChangeFahrenheit "°F" "°C" "blue" (fahrenheitToCelsius fahrenheit)
Nothing ->
viewConverter model.fahrenheit ChangeFahrenheit "°F" "°C" "red" "???"
viewInches : Model -> Html Msg
viewInches model =
case String.toFloat model.inches of
Just inches ->
viewConverter model.inches ChangeInches "in" "m" "blue" (inchesToMeters inches)
Nothing ->
viewConverter model.inches ChangeInches "in" "m" "red" "???"
celsiusToFahrenheit : Float -> String
celsiusToFahrenheit celsius =
String.fromFloat (celsius * 1.8 + 32)
fahrenheitToCelsius : Float -> String
fahrenheitToCelsius fahrenheit =
String.fromFloat (fahrenheit / 1.8 - 32)
inchesToMeters : Float -> String
inchesToMeters inches =
String.fromFloat (inches * 0.0254)
viewConverter : String -> (String -> Msg) -> String -> String -> String -> String -> Html Msg
viewConverter userInput convert convertFrom convertTo color equivalentTemp =
span []
[ input [ value userInput, onInput convert, style "width" "40px", style "border" ("1px solid " ++ color) ] []
, text (convertFrom ++ " = ")
, span [ style "color" color ] [ text equivalentTemp ]
, text convertTo
]
module Main exposing (Model, Msg(..), init, main, update, view, viewInput, viewValidation)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
main =
Browser.sandbox { init = init, update = update, view = view }
type alias Model =
{ name : String
, password : String
, passwordAgain : String
}
init : Model
init =
Model "" "" ""
type Msg
= Name String
| Password String
| PasswordAgain String
update : Msg -> Model -> Model
update msg model =
case msg of
Name name ->
{ model | name = name }
Password password ->
{ model | password = password }
PasswordAgain password ->
{ model | passwordAgain = password }
view : Model -> Html Msg
view model =
div []
[ viewInput "text" "Name" model.name Name
, viewInput "password" "Password" model.password Password
, viewInput "password" "Re-enter Password" model.passwordAgain PasswordAgain
, viewValidation model
]
viewInput : String -> String -> String -> (String -> msg) -> Html msg
viewInput t p v toMsg =
input [ type_ t, placeholder p, value v, onInput toMsg ] []
type ValidationResult
= ShortPassword
| NoDigitsInPassword
| NoUppercaseCharacters
| NoLowercaseCharacters
| PasswordsNotMatch
| Valid
viewValidation : Model -> Html msg
viewValidation model =
case validate model of
ShortPassword ->
viewValidationError "Password should be longer than 8 characters"
NoDigitsInPassword ->
viewValidationError "Password should contain one numeric character"
NoUppercaseCharacters ->
viewValidationError "Password should contain one upper case character"
NoLowercaseCharacters ->
viewValidationError "Password should contain one lower case character"
PasswordsNotMatch ->
viewValidationError "Passwords do not match!"
Valid ->
div [ style "color" "green" ] [ text "OK" ]
viewValidationError : String -> Html msg
viewValidationError errorMessage =
div [ style "color" "red" ] [ text errorMessage ]
validate : Model -> ValidationResult
validate model =
if String.length model.password < 8 then
ShortPassword
else if not (String.any Char.isDigit model.password) then
NoDigitsInPassword
else if not (String.any Char.isUpper model.password) then
NoUppercaseCharacters
else if not (String.any Char.isLower model.password) then
NoLowercaseCharacters
else if model.password /= model.passwordAgain then
PasswordsNotMatch
else
Valid
import Browser
import Html exposing (Html, button, div, text, input)
import Html.Events exposing (onClick, onInput)
import Html.Attributes exposing (..)
main =
Browser.sandbox { init = init, update = update, view = view }
type alias Model =
{ counter : Int
}
init : Model
init =
Model 10
type Msg = Reset | Change String
update : Msg -> Model -> Model
update msg model =
case msg of
Reset ->
init
Change newCounter ->
{ model | counter = Maybe.withDefault model.counter (String.toInt newCounter) }
view : Model -> Html Msg
view model =
div []
[ div [] [ text (String.fromInt model.counter) ]
, input [ type_ "range", placeholder "Type counter", value (String.fromInt model.counter), onInput Change ] []
, viewButton "Reset" Reset
, viewSnowman model
]
viewButton : String -> msg -> Html msg
viewButton t toMsg =
button [ onClick toMsg ] [ text t ]
viewSnowman : Model -> Html msg
viewSnowman model =
div
[ style "display" "flex"
, style "flex-direction" "column"
, style "align-items" "center"
, style "width" "50%"
]
[ viewShape model 1
, viewShape model 2
, viewShape model 3
]
viewShape : Model -> Int -> Html msg
viewShape model position =
div
[ style "width" ((String.fromInt (model.counter * position)) ++ "px")
, style "height" ((String.fromInt (model.counter * position)) ++ "px")
, style "background-color" (getColor model.counter)
, style "border-radius" "50%"
, style "transition" "background-color 300ms linear"
]
[]
getColor : Int -> String
getColor counter =
if counter <= 50 then
"green"
else
"red"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment