Commits: 8
Correction
index 67e6def..ae30437 100644
--- a/content/day-3.txt
+++ b/content/day-3.txt
@@ -321,7 +321,7 @@ Take your time. Here are some hints to help you:
=
= #. Names are given to values wherever you see a {Code|=} sign. The name is on the left and the value is below and slightly to the right. In our code we are giving only one name and it's value is quite complex. In fact the whole program is about computing this value. Try to find it.
=
- #. Functions are called wherever you see a name that have any expression to the right (or below and right) of it (like: {Code|fun "learning Elm together"}), or that stand to the left of the {Code|\|>} (pipe operator; like: {Code|"learning Elm together" \|> fun}). The expression to the right of the function (or left of pipe) is called /the argument/. Sometimes an argument is a complex expression. Some functions take more than one argument (e.g. {Code|Svg.svg} takes 2 and the second one is very complex), and sometimes one is on the right and the other comes through the pipe 🤕. There is a lot of functions called here (36 to be precise) and most are prefixed with a name of the module that exposed them to us.
+ #. Functions are called wherever you see a name that have any expression to the right (or below and right) of it (like: {Code|fun "learning Elm together"}), or that stand to the left of the {Code|\|>} (pipe operator; like: {Code|"learning Elm together" \|> fun}). The expression to the right of the function (or left of pipe) is called /the argument/. Sometimes an argument is a complex expression. Some functions take more than one argument (e.g. {Code|Svg.svg} takes 2 and the second one is very complex), and sometimes one is on the right and the other comes through the pipe 🤕. There is a lot of functions called here (36 to be precise) and all of them are prefixed with a name of the module that exposed them to us.
=
= #. Interestingly there are only two names exposed by a module that do not refer to a function. Try to find them!
=| NoteMove "We are still working ..." note to the top
index ae30437..ab7167f 100644
--- a/content/day-3.txt
+++ b/content/day-3.txt
@@ -4,6 +4,11 @@
=| Emphasize
= Connecting the Dots
=
+| Note
+ *We are still working on this content.*
+
+ Stay tuned {Icon|name=radio}
+
=| Note
= So far we have been writing the code of our program without thinking too much about what it means. Today we are going to learn about
=
@@ -240,13 +245,10 @@ We don't have to create all the functions that we need. There are thousands of t
=
=And then use any name that it exposes, like this
=
-| Note
- *We are still working on this content.*
=| Terminal
= > String.fromInt 10
= "10" : String
=
- Stay tuned {Icon|name=radio}
=If the name comes from an imported module, you need to prefix it with the name of the module, like we did above.
=
=Let's look at our code and try to recognize some literal values, lists, names and functions. Here is how it should look after day 2:
@@ -324,10 +326,7 @@ Take your time. Here are some hints to help you:
= #. Functions are called wherever you see a name that have any expression to the right (or below and right) of it (like: {Code|fun "learning Elm together"}), or that stand to the left of the {Code|\|>} (pipe operator; like: {Code|"learning Elm together" \|> fun}). The expression to the right of the function (or left of pipe) is called /the argument/. Sometimes an argument is a complex expression. Some functions take more than one argument (e.g. {Code|Svg.svg} takes 2 and the second one is very complex), and sometimes one is on the right and the other comes through the pipe 🤕. There is a lot of functions called here (36 to be precise) and all of them are prefixed with a name of the module that exposed them to us.
=
= #. Interestingly there are only two names exposed by a module that do not refer to a function. Try to find them!
-| Note
- *We are still working on this content.*
=
- Stay tuned {Icon|name=radio}
=
=
=Let's take a deeper look at how we give attributes to an SVG element.Draft section about dot function on day 3
index ab7167f..0898a8a 100644
--- a/content/day-3.txt
+++ b/content/day-3.txt
@@ -121,6 +121,8 @@ Above we applied the function (by calling it's name: {Code|fun}) to a literal va
=
= Alternatively you can think of functions as parametrized values. The value you get depends on what value you provide to it. Eggs can have different sizes . An egg painting machine would give you different painted eggs depending on what egg you put in it.
=
+ Don't worry if the concept of a function is not very clear yet. Most people have difficulty here. You will see some practical examples of functions soon.
+
=Now we see that we can get a value in three ways: (1) by literally expressing it, (2) by calling it's name and (3) by applying a function to another value.
=
=Not every function can be applied to any value. You can add two numbers (like {Code|2} and {Code|5} in {Code|2 + 5}), but you can't add a number to a string ({Code|2 + "Hello!"} - try it and see an error!). The system that governs what function can be applied to what value is called a *type system* and it plays important role in Elm programming.
@@ -327,7 +329,189 @@ Take your time. Here are some hints to help you:
=
= #. Interestingly there are only two names exposed by a module that do not refer to a function. Try to find them!
=
+| Header
+ Let's make a function
+
+Now we know what is what. Let's consider where we have a repetitive code that we could turn into a named function. If you look at the code from a distance, you can see that there is one block that is repeated 5 times almost without a difference. I'm talking about this:
+
+| Monospace
+ Svg.circle
+ [ Svg.Attributes.r "10"
+ , Svg.Attributes.cx "0"
+ , Svg.Attributes.cy "0"
+ , Svg.Attributes.fill "..."
+ , Svg.Attributes.transform "rotate(...) translate(80)"
+ ]
+ []
+
+This block of code is repeated five times in our code - once for each dot. Now I'm going to show you how to eliminate the repetition in few steps.
+
+First let's make them even more uniform by adding {Code|rotate(0)} to the first block. It will help us later. The code should look like this:
+
+| Code
+ TODO
+
+
+
+Then let's give the value produced by this block a name. We can call it the {Code|dot}. Select the first block that you have just modified, everything between {Code|[} and the {Code|,} on line 20 and cut it with {Key|command} + {Key|x}. Then in the empty space left type {Code|dot}.
+
+Move your cursor to the end of the file and type {Code|dot =}, press {Key|enter} and paste the code you cut before with {Key|command} + {Key|v}. The code should now look like this:
+
+| Code
+ TODO
+
+Reload the browser. Everything should work exactly the same as before. One of the dots is now a named value, but for our program it makes no difference. What is important is it's value, not where it comes from.
+
+Of course the goal is to have our list of dots looking like this:
+
+| Monospace
+ [ dot
+ , dot
+ , dot
+ , dot
+ , dot
+ ]
+
+Let's try it. The effect will be that all the dots will be in the same place, one on top of another. Also they will all have the same color. So on the screen you should see only one dot, somewhat to the right of center.
+
+The dots need to have some parameters so they can be different. We already identified them: it's color and rotation. Above I said that a function is a parametrized value. Let's turn our dot definition on line {Code|TODO} into a function with two parameters like this:
+
+| Code
+ TODO: Rest of the code
+
+ dot color rotation =
+ Svg.circle
+ [ Svg.Attributes.r "10"
+ , Svg.Attributes.cx "0"
+ , Svg.Attributes.cy "0"
+ , Svg.Attributes.fill "skyblue"
+ , Svg.Attributes.transform "rotate(0) translate(80)"
+ ]
+ []
+
+This way we declared that when calling a {Code|dot} name you will provide two values: first one for {Code|color} and second for {Code|rotation}. Let's stay true to our word and provide it. Change the list on lines {Code|todo} to look like this:
+
+| Code
+ TODO: Rest of the code
+
+ [ dot "skyblue" 0
+ , dot "orange" 72
+ , dot "red" 144
+ , dot "lime" 216
+ , dot "maroon" 288
+ ]
+
+Let's reload again and see that there is still only one, skyblue dot visible. That's because we did not tell Elm what to do with the values of the two parameters we provide for the {Code|dot} function. We gave them names ({Code|color} and {Code|rotation}), but never called them.
+
+First, let's use the {Code|color} parameter. If you want to change the color of the dot, you need to pass a different value to the {Code|Svg.Attributes.fill} function on line {Code|TODO}. Currently the value is a literal string {Code|"skyblue"}. Instead we want to give it whatever value was given for the {Code|color} parameter. We do it by simply calling the name of the parameter in place of a literal value, like this:
+
+
+| Code
+ TODO: Rest of the code
+
+ dot color rotation =
+ Svg.circle
+ [ Svg.Attributes.r "10"
+ , Svg.Attributes.cx "0"
+ , Svg.Attributes.cy "0"
+ , Svg.Attributes.fill color
+ , Svg.Attributes.transform "rotate(0) translate(80)"
+ ]
+ []
+
+Now let's do the same for rotation. This one is more complex, because we cannot just pass {Code|rotation} value to the {Code|Svg.Attributes.transform} function. The {Code|rotation} is just a number, while the function expects a string formatted like this: {Code|"rotate(...) translate(80)"}.
+
+We can use the {Code|++} operator to glue the strings together. First part is constant, so we can just give it a literal value of {Code|"rotate("}. After that we put the {Code|++} and our variable part: {Code|rotation}. Finally the rest of the string is also constant: {Code|" translate(80)"} (notice the space before {Code|translate}!). All together we have:
+
+| Code
+ TODO: Rest of the code
+
+ dot color rotation =
+ Svg.circle
+ [ Svg.Attributes.r "10"
+ , Svg.Attributes.cx "0"
+ , Svg.Attributes.cy "0"
+ , Svg.Attributes.fill color
+ , Svg.Attributes.transform "rotate(" ++ rotation ++ ") translate(80)"
+ ]
+ []
+
+But Elm will complain about this. First it looks like we gave 5 arguments to the {Code|Svg.Attributes.transform} function, and it only takes one. We can fix it by putting a parentheses around the {Code|"rotate(" ++ rotation ++ ") translate(80)" }, basically telling Elm that this is a single expression and it should evaluate it's value before passing it to the {Code|Svg.Attributes.transform} function. Now it should look like this:
+
+| Code
+ TODO: Rest of the code
+
+ dot color rotation =
+ Svg.circle
+ [ Svg.Attributes.r "10"
+ , Svg.Attributes.cx "0"
+ , Svg.Attributes.cy "0"
+ , Svg.Attributes.fill color
+ , Svg.Attributes.transform ("rotate(" ++ rotation ++ ") translate(80)")
+ ]
+ []
+
+Here we face another problem. Elm complains with the following:
+
+| Monospace
+ TODO: Provide error message. Make sure the line and column numbers are correct.
+
+It's the type system in action. We can only use {Code|++} function with both arguments being the same type. Here one argument is:
+
+| Monospace
+ "rotate(" : String
+
+and another is:
+
+| Monospace
+ rotation : Float
+
+Elm won't have that. Fortunately there is an easy way to satisfy the type system. The {Code|String.fromFloat} takes a {Code|Float} and gives a {Code|String}. Try it in the REPL:
+
+| Terminal
+ > String.fromFloat
+ <function> : Float -> String
+
+ > String.fromFloat 10
+ "10" : String
+
+ > String.fromFloat 10.2
+ "10.2" : String
+
+That's what we need! Let's pass the value of {Code|rotation} through this function like this:
+
+| Code
+ TODO: Rest of the code
+
+ dot color rotation =
+ Svg.circle
+ [ Svg.Attributes.r "10"
+ , Svg.Attributes.cx "0"
+ , Svg.Attributes.cy "0"
+ , Svg.Attributes.fill color
+ , Svg.Attributes.transform ("rotate(" ++ (String.fromFloat rotation) ++ ") translate(80)")
+ ]
+ []
+
+| Code
+ IDEA: What if we use String.concat instead?
+
+ dot color rotation =
+ Svg.circle
+ [ Svg.Attributes.r "10"
+ , Svg.Attributes.cx "0"
+ , Svg.Attributes.cy "0"
+ , Svg.Attributes.fill color
+ , Svg.Attributes.transform (String.concat
+ [ "rotate("
+ , String.fromFloat rotation
+ , ") translate(80)"
+ ]
+ )
+ ]
+ []
=
+This should work! The browser should now present the dots as intended and I would argue that the code is more readable now.
=
=Let's take a deeper look at how we give attributes to an SVG element.
=Draft section about line function on day 3
index 0898a8a..80cf295 100644
--- a/content/day-3.txt
+++ b/content/day-3.txt
@@ -513,6 +513,111 @@ That's what we need! Let's pass the value of {Code|rotation} through this functi
=
=This should work! The browser should now present the dots as intended and I would argue that the code is more readable now.
=
+| Header
+ Lines to Connect the Dots
+
+Armed with our functional superpowers, let's make another function that draws a line. Let me fist show you a complete code and then we can discuss it.
+
+| Code
+ line color rotation =
+ Svg.line
+ [ Svg.Attributes.strokeWidth "1"
+ , Svg.Attributes.x1 "0"
+ , Svg.Attributes.y1 "0"
+ , Svg.Attributes.x1 "80"
+ , Svg.Attributes.y1 "0"
+ , Svg.Attributes.stroke color
+ , Svg.Attributes.transform
+ (String.concat
+ [ "rotate("
+ , String.fromFloat rotation
+ , ")"
+ ]
+ )
+ ]
+ []
+
+It works similar to the {Code|dot} function so you can just copy and past the it. Then apply the following changes:
+
+| List
+ #. The name needs to be different. {Code|line} seems appropriate.
+
+ #. Instead of a {Code|Svg.circle} we will call the {Code|Svg.line} function
+
+ #. The line doesn't have a radius, so remove the first attribute, {Code|Svg.Attributes.r}.
+
+ #. The line goes from one point to another, so it has four coordinates {Code|x1} and {Code|y1} for the beggening, {Code|x2} and {Code|y2} for the end. Beggening should be in the middle of the circle, which is {Code|x=0, y=0} (/the origin/). We will make the end reach to the big circle by giving the {Code|x2} value of {Code|80} (same as a radius of the circle).
+
+ #. Line can't be filled, as it has no area. Instead we give it a color using {Code|Svg.Attributes.stroke} function.
+
+ #. We do not need to translate the line. It's enough to rotate it.
+
+Once you have the function defined, let's use it. For every dot, create one line, like so:
+
+| Code
+ module Main exposing (main)
+
+ import Element
+ import Svg
+ import Svg.Attributes
+
+
+ main =
+ [ dot "skyblue" 0
+ , line "skyblue" 0
+ , dot "orange" 72
+ , line "orange" 72
+ , dot "red" 144
+ , dot "lime" 216
+ , dot "maroon" 288
+ ]
+ |> Svg.svg
+ [ Svg.Attributes.height "100%"
+ , Svg.Attributes.width "100%"
+ , Svg.Attributes.style "background: none"
+ , Svg.Attributes.viewBox "-100 -100 200 200"
+ ]
+ |> Element.html
+ |> Element.layout
+ [ Element.width Element.fill
+ , Element.height Element.fill
+ ]
+
+
+ dot color rotation =
+ Svg.circle
+ [ Svg.Attributes.r "10"
+ , Svg.Attributes.cx "0"
+ , Svg.Attributes.cy "0"
+ , Svg.Attributes.fill color
+ , Svg.Attributes.transform
+ (String.concat
+ [ "rotate("
+ , String.fromFloat rotation
+ , ") translate(80)"
+ ]
+ )
+ ]
+ []
+
+
+ line color rotation =
+ Svg.line
+ [ Svg.Attributes.strokeWidth "1"
+ , Svg.Attributes.x1 "0"
+ , Svg.Attributes.y1 "0"
+ , Svg.Attributes.x1 "80"
+ , Svg.Attributes.y1 "0"
+ , Svg.Attributes.stroke color
+ , Svg.Attributes.transform
+ (String.concat
+ [ "rotate("
+ , String.fromFloat rotation
+ , ")"
+ ]
+ )
+ ]
+ []
=Let's take a deeper look at how we give attributes to an SVG element.
=
=We've already seen a few example of SVG attributes. The radius of our dot ({Code|circle}) is an attribute.Remove SVG gradients from curriculum for day 3
Remove the content pieces from the bottom.
index 80cf295..15d5af6 100644
--- a/content/day-3.txt
+++ b/content/day-3.txt
@@ -17,7 +17,7 @@
= - Functions
= - Modules
= - Types
- - SVG gradients
+ - SVG lines
=
=Before we begin, let's reflect on the following.
=
@@ -618,175 +618,17 @@ Once you have the function defined, let's use it. For every dot, create one line
= )
= ]
= []
-Let's take a deeper look at how we give attributes to an SVG element.
=
-We've already seen a few example of SVG attributes. The radius of our dot ({Code|circle}) is an attribute.
+You should see something like this in the browser:
=
-| Code
- Svg.circle [ Svg.Attributes.r "10" ] []
-
-Try giving it a new value to see your dot grow or shrink.
-
-Our viewBox is also an attribute. It's an attribute of the {Code|svg} element.
-
-| Code
- Svg.svg
- [ Svg.Attributes.viewBox "-300 -300 600 600" ]
- [ Svg.circle [ Svg.Attributes.r "10" ] [] ]
-
-Again, try giving it new values. As we saw earlier, the first two values (which represent the left and top of the viewBox) must be equal to the negative of the half of the last two values (which correspond to width and height). Try other combinations of values to adjust the placement of the dot. If the behavior of the viewBox is difficult to understand, refer again to the interactive tutorial above.
-
-To color our dot, we'll have to give it a second attribute. Many SVG elements take a {Code|List} of attributes. A {Code|List} is a very important concept in software development. {Code|Lists} allow us to group an arbitary number of similar values. In this case, we'll be using a {Code|List} to group {Code|Attribute a} values. Whenever you see {Code|[...]} in an Elm source code file, you are dealing with a list.
-
-Before we give a color to our dot, try to identify all the lists in the code we're writen already. There are 5. Hint: It is possible for a list to have only 1 or 0 items ({Code|[]}).
-
-| Code
- Svg.circle [ Svg.Attributes.r "10" ] []
-
-When we take a look at the code responsible for creating our dot, we see that it is followed by two lists. We'll only need to worry about the first one at the moment. As we've discussed, the first list already contains the {Code|r} attribute of the circle, representing the radius. We'll need to add a second attribute to the circle. We use a comma ({Code|,}) to separate elements in a list.
-
-| Code
- Svg.circle [ Svg.Attributes.r "10", ... ] []
-
-To color our circle, we'll use the {Code|fill} attribute.
-
-| Code
- Svg.circle
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "blue"
- ]
- []
-
-You should see this result:
-
-| Window
- | DotWithViewBox
- background=none
- fill=blue
- viewBox=-300 -300 600 600
-
-Let's use our new understanding of lists to do something a bit more interesting. Let's draw multiple dots!
-
-We can start by taking a look at our {Code|main} value:
-
-| Code
- main =
- Element.layout
- [ Element.width Element.fill
- , Element.height Element.fill
- ]
- (Element.html
- (Svg.svg
- [ Svg.Attributes.viewBox "-500 -500 1000 1000"
- ]
- [ Svg.circle
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "blue"
- ]
- []
- ]
- )
- )
-
-Where is our list of circles? To find it, first find the circle.
-
-| Code
- Svg.circle
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "blue"
- ]
- []
-
-Next, identify the first open square bracket {Code|[} before the circle.
-
-| Code
- [ Svg.circle
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "blue"
- ]
- []
- ...
-
-This is where the list begins.
-
-Finally, identify the matching closing brakcet {Code|]}. This is a bit tricky because there are two lists within this list. The first is the list of attributes to the circle we saw earlier. The second is an empty list. We'll see exactly what they do in a moment. Ignore both of these for now. The matching closing bracket should be on the same indentation level as the opening bracket. Your text editor should be able to help you here. When you move your cursor before the opening bracket, the closing bracket should be highlighted.
-
-| Code
- [ Svg.circle
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "blue"
- ]
- []
- ]
-
-Right now, our list of circles has one value. We want to give it a second value. The second value will look identical to the first. What is the first value?
-
-| Code
- Svg.circle
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "blue"
- ]
- []
-
-It might not seem obvious at first that this is all one value. But it is. {Code|Svg.circle} takes two lists as arguments. We'll see what an argument is later. For now, we will need to understand the difference between an attribute and a child.
-
-Imagine a box of colored easter eggs. One egg is painted yellow, another red, another blue. Moreover, they don't all come from the same bird. One is a small robin's egg. Another is a medium chicken egg. Another is a huge ostrich egg.
-
-Some of the elements in our image are 'things'. A box is a thing. Each egg is also a thing. Some of the elements in our image are not things. Blueness is not a thing. Medium-sizeness is not a thing. You can see blueness. You can see medium-sizeness. But they are not things. They are attributes of a thing. A thing can be blue. It can be medium-sized.
-
-It is a convention in many programming languages, including Elm and SVG, to distinguish between the attributes and children of an element. If we wanted to represent our box in SVG, we would give our box several attributes. It would have a color (maybe brown). It would have a width, length, depth. We would also give it several children. Each of the eggs within the box would be a child of the box. A box with 6 eggs would have 6 children. Each of these children (the eggs) would have different attributes: blue, red, medium-sized, etc. The children of an element are the 'things' it contains. The attributes of a thing are the elements that describe it.
-
-The first list following {Code|Svg.circle} is:
-
-| Code
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "blue"
- ]
-
-This is a list of attributes. A radius is not a 'thing'. A fill color is not a 'thing'. They are elements that describe a thing. They describe our circle.
-
-The second list is:
-
-| Code
- []
-
-It is an empty list. Nevertheless, it is a list of children. Our circles don't have any children.
-
-Is the circle itself an attribute or a thing?
-
-From Elm's perspective, this entire code block is a circle:
-
-| Code
- Svg.circle
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "blue"
- ]
- []
-
-This is not a circle:
-
-| Code
- Svg.circle
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "blue"
- ]
-
-Nor is this:
+| Monospace
+ TODO: Example showing the connected dots
=
-| Code
- Svg.circle
+| Emphasize
+ Congratulations!
=
-To create a list with two circles, we'll want to duplicate the properly formed circle value. You can give the second dot a different color from the first.
+| Emphasize
+ {Icon|name=award}
=
-| Code
- [ Svg.circle
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "blue"
- ]
- []
- , Svg.circle
- [ Svg.Attributes.r "10"
- , Svg.Attributes.fill "red"
- ]
- []
- ]
+| Emphasize
+ You are ready for {Link|Day 4|url=/day-4.html}!Correct typos
index d1fc7a3..7a9f8a4 100644
--- a/content/day-1.txt
+++ b/content/day-1.txt
@@ -289,7 +289,7 @@ One method is to use the *cartesian coordinates system*. To get some intuition a
=| Note
= TODO: Image of the table, the flower pot and the villain
=
-However, if you had a ruler, you could say: "it's 63.3cm from the top edge and 27.1cm from the left edge". To do that you would have previously agree which edge is left and which is top - not so obvious in case of a table. Fortunately in SVG we have this sort of agreement made for us. We alsways measure from the top and left edge of the viewport.
+However, if you had a ruler, you could say: "it's 63.3cm from the top edge and 27.1cm from the left edge". To do that you would have previously agree which edge is left and which is top - not so obvious in case of a table. Fortunately in SVG we have this sort of agreement made for us. We always measure from the top and left edge of the viewport.
=
=The distance from the left edge is called {Code|x} and the distance from the top is called {Code|y}. The bigger the {Code|x} the more to the right goes the element. The bigger the {Code|y} the more it goes down. Try it out:
=
@@ -302,7 +302,7 @@ The distance from the left edge is called {Code|x} and the distance from the top
=
=Adjust the sliders below to change the {Code|x} and {Code|y} coordinates of the dot. It's like moving the flower pot on the table by describing how far left, right, up or down it should be.
=
-Initially the center of the dot is at a point called /the origin/ or {Code|\{ x = 0, y = 0\\}}. The origin is in the top left corner of the viewport. That's why only quarter of the dot is visible. If we want to help our dot get out of hiding, we'll have to place the center of the dot at a point with positive {Code|x} and {Code|y} values.
+Initially the center of the dot is at a point called /the origin/ or {Code|\{ x = 0, y = 0\\}}. The origin is in the top left corner of the viewport. That's why only a quarter of the dot is visible. If we want to help our dot get out of hiding, we'll have to place the center of the dot at a point with positive {Code|x} and {Code|y} values.
=
=To change the position of the dot, we can use the {Code|cx} and {Code|cy} attributes of the {Code|circle} element, like this:
=
@@ -412,7 +412,7 @@ In the code we set the viewbox as an attribute of the {Code|svg} element, like t
= , Element.height Element.fill
= ]
=
-There are only two changes here. First we reset the {Code|cx} and {Code|cy} attributes of the {Code|circle} back to {Code|"0"} (on lines 11 and 12). We want the dot to be back at origin. Then we set up the position of the viewbox on line 20. Try experimenting with different values. If you set them right and refresh the broswer the dot should be in the center of the screen.
+There are only two changes here. First we reset the {Code|cx} and {Code|cy} attributes of the {Code|circle} back to {Code|"0"} (on lines 11 and 12). We want the dot to be back at origin. Then we set up the position of the viewbox on line 20. Try experimenting with different values. If you set them right and refresh the browser the dot should be in the center of the screen.
=
=| Window
= | DotWithViewBox
@@ -425,7 +425,7 @@ You can also remove line 19 to remove the pink background, or set it to some oth
=| Header
= Color
=
-Speaking of colors, now that we've centered our dot, it's time to give it a color! We do it by adding an {Code|fill} attribute to the {Code|circle} element, like that:
+Speaking of colors, now that we've centered our dot, it's time to give it a color! We do it by adding a {Code|fill} attribute to the {Code|circle} element, like that:
=
=| Code
= module Main exposing (main)index af026fb..8161521 100644
--- a/content/day-2.txt
+++ b/content/day-2.txt
@@ -5,7 +5,7 @@
= Let's Place the Dots in a Circle
=
=| Note
- Today we are going to lear about
+ Today we are going to learn about
=
= | List
= - SVG transformations
@@ -324,7 +324,7 @@ Now, notice that the dots displayed by the program we are creating are not layin
= radius = 80
= scatter = False
=
-On the right, you immediately see a patern. They form a circle. But in fact both pictures are showing 5 dots laying on a circle. Look:
+On the right, you immediately see a pattern. They form a circle. But in fact both pictures are showing 5 dots laying on a circle. Look:
=
=| Row
= | Circle
@@ -451,7 +451,7 @@ We will start from where we left off yesterday. Open {Code|src//Main.elm} in you
= , Element.height Element.fill
= ]
=
-It's a good starting point. We already have a single dot in the middle. Let's say this is will be the center of our circle.
+It's a good starting point. We already have a single dot in the middle. Let's say this will be the center of our circle.
=
=Now it's time to introduce our protractor and ruler. These is a property of an SVG element called `transform`. You use it like that:
=
@@ -537,7 +537,7 @@ For that we need to add another transformation before the move. First we will ro
= []
= ]
=
-This will rotate the element by 72 degrees. On it's own it wouldn't make any difference, because the dot is round - it doesn't matter how you rotate it, it always looks the same. But It also rotates it's internal coordinates system. So the translation will move it in a different direction then the first dot.
+This will rotate the element by 72 degrees. On its own it wouldn't make any difference, because the dot is round - it doesn't matter how you rotate it, it always looks the same. But It also rotates its internal coordinates system. So the translation will move it in a different direction then the first dot.
=
=Now it's time to add the third, red dot. Duplicate the second one, change fill to `"red"` and put `144` for rotate function, like this:
=index 5780836..4125171 100644
--- a/content/day-3.txt
+++ b/content/day-3.txt
@@ -5,7 +5,7 @@
= Connecting the Dots
=
=| Note
- So far we have been writing the code of our program without thinking too much about about what it means. Today we are going to learn about
+ So far we have been writing the code of our program without thinking too much about what it means. Today we are going to learn about
=
= | List
= - Values and names
@@ -83,7 +83,7 @@ Now let's focus our attention to *names*. You can give any value a name.
= "Hello!" : String
= >
=
-From now on you can refer to this value either literally or by it's name:
+From now on you can refer to this value either literally or by its name:
=
=| Terminal
= > kittens
@@ -109,19 +109,19 @@ Here we gave a name {Code|fun} to a function, that given {Code|something} will p
= > fun "Learning Elm"
= "Learning Elm is fun!" : String
=
-Above we applied the function (by calling it's name: {Code|fun}) to a literal value: {Code|"Learning Elm"}. In return the function produced another value: {Code|"Learning Elm is fun!"}. So a function takes a value and gives a value. But function itself is also a value.
+Above we applied the function (by calling its name: {Code|fun}) to a literal value: {Code|"Learning Elm"}. In return the function produced another value: {Code|"Learning Elm is fun!"}. So a function takes a value and gives a value. But function itself is also a value.
=
=| Note
= Imagine a machine that paints eggs. You put an egg into the machine and on the other side you get a painted egg. The egg is a thing and the painted egg is also a thing. But so is the machine!
=
-Now we see that we can get a value in three ways: (1) by literally expressing it, (2) by calling it's name and (3) by applying a function to another value.
+Now we see that we can get a value in three ways: (1) by literally expressing it, (2) by calling its name and (3) by applying a function to another value.
=
-Not every function can be applied to any value. You can add two numbers (like {Code|2} and {Code|5} in {Code|2 + 5}), but you can't a number to a string ({Code|2 + "Hello!"} - try it and see an error!). The system that governs what function can be applied to what value is called a *type system* and it plays important role in Elm programming.
+Not every function can be applied to any value. You can add two numbers (like {Code|2} and {Code|5} in {Code|2 + 5}), but you can't add a number to a string ({Code|2 + "Hello!"} - try it and see an error!). The system that governs what function can be applied to what value is called a *type system* and it plays important role in Elm programming.
=
=| Note
= Again, imagine a machine that paints eggs. If you try to put a carrot in that machine, the dumb machine would make a mess of your carrot and probably jam. But a smart machine would sound a low pitch buzz and simply refuse to take the carrot. That way a smart machine avoids making a mess and possibly damaging itself. The Elm's type system is what makes your functions smart. It stops you from putting a carrot into the egg painting machine!
=
-Every value in Elm has a type. You can see the type in the REPL - after evaluating the expression it shows it's value and the type, like here:
+Every value in Elm has a type. You can see the type in the REPL - after evaluating the expression it shows its value and the type, like here:
=
=| Terminal
= > kittens
@@ -141,7 +141,7 @@ Composite values like lists have composite types. For example here the type is {
= > [ "Hello", "Good bye" ]
= ["Hello","Good bye"] : List String
=
-This means that it's a list of strings. That means that all the elements of this list are of type {Code|String}. When talking about lists you have to tell that it's a list and what is the type of it's element. Only this can be considered a fully specified type. Compare:
+This means that it's a list of strings. That means that all the elements of this list are of type {Code|String}. When talking about lists you have to tell that it's a list and what is the type of its element. Only this can be considered a fully specified type. Compare:
=
=| Terminal
= > [ 1, 2, 3 ]
@@ -177,12 +177,12 @@ What's the type of an empty list? Let's see:
= > []
= [] : List a
=
-A list of {Code|a}. Obviously {Code|a} is not a type. This means that the type of the elements cannot be determine yet. This is signaled by the lowercase term where the type should be: {Code|a} instead of the capitalized {Code|String}.
+A list of {Code|a}. Obviously {Code|a} is not a type. This means that the type of the elements cannot be determined yet. This is signaled by the lowercase term where the type should be: {Code|a} instead of the capitalized {Code|String}.
=
=| Note
= Notice that the {Code|number} (type of value {Code|15} for example} is also lowercase. That's because it's also not a concrete type! Elm has two concrete types for numbers: {Code|Int} that can represent an integer number (1, 2, 3, 0, -122 etc.) and {Code|Float} that can represent a number with a fraction, (like 1.2, -3.5, 44.2). Because fraction part can be 0 (e.g. 1.0, 2.0, 0.0, -122.0 - so called whole numbers), it's not possible to tell if {Code|2} is an {Code|Int} or a {Code|Float}. We will see some of the implications of this later.
=
-Above I said that every value has a type and also that a function is a value on it's own. Let's try the following in REPL:
+Above I said that every value has a type and also that a function is a value on its own. Let's try the following in REPL:
=
=| Terminal
= > fun
@@ -198,7 +198,7 @@ The part expressed as {Code|"Learning Elm"} is a {Code|String} (we recognize it
=
=The part after the arrow symbol is the type that the function returns. It is also {Code|String}. That also should not surprise us, since {Code|"Learning Elm is fun!"} is also a {Code|String}.
=
-Not every function returns the same type as it takes. For example function {Code|String.fromInt} takes a value of type {Code|Int} and returns a value of type {Code|String}. It's type is therefor {Code|Int -> String}. We read it as: /type of String.fromInt is a function from Int to String/. Let's see it in action:
+Not every function returns the same type as it takes. For example function {Code|String.fromInt} takes a value of type {Code|Int} and returns a value of type {Code|String}. Its type is therefor {Code|Int -> String}. We read it as: /type of String.fromInt is a function from Int to String/. Let's see it in action:
=
=| Terminal
= > String.fromInt 10
@@ -257,9 +257,9 @@ Our viewBox is also an attribute. It's an attribute of the {Code|svg} element.
=
=Again, try giving it new values. As we saw earlier, the first two values (which represent the left and top of the viewBox) must be equal to the negative of the half of the last two values (which correspond to width and height). Try other combinations of values to adjust the placement of the dot. If the behavior of the viewBox is difficult to understand, refer again to the interactive tutorial above.
=
-To color our dot, we'll have to give it a second attribute. Many SVG elements take a {Code|List} of attributes. A {Code|List} is a very important concept in software development. {Code|Lists} allow us to group an arbitary number of similar values. In this case, we'll be using a {Code|List} to group {Code|Attribute a} values. Whenever you see {Code|[...]} in an Elm source code file, you are dealing with a list.
+To color our dot, we'll have to give it a second attribute. Many SVG elements take a {Code|List} of attributes. A {Code|List} is a very important concept in software development. {Code|Lists} allow us to group an arbitrary number of similar values. In this case, we'll be using a {Code|List} to group {Code|Attribute a} values. Whenever you see {Code|[...]} in an Elm source code file, you are dealing with a list.
=
-Before we give a color to our dot, try to identify all the lists in the code we're writen already. There are 5. Hint: It is possible for a list to have only 1 or 0 items ({Code|[]}).
+Before we give a color to our dot, try to identify all the lists in the code we have written already. There are 5. Hint: It is possible for a list to have only 1 or 0 items ({Code|[]}).
=
=| Code
= Svg.circle [ Svg.Attributes.r "10" ] []
@@ -330,7 +330,7 @@ Next, identify the first open square bracket {Code|[} before the circle.
=
=This is where the list begins.
=
-Finally, identify the matching closing brakcet {Code|]}. This is a bit tricky because there are two lists within this list. The first is the list of attributes to the circle we saw earlier. The second is an empty list. We'll see exactly what they do in a moment. Ignore both of these for now. The matching closing bracket should be on the same indentation level as the opening bracket. Your text editor should be able to help you here. When you move your cursor before the opening bracket, the closing bracket should be highlighted.
+Finally, identify the matching closing bracket {Code|]}. This is a bit tricky because there are two lists within this list. The first is the list of attributes to the circle we saw earlier. The second is an empty list. We'll see exactly what they do in a moment. Ignore both of these for now. The matching closing bracket should be on the same indentation level as the opening bracket. Your text editor should be able to help you here. When you move your cursor before the opening bracket, the closing bracket should be highlighted.
=
=| Code
= [ Svg.circleMerge branch 'content' into content-fix
Correct typos and grammatical error
index f70e581..03a2ca8 100644
--- a/content/day-3.txt
+++ b/content/day-3.txt
@@ -59,7 +59,7 @@ Some value literals are simple, like numbers and strings. Some are complex. Prev
= > [ 1, 2, 5, 77, 2 ]
= [1,2,5,77.6,2] : List number
=
-First notice that a list literal starts with {Code|[} and ends with {Code|]}. Inside there are values called /elements of the list/. Each element is separated from others with a {Code|,} (comma). Then notice that each element is a value on it's own, but the whole list is also a value.
+First notice that a list literal starts with {Code|[} and ends with {Code|]}. Inside there are values called /elements of the list/. Each element is separated from others with a {Code|,} (comma). Then notice that each element is a value on its own, but the whole list is also a value.
=
=| Note
= It can be called a /composite value/. It's like the box of eggs. Each egg is a thing, but the box of eggs is also a thing (composed of the box and the eggs).
@@ -119,7 +119,7 @@ Above we applied the function (by calling its name: {Code|fun}) to a literal val
=| Note
= Imagine a machine that paints eggs. You put an egg into the machine and on the other side you get a painted egg. The egg is a thing and the painted egg is also a thing. But so is the machine!
=
- Alternatively you can think of functions as parametrized values. The value you get depends on what value you provide to it. Eggs can have different sizes . An egg painting machine would give you different painted eggs depending on what egg you put in it.
+ Alternatively you can think of functions as parameterized values. The value you get depends on what value you provide to it. Eggs can have different sizes . An egg painting machine would give you different painted eggs depending on what egg you put in it.
=
= Don't worry if the concept of a function is not very clear yet. Most people have difficulty here. You will see some practical examples of functions soon.
=
@@ -189,7 +189,7 @@ What's the type of an empty list? Let's see:
=A list of {Code|a}. Obviously {Code|a} is not a type. This means that the type of the elements cannot be determined yet. This is signaled by the lowercase term where the type should be: {Code|a} instead of the capitalized {Code|String}.
=
=| Note
- Notice that the {Code|number} (type of value {Code|15} for example) is also lowercase. That's because it's also not a concrete type! Elm has two concrete types for numbers: {Code|Int} that can represent an integer number (1, 2, 3, 0, -122 etc.) and {Code|Float} that can represent a number with a fraction, (like 1.2, -3.5, 44.2). Because fraction part can be 0 (e.g. 1.0, 2.0, 0.0, -122.0 - so called whole numbers), it's not possible to tell if {Code|2} is an {Code|Int} or a {Code|Float}. We will see some of the implications of this later.
+ Notice that the {Code|number} (type of value {Code|15} for example) is also lowercase. That's because it's not a concrete type! Elm has two concrete types for numbers: {Code|Int} that can represent an integer number (1, 2, 3, 0, -122 etc.) and {Code|Float} that can represent a number with a fraction, (like 1.2, -3.5, 44.2). Because fraction part can be 0 (e.g. 1.0, 2.0, 0.0, -122.0 - so called whole numbers), it's not possible to tell if {Code|2} is an {Code|Int} or a {Code|Float}. We will see some of the implications of this later.
=
=Above I said that every value has a type and also that a function is a value on its own. Let's try the following in REPL:
=
@@ -327,7 +327,7 @@ Take your time. Here are some hints to help you:
=
= #. Functions are called wherever you see a name that have any expression to the right (or below and right) of it (like: {Code|fun "learning Elm together"}), or that stand to the left of the {Code|\|>} (pipe operator; like: {Code|"learning Elm together" \|> fun}). The expression to the right of the function (or left of pipe) is called /the argument/. Sometimes an argument is a complex expression. Some functions take more than one argument (e.g. {Code|Svg.svg} takes 2 and the second one is very complex), and sometimes one is on the right and the other comes through the pipe 🤕. There is a lot of functions called here (36 to be precise) and all of them are prefixed with a name of the module that exposed them to us.
=
- #. Interestingly there are only two names exposed by a module that do not refer to a function. Try to find them!
+ #. Interestingly there is only one name exposed by a module that do not refer to a function. Try to find it!
=
=| Header
= Let's make a function
@@ -360,7 +360,7 @@ Move your cursor to the end of the file and type {Code|dot =}, press {Key|enter}
=| Code
= TODO
=
-Reload the browser. Everything should work exactly the same as before. One of the dots is now a named value, but for our program it makes no difference. What is important is it's value, not where it comes from.
+Reload the browser. Everything should work exactly the same as before. One of the dots is now a named value, but for our program it makes no difference. What is important is its value, not where it comes from.
=
=Of course the goal is to have our list of dots looking like this:
=
@@ -374,7 +374,7 @@ Of course the goal is to have our list of dots looking like this:
=
=Let's try it. The effect will be that all the dots will be in the same place, one on top of another. Also they will all have the same color. So on the screen you should see only one dot, somewhat to the right of center.
=
-The dots need to have some parameters so they can be different. We already identified them: it's color and rotation. Above I said that a function is a parametrized value. Let's turn our dot definition on line {Code|TODO} into a function with two parameters like this:
+The dots need to have some parameters so they can be different. We already identified them: color and rotation. Above I said that a function is a parametrized value. Let's turn our dot definition on line {Code|TODO} into a function with two parameters like this:
=
=| Code
= TODO: Rest of the code
@@ -436,7 +436,7 @@ We can use the {Code|++} operator to glue the strings together. First part is co
= ]
= []
=
-But Elm will complain about this. First it looks like we gave 5 arguments to the {Code|Svg.Attributes.transform} function, and it only takes one. We can fix it by putting a parentheses around the {Code|"rotate(" ++ rotation ++ ") translate(80)" }, basically telling Elm that this is a single expression and it should evaluate it's value before passing it to the {Code|Svg.Attributes.transform} function. Now it should look like this:
+But Elm will complain about this. First it looks like we gave 5 arguments to the {Code|Svg.Attributes.transform} function, and it only takes one. We can fix it by putting a parentheses around the {Code|"rotate(" ++ rotation ++ ") translate(80)" }, basically telling Elm that this is a single expression and it should evaluate its value before passing it to the {Code|Svg.Attributes.transform} function. Now it should look like this:
=
=| Code
= TODO: Rest of the code
@@ -511,12 +511,12 @@ That's what we need! Let's pass the value of {Code|rotation} through this functi
= ]
= []
=
-This should work! The browser should now present the dots as intended and I would argue that the code is more readable now.
+This should work! The browser should now present the dots as intended and I would agree that the code is more readable now.
=
=| Header
= Lines to Connect the Dots
=
-Armed with our functional superpowers, let's make another function that draws a line. Let me fist show you a complete code and then we can discuss it.
+Armed with our functional superpowers, let's make another function that draws a line. Let me first show you a complete code and then we can discuss it.
=
=| Code
= line color rotation =
@@ -537,7 +537,7 @@ Armed with our functional superpowers, let's make another function that draws a
= ]
= []
=
-It works similar to the {Code|dot} function so you can just copy and past the it. Then apply the following changes:
+It works similar to the {Code|dot} function so you can just copy and paste it. Then apply the following changes:
=
=| List
= #. The name needs to be different. {Code|line} seems appropriate.
@@ -546,7 +546,7 @@ It works similar to the {Code|dot} function so you can just copy and past the it
=
= #. The line doesn't have a radius, so remove the first attribute, {Code|Svg.Attributes.r}.
=
- #. The line goes from one point to another, so it has four coordinates {Code|x1} and {Code|y1} for the beggening, {Code|x2} and {Code|y2} for the end. Beggening should be in the middle of the circle, which is {Code|x=0, y=0} (/the origin/). We will make the end reach to the big circle by giving the {Code|x2} value of {Code|80} (same as a radius of the circle).
+ #. The line goes from one point to another, so it has four coordinates {Code|x1} and {Code|y1} for the beginning, {Code|x2} and {Code|y2} for the end. Beginning should be in the middle of the circle, which is {Code|x=0, y=0} (/the origin/). We will make the end reach to the big circle by giving the {Code|x2} value of {Code|80} (same as a radius of the circle).
=
= #. Line can't be filled, as it has no area. Instead we give it a color using {Code|Svg.Attributes.stroke} function.
=