Pi digit extraction algorithm
diff --git a/DIRECTORY.md b/DIRECTORY.md
index f4499d8e07bd..bef7bca86cc3 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -300,6 +300,7 @@
   * [Average Mean](https://github.com/TheAlgorithms/Python/blob/master/maths/average_mean.py)
   * [Average Median](https://github.com/TheAlgorithms/Python/blob/master/maths/average_median.py)
   * [Average Mode](https://github.com/TheAlgorithms/Python/blob/master/maths/average_mode.py)
+  * [Bailey Borwein Plouffe](https://github.com/TheAlgorithms/Python/blob/master/maths/bailey_borwein_plouffe.py)
   * [Basic Maths](https://github.com/TheAlgorithms/Python/blob/master/maths/basic_maths.py)
   * [Binary Exp Mod](https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exp_mod.py)
   * [Binary Exponentiation](https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exponentiation.py)
@@ -603,6 +604,7 @@
   * [Shell Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/shell_sort.py)
   * [Sleep Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/sleep_sort.py)
   * [Stooge Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/stooge_sort.py)
+  * [Strand Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/strand_sort.py)
   * [Tim Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/tim_sort.py)
   * [Topological Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/topological_sort.py)
   * [Tree Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/tree_sort.py)
diff --git a/maths/bailey_borwein_plouffe.py b/maths/bailey_borwein_plouffe.py
new file mode 100644
index 000000000000..7834668864af
--- /dev/null
+++ b/maths/bailey_borwein_plouffe.py
@@ -0,0 +1,87 @@
+def bailey_borwein_plouffe(digit_position: int, precision: int = 1000) -> str:
+    """
+    Implement a popular pi-digit-extraction algorithm known as the 
+    Bailey-Borwein-Plouffe (BBP) formula to calculate the nth hex digit of pi.
+    Wikipedia page:
+    https://en.wikipedia.org/wiki/Bailey%E2%80%93Borwein%E2%80%93Plouffe_formula
+    @param digit_position: a positive integer representing the position of the digit to extract. 
+    The digit immediately after the decimal point is located at position 1.
+    @param precision: number of terms in the second summation to calculate.
+    A higher number reduces the chance of an error but increases the runtime.
+    @return: a hexadecimal digit representing the digit at the nth position
+    in pi's decimal expansion.
+    
+    >>> "".join(bailey_borwein_plouffe(i) for i in range(1, 11))
+    '243f6a8885'
+    >>> bailey_borwein_plouffe(5, 10000)
+    '6'
+    >>> bailey_borwein_plouffe(-10)
+    Traceback (most recent call last):
+      ...
+    ValueError: Digit position must be a positive integer
+    >>> bailey_borwein_plouffe(0)
+    Traceback (most recent call last):
+      ...
+    ValueError: Digit position must be a positive integer
+    >>> bailey_borwein_plouffe(1.7)
+    Traceback (most recent call last):
+      ...
+    ValueError: Digit position must be a positive integer
+    >>> bailey_borwein_plouffe(2, -10)
+    Traceback (most recent call last):
+      ...
+    ValueError: Precision must be a nonnegative integer
+    >>> bailey_borwein_plouffe(2, 1.6)
+    Traceback (most recent call last):
+      ...
+    ValueError: Precision must be a nonnegative integer
+    """
+    if (not isinstance(digit_position, int)) or (digit_position <= 0):
+        raise ValueError("Digit position must be a positive integer")
+    elif (not isinstance(precision, int)) or (precision < 0):
+        raise ValueError("Please input a nonnegative integer for the precision")
+
+    # compute an approximation of (16 ** (n - 1)) * pi whose fractional part is mostly accurate
+    sum_result = (
+        4 * _subsum(digit_position, 1, precision)
+        - 2 * _subsum(digit_position, 4, precision)
+        - _subsum(digit_position, 5, precision)
+        - _subsum(digit_position, 6, precision)
+    )
+
+    # return the first hex digit of the fractional part of the result
+    return hex(int((sum_result % 1) * 16))[2:]
+
+
+def _subsum(
+    digit_pos_to_extract: int, denominator_addend: int, precision: int
+) -> float:
+    # only care about first digit of fractional part; don't need decimal
+    """
+    Private helper function to implement the summation
+    functionality. 
+    @param digit_pos_to_extract: digit position to extract
+    @param denominator_addend: added to denominator of fractions in the formula
+    @param precision: same as precision in main function
+    @return: floating-point number whose integer part is not important 
+    """
+    sum = 0.0
+    for sum_index in range(digit_pos_to_extract + precision):
+        denominator = 8 * sum_index + denominator_addend
+        exponential_term = 0.0
+        if sum_index < digit_pos_to_extract:
+            # if the exponential term is an integer and we mod it by the denominator before
+            # dividing, only the integer part of the sum will change; the fractional part will not
+            exponential_term = pow(
+                16, digit_pos_to_extract - 1 - sum_index, denominator
+            )
+        else:
+            exponential_term = pow(16, digit_pos_to_extract - 1 - sum_index)
+        sum += exponential_term / denominator
+    return sum
+
+
+if __name__ == "__main__":
+    import doctest
+
+    doctest.testmod()

### **Describe your change:**
I added an algorithm that extracts the nth hexadecimal digit of pi

* [X] Add an algorithm?
* [ ] Fix a bug or typo in an existing algorithm?
* [ ] Documentation change?

### **Checklist:**
* [X] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Python/blob/master/CONTRIBUTING.md).
* [X] This pull request is all my own work -- I have not plagiarized.
* [X] I know that pull requests will not be merged if they fail the automated tests.
* [X] This PR only changes one algorithm file.  To ease review, please open separate PRs for separate algorithms.
* [X] All new Python files are placed inside an existing directory.
* [X] All filenames are in all lowercase characters with no spaces or dashes.
* [X] All functions and variable names follow Python naming conventions.
* [X] All function parameters and return values are annotated with Python [type hints](https://docs.python.org/3/library/typing.html).
* [X] All functions have [doctests](https://docs.python.org/3/library/doctest.html) that pass the automated testing.
* [X] All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation.
* [X] If this pull request resolves one or more open issues then the commit message contains `Fixes: #{$ISSUE_NO}`.
