<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Bartosz Gajda</title>
    <description>The latest articles on Forem by Bartosz Gajda (@bartoszgajda55).</description>
    <link>https://forem.com/bartoszgajda55</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F446090%2F885585da-c231-4a56-a940-8655125f8b37.jpeg</url>
      <title>Forem: Bartosz Gajda</title>
      <link>https://forem.com/bartoszgajda55</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bartoszgajda55"/>
    <language>en</language>
    <item>
      <title>5 Essential skills for becoming a Data Engineer</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Sat, 19 Sep 2020 12:47:05 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/5-essential-skills-for-becoming-a-data-engineer-34df</link>
      <guid>https://forem.com/bartoszgajda55/5-essential-skills-for-becoming-a-data-engineer-34df</guid>
      <description>&lt;p&gt;The Data Engineer skills is a hot topic, for everyone interested in becoming a one. The rise of data platforms wouldn't be possible without the data engineer skills, that develop the  infrastructure and tools. The need for specialists in this area is forecasted to only increase, therefore if your are considering on becoming a Data Engineer, those are my 5 essential skills you have to poses. Enjoy!&lt;/p&gt;

&lt;h2&gt;Programming - &lt;a rel="noreferrer noopener" href="https://www.scala-lang.org/"&gt;Scala&lt;/a&gt; and/or &lt;a rel="noreferrer noopener" href="https://www.python.org/"&gt;Python&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5wv6uvXl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/09/scala-python.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5wv6uvXl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/09/scala-python.jpg" alt="" class="wp-image-3906" width="500" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first and the most important skill - programming. The job of a Data Engineer requires to write a significant amount of custom, tailored code, which cannot be otherwise generated using fancy GUI software. The ability to code and to create readable, clean and scalable code is a must.&lt;/p&gt;

&lt;p&gt;I have chosen two programming languages here: Scala and Python. I am not going to lie, that Scala is my personal favorite (if you haven't guessed already by the number of posts on this topic :)) although Python is also a good choice. &lt;/p&gt;

&lt;p&gt;Some of the Data Engineering frameworks have been written in Scala (eg. Apache Spark), and it works great when you need more control over the code.&lt;/p&gt;

&lt;p&gt;Python is probably much easier to start with and generally more newbie friendly, although it has some performance issues, which in data world might be critical.&lt;/p&gt;

&lt;p&gt;A good option is to learn one of those to a proficient stage, and other one to at least basics - it is always better to have another tool under your belt, even tough it might not be as good as others.&lt;/p&gt;

&lt;p&gt;If you are looking to learn Scala, be sure to check out &lt;a href="https://bartoszgajda.com/2020/05/03/5-best-resources-to-learn-scala/"&gt;my post&lt;/a&gt; that explains where to start from.&lt;/p&gt;

&lt;h2&gt;Data Manipulation - &lt;a rel="noreferrer noopener" href="https://en.wikipedia.org/wiki/SQL"&gt;SQL&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4rfiw1wJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/09/sql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4rfiw1wJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/09/sql.png" alt="" class="wp-image-3908" width="200" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Despite the fact that in data world there is a flood of semi and unstructured data, SQL is still the de facto data manipulation language. Whether you are working with relation database, data warehouse or a processing engine like Spark - SQL is widely supported.&lt;/p&gt;

&lt;p&gt;Some of the technologies use their own variations of SQL, like a CQL in Cassandra distributed database system, and there isn't anything on the horizon that would make SQL go away.&lt;/p&gt;

&lt;p&gt;Not all data engineering tasks are focused on building fancy Machine Learning pipelines, or Stream Processing. Lots of simple problems can be solved by writing a SQL query. Modern SQL engines can handle automatic optimization of those queries, which is great if high performance programming is not your strong skill.&lt;/p&gt;

&lt;h2&gt;Processing Engine - &lt;a rel="noreferrer noopener" href="https://spark.apache.org/"&gt;Apache Spark&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PkV_qgoA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/09/spark-1024x533.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PkV_qgoA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/09/spark-1024x533.png" alt="" class="wp-image-3909" width="256" height="133"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The third element on the list, is probably my favorite - Apache Spark processing engine. As a Data Engineer you don't want to reinvent the wheel - you want to use the framework that is capable of solving majority of problems in unified and repeatable way. &lt;/p&gt;

&lt;p&gt;The days of Hadoop's MapReduce are long gone, and the Apache Spark is something you should focus on. It is the most popular general purpose processing engine, that can to ETL, batch and streaming processing, machine and deep learning and many more.&lt;/p&gt;

&lt;p&gt;The nice thing about Spark is that it supports 3 languages: Java, Scala and Python. R is also supported by to lesser extend. &lt;/p&gt;

&lt;p&gt;Learning Apache Spark may seem cumbersome at the start, but once you get a good grasp of the basics, it's very pleasant to work with. However, once you will go to the advanced topics, like optimization, various types of testing and deployment, the learning curve becomes quite steep.&lt;/p&gt;

&lt;p&gt;If your are looking for a quick intro on how to get started with Spark, check out &lt;a href="https://bartoszgajda.com/2019/07/05/setting-up-intellij-idea-for-apache-spark-and-scala-development/"&gt;my post&lt;/a&gt; on it.&lt;/p&gt;

&lt;h2&gt;Cloud - &lt;a rel="noreferrer noopener" href="https://aws.amazon.com/"&gt;AWS&lt;/a&gt; or &lt;a rel="noreferrer noopener" href="https://cloud.google.com/"&gt;GCP&lt;/a&gt; or &lt;a rel="noreferrer noopener" href="https://azure.microsoft.com/en-gb/"&gt;Azure&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lomkJ9Mo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/09/cloud-1024x439.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lomkJ9Mo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/09/cloud-1024x439.png" alt="" class="wp-image-3910" width="512" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope I don't have to convince you that cloud is now everywhere. The data platforms and data engineering pipelines are no different - lots of those utilize cloud services.&lt;/p&gt;

&lt;p&gt;Storing data on AWS S3, streaming data with GCP Pub/Sub or storing data in Azure Cosmos DB - those combinations are frequently found in lots of commercial systems. Whether you are just starting with the cloud, or have some previous experience - being a data engineer means using the cloud regularly.&lt;/p&gt;

&lt;p&gt;Out of those three, the AWS is probably the safest choice. It's the most popular, has the most services, is widely known and there are lots of tutorials that can guide you through. &lt;/p&gt;

&lt;p&gt;My personal favorite however is the Google Cloud Platform - it's extremely developer friendly, has an awesome selection of services and access to the most advanced AI and ML products. Google is pushing strongly into the cloud territory and I for a good reason - companies like the flexibility and agility it gives to developer teams.&lt;/p&gt;

&lt;p&gt;For the Azure, I don't have a lot of experience using it, so I leave this choice to you. Although I know that they work closely with Databricks, a company behind Apache Spark, and this might bring some interesting advances in data engineering field.&lt;/p&gt;

&lt;p&gt;If you are considering learning GCP and getting ACE certified, be sure to check &lt;a href="https://bartoszgajda.com/2020/07/13/5-best-study-resources-for-gcp-ace-exam/"&gt;my post&lt;/a&gt; on best resources to prepare for the exam.&lt;/p&gt;

&lt;h2&gt;Deployment - &lt;a rel="noreferrer noopener" href="https://www.docker.com/"&gt;Docker&lt;/a&gt; and &lt;a rel="noreferrer noopener" href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ibmhf1ZB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/09/docker-k8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ibmhf1ZB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/09/docker-k8s.png" alt="" class="wp-image-3911" width="394" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last but not least - the deployment. And even more precisely - containerization. The Docker and Kubernetes are combination that made the containers a sensible alternative to cumbersome VMs and clusters, like in the old days. Now, companies want to ship their products fast, and be ready to scale when business is getting traction, therefore scalable deployment is a must.&lt;/p&gt;

&lt;p&gt;Docker will help you pack your applications into a containers, that can be easily scaled up or down, depending on a need. Kubernetes handles the orchestration of clusters of containers - in the end data platforms are quite complicated beings, with lots of moving parts and you want to ensure they are prepared for extra demand and resilient to failures.&lt;/p&gt;

&lt;p&gt;If you are looking for some nice tips and tricks when working with Docker, be sure to check out &lt;a href="https://bartoszgajda.com/2019/09/06/5-docker-most-useful-commands/"&gt;my post&lt;/a&gt; on this.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so :)&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>datascience</category>
      <category>career</category>
      <category>dataengineering</category>
    </item>
    <item>
      <title>RESTful Web scraping in Scala, using Play Framework and Jsoup</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Sat, 19 Sep 2020 12:43:39 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/restful-web-scraping-in-scala-using-play-framework-and-jsoup-g1d</link>
      <guid>https://forem.com/bartoszgajda55/restful-web-scraping-in-scala-using-play-framework-and-jsoup-g1d</guid>
      <description>&lt;p&gt;Recently I have encountered a very cool site with cooking recipes, which had extremely poor UI, especially when using a mobile. There was no official API, and so I have decided to build a web service that would web scrape the content out of it, and publish it using RESTful API. In this post I will show you how to use &lt;a href="https://www.scala-lang.org/"&gt;Scala&lt;/a&gt;, &lt;a href="https://www.playframework.com/" rel="noreferrer noopener"&gt;Play Framework&lt;/a&gt; and &lt;a href="https://jsoup.org/" rel="noreferrer noopener"&gt;Jsoup&lt;/a&gt; to build such service. Enjoy!&lt;/p&gt;

&lt;h2&gt;You will need&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Scala - I use the version 2.13.1&lt;/li&gt;
&lt;li&gt;Sbt - install from official &lt;a href="https://www.scala-sbt.org/" rel="noreferrer noopener"&gt;website&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;IDE of choice - IntelliJ or VS Code, I use latter&lt;/li&gt;
&lt;li&gt;Around 15 minutes of your time&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Creating empty Play project&lt;/h2&gt;

&lt;p&gt;We will start off by creating a Play project. You can of course start from the scratch and add the code iteratively, but for the scope of this tutorial, I will suggest using on of the Play's example projects as a starter. &lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/playframework/play-samples/tree/2.8.x/play-scala-rest-api-example"&gt;Scala Rest API project&lt;/a&gt; have almost everything we need. This project serves as a nice backbone to our use case, which we will be able to extend with ease.&lt;/p&gt;

&lt;p&gt;Let's start by cloning the Play Framework samples repository, and opening the Scala Rest API example like this:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;git clone https://github.com/playframework/play-samples.git
cd play-scala-rest-api-example&lt;/pre&gt;

&lt;p&gt;After this, try running this command - the Play application should shoot off, and you should be able to access it at &lt;code&gt;http://localhost:9000&lt;/code&gt;&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;sbt run&lt;/pre&gt;

&lt;p&gt;If the application builds and runs correctly, we are done with initializing the project. Now, you can open this folder with your IDE of choice - I will use VS Code&lt;/p&gt;

&lt;h2&gt;Adding Jsoup dependency&lt;/h2&gt;

&lt;p&gt;Next, we will add the Jsoup - an open source HTML parser for Java and JVM. To do this, open a &lt;code&gt;build.sbt&lt;/code&gt; file and add the following in the &lt;code&gt;libraryDependencies&lt;/code&gt; block:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;"org.jsoup" % "jsoup" % "1.13.1"&lt;/pre&gt;

