You can use regular expressions in PHP with the function preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] ) . Only the first two paremeters are mandatory and they are the regex and the string where you want to search respectively.

In case of finding a result, preg_match() returns an array where the item at index 0 is the whole match. From 1 onwards they are placed the different groups of your regular expressions (in case there is any). If no match is found, preg_match() returns null.

One of the details that must be taken into account when using regular expressions on PHP is that they must be enclosed by forward slashes (/), e.g. $multiline_meaning_re = ‘/^([A-za-z ,»().\’;:]+)/’; . This regular expression matches any string with any set of letters, spaces, commas, double and single quotes, parenthesis points, colon and/or semicolon.

As a complete example, the following snippet opens a file, parses it to look for English idioms and uploads all of them a MySQL database.

<?php
$servername = "";
$database = "";
$username = "";
$password = "";
$conn = mysqli_connect($servername, $username, $password, $database);

// Check connection
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}

    class Idiom {
        var $idiom = "";
        var $meaning = "";
        var $example = [];
        function print(){
            echo($this->idiom . "<br>" . $this->meaning . "<ul>");
            print_r($this->example);
            if(count($this->example) == 0 )
              echo("ERROR!!!!. There should be at least one example");
            foreach ($this->example as $value) {
                echo("<li>" . $value . "</li>");
            }
            echo("</ul>");
        }
        function upload($conn){
          echo("Uploading...");
          $example = "<ul class='list-group'>";
          foreach ($this->example as $value) {
            if($value !== '')
              $example = $example . "<li class='list-group-item'>" . $value . '</li>';
          }
          $example = $example . "</ul>";

          $idiom = mysqli_real_escape_string($conn, $this->idiom);
          $meaning = mysqli_real_escape_string($conn, $this->meaning);
          $example = mysqli_real_escape_string($conn, $example);

          $query = 'INSERT INTO idioms (`idiom`, `meaning`, `example`) VALUES ("'. $idiom . '","'. $meaning . '","'. $example . '")';
          mysqli_query($conn, $query);
        }
    }

    $file = fopen("idioms.txt", "r") or die("Unable to open file!");
    $idiom_meaning_re     = '/^([A-za-z,. -\/()\']+):([A-za-z ,"().\';:\n]+)/';
    $multiline_meaning_re = '/^([A-za-z ,"().\';:]+)/';
    $example_re           = '/^\|--([A-Za-z0-9 \',?.-;$\n"]+[^:])/';
    $new_idiom = 0;
    $new_example = 0;
    $idiom = null;
    $example = "";
    // Output one line until end-of-file
    while(!feof($file)) {
      $line = fgets($file);
      //echo($line . "<br>");
      preg_match($idiom_meaning_re, $line, $matches);

      if($matches != null){
        if($new_example === 1){
          array_push($idiom->example, $example);
          $new_example = 0;
        }
        if($idiom != null){
          $idiom->print();
          $idiom->upload($conn);
        }
        $idiom = new Idiom;
        $idiom->example = [];
        $example = "";
        $new_idiom = 1;
        $idiom->idiom = trim($matches[1]);
        $idiom->meaning = trim($matches[2]);
      }else{
        preg_match($example_re, $line, $matches);
        if($matches != null){
           if($example !== "")
              array_push($idiom->example, $example);
           $new_idiom = 0;
           $new_example = 1;
           $example = trim($matches[1]);
        }else{
          preg_match($multiline_meaning_re, $line, $matches);
          //var_dump($matches);
          if($matches != null && $new_idiom){
            $idiom->meaning = $idiom->meaning . ' ' . trim($matches[1]);
            //echo($idiom->meaning);
          } elseif ($matches != null && $new_example) {
            $example = $example . ' ' . trim($matches[1]);
          } else {
            $new_idiom   = 0;
            $new_example = 0;
          }
        }
      }
    }
    echo("Closing file");
    fclose($file);

    mysqli_close($conn);

?>

You can find further information about the preg_match() in the PHP official documentation.

One of the first questions you may ask yourself when getting introduced in D3 is: why are we using selectAll(‘html-tag-name’) method if there is no item to select of that type?

