Commits: 1

Extract workshop slides and samples from fpart-wiki

new file mode 100644
index 0000000..9114974
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/elm-stuff
+/**/.DS_Store
new file mode 100644
index 0000000..a115152
Binary files /dev/null and b/assets/Elm MVU architecture.jpg differ
new file mode 100644
index 0000000..a975a29
Binary files /dev/null and b/assets/mac-launchpad-terminal.png differ
new file mode 100644
index 0000000..5bc5df1
Binary files /dev/null and b/assets/mac-terminal-window.png differ
new file mode 100644
index 0000000..988c3a5
--- /dev/null
+++ b/elm.json
@@ -0,0 +1,31 @@
+{
+    "type": "application",
+    "source-directories": [
+        "src"
+    ],
+    "elm-version": "0.19.0",
+    "dependencies": {
+        "direct": {
+            "elm/browser": "1.0.0",
+            "elm/core": "1.0.0",
+            "elm/html": "1.0.0",
+            "elm/svg": "1.0.1",
+            "ianmackenzie/elm-geometry": "1.2.1",
+            "ianmackenzie/elm-geometry-svg": "1.0.2",
+            "mdgriffith/elm-ui": "1.1.0"
+        },
+        "indirect": {
+            "elm/json": "1.0.0",
+            "elm/time": "1.0.0",
+            "elm/url": "1.0.0",
+            "elm/virtual-dom": "1.0.2",
+            "ianmackenzie/elm-float-extra": "1.0.1",
+            "ianmackenzie/elm-interval": "1.0.1",
+            "ianmackenzie/elm-triangular-mesh": "1.0.2"
+        }
+    },
+    "test-dependencies": {
+        "direct": {},
+        "indirect": {}
+    }
+}
\ No newline at end of file
new file mode 100644
index 0000000..a2ea019
--- /dev/null
+++ b/index.md
@@ -0,0 +1,314 @@
+---
+presentation:
+  enableSpeakerNotes: true
+  theme: solarized.css
+---
+
+<!-- slide -->
+
+# FP-Art!
+## A functional programming workshop
+### for non-programmers
+
+<!-- slide -->
+
+## Setup
+
+<!-- slide -->
+
+> This setup instructions are based on an assumption that you are using a Mac.
+>
+> If you are using Linux or BSD, then you probably know how to install stuff.
+>
+> If you are using anything else, then... well, good luck.
+>
+> The rest of the instructions should work with any platform.
+
+<!-- slide -->
+
+We will need:
+
+- a text editor (I use [Atom][])
+- and [Elm programming language][]
+
+[Atom]: https://atom.io/
+[Elm programming language]: https://elm-lang.org/
+
+<!-- slide -->
+
+We will use the terminal a little bit.
+
+# :fa-terminal:
+
+Don't be scared. It's easy :)
+
+<!-- slide data-background-image="images/mac-launchpad-terminal.png" data-background-size="cover" data-background-position="top center"-->
+
+> <p style="color: white">In Launchpad find a program called <code>terminal</code> and start it.</p>
+
+<!-- slide -->
+
+You should see a window like this
+
+<img class="plain" alt="Mac Terminal app window" src="images/mac-terminal-window.png" />
+
+<!-- slide -->
+
+Now we are going to install few things.
+
+- Homebrew (to install other things)
+- Elm programming language
+- Atom editor
+
+<!-- slide -->
+
+### Install Homebrew
+
+Follow instructions on the [Homebrew website](https://brew.sh/) by typing the following in the terminal (you probably want to copy and paste it):
+
+```sh
+/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+```
+
+<small>
+Make sure that the command is exactly like the one above, including the `/` character at the beginning, the quotes and parentheses.
+
+It will ask you to confirm several actions and ask for your password. It may take few minutes to finish, so get your coffee
+</small>
+
+:fa-coffee:
+
+Once it's done you should see a command prompt like that:
+
+```
+~ your-name$
+```
+
+
+<!-- slide -->
+
+### Install the Elm programming language
+
+<small>Once we have Homebrew installed, we can use it to install the language.</small>
+
+Type the following in the terminal.
+
+```sh
+brew install node elm
+```
+
+and check if it works by typing:
+
+```
+elm repl
+```
+
+<!-- slide -->
+
+Note that the command line changes. You should see something like that
+
+```
+---- Elm 0.19.0 ----------------------------------------------------------------
+Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
+--------------------------------------------------------------------------------
+>
+```
+
+It's the Elm REPL
+
+<small>Read - Evaluate - Print Loop</small>
+
+*[REPL]: Read - Evaluate - Print Loop.
+
+<!-- slide -->
+
+Inside the REPL type
+
+```
+2 + 2
+```
+
+And expect to see
+
+```
+---- Elm 0.19.0 ----------------------------------------------------------------
+Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
+--------------------------------------------------------------------------------
+> 2 + 2
+4 : number
+>
+```
+
+Easy, huh?
+
+<!-- slide -->
+
+We will learn more about REPL later. For now type `:exit` to close it.
+
+The command line should look like before again.
+
+<!-- slide -->
+
+### Install Atom text editor
+
+Computer programs are represented as text, so the text editor is the most fundamental tool of a programmer. There is a lot of good text editors, but to get you started, we will use [Atom] here.
+
+<!-- slide -->
+
+Type following in the terminal:
+
+```
+brew cask install atom
+```
+
+And start it with:
+
+```sh
+atom
+```
+
+<!-- slide -->
+
+One last thing we need is Elm support for Atom editor. You can install it by typing in the terminal:
+
+```
+apm install language-elm
+```
+
+<small>APM is the Atom Package Manager, but don't pay much attention to it. We won't be using it again.</small>
+
+<!-- slide -->
+
+**We are all set!**
+
+:smile:
+
+<!-- slide -->
+
+
+# First program!
+
+<!-- slide -->
+
+As mentioned before, programs are represented as text (called *the source code*).
+
+The source code is stored in files
+
+:fa-file:
+
+and files are organized in directories
+
+:fa-folder:
+
+<!-- slide -->
+
+So the first step is to create a directory for our new program. Let's call it `fpart`.
+
+In the terminal type
+
+```sh
+mkdir fpart/
+```
+
+and then
+
+```
+cd fpart/
+```
+
+<small>This creates a new directory and makes it the current one. Again, don't worry about the details.</small>
+
+<!-- slide -->
+
+To easily create a new program, we can type
+
+```
+elm init
+```
+
+<!-- slide -->
+
+Then to create a file with source code, type
+
+```
+atom src/Main.elm
+```
+
+<small>This command should open a new Atom window with empty text file.</small>
+
+<!-- slide data-transition=zoom -->
+
+### `main.elm`
+
+```elm
+module Main exposing (main)
+
+import Html
+
+
+main =
+    Html.text "Hello, Tree!"
+```
+
+<small>Type the above in the editor and save the file</small>
+
+<!-- slide -->
+
+To see the program running type following in the terminal
+
+```sh
+elm reactor
+```
+
+<small>This command starts the Elm reactor, which will let you run your program in the web browser. Note that it won't give you the command line back - it will run as long as you don't stop it.</small>
+
+<!-- slide -->
+
+# Voila!
+
+<small>Open following address in the web browser</small>
+
+http://localhost:8000/src/Main.elm
+
+<small>Note that the same address was printed by Elm reactor</small>
+
+<!-- slide -->
+
+# Let's make a dot!
+# :fa-circle:
+
+<!-- slide -->
+
+We are going to use a technology called SVG
+
+<small>Scalable Vector Graphics</small>
+
+
+*[SVG]: Scalable Vector Graphics
+
+<!-- slide -->
+
+Let's install an Elm package to help us work with SVG.
+
+Stop the Reactor running in terminal by pressing
+
+`CTRL-C`
+
+and type the following
+
+```
+elm install elm/svg
+```
+
+Then start the reactor again
+
+```
+elm reactor
+```
+
+<small>you can press up arrow :fa-arrow-up: on the keyboard to get to previous commands</small>
+
+<!-- slide -->
+
+<iframe id="cartesian" data-src="./CartesianCoordinates.html" class="stretch">
+</iframe>
new file mode 100644
index 0000000..609bebd
--- /dev/null
+++ b/src/CartesianCoordinates.elm
@@ -0,0 +1,136 @@
+module CartesianCoordinates exposing (main)
+
+import Browser
+import CartesianPlane exposing (graph)
+import Element
+import Element.Background as Background
+import Element.Border as Border
+import Element.Input as Input
+import Html exposing (Html)
+import Svg exposing (..)
+import Svg.Attributes exposing (..)
+
+
+main =
+    Browser.element
+        { init = init
+        , view = view
+        , update = update
+        , subscriptions = subscriptions
+        }
+
+
+type alias Flags =
+    ()
+
+
+type alias Model =
+    { x : Float
+    , y : Float
+    }
+
+
+type Msg
+    = SetX Float
+    | SetY Float
+
+
+init : Flags -> ( Model, Cmd Msg )
+init () =
+    ( { x = 0, y = 0 }
+    , Cmd.none
+    )
+
+
+view : Model -> Html.Html Msg
+view model =
+    Element.layout
+        [ Element.height Element.fill -- (Element.px 600)
+        , Element.width Element.fill
+        ]
+    <|
+        Element.column
+            [ Element.height Element.fill
+            , Element.width <| Element.px 600
+            , Element.centerX
+            , Element.spacing 30
+            , Element.padding 30
+            ]
+            [ Element.el [ Element.height <| Element.px 400 ] <|
+                Element.html <|
+                    graph
+                        [ circle
+                            [ cx <| String.fromFloat model.x
+                            , cy <| String.fromFloat model.y
+                            , r "0.01"
+                            , fill "magenta"
+                            ]
+                            []
+                        , text_
+                            [ x <| String.fromFloat (model.x + 0.03)
+                            , y <| String.fromFloat model.y
+                            , fontSize "0.05"
+                            , dominantBaseline "central"
+                            ]
+                            [ text <| Debug.toString ( model.x, model.y ) ]
+                        ]
+            , Input.slider
+                [ Element.behindContent
+                    (Element.el
+                        [ Element.width Element.fill
+                        , Element.height (Element.px 2)
+                        , Element.centerY
+                        , Background.color <| Element.rgb 0.7 0.7 0.7
+                        , Border.rounded 2
+                        ]
+                        Element.none
+                    )
+                ]
+                { onChange = SetX
+                , label =
+                    Input.labelBelow [ Element.centerX ] <|
+                        Element.text ("x value: " ++ String.fromFloat model.x)
+                , min = -1
+                , max = 1
+                , value = model.x
+                , thumb = Input.defaultThumb
+                , step = Just 0.01
+                }
+            , Input.slider
+                [ Element.behindContent
+                    (Element.el
+                        [ Element.width Element.fill
+                        , Element.height (Element.px 2)
+                        , Element.centerY
+                        , Background.color <| Element.rgb 0.7 0.7 0.7
+                        , Border.rounded 2
+                        ]
+                        Element.none
+                    )
+                ]
+                { onChange = SetY
+                , label =
+                    Input.labelBelow [ Element.centerX ] <|
+                        Element.text ("y value: " ++ String.fromFloat model.y)
+                , min = -1
+                , max = 1
+                , value = model.y
+                , thumb = Input.defaultThumb
+                , step = Just 0.01
+                }
+            ]
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg model =
+    case msg of
+        SetX x ->
+            ( { model | x = x }, Cmd.none )
+
+        SetY y ->
+            ( { model | y = y }, Cmd.none )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+    Sub.none
new file mode 100644
index 0000000..394005d
--- /dev/null
+++ b/src/CartesianPlane.elm
@@ -0,0 +1,38 @@
+module CartesianPlane exposing (graph)
+
+import Html exposing (Html)
+import Svg exposing (..)
+import Svg.Attributes exposing (..)
+
+
+graph : List (Svg msg) -> Html msg
+graph shapes =
+    let
+        background =
+            g []
+                [ line
+                    [ x1 "-1"
+                    , y1 "0"
+                    , x2 "1"
+                    , y2 "0"
+                    , stroke "black"
+                    , strokeWidth "0.001"
+                    ]
+                    []
+                , line
+                    [ x1 "0"
+                    , x2 "0"
+                    , y1 "-1"
+                    , y2 "1"
+                    , stroke "black"
+                    , strokeWidth "0.001"
+                    ]
+                    []
+                ]
+    in
+    svg
+        [ viewBox "-1 -1 2 2"
+        , preserveAspectRatio "xMidYMid meet"
+        , Svg.Attributes.style "width: 100%, height: 100%"
+        ]
+        (background :: shapes)
new file mode 100644
index 0000000..fead82e
--- /dev/null
+++ b/src/PolarCoordinates.elm
@@ -0,0 +1,180 @@
+module PolarCoordinates exposing (main)
+
+import Browser
+import Element
+import Element.Background as Background
+import Element.Border as Border
+import Element.Input as Input
+import Html exposing (Html)
+import Svg exposing (..)
+import Svg.Attributes exposing (..)
+
+
+main =
+    Browser.element
+        { init = init
+        , view = view
+        , update = update
+        , subscriptions = subscriptions
+        }
+
+
+type alias Flags =
+    ()
+
+
+type alias Model =
+    { angle : Float
+    , radius : Float
+    }
+
+
+type Msg
+    = SetAngle Float
+    | SetRadius Float
+
+
+init : Flags -> ( Model, Cmd Msg )
+init () =
+    ( { angle = 0, radius = 0.5 }
+    , Cmd.none
+    )
+
+
+view : Model -> Html.Html Msg
+view model =
+    let
+        point =
+            cartesian model
+    in
+    Element.layout
+        [ Element.height Element.fill -- (Element.px 600)
+        , Element.width Element.fill
+        , Background.color <| Element.rgb 0.6 0 0
+        ]
+    <|
+        Element.column
+            [ Element.height Element.fill
+            , Element.width <| Element.px 600
+            , Background.color <| Element.rgb 0 0.6 0
+            , Element.centerX
+            , Element.spacing 30
+            , Element.padding 30
+            ]
+            [ Element.el [] <|
+                Element.html <|
+                    svg
+                        [ viewBox "-1 -1 2 2"
+                        , preserveAspectRatio "xMidYMid meet"
+                        , Svg.Attributes.style "width: 100%, height: 100%"
+                        ]
+                        [ line
+                            [ x1 "-1"
+                            , y1 "0"
+                            , x2 "1"
+                            , y2 "0"
+                            , stroke "black"
+                            , strokeWidth "0.001"
+                            ]
+                            []
+                        , line
+                            [ x1 "0"
+                            , x2 "0"
+                            , y1 "-1"
+                            , y2 "1"
+                            , stroke "black"
+                            , strokeWidth "0.001"
+                            ]
+                            []
+                        , circle
+                            [ cx <| String.fromFloat point.x
+                            , cy <| String.fromFloat point.y
+                            , r "0.01"
+                            , fill "magenta"
+                            ]
+                            []
+                        , line
+                            [ x1 "0"
+                            , x2 <| String.fromFloat point.x
+                            , y1 "0"
+                            , y2 <| String.fromFloat point.y
+                            , stroke "magenta"
+                            , strokeWidth "0.001"
+                            ]
+                            []
+                        , text_
+                            [ x <| String.fromFloat (point.x + 0.02)
+                            , y <| String.fromFloat (point.y + 0.01)
+                            , Svg.Attributes.fontSize "0.03pt"
+                            ]
+                            [ text <|
+                                Debug.toString ( point.x, point.y )
+                            ]
+                        ]
+            , Input.slider
+                [ Element.behindContent
+                    (Element.el
+                        [ Element.width Element.fill
+                        , Element.height (Element.px 2)
+                        , Element.centerY
+                        , Background.color <| Element.rgb 0.7 0.7 0.7
+                        , Border.rounded 2
+                        ]
+                        Element.none
+                    )
+                ]
+                { onChange = SetAngle
+                , label =
+                    Input.labelBelow [ Element.centerX ] <|
+                        Element.text ("angle value: " ++ String.fromFloat model.angle)
+                , min = 0
+                , max = 360
+                , value = model.angle
+                , thumb = Input.defaultThumb
+                , step = Just 1
+                }
+            , Input.slider
+                [ Element.behindContent
+                    (Element.el
+                        [ Element.width Element.fill
+                        , Element.height (Element.px 2)
+                        , Element.centerY
+                        , Background.color <| Element.rgb 0.7 0.7 0.7
+                        , Border.rounded 2
+                        ]
+                        Element.none
+                    )
+                ]
+                { onChange = SetRadius
+                , label =
+                    Input.labelBelow [ Element.centerX ] <|
+                        Element.text ("radius value: " ++ String.fromFloat model.radius)
+                , min = 0
+                , max = 1
+                , value = model.radius
+                , thumb = Input.defaultThumb
+                , step = Just 0.01
+                }
+            ]
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg model =
+    case msg of
+        SetAngle angle ->
+            ( { model | angle = angle }, Cmd.none )
+
+        SetRadius radius ->
+            ( { model | radius = radius }, Cmd.none )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+    Sub.none
+
+
+cartesian : { angle : Float, radius : Float } -> { x : Float, y : Float }
+cartesian model =
+    { x = model.radius * cos (degrees model.angle)
+    , y = model.radius * sin (degrees model.angle)
+    }