diff --git a/extra/07_some_python_insights.ipynb b/extra/07_some_python_insights.ipynb
new file mode 100644
index 00000000..96a93229
--- /dev/null
+++ b/extra/07_some_python_insights.ipynb
@@ -0,0 +1,408 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "0",
+ "metadata": {},
+ "source": [
+ "# Python Insights 🤓"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1",
+ "metadata": {
+ "jp-MarkdownHeadingCollapsed": true
+ },
+ "source": [
+ "## Why intervals are open-ended in Python?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2",
+ "metadata": {
+ "jp-MarkdownHeadingCollapsed": true
+ },
+ "source": [
+ "Half-open intervals `[start:end)` with 0-based indexing"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\n",
+ "lst"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4",
+ "metadata": {},
+ "source": [
+ "### 1. Length is just end - start"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "lst[1:4] # ['b', 'c', 'd'] — length is 4-1 = 3"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6",
+ "metadata": {},
+ "source": [
+ "### 2. Consecutive slices don't overlap"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "lst[0:3] # ['a', 'b', 'c']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "lst[3:6] # ['d', 'e', 'f']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "lst[6:9] # ['g', 'h', 'i']"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "10",
+ "metadata": {},
+ "source": [
+ "### 3. First n elements is clean"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "11",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "n = 5\n",
+ "lst[:n] # ['a', 'b', 'c', 'd', 'e'] — exactly n elements"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "12",
+ "metadata": {},
+ "source": [
+ "### 4. Empty slices make sense"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "13",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "lst[3:3] # [] — naturally empty"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "14",
+ "metadata": {
+ "jp-MarkdownHeadingCollapsed": true
+ },
+ "source": [
+ "## What happens inside a `for` and `while` loops?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "15",
+ "metadata": {},
+ "source": [
+ "**Remember:** in Python, `for item in container` allows you to assign the `item` variable to **every single element** that `container` holds.\n",
+ "One at a time.\n",
+ "\n",
+ "We call these container objects **iterables**."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "16",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "fruits = [\"apple\", \"banana\", \"cherry\"] # a list, a tuple, a string, a dictionary, a set... are all iterables\n",
+ "count = 0\n",
+ "\n",
+ "for fruit in fruits:\n",
+ " count += 1\n",
+ " print(f\"Item {count}: {fruit}\")\n",
+ "\n",
+ "print(f\"Total fruits: {count}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "17",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "for index, fruit = enumerate(fruits):\n",
+ " print(index, fruit)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "18",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "a, b, c = 1, 2, 3"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "19",
+ "metadata": {},
+ "source": [
+ "Let's try to \"visualize\" what happens with the [Python Tutor](https://pythontutor.com/render.html#code=fruits%20%3D%20%5B%22apple%22,%20%22banana%22,%20%22cherry%22%5D%0Acount%20%3D%200%0A%0Afor%20fruit%20in%20fruits%3A%0A%20%20%20%20count%20%2B%3D%201%0A%20%20%20%20print%28f%22Item%20%7Bcount%7D%3A%20%7Bfruit%7D%22%29%0A%0Aprint%28f%22Total%20fruits%3A%20%7Bcount%7D%22%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "20",
+ "metadata": {},
+ "source": [
+ "The same idea with a `while` loop"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "21",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "fruits = [\"apple\", \"banana\", \"cherry\"]\n",
+ "i = 0\n",
+ "\n",
+ "while i < len(fruits):\n",
+ " fruit = fruits[i]\n",
+ " print(f\"Item {i+1}: {fruit}\")\n",
+ " i += 1\n",
+ "\n",
+ "print(\"Done!\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "22",
+ "metadata": {},
+ "source": [
+ "With the [Python Tutor](https://pythontutor.com/render.html#code=fruits%20%3D%20%5B%22apple%22,%20%22banana%22,%20%22cherry%22%5D%0Ai%20%3D%200%0A%0Awhile%20i%20%3C%20len%28fruits%29%3A%0A%20%20%20%20fruit%20%3D%20fruits%5Bi%5D%0A%20%20%20%20print%28f%22Item%20%7Bi%2B1%7D%3A%20%7Bfruit%7D%22%29%0A%20%20%20%20i%20%2B%3D%201%0A%0Aprint%28%22Done!%22%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "23",
+ "metadata": {},
+ "source": [
+ "### One example"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "24",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "numbers = [1, 2, 3]\n",
+ "result = []\n",
+ "\n",
+ "for num in numbers:\n",
+ " result.append(num * 2)\n",
+ " print(f\"Num is: {num}\")\n",
+ "\n",
+ "print(f\"Numbers (list): {numbers}\") # What do you think are the values of numbers?\n",
+ "print(result)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "25",
+ "metadata": {},
+ "source": [
+ "## Some live coding together"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "26",
+ "metadata": {},
+ "source": [
+ "### Remove vowels"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "27",
+ "metadata": {},
+ "source": [
+ "From Leetle, 2 July 2025\n",
+ "\n",
+ "Write a function that takes a string and returns a new string with all vowels (a, e, i, o, u) removed.\n",
+ "Both uppercase and lowercase vowels should be removed.\n",
+ "\n",
+ "Examples:\n",
+ "- Input: `\"hello, world!\"`\n",
+ "- Output: `\"hll, wrld!\"`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "28",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def solve(message: str) -> str:\n",
+ " vowels = \"aeiouAEIOU\"\n",
+ " result = \"\"\n",
+ " for char in message:\n",
+ " if char not in vowels:\n",
+ " result += char\n",
+ " return result"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "29",
+ "metadata": {},
+ "source": [
+ "### Old phones keyboards"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "30",
+ "metadata": {},
+ "source": [
+ "From Leetle, 8 August 2025\n",
+ "\n",
+ "Write a function that decodes old phone keypad text input.\n",
+ "Each number represents letters: `2=ABC`, `3=DEF`, `4=GHI`, `5=JKL`, `6=MNO`, `7=PQRS`, `8=TUV`, `9=WXYZ`.\n",
+ "Multiple presses select the letter (`22=B`, `777=R`).\n",
+ "Space separates different letters on same key."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "31",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def solve(string: str) -> str:\n",
+ " keypad = {\n",
+ " \"2\": \"ABC\", \"3\": \"DEF\", \"4\": \"GHI\", \"5\": \"JKL\",\n",
+ " \"6\": \"MNO\", \"7\": \"PQRS\", \"8\": \"TUV\", \"9\": \"WXYZ\",\n",
+ " }\n",
+ " result = \"\"\n",
+ " for word in string.split():\n",
+ " press = len(word) - 1\n",
+ " number = keypad[word[0]]\n",
+ " result += keypad[number][press]\n",
+ " return result"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "32",
+ "metadata": {},
+ "source": [
+ "### Sum until a single digit"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "33",
+ "metadata": {},
+ "source": [
+ "From Leetle, 3 May 2025\n",
+ "\n",
+ "Write a function that repeatedly sums the digits of a number until a single digit is obtained.\n",
+ "\n",
+ "Examples:\n",
+ "\n",
+ "| Input | Output | Steps |\n",
+ "| --- | --- | --- |\n",
+ "| 16 | 7 | 6+1 = 7 |\n",
+ "| 546 | 6 | 5+4+6 = 15 then 1+5 = 6 |"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "34",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def solve(number: int) -> int:\n",
+ " ..."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.13.7"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}