&lt;p&gt;Of course, make sure to use the latest version possible - at the time of authoring this article, &lt;strong&gt;1.13.1&lt;/strong&gt; was the latest one.&lt;/p&gt;

&lt;p&gt;Now, wait for &lt;code&gt;sbt&lt;/code&gt; to refresh the dependencies, and we are ready to write some code!&lt;/p&gt;

&lt;h2&gt;Defining an endpoint&lt;/h2&gt;

&lt;p&gt;The first coding step is to define an endpoint to Play framework. This is done, by adding route definitions to &lt;code&gt;conf/routes&lt;/code&gt; file. In our case, I want to have a &lt;code&gt;v1/recipes&lt;/code&gt; endpoint that is solely handled by &lt;code&gt;RecipeRouter&lt;/code&gt; class. We can do this by adding the following:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;-&amp;gt;         /v1/recipes             v1.recipe.RecipeRouter&lt;/pre&gt;

&lt;p&gt;Now, any request that hits that URL, will be redirected to our router.&lt;/p&gt;

&lt;p&gt;Next of, I am creating a package for my recipe related classes &lt;code&gt;app/v1/recipe&lt;/code&gt;. In here, let's create an entry point that will handle the requests: &lt;code&gt;RecipeRouter&lt;/code&gt;&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;package v1.recipe

import javax.inject.Inject

import play.api.routing.Router.Routes
import play.api.routing.SimpleRouter
import play.api.routing.sird._

class RecipeRouter @Inject()(controller: RecipeController) extends SimpleRouter {
  val prefix = "/v1/recipes"

  def link(id: String): String = {
    import io.lemonlabs.uri.dsl._
    val url = prefix / id.toString
    url.toString()
  }

  override def routes: Routes = {
    case GET(p"/") =&amp;gt;
      controller.index

    case GET(p"/all/$id") =&amp;gt;
      controller.showAll(id)
  }

}&lt;/pre&gt;

&lt;h2&gt;Connecting to website&lt;/h2&gt;

&lt;p&gt;Going further, it's time to finally use &lt;code&gt;Jsoup&lt;/code&gt; to get some content out of the website. In the previous section, we have defined &lt;code&gt;showAll&lt;/code&gt; function, and that's the one I will be implementing here. We will be making use of the &lt;code&gt;id&lt;/code&gt; parameter, which come in handy in many situations.&lt;/p&gt;

&lt;p&gt;So, let's move to &lt;code&gt;RecipeController&lt;/code&gt; class, and define the first element: &lt;code&gt;sourceUrl&lt;/code&gt;. I like to have it defined as a class field, so that it is accessible by all methods:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;val sourceUrl: String = "https://kwestiasmaku.com"&lt;/pre&gt;

&lt;p&gt;Then, inside our method, let's get the content of this website. It can be done like this:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;def showAll(pageId: String): Action[AnyContent] = Action { implicit request =&amp;gt;
    val htmlDocument = Jsoup.connect(s"${sourceUrl}/home-przepisy?page=${pageId}").get()

    val r: Result = Ok(htmlDocument)
    r
}&lt;/pre&gt;

&lt;p&gt;In the snippet above, we are connecting to our website, b using &lt;code&gt;Jsoup.connect&lt;/code&gt; method, while passing the correct URL as a string. What we get, is an HTML document, that we just return for now. We will do some finer extraction in the next section.&lt;/p&gt;

&lt;p&gt;To test the endpoint, call the following URL in your browser, or any http client, like &lt;code&gt;curl&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;http://localhost:9000/v1/recipes/all/1&lt;/pre&gt;

&lt;p&gt;You should see a response, which is raw HTML document. Now, let's parse it and extract some meaningful data.&lt;/p&gt;

&lt;h2&gt;Extracting the content&lt;/h2&gt;

&lt;p&gt;Now, let's extract some specific elements from the raw HTML. For this, we can use the &lt;code&gt;select&lt;/code&gt; method of Jsoup. This method requires a CSS like selector syntax - if you have used CSS before, then it is as easy specifying the correct string - in our case, to extract single recipe HTML object, use the following:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;import scala.jdk.CollectionConverters._

val recipesDomElements = htmlDocument.select("section#block-system-main .col").asScala&lt;/pre&gt;

&lt;p&gt;This query returns, collection-like structure, on which we can easily iterate. To extract specific elements from a single recipe, use the following:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;final case class Recipe(title: String, href: String, img: String)

val recipeData = for(recipeElement &amp;lt;- recipesDomElements)
      yield Recipe(
        recipeElement.select(".views-field-title a").html(),
        sourceUrl + recipeElement.select(".views-field-title a").attr("href"),
        recipeElement.select("img").attr("src")
      )&lt;/pre&gt;

&lt;p&gt;In here, we use a simple &lt;code&gt;for&lt;/code&gt; loop, which yields the concrete data, by wrapping it into &lt;code&gt;Recipe&lt;/code&gt; case class. Now, we have nicely cleaned data, and we can finally return it as JSON.&lt;/p&gt;

&lt;h2&gt;Returning a JSON&lt;/h2&gt;

&lt;p&gt;Last step is to return our collection of &lt;code&gt;Recipe&lt;/code&gt; case classes as a JSON. We can do this using Play's built in &lt;code&gt;Json&lt;/code&gt; class, and its methods:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;implicit val recipeWrites: OWrites[Recipe] = Json.writes[Recipe]

val r: Result = Ok(Json.toJson(recipeData))
r&lt;/pre&gt;

&lt;p&gt;An important thing to have in mind, is that before converting a case class into its JSON representation, we must declare implicit writer, so that the &lt;code&gt;Json&lt;/code&gt; class knows how to write this specific data.&lt;/p&gt;

&lt;p&gt;And that's it! The complete &lt;code&gt;RecipeController&lt;/code&gt; class implementation looks like the following:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;package v1.recipe

import javax.inject.Inject
import org.jsoup.Jsoup
import play.api.mvc._
import play.api.libs.json.{Json, OWrites}

import scala.jdk.CollectionConverters._

