This is a quick demonstration of RMOTR Jupyterlab Solutions, an open source extension that implements visibility toggle for cells in Jupyter Lab. It's similar to previous Jupyter Notebook attempts like Exercise and Exercise2.

**Important:** The following demonstration assumes you're inside a JupyterLab, fork this project with the button at the right to see it in action š

#### Overview of functionalityĀ¶

The best way to demonstrate how this extension work, is with a real example of one of the coding activities we propose to our students, so let's get started:

### Palindromic PrimesĀ¶

A palindromic number is a number that reads the same forwards and backwards. Example: "121" (You read: "one, two, one", forwards and backwards). "1001" ("one, zero, zero, one"), etc.

The objective of this exercise is to write a function `next_palindromic_prime`

that receives a number and returns the closest larger number that's both a **prime** and **palindromic**.

You could take a stab at `next_palindromic_prime`

right now, but this is a good example of "divide and conquer". We'll divide our bigger problem into smaller ones and resolve them separately. We'll divide it into 2 major parts:

- Is palindromic? Figuring out if a number is palindromic
- Is prime? Figuring out if a number is prime.

With these two parts working, `next_palindromic_prime`

would be greatly simplified. Here's some pseudocode:

```
def next_palindromic_prime(n):
repeat to infinite:
n += 1
if is_palindromic(n) and is_prime(n):
return n
```

#### Is PalindromicĀ¶

We'll start with a function `is_palindromic`

, that given a number, returns True or False depending if the number is palindromic or not.

Let's start with a couple of examples:

```
n1 = 1001 # is palindromic
n2 = 1234 # is NOT palindromic
```

```
print(f"Our Numbers: {n1}, {n2}")
```

As we said, a Palindromic number is one that looks the same "forwards and backwards", that means that for example, for `n2`

we'd have:

```
Forward: 1234
Backwwards: 4321
```

So, if we can just compare the original number to its "reversed" version, we can answer if `n`

is palindromic or not. So, with all this said: *how can you reverse a string?*. Try it out below:

```
#Ā reverse n1. If you're not sure about it click on "Reveal Solution"
```

```
str(n1)[::-1]
```

```
#Ā reverse n2. If you're not sure about it click on "Reveal Solution"
```

```
str(n2)[::-1]
```

Here's the explanation of it:

First of all, the data type of our `n1`

and `n2`

variables is `int`

, which "can't" be reversed. When we talk about "reversing `1234`

" we're actually talking about reversing *the digits, or characters* of `1234`

, so we must first turn `1234`

into a string:

```
str(n1) # "1234", please note the quotes
```

Once the number is transformed into a string, we can now "reverse" it with a quick Python slicing hack involving the `-1`

step:

```
str(n1)[::-1] # "4321"
```

So now we can write our `is_palindromic`

function using this hack, give it a try and check the solution if it doesn't work. I've included a couple of tests for you to verify if it works:

```
def is_palindromic(a_number):
#Ā your code here
pass
```

```
assert is_palindromic(1001) is True
assert is_palindromic(1234) is False
assert is_palindromic(121) is True
assert is_palindromic(1) is True
```

```
def is_palindromic(a_number):
return str(a_number) == str(a_number)[::-1]
```

#### Is PrimeĀ¶

You're probably bored already of solving `is_prime`

functions, so we won't get into much detail; I've added a couple of tests for you to try your code and the solution is also available:

```
def is_prime(a_number):
#Ā your code here
pass
```

```
# Primes
assert is_prime(3) is True
assert is_prime(17) is True
assert is_prime(97) is True
assert is_prime(7919) is True
# Not Primes
assert is_prime(4) is False
assert is_prime(8) is False
assert is_prime(15) is False
assert is_prime(7833) is False
```

```
def is_prime(a_number):
if a_number <= 1:
return False
if a_number in {2, 3}:
return True
for divisor in range(2, a_number - 1):
if a_number % divisor == 0:
return False
return True
```

#### Finally, next palindromic primeĀ¶

We're now ready to resolve the `next_palindromic_prime`

, give it a shot!

```
def next_palindromic_prime(n):
# your code here
pass
```

```
assert next_palindromic_prime(100) == 101
assert next_palindromic_prime(150) == 151
assert next_palindromic_prime(160) == 181
assert next_palindromic_prime(200) == 313
assert next_palindromic_prime(10000) == 10301
assert next_palindromic_prime(12000) == 12421
```

Check the solution if you want to see how we solved it:

```
import itertools
def next_palindromic_prime(n):
for next_num in itertools.count(n + 1):
if is_palindromic(next_num) and is_prime(next_num):
return next_num
```

And here's a quick explanation about it:

This is one of those times when you have to repeat "to the infinite". You have to keep repeating and looking for a number that is both palindromic and prime. To do that, we could have used a `while`

loop, something like:

```
while True:
n += 1
if is_palindromic(n) and is_prime(next):
return n
```

This is of course less "pythonic" (and even dangerous, if we forget `n += 1`

). So we use `itertools.count`

: this method just keeps incrementing infinitely, which is exactly what we need.

The rest is just what we've discussed so far; once you find a number that satisfices both conditions (prime and palindromic) you have found your answer.

### Final Notes about Jupyterlab SolutionsĀ¶

Hopefully, this example has demonstrated the capabilities of the Jupyterlab Solutions extension. If you want to install it in your own computer, just follow the steps on the [docs].

Do you need help or have found a problem? Create a new issue.