First, let’s see an example of the situation we are talking about:

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    
    // Add your code below this line
    d3.select('body')
      .selectAll('h2')
      .data(dataset)
      .enter()
      .append('h2')
      .text('New Title')
    // Add your code above this line
  </script>
</body>

In the previous example, the only existing HTML tag is <body> . We select body (d3.select(‘body’) ) and then we perform the .selectAll(‘h2’) . On its own, it makes no sense as the method won’t return any value since no <h2>  tag exists. Nevertheless, it will make sense if we keep looking at the following code.

After the select .selectAll(‘h2’)  we attach the existing dataset to the selected items (.data(dataset) ). Then, we use the enter()  method, which gives meaning to the previous .selectAll(‘h2’) . When using enter() , D3 looks for the number of selected items to bind them with the data. In case of having not enough items in the selection, the enter()  method will create them.

Therefore, as .selectAll(‘h2’)  was empty and the dataset  variable contains 9 elements, it will iterate the code 9 times. In case of having already created some  <h2>  elements, it will simply fulfill the HTML code the necessary iteration to cover all the dataset  elements. Remember that who does this iteration is  the data() method.  It parses the data set, and any method that’s chained after data() is run once for each item in the data set.

You can find more information in the official documentation at the D3js.org website.

Scales

In D3 there exists the Scale function to change the value of the data set so that it can fit in the screen. Two important methods are range() and domain(). The domain method covers the set of input values whereas the range function convers the set of output values. Let’s see an example:

const scale = d3.scaleLinear();
scale.domain([50, 480]);
scale.range([10, 500]);

scale(50) // Returns 10
scale(480) // Returns 500
scale(325) // Returns 323.37
scale(750) // Returns 807.67

From freeCodeCamp:

The domain()  method passes information to the scale about the raw data values for the plot. The range()  method gives it information about the actual space on the web page for the visualization.

Platform used: Raspberry Pi 3 B+
Bluetooth module: built-in
First, update firmware to make sure you have latest version:

sudo rpi-update

Now, install all the needed pulse-audio packages:

 sudo apt install pulseaudio-*.

Configure the bluetooth in the Raspberry:

pi@raspberrypi:~ $ bluetoothctl
[NEW] Controller XX:XX:XX:XX:XX:XX raspberrypi [default]
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# agent NoInputNoOutput
Agent registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# discoverable on
Changing discoverable on succeeded
[CHG] Controller B8:27:EB:DB:58:46 Discoverable: yes
[bluetooth]# pairable on
Changing pairable on succeeded

In your mobile phone, search for the raspberry bluetooth signal and pair to it:

[Noname]# connect XX:XX:XX:XX:XX:XX
Attempting to connect to XX:XX:XX:XX:XX:XX
[CHG] Device XX:XX:XX:XX:XX:XX ServicesResolved: yes
Connection successful
[Noname]# trust XX:XX:XX:XX:XX:XX
Changing XX:XX:XX:XX:XX:XX trust succeeded
[CHG] Controller XX:XX:XX:XX:XX:XX Discoverable: no
[Noname]# exit

Now, you can try to play some audio in your mobile and it should be reproduced in the the Raspberry.
In my case, audio was driven out to the HDMI. In case you want to switch it through the Jack 3.5 mm output you can run:

sudo raspi-config

Then, select Advanced Options > Audio > Force 3.5 mm (‘headphone’) jack
With this all set, you can stream any audio such as the built-in music player, Spotify or YouTube to the Raspberry and from it to the connected speakers or HDMI display.

Finally, as the device has been stored as a trusted device, every time the Raspberry is booted, you won’t need to repeat this process. It will be so easy as connecting your mobile phone to the available raspberry bluetooth signal.

If sound sounds distorted, try restarting pulseaudio with:

pulseaudio -k

Handling with several devices

If you pair several devices, only first connected device will be able to stream audio. If I connect my computer to the raspberry and then I try to connect my mobile phone (both previously paired and trusted), phone connection will fail. First, I’ll need to disconenct my computer and only then I’ll be able to successfully connect to the raspberry with my mobile phone.