added list and table styling, also migrated all the SLSW blogs

This commit is contained in:
Rick van Lieshout 2022-09-18 22:26:24 +02:00
parent 74082cd463
commit 54e3e0d450
21 changed files with 3628 additions and 2803 deletions

View File

@ -11,3 +11,27 @@ disqusId: "25"
---
Servers.... Both a joy and a pain. This week my server has just been a pain though.... What should've been a relaxing night with some easy peasy hard drive replacements quickly turned into hours of downtime and lots of yelling and screaming :(
During my holiday stay (at [Tropical Islands](https://www.tropical-islands.de) in Germany, pictures can be found [here](https://goo.gl/photos/uSCW7ciDUZtCdXY46)), I decided I'd replace the last 3 500 GB drives in my server array (don't ask me why I was thinking about my server on holiday). So, as soon as I got home, I decided to look around and order some of those beautiful WD Red drives. I considered upgrading my parity drive as well, but I'd have to buy 3 TB models and that seemed like more of a hassle than I was willing to take on at the moment. (I should have.)
So, the drives arrived, I ran a quick benchmark followed by a quick drive test and all seemed fine with the first drive. At this point, I decide to open up the server and replace the first 500 GB hard drive. After a lot of gymnastics (trying to read drive labels while the drives are in the drive bays) I finally figured out which drive I should replace and I went to work on that drive. I was careful not to touch any of the other cables to avoid accidentally unplugging them and I thought I had done a good job. I remember thinking: "Drive replaced, cables still connected, not much hassle so far. Let's turn it on". And so I did.
## Prepare for trouble...
My good mood was rudely interrupted by a loud beep followed by three, rapid, beeps. At first, I thought it was the regular old "fan not spinning" error (I use several ways to limit fan speed) but on further inspection, I realised that the fan was spinning just fine. Things were about to turn bad....
The drive I had inserted was fine, the OS picked it up and it was performing well. One of the other drives had failed though... So I shut it back down, reconnected the old drive (the one I replaced) and replaced the failing drive with a brand new one. A parity sync is necessary at this point.. Sigh..
After replacing the "failed" drive and letting the machine run for a while I got an email from my server, emails from my server are usually bad, stating that a drive had failed. At first, I was going to dismiss it as I had just replaced one and figured the email was simply delayed. Upon closer inspection, I found out that another hard drive had failed! So I logged back into the server and inspected the problem. The new drive had failed... even though it previously passed my tests with flying colours!
Something was up... and after countless hours of fighting with my server I finally figured it out. The SATA port on the controller was faulty. It didn't error, it didn't smoke, it looked fine. It even held on to the cable just fine (cause of those tiny little lips on SATA cables) so it was kinda hard to find out that the SATA port was faulty.
![picture of a random yellow sata cable](./images/sata.jpg)
So, with a way to reproducibly "fail" known good drives it was just a matter of plugging the SATA cable into another port and go on with my day.... or so I thought....
Little did I know that my server had used up all its SATA ports! I didn't have a single one left! In the end, I had to go out, pay way too much for a raid card that I didn't need and work on the server till dawn in order to fix my mistakes.
Please don't make the same mistake... make sure you have a replacement SATA port (or raid card for that matter).
Live and Learn I guess, Live. And. Learn.

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,35 @@
---
title: Scala Day 0 - What is Scala?
date: "2017-03-30"
template: "post"
draft: false
category: "Development/slsw"
tags:
- "Development"
- "slsw"
description: "My final assignment for a school course is to learn a new language from a book (uh-oh). I picked Scala and here's why"
disqusId: "20"
---
One of the final assignments for a school course called "APP" (Algorithms Programming language & Paradigms) was/is to learn a new programming language using the book "[Seven languages in Seven weeks](https://pragprog.com/book/btlang/seven-languages-in-seven-weeks)".
The idea of this book is that you can get comfortable with a programming language in just a week. As you can probably guess from the title the book covers 7 languages in total and I will be covering at least 1 (Scala).
## What is Scala
Scala is a hybrid language that tries to bridge the gap between object-oriented languages like Java and functional languages like Haskell.
## Why did I pick Scala for the assignment?
I have never really liked functional languages (except Javascript) much. It's a hard paradigm for me to wrap my head around in most languages and it gets tiring quickly. I thought having an assignment (for which I will be graded) to focus on might help me stay on the right path.
So... if you wanted to go functional why not go Haskell you ask? Well, purely functional programming is something which just doesn't "speak" to me, combining it with an OO approach might just be the thing that makes the gears click. At the very least it should provide a gradual learning curve to apply functional programming ideas to my code.
Besides my personal reasons, there are some objective reasons why Scala is "better" than Haskell:
- Scala is much more popular than Haskell, as such chances of encountering it "in the wild" are severely increased.
- Scala painlessly integrates with pre-existing java libraries.
- Scala uses the Java Virtual Machine (JVM), this has numerous benefits.
- Like Java, Scala is statically typed and the syntax somewhat resembles that of Java too.
Well thats it for today folks, check back in for the next blog within a few days!

View File

@ -0,0 +1,284 @@
---
title: Scala Day 1 - The Basics
date: "2017-04-02"
template: "post"
draft: false
category: "Development/slsw"
tags:
- "Development"
- "slsw"
description: "Let's take a deep dive into a programming book and Scala!"
disqusId: "21"
---
So day 1 has arrived, I've opened the book and I've started looking at the assignments in front of me. The book starts off by telling us how to install Scala so that is what I'll start with today.
## Installing Scala
Being on Linux the first thing I did was use my package manager of choice (Pacman) to check whether there was a Scala package in my repositories. Sure enough, it found a package (20MB in size) and proceeded to download and install said package.
While Pacman started collecting all the little dots, I took a quick look at the [Scala download page](https://www.scala-lang.org/download/install.html). On there I am greeted with a friendly message telling me the binary for my system is ready to download. Right below the download button is a link on how to install Scala. Curiosity got to me and I decided to open the link. The installation steps briefly explain that there are 2 binaries in the compressed folder which are of importance: "scala" and "scalac". To anyone coming from Java, these should be fairly familiar seeing as Java uses "java" and "javac" for their interpreter and compiler respectively. (note: the installation steps assume you know how to add PATH variables).
The next message on this page tells me about a popular build tool called `sbt` so I went ahead and installed that as well.
The final step on this page recommends me to install "[The Scala IDE](http://scala-ide.org/?_ga=1.153666491.264179122.1490891096)" or use the IntelliJ plugin. Seeing as I adore the JetBrains product line I've opted to choose the latter.
While browsing the downloads page I noticed Pacman had beat his level. (a.k.a collected all the dots. a.k.a the install has finished) Which means it's high time for me to continue on with the assignments.
## Scala types
The next step in the book guides me through using the interpreter to execute basic bits of code. These range from a simple hello world to entering some arithmetics. In the code block below you can see both my input and the interpreter's output.
```scala
scala> println("hello, surreal world")
hello, surreal world
scala> 1 + 1
res1: Int = 2
scala> 5 + 4 * 3
res2: Int = 17
scala> 5. + (4.*(3))
res3: Int = 17
```
Two things struck me as odd about these results. First up the word "Int" is written with a capital I. This is weird to me because in Java "int" is a base type, not a class (it uses the Integer wrapper class). Next up is the "ResX" line, does that just mean result or is there something more to find out about it? After a quick Google search I found out the "res" is an immutable variable which we can use like so:
```scala
res0: Int = 10
scala> res0 + 10
res1: Int = 20
```
## Type inference, arrow notation, "var vs val" and GitHub
At this point the code is getting slightly more complicated and typing it all directly into the interpreter would be a fool's effort. Therefore I've switched to using IntelliJ with the scala plugin and .scala files. All the files can be found on [GitHub](https://github.com/Mastermindzh/Seven-Languages-in-Seven-Weeks/tree/master/Scala/Day%201).
After fiddling a bit with the examples I've found a few things I already like in Scala:
- Type inference. To me, not having to specify the type of a variable is strangely satisfying.
- Anonymous function syntax support (a.k.a arrow notation).
- First class ranges
- 1 line methods without braces
- companion objects ([extending.scala](https://github.com/Mastermindzh/Seven-Languages-in-Seven-Weeks/blob/master/Scala/Day%201/extending.scala) on Github)
- No semicolons! (although I sometimes use them by accident)
## Inheritance is weird
Inheritance is one of the many joys from the Object-Oriented programming paradigm and I'm glad to read Scala supports inheritance too. The way Scala does it, however, is rather weird in my opinion. Take a look at the following code:
```scala
class Person(val name: String) {
def talk(message: String) = println(name + " says " + message)
def id(): String = name
}
class Employee(override val name: String, val number: String) extends Person(name) {
override def talk(message: String) {
println(name + " with number " + number + " says: " + message)
}
override def id():String = number.toString
}
```
As you can see we have to specify the parameter list of the class we want to extend. Also, note that we don't have to specify the type of said parameters. Another peculiarity is the "override" keyword. Apparently, it is mandatory to prevent the creation of new methods due to mis-spelling .... lame.
## Traits
Traits, in short, resemble a Java interface combined with an implementation.
We will start by defining a trait "Bad" for the Person class we've defined earlier:
```scala
trait Bad{
def curse() = println("Object oriented languages are cool too!");
}
```
Next, we'll override the person class with a new class and add the "Bad" trait:
```scala
class BadPerson(override val name:String) extends Person(name) with Bad
```
Now if we create a new object of BadPerson we can call the "curse" method.
```scala
val badPerson = new BadPerson("Mr. bad")
badPerson.curse
```
We can also add multiple traits to a class by repeating "with TRAIT" like so:
```scala
class IndecisivePerson(override val name: String) extends Person(name) with Nice with Bad
```
## Self-Study
At the end of every day, the book ends with a few assignments, some are theoretical and some are practical.
Day 1's theoretical questions are:
1. Find the Scala API
2. Find a comparison of Java and Scala
3. Find a discussion of "val" vs "var"
My answers to these are:
1. [http://www.scala-lang.org/api/current/](http://www.scala-lang.org/api/current/)
2. [https://www.toptal.com/scala/why-should-i-learn-scala](https://www.toptal.com/scala/why-should-i-learn-scala)
3. [http://www.scala-lang.org/old/node/5367](http://www.scala-lang.org/old/node/5367)
Finally, we get to move on to the practical assignment for the week. For the assignment, I have to create a "Tic-tac-toe" game for 2 players.
Writing this game has been really interesting. I tried using as few variables as possible and I tried to use Scala-specific features. One of these features I have already fallen in love with: collections. Scala collections have methods similar to [LINQ in c#](https://msdn.microsoft.com/en-us/library/bb397933.aspx) and they are extremely useful. Examples of these collection methods can be found in the "boardHasWinner" method in the code below.
The complete code for this game, including the bonus problem, can also be found at [Github](https://github.com/Mastermindzh/Seven-Languages-in-Seven-Weeks/blob/master/Scala/Day%201/Self-Study/day1.scala).
```scala
object TicTacToe {
var currentPlayer = 'X';
val playerOne = 'X'
val playerTwo = 'O'
val board = Array(
Array('_', '_', '_'),
Array('_', '_', '_'),
Array('_', '_', '_')
)
/**
* Flips current player to the other player.
*/
def flipPlayers = {
if(currentPlayer.equals(playerOne)){
currentPlayer = playerTwo
}else{
currentPlayer = playerOne
}
}
/**
* read user input and play a move
* @param error set to true if user made a mistake and has to re-enter his position
*/
def readLine(error : Boolean = false) : Unit = {
if(error){
System.err.println("Please enter a value ON the grid which has no mark yet.")
}
println("Please enter the x position you want to place your mark at")
val x = scala.io.StdIn.readLine().toInt
println("Please enter the y position you want to place your mark at")
val y = scala.io.StdIn.readLine().toInt
if((x > 0 && x < 4) && (y > 0 && y < 4) ){
play(x,y)
}else{
readLine(true)
}
}
/**
* checks whether pos(x,y) is a valid position
* if it's valid it will put currentPlayer on that position
* if it isn't it will ask the user for new input using the readLine method
* @param x coordinate
* @param y coordinate
*/
def play(x : Int, y : Int) = {
if(board(x - 1)(y - 1).equals('_')){
board(x - 1)(y - 1) = currentPlayer
flipPlayers
}else{
readLine(true)
}
}
/**
* Checks whether the board is full
* @return true if board is full, else false
*/
def boardIsFull : Boolean = {
board.foreach { row =>
// if any row contains an underscore we're obv not full yet so we can return false;
if(row contains '_'){
return false;
}
}
return true;
}
/**
* main game loop
*/
def run = {
while(!boardIsFull && !boardHasWinner){
printBoard
readLine()
if(boardHasWinner){
flipPlayers // reverse last player flip
println("Congrats " + currentPlayer + " you have won this game of Tic-Tac-Toe")
}
}
if(!boardHasWinner){
println("Sorry, it's a draw!")
}
// print the board once more so the players can see the final score
printBoard
// exit execution
System.exit(0)
}
/**
* Checks whether the board has a winner
* @return true if board has a winner else false.
*/
def boardHasWinner : Boolean = {
//check horizontals
board.foreach {row =>
if(row(0) != '_' && row.forall(c => c.equals(row(0)))){
return true
}
}
// check diagonals
val topLeftBottomRight = Array(board(0)(0), board(1)(1), board(2)(2))
val bottomLeftTopRight = Array(board(0)(2), board(1)(1), board(2)(0))
if(topLeftBottomRight(0) != '_' && topLeftBottomRight.forall(c => c.equals(topLeftBottomRight(0)))){
return true
}
if(bottomLeftTopRight(0) != '_' && bottomLeftTopRight.forall(c => c.equals(bottomLeftTopRight(0)))){
return true
}
// if no winner has been found, return false.
return false
}
/**
* Prints a visual representation of the board and who's turn it is
*/
def printBoard = {
board.foreach { row => println("" + row(0) + " | "
+ row(1) + " | "
+ row(2) )}
println(currentPlayer + " is playing")
}
}
// let's play!
TicTacToe.run
```

View File

@ -0,0 +1,265 @@
---
title: Scala Day 2 - Let's get functional
date: "2017-04-03"
template: "post"
draft: false
category: "Development/slsw"
tags:
- "Development"
- "slsw"
description: "Today we'll focus on the functional aspects of Scala"
disqusId: "22"
---
I feel like I covered a lot in the first chapter but that I haven't yet found the real power of functional programming. Day 2 promises to change that by diving right into functional programming.
## Val vs Var
I've already looked at this on day 1, looking back at the chapter I realize I wasn't yet meant to find out about the difference between "val vs var". In short, val is immutable while var is mutable.
The remainder of the chapter emphasizes the importance of using val, especially while designing an application with concurrency in mind.
> This basic design philosophy is the key element that differentiates functional programming from object-oriented programming: mutable state limits concurrency.
>
> \- Tate, Bruce, Seven Languages in seven weeks (p 155)
## Collections
In the first blog I already pointed out some of the features I had discovered about collections. I used some of these awesome features in my day 1 self-study.
The second chapter goes into more detail about collections. First up are lists.
## Lists
Scala's lists, of type List, are ordered collections of elements with random access. One of the things the book immediately goes into is the ability to store different types of objects in the list. Take a look at the interpreters response when I try to create a list of two strings and an integer:
```scala
scala> List("one", "two", 3)
res6: List[Any] = List(one, two, 3)
```
This returns a list with data type "Any", which is the catchall data type for Scala. To access an item we use the "()" operator. Think of it as the list being a method on which you "call" a get function. Doing so will return an "Any" object, which to me is weird because it's type could be inferred as well.
```scala
scala> List("one", "two", 3)(2)
res7: Any = 3
```
Trying to access a number outside the list will throw either a "NoSuchElement" exception (if the index specified is too high) or a regular old "IndexOutOfBoundsException". (if the index is below 0)
## Sets
A set is like a list, but it doesn't have any explicit order. We can specify a set with the Set keyword like so:
```scala
scala> val animals = Set("lions", "tigers", "bears")
animals: scala.collection.immutable.Set[java.lang.String] = Set(lions, tigers, bears)
```
Adding or subtracting from it is as easy as using the + or - operator:
```scala
scala> animals + "armadillos"
res0: scala.collection.immutable.Set[String] = Set(lions, tigers, bears, armadillos)
scala> res0 - "tigers"
res2: scala.collection.immutable.Set[String] = Set(lions, bears, armadillos).
```
Combining sets can be done with the "++" operator (or list.union) and the "--" operator (or list.diff) will return a list of differences between the two lists:
```scala
scala> animals ++ Set("armadillos", "raccoons")
res3: scala.collection.immutable.Set[String] = Set(bears, tigers, lions, armadillos, raccoons)
scala> animals -- Set("lions", "bears")
res4: scala.collection.immutable.Set[String] = Set(tigers)
```
Set intersection can be done with "List.intersect" like so:
```scala
animals.intersect(Set("armadillos","raccoons","lions","tigers"))
res8: scala.collection.immutable.Set[String] = Set(lions, tigers)
```
As I've mentioned before, Sets, unlike lists, are independent of order. This rule will mean that equality for sets is different. Therefor evaluating two sets with the same elements in a different order will return true:
```scala
scala> Set(1, 2, 3) == Set(3, 2, 1)
res9: Boolean = true
```
## Maps
A map is a key-value pair, similar to hashmaps in Java. Specifying a map of ordinal numbers can be done with:
```scala
val ordinals = Map(0 -> "zero", 1 -> "one", 2 -> "two")
ordinals: scala.collection.immutable.Map[Int,String] = Map(0 -> zero, 1 -> one, 2 -> two)
```
We can also specify the type for a HashMap like so:
```scala
import scala.collection.mutable.HashMap
val map = new HashMap[Int, String]
```
We can then add items like so:
```scala
map += 4 -> "four"
map += 8 -> "eight"
```
## List methods
Scala supports anonymous functions, I've used this to solve some problems in the Tic-Tac-Toe game from the first blog.
Apart from the "foreach" method, there are some other useful list methods:
<!-- prettier-ignore -->
| Function | What it does |
| ------------ | -------------------------------------------- |
| List.head | Returns the first element |
| List.tail | Returns all but the first element |
| List.last | Returns the last element |
| list.init | Returns all but the last element (recursion) |
| List.reverse | Reverses the list |
| List.drop(2) | Removes the first two objects. |
## Count, map filter and Others
Scala has many other functions that manipulate lists in various ways. I won't go over these but the code examples below should give you an idea of the possibilities.
```scala
scala> val words = List("peg", "al", "bud", "kelly")
words: List[String] = List(peg, al, bud, kelly)
scala> words.count(word => word.size > 2)
res0: Int = 3
scala> words.filter(word => word.size > 2)
res1: List[String] = List(peg, bud, kelly)
scala> words.map(word => word.size)
res2: List[Int] = List(3, 2, 3, 5)
scala> words.forall(word => word.size > 1)
res3: Boolean = true
scala> words.exists(word => word.size > 5)
res4: Boolean = false
```
We can also parameterise our anonymous functions so that we can sort a list based on the first letter of each word. We do that like this:
```scala
words.sortWith((s, t) => s.charAt(0).toLower < t.charAt(0).toLower)
```
We can also sort by word size:
```scala
words.sort((s, t) => s.size undefined
```
## foldLeft
The foldLeft method takes an initial value and a code block. It will take the initial value and for each item in the list run the code block passing back in the calculated value. Let me show you:
```scala
val list = List(1, 2, 3)
val sum = (0 /: list) {(sum, i) => sum + i}
```
1. Initially, /: takes the initial value, 0 , and the first element of list , 1 ,and passes them into the code block. sum is 0 , i is 1 , and the result of 0 + 1 is 1 .
2. Next, /: takes 1 , the result returned from the code block, and folds it back into the calculation as sum . So, sum is 1 ; i is the next element of list , or 2 ; and the result of the code block is 3 .
3. Finally, /: takes 3, the result returned from the code block, and folds it back into the calculation as sum . So, sum is 3 ; i is the next element of list , or 3 ; and sum + i is 6 .
We can achieve the same thing by using the foldLeft method like so:
```scala
list.foldLeft(0)((sum, value) => sum + value)
```
## Self-Study
I'm starting to like Scala more and more, the practical challenge for this week was really fun albeit a bit simple.
The theoretical questions for day 2 are:
1. A discussion on how to use Scala files
2. What makes a closure different from a code block
Once again these questions are trivial if you've actually paid attention while reading the book. Anyway, here are the answers:
1. [http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html](http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html)
2. [http://stackoverflow.com/questions/1812401/exactly-what-is-the-difference-between-a-closure-and-a-block](http://stackoverflow.com/questions/1812401/exactly-what-is-the-difference-between-a-closure-and-a-block)
The results of the second day's practical assignments can found on [Github](https://github.com/Mastermindzh/Seven-Languages-in-Seven-Weeks/tree/master/Scala/Day%202/src/myApp) or below:
```scala
/**
Self-Study day 2, practical assignments:
• Use foldLeft to compute the total size of a list of strings.
• Write a Censor trait with a method that will replace the curse words
Shoot and Darn with Pucky and Beans alternatives. Use a map to
store the curse words and their alternatives.
• Load the curse words and alternatives from a file.
*/
trait Censor {
val curseWords = Map("shoot" -> "pucky", "darn" -> "beans")
/**
* Awesome function which will build a curseWords map from a file.
* @param input string input
* @param path curseWords file
* @return clean string
*/
def censorTextUsingFile(input: String, path: String) : String = {
// neat little statement which will read a file from a path, get its lines
// for each line it will split on "=" and put the values in the map
val myMap = io.Source.fromResource(path).getLines.foldLeft(Map[String, String]())((map, line) =>
map + (line.split("=")(0) -> line.split("=")(1))
)
censorText(input, myMap)
}
/**
* censors input text using the builtin curseWords map or @param map
* @param input string to be censored
* @param map optional, map of curse words
* @return censored string
*/
def censorText(input: String, map: Map[String, String] = curseWords) : String ={
val words = input.split(" ")
words.map(word => map.getOrElse(word.toLowerCase, word)).mkString(" ")
}
}
object MyApp extends App with Censor{
// print combined size of a list of strings
val list = List("one", "two" , "three")
println(list.foldLeft(0)((sum, value) => sum + value.length))
val strToCensor = "Shoot !, this darn thing won't work!"
// censor using builtin map
println(this.censorText(strToCensor))
// censor using curseWords.txt file from resources folder
println(this.censorTextUsingFile(strToCensor, "curseWords.txt"))
}
```

View File

@ -0,0 +1,173 @@
---
title: Scala Day 3 - Concurrency is key!
date: "2017-04-04"
template: "post"
draft: false
category: "Development/slsw"
tags:
- "Development"
- "slsw"
description: "A day full of functional joy and concurrency "
disqusId: "23"
---
Day 3 promises to go into "hard things" like XML and concurrency. So far I've been liking Scala and if it can really simplify concurrency then it might earn a permanent slot in my toolkit.
## XML
We can express XML just as easily as we do a string, the example below shows how to express some XML and how to access its inner text. Note, however, that you need to add the "scala-xml" jar file to your build solution as it no longer comes included with Scala.
```scala
scala> val movies =
| <movies>
| <movie genre="scifi">Star Trek</movie>
| <movie genre="fairytale">Star Wars</movie>
| </movies>
movies: scala.xml.Elem =
<movies>
<movie genre="scifi">Star Trek</movie>
<movie genre="fairytale">Star Wars</movie>
</movies>
scala> movies.text
res0: String =
"
Star Trek
Star Wars
"
```
We can use the " \ " operator to search for specific entries, which we can then access just as with a list:
```scala
scala> val movieNodes = movies \ "movie"
movieNodes: scala.xml.NodeSeq = NodeSeq(<movie genre="scifi">Star Trek</movie>, <movie genre="fairytale">Star Wars</movie>)
scala> movieNodes(0)
res1: scala.xml.Node = <movie genre="scifi">Star Trek</movie>
```
To check the "genre" attribute of the first item in movieNodes we run:
```scala
scala> movieNodes(1)
res3: scala.xml.Node = <movie genre="fairytale">Star Wars</movie>
scala> movieNodes(1) \ "@genre"
res4: scala.xml.NodeSeq = fairytale
```
As we can see it returned the correct genre, fairytale, for the movie "Star Wars". So far Scala delivers on its promise to make "hard things" like XML easy. Let's see what else we can do.
## Pattern matching, guards and Regex
Scala will use pattern matching often, such as when you parse XML or pass messages between threads.
The simplest form of pattern matching can be achieved with:
```scala
def doChore(chore: String): String = chore match {
case "clean dishes" => "scrub, dry"
case "cook dinner" => "chop, sizzle"
case _ => "whine, complain"
}
println(doChore("clean dishes" ))
println(doChore("mow lawn" ))
```
We define two chores and an alternative. We then call the method with a valid and invalid parameter. This will match the valid one and return "scrub, dry", the second won't match and will return "whine, complain".
Scala also supports guards in the case statement. Using this to calculate factorials, for instance, we can filter out weird numbers (like 0 and negatives) while matching all the other positive numbers to x, and thus return it's factorial.
```scala
def factorial(n: Int): Int = n match {
case 0 => 1
case y if n < 0 => 0
case x if x > 0 => factorial(n - 1) * n
}
println(factorial(-2))
println(factorial(0))
println(factorial(5))
```
We can also use regular expressions to do our matching:
```scala
scala> val reg = """^(F|f)\w*""".r
reg: scala.util.matching.Regex = ^(F|f)\w*
scala> println(reg.findFirstIn("Fantastic"))
Some(Fantastic)
scala> println(reg.findFirstIn("not Fantastic"))
None
```
We can even combine XML and the matching features like so:
```scala
(movies \ "_" ).foreach { movie =>
movie match {
case <movie>{movieName}</movie> =>
println(movieName)
case <short>{shortName}</short> =>
println(shortName + " (short)" )
}
}
val movies = <movies>
<movie>The Incredibles</movie>
<movie>WALL E</movie>
<short>Jack Jack Attack</short>
<short>Geri's Game</short>
</movies>
```
This will go through every item in the tree (\_) and match it to either movie or short. If it's a movie it will just print its text, otherwise, it'll print its text + (short).
In order to get this to work however I had to download the [scala.xml](https://github.com/scala/scala-xml) library, as it no longer comes included with Scala since Scala 2.11.
## Concurrency
Finally! We get to do something with concurrency, now Scala can really show me what it's worth!
The book starts off by telling me about Actors, which have pools of threads and queues, and message passing. When you send a message (using the ! operator) you place an object on its queue. The actor then reads the message and takes action. Usually, the actor uses a pattern matcher to detect what it has to do before it starts doing something.
The book provides a sample application but that plain doesn't work. Upon investigating the issue I discovered that Scala's built-in concurrency feature is deprecated in favour of [Akka](http://akka.io/). This saddens me beyond belief. I have already worked with Akka and had expected Scala to offer me something else. This also means that the rest of the book is not going to be useful anymore.
Stubborn as I am, even with a closing deadline, I decided I wasn't going to let a stupid book stop me and decided to update the code to work with Akka. All of which can be found at [Github](https://github.com/Mastermindzh/Seven-Languages-in-Seven-Weeks/tree/master/Scala/Day%203/src/Concurrency).
This disaster can be summed up by a fantastic quote though (and I **love** quotes):
> All that is necessary is to accept the impossible, do without the
> indispensable, and bear the intolerable.
>
> \- Norris, Kathleen, As quoted in: The Litchfield Co-operator, Issues 116-163 (1945)
## Self-study
The theoretical question for the day is: _For the sizer program, what would happen if you did not create a new actor for each link you wanted to follow? What would happen to the performance of the application?_
And the answer is: it would be just as slow as the sequential one.
The practical assignment is: _Take the sizer application and add a message to count the number of links on the page._
I did this by creating another Loader and calling that in my UrlActor. The code can, once again, be found on Github or in the code block below.
```scala
object PageLinkLoader {
def getLinks(url: String) : Int = {
val content = Source.fromURL(url)(io.Codec("ISO-8859-1")).mkString
val links = hrefRegex.findAllIn(content).matchData.toList.map(_.group(2))
links.size
}
//I stole this regex from somewhere for a previous project, don't remember where
val hrefRegex = """<a\s+(?:[^>]*?\s+)?href=(["'])(.*?)\1""".r
}
```
So that's it, right? Wrong! My school assignment requires me to do one more assignment. What assignment is that? Well you'll just have to wait on the next blog to find out! Laters!

View File

@ -3,7 +3,7 @@ title: Scala Day 4 - A challenge!
date: "2017-04-05"
template: "post"
draft: false
category: "Development"
category: "Development/slsw"
tags:
- "Development"
- "slsw"

5419
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -168,6 +168,33 @@ figcaption {
text-align: center;
}
ol,
ul {
padding-left: 5rem;
}
table {
// border: 1px solid $color-base;
border-collapse: collapse;
width: 70%;
th {
border-bottom: 1px solid $color-base;
border-collapse: collapse;
padding: 1rem;
text-align: left;
}
tr,
th {
td {
padding: 0.3rem;
padding-left: 1rem;
}
}
}
@include breakpoint-sm {
figure.float-left,

View File

@ -6,14 +6,14 @@ exports[`Layout renders correctly 1`] = `
<div
className="CookieConsent"
style={
Object {
{
"bottom": "0",
}
}
>
<div
className=""
style={Object {}}
style={{}}
>
This website uses cookies to enhance the user experience.
@ -35,7 +35,7 @@ exports[`Layout renders correctly 1`] = `
className=""
id="rcc-confirm-button"
onClick={[Function]}
style={Object {}}
style={{}}
>
I understand
</button>

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Content renders correctly 1`] = `
Array [
[
<div>
<span>
<span
@ -32,7 +32,7 @@ Array [
<a
href="/"
style={
Object {
{
"lineHeight": "50px",
"marginRight": "10px",
}
@ -58,7 +58,7 @@ Array [
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -73,14 +73,14 @@ Array [
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -90,7 +90,7 @@ Array [
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -106,14 +106,14 @@ Array [
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -140,7 +140,7 @@ Array [
</h1>
<div
dangerouslySetInnerHTML={
Object {
{
"__html": "<p>An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.</p>",
}
}

View File

@ -33,7 +33,7 @@ exports[`Post renders correctly 1`] = `
<a
href="/"
style={
Object {
{
"lineHeight": "50px",
"marginRight": "10px",
}
@ -59,7 +59,7 @@ exports[`Post renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -74,14 +74,14 @@ exports[`Post renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -91,7 +91,7 @@ exports[`Post renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -107,14 +107,14 @@ exports[`Post renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -141,7 +141,7 @@ exports[`Post renders correctly 1`] = `
</h1>
<div
dangerouslySetInnerHTML={
Object {
{
"__html": "<p>An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.</p>",
}
}

View File

@ -168,7 +168,7 @@ exports[`Sidebar renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -183,14 +183,14 @@ exports[`Sidebar renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -200,7 +200,7 @@ exports[`Sidebar renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -216,14 +216,14 @@ exports[`Sidebar renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>

View File

@ -169,7 +169,7 @@ exports[`CategoriesTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -184,14 +184,14 @@ exports[`CategoriesTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -201,7 +201,7 @@ exports[`CategoriesTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -217,14 +217,14 @@ exports[`CategoriesTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -280,14 +280,14 @@ exports[`CategoriesTemplate renders correctly 1`] = `
<div
className="CookieConsent"
style={
Object {
{
"bottom": "0",
}
}
>
<div
className=""
style={Object {}}
style={{}}
>
This website uses cookies to enhance the user experience.
@ -309,7 +309,7 @@ exports[`CategoriesTemplate renders correctly 1`] = `
className=""
id="rcc-confirm-button"
onClick={[Function]}
style={Object {}}
style={{}}
>
I understand
</button>

View File

@ -169,7 +169,7 @@ exports[`CategoryTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -184,14 +184,14 @@ exports[`CategoryTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -201,7 +201,7 @@ exports[`CategoryTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -217,14 +217,14 @@ exports[`CategoryTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -346,14 +346,14 @@ exports[`CategoryTemplate renders correctly 1`] = `
<div
className="CookieConsent"
style={
Object {
{
"bottom": "0",
}
}
>
<div
className=""
style={Object {}}
style={{}}
>
This website uses cookies to enhance the user experience.
@ -375,7 +375,7 @@ exports[`CategoryTemplate renders correctly 1`] = `
className=""
id="rcc-confirm-button"
onClick={[Function]}
style={Object {}}
style={{}}
>
I understand
</button>

View File

@ -169,7 +169,7 @@ exports[`IndexTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -184,14 +184,14 @@ exports[`IndexTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -201,7 +201,7 @@ exports[`IndexTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -217,14 +217,14 @@ exports[`IndexTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -343,14 +343,14 @@ exports[`IndexTemplate renders correctly 1`] = `
<div
className="CookieConsent"
style={
Object {
{
"bottom": "0",
}
}
>
<div
className=""
style={Object {}}
style={{}}
>
This website uses cookies to enhance the user experience.
@ -372,7 +372,7 @@ exports[`IndexTemplate renders correctly 1`] = `
className=""
id="rcc-confirm-button"
onClick={[Function]}
style={Object {}}
style={{}}
>
I understand
</button>

View File

@ -169,7 +169,7 @@ exports[`NotFoundTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -184,14 +184,14 @@ exports[`NotFoundTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -201,7 +201,7 @@ exports[`NotFoundTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -217,14 +217,14 @@ exports[`NotFoundTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -270,14 +270,14 @@ exports[`NotFoundTemplate renders correctly 1`] = `
<div
className="CookieConsent"
style={
Object {
{
"bottom": "0",
}
}
>
<div
className=""
style={Object {}}
style={{}}
>
This website uses cookies to enhance the user experience.
@ -299,7 +299,7 @@ exports[`NotFoundTemplate renders correctly 1`] = `
className=""
id="rcc-confirm-button"
onClick={[Function]}
style={Object {}}
style={{}}
>
I understand
</button>

View File

@ -169,7 +169,7 @@ exports[`PageTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -184,14 +184,14 @@ exports[`PageTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -201,7 +201,7 @@ exports[`PageTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -217,14 +217,14 @@ exports[`PageTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -254,7 +254,7 @@ exports[`PageTemplate renders correctly 1`] = `
<div>
<div
dangerouslySetInnerHTML={
Object {
{
"__html": "<p>An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.</p>",
}
}
@ -265,14 +265,14 @@ exports[`PageTemplate renders correctly 1`] = `
<div
className="CookieConsent"
style={
Object {
{
"bottom": "0",
}
}
>
<div
className=""
style={Object {}}
style={{}}
>
This website uses cookies to enhance the user experience.
@ -294,7 +294,7 @@ exports[`PageTemplate renders correctly 1`] = `
className=""
id="rcc-confirm-button"
onClick={[Function]}
style={Object {}}
style={{}}
>
I understand
</button>

View File

@ -34,7 +34,7 @@ exports[`PostTemplate renders correctly 1`] = `
<a
href="/"
style={
Object {
{
"lineHeight": "50px",
"marginRight": "10px",
}
@ -60,7 +60,7 @@ exports[`PostTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -75,14 +75,14 @@ exports[`PostTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -92,7 +92,7 @@ exports[`PostTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -108,14 +108,14 @@ exports[`PostTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -142,7 +142,7 @@ exports[`PostTemplate renders correctly 1`] = `
</h1>
<div
dangerouslySetInnerHTML={
Object {
{
"__html": "<p>An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.</p>",
}
}
@ -184,14 +184,14 @@ exports[`PostTemplate renders correctly 1`] = `
<div
className="CookieConsent"
style={
Object {
{
"bottom": "0",
}
}
>
<div
className=""
style={Object {}}
style={{}}
>
This website uses cookies to enhance the user experience.
@ -213,7 +213,7 @@ exports[`PostTemplate renders correctly 1`] = `
className=""
id="rcc-confirm-button"
onClick={[Function]}
style={Object {}}
style={{}}
>
I understand
</button>

View File

@ -169,7 +169,7 @@ exports[`TagTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -184,14 +184,14 @@ exports[`TagTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -201,7 +201,7 @@ exports[`TagTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -217,14 +217,14 @@ exports[`TagTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -346,14 +346,14 @@ exports[`TagTemplate renders correctly 1`] = `
<div
className="CookieConsent"
style={
Object {
{
"bottom": "0",
}
}
>
<div
className=""
style={Object {}}
style={{}}
>
This website uses cookies to enhance the user experience.
@ -375,7 +375,7 @@ exports[`TagTemplate renders correctly 1`] = `
className=""
id="rcc-confirm-button"
onClick={[Function]}
style={Object {}}
style={{}}
>
I understand
</button>

View File

@ -169,7 +169,7 @@ exports[`TagsTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f1c40f",
"fontSize": "1.1em",
"position": "absolute",
@ -184,14 +184,14 @@ exports[`TagsTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 384 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -201,7 +201,7 @@ exports[`TagsTemplate renders correctly 1`] = `
>
<div
style={
Object {
{
"color": "#f39c12",
"fontSize": "1em",
"left": "-3px",
@ -217,14 +217,14 @@ exports[`TagsTemplate renders correctly 1`] = `
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
style={{}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM352 256c0 53-43 96-96 96s-96-43-96-96s43-96 96-96s96 43 96 96zm32 0c0-70.7-57.3-128-128-128s-128 57.3-128 128s57.3 128 128 128s128-57.3 128-128z"
fill="currentColor"
style={Object {}}
style={{}}
/>
</svg>
</div>
@ -280,14 +280,14 @@ exports[`TagsTemplate renders correctly 1`] = `
<div
className="CookieConsent"
style={
Object {
{
"bottom": "0",
}
}
>
<div
className=""
style={Object {}}
style={{}}
>
This website uses cookies to enhance the user experience.
@ -309,7 +309,7 @@ exports[`TagsTemplate renders correctly 1`] = `
className=""
id="rcc-confirm-button"
onClick={[Function]}
style={Object {}}
style={{}}
>
I understand
</button>