<?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>DEV Community: Cecilia Baggini</title>
    <description>The latest articles on DEV Community by Cecilia Baggini (@cbaggini).</description>
    <link>https://dev.to/cbaggini</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%2F614927%2Ff2006263-efbc-4fd4-a0b9-cea05a396285.png</url>
      <title>DEV Community: Cecilia Baggini</title>
      <link>https://dev.to/cbaggini</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cbaggini"/>
    <language>en</language>
    <item>
      <title>SonarCloud vs LeftShift for automated code quality and security checks</title>
      <dc:creator>Cecilia Baggini</dc:creator>
      <pubDate>Fri, 07 May 2021 16:49:09 +0000</pubDate>
      <link>https://dev.to/cbaggini/sonarcloud-vs-leftshift-for-automated-code-quality-and-security-checks-m30</link>
      <guid>https://dev.to/cbaggini/sonarcloud-vs-leftshift-for-automated-code-quality-and-security-checks-m30</guid>
      <description>&lt;p&gt;Lately, I have been looking for automated tools to improve the quality and security of my apps. I have looked at two online apps for this, SonarCloud and LeftShift.&lt;br&gt;
They are both intuitive and easy to setup; they can also be connected to GitHub and GitLab to examine repositories automatically every time a new commit is pushed.&lt;br&gt;
ShiftLeft requires access to all repositories, while SonarCloud gives the option of only allowing access to some repositories.&lt;br&gt;
ShiftLeft identifies security issues in the code and scored them according to severity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dkavV7CY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qns9c0skmbhhndcjbse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dkavV7CY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qns9c0skmbhhndcjbse.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SonarCloud provide a more extensive report, including three sections: reliability (are there any bugs?), maintainability (is the code clear and well-structured?) and security (are there any vulnerabilities?).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SQNqUAuU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x72ypwxvovulw6ejum1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SQNqUAuU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x72ypwxvovulw6ejum1r.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first sight, SonarCode is more comprehensive, as it looks at the general code structure and how maintainable it is as well as security issues. However, when I analysed the same app with both tools, they suggested different security issues that should be fix. In conclusion, I will probably use them both as they provide complementary information.&lt;/p&gt;

</description>
      <category>security</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to create interactive HTML reports using R</title>
      <dc:creator>Cecilia Baggini</dc:creator>
      <pubDate>Sat, 01 May 2021 09:52:21 +0000</pubDate>
      <link>https://dev.to/cbaggini/how-to-create-interactive-html-reports-using-r-17m</link>
      <guid>https://dev.to/cbaggini/how-to-create-interactive-html-reports-using-r-17m</guid>
      <description>&lt;p&gt;In this post, I will explain how to create interactive HTML reports including widgets such as maps and interactive graphs using R. I assume that the reader is familiar with basic R. I will use two public APIs from the Environment Agency to download data, the &lt;a href="https://environment.data.gov.uk/water-quality/view/doc/reference" rel="noopener noreferrer"&gt;Water Quality Archive&lt;/a&gt; for water quality data (phosphate in this example) and the &lt;a href="http://environment.data.gov.uk/flood-monitoring/doc/rainfall" rel="noopener noreferrer"&gt;Rainfall API&lt;/a&gt; to look for rainfall monitoring locations.&lt;br&gt;
First, let’s load the packages we need and get the current date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;library(readr)
library(sf)
library(dplyr)
library(leaflet)
library(rgdal)
library(tidyr)
library(ggplot2)
library(plotly)
library(DT)
library(htmltools)

###Get Current Date and Time
now &amp;lt;- format(as.Date(Sys.Date()), '%d/%m/%Y')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we can retrieve phosphate information for two sites (Powick and Leintwardine on the River Teme, West Midlands). The information to retrieve determinand and site codes are in the documentation linked above. Once we have retrieved the data, we can rename the columns to something a bit more sensible than the original output and create a new concentration column that converts concentrations below the limit of detection to half of the limit of detection. We also add latitude and longitude columns converting from UK-specific coordinates (eastings and northings).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Set URL parameters
base_url = "https://environment.data.gov.uk/water-quality/data/measurement.csv?_limit=10000"
sampling_points = "&amp;amp;samplingPoint=MD-13598380&amp;amp;samplingPoint=MD-13624310"
start_date = "&amp;amp;startDate=2019-01-01"
detcode = "&amp;amp;determinand=0118"

# retrieve data from API and rename columns
all_records &amp;lt;- read_csv(paste0(base_url, sampling_points, detcode, start_date))
colnames(all_records) &amp;lt;- c("id", "smpt_url", "smpt_code", "smpt_name", "sample_datetime",           "determinand",                           "determinand_def", "detcode", "less_than", "concentration", "result_interpretation",
                           "unit", "smpt_type", "is_compliance", "sample_purpose", "easting", "northing")

