Week 43 of 2018
Development log of Elm Tree Workshop
14 items
- Extract workshop slides and samples from fpart-wiki
- Gitignore .swp files
- Begin reconstructing the 'fpart' presentation as an Elm program
- Evolve program to Browser.sandobx, center text on slides
- Implement keyboard navigation
- Embed the cartesian coordinates sample in the slide
- Indent the slides content
- In PolarCoordinates, use CartesianPlane.graph to draw cartesian plane
- Merge remote-tracking branch 'origin/elm' into elm
- Embed PolarCoordinates sample in slides
- Create content for slides.
- Put slides back in MD file for easier editing
- Work on outline for slides
- Add more to the conspect
Extract workshop slides and samples from fpart-wiki
On by
new file mode 100644
index 0000000..9114974
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/elm-stuff
+/**/.DS_Storenew file mode 100644
index 0000000..a115152
Binary files /dev/null and b/assets/Elm MVU architecture.jpg differnew file mode 100644
index 0000000..a975a29
Binary files /dev/null and b/assets/mac-launchpad-terminal.png differnew file mode 100644
index 0000000..5bc5df1
Binary files /dev/null and b/assets/mac-terminal-window.png differnew 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 filenew 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.nonenew 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)
+ }Gitignore .swp files
On by
index 9114974..0c19f1d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
=/elm-stuff
=/**/.DS_Store
+*.swpBegin reconstructing the 'fpart' presentation as an Elm program
On by
We can render markdown and html elements
Next todo: scaling images to fit on slide
index 988c3a5..67b87e4 100644
--- a/elm.json
+++ b/elm.json
@@ -10,6 +10,8 @@
= "elm/core": "1.0.0",
= "elm/html": "1.0.0",
= "elm/svg": "1.0.1",
+ "elm-community/list-extra": "8.1.0",
+ "elm-explorations/markdown": "1.0.0",
= "ianmackenzie/elm-geometry": "1.2.1",
= "ianmackenzie/elm-geometry-svg": "1.0.2",
= "mdgriffith/elm-ui": "1.1.0"new file mode 100644
index 0000000..88cb6e2
--- /dev/null
+++ b/src/Main.elm
@@ -0,0 +1,400 @@
+module Main exposing (main)
+
+import Dict
+import Element
+import Html exposing (Html)
+import Html.Attributes as Html
+import Presentation exposing (Slide, markdown)
+
+
+currentSlide =
+ 5
+
+
+main =
+ let
+ slide =
+ slides
+ |> Dict.get currentSlide
+
+ notFound =
+ Element.text "404: Slide not found"
+ in
+ Element.layout [ Element.width Element.fill, Element.height Element.fill ] <|
+ Element.row
+ [ Element.centerX, Element.centerY ]
+ [ slide
+ |> Maybe.map (Element.column [])
+ |> Maybe.withDefault notFound
+ ]
+
+
+slides =
+ Dict.fromList <|
+ List.indexedMap Tuple.pair <|
+ [ markdown """
+ # FP-Art!
+ ## A functional programming workshop
+ ### for non-programmers
+ """
+ , markdown """
+ # Stuff
+ """
+ ]
+ :: [ markdown """
+ ## Setup
+ """
+ , markdown """
+ # Stuff
+ """
+ ]
+ :: [ markdown """
+ > 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.
+
+ """ ]
+ :: [ markdown """
+
+ We will need:
+
+ - a text editor (I use [Atom][])
+ - and [Elm programming language][]
+
+ [Atom]: https://atom.io/
+ [Elm programming language]: https://elm-lang.org/
+
+ """
+ ]
+ :: [ markdown """
+
+ 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>
+
+ """
+ ]
+ :: [ markdown """
+ You should see a window like this
+ """
+ , Element.el [ Element.height Element.fill, Element.width Element.fill ] <| Element.html <| Html.img [ Html.class "plain", Html.alt "Mac Terminal app window", Html.src "../assets/mac-terminal-window.png" ] []
+ , markdown """
+ Here is some more markdown.
+ """
+ ]
+ :: [ markdown """
+
+Now we are going to install few things.
+
+- Homebrew (to install other things)
+- Elm programming language
+- Atom editor
+
+"""
+ ]
+ :: [ markdown """
+
+### 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$
+```
+
+
+"""
+ ]
+ :: [ markdown """
+
+### 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
+```
+
+"""
+ ]
+ :: [ markdown """
+
+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.
+
+"""
+ ]
+ :: [ markdown """
+
+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?
+
+"""
+ ]
+ :: [ markdown """
+
+We will learn more about REPL later. For now type `:exit` to close it.
+
+The command line should look like before again.
+
+"""
+ ]
+ :: [ markdown """
+
+### 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.
+
+"""
+ ]
+ :: [ markdown """
+
+Type following in the terminal:
+
+```
+brew cask install atom
+```
+
+And start it with:
+
+```sh
+atom
+```
+
+"""
+ ]
+ :: [ markdown """
+
+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>
+
+"""
+ ]
+ :: [ markdown """
+
+**We are all set!**
+
+:smile:
+
+"""
+ ]
+ :: [ markdown """
+
+
+# First program!
+
+"""
+ ]
+ :: [ markdown """
+
+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:
+
+"""
+ ]
+ :: [ markdown """
+
+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>
+
+"""
+ ]
+ :: [ markdown """
+
+To easily create a new program, we can type
+
+```
+elm init
+```
+
+"""
+ ]
+ :: [ markdown """
+
+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>
+
+"""
+ ]
+ :: [ markdown """
+
+### `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>
+
+"""
+ ]
+ :: [ markdown """
+
+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>
+
+"""
+ ]
+ :: [ markdown """
+
+# 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>
+
+"""
+ ]
+ :: [ markdown """
+
+# Let's make a dot!
+# :fa-circle:
+
+"""
+ ]
+ :: [ markdown """
+
+We are going to use a technology called SVG
+
+<small>Scalable Vector Graphics</small>
+
+
+*[SVG]: Scalable Vector Graphics
+
+"""
+ ]
+ :: [ markdown """
+
+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>
+
+"""
+ ]
+ :: [ markdown """
+
+<iframe id="cartesian" data-src="./CartesianCoordinates.html" class="stretch">
+</iframe>
+
+"""
+ ]
+ :: []new file mode 100644
index 0000000..c017bb5
--- /dev/null
+++ b/src/Presentation.elm
@@ -0,0 +1,41 @@
+module Presentation exposing (Slide, markdown)
+
+import Element exposing (Element)
+import List.Extra as List
+import Markdown
+
+
+type alias Slide msg =
+ List (Element msg)
+
+
+markdown : String -> Element msg
+markdown string =
+ let
+ dedentedString =
+ string
+ |> String.lines
+ |> List.map dedent
+ |> String.join "\n"
+
+ dedent line =
+ line
+ |> String.toList
+ |> List.indexedMap Tuple.pair
+ |> List.dropWhile (\( index, character ) -> index < indentation && character == ' ')
+ |> List.map Tuple.second
+ |> String.fromList
+
+ indentation =
+ string
+ |> String.lines
+ |> List.filter (\line -> String.trim line /= "")
+ |> List.head
+ |> Maybe.withDefault ""
+ |> String.toList
+ |> List.findIndex ((/=) ' ')
+ |> Maybe.withDefault 0
+ in
+ Markdown.toHtml [] dedentedString
+ |> Element.html
+ |> Element.el [ Element.centerX ]Evolve program to Browser.sandobx, center text on slides
On by
index 88cb6e2..50a8c46 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -1,45 +1,71 @@
=module Main exposing (main)
=
+import Browser
=import Dict
=import Element
+import Element.Font as Font
=import Html exposing (Html)
=import Html.Attributes as Html
=import Presentation exposing (Slide, markdown)
=
=
-currentSlide =
- 5
+main =
+ Browser.sandbox
+ { init = init
+ , view = view
+ , update = update
+ }
=
=
-main =
- let
- slide =
- slides
- |> Dict.get currentSlide
-
- notFound =
- Element.text "404: Slide not found"
- in
- Element.layout [ Element.width Element.fill, Element.height Element.fill ] <|
+type alias Model =
+ { currentSlide : Int
+ }
+
+
+type Msg
+ = Next
+ | Previous
+
+
+init : Model
+init =
+ { currentSlide = 0 }
+
+
+view : Model -> Html Msg
+view model =
+ Element.layout
+ [ Element.width Element.fill
+ , Element.height Element.fill
+ ]
+ <|
= Element.row
- [ Element.centerX, Element.centerY ]
- [ slide
+ [ Element.centerX, Element.centerY, Font.center ]
+ [ slides
+ |> Dict.get model.currentSlide
= |> Maybe.map (Element.column [])
- |> Maybe.withDefault notFound
+ |> Maybe.withDefault (Element.text "404: Slide not found")
= ]
=
=
+update : Msg -> Model -> Model
+update msg model =
+ case msg of
+ Next ->
+ { model | currentSlide = model.currentSlide + 1 }
+
+ Previous ->
+ { model | currentSlide = model.currentSlide - 1 }
+
+
=slides =
= Dict.fromList <|
= List.indexedMap Tuple.pair <|
= [ markdown """
- # FP-Art!
- ## A functional programming workshop
- ### for non-programmers
- """
- , markdown """
- # Stuff
- """
+ # FP-Art!
+ ## A functional programming workshop
+ ### for non-programmers
+ """
= ]
= :: [ markdown """
= ## SetupImplement keyboard navigation
On by
index 67b87e4..d17943a 100644
--- a/elm.json
+++ b/elm.json
@@ -9,6 +9,7 @@
= "elm/browser": "1.0.0",
= "elm/core": "1.0.0",
= "elm/html": "1.0.0",
+ "elm/json": "1.0.0",
= "elm/svg": "1.0.1",
= "elm-community/list-extra": "8.1.0",
= "elm-explorations/markdown": "1.0.0",
@@ -17,7 +18,6 @@
= "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",index 50a8c46..0e51aaa 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -1,22 +1,29 @@
=module Main exposing (main)
=
-import Browser
+import Browser exposing (Document)
+import Browser.Events
=import Dict
=import Element
=import Element.Font as Font
=import Html exposing (Html)
=import Html.Attributes as Html
+import Json.Decode as Decode exposing (Decoder)
=import Presentation exposing (Slide, markdown)
=
=
=main =
- Browser.sandbox
+ Browser.document
= { init = init
= , view = view
= , update = update
+ , subscriptions = subscriptions
= }
=
=
+type alias Flags =
+ ()
+
+
=type alias Model =
= { currentSlide : Int
= }
@@ -27,35 +34,72 @@ type Msg
= | Previous
=
=
-init : Model
-init =
- { currentSlide = 0 }
+init : Flags -> ( Model, Cmd Msg )
+init flags =
+ ( { currentSlide = 0 }
+ , Cmd.none
+ )
=
=
-view : Model -> Html Msg
+view : Model -> Document Msg
=view model =
- Element.layout
- [ Element.width Element.fill
- , Element.height Element.fill
- ]
- <|
- Element.row
- [ Element.centerX, Element.centerY, Font.center ]
- [ slides
- |> Dict.get model.currentSlide
- |> Maybe.map (Element.column [])
- |> Maybe.withDefault (Element.text "404: Slide not found")
+ { title = "FP-Art!"
+ , body =
+ [ Element.layout
+ [ Element.width Element.fill
+ , Element.height Element.fill
= ]
+ <|
+ Element.column
+ [ Element.centerX, Element.centerY, Font.center ]
+ [ slides
+ |> Dict.get model.currentSlide
+ |> Maybe.map (Element.column [ Element.height Element.fill ])
+ |> Maybe.withDefault (Element.text "404: Slide not found")
+ ]
+ ]
+ }
=
=
-update : Msg -> Model -> Model
+update : Msg -> Model -> ( Model, Cmd Msg )
=update msg model =
= case msg of
= Next ->
- { model | currentSlide = model.currentSlide + 1 }
+ ( { model
+ | currentSlide =
+ min (Dict.size slides - 1) (model.currentSlide + 1)
+ }
+ , Cmd.none
+ )
=
= Previous ->
- { model | currentSlide = model.currentSlide - 1 }
+ ( { model
+ | currentSlide =
+ max 0 (model.currentSlide - 1)
+ }
+ , Cmd.none
+ )
+
+
+subscriptions model =
+ let
+ handleKeyPress : Decoder Msg
+ handleKeyPress =
+ Decode.field "key" Decode.string
+ |> Decode.andThen
+ (\key ->
+ case Debug.log "Key" key of
+ "ArrowLeft" ->
+ Decode.succeed Previous
+
+ "ArrowRight" ->
+ Decode.succeed Next
+
+ _ ->
+ Decode.fail "Unsupported key"
+ )
+ in
+ Browser.Events.onKeyPress handleKeyPress
=
=
=slides =Embed the cartesian coordinates sample in the slide
On by
Making the SVG element fit the slide was difficult. In the end we are relying on setting the width of it's parent to absolute value in pixels.
Co-Authored-By: Sam Phillips samuel.rodney.phillips@gmail.com
index 609bebd..8d5eb8f 100644
--- a/src/CartesianCoordinates.elm
+++ b/src/CartesianCoordinates.elm
@@ -1,4 +1,14 @@
-module CartesianCoordinates exposing (main)
+module CartesianCoordinates exposing
+ ( Flags
+ , Model
+ , Msg
+ , init
+ , main
+ , subscriptions
+ , ui
+ , update
+ , view
+ )
=
=import Browser
=import CartesianPlane exposing (graph)
@@ -44,80 +54,17 @@ init () =
=
=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
- }
+ let
+ wrapper element =
+ Element.el
+ [ Element.width (Element.maximum 600 Element.fill), Element.centerX ]
+ element
+ in
+ ui model
+ |> wrapper
+ |> Element.layout
+ [ Element.height Element.fill -- (Element.px 600)
+ , Element.width Element.fill
= ]
=
=
@@ -134,3 +81,79 @@ update msg model =
=subscriptions : Model -> Sub Msg
=subscriptions model =
= Sub.none
+
+
+ui model =
+ Element.column
+ [ Element.width Element.fill
+ , Element.centerX
+ , Element.spacing 30
+ , Element.padding 30
+ ]
+ [ Element.el
+ [ Element.height Element.fill
+ , Element.width Element.fill
+ ]
+ <|
+ 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
+ }
+ ]index 394005d..0d82b4a 100644
--- a/src/CartesianPlane.elm
+++ b/src/CartesianPlane.elm
@@ -33,6 +33,8 @@ graph shapes =
= svg
= [ viewBox "-1 -1 2 2"
= , preserveAspectRatio "xMidYMid meet"
+ , Svg.Attributes.width "100%"
+ , Svg.Attributes.height "100%"
= , Svg.Attributes.style "width: 100%, height: 100%"
= ]
= (background :: shapes)index 0e51aaa..da86dd4 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -2,11 +2,13 @@ module Main exposing (main)
=
=import Browser exposing (Document)
=import Browser.Events
+import CartesianCoordinates
=import Dict
=import Element
=import Element.Font as Font
-import Html exposing (Html)
-import Html.Attributes as Html
+import Element.Keyed
+import Html
+import Html.Attributes
=import Json.Decode as Decode exposing (Decoder)
=import Presentation exposing (Slide, markdown)
=
@@ -26,18 +28,29 @@ type alias Flags =
=
=type alias Model =
= { currentSlide : Int
+
+ -- Nested programs
+ , cartesianCoordinates : CartesianCoordinates.Model
= }
=
=
=type Msg
= = Next
= | Previous
+ -- Nested programs
+ | CartesianCoordinatesMsg CartesianCoordinates.Msg
=
=
=init : Flags -> ( Model, Cmd Msg )
=init flags =
- ( { currentSlide = 0 }
- , Cmd.none
+ let
+ ( cartesianCoordinatesModel, cartesianCoordinatesCmd ) =
+ CartesianCoordinates.init ()
+ in
+ ( { currentSlide = 0
+ , cartesianCoordinates = cartesianCoordinatesModel
+ }
+ , Cmd.batch [ Cmd.map CartesianCoordinatesMsg cartesianCoordinatesCmd ]
= )
=
=
@@ -51,10 +64,19 @@ view model =
= ]
= <|
= Element.column
- [ Element.centerX, Element.centerY, Font.center ]
- [ slides
+ [ Element.centerX
+ , Font.center
+ , Element.height Element.fill
+ , Element.width (Element.maximum 800 Element.fill)
+ ]
+ [ slides model
= |> Dict.get model.currentSlide
- |> Maybe.map (Element.column [ Element.height Element.fill ])
+ |> Maybe.map
+ (Element.column
+ [ Element.width Element.fill
+ , Element.centerY
+ ]
+ )
= |> Maybe.withDefault (Element.text "404: Slide not found")
= ]
= ]
@@ -67,7 +89,7 @@ update msg model =
= Next ->
= ( { model
= | currentSlide =
- min (Dict.size slides - 1) (model.currentSlide + 1)
+ min (Dict.size (slides model) - 1) (model.currentSlide + 1)
= }
= , Cmd.none
= )
@@ -80,6 +102,16 @@ update msg model =
= , Cmd.none
= )
=
+ -- Nested programs
+ CartesianCoordinatesMsg msg_ ->
+ let
+ ( model_, cmd_ ) =
+ CartesianCoordinates.update msg_ model.cartesianCoordinates
+ in
+ ( { model | cartesianCoordinates = model_ }
+ , Cmd.map CartesianCoordinatesMsg cmd_
+ )
+
=
=subscriptions model =
= let
@@ -95,6 +127,12 @@ subscriptions model =
= "ArrowRight" ->
= Decode.succeed Next
=
+ "a" ->
+ Decode.succeed Previous
+
+ "d" ->
+ Decode.succeed Next
+
= _ ->
= Decode.fail "Unsupported key"
= )
@@ -102,7 +140,7 @@ subscriptions model =
= Browser.Events.onKeyPress handleKeyPress
=
=
-slides =
+slides model =
= Dict.fromList <|
= List.indexedMap Tuple.pair <|
= [ markdown """
@@ -111,6 +149,23 @@ slides =
= ### for non-programmers
= """
= ]
+ :: [ markdown """
+ Move sliders to change the `x` and `y` coordinates of the dot. It's like moving a thing on a table by telling how far left, right, up or down should it go.
+ """
+ , model.cartesianCoordinates
+ |> CartesianCoordinates.ui
+ |> Element.map CartesianCoordinatesMsg
+ |> Element.el
+ [ Element.centerX
+ , Element.width (Element.maximum 600 Element.fill)
+ ]
+ ]
+ -- :: [ markdown """
+ -- # FP-Art!
+ -- ## A functional programming workshop
+ -- ### for non-programmers
+ -- """
+ -- ]
= :: [ markdown """
= ## Setup
= """
@@ -157,7 +212,16 @@ slides =
= :: [ markdown """
= You should see a window like this
= """
- , Element.el [ Element.height Element.fill, Element.width Element.fill ] <| Element.html <| Html.img [ Html.class "plain", Html.alt "Mac Terminal app window", Html.src "../assets/mac-terminal-window.png" ] []
+ , Html.img
+ [ Html.Attributes.alt "Mac Terminal app window"
+ , Html.Attributes.src "../assets/mac-terminal-window.png"
+ ]
+ []
+ |> Element.html
+ |> Element.el
+ [ Element.height Element.fill
+ , Element.width Element.fill
+ ]
= , markdown """
= Here is some more markdown.
= """Indent the slides content
On by
Co-Authored-By: Sam Phillips samuel.rodney.phillips@gmail.com
index da86dd4..d00c059 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -147,7 +147,7 @@ slides model =
= # FP-Art!
= ## A functional programming workshop
= ### for non-programmers
- """
+ """
= ]
= :: [ markdown """
= Move sliders to change the `x` and `y` coordinates of the dot. It's like moving a thing on a table by telling how far left, right, up or down should it go.
@@ -167,51 +167,50 @@ slides model =
= -- """
= -- ]
= :: [ markdown """
- ## Setup
- """
+ ## Setup
+ """
= , markdown """
- # Stuff
- """
+ # Stuff
+ """
= ]
= :: [ markdown """
- > 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.
-
- """ ]
+ > 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.
+
+ """ ]
= :: [ markdown """
=
- We will need:
+ We will need:
=
- - a text editor (I use [Atom][])
- - and [Elm programming language][]
+ - a text editor (I use [Atom][])
+ - and [Elm programming language][]
=
- [Atom]: https://atom.io/
- [Elm programming language]: https://elm-lang.org/
+ [Atom]: https://atom.io/
+ [Elm programming language]: https://elm-lang.org/
=
- """
+ """
= ]
= :: [ markdown """
+ We will use the terminal a little bit.
=
- We will use the terminal a little bit.
+ # :fa-terminal:
=
- # :fa-terminal:
+ Don't be scared. It's easy :)
=
- 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"-->
=
- <!-- 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>
=
- > <p style="color: white">In Launchpad find a program called <code>terminal</code> and start it.</p>
-
- """
+ """
= ]
= :: [ markdown """
- You should see a window like this
- """
+ You should see a window like this
+ """
= , Html.img
= [ Html.Attributes.alt "Mac Terminal app window"
= , Html.Attributes.src "../assets/mac-terminal-window.png"
@@ -223,312 +222,312 @@ slides model =
= , Element.width Element.fill
= ]
= , markdown """
- Here is some more markdown.
- """
+ Here is some more markdown.
+ """
= ]
= :: [ markdown """
=
-Now we are going to install few things.
+ Now we are going to install few things.
=
-- Homebrew (to install other things)
-- Elm programming language
-- Atom editor
+ - Homebrew (to install other things)
+ - Elm programming language
+ - Atom editor
=
-"""
+ """
= ]
= :: [ markdown """
=
-### Install Homebrew
+ ### 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):
+ 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)"
-```
+ ```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.
+ <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>
+ 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:
+ :fa-coffee:
=
-Once it's done you should see a command prompt like that:
+ Once it's done you should see a command prompt like that:
=
-```
-~ your-name$
-```
+ ```
+ ~ your-name$
+ ```
=
=
-"""
+ """
= ]
= :: [ markdown """
=
-### Install the Elm programming language
+ ### Install the Elm programming language
=
-<small>Once we have Homebrew installed, we can use it to install the language.</small>
+ <small>Once we have Homebrew installed, we can use it to install the language.</small>
=
-Type the following in the terminal.
+ Type the following in the terminal.
=
-```sh
-brew install node elm
-```
+ ```sh
+ brew install node elm
+ ```
=
-and check if it works by typing:
+ and check if it works by typing:
=
-```
-elm repl
-```
+ ```
+ elm repl
+ ```
=
-"""
+ """
= ]
= :: [ markdown """
=
-Note that the command line changes. You should see something like that
+ 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.
---------------------------------------------------------------------------------
->
-```
+ ```
+ ---- 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
+ It's the Elm REPL
=
-<small>Read - Evaluate - Print Loop</small>
+ <small>Read - Evaluate - Print Loop</small>
=
-*[REPL]: Read - Evaluate - Print Loop.
+ *[REPL]: Read - Evaluate - Print Loop.
=
-"""
+ """
= ]
= :: [ markdown """
=
-Inside the REPL type
+ Inside the REPL type
=
-```
-2 + 2
-```
+ ```
+ 2 + 2
+ ```
=
-And expect to see
+ 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
->
-```
+ ```
+ ---- 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?
+ Easy, huh?
=
-"""
+ """
= ]
= :: [ markdown """
=
-We will learn more about REPL later. For now type `:exit` to close it.
+ We will learn more about REPL later. For now type `:exit` to close it.
=
-The command line should look like before again.
+ The command line should look like before again.
=
-"""
+ """
= ]
= :: [ markdown """
=
-### Install Atom text editor
+ ### 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.
+ 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.
=
-"""
+ """
= ]
= :: [ markdown """
=
-Type following in the terminal:
+ Type following in the terminal:
=
-```
-brew cask install atom
-```
+ ```
+ brew cask install atom
+ ```
=
-And start it with:
+ And start it with:
=
-```sh
-atom
-```
+ ```sh
+ atom
+ ```
=
-"""
+ """
= ]
= :: [ markdown """
=
-One last thing we need is Elm support for Atom editor. You can install it by typing in the terminal:
+ One last thing we need is Elm support for Atom editor. You can install it by typing in the terminal:
=
-```
-apm install language-elm
-```
+ ```
+ 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>
+ <small>APM is the Atom Package Manager, but don't pay much attention to it. We won't be using it again.</small>
=
-"""
+ """
= ]
= :: [ markdown """
=
-**We are all set!**
+ **We are all set!**
=
-:smile:
+ :smile:
=
-"""
+ """
= ]
= :: [ markdown """
=
=
-# First program!
+ # First program!
=
-"""
+ """
= ]
= :: [ markdown """
=
-As mentioned before, programs are represented as text (called *the source code*).
+ As mentioned before, programs are represented as text (called *the source code*).
=
-The source code is stored in files
+ The source code is stored in files
=
-:fa-file:
+ :fa-file:
=
-and files are organized in directories
+ and files are organized in directories
=
-:fa-folder:
+ :fa-folder:
=
-"""
+ """
= ]
= :: [ markdown """
=
-So the first step is to create a directory for our new program. Let's call it `fpart`.
+ So the first step is to create a directory for our new program. Let's call it `fpart`.
=
-In the terminal type
+ In the terminal type
=
-```sh
-mkdir fpart/
-```
+ ```sh
+ mkdir fpart/
+ ```
=
-and then
+ and then
=
-```
-cd fpart/
-```
+ ```
+ cd fpart/
+ ```
=
-<small>This creates a new directory and makes it the current one. Again, don't worry about the details.</small>
+ <small>This creates a new directory and makes it the current one. Again, don't worry about the details.</small>
=
-"""
+ """
= ]
= :: [ markdown """
=
-To easily create a new program, we can type
+ To easily create a new program, we can type
=
-```
-elm init
-```
+ ```
+ elm init
+ ```
=
-"""
+ """
= ]
= :: [ markdown """
=
-Then to create a file with source code, type
+ Then to create a file with source code, type
=
-```
-atom src/Main.elm
-```
+ ```
+ atom src/Main.elm
+ ```
=
-<small>This command should open a new Atom window with empty text file.</small>
+ <small>This command should open a new Atom window with empty text file.</small>
=
-"""
+ """
= ]
= :: [ markdown """
=
-### `main.elm`
+ ### `main.elm`
=
-```elm
-module Main exposing (main)
+ ```elm
+ module Main exposing (main)
=
-import Html
+ import Html
=
=
-main =
- Html.text "Hello, Tree!"
-```
+ main =
+ Html.text "Hello, Tree!"
+ ```
=
-<small>Type the above in the editor and save the file</small>
+ <small>Type the above in the editor and save the file</small>
=
-"""
+ """
= ]
= :: [ markdown """
=
-To see the program running type following in the terminal
+ To see the program running type following in the terminal
=
-```sh
-elm reactor
-```
+ ```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>
+ <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>
=
-"""
+ """
= ]
= :: [ markdown """
=
-# Voila!
+ # Voila!
=
-<small>Open following address in the web browser</small>
+ <small>Open following address in the web browser</small>
=
-http://localhost:8000/src/Main.elm
+ http://localhost:8000/src/Main.elm
=
-<small>Note that the same address was printed by Elm reactor</small>
+ <small>Note that the same address was printed by Elm reactor</small>
=
-"""
+ """
= ]
= :: [ markdown """
=
-# Let's make a dot!
-# :fa-circle:
+ # Let's make a dot!
+ # :fa-circle:
=
-"""
+ """
= ]
= :: [ markdown """
=
-We are going to use a technology called SVG
+ We are going to use a technology called SVG
=
-<small>Scalable Vector Graphics</small>
+ <small>Scalable Vector Graphics</small>
=
=
-*[SVG]: Scalable Vector Graphics
+ *[SVG]: Scalable Vector Graphics
=
-"""
+ """
= ]
= :: [ markdown """
=
-Let's install an Elm package to help us work with SVG.
+ Let's install an Elm package to help us work with SVG.
=
-Stop the Reactor running in terminal by pressing
+ Stop the Reactor running in terminal by pressing
=
-`CTRL-C`
+ `CTRL-C`
=
-and type the following
+ and type the following
=
-```
-elm install elm/svg
-```
+ ```
+ elm install elm/svg
+ ```
=
-Then start the reactor again
+ Then start the reactor again
=
-```
-elm reactor
-```
+ ```
+ elm reactor
+ ```
=
-<small>you can press up arrow :fa-arrow-up: on the keyboard to get to previous commands</small>
+ <small>you can press up arrow :fa-arrow-up: on the keyboard to get to previous commands</small>
=
-"""
+ """
= ]
= :: [ markdown """
=
-<iframe id="cartesian" data-src="./CartesianCoordinates.html" class="stretch">
-</iframe>
+ <iframe id="cartesian" data-src="./CartesianCoordinates.html" class="stretch">
+ </iframe>
=
-"""
+ """
= ]
= :: []In PolarCoordinates, use CartesianPlane.graph to draw cartesian plane
On by
Remove background colors from PolarCoordinates.view
Co-authored-by: Tadeusz Łazurski tadeusz@lazurski.pl
index fead82e..65f6718 100644
--- a/src/PolarCoordinates.elm
+++ b/src/PolarCoordinates.elm
@@ -1,6 +1,7 @@
=module PolarCoordinates exposing (main)
=
=import Browser
+import CartesianPlane
=import Element
=import Element.Background as Background
=import Element.Border as Border
@@ -50,43 +51,19 @@ view model =
= 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
+ CartesianPlane.graph
+ [ circle
= [ cx <| String.fromFloat point.x
= , cy <| String.fromFloat point.y
= , r "0.01"Merge remote-tracking branch 'origin/elm' into elm
On by
Embed PolarCoordinates sample in slides
On by
Co-authored-by: Tadeusz Łazurski tadeusz@lazurski.pl
index 8d5eb8f..6be4d7b 100644
--- a/src/CartesianCoordinates.elm
+++ b/src/CartesianCoordinates.elm
@@ -63,7 +63,7 @@ view model =
= ui model
= |> wrapper
= |> Element.layout
- [ Element.height Element.fill -- (Element.px 600)
+ [ Element.height Element.fill
= , Element.width Element.fill
= ]
=index d00c059..f40b7a2 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -10,6 +10,7 @@ import Element.Keyed
=import Html
=import Html.Attributes
=import Json.Decode as Decode exposing (Decoder)
+import PolarCoordinates
=import Presentation exposing (Slide, markdown)
=
=
@@ -31,6 +32,7 @@ type alias Model =
=
= -- Nested programs
= , cartesianCoordinates : CartesianCoordinates.Model
+ , polarCoordinates : PolarCoordinates.Model
= }
=
=
@@ -39,6 +41,7 @@ type Msg
= | Previous
= -- Nested programs
= | CartesianCoordinatesMsg CartesianCoordinates.Msg
+ | PolarCoordinatesMsg PolarCoordinates.Msg
=
=
=init : Flags -> ( Model, Cmd Msg )
@@ -46,11 +49,18 @@ init flags =
= let
= ( cartesianCoordinatesModel, cartesianCoordinatesCmd ) =
= CartesianCoordinates.init ()
+
+ ( polarCoordinatesModel, polarCoordinatesCmd ) =
+ PolarCoordinates.init ()
= in
= ( { currentSlide = 0
= , cartesianCoordinates = cartesianCoordinatesModel
+ , polarCoordinates = polarCoordinatesModel
= }
- , Cmd.batch [ Cmd.map CartesianCoordinatesMsg cartesianCoordinatesCmd ]
+ , Cmd.batch
+ [ Cmd.map CartesianCoordinatesMsg cartesianCoordinatesCmd
+ , Cmd.map PolarCoordinatesMsg polarCoordinatesCmd
+ ]
= )
=
=
@@ -112,6 +122,15 @@ update msg model =
= , Cmd.map CartesianCoordinatesMsg cmd_
= )
=
+ PolarCoordinatesMsg msg_ ->
+ let
+ ( model_, cmd_ ) =
+ PolarCoordinates.update msg_ model.polarCoordinates
+ in
+ ( { model | polarCoordinates = model_ }
+ , Cmd.map PolarCoordinatesMsg cmd_
+ )
+
=
=subscriptions model =
= let
@@ -150,8 +169,8 @@ slides model =
= """
= ]
= :: [ markdown """
- Move sliders to change the `x` and `y` coordinates of the dot. It's like moving a thing on a table by telling how far left, right, up or down should it go.
- """
+ Move sliders to change the `x` and `y` coordinates of the dot. It's like moving a thing on a table by telling how far left, right, up or down should it go.
+ """
= , model.cartesianCoordinates
= |> CartesianCoordinates.ui
= |> Element.map CartesianCoordinatesMsg
@@ -160,17 +179,25 @@ slides model =
= , Element.width (Element.maximum 600 Element.fill)
= ]
= ]
- -- :: [ markdown """
- -- # FP-Art!
- -- ## A functional programming workshop
- -- ### for non-programmers
- -- """
- -- ]
= :: [ markdown """
- ## Setup
+ Move sliders to change the `angle` and `length` properties of the line connecting the dot and origin. The x and y coordinates will be calculated like this:
+
+ ```
+ x = cos(angle) * length
+
+ y = sin(angle) * length
+ ```
= """
- , markdown """
- # Stuff
+ , model.polarCoordinates
+ |> PolarCoordinates.ui
+ |> Element.map PolarCoordinatesMsg
+ |> Element.el
+ [ Element.centerX
+ , Element.width (Element.maximum 600 Element.fill)
+ ]
+ ]
+ :: [ markdown """
+ ## Setup
= """
= ]
= :: [ markdown """index 65f6718..7a0d79c 100644
--- a/src/PolarCoordinates.elm
+++ b/src/PolarCoordinates.elm
@@ -1,8 +1,18 @@
-module PolarCoordinates exposing (main)
+module PolarCoordinates exposing
+ ( Flags
+ , Model
+ , Msg
+ , init
+ , main
+ , subscriptions
+ , ui
+ , update
+ , view
+ )
=
=import Browser
=import CartesianPlane
-import Element
+import Element exposing (Element)
=import Element.Background as Background
=import Element.Border as Border
=import Element.Input as Input
@@ -44,95 +54,109 @@ init () =
=
=view : Model -> Html.Html Msg
=view model =
+ let
+ wrapper element =
+ Element.el
+ [ Element.width (Element.maximum 600 Element.fill), Element.centerX ]
+ element
+ in
+ ui model
+ |> wrapper
+ |> Element.layout
+ [ Element.height Element.fill
+ , Element.width Element.fill
+ ]
+
+
+ui : Model -> Element Msg
+ui model =
= let
= point =
= cartesian model
= in
- Element.layout
- [ Element.height Element.fill -- (Element.px 600)
- , Element.width Element.fill
+ Element.column
+ [ Element.width Element.fill
+ , Element.centerX
+ , Element.spacing 30
+ , Element.padding 30
= ]
- <|
- Element.column
+ [ Element.el
= [ Element.height Element.fill
- , Element.width <| Element.px 600
- , Element.centerX
- , Element.spacing 30
- , Element.padding 30
+ , Element.width Element.fill
= ]
- [ Element.el [] <|
- Element.html <|
- CartesianPlane.graph
- [ 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 )
- ]
+ <|
+ Element.html <|
+ CartesianPlane.graph
+ [ 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"
= ]
- , 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
+ []
+ , text_
+ [ x <| String.fromFloat (point.x + 0.02)
+ , y <| String.fromFloat (point.y + 0.01)
+ , Svg.Attributes.fontSize "0.03pt"
= ]
- 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
+ [ text <|
+ Debug.toString ( point.x, point.y )
= ]
- 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
- }
+ ]
+ , 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 )Create content for slides.
On by
Co-authored-by: Tadeusz Łazurski tadeusz@lazurski.pl
index f40b7a2..f18bc73 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -163,39 +163,11 @@ slides model =
= Dict.fromList <|
= List.indexedMap Tuple.pair <|
= [ markdown """
- # FP-Art!
+ # Software Garden
= ## A functional programming workshop
= ### for non-programmers
= """
= ]
- :: [ markdown """
- Move sliders to change the `x` and `y` coordinates of the dot. It's like moving a thing on a table by telling how far left, right, up or down should it go.
- """
- , model.cartesianCoordinates
- |> CartesianCoordinates.ui
- |> Element.map CartesianCoordinatesMsg
- |> Element.el
- [ Element.centerX
- , Element.width (Element.maximum 600 Element.fill)
- ]
- ]
- :: [ markdown """
- Move sliders to change the `angle` and `length` properties of the line connecting the dot and origin. The x and y coordinates will be calculated like this:
-
- ```
- x = cos(angle) * length
-
- y = sin(angle) * length
- ```
- """
- , model.polarCoordinates
- |> PolarCoordinates.ui
- |> Element.map PolarCoordinatesMsg
- |> Element.el
- [ Element.centerX
- , Element.width (Element.maximum 600 Element.fill)
- ]
- ]
= :: [ markdown """
= ## Setup
= """
@@ -215,7 +187,7 @@ slides model =
= We will need:
=
= - a text editor (I use [Atom][])
- - and [Elm programming language][]
+ - and the [Elm programming language][]
=
= [Atom]: https://atom.io/
= [Elm programming language]: https://elm-lang.org/
@@ -223,7 +195,25 @@ slides model =
= """
= ]
= :: [ markdown """
- We will use the terminal a little bit.
+ ### Elm Installation
+ """
+ ]
+ :: [ markdown """
+ To install the Elm programming language, go to the [website][Elm] and follow the installation instructions.
+
+ [Elm]: http://elm-lang.org/
+ """
+ ]
+ :: [ markdown """
+ Some of the tools we use with Elm require Node.js.
+
+ Go to the [Node.js website][Node.js] and install the current version (the green button on the right).
+
+ [Node.js]: https://nodejs.org/en/
+ """
+ ]
+ :: [ markdown """
+ We will need to use the terminal a little bit.
=
= # :fa-terminal:
=
@@ -557,4 +547,32 @@ slides model =
=
= """
= ]
+ :: [ markdown """
+ Move sliders to change the `x` and `y` coordinates of the dot. It's like moving a thing on a table by telling how far left, right, up or down should it go.
+ """
+ , model.cartesianCoordinates
+ |> CartesianCoordinates.ui
+ |> Element.map CartesianCoordinatesMsg
+ |> Element.el
+ [ Element.centerX
+ , Element.width (Element.maximum 600 Element.fill)
+ ]
+ ]
+ :: [ markdown """
+ Move sliders to change the `angle` and `length` properties of the line connecting the dot and origin. The x and y coordinates will be calculated like this:
+
+ ```
+ x = cos(angle) * length
+
+ y = sin(angle) * length
+ ```
+ """
+ , model.polarCoordinates
+ |> PolarCoordinates.ui
+ |> Element.map PolarCoordinatesMsg
+ |> Element.el
+ [ Element.centerX
+ , Element.width (Element.maximum 600 Element.fill)
+ ]
+ ]
= :: []Put slides back in MD file for easier editing
On by
Also make Git ignore Emacs temporary files.
Co-Authored-By: Sam Phillips samuel.rodney.phillips@gmail.com
index 0c19f1d..1cf77ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
=/elm-stuff
=/**/.DS_Store
=*.swp
+.#*index a2ea019..5704253 100644
--- a/index.md
+++ b/index.md
@@ -6,7 +6,45 @@ presentation:
=
=<!-- slide -->
=
-# FP-Art!
+## Conspect
+
+- Setup the development environment
+
+ - Elm
+
+ - Node.js
+
+ why?
+
+ - Test REPL (2 + 2)
+
+ - Atom
+
+
+
+- Setup the project
+
+ Do we want source control?
+
+ - Create directory
+
+ - `elm init`
+
+ - Open a file in the editor
+
+ - Type hello world program
+
+ - Elm Reactor
+
+ - Web browser
+
+
+
+
+
+<!-- slide -->
+
+# Software Garden
=## A functional programming workshop
=### for non-programmers
=
@@ -29,14 +67,34 @@ presentation:
=We will need:
=
=- a text editor (I use [Atom][])
-- and [Elm programming language][]
+- and the [Elm programming language][]
=
=[Atom]: https://atom.io/
=[Elm programming language]: https://elm-lang.org/
=
=<!-- slide -->
=
-We will use the terminal a little bit.
+### Elm Installation
+
+<!-- slide -->
+
+To install the Elm programming language, go to it's website:
+
+http://elm-lang.org/
+
+and follow the installation instructions.
+
+<!-- slide -->
+
+Some of the tools we use with Elm require Node.js.
+
+Go to the [Node.js website][Node.js] and install the current version (the green button on the right).
+
+[Node.js]: https://nodejs.org/en/
+
+<!-- slide -->
+
+We will need to use the terminal a little bit.
=
=# :fa-terminal:
=
@@ -44,13 +102,17 @@ 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>
+<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 -->
+
+<img alt="Mac Terminal app window" src="../assets/mac-terminal-window.png" class="plain"/>
=
=<!-- slide -->
=
@@ -185,7 +247,6 @@ apm install language-elm
=
=<!-- slide -->
=
-
=# First program!
=
=<!-- slide -->
@@ -236,7 +297,7 @@ atom src/Main.elm
=
=<small>This command should open a new Atom window with empty text file.</small>
=
-<!-- slide data-transition=zoom -->
+<!-- slide -->
=
=### `main.elm`
=
@@ -308,7 +369,21 @@ elm reactor
=
=<small>you can press up arrow :fa-arrow-up: on the keyboard to get to previous commands</small>
=
+
+<!-- slide -->
+
+Move sliders to change the `x` and `y` coordinates of the dot. It's like moving a thing on a table by telling how far left, right, up or down should it go.
+
+`<CartesianCoordinates program>`
+
=<!-- slide -->
=
-<iframe id="cartesian" data-src="./CartesianCoordinates.html" class="stretch">
-</iframe>
+Move sliders to change the `angle` and `length` properties of the line connecting the dot and origin. The x and y coordinates will be calculated like this:
+
+```
+x = cos(angle) * length
+y = sin(angle) * length
+```
+
+
+`<PolarCoordinates program>`Work on outline for slides
On by
index 5704253..334b686 100644
--- a/index.md
+++ b/index.md
@@ -39,6 +39,236 @@ presentation:
= - Web browser
=
=
+- Let's make a dot!
+
+ - Introduce a problem: We want to have a dot on the screen
+
+ - Show complete code
+
+ - Explain:
+
+ The dot has a position (x + y coordinates) and size (radius)
+
+ Coordinate planes: we can use CartesianCoordinates
+
+ - Introduce SVG
+
+
+- Give a color to the dot
+
+ - Explain SVG attributes (svg elements take a list of attributes)
+
+ - Everyone can pick a color
+
+
+- Multiple dots
+
+ - Introduce a problem: We want to have two dots on the screen
+
+ - Explain a list, and show there is already a list there (with one item)
+
+ Do you see any other lists?
+
+ - Element takes a list of children
+
+ - Mention, how can we have a list with one or zero elements? Shopping list with one one item. Empty spoon drawer (list of spoons)
+
+ - Give your new dot a color and different coordinates
+
+ - Show the code for 2 dots
+
+ - Exercise: make 3 more dots (5 total)
+
+
+- Place the dots in a circle
+
+ - Introduce a problem: We want to place the dots in a circle: show an example in the slides
+
+ - How we will get there: we will change the cartesian coordinates of the dots, nothing else! But figuring out the right coordinates is a bit tricky
+
+ - How can we figure out the correct cartesian coordinates?
+
+ - Story about the flowerpot and the table: two ways to measure relative position, one is distance from a x and y axis (cartesian coordinates), the other is angle and distance relative to origin (polar coordinates)
+
+ - What does this have to do with a circle? Do you know the expression 'I did a 180'. Where would you be looking if you did two 180s (a "360"). We see that circles and angles are closely related!
+
+ - Exercise with compass and 5 objects, place objects evenly along compass. How many degrees apart are they? (observe if we multiply the result by 5, we're back to 360)
+
+ - We have one part of it (angle), we now need the distance. Notice they are all the same distance from the origin (the center dot) of the compass. Definition of circle: points that are an equal distance from a center. Actually, the distance doesn't matter, so long as they all have the same distance. You can have a big circle or a small circle, they're both circles
+
+ - Ok great, we're done! Now, does anyone know how to give an angle and distance to svg? Oh... no? We don't either... you can't. You can only give x and y values relative to the origin
+
+ - So we already know that angle and length are just another way of describing x and y. But we need some way of translating between the two
+
+ Using a visual demonstration, if you draw a line from your object to the x axis, you have a triangle. Same if you draw a line to the y axis. You can figure out the point on the axis using sin and cos functions and multiplying the result by the length.
+
+ Let's use a chart to figure out the sin and cos of our angles
+
+ *It's important to get a chart, otherwise we have to use calculators which work with radians*
+
+ - Now we are done... we can plug in our x and y values, and presto, our dots are arranged in a circle. But we don't see most of them...
+
+ - Our origin is in the top left corner. This means any dots with negative x or y values are off the screen.
+
+ We can shift the dots so they are on the screen, or shift the screen so that it covers the dots. We will be shifting the screen
+
+ Sample viewbox program to demonstrate
+
+ Create a viewbox with correct perimeters (must be more than the radius of the circle plus the radius of a dot in each direction, and width and height are circumference)
+
+
+- Let the computer do the math
+
+ - Introduce the problem: Can we avoid all these repetitive and manual steps?
+
+ - What is a program made of? (in the REPL):
+
+ - Values and names
+
+ ```
+ 5
+ 10.4
+ "Hello World"
+ [1, 2, 3, 4, 5]
+ ```
+
+ Numbers, strings, lists containing numbers and strings are all values. They are self-referential. The simply state what they are. There are other kinds of values that we will see later.
+
+
+ You can give (or assign) a name to a value, as shown.
+
+ ```
+ family = 5
+ price = 10.4
+ morningGreeting = "Hello World"
+ fingers = [1, 2, 3, 4, 5]
+ ```
+
+ Here, `family` is a name and `5` is the value assigned to `family`.
+
+ You can get the value back by calling its name.
+
+ ```
+ ---- Elm 0.19.0 ----------------------------------------------------------------
+ Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
+ --------------------------------------------------------------------------------
+ > family = 5
+ 5 : number
+ > family
+ 5 : number
+ ```
+
+ - Operators (+, -, ++)
+
+ ```
+ > 2 + 5
+ 7 : number
+ ```
+
+ ```
+ > 4 - 6
+ -2 : number
+ ```
+
+ ```
+ > "Hello" ++ " world!"
+ "Hello world!" : String
+ ```
+
+ ```
+ > 1 :: [2, 3, 4, 5]
+ [1,2,3,4,5] : List number
+ ```
+
+ Operators take two values and return a new value. We know that names refer to values, so we can use them in place of values:
+
+ ```
+ > family = 5
+ 5 : number
+ > family + 2
+ 7 : number
+ ```
+
+ You can also give a name to the value returned by an operator:
+
+ ```
+ > family = 5
+ 5 : number
+ > familyAndPets = family + 2
+ 7 : number
+ > familyAndPets
+ 7 : number
+ ```
+
+ Note that different values have different types.
+
+ ```
+ 5 : number
+ 10.4 : Float
+ "Hello World" : String
+ [1,2,3,4,5] : List number
+ ```
+ Different operators work on different types. Adding a number and a string doesn't make sense. So if you try, Elm will complain (and give a helpful hint):
+
+ ```
+ > "Hello " + 5
+ -- TYPE MISMATCH ----------------------------------------------------------- elm
+
+ I cannot do addition with String values like this one:
+
+ 5| "Hello " + 5
+ ^^^^^^^^
+ The (+) operator only works with Int and Float values.
+
+ Hint: Switch to the (++) operator to append strings!
+ ```
+
+ (Int and Float are both types representing numbers)
+
+
+ - Functions
+
+ ```elm
+ fun something = something ++ " is fun."
+ ```
+
+ Mention that operators are really functions:
+
+ ```elm
+ (-) 5 10
+ 5 - 10
+ ```
+
+ - Exercise: In our Main.elm, try to identify some values, names and functions:
+
+ Hint: `"darkred"` is a value, `main` is a name, `width` is a function.
+
+ - Where can we use some functions?
+
+ - Apply to our trigonometry calculations
+
+ - Compose and copy and paste the trigonometry functions to calculate cx and cy:
+
+ ```elm
+ (String.fromFloat (sin (degrees 72) * 100))
+ (String.fromFloat (cos (degrees 72) * 100))
+ ```
+
+ - Eliminate repetition:
+
+ - define and reuse radius (100)
+
+ - define and reuse `x : angle -> cx` and `y : angle -> cy`
+
+ - define and reuse `dot : angle -> color -> Svg`
+
+ - Make it more general
+
+ - Show List and list operations (map and indexedMap)
+
+ - Make a `palette : List color`
+
+ - Use `List.indexedMap dot palette` to generate the dots
=
=
=Add more to the conspect
On by
Co-Authored-By: Sam Phillips samuel.rodney.phillips@gmail.com
index 334b686..936c34e 100644
--- a/index.md
+++ b/index.md
@@ -132,8 +132,7 @@ presentation:
= [1, 2, 3, 4, 5]
= ```
=
- Numbers, strings, lists containing numbers and strings are all values. They are self-referential. The simply state what they are. There are other kinds of values that we will see later.
-
+ Numbers, strings, lists containing numbers and strings are all values. They are self-referential. They simply state what they are. There are other kinds of values that we will see later.
=
= You can give (or assign) a name to a value, as shown.
=
@@ -232,36 +231,146 @@ presentation:
= fun something = something ++ " is fun."
= ```
=
- Mention that operators are really functions:
+ Explain: a function is a thing that takes some values (called arguments) and return one value. So it's similar to operators. In fact operators are functions!
=
= ```elm
= (-) 5 10
= 5 - 10
= ```
=
- - Exercise: In our Main.elm, try to identify some values, names and functions:
+ You can think of a function as a machine. You put something in the machine, and it produces something in return. For example think about a machine that produces rubber ducks. You put a bucket of white plastic pellets and a bucket of red paint, and you get a bunch of red rubber ducks!
+
+ What you get will depends on what you put. The color of the ducks depends on the paint you put. Quantity of ducks depends on how much plastic you put in.
+
+ ```elm
+ makeMeSomeDucks color plastic =
+ String.fromInt plastic ++ " " ++ color ++ " rubber ducks"
+ ```
+
+ Once you have a function, you can call it like this:
+
+ ```elm
+ > makeMeSomeDucks "blue" 12
+ "12 blue rubber ducks" : String
+ ```
+
+ Note: functions help organize code into nice reusable chunks.
+
+ How do you get functions? There are three ways.
+
+ 1. Some functions are always there for you, e.g. `(+)`, `(-)`
+
+ 2. Some functions you can import using code like this:
+
+ ```elm
+ import Svg
+ ```
+
+ and then
+
+ ```
+ Svg.circle [ cx "10", cy "10", r "20" ] [ ]
+ ```
+
+ To call a function that was imported, you have to prefix it with the name of the module (in this example `Svg`).
+
+ 3. Finally, you will write some functions, just like we saw in the `fun` and `makeMeSomeDucks` examples.
+
+
+ Finally there is one special thing: the first line of the program is a module declaration. For now it's enough for us to know, that it has to be there and it has to match the name of the file.
+
+ - Exercise: In our Main.elm, try to identify some values, names and function calls:
=
= Hint: `"darkred"` is a value, `main` is a name, `width` is a function.
=
+ Hint: There is nothing else there now, but we will soon introduce our own functions.
+
= - Where can we use some functions?
=
+ As we said before, functions are good when we have some repetitive operation that can be parametrized (like rubber ducks production).
+
+ Obviously calculating `x` and `y` coordinates is repetitive and can be parametrized (parameters are `radius` and `angle`).
+
= - Apply to our trigonometry calculations
=
= - Compose and copy and paste the trigonometry functions to calculate cx and cy:
=
= ```elm
- (String.fromFloat (sin (degrees 72) * 100))
- (String.fromFloat (cos (degrees 72) * 100))
+ cx (String.fromFloat (cos (degrees 72) * 100))
+ cy (String.fromFloat (sin (degrees 72) * 100))
= ```
=
= - Eliminate repetition:
=
= - define and reuse radius (100)
=
+ Assign a value of `100` to a name `radius`:
+
+ ```
+ radius = 100
+ ```
+
+ and plug it to our functions:
+
+ ```elm
+ cx (String.fromFloat (cos (degrees 72) * radius))
+ cy (String.fromFloat (sin (degrees 72) * radius))
+ ```
+
+ As you see the names are good for repetitive things too.
+
= - define and reuse `x : angle -> cx` and `y : angle -> cy`
=
+
+ ```elm
+ x angle =
+ String.fromFloat (cos (degrees angle) * radius)
+ ```
+
+ ```elm
+ y angle =
+ String.fromFloat (sin (degrees angle) * radius)
+ ```
+
+ Then plug it into the code making circles:
+
+ ```elm
+ circle
+ [ cx (x 72)
+ , cy (y 72)
+ , r "10"
+ , fill "darkred"
+ ]
+ ```
+
= - define and reuse `dot : angle -> color -> Svg`
=
+
+ ```elm
+ dot angle color =
+ circle
+ [ cx (x 72)
+ , cy (y 72)
+ , r "10"
+ , fill color
+ ]
+ ```
+
+ and plug it into our SVG picture:
+
+
+ ```
+ svg [ viewbox "-100 -100 200 200" ]
+ [ dot 0 "darkred"
+ , dot 288 "gold"
+ , dot 72 "fuchsia"
+ , dot 144 "saddlebrown"
+ , dot 216 "deepskyblue"
+ ]
+ ```
+
+ Want some more cool color inspiration. Check out https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords
+
= - Make it more general
=
= - Show List and list operations (map and indexedMap)