class RecipeController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
  implicit val recipeWrites: OWrites[Recipe] = Json.writes[Recipe]
  val sourceUrl: String = "https://kwestiasmaku.com"

  def index: Action[AnyContent] = Action { implicit request =&amp;gt;
    val r: Result = Ok("hello world")
    r
  }

  def showAll(pageId: String): Action[AnyContent] = Action { implicit request =&amp;gt;
    val htmlDocument = Jsoup.connect(s"${sourceUrl}/home-przepisy?page=${pageId}").get()
    val recipesDomElements = htmlDocument.select("section#block-system-main .col").asScala

    val recipeData = for(recipeElement &lt;/pre&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂&lt;/p&gt;

</description>
      <category>scala</category>
      <category>webdev</category>
      <category>restapi</category>
      <category>backend</category>
    </item>
    <item>
      <title>Scala collections in a nutshell</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Sat, 19 Sep 2020 12:38:47 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/scala-collections-in-a-nutshell-o1o</link>
      <guid>https://forem.com/bartoszgajda55/scala-collections-in-a-nutshell-o1o</guid>
      <description>&lt;p&gt;The Scala language, being a mix of object oriented and functional programming paradigms, has a quite unique collection framework, compared to some other languages. Although inheriting a lot from Java and JVM world, the Scala has a much easier and to use API and is overall more polished. &lt;/p&gt;

&lt;p&gt;In this post, I will show you a range of Scala collections, how to use them with code samples, and where to use them. Enjoy!&lt;/p&gt;

&lt;h2&gt;Scala &lt;code&gt;collection&lt;/code&gt; package(s)&lt;/h2&gt;

&lt;p&gt;First, let's have a look at the packages that contain all the Scala collections. The top-level package is called as you might expect - &lt;code&gt;collection&lt;/code&gt;.  What is more interesting, are the sub-packages included in it. Those contain a more specialized version of typical collections, tailored for the specific use case. &lt;/p&gt;

&lt;p&gt;Whether you require parallel processing, concurrent access or just want to have a normal key-based lookup - just import the right package, and you are good to go!&lt;/p&gt;

&lt;p&gt;The table below presents the name of &lt;code&gt;collections&lt;/code&gt; sub-package, as well as brief description of what you can find there.&lt;/p&gt;


&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Package Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;collection&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines the base traits and objects needed to use and extend Scala’s collections&lt;br&gt;library, including all definitions in sub-packages. Most of the abstractions you’ll&lt;br&gt;work with are defined here.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;collection.concurrent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines a &lt;em&gt;Map &lt;/em&gt;trait and &lt;em&gt;TrieMap &lt;/em&gt;class with atomic, lock-free access&lt;br&gt;operations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;collection.convert&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines types for wrapping Scala collections with Java collection abstractions&lt;br&gt;and wrapping Java collections with Scala collection abstractions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;collection.generic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines reusable components used to build the specific mutable, immutable,&lt;br&gt;etc. collections.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;collection.immutable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines the immutable collections, the ones you’ll use most frequently.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;collection.mutable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines mutable collections. Most of the specific collection types are available&lt;br&gt;in mutable and immutable forms, but not all.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;collection.parallel&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines reusable components used to build specific mutable and immutable&lt;br&gt;collections that distribute processing to parallel threads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;collection.parallel.immutable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines parallel, immutable collections.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;collection.parallel.mutable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines parallel, mutable collections.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;collections.script&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A deprecated package of tools for observing collection operations.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
Source: &lt;a href="https://learning.oreilly.com/library/view/programming-scala-2nd/9781491950135/" rel="noreferrer noopener"&gt;Programming Scala, 2nd Edition&lt;/a&gt;




&lt;p&gt;As you can see the range of options is very wide. On one hand, it is always good to have an appropriate collection for any use case. On the other hand, it is quite difficult to get started, if you are just looking to implement simple &lt;code&gt;Map&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the purpose of this post, let's focus on the most widely used collections - &lt;code&gt;immutable&lt;/code&gt; &lt;/p&gt;

&lt;h2&gt;&lt;code&gt;collection.immutable&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;The package of immutable collections is the most popular out of all Scala collections. In fact, this package is included in the scope by default, so we can start using it without any imports.&lt;/p&gt;

&lt;p&gt;This package includes lots of both traits and concrete implementations of certain data structures. The image below shows those (blue is a &lt;em&gt;trait&lt;/em&gt;, and black is &lt;em&gt;class&lt;/em&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NAbmMrJY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/08/collections-immutable-diagram.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NAbmMrJY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bartoszgajda.com/wp-content/uploads/2020/08/collections-immutable-diagram.svg" alt="" class="wp-image-3841"&gt;&lt;/a&gt;Source: &lt;a href="https://docs.scala-lang.org/overviews/collections/overview.html" rel="noreferrer noopener"&gt;Scala Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's set that aside and actually learn to use some of the basic collections. The following sections focus on some of the widely used implementations, one at a time.&lt;/p&gt;

&lt;h2&gt;&lt;code&gt;Set&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;The first one on the list is &lt;code&gt;Set&lt;/code&gt;. This is a collection, which contains no duplicate elements. If having only unique elements in the collection, that is the one you should choose. A &lt;code&gt;Set&lt;/code&gt; is created like that:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;// Set of Char type
val set: Set[Char] = Set('a', 'b', 'c')

// Or just empty Set
val setOfInt: Set[Int] = Set()&lt;/pre&gt;

&lt;p&gt;What's interesting about operations in &lt;code&gt;Set&lt;/code&gt;, is the &lt;code&gt;apply&lt;/code&gt; method. The &lt;code&gt;apply&lt;/code&gt; method behaves like &lt;code&gt;contains&lt;/code&gt; method - both check whether the &lt;code&gt;Set&lt;/code&gt; contains a given element:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;val set: Set[Int] = Set(1, 2, 5, 6, 9)

set.contains(2) // true
set(2) // same as above, returns true&lt;/pre&gt;

&lt;p&gt;A &lt;code&gt;Set&lt;/code&gt; offers a wide range of operations - full reference can be found &lt;a href="https://www.scala-lang.org/api/current/scala/collection/immutable/Set.html" rel="noreferrer noopener"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Where to use &lt;code&gt;Set&lt;/code&gt;?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't want duplicates&lt;/li&gt;
&lt;li&gt;Need to quickly check for the presence of an element&lt;/li&gt;
&lt;li&gt;No need to traverse&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;code&gt;Map&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;Map&lt;/code&gt; is a collection of key-value pairs. Every key has a corresponding value assigned to it. Keys have to be unique, in order to provide &lt;code&gt;O(1)&lt;/code&gt; lookup time. Values, however, do not have to be unique. Let's see how we can create a &lt;code&gt;Map&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;// A Map of Int to String mapping
val map: Map[Int, String] = Map(1 -&amp;gt; "one", 2 -&amp;gt; "two", 3 -&amp;gt; "three")

// Or an empty Map
val emptyMap: Map[String, String] = Map()&lt;/pre&gt;

&lt;p&gt;The elements in the &lt;code&gt;Map&lt;/code&gt;, are created using &lt;code&gt;key -&amp;gt; value&lt;/code&gt; syntax, although you can also use &lt;code&gt;(key, value)&lt;/code&gt; if you prefer (first version is preferred though).&lt;/p&gt;

&lt;p&gt;What's interesting about the &lt;code&gt;Map&lt;/code&gt;, is how we can get a value, using a key. The default method to get a value is &lt;code&gt;get(key)&lt;/code&gt; method. This method, however, returns an &lt;code&gt;Option[T]&lt;/code&gt;, and not &lt;code&gt;T&lt;/code&gt;. That is to accommodate for a situation when a key doesn't exist - instead of an exception, an &lt;code&gt;Option[None]&lt;/code&gt; is returned. If you prefer getting straight value, the apply method will give you that (or exception if none found of course). Let's see how it looks:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;val map: Map[Char, Int] = Map('I' -&amp;gt; 1, 'V' -&amp;gt; 5, 'X' -&amp;gt; 10)

map.get('I') // returns Option[Int]
map.get('D') // returns Option[None]

map('V') // returns 5
map('C') // throws exception&lt;/pre&gt;

&lt;p&gt;A &lt;code&gt;Map&lt;/code&gt; offers a wide range of operations - full reference can be found &lt;a href="https://www.scala-lang.org/api/current/scala/collection/Map.html" rel="noreferrer noopener"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can learn more about &lt;code&gt;Option&lt;/code&gt; in my &lt;a href="https://bartoszgajda.com/2020/02/23/monads-in-scala-by-example/" rel="noreferrer noopener"&gt;blog post&lt;/a&gt; on it.&lt;/p&gt;

&lt;p&gt;Where to use &lt;code&gt;Map&lt;/code&gt;?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need key-value storage&lt;/li&gt;
&lt;li&gt;Need O(1) lookup and retrieval&lt;/li&gt;
&lt;li&gt;Order is not important&lt;/li&gt;
&lt;li&gt;No duplicate keys required&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;code&gt;Vector&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;Vector&lt;/code&gt; is an indexed, ordered, and traversable sequence. Despite sounding quite complicated, it's quite popular, general-purpose data structure, thanks to its good balance between fast random selection and fast random functional updates. Let's see how to use them in practice:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;// A Vector of Integers
val vector: Vector[Int] = Vector(1, 2, 3, 5, 7, 11)

// Or an empty Vector
val emptyVector: Vector[String] = Vector()&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;apply&lt;/code&gt; method of &lt;code&gt;Vector&lt;/code&gt;, simply gets and element, using and index in the vector. In this data structure, an index must be between zero and the length of a vector - otherwise, and &lt;code&gt;IndexOutOfBoundsException&lt;/code&gt; is thrown:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;val vector: Vector[String] = Vector("one", "two", "three")

vector(0) // returns "one"
vector(3) // exception&lt;/pre&gt;

&lt;p&gt;A &lt;code&gt;Vector&lt;/code&gt; offers a wide range of operations - full reference can be found &lt;a href="https://www.scala-lang.org/api/current/scala/collection/immutable/Vector.html" rel="noreferrer noopener"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Where to use &lt;code&gt;Vector&lt;/code&gt;?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need fast random access and updates&lt;/li&gt;
&lt;li&gt;Need fast append/prepend/tail operations&lt;/li&gt;
&lt;li&gt;Must be traversable&lt;/li&gt;
&lt;li&gt;Ordering matters&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;code&gt;List&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;The last collection is the easiest and therefore popular among simple use cases - &lt;code&gt;List&lt;/code&gt;. This collection is implemented as a linked list, which represents ordered collections. Let's see how to use a &lt;code&gt;List&lt;/code&gt;:&lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;// List of Strings
val list: List[String] = List("blue", "red", "yellow")

// Empty List
val emptyList: List[Int] = List()&lt;/pre&gt;

&lt;p&gt;As mentioned above, a &lt;code&gt;List&lt;/code&gt; is implemented as a linked list. This means, that we can create a list, using prepend operator &lt;code&gt;::&lt;/code&gt; and a Nil, which represents empty list. This can be done like this: &lt;/p&gt;

&lt;pre class="EnlighterJSRAW"&gt;// Same as example from above
val list: List[String] = "blue" :: ("red" :: ("yellow" :: Nil))

// And an empty List
val emptyList = Nil&lt;/pre&gt;

&lt;p&gt;A &lt;code&gt;List&lt;/code&gt; offers a wide range of operations - full reference can be found &lt;a href="https://www.scala-lang.org/api/current/scala/collection/immutable/List.html" rel="noreferrer noopener"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Where to use &lt;code&gt;List&lt;/code&gt;?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have to be traversable&lt;/li&gt;
&lt;li&gt;Need O(1) prepending and reading of head element&lt;/li&gt;
&lt;li&gt;Can tolerate O(n) appending and reading of internal elements&lt;/li&gt;
&lt;li&gt;Don't need random access&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂&lt;/p&gt;

</description>
      <category>scala</category>
      <category>java</category>
      <category>jvm</category>
      <category>functional</category>
    </item>
    <item>
      <title>5 best study resources for GCP ACE exam</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Mon, 10 Aug 2020 13:20:39 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/5-best-study-resources-for-gcp-ace-exam-1jfi</link>
      <guid>https://forem.com/bartoszgajda55/5-best-study-resources-for-gcp-ace-exam-1jfi</guid>
      <description>&lt;p&gt;Recently, I have finally had a chance to attempt an exam for Google Cloud Certified Associate Cloud Engineer certification and I have passed in first attempt! This achievement has been possible, thanks to thorough preparation, during which I have used a selection of resources. In this post I will be sharing with you 5 of those that I think have contributed the most to the positive outcome of the GCP ACE exam. Enjoy!&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Official GCP ACE Study Guide
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I8mCGnig--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/0%2AHszVHvk5PjrUbBVb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I8mCGnig--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/0%2AHszVHvk5PjrUbBVb.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first element on the list is probably the most comprehensive source of knowledge you can get to prepare for GCP ACE exam. This book consists of 18 chapters, each covering a large chunk of knowledge you have to possess in order to pass the exam. Chapters include screenshots, so you can easily recreate the steps shown on the paper. Each of those chapters is finished with 20 question mini-exam, that reflects quite good the questions you might encounter on real assignment.&lt;/p&gt;

&lt;p&gt;In addition to that, you also get two full practice exams and around 100 flashcards. The flashcards are especially useful in the learning process, but I know it’s quite personal thing.&lt;/p&gt;

&lt;p&gt;This books costs typically around £25, which I think is really good bang for the buck.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. A Cloud Guru Course
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_I94sqS0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/554/0%2A1hzIkcx-a0l_YDH5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_I94sqS0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/554/0%2A1hzIkcx-a0l_YDH5.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second source I have used was A Cloud Guru course on GCP ACE certification exam. I have used the Udemy to get it, but you can also buy it from an official page (it’s probably better to buy at the source).&lt;/p&gt;

&lt;p&gt;The course is quite comprehensive, especially the GKE and Kubernetes related chapters. It takes around 10–12 hours to complete, depending on your studying pace. This course also covers all the chapters like the book, but it comes in much more practical fashion.&lt;/p&gt;

&lt;p&gt;Online courses have big advantage over written word, as it is easier to follow what the instructor is doing and getting hands-on experience of the platform.&lt;/p&gt;

&lt;p&gt;The price of this course varies — I got it on Udemy for around £15, but that was during sale (which thankfully are quite often on Udemy). If you buy it directly, it is going to cost you a bit more.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Linux Academy Course
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f4KJyMBp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/730/0%2AoCu9Wy0nv3icADQJ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f4KJyMBp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/730/0%2AoCu9Wy0nv3icADQJ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another online course comes from Linux Academy. They are known for their high-quality exam prep course and this one is no exception. It takes a bit longer than A Cloud Guru one but in my opinion it’s for the better.&lt;/p&gt;

&lt;p&gt;This course covers all of the exam study points (as all of the above sources) but in my personal opinion, does the best work of showing how to actually use the GCP in practice. The lessons are optimally sized and the instructor does a great job of explaining the inner workings of Google Cloud services.&lt;/p&gt;

&lt;p&gt;This course is at the time of writing only available on Linux Academy site. The best option there is to go with membership — that will cost you \$49 per month.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Google Code Labs
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zv4LURh5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1382/0%2AxFN0kCNGcGnYn1hm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zv4LURh5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1382/0%2AxFN0kCNGcGnYn1hm.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Code Labs is my personal favourite on this list. This site is a collection of labs that are completely free and guide you step by step how to implement a real-world solution or application on Google Cloud Platform.&lt;/p&gt;

&lt;p&gt;There is a broad selection of labs, covering more Google services than you actually need to pass the ACE exam. Each lab shows you the exact steps you have to complete, in order to finish with complete and working solution to a selected problem (like deploying a Spring Web app on Google App Engine).&lt;/p&gt;

&lt;p&gt;It is a great resource not only for ACE exam but for any Google Cloud certification.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Google Qwiklabs
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rMixTzl7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/892/0%2ATyV4lw_sDS9wKr6r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rMixTzl7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/892/0%2ATyV4lw_sDS9wKr6r.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last resource on the list is probably well known to anyone preparing for GCP Associate Cloud Engineer exam. The Qwiklabs provides a so called ‘quests’ which are a form of labs that guide you Google Cloud Platform and show the underlying fundamentals of this environment.&lt;/p&gt;

&lt;p&gt;It’s quite comprehensive, although I wouldn’t risk attempting the exam after the Qwiklabs only, but it serves as great supporting material.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂&lt;br&gt;
&lt;/p&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--V2J_1RRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1120823982368985091/nCtZbGBM_normal.png" alt="Bartosz Gajda profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Bartosz Gajda
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/bartoszgajda55"&gt;@bartoszgajda55&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Want to become &lt;a href="https://twitter.com/googlecloud"&gt;@googlecloud&lt;/a&gt; Certified Associate Cloud Engineer? This post shows 5 best resources to study and pass the exam with ease!&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/tKfuSaPuuX"&gt;bartoszgajda.com/2020/07/13/5-b…&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="https://twitter.com/hashtag/google"&gt;#google&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/google"&gt;#google&lt;/a&gt;cloudplatform &lt;a href="https://twitter.com/hashtag/gcp"&gt;#gcp&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/gcp"&gt;#gcp&lt;/a&gt;ace &lt;a href="https://twitter.com/hashtag/asociatecloudengineer"&gt;#asociatecloudengineer&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/exam"&gt;#exam&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/certification"&gt;#certification&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/cloud"&gt;#cloud&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/aws"&gt;#aws&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/azure"&gt;#azure&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      18:43 PM - 28 Sep 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1310651444043952128" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1310651444043952128" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      1
      &lt;a href="https://twitter.com/intent/like?tweet_id=1310651444043952128" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      0
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


</description>
      <category>googlecloud</category>
      <category>gcp</category>
      <category>cloud</category>
      <category>resources</category>
    </item>
    <item>
      <title>Exploiting Schema Inference in Apache Spark</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Mon, 10 Aug 2020 13:18:25 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/exploiting-schema-inference-in-apache-spark-4mej</link>
      <guid>https://forem.com/bartoszgajda55/exploiting-schema-inference-in-apache-spark-4mej</guid>
      <description>&lt;p&gt;One of the greatest feature of Apache Spark is it’s ability to infer the schema on the fly. Reading the data and generating a schema as you go although being easy to use, makes the data reading itself slower. However, there is a trick to generate the schema once, and then just load it from disk. Let’ dive in!&lt;/p&gt;

&lt;p&gt;For the sake of this article, let’s assume that we are using data with complex data structure, where creating a case class or struct type of any kind would be a hundred lines long.&lt;/p&gt;

&lt;h1&gt;
  
  
  Saving the Schema
&lt;/h1&gt;

&lt;p&gt;Let’s begin with reading some sample data and enforcing a schema inference on it. Using Apache Spark and Scala language, this can be done like following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val carsDf = spark.read
    .option("inferSchema", "true")
    .json("src/main/resources/data/cars.json")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I read a sample JSON file (&lt;code&gt;cars.json&lt;/code&gt;) to a DataFrame called &lt;code&gt;carsDf&lt;/code&gt;. A sample record of this dataset looks like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "Name":"chevrolet chevelle malibu",
   "Miles_per_Gallon":18,
   "Cylinders":8,
   "Displacement":307,
   "Horsepower":130,
   "Weight_in_lbs":3504,
   "Acceleration":12,
   "Year":"1970-01-01",
   "Origin":"USA"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As we can see above, the schema is fairly straight forward to understand. Now, let’s see what Spark has managed to infer from it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val schemaJson = carsDf.schema.json
println(schemaJson)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The output of this action can be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "type":"struct",
   "fields":[
      {
         "name":"Acceleration",
         "type":"double",
         "nullable":true,
         "metadata":{

         }
      },
      {
         "name":"Cylinders",
         "type":"long",
         "nullable":true,
         "metadata":{

         }
      },
      {
         "name":"Displacement",
         "type":"double",
         "nullable":true,
         "metadata":{

         }
      },
      {
         "name":"Horsepower",
         "type":"long",
         "nullable":true,
         "metadata":{

         }
      },
      {
         "name":"Miles_per_Gallon",
         "type":"double",
         "nullable":true,
         "metadata":{

         }
      },
      {
         "name":"Name",
         "type":"string",
         "nullable":true,
         "metadata":{

         }
      },
      {
         "name":"Origin",
         "type":"string",
         "nullable":true,
         "metadata":{

         }
      },
      {
         "name":"Weight_in_lbs",
         "type":"long",
         "nullable":true,
         "metadata":{

         }
      },
      {
         "name":"Year",
         "type":"string",
         "nullable":true,
         "metadata":{

         }
      }
   ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That is how Spark defines the schema it managed to infer. Now, this information would have to be recreated every time we launch our Spark job. When doing development, there is a lot of that, and so we are losing a lot of time on recreation of that schema. Let’s try to generate it once and reuse in consecutive reads.&lt;/p&gt;

&lt;p&gt;In the Scala I am using, the schema’s JSON file can be saved to local filesystem using the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val file = new File("src/resources/schema.json")
val bw = new BufferedWriter(new FileWriter(file))
bw.write(schemaJson)
bw.close()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This way, our inferred schema is saved to local filesystem as a JSON file called &lt;code&gt;schema.json&lt;/code&gt;. In the next step, we will see how to read it and speed up the Spark with it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Loading the Schema
&lt;/h1&gt;

&lt;p&gt;Now, let’s see how to read the JSON file using Spark and Scala environment. This can be done using the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.apache.spark.sql.types.{DataType, StructType}

val schemaJson = Source
    .fromFile("src/resources/schema.json")
    .getLines
    .mkString

val schemaStructType = Try(DataType.fromJson(schemaJson))
        .getOrElse(LegacyTypeStringParser.parse(schemaJson))
    match {
      case t: StructType =&amp;gt; t
      case _ =&amp;gt; throw new RuntimeException(s"Failed parsing JSON Schema")
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The section of code above, reads the schema from JSON file and parses it into a &lt;code&gt;StructType&lt;/code&gt; instance, thanks to Spark SQL package. I have used pattern matching here, to accommodate for the incorrect path being used.&lt;/p&gt;

&lt;p&gt;With the pre-generated schema being available, reading the data in Spark will be way faster. Using our example with &lt;code&gt;cars.json&lt;/code&gt; file, we can read this data like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val carsDf = spark.read
    .schema(schemaStructType)
    .json("src/main/resources/data/cars.json")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂&lt;/p&gt;

</description>
      <category>spark</category>
      <category>scala</category>
      <category>bigdata</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Scala Type Bounds</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Mon, 10 Aug 2020 13:16:36 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/scala-type-bounds-21op</link>
      <guid>https://forem.com/bartoszgajda55/scala-type-bounds-21op</guid>
      <description>&lt;p&gt;Working with types in Scala can be challenging in many ways. The deeper you dig into the complexity of this subject, the more difficult is to find the right path. In this short post, I will be explaining some of the most fundamental of Scala type system — the type bounds. Enjoy!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is type bound?
&lt;/h2&gt;

&lt;p&gt;A type bound is nothing more than a mechanism to add restrictions to the type parameters. When passing a type to let’s say a class, we can limit to what types we want to allow. This mechanism allows for greater control over our code and hopefully making it more robust.&lt;/p&gt;

&lt;p&gt;There are 3 distinct type bounds available in Scala — upper bound, lower bound and upper and lower combined. The chapters below explain how to use each of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upper type bound
&lt;/h2&gt;

&lt;p&gt;An upper type bound constraints a type &lt;code&gt;A&lt;/code&gt; to be a &lt;strong&gt;subtype&lt;/strong&gt; of &lt;code&gt;B&lt;/code&gt;. The Scala notation looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    class SomeClass[A &amp;lt;: B]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The example above defines the type of &lt;code&gt;A&lt;/code&gt; as a subtype of &lt;code&gt;B&lt;/code&gt;. To understand it better, let's use some better example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    trait Eatable

    class Vegetable extends Eatable
    class Meat extends Eatable

    class Potato extends Vegetable
    class Beef extends Meat
    class Orange extends Eatable

    class Vegan[A &amp;lt;: Vegetable]
    class Carnivore[A &amp;lt;: Meat]
    class Food[A &amp;lt;: Eatable]

    val vegan = new Vegan[Potato] // works fine
    val mixed = new Carnivore[Potato] // error - type argument doesn't conform to type parameter bound
    val all = new Food[Beef] // all good
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As seen on a few examples above, the mechanism is pretty easy to use. The class &lt;code&gt;Vegan&lt;/code&gt;, requires its type parameter to a subtype of &lt;code&gt;Vegetable&lt;/code&gt;, which is exactly what &lt;code&gt;Potato&lt;/code&gt; is. On the other hand, class &lt;code&gt;Carnivore&lt;/code&gt; requires its parameter type to be a subtype of &lt;code&gt;Meat&lt;/code&gt;, which &lt;code&gt;Potato&lt;/code&gt; isn't hence the error. The &lt;code&gt;Food&lt;/code&gt; class accepts any class that extends &lt;code&gt;Eatable&lt;/code&gt; trait - a &lt;code&gt;Beef&lt;/code&gt; is one of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lower type bound
&lt;/h2&gt;

&lt;p&gt;A lower type bounds works as one would expect — it limits the type &lt;code&gt;A&lt;/code&gt; to be a &lt;strong&gt;supertype&lt;/strong&gt; of &lt;code&gt;B&lt;/code&gt;. The notation looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    class OtherClass[A &amp;gt;:  B]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The notation is similar to previous bound — only the less than sign is replaced with greater than sign. Let’s use the classes from previous examples to see the lower type bound in practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    trait Eatable

    class Vegetable extends Eatable
    class Meat extends Eatable

    class Potato extends Vegetable
    class Beef extends Meat
    class Orange extends Eatable

    class Stew[A &amp;gt;: Potato]
    class BBQ[A &amp;gt;: Beef]
    class Juice[A &amp;gt;: Orange]

    val stew = new Stew[Vegetable] // works fine
    val BBQ = new BBQ[Meat] // fine as well
    val juice = new Juice[Potato] // error
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The lower type bound is similarly easy to use. We specify three more concrete classes: &lt;code&gt;Stew&lt;/code&gt;, &lt;code&gt;BBQ&lt;/code&gt;, and &lt;code&gt;Juice&lt;/code&gt;. &lt;code&gt;Stew&lt;/code&gt; requires its type parameter to a supertype of &lt;code&gt;Potato&lt;/code&gt;, for &lt;code&gt;BBQ&lt;/code&gt; the type parameter should be a supertype of &lt;code&gt;Beef&lt;/code&gt; and for &lt;code&gt;Juice&lt;/code&gt; - supertype of &lt;code&gt;Orange&lt;/code&gt;. First to instantiations work fine, but the last one fails - the &lt;code&gt;Potato&lt;/code&gt; is by no means a supertype of &lt;code&gt;Orange&lt;/code&gt;, therefore an error is thrown.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lower and upper type bound
&lt;/h2&gt;

&lt;p&gt;Last example is actually a combination of previous two. Scala allows to define both lower and upper bounds in the same time. The notation for this looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    class LastClass[A &amp;lt;: B &amp;gt;: C]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In this example, the type &lt;code&gt;A&lt;/code&gt;, has to be a subtype of &lt;code&gt;B&lt;/code&gt;, while also being a supertype of &lt;code&gt;C&lt;/code&gt;. As complicated as it may sound, it will be easier to understand using our 'food' examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    trait Eatable

    class Vegetable extends Eatable
    class Meat extends Eatable

    class Potato extends Vegetable
    class Beef extends Meat
    class Orange extends Eatable

    class MarisPiper extends Potato
    class Wagyu extends Beef
    class Curacao extends Orange

    class RedMeat[A &amp;lt;: Meat &amp;gt;: Wagyu]
    class RootVegetable[A &amp;lt;: Vegetable &amp;gt;: MarisPiper]

    val stew = new RedMeat[Beef] // all good
    val BBQ = new RootVegetable[Potato] // works fine
    val juice = new RootVegetable[MarisPiper] // error
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This example should be fairly self-explanatory — we have two classes that use both upper and lower type bounds for their type parameters: &lt;code&gt;RedMeat&lt;/code&gt; and &lt;code&gt;RootVegetable&lt;/code&gt;. From the classes defined, the &lt;code&gt;Beef&lt;/code&gt; works for the first one, and &lt;code&gt;Potato&lt;/code&gt; for the second one. The &lt;code&gt;Meat&lt;/code&gt; doesn't meet the upper type bound and &lt;code&gt;Wagyu&lt;/code&gt; the lower type bound for &lt;code&gt;RedMeat&lt;/code&gt; class type parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--V2J_1RRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1120823982368985091/nCtZbGBM_normal.png" alt="Bartosz Gajda profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Bartosz Gajda
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/bartoszgajda55"&gt;@bartoszgajda55&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Scala's type bounds explained - upper bound lower bound and combination of both. Leverage &lt;a href="https://twitter.com/scala_lang"&gt;@scala_lang&lt;/a&gt; powerful type system mechanism.&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/1AyQ1y2jpK"&gt;bartoszgajda.com/2020/06/14/sca…&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="https://twitter.com/hashtag/scala"&gt;#scala&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/scala"&gt;#scala&lt;/a&gt;lang &lt;a href="https://twitter.com/hashtag/fp"&gt;#fp&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/oop"&gt;#oop&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/programming"&gt;#programming&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/tutorial"&gt;#tutorial&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/typesystem"&gt;#typesystem&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/java"&gt;#java&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/jvm"&gt;#jvm&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      13:10 PM - 15 Sep 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1305856520098373632" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1305856520098373632" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1305856520098373632" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      0
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


</description>
      <category>scala</category>
      <category>java</category>
      <category>jvm</category>
      <category>functional</category>
    </item>
    <item>
      <title>Why I have chosen AWS Lightsail to host my site</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Mon, 10 Aug 2020 13:11:17 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/why-i-have-chosen-aws-lightsail-to-host-my-site-pj0</link>
      <guid>https://forem.com/bartoszgajda55/why-i-have-chosen-aws-lightsail-to-host-my-site-pj0</guid>
      <description>&lt;p&gt;When I have decided to start writing my own programming blog, I wasn’t sure what is the best platform to start on. I was convinced that despite its flaws, WordPress will be my CMS of choice. But that wasn’t the only choice to make — a hosting platform had to be chosen as well. In this post, I will explain why I think AWS Lightsail is the optimal service to do this.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is AWS Lightsail?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Lightsail is an easy-to-use cloud platform that offers you everything needed to build an application or website, plus a cost-effective, monthly plan.&lt;/em&gt;&lt;br&gt;
 &lt;a href="https://aws.amazon.com/lightsail/"&gt;*AWS Website&lt;/a&gt;*&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Amazon Web Services (AWS) ecosystem consists of several hosting options and Lightsail is one of them. As the quote above explains — it’s a managed hosting service that combines computing and storage with affordable pricing. This service itself can support a range of use cases, from test environment for hobby projects to fully-featured web applications.&lt;/p&gt;

&lt;p&gt;Now, let’s dive deeper into why I think it’s a great platform for anyone looking for easy and cheap hosting of their site.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. It’s fully managed
&lt;/h2&gt;

&lt;p&gt;The Lightsail is a managed service, which means that we do not have to think about the underlying infrastructure or platform, updates or anything like it. No need to configure networking, security and what not — it’s all taken care by AWS. What is great as well about Lightsail, is its User Interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qTMlp5Dm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AMqi_QraVYlFegzH9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qTMlp5Dm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AMqi_QraVYlFegzH9.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What you get is a simple and effective dashboard for managing your instances. In reality, you really don’t need to do anything over there, except for making database snapshots from time to time.&lt;/p&gt;

&lt;p&gt;If your really need to get connected directly to the instance, there is an option to do it. You can connect using popular clients like PuTTy or use the AWS’s built in Shell.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. It supports many environments
&lt;/h2&gt;

&lt;p&gt;I use the Lightsail to host the WordPress instance, but that is not the only option. As of writing this post, the AWS allows to choose from 25 different environment options, depending on your needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3lYhf_PD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AAMkha0d8x8xeyj11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3lYhf_PD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AAMkha0d8x8xeyj11.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see on the screenshot above, the options are quite diverse and broad. I personally use the WordPress option only, but I assume other environment works equally good if not better.&lt;/p&gt;

&lt;p&gt;Hosting the hobby projects, thanks to PHP, Node and Python runtimes is very easy. The instance creation wizard is just a click-through setup that doesn’t require any AWS specific knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. It’s cheap
&lt;/h2&gt;

&lt;p&gt;For some this might be the most important point — hosting on AWS Lightsail is just cheap. The cheapest plan you can get (and the one I am actually using) will cost you $3.5 per month. If you really need some computing power, you can up to 8 CPUs and 32GB of RAM for $160 per month.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SOkhlz7o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A3M3PumWLlumbvN-O.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SOkhlz7o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A3M3PumWLlumbvN-O.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From my experience, I can say that for hosting a WordPress blog, the cheapest plan will do just fine. I don’t have a massive traffic on my site, and my monthly viewer count ranges around 1000, so 512MB of RAM and 1 CPU is enough.&lt;/p&gt;

&lt;p&gt;For hosting load and traffic heavy applications, I would recommend revising other services — $160 per month is quite a lot and other AWS services might provide same computing power with a smaller price tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. It scales automatically
&lt;/h2&gt;

&lt;p&gt;Because AWS Lightsail is a managed service, the scaling is automatic by default. This is a great option if your website gets spikes in traffic or load, or you expect your site to grow rapidly. I have myself noticed that my WordPress instance gets significantly more traffic when I share a new post on the Social Medias. Despite that, I have never had a problem accessing the site, nor any of my visitors.&lt;/p&gt;

&lt;p&gt;One thing about scaling that has to be kept in mind is that it costs — a spike in traffic that requires to upscale the website will surely be seen on a monthly bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂&lt;br&gt;
&lt;/p&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--V2J_1RRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1120823982368985091/nCtZbGBM_normal.png" alt="Bartosz Gajda profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Bartosz Gajda
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/bartoszgajda55"&gt;@bartoszgajda55&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Looking for easy and cheap website hosting - &lt;a href="https://twitter.com/awscloud"&gt;@awscloud&lt;/a&gt;  Lightsail is the way to go. I explain why hosting &lt;a href="https://twitter.com/WordPress"&gt;@WordPress&lt;/a&gt; on &lt;a href="https://twitter.com/hashtag/AWS"&gt;#AWS&lt;/a&gt; Lightsail is the best option.&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/qEe1GevAS7"&gt;bartoszgajda.com/2020/06/01/why…&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="https://twitter.com/hashtag/aws"&gt;#aws&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/amazonwebservices"&gt;#amazonwebservices&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/cloud"&gt;#cloud&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/lightsail"&gt;#lightsail&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/aws"&gt;#aws&lt;/a&gt;lightsail &lt;a href="https://twitter.com/hashtag/deployment"&gt;#deployment&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/hosting"&gt;#hosting&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/wordpress"&gt;#wordpress&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/wp"&gt;#wp&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      10:46 AM - 31 Aug 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1300384425021247488" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1300384425021247488" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1300384425021247488" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      0
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


</description>
      <category>aws</category>
      <category>cloud</category>
      <category>serverless</category>
      <category>devops</category>
    </item>
    <item>
      <title>Partial Functions in Scala</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Mon, 10 Aug 2020 13:09:23 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/partial-functions-in-scala-4152</link>
      <guid>https://forem.com/bartoszgajda55/partial-functions-in-scala-4152</guid>
      <description>&lt;p&gt;Writing functions and methods that process the input data and produce some output is the very core of any type of programming. When diving deeper into different types of functions in Scala, there is one type that differs from others — partial function. As the element of Scala’s standard library, it is appropriate to know what it is and where it should be used. Let’s dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Partial Function?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;A partial function of type &lt;em&gt;PartialFunction[A, B]&lt;/em&gt; is a unary function where the domain does not necessarily include all values of type &lt;em&gt;A&lt;/em&gt;.&lt;br&gt;
 &lt;em&gt;Scala Standard Library&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The definition above, taken straight from the Scala lang standard library docs may seem quite obfuscated. Fear not though, as the concept of partial function is very easy to understand.&lt;/p&gt;

&lt;p&gt;In essence, a partial function is a function that accepts only a specific set of data as the input. This doesn’t mean that the function takes only integers and not strings — this behaviour is a standard element of any function. The partial function that accepts integer parameter as the input, can specify what exact integers are accepted.&lt;/p&gt;

&lt;p&gt;To better understand the concept, let’s see some code examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to write Partial Function
&lt;/h2&gt;

&lt;p&gt;First, let’s write a standard function that accepts any input of type Int:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   val standardFunction = (x: Int) =&amp;gt; x % 10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;standardFunction&lt;/code&gt; is like any other - takes a parameter and returns the remainder when dividing by 10. Now, what if a developer passes zero as the parameter? Or if we need even more refined restrictions regarding the parameter? One way would be to write a long block of ifs and elses, but that is not what you would want to do. Instead, let's write a partial function, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    val partialFunction: PartialFunction[Int, Int] = {
        case 1 =&amp;gt; 100
        case 2 =&amp;gt; 120
        case 3 =&amp;gt; 130
      }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;partialFunction&lt;/code&gt; above is defined using the &lt;code&gt;PartialFunction[Int, Int]&lt;/code&gt; trait. The type parameters say that both input and the output will be of type Int. As you can see, this function accepts only three parameters: either 1, 2 or 3. For any other parameter, an exception will be thrown.&lt;/p&gt;

&lt;p&gt;The construction of a partial function is quite easy, but the power comes with the different operators you can use with them. Let’s look at some of them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    partialFunction.isDefinedAt(67)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;isDefinedAt()&lt;/code&gt; - this method allows to check if the partial function will accepts a certain parameter - in our case, 67 will not be accepted, and the method will return false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    partialFunction.lift
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;lift&lt;/code&gt; - this method wraps the return type into an &lt;code&gt;Option&lt;/code&gt;. For the our &lt;code&gt;partialFunction&lt;/code&gt;, that will be &lt;code&gt;Option[Int]&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    partialFunction orElse otherPartialFunction
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;orElse&lt;/code&gt; - this one is very neat - it allows to chain multiple partial function, if the first one doesn't accept the input, or in different words - it's &lt;code&gt;isDefinedAt&lt;/code&gt; method returns false.&lt;/p&gt;

&lt;p&gt;There is plethora of other methods available — be sure to check out the &lt;a href="https://www.scala-lang.org/api/current/scala/PartialFunction.html"&gt;official docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;Map&lt;/code&gt; vs &lt;code&gt;Collect&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;One other interesting behaviour of partial functions can be observed when using it for mapping a collection. Let’s try to use it as if it was a standard function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    List(1, 2, 3, 4, 5).map(partialFunction)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The first three parameters are fine — the &lt;code&gt;partialFunction&lt;/code&gt; have a defined output for them. But what happens with parameters 4 and 5. The answer is: &lt;code&gt;MatchError&lt;/code&gt;. The map function is not able to determine the output and fails.&lt;/p&gt;

&lt;p&gt;The solution to this is to use the collect method. This method uses the &lt;code&gt;isDefinedAt&lt;/code&gt; method before applying the mapping function, therefore avoiding the &lt;code&gt;MatchError&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    List(1, 2, 3, 4, 5).collect(partialFunction)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--V2J_1RRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1120823982368985091/nCtZbGBM_normal.png" alt="Bartosz Gajda profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Bartosz Gajda
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/bartoszgajda55"&gt;@bartoszgajda55&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Learn what &lt;a href="https://twitter.com/hashtag/PartialFunctions"&gt;#PartialFunctions&lt;/a&gt; are and how to use them in &lt;a href="https://twitter.com/hashtag/Scala"&gt;#Scala&lt;/a&gt;. See the difference between &lt;a href="https://twitter.com/hashtag/map"&gt;#map&lt;/a&gt; and &lt;a href="https://twitter.com/hashtag/collect"&gt;#collect&lt;/a&gt; when using those on collection.&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/qK0xTr1Hmx"&gt;bartoszgajda.com/2020/05/17/par…&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="https://twitter.com/hashtag/scala"&gt;#scala&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/scala"&gt;#scala&lt;/a&gt;lang &lt;a href="https://twitter.com/hashtag/partialfunctions"&gt;#partialfunctions&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/java"&gt;#java&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/jvm"&gt;#jvm&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/functionalprogramming"&gt;#functionalprogramming&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/programming"&gt;#programming&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/it"&gt;#it&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/development"&gt;#development&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      12:10 PM - 24 Aug 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1297868840131493889" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1297868840131493889" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1297868840131493889" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      0
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


</description>
      <category>scala</category>
      <category>java</category>
      <category>jvm</category>
      <category>functional</category>
    </item>
    <item>
      <title>5 best resources to learn Scala</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Mon, 10 Aug 2020 13:03:11 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/5-best-resources-to-learn-scala-19e0</link>
      <guid>https://forem.com/bartoszgajda55/5-best-resources-to-learn-scala-19e0</guid>
      <description>&lt;p&gt;Scala is one of the most popular languages used in the JVM ecosystem. The recent post by &lt;a href="https://www.lihaoyi.com/post/TheDeathofHypeWhatsNextforScala.html"&gt;Li Haoyi&lt;/a&gt; explains why Scala is entering the ‘slope of enlightenment’, with ever-growing community and plethora of mature and production-ready tools. It is a great time to start learning Scala and this post will list you, in my opinion, the best places to start your journey with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;a href="https://docs.scala-lang.org/overviews/scala-book/introduction.html"&gt;Scala Book&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ogxiZV39--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2002/0%2A0FYrX0MWyJogb0pi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ogxiZV39--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2002/0%2A0FYrX0MWyJogb0pi.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is no better place to start than Scala Book, that can be found on the official page of Scala language. This is a free guide into the world of Scala for beginners who want to get started as quickly as possible. It provides enough details to grasp the basics of Scala programming, without overwhelming you with too much information.&lt;/p&gt;

&lt;p&gt;You will learn basic control structures, syntax, collections, classes, traits and a few fundamentals of functional programming. There is a lot of different code examples, so you have a chance to explore it in your way. There is no timing or schedule, so you can learn in anytime you fancy.&lt;/p&gt;

&lt;p&gt;My journey with Scala started there, and it helped a lot at the beginning (especially with sometimes weirdly looking syntax :))&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;a href="https://www.scala-exercises.org/"&gt;Scala Exercises&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vIu7Emie--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2048/0%2AE2HPk2Pa1_pRGzL4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vIu7Emie--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2048/0%2AE2HPk2Pa1_pRGzL4.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Scala Exercises is another free to use resource, that can learn you various elements of Scala ecosystem using a series of lectures and exercises. Every chapter in each course, explains in detail what a certain feature is and how to use it in real-life examples. The exercises at the end of the chapter help you to test yourself and improve the learning process.&lt;/p&gt;

&lt;p&gt;There is a plethora of courses available, on topics including: Scala Standard Library, Cats, Shapeless, Doobie and more.&lt;/p&gt;

&lt;p&gt;You can login to the site using your GitHub account, which helps to track the courses and chapters you have enrolled in and progress within them.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. &lt;a href="http://www.horstmann.com/scala/index.html"&gt;Scala for the Impatient&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hhun_kSl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A4MOTxAeW6vFy__Va.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hhun_kSl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A4MOTxAeW6vFy__Va.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first of non-free resources is the book by Cay Horstmman that serves as a guide for Java programmers that want to dive into Scala language. Although being aimed at Java devs, this book can be easily understood by developers using any other major programming language.&lt;/p&gt;

&lt;p&gt;The huge plus of this book is that it explains the features of Scala language in a very concise and easy to digest way. There is no over lengthy debates over the implementation of let’s say certain classes in collections library — instead, you get a nicely rounded explanation of what it is and how to use it.&lt;/p&gt;

&lt;p&gt;The easiest place to get this book is most probably Amazon. You should look for a promotions, as they happen quite often on this book (at least in UK).&lt;/p&gt;

&lt;h2&gt;
  
  
  4. &lt;a href="https://www.udemy.com/course/rock-the-jvm-scala-for-beginners/"&gt;Scala &amp;amp; Functional Programming for Beginners&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S52HbSMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2048/0%2AjWbSO7R18p5ePumG.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S52HbSMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2048/0%2AjWbSO7R18p5ePumG.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first video course I am recommending is ‘Scala &amp;amp; Functional Programming for Beginners’ that can be found on Udemy platform. This course guides you through the world of Scala in well sized chunks, that covers a great deal of topics that are required from Scala developers.&lt;/p&gt;

&lt;p&gt;This course is split into basics, object oriented programming, functional programming and pattern matching. Additionally, there is extra chapter that takes all this information and help you to apply it into a practical project.&lt;/p&gt;

&lt;p&gt;Standard price is around £50, but Udemy does regular promotions, so keep an eye on the site and you might this course for as low as £10.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. &lt;a href="https://www.udemy.com/course/advanced-scala/"&gt;Advanced Scala and Functional Programming&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nj19nzVH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2048/0%2AEPyo5C1jLeNgfn9C.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nj19nzVH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2048/0%2AEPyo5C1jLeNgfn9C.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last resource and the second video course is the continuation of the course from point 4. This course however, is aimed at more advanced developers and those interested in getting from good to great in Scala.&lt;/p&gt;

&lt;p&gt;The course itself tackles important topics like advanced functional programming, concurrency, implicits and type system. All presented with easy to understand context and lots of code samples.&lt;/p&gt;

&lt;p&gt;Same as before, it is best to look for promotions on Udemy website — you should be able to get it at the price around £10.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--V2J_1RRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1120823982368985091/nCtZbGBM_normal.png" alt="Bartosz Gajda profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Bartosz Gajda
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/bartoszgajda55"&gt;@bartoszgajda55&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      5 best resources for an aspiring &lt;a href="https://twitter.com/scala_lang"&gt;@scala_lang&lt;/a&gt; developer. A selection of books, courses, and online sites, which will accelerate your &lt;a href="https://twitter.com/hashtag/Scala"&gt;#Scala&lt;/a&gt; learning.&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/Vxnt6kDzvo"&gt;bartoszgajda.com/2020/05/03/5-b…&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="https://twitter.com/hashtag/scala"&gt;#scala&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/scala"&gt;#scala&lt;/a&gt;lang &lt;a href="https://twitter.com/hashtag/programming"&gt;#programming&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/development"&gt;#development&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/jvm"&gt;&lt;/a&gt;&lt;a href="https://twitter.com/hashtag/jvm"&gt;#jvm&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/functionalprogramming"&gt;#functionalprogramming&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/learning"&gt;#learning&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/jvm"&gt;&lt;/a&gt;&lt;a href="https://twitter.com/hashtag/jvm"&gt;#jvm&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/java"&gt;#java&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/udemy"&gt;#udemy&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      09:51 AM - 17 Aug 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1295297264081080320" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1295297264081080320" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1295297264081080320" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      0
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


</description>
      <category>scala</category>
      <category>java</category>
      <category>jvm</category>
      <category>resources</category>
    </item>
    <item>
      <title>Unit Testing Apache Spark Structured Streaming using MemoryStream</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Mon, 10 Aug 2020 13:00:33 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/unit-testing-apache-spark-structured-streaming-using-memorystream-53bk</link>
      <guid>https://forem.com/bartoszgajda55/unit-testing-apache-spark-structured-streaming-using-memorystream-53bk</guid>
      <description>&lt;p&gt;Unit testing &lt;a href="https://spark.apache.org/"&gt;Apache Spark&lt;/a&gt; Structured Streaming jobs using &lt;em&gt;MemoryStream&lt;/em&gt; in a non-trivial task. Sadly enough, official Spark &lt;a href="https://spark.apache.org/docs/latest/"&gt;documentation &lt;/a&gt;still lacks a section on testing. In this post, therefore, I will show you how to start writing unit tests of Spark Structured Streaming.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is MemoryStream?
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A Source that produces value stored in memory as they are added by the user. This Source is intended for use in unit tests as it can only replay data when the object is still available.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.javadoc.io/doc/org.apache.spark/spark-sql_2.12/latest/org/apache/spark/sql/execution/streaming/MemoryStream.html"&gt;&lt;em&gt;Spark SQL Docs&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;MemoryStream&lt;/em&gt; is one of the streaming sources available in Apache Spark. This source allows us to add and store data in memory, which is very convenient for unit testing. The official docs emphasize this, along with a warning that data can be replayed only when the object is still available.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;MemoryStream&lt;/em&gt; takes a type parameter, which gives our unit tests a very desired type safety. The API of this abstraction is rich but not overwhelming. You should check it out for a full reference.&lt;/p&gt;

&lt;p&gt;Before writing any unit test, let’s create some sample job which will be tested.&lt;/p&gt;

&lt;h1&gt;
  
  
  Writing Spark Structured Streaming job
&lt;/h1&gt;

&lt;p&gt;The job I will be using for the testing, has a simple role — read data from Kafka data source and write it to the Mongo database. In your case, the set of transformations and aggregations will be probably much richer, but the principles stay the same.&lt;/p&gt;

&lt;p&gt;First, I read the Kafka data source and extract the &lt;code&gt;value&lt;/code&gt; column. I am also applying a prebuilt &lt;code&gt;rsvpStruct&lt;/code&gt; schema, but that is specific to my code sample.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import spark.implicits._
val df = spark.readStream
  .format("kafka")
  .option("kafka.bootstrap.servers", "localhost:9092")
  .option("subscribe", "rsvp")
  .load()
val rsvpJsonDf = df.selectExpr("CAST(value as STRING)")
val rsvpStruct = Schema.getRsvpStructSchema
val rsvpDf = rsvpJsonDf.select(from_json($"value", rsvpStruct).as("rsvp"))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, I am outputting the content of parsed data into a Mongo collection. That is done is &lt;code&gt;foreachBatch&lt;/code&gt; action, which loops through every batch in the current result set and allows to perform an arbitrary operation. In my case, I am using &lt;a href="https://docs.mongodb.com/spark-connector/current/scala-api/"&gt;Mongo Spark&lt;/a&gt; connector for persisting the batches.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rsvpDf.writeStream
  .outputMode("append")
  .option("checkpointLocation", "/raw")
  .foreachBatch({(batchDf: DataFrame, batchId: Long) =&amp;gt;
    val outputDf = batchDf.select("rsvp.*")
    outputDf.write
      .format("mongo")
      .mode("append")
      .save()
  })
  .start()
  .awaitTermination()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now that we have the sample job created, let’s start writing a unit test using &lt;em&gt;MemoryStream&lt;/em&gt; class.&lt;/p&gt;

&lt;h1&gt;
  
  
  Unit testing Spark using MemoryStream
&lt;/h1&gt;

&lt;p&gt;The preliminary step in writing a unit test is to have some sample data that can be used by unit tests. In my case, I am using a stringified JSON, that contains information I am normally receiving from my Kafka data source. You should use any data that fits your use case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val sampleRsvp = """{"venue":{"venue_name":"Capitello Wines" ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, inside the test case, we create our &lt;code&gt;SparkSession&lt;/code&gt;. Nothing special has to be set here, just typical config you use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SaveRawDataTest extends AnyFunSuite {
  test("should ingest raw RSVP data and read the parsed JSON correctly") {
    val spark = SparkSession.builder()
      .appName("Save Raw Data Test")
      .master("local[1]")
      .getOrCreate()
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Going further, we define our &lt;code&gt;MemoryStream&lt;/code&gt; using String type parameter. I use string, because that's the type of sample data I am using. To create the &lt;code&gt;MemoryStream&lt;/code&gt;, to imports are needed: &lt;code&gt;sqlContext&lt;/code&gt; that can be obtained from SparkSession and Spark &lt;code&gt;implicits&lt;/code&gt; library, which includes the needed type encoders. Lastly, I convert the stream to &lt;code&gt;DataSet&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;implicit val sqlCtx: SQLContext = spark.sqlContext
import spark.implicits._

val events = MemoryStream[String]
val sessions = events.toDS
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Converting to &lt;code&gt;DataSet&lt;/code&gt; allows us to make first assertion. We can check if the &lt;code&gt;DataSet&lt;/code&gt; is indeed a streaming one. You can do this using the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assert(sessions.isStreaming, "sessions must be a streaming Dataset")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, I add the transformations that have been included in the sample job. In this case however, I will not be checking if the data has been saved in Mongo — I am only interested if the raw stringified JSON has been parse correctly and I can run SQL queries on it. The transformations I use are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val transformedSessions = sessions.select(from_json($"value", rsvpStruct).as("rsvp"))
val streamingQuery = transformedSessions
  .writeStream
  .format("memory")
  .queryName("rawRsvp")
  .outputMode("append")
  .start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It is important to use &lt;code&gt;memory&lt;/code&gt; format, so that the actual data can be queried in a further step to make the assertions. It is useful to also name those results, using &lt;code&gt;queryName&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;Lastly, I add my sample data into the instance of &lt;code&gt;MemoryStream&lt;/code&gt;, process those and commit the offsets, as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val batch = sampleRsvp
val currentOffset = events.addData(batch)

streamingQuery.processAllAvailable()
events.commit(currentOffset.asInstanceOf[LongOffset])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The very last step is to query the committed data and run some assertions on them. In my case, I run a &lt;code&gt;SQL&lt;/code&gt; query, to get the event_name property and I run assertions against that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val rsvpEventName = spark.sql("select rsvp.event.event_name from rawRsvp")
    .collect()
    .map(_.getAs[String](0))
    .head

assert(rsvpEventName == "Eugene ISSA &amp;amp; Technology Association of Oregon December Cyber Security Meetup")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂&lt;/p&gt;

</description>
      <category>spark</category>
      <category>apachespark</category>
      <category>testing</category>
      <category>bigdata</category>
    </item>
    <item>
      <title>5 best IntelliJ IDEA shortcuts</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Mon, 10 Aug 2020 12:58:15 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/5-best-intellij-idea-shortcuts-4c97</link>
      <guid>https://forem.com/bartoszgajda55/5-best-intellij-idea-shortcuts-4c97</guid>
      <description>&lt;p&gt;&lt;a href="https://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt; is awesomely large and complex IDE, mastering which can take years. Knowing the essential IntelliJ IDEA shortcuts can drastically increase your productivity and make using a mouse seem obsolete. In this post I will show you 5 IntelliJ IDEA shortcuts that in my opinion are the best. Enjoy!&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://www.jetbrains.com/help/rider/Navigation_and_Search__Navigating_to_Recent_Locations.html#recent_locations"&gt;Recent Locations&lt;/a&gt; — &lt;code&gt;Ctrl + Shift + E&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;This shortcut shows the popup with the recently accessed files or the files that have been recently changed (Figure 1). Pressing the &lt;code&gt;Ctrl + Shift + E&lt;/code&gt; shortcut again will show you only the changed files. You can start typing, to filter the files. Useful for quickly jumping through files when working in larger context.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a9MW-1SL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1434/0%2AWtUWI_Vj8pBZGHl4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a9MW-1SL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1434/0%2AWtUWI_Vj8pBZGHl4.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://www.jetbrains.com/help/idea/viewing-reference-information.html#inline-quick-documentation"&gt;Show JavaDoc Popup&lt;/a&gt; — &lt;code&gt;Ctrl + Q&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Another useful shortcut, for quickly accessing the JavaDoc of a certain class or interface. Just place the caret on a name and press &lt;code&gt;Ctrl + Q&lt;/code&gt; which will show the popup, as on Figure 2. The availability of JavaDoc depends of course on the framework or library you are using. It is a useful thing to know when working with large frameworks like Spring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gJ8sLypc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1488/0%2A-vlhNgPVJRllHR5t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gJ8sLypc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1488/0%2A-vlhNgPVJRllHR5t.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-project.html#find_in_project"&gt;Replace in Path&lt;/a&gt; — &lt;code&gt;Ctrl + Shift + F&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Replace in path shortcut helped me couple times to avoid going through files when trying to change a variable that occurs many times in the project. The &lt;code&gt;Ctrl + Shift + F&lt;/code&gt; shortcut shows you the popup as on Figure 3. In the first input you can provide the term you are want to replace and in the second one - to what replace with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YQp42miN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1540/0%2A3GRl8uOkTytnzrlu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YQp42miN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1540/0%2A3GRl8uOkTytnzrlu.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://www.jetbrains.com/help/idea/find-highlight-usages.html#usages_in_file"&gt;Highlight Usages&lt;/a&gt; — &lt;code&gt;Ctrl + Shift + F7&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Highlighting the usages is especially useful when working with large files. To do this, place a caret on the word you want to highlight and press &lt;code&gt;Ctrl + Shift + F7&lt;/code&gt;. Depending on the theme you are using, the word may be highlighted differently. In my case, it's bright yellow, like on Figure 4.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zn4SuZbL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1346/0%2Abl3zXQT6I8GYoHFa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zn4SuZbL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1346/0%2Abl3zXQT6I8GYoHFa.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://www.jetbrains.com/help/idea/viewing-structure-of-a-source-file.html"&gt;Show File Structure&lt;/a&gt; — &lt;code&gt;Ctrl + F12&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;The last shortcut helped me a lot when working with complex classes. All you need to do is to press combination &lt;code&gt;Ctrl + F12&lt;/code&gt; and a popup like on Figure 5 will be shown to you. Here you can see all method signatures displayed, which is super helpful when you are only interested in skimming through the class. Pressing the &lt;code&gt;Ctrl + F12&lt;/code&gt; again will also show the members inherited from superclass.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rRgjwufR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1216/0%2AXTuL5ynwli_zw6Yt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rRgjwufR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1216/0%2AXTuL5ynwli_zw6Yt.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally you can follow me on my social media if you fancy so :)&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--V2J_1RRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1120823982368985091/nCtZbGBM_normal.png" alt="Bartosz Gajda profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Bartosz Gajda
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/bartoszgajda55"&gt;@bartoszgajda55&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Best &lt;a href="https://twitter.com/intellijidea"&gt;@intellijidea&lt;/a&gt; shortcuts to speed up your work. Learn 5 shortcuts in IntelliJ IDEA that can drastically ease up your code editing tasks.&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/apgU6qj4D8"&gt;bartoszgajda.com/2020/03/23/5-b…&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="https://twitter.com/hashtag/intellijidea"&gt;&lt;/a&gt;&lt;a href="https://twitter.com/hashtag/intellij"&gt;#intellij&lt;/a&gt;idea &lt;a href="https://twitter.com/hashtag/intellij"&gt;#intellij&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/idea"&gt;&lt;/a&gt;&lt;a href="https://twitter.com/hashtag/ide"&gt;#ide&lt;/a&gt;a &lt;a href="https://twitter.com/hashtag/jetbrains"&gt;#jetbrains&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/ide"&gt;#ide&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/tips"&gt;#tips&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/tricks"&gt;#tricks&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/shortcuts"&gt;#shortcuts&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/webstorm"&gt;#webstorm&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/pycharm"&gt;#pycharm&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/rider"&gt;#rider&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/clion"&gt;#clion&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      15:48 PM - 03 Aug 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1290313679867539456" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1290313679867539456" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1290313679867539456" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      1
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


</description>
      <category>intellij</category>
      <category>ide</category>
      <category>tips</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using Angular and Chart.js to build real-time charts</title>
      <dc:creator>Bartosz Gajda</dc:creator>
      <pubDate>Mon, 10 Aug 2020 12:56:05 +0000</pubDate>
      <link>https://forem.com/bartoszgajda55/using-angular-and-chart-js-to-build-real-time-charts-1078</link>
      <guid>https://forem.com/bartoszgajda55/using-angular-and-chart-js-to-build-real-time-charts-1078</guid>
      <description>&lt;p&gt;&lt;a href="https://angular.io/"&gt;Angular&lt;/a&gt; and &lt;a href="https://www.chartjs.org/"&gt;Chart.js&lt;/a&gt; is popular combination when creating any data visualization application. The first one can handle a very large throughput of data and the later is capable of rendering the plots in real-time, thanks to Canvas API. In this post I will guide you through the process of creating a real-time chart using Angular and Chart.js&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;Before starting to write any code, make sure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.org/en/"&gt;Node.js&lt;/a&gt; — I use version 13.2.0&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cli.angular.io/"&gt;Angular CLI&lt;/a&gt; — I use version 8.3.20&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;10 minutes of free time&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Creating new Angular project
&lt;/h1&gt;

&lt;p&gt;The first step required is to create a new Angular project. As mentioned in prerequisites, I am using Angular CLI to do so and I highly advise you to do the same. Open a terminal window, navigate to desired directory and execute the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new angular-charts --routing=true --styling=scss
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This command creates a new Angular project called &lt;em&gt;angular-charts&lt;/em&gt; in directory of the same name. Additionally, I have added two optional flags — &lt;code&gt;routing&lt;/code&gt; adds the router module to the app and &lt;code&gt;styling&lt;/code&gt; sets the extensions of style sheets used.&lt;/p&gt;

&lt;p&gt;With the project created, open it up in your IDE of choice — I will be using Visual Studio Code for this.&lt;/p&gt;

&lt;h1&gt;
  
  
  Adding a service layer*
&lt;/h1&gt;

&lt;p&gt;The next step of this tutorial is to add a service layer. I have marked this step with asterisk, because it is &lt;strong&gt;optional&lt;/strong&gt;. If you already have one, or you don’t need one, then feel free to skip this section.&lt;/p&gt;

&lt;p&gt;Let’s start this section with generating a service that will give access to real-time data source using &lt;code&gt;Observable&lt;/code&gt;. To generate a service, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate service sse
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After executing the command, and &lt;code&gt;SseService&lt;/code&gt; gets created and that's where the service layer code will be placed. For this tutorial I am using SSE or Server Sent Events data source, tutorial on which you can find &lt;a href="https://bartoszgajda.com/2019/12/22/angular-and-server-sent-events-sse/"&gt;here&lt;/a&gt;. If you need more explanation, don't hesitate to read that tutorial. To avoid repetition in this post, I will just paste in the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable, NgZone } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
  providedIn: "root"
})
export class SseService {
  constructor(private _zone: NgZone) {}
  getServerSentEvent(url: string): Observable&amp;lt;any&amp;gt; {
    return Observable.create(observer =&amp;gt; {
      const eventSource = this.getEventSource(url);
      eventSource.onmessage = event =&amp;gt; {
        this._zone.run(() =&amp;gt; {
          observer.next(event);
        });
      };
      eventSource.onerror = error =&amp;gt; {
        this._zone.run(() =&amp;gt; {
          observer.error(error);
        });
      };
    });
  }
  private getEventSource(url: string): EventSource {
    return new EventSource(url);
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Hooking up the Chart.js
&lt;/h1&gt;

&lt;p&gt;The next step is to hook in Chart.js library into our Angular project. There are couple ways to do so, but I will use a dedicated package, called &lt;a href="https://valor-software.com/ng2-charts/"&gt;&lt;strong&gt;Ng2-Charts&lt;/strong&gt;&lt;/a&gt;. This package exposes a much nicer API while retaining all the required functionality. In my case, I add the following dependencies to my &lt;code&gt;package.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"chart.js": "^2.9.3",
"ng2-charts": "^2.3.0",
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After modifying the &lt;code&gt;package.json&lt;/code&gt; file, don't forget to run either &lt;code&gt;npm install&lt;/code&gt; or &lt;code&gt;yarn&lt;/code&gt; depending on your package manager.&lt;/p&gt;

&lt;h1&gt;
  
  
  Adding HTML template
&lt;/h1&gt;

&lt;p&gt;Going further, we have to add an HTML template that will render the chart. In the case of this tutorial, you can place it anywhere you fancy — the code is single HTML tag with custom properties which we will explore in next step. I place it in a component HTML template called &lt;code&gt;count-events.component.html&lt;/code&gt;. The HTML template should include the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;canvas
    width="600"
    height="400"
    [datasets]="countEventsData"
    [chartType]="countEventsChartType"
    [labels]="countEventsLabels"
    [colors]="countEventsColors"
    [options]="countEventsOptions"
&amp;gt;&amp;lt;/canvas&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I have placed my chart is count-events folder, therefore all variables are prepended with those. In the &lt;code&gt;canvas&lt;/code&gt; tag we specify height, width and variable configuration, which will be placed in corresponding &lt;code&gt;.ts&lt;/code&gt; file.&lt;/p&gt;

&lt;h1&gt;
  
  
  Configuring Chart.js
&lt;/h1&gt;

&lt;p&gt;As mentioned in chapter above, we will add some custom configuration to the Chart.js plots. This configuration will be placed in your components’ TypeScript file, in my case it is called &lt;code&gt;count-events.component.ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The first thing that has to be set is the &lt;code&gt;datasets&lt;/code&gt; property. That is a container that will hold the data displayed on the plot itself. The code for this should look like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;countEventsData: ChartDataSets[] = [
  { data: [], label: "Number of Events", fill: false }
];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This variable is an array, meaning you can have many data sets displayed on a single plot. Inside of each element there are three core parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;data&lt;/code&gt; - an array that holds the single values to be displayed on the chart&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;label&lt;/code&gt; - label of the data set&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;fill&lt;/code&gt; - configuration option setting the appearance of the data set on chart&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next configuration is the &lt;code&gt;chartType&lt;/code&gt; property. That is a single string, flagging the type of chart that should be used. There is a wide variety of options available, including line, bar, graph or pie, but for this tutorial we are going to stick with the simplest one - line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;countEventsChartType = "line";
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Going further, &lt;code&gt;labels&lt;/code&gt; property has to be set. This element sets what labels the &lt;strong&gt;X&lt;/strong&gt; axis receives. In our case however, we don't want to set them as a constant. We want to be able to update the labels in real-time, in cnjuction with the incoming data. This property therefore is set as empty array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;countEventsLabels: Label[] = [];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next property is &lt;code&gt;colors&lt;/code&gt;. The name itself is probably self explanatory, so I will jump straight to code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;countEventsColors: Color[] = [
    {
      borderColor: "#039BE5",
      pointBackgroundColor: "#039BE5"
    }
];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Last bit of configuration is called &lt;code&gt;options&lt;/code&gt;. That is the central configuration point, for all major flags that can be set. The amount of available options is very broad, so please refer to &lt;a href="https://www.chartjs.org/docs/latest/general/options.html"&gt;Chart.js docs&lt;/a&gt; for complete documentation. In our case, we are only interested in removing the animations - that will optimize the chart and make it run faster. To do this, paste the following into your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;countEventsOptions: ChartOptions = {
    animation: {
      duration: 0
    }
 };
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Connecting Service and Chart.js
&lt;/h1&gt;

&lt;p&gt;Last chapter of this tutorial will show you how to glue the service and the Chart.js together. To make this happen, we will implement couple functions in the &lt;code&gt;count-events.component.ts&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;We start off with subscribing to the data source, which is an &lt;code&gt;SseService&lt;/code&gt; in our case. That is done in the &lt;code&gt;ngOnInit&lt;/code&gt; hook, so that we connect to data source whenever our component is loaded in the application. In here, we create a &lt;code&gt;Subscription&lt;/code&gt; to the endpoint and call &lt;code&gt;pushEventToChartData&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private countEventsSubscription$: Subscription;
ngOnInit() {
    this.countEventsSubscription$ = this.sseService
      .getServerSentEvent("http://localhost:8082/count-events")
      .subscribe(event =&amp;gt; {
        let data = JSON.parse(event.data);
        this.pushEventToChartData(data);
      });
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The aforementioned function have a simple purpose — it checks whether the &lt;code&gt;datasets&lt;/code&gt; have reached an arbitrary limit (20 in this case) and if so, removes the last element before pushing the new one into this collection. On thing has the kept in mind - if adding or removing elements, it has to be done for both &lt;code&gt;datasets&lt;/code&gt; collections and labels &lt;code&gt;collections&lt;/code&gt;. Both of them have to by kept synced all the time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private pushEventToChartData(event: CountEvents): void {
    if (this.isChartDataFull(this.countEventsData, 20)) {
      this.removeLastElementFromChartDataAndLabel();
    }
    this.countEventsData[0].data.push(event.count);
    this.countEventsLabels.push(
      this.getLabel(event)
    );
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The last pieces of code include the helper functions calls to which can be found in snippet above. First functions could be used to implement some prettier looking labels. Second one removes the last element from both &lt;code&gt;datasets&lt;/code&gt; and &lt;code&gt;labels&lt;/code&gt; collections. The third checks whether the a collections has reached its limit, which I have set to be 20 in my case. The snippets for those are as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private getLabel(event: CountEvents): string {
    return `${event.window}`;
  }

  private removeLastElementFromChartDataAndLabel(): void {
    this.countEventsData[0].data = this.countEventsData[0].data.slice(1);
    this.countEventsLabels = this.countEventsLabels.slice(1);
  }

  private isChartDataFull(chartData: ChartDataSets[], limit: number): boolean {
    return chartData[0].data.length &amp;gt;= limit;
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Wrapping this all up, the complete code for &lt;code&gt;count-events.component.ts&lt;/code&gt; file looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class CountEventsComponent implements OnInit, OnDestroy {
  private countEventsSubscription$: Subscription;
  private eventsOnChartLimit = 20;
  countEventsChartType = "line";
  countEventsData: ChartDataSets[] = [
    { data: [], label: "Number of Events", fill: false }
  ];
  countEventsLabels: Label[] = [];
  countEventsColors: Color[] = [
    {
      borderColor: "#039BE5",
      pointBackgroundColor: "#039BE5"
    }
  ];
  countEventsOptions: ChartOptions = {
    animation: {
      duration: 0
    }
  };

  constructor(private sseService: SseService) {}

  ngOnInit() {
    this.countEventsSubscription$ = this.sseService
      .getServerSentEvent("http://localhost:8082/count-events")
      .subscribe(event =&amp;gt; {
        let data = JSON.parse(event.data);
        this.pushEventToChartData(data);
      });
  }

  private pushEventToChartData(event: CountEvents): void {
    if (this.isChartDataFull(this.countEventsData, 20)) {
      this.removeLastElementFromChartDataAndLabel();
    }
    this.countEventsData[0].data.push(event.count);
    this.countEventsLabels.push(
      this.getLabel(event)
    );
  }

  private getLabel(event: CountEvents): string {
    return `${event.window}`;
  }

  private removeLastElementFromChartDataAndLabel(): void {
    this.countEventsData[0].data = this.countEventsData[0].data.slice(1);
    this.countEventsLabels = this.countEventsLabels.slice(1);
  }

  private isChartDataFull(chartData: ChartDataSets[], limit: number): boolean {
    return chartData[0].data.length &amp;gt;= limit;
  }

  ngOnDestroy() {
    this.countEventsSubscription$.unsubscribe();
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And that this tutorial finished. Using Angular and Chart.js is not a rocket science and the benefits of having a real-time charts can be huge.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally you can follow me on my social media if you fancy so :)&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--V2J_1RRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1120823982368985091/nCtZbGBM_normal.png" alt="Bartosz Gajda profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Bartosz Gajda
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/bartoszgajda55"&gt;@bartoszgajda55&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Using &lt;a href="https://twitter.com/angular"&gt;@angular&lt;/a&gt; and &lt;a href="https://twitter.com/chartjs"&gt;@chartjs&lt;/a&gt; to build a real-time, interactive data charts. Plotting continuous data using &lt;a href="https://twitter.com/ReactiveX"&gt;@ReactiveX&lt;/a&gt; and asynchronous &lt;a href="https://twitter.com/hashtag/apis"&gt;#apis&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/BwkPHPAXdQ"&gt;bartoszgajda.com/2020/03/17/usi…&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="https://twitter.com/hashtag/angular"&gt;#angular&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/chartjs"&gt;#chartjs&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/frontend"&gt;#frontend&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/web"&gt;#web&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/web"&gt;#web&lt;/a&gt;development &lt;a href="https://twitter.com/hashtag/javascript"&gt;#javascript&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/typescript"&gt;#typescript&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/realtime"&gt;#realtime&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      12:23 PM - 24 Jun 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1275766441925640192" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1275766441925640192" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      3
      &lt;a href="https://twitter.com/intent/like?tweet_id=1275766441925640192" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      1
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


</description>
      <category>angular</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