# Add concentration and latitude/longitude columns
all_records$less_than_bool &amp;lt;- ifelse(is.na(all_records$less_than), FALSE, TRUE)
all_records$concentration_adj &amp;lt;- as.numeric(ifelse(all_records$less_than_bool == "TRUE", all_records$concentration/2, all_records$concentration))

latlon &amp;lt;- all_records %&amp;gt;%
  st_as_sf(coords = c("easting", "northing"), crs = 27700) %&amp;gt;%
  st_transform(4326) %&amp;gt;%
  st_coordinates() %&amp;gt;%
  as_tibble()
all_records$lat &amp;lt;- latlon$Y
all_records$lon &amp;lt;- latlon$X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then create an HTML table with site names, codes and coordinates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sites &amp;lt;- all_records %&amp;gt;% select(smpt_code, smpt_name, easting, 
                       northing, lat, lon) %&amp;gt;% 
  distinct(.keep_all = TRUE)

# Sites table
table_df &amp;lt;- sites %&amp;gt;% select(smpt_code, smpt_name, easting, northing) %&amp;gt;% 
  rename("Site code" = smpt_code,
         "Site name"= smpt_name,
         "Easting" = easting,
         "Northing" = northing)
sites_table &amp;lt;- datatable(table_df, width="100%", height="100%",
                         caption = htmltools::tags$caption( style = 'caption-side: top; 
                                                     text-align: center; color:black; 
                                                     font-size:200% ;','Monitoring sites') )

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we search for the closest rainfall monitoring site to each of the water quality sites and put this information in another table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rainfall_data = data.frame()
for (i in 1:nrow(sites)) {
  lat &amp;lt;- sites$lat[i]
  lon &amp;lt;- sites$lon[i]
  rainfall_st &amp;lt;- read_csv(paste0("https://environment.data.gov.uk/flood-monitoring/id/stations.csv?parameter=rainfall&amp;amp;lat=",lat,"&amp;amp;long=",lon,"&amp;amp;dist=10"))
  if (nrow(rainfall_st) &amp;gt; 0) {
    rainfall_data &amp;lt;- rbind(rainfall_data, rainfall_st[1,])
  }
}
rainfall_data &amp;lt;- as.data.frame(rainfall_data)

# rainfall table
rainfall_table_df &amp;lt;- rainfall_data %&amp;gt;% select(notation, qualifier, easting, northing) %&amp;gt;% 
  rename("Site code" = notation,
         "Site type"= qualifier,
         "Easting" = easting,
         "Northing" = northing)
rainfall_table &amp;lt;- datatable(rainfall_table_df, width="100%", height="100%",
                            caption = htmltools::tags$caption( style = 'caption-side: top; 
                                                     text-align: center; color:black; 
                                                     font-size:200% ;','Rainfall gauges') )

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, we can create a map showing water quality and corresponding rainfall monitoring point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pal &amp;lt;- colorFactor("Dark2", domain = all_records$smpt_code)
fillColor = ~pal(smpt_code)
# map
m &amp;lt;- leaflet() %&amp;gt;% 
  fitBounds(min(all_records$lon), min(all_records$lat), 
            max(all_records$lon), max(all_records$lat),
            options = list(padding = c(25,25))) %&amp;gt;%
  addTiles() %&amp;gt;%
  ## add sites
  addCircleMarkers(data = sites, ~lon, ~lat, 
                   color = "black",
                   weight = 0.5,
                   radius = 6,
                   layerId = ~smpt_code, 
                   fillOpacity = 0.7,
                   opacity = 1,
                   fillColor = fillColor,
                   popup = ~paste("&amp;lt;strong&amp;gt;Site Id :&amp;lt;/strong&amp;gt;", smpt_code, "&amp;lt;br&amp;gt;",
                                  "&amp;lt;strong&amp;gt;Site Name :&amp;lt;/strong&amp;gt;", smpt_name, "&amp;lt;br&amp;gt;")
  ) %&amp;gt;%
  ## add rainfall sites
  addCircleMarkers(data = rainfall_data, ~long, ~lat, 
                   color = "black",
                   weight = 0.5,
                   radius = 6,
                   layerId = ~notation, 
                   fillOpacity = 0.7,
                   opacity = 1,
                   fillColor = "blue",
                   popup = ~paste("&amp;lt;strong&amp;gt;Site Id :&amp;lt;/strong&amp;gt;", notation, "&amp;lt;br&amp;gt;",
                                  "&amp;lt;strong&amp;gt;Site type :&amp;lt;/strong&amp;gt;", qualifier, "&amp;lt;br&amp;gt;")
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we create an interactive Plotly graph that shows how phosphate changes in time at the two sites we selected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# time series graph
ts &amp;lt;- ggplot(all_records, aes(sample_datetime, concentration_adj, colour = smpt_name)) +
  geom_line() +
  geom_point() +
  theme_bw() +
  labs(title = "Phosphate concentration by site",
       colour = "Site name") +
  xlab("Sample date") +
  ylab("Concentration (mg/l)") 
ts1 &amp;lt;- ggplotly(ts)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we assemble the two tables, the map and the graph and a title in a tagList and then save it to an HTML file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# assemble final document
doc &amp;lt;- htmltools::tagList(
  h1(paste("Phosphate data summary - data extracted on ", now), style="text-align:center;"),
  div(m),
  div(div(sites_table, style="width:50%;"),
      div(rainfall_table, style="width:50%;margin-left:2em;"), style="margin:2em;display:flex;"),
  div(ts1)
)

htmltools::save_html(html = doc, file = "Phosphate_report.html")

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is the final product!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faolxviwlc84vw7r4rl5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faolxviwlc84vw7r4rl5y.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>r</category>
    </item>
    <item>
      <title>Best practice for building a RESTful API</title>
      <dc:creator>Cecilia Baggini</dc:creator>
      <pubDate>Fri, 23 Apr 2021 09:02:28 +0000</pubDate>
      <link>https://dev.to/cbaggini/best-practice-for-building-a-restful-api-9lb</link>
      <guid>https://dev.to/cbaggini/best-practice-for-building-a-restful-api-9lb</guid>
      <description>&lt;p&gt;Lately, I have been learning how to use Node.js and Express to build APIs. There are no fixed standards to build APIs, but reading online I identified some common themes on how to build a functional and usable API. Some common themes were:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t return plain text&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even if the response body is formatted like a JSON, if the response header is not set as application/json some clients may have issues parsing it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use plural rather than singular&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, use /articles/ rather than /article/&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid using verbs in URIs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the HTTP verbs (e.g. GET, POST, PUT, PATCH, DELETE) to let the user understand what sort of action the endpoint will perform. &lt;br&gt;
For example, use POST: /users/ rather than POST: /users/newUser/&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Always return a meaningful status code with error message in the response body&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the request is not successful, the API should return an error status rather than an ok status like 200. It is also helpful for the user if there is an error message in the response body.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use trailing slashes consistently&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All the endpoints of an API should be consistent in using trailing slashes (e.g. /users/) or not (e.g. /users). Ideally, the client should be automatically redirected to the correct endpoint if they use the other version of the URI. Most frameworks will have such an option, so it is worth looking for it and using it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use a framework&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As an API gets more complex, it is worth investing some time in learning an API framework, such as Django REST Framework for Python or Restify for Node.js. Using an API-specific framework will make it much easier to keep the API consistent and usable.&lt;/p&gt;

</description>
      <category>node</category>
      <category>programming</category>
    </item>
    <item>
      <title>Using indexes to speed up queries in PostgreSQL</title>
      <dc:creator>Cecilia Baggini</dc:creator>
      <pubDate>Thu, 15 Apr 2021 14:19:24 +0000</pubDate>
      <link>https://dev.to/cbaggini/using-indexes-to-speed-up-queries-in-postgresql-222f</link>
      <guid>https://dev.to/cbaggini/using-indexes-to-speed-up-queries-in-postgresql-222f</guid>
      <description>&lt;p&gt;In this post, I am going to explain how you can use indexes to speed up SELECT queries on a PostgreSQL database. Most of what this post covers will apply to any type of SQL database, but the syntax may be specific to PostgreSQL.&lt;/p&gt;

&lt;p&gt;I spent the last month at work designing a new database to store chemical substances concentrations in rivers to provide data to the web application I manage. Finally I figured everything out: how many tables to create, how to connect them, which primary and foreign keys to use… and then I queried it from my web application and it took ages to return any result!&lt;/p&gt;

&lt;p&gt;Had I spent a month working on something that would make my application unusable? Admittedly, the table that was giving me issues has almost 30 million rows, but everything I read online suggested that shouldn’t be a problem. So how to speed up my queries and make my application responsive?&lt;/p&gt;

&lt;p&gt;I had already read about indexes, but I was convinced that since I already had a primary key covering multiple columns (including the one I was using to filter my slow query), it would not make a massive difference. How wrong I was! Adding an index for substance names to my table reduced query times from 23 to 0.4 seconds!&lt;/p&gt;

&lt;p&gt;So when is adding an index to a table appropriate? Indexes will massively speed up SELECT queries that filter a fraction of the rows from a table. So if you’re going to use regularly queries that filter a large table based on one column, it makes sense to create an index for that column.&lt;br&gt;
Creating an index for a table in PostgreSQL is very easy: just write &lt;/p&gt;

&lt;p&gt;&lt;code&gt;CREATE INDEX index_name ON table_name (column_name1, column_name2);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you’re repeatedly querying a table for a small slice of rows, a partial index is probably a better choice. Partial indexes only cover a subset of a table’s data, are smaller in size, easier to maintain and faster to scan. In some cases, creating a full column index when you only want to get a small portion of the table can actually slow down your queries. The code to create a partial index in PostgreSQL is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CREATE INDEX index_name ON table_name (column_name1) WHERE condition;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That’s it for now, hope it was useful!&lt;/p&gt;

</description>
      <category>sql</category>
      <category>postgres</category>
    </item>
  </channel>
</rss>
