diff --git a/.vscode/settings.json b/.vscode/settings.json index 91ceb037c..b37fe572a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,7 +17,6 @@ "files.autoSave": "afterDelay", "screencastMode.onlyKeyboardShortcuts": true, "terminal.integrated.fontSize": 18, - "workbench.activityBar.visible": true, "workbench.colorTheme": "Visual Studio Dark", "workbench.fontAliasing": "antialiased", "workbench.statusBar.visible": true diff --git a/ch00-introduction/00_04_codespace.ipynb b/ch00-introduction/00_04_codespace.ipynb index cb0c19d79..d65fbe8a5 100644 --- a/ch00-introduction/00_04_codespace.ipynb +++ b/ch00-introduction/00_04_codespace.ipynb @@ -47,7 +47,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -61,7 +61,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.12.1" } }, "nbformat": 4, diff --git a/ch01-datastructures/01_01_loops.ipynb b/ch01-datastructures/01_01_loops.ipynb index 221f58679..44d37764f 100644 --- a/ch01-datastructures/01_01_loops.ipynb +++ b/ch01-datastructures/01_01_loops.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -28,9 +28,26 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n" + ] + } + ], "source": [ "for i in range(0, 10):\n", " print(i)" @@ -38,9 +55,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n" + ] + } + ], "source": [ "for i in range(5):\n", " print(i)" @@ -48,9 +77,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "2\n", + "4\n", + "6\n", + "8\n" + ] + } + ], "source": [ "for i in range(0, 10, 2):\n", " print(i)" @@ -58,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -73,7 +114,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -91,27 +132,353 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[[0, 0, 0, 0, 0, 100],\n", + " [0, 0, 0, 0, 1, 95],\n", + " [0, 0, 0, 0, 2, 90],\n", + " [0, 0, 0, 0, 3, 85],\n", + " [0, 0, 0, 0, 4, 80],\n", + " [0, 0, 0, 0, 5, 75],\n", + " [0, 0, 0, 0, 6, 70],\n", + " [0, 0, 0, 0, 7, 65],\n", + " [0, 0, 0, 0, 8, 60],\n", + " [0, 0, 0, 0, 9, 55],\n", + " [0, 0, 0, 0, 10, 50],\n", + " [0, 0, 0, 0, 11, 45],\n", + " [0, 0, 0, 0, 12, 40],\n", + " [0, 0, 0, 0, 13, 35],\n", + " [0, 0, 0, 0, 14, 30],\n", + " [0, 0, 0, 0, 15, 25],\n", + " [0, 0, 0, 0, 16, 20],\n", + " [0, 0, 0, 0, 17, 15],\n", + " [0, 0, 0, 0, 18, 10],\n", + " [0, 0, 0, 0, 19, 5],\n", + " [0, 0, 0, 0, 20, 0],\n", + " [0, 0, 0, 1, 0, 90],\n", + " [0, 0, 0, 1, 1, 85],\n", + " [0, 0, 0, 1, 2, 80],\n", + " [0, 0, 0, 1, 3, 75],\n", + " [0, 0, 0, 1, 4, 70],\n", + " [0, 0, 0, 1, 5, 65],\n", + " [0, 0, 0, 1, 6, 60],\n", + " [0, 0, 0, 1, 7, 55],\n", + " [0, 0, 0, 1, 8, 50],\n", + " [0, 0, 0, 1, 9, 45],\n", + " [0, 0, 0, 1, 10, 40],\n", + " [0, 0, 0, 1, 11, 35],\n", + " [0, 0, 0, 1, 12, 30],\n", + " [0, 0, 0, 1, 13, 25],\n", + " [0, 0, 0, 1, 14, 20],\n", + " [0, 0, 0, 1, 15, 15],\n", + " [0, 0, 0, 1, 16, 10],\n", + " [0, 0, 0, 1, 17, 5],\n", + " [0, 0, 0, 1, 18, 0],\n", + " [0, 0, 0, 2, 0, 80],\n", + " [0, 0, 0, 2, 1, 75],\n", + " [0, 0, 0, 2, 2, 70],\n", + " [0, 0, 0, 2, 3, 65],\n", + " [0, 0, 0, 2, 4, 60],\n", + " [0, 0, 0, 2, 5, 55],\n", + " [0, 0, 0, 2, 6, 50],\n", + " [0, 0, 0, 2, 7, 45],\n", + " [0, 0, 0, 2, 8, 40],\n", + " [0, 0, 0, 2, 9, 35],\n", + " [0, 0, 0, 2, 10, 30],\n", + " [0, 0, 0, 2, 11, 25],\n", + " [0, 0, 0, 2, 12, 20],\n", + " [0, 0, 0, 2, 13, 15],\n", + " [0, 0, 0, 2, 14, 10],\n", + " [0, 0, 0, 2, 15, 5],\n", + " [0, 0, 0, 2, 16, 0],\n", + " [0, 0, 0, 3, 0, 70],\n", + " [0, 0, 0, 3, 1, 65],\n", + " [0, 0, 0, 3, 2, 60],\n", + " [0, 0, 0, 3, 3, 55],\n", + " [0, 0, 0, 3, 4, 50],\n", + " [0, 0, 0, 3, 5, 45],\n", + " [0, 0, 0, 3, 6, 40],\n", + " [0, 0, 0, 3, 7, 35],\n", + " [0, 0, 0, 3, 8, 30],\n", + " [0, 0, 0, 3, 9, 25],\n", + " [0, 0, 0, 3, 10, 20],\n", + " [0, 0, 0, 3, 11, 15],\n", + " [0, 0, 0, 3, 12, 10],\n", + " [0, 0, 0, 3, 13, 5],\n", + " [0, 0, 0, 3, 14, 0],\n", + " [0, 0, 0, 4, 0, 60],\n", + " [0, 0, 0, 4, 1, 55],\n", + " [0, 0, 0, 4, 2, 50],\n", + " [0, 0, 0, 4, 3, 45],\n", + " [0, 0, 0, 4, 4, 40],\n", + " [0, 0, 0, 4, 5, 35],\n", + " [0, 0, 0, 4, 6, 30],\n", + " [0, 0, 0, 4, 7, 25],\n", + " [0, 0, 0, 4, 8, 20],\n", + " [0, 0, 0, 4, 9, 15],\n", + " [0, 0, 0, 4, 10, 10],\n", + " [0, 0, 0, 4, 11, 5],\n", + " [0, 0, 0, 4, 12, 0],\n", + " [0, 0, 0, 5, 0, 50],\n", + " [0, 0, 0, 5, 1, 45],\n", + " [0, 0, 0, 5, 2, 40],\n", + " [0, 0, 0, 5, 3, 35],\n", + " [0, 0, 0, 5, 4, 30],\n", + " [0, 0, 0, 5, 5, 25],\n", + " [0, 0, 0, 5, 6, 20],\n", + " [0, 0, 0, 5, 7, 15],\n", + " [0, 0, 0, 5, 8, 10],\n", + " [0, 0, 0, 5, 9, 5],\n", + " [0, 0, 0, 5, 10, 0],\n", + " [0, 0, 0, 6, 0, 40],\n", + " [0, 0, 0, 6, 1, 35],\n", + " [0, 0, 0, 6, 2, 30],\n", + " [0, 0, 0, 6, 3, 25],\n", + " [0, 0, 0, 6, 4, 20],\n", + " [0, 0, 0, 6, 5, 15],\n", + " [0, 0, 0, 6, 6, 10],\n", + " [0, 0, 0, 6, 7, 5],\n", + " [0, 0, 0, 6, 8, 0],\n", + " [0, 0, 0, 7, 0, 30],\n", + " [0, 0, 0, 7, 1, 25],\n", + " [0, 0, 0, 7, 2, 20],\n", + " [0, 0, 0, 7, 3, 15],\n", + " [0, 0, 0, 7, 4, 10],\n", + " [0, 0, 0, 7, 5, 5],\n", + " [0, 0, 0, 7, 6, 0],\n", + " [0, 0, 0, 8, 0, 20],\n", + " [0, 0, 0, 8, 1, 15],\n", + " [0, 0, 0, 8, 2, 10],\n", + " [0, 0, 0, 8, 3, 5],\n", + " [0, 0, 0, 8, 4, 0],\n", + " [0, 0, 0, 9, 0, 10],\n", + " [0, 0, 0, 9, 1, 5],\n", + " [0, 0, 0, 9, 2, 0],\n", + " [0, 0, 0, 10, 0, 0],\n", + " [0, 0, 1, 0, 0, 75],\n", + " [0, 0, 1, 0, 1, 70],\n", + " [0, 0, 1, 0, 2, 65],\n", + " [0, 0, 1, 0, 3, 60],\n", + " [0, 0, 1, 0, 4, 55],\n", + " [0, 0, 1, 0, 5, 50],\n", + " [0, 0, 1, 0, 6, 45],\n", + " [0, 0, 1, 0, 7, 40],\n", + " [0, 0, 1, 0, 8, 35],\n", + " [0, 0, 1, 0, 9, 30],\n", + " [0, 0, 1, 0, 10, 25],\n", + " [0, 0, 1, 0, 11, 20],\n", + " [0, 0, 1, 0, 12, 15],\n", + " [0, 0, 1, 0, 13, 10],\n", + " [0, 0, 1, 0, 14, 5],\n", + " [0, 0, 1, 0, 15, 0],\n", + " [0, 0, 1, 1, 0, 65],\n", + " [0, 0, 1, 1, 1, 60],\n", + " [0, 0, 1, 1, 2, 55],\n", + " [0, 0, 1, 1, 3, 50],\n", + " [0, 0, 1, 1, 4, 45],\n", + " [0, 0, 1, 1, 5, 40],\n", + " [0, 0, 1, 1, 6, 35],\n", + " [0, 0, 1, 1, 7, 30],\n", + " [0, 0, 1, 1, 8, 25],\n", + " [0, 0, 1, 1, 9, 20],\n", + " [0, 0, 1, 1, 10, 15],\n", + " [0, 0, 1, 1, 11, 10],\n", + " [0, 0, 1, 1, 12, 5],\n", + " [0, 0, 1, 1, 13, 0],\n", + " [0, 0, 1, 2, 0, 55],\n", + " [0, 0, 1, 2, 1, 50],\n", + " [0, 0, 1, 2, 2, 45],\n", + " [0, 0, 1, 2, 3, 40],\n", + " [0, 0, 1, 2, 4, 35],\n", + " [0, 0, 1, 2, 5, 30],\n", + " [0, 0, 1, 2, 6, 25],\n", + " [0, 0, 1, 2, 7, 20],\n", + " [0, 0, 1, 2, 8, 15],\n", + " [0, 0, 1, 2, 9, 10],\n", + " [0, 0, 1, 2, 10, 5],\n", + " [0, 0, 1, 2, 11, 0],\n", + " [0, 0, 1, 3, 0, 45],\n", + " [0, 0, 1, 3, 1, 40],\n", + " [0, 0, 1, 3, 2, 35],\n", + " [0, 0, 1, 3, 3, 30],\n", + " [0, 0, 1, 3, 4, 25],\n", + " [0, 0, 1, 3, 5, 20],\n", + " [0, 0, 1, 3, 6, 15],\n", + " [0, 0, 1, 3, 7, 10],\n", + " [0, 0, 1, 3, 8, 5],\n", + " [0, 0, 1, 3, 9, 0],\n", + " [0, 0, 1, 4, 0, 35],\n", + " [0, 0, 1, 4, 1, 30],\n", + " [0, 0, 1, 4, 2, 25],\n", + " [0, 0, 1, 4, 3, 20],\n", + " [0, 0, 1, 4, 4, 15],\n", + " [0, 0, 1, 4, 5, 10],\n", + " [0, 0, 1, 4, 6, 5],\n", + " [0, 0, 1, 4, 7, 0],\n", + " [0, 0, 1, 5, 0, 25],\n", + " [0, 0, 1, 5, 1, 20],\n", + " [0, 0, 1, 5, 2, 15],\n", + " [0, 0, 1, 5, 3, 10],\n", + " [0, 0, 1, 5, 4, 5],\n", + " [0, 0, 1, 5, 5, 0],\n", + " [0, 0, 1, 6, 0, 15],\n", + " [0, 0, 1, 6, 1, 10],\n", + " [0, 0, 1, 6, 2, 5],\n", + " [0, 0, 1, 6, 3, 0],\n", + " [0, 0, 1, 7, 0, 5],\n", + " [0, 0, 1, 7, 1, 0],\n", + " [0, 0, 2, 0, 0, 50],\n", + " [0, 0, 2, 0, 1, 45],\n", + " [0, 0, 2, 0, 2, 40],\n", + " [0, 0, 2, 0, 3, 35],\n", + " [0, 0, 2, 0, 4, 30],\n", + " [0, 0, 2, 0, 5, 25],\n", + " [0, 0, 2, 0, 6, 20],\n", + " [0, 0, 2, 0, 7, 15],\n", + " [0, 0, 2, 0, 8, 10],\n", + " [0, 0, 2, 0, 9, 5],\n", + " [0, 0, 2, 0, 10, 0],\n", + " [0, 0, 2, 1, 0, 40],\n", + " [0, 0, 2, 1, 1, 35],\n", + " [0, 0, 2, 1, 2, 30],\n", + " [0, 0, 2, 1, 3, 25],\n", + " [0, 0, 2, 1, 4, 20],\n", + " [0, 0, 2, 1, 5, 15],\n", + " [0, 0, 2, 1, 6, 10],\n", + " [0, 0, 2, 1, 7, 5],\n", + " [0, 0, 2, 1, 8, 0],\n", + " [0, 0, 2, 2, 0, 30],\n", + " [0, 0, 2, 2, 1, 25],\n", + " [0, 0, 2, 2, 2, 20],\n", + " [0, 0, 2, 2, 3, 15],\n", + " [0, 0, 2, 2, 4, 10],\n", + " [0, 0, 2, 2, 5, 5],\n", + " [0, 0, 2, 2, 6, 0],\n", + " [0, 0, 2, 3, 0, 20],\n", + " [0, 0, 2, 3, 1, 15],\n", + " [0, 0, 2, 3, 2, 10],\n", + " [0, 0, 2, 3, 3, 5],\n", + " [0, 0, 2, 3, 4, 0],\n", + " [0, 0, 2, 4, 0, 10],\n", + " [0, 0, 2, 4, 1, 5],\n", + " [0, 0, 2, 4, 2, 0],\n", + " [0, 0, 2, 5, 0, 0],\n", + " [0, 0, 3, 0, 0, 25],\n", + " [0, 0, 3, 0, 1, 20],\n", + " [0, 0, 3, 0, 2, 15],\n", + " [0, 0, 3, 0, 3, 10],\n", + " [0, 0, 3, 0, 4, 5],\n", + " [0, 0, 3, 0, 5, 0],\n", + " [0, 0, 3, 1, 0, 15],\n", + " [0, 0, 3, 1, 1, 10],\n", + " [0, 0, 3, 1, 2, 5],\n", + " [0, 0, 3, 1, 3, 0],\n", + " [0, 0, 3, 2, 0, 5],\n", + " [0, 0, 3, 2, 1, 0],\n", + " [0, 0, 4, 0, 0, 0],\n", + " [0, 1, 0, 0, 0, 50],\n", + " [0, 1, 0, 0, 1, 45],\n", + " [0, 1, 0, 0, 2, 40],\n", + " [0, 1, 0, 0, 3, 35],\n", + " [0, 1, 0, 0, 4, 30],\n", + " [0, 1, 0, 0, 5, 25],\n", + " [0, 1, 0, 0, 6, 20],\n", + " [0, 1, 0, 0, 7, 15],\n", + " [0, 1, 0, 0, 8, 10],\n", + " [0, 1, 0, 0, 9, 5],\n", + " [0, 1, 0, 0, 10, 0],\n", + " [0, 1, 0, 1, 0, 40],\n", + " [0, 1, 0, 1, 1, 35],\n", + " [0, 1, 0, 1, 2, 30],\n", + " [0, 1, 0, 1, 3, 25],\n", + " [0, 1, 0, 1, 4, 20],\n", + " [0, 1, 0, 1, 5, 15],\n", + " [0, 1, 0, 1, 6, 10],\n", + " [0, 1, 0, 1, 7, 5],\n", + " [0, 1, 0, 1, 8, 0],\n", + " [0, 1, 0, 2, 0, 30],\n", + " [0, 1, 0, 2, 1, 25],\n", + " [0, 1, 0, 2, 2, 20],\n", + " [0, 1, 0, 2, 3, 15],\n", + " [0, 1, 0, 2, 4, 10],\n", + " [0, 1, 0, 2, 5, 5],\n", + " [0, 1, 0, 2, 6, 0],\n", + " [0, 1, 0, 3, 0, 20],\n", + " [0, 1, 0, 3, 1, 15],\n", + " [0, 1, 0, 3, 2, 10],\n", + " [0, 1, 0, 3, 3, 5],\n", + " [0, 1, 0, 3, 4, 0],\n", + " [0, 1, 0, 4, 0, 10],\n", + " [0, 1, 0, 4, 1, 5],\n", + " [0, 1, 0, 4, 2, 0],\n", + " [0, 1, 0, 5, 0, 0],\n", + " [0, 1, 1, 0, 0, 25],\n", + " [0, 1, 1, 0, 1, 20],\n", + " [0, 1, 1, 0, 2, 15],\n", + " [0, 1, 1, 0, 3, 10],\n", + " [0, 1, 1, 0, 4, 5],\n", + " [0, 1, 1, 0, 5, 0],\n", + " [0, 1, 1, 1, 0, 15],\n", + " [0, 1, 1, 1, 1, 10],\n", + " [0, 1, 1, 1, 2, 5],\n", + " [0, 1, 1, 1, 3, 0],\n", + " [0, 1, 1, 2, 0, 5],\n", + " [0, 1, 1, 2, 1, 0],\n", + " [0, 1, 2, 0, 0, 0],\n", + " [0, 2, 0, 0, 0, 0],\n", + " [1, 0, 0, 0, 0, 0]]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "combinations" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "293" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "len(combinations)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n" + ] + } + ], "source": [ "for count_25 in range(4+1):\n", " print(count_25)" @@ -119,9 +486,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "25\n", + "50\n", + "75\n", + "100\n" + ] + } + ], "source": [ "for amount_25 in range(0, 100+1, 25):\n", " print(amount_25)" @@ -129,7 +508,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -149,9 +528,312 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[[0, 0, 0, 0, 0, 100],\n", + " [0, 0, 0, 0, 5, 95],\n", + " [0, 0, 0, 0, 10, 90],\n", + " [0, 0, 0, 0, 15, 85],\n", + " [0, 0, 0, 0, 20, 80],\n", + " [0, 0, 0, 0, 25, 75],\n", + " [0, 0, 0, 0, 30, 70],\n", + " [0, 0, 0, 0, 35, 65],\n", + " [0, 0, 0, 0, 40, 60],\n", + " [0, 0, 0, 0, 45, 55],\n", + " [0, 0, 0, 0, 50, 50],\n", + " [0, 0, 0, 0, 55, 45],\n", + " [0, 0, 0, 0, 60, 40],\n", + " [0, 0, 0, 0, 65, 35],\n", + " [0, 0, 0, 0, 70, 30],\n", + " [0, 0, 0, 0, 75, 25],\n", + " [0, 0, 0, 0, 80, 20],\n", + " [0, 0, 0, 0, 85, 15],\n", + " [0, 0, 0, 0, 90, 10],\n", + " [0, 0, 0, 0, 95, 5],\n", + " [0, 0, 0, 0, 100, 0],\n", + " [0, 0, 0, 10, 0, 90],\n", + " [0, 0, 0, 10, 5, 85],\n", + " [0, 0, 0, 10, 10, 80],\n", + " [0, 0, 0, 10, 15, 75],\n", + " [0, 0, 0, 10, 20, 70],\n", + " [0, 0, 0, 10, 25, 65],\n", + " [0, 0, 0, 10, 30, 60],\n", + " [0, 0, 0, 10, 35, 55],\n", + " [0, 0, 0, 10, 40, 50],\n", + " [0, 0, 0, 10, 45, 45],\n", + " [0, 0, 0, 10, 50, 40],\n", + " [0, 0, 0, 10, 55, 35],\n", + " [0, 0, 0, 10, 60, 30],\n", + " [0, 0, 0, 10, 65, 25],\n", + " [0, 0, 0, 10, 70, 20],\n", + " [0, 0, 0, 10, 75, 15],\n", + " [0, 0, 0, 10, 80, 10],\n", + " [0, 0, 0, 10, 85, 5],\n", + " [0, 0, 0, 10, 90, 0],\n", + " [0, 0, 0, 20, 0, 80],\n", + " [0, 0, 0, 20, 5, 75],\n", + " [0, 0, 0, 20, 10, 70],\n", + " [0, 0, 0, 20, 15, 65],\n", + " [0, 0, 0, 20, 20, 60],\n", + " [0, 0, 0, 20, 25, 55],\n", + " [0, 0, 0, 20, 30, 50],\n", + " [0, 0, 0, 20, 35, 45],\n", + " [0, 0, 0, 20, 40, 40],\n", + " [0, 0, 0, 20, 45, 35],\n", + " [0, 0, 0, 20, 50, 30],\n", + " [0, 0, 0, 20, 55, 25],\n", + " [0, 0, 0, 20, 60, 20],\n", + " [0, 0, 0, 20, 65, 15],\n", + " [0, 0, 0, 20, 70, 10],\n", + " [0, 0, 0, 20, 75, 5],\n", + " [0, 0, 0, 20, 80, 0],\n", + " [0, 0, 0, 30, 0, 70],\n", + " [0, 0, 0, 30, 5, 65],\n", + " [0, 0, 0, 30, 10, 60],\n", + " [0, 0, 0, 30, 15, 55],\n", + " [0, 0, 0, 30, 20, 50],\n", + " [0, 0, 0, 30, 25, 45],\n", + " [0, 0, 0, 30, 30, 40],\n", + " [0, 0, 0, 30, 35, 35],\n", + " [0, 0, 0, 30, 40, 30],\n", + " [0, 0, 0, 30, 45, 25],\n", + " [0, 0, 0, 30, 50, 20],\n", + " [0, 0, 0, 30, 55, 15],\n", + " [0, 0, 0, 30, 60, 10],\n", + " [0, 0, 0, 30, 65, 5],\n", + " [0, 0, 0, 30, 70, 0],\n", + " [0, 0, 0, 40, 0, 60],\n", + " [0, 0, 0, 40, 5, 55],\n", + " [0, 0, 0, 40, 10, 50],\n", + " [0, 0, 0, 40, 15, 45],\n", + " [0, 0, 0, 40, 20, 40],\n", + " [0, 0, 0, 40, 25, 35],\n", + " [0, 0, 0, 40, 30, 30],\n", + " [0, 0, 0, 40, 35, 25],\n", + " [0, 0, 0, 40, 40, 20],\n", + " [0, 0, 0, 40, 45, 15],\n", + " [0, 0, 0, 40, 50, 10],\n", + " [0, 0, 0, 40, 55, 5],\n", + " [0, 0, 0, 40, 60, 0],\n", + " [0, 0, 0, 50, 0, 50],\n", + " [0, 0, 0, 50, 5, 45],\n", + " [0, 0, 0, 50, 10, 40],\n", + " [0, 0, 0, 50, 15, 35],\n", + " [0, 0, 0, 50, 20, 30],\n", + " [0, 0, 0, 50, 25, 25],\n", + " [0, 0, 0, 50, 30, 20],\n", + " [0, 0, 0, 50, 35, 15],\n", + " [0, 0, 0, 50, 40, 10],\n", + " [0, 0, 0, 50, 45, 5],\n", + " [0, 0, 0, 50, 50, 0],\n", + " [0, 0, 0, 60, 0, 40],\n", + " [0, 0, 0, 60, 5, 35],\n", + " [0, 0, 0, 60, 10, 30],\n", + " [0, 0, 0, 60, 15, 25],\n", + " [0, 0, 0, 60, 20, 20],\n", + " [0, 0, 0, 60, 25, 15],\n", + " [0, 0, 0, 60, 30, 10],\n", + " [0, 0, 0, 60, 35, 5],\n", + " [0, 0, 0, 60, 40, 0],\n", + " [0, 0, 0, 70, 0, 30],\n", + " [0, 0, 0, 70, 5, 25],\n", + " [0, 0, 0, 70, 10, 20],\n", + " [0, 0, 0, 70, 15, 15],\n", + " [0, 0, 0, 70, 20, 10],\n", + " [0, 0, 0, 70, 25, 5],\n", + " [0, 0, 0, 70, 30, 0],\n", + " [0, 0, 0, 80, 0, 20],\n", + " [0, 0, 0, 80, 5, 15],\n", + " [0, 0, 0, 80, 10, 10],\n", + " [0, 0, 0, 80, 15, 5],\n", + " [0, 0, 0, 80, 20, 0],\n", + " [0, 0, 0, 90, 0, 10],\n", + " [0, 0, 0, 90, 5, 5],\n", + " [0, 0, 0, 90, 10, 0],\n", + " [0, 0, 0, 100, 0, 0],\n", + " [0, 0, 25, 0, 0, 75],\n", + " [0, 0, 25, 0, 5, 70],\n", + " [0, 0, 25, 0, 10, 65],\n", + " [0, 0, 25, 0, 15, 60],\n", + " [0, 0, 25, 0, 20, 55],\n", + " [0, 0, 25, 0, 25, 50],\n", + " [0, 0, 25, 0, 30, 45],\n", + " [0, 0, 25, 0, 35, 40],\n", + " [0, 0, 25, 0, 40, 35],\n", + " [0, 0, 25, 0, 45, 30],\n", + " [0, 0, 25, 0, 50, 25],\n", + " [0, 0, 25, 0, 55, 20],\n", + " [0, 0, 25, 0, 60, 15],\n", + " [0, 0, 25, 0, 65, 10],\n", + " [0, 0, 25, 0, 70, 5],\n", + " [0, 0, 25, 0, 75, 0],\n", + " [0, 0, 25, 10, 0, 65],\n", + " [0, 0, 25, 10, 5, 60],\n", + " [0, 0, 25, 10, 10, 55],\n", + " [0, 0, 25, 10, 15, 50],\n", + " [0, 0, 25, 10, 20, 45],\n", + " [0, 0, 25, 10, 25, 40],\n", + " [0, 0, 25, 10, 30, 35],\n", + " [0, 0, 25, 10, 35, 30],\n", + " [0, 0, 25, 10, 40, 25],\n", + " [0, 0, 25, 10, 45, 20],\n", + " [0, 0, 25, 10, 50, 15],\n", + " [0, 0, 25, 10, 55, 10],\n", + " [0, 0, 25, 10, 60, 5],\n", + " [0, 0, 25, 10, 65, 0],\n", + " [0, 0, 25, 20, 0, 55],\n", + " [0, 0, 25, 20, 5, 50],\n", + " [0, 0, 25, 20, 10, 45],\n", + " [0, 0, 25, 20, 15, 40],\n", + " [0, 0, 25, 20, 20, 35],\n", + " [0, 0, 25, 20, 25, 30],\n", + " [0, 0, 25, 20, 30, 25],\n", + " [0, 0, 25, 20, 35, 20],\n", + " [0, 0, 25, 20, 40, 15],\n", + " [0, 0, 25, 20, 45, 10],\n", + " [0, 0, 25, 20, 50, 5],\n", + " [0, 0, 25, 20, 55, 0],\n", + " [0, 0, 25, 30, 0, 45],\n", + " [0, 0, 25, 30, 5, 40],\n", + " [0, 0, 25, 30, 10, 35],\n", + " [0, 0, 25, 30, 15, 30],\n", + " [0, 0, 25, 30, 20, 25],\n", + " [0, 0, 25, 30, 25, 20],\n", + " [0, 0, 25, 30, 30, 15],\n", + " [0, 0, 25, 30, 35, 10],\n", + " [0, 0, 25, 30, 40, 5],\n", + " [0, 0, 25, 30, 45, 0],\n", + " [0, 0, 25, 40, 0, 35],\n", + " [0, 0, 25, 40, 5, 30],\n", + " [0, 0, 25, 40, 10, 25],\n", + " [0, 0, 25, 40, 15, 20],\n", + " [0, 0, 25, 40, 20, 15],\n", + " [0, 0, 25, 40, 25, 10],\n", + " [0, 0, 25, 40, 30, 5],\n", + " [0, 0, 25, 40, 35, 0],\n", + " [0, 0, 25, 50, 0, 25],\n", + " [0, 0, 25, 50, 5, 20],\n", + " [0, 0, 25, 50, 10, 15],\n", + " [0, 0, 25, 50, 15, 10],\n", + " [0, 0, 25, 50, 20, 5],\n", + " [0, 0, 25, 50, 25, 0],\n", + " [0, 0, 25, 60, 0, 15],\n", + " [0, 0, 25, 60, 5, 10],\n", + " [0, 0, 25, 60, 10, 5],\n", + " [0, 0, 25, 60, 15, 0],\n", + " [0, 0, 25, 70, 0, 5],\n", + " [0, 0, 25, 70, 5, 0],\n", + " [0, 0, 50, 0, 0, 50],\n", + " [0, 0, 50, 0, 5, 45],\n", + " [0, 0, 50, 0, 10, 40],\n", + " [0, 0, 50, 0, 15, 35],\n", + " [0, 0, 50, 0, 20, 30],\n", + " [0, 0, 50, 0, 25, 25],\n", + " [0, 0, 50, 0, 30, 20],\n", + " [0, 0, 50, 0, 35, 15],\n", + " [0, 0, 50, 0, 40, 10],\n", + " [0, 0, 50, 0, 45, 5],\n", + " [0, 0, 50, 0, 50, 0],\n", + " [0, 0, 50, 10, 0, 40],\n", + " [0, 0, 50, 10, 5, 35],\n", + " [0, 0, 50, 10, 10, 30],\n", + " [0, 0, 50, 10, 15, 25],\n", + " [0, 0, 50, 10, 20, 20],\n", + " [0, 0, 50, 10, 25, 15],\n", + " [0, 0, 50, 10, 30, 10],\n", + " [0, 0, 50, 10, 35, 5],\n", + " [0, 0, 50, 10, 40, 0],\n", + " [0, 0, 50, 20, 0, 30],\n", + " [0, 0, 50, 20, 5, 25],\n", + " [0, 0, 50, 20, 10, 20],\n", + " [0, 0, 50, 20, 15, 15],\n", + " [0, 0, 50, 20, 20, 10],\n", + " [0, 0, 50, 20, 25, 5],\n", + " [0, 0, 50, 20, 30, 0],\n", + " [0, 0, 50, 30, 0, 20],\n", + " [0, 0, 50, 30, 5, 15],\n", + " [0, 0, 50, 30, 10, 10],\n", + " [0, 0, 50, 30, 15, 5],\n", + " [0, 0, 50, 30, 20, 0],\n", + " [0, 0, 50, 40, 0, 10],\n", + " [0, 0, 50, 40, 5, 5],\n", + " [0, 0, 50, 40, 10, 0],\n", + " [0, 0, 50, 50, 0, 0],\n", + " [0, 0, 75, 0, 0, 25],\n", + " [0, 0, 75, 0, 5, 20],\n", + " [0, 0, 75, 0, 10, 15],\n", + " [0, 0, 75, 0, 15, 10],\n", + " [0, 0, 75, 0, 20, 5],\n", + " [0, 0, 75, 0, 25, 0],\n", + " [0, 0, 75, 10, 0, 15],\n", + " [0, 0, 75, 10, 5, 10],\n", + " [0, 0, 75, 10, 10, 5],\n", + " [0, 0, 75, 10, 15, 0],\n", + " [0, 0, 75, 20, 0, 5],\n", + " [0, 0, 75, 20, 5, 0],\n", + " [0, 0, 100, 0, 0, 0],\n", + " [0, 50, 0, 0, 0, 50],\n", + " [0, 50, 0, 0, 5, 45],\n", + " [0, 50, 0, 0, 10, 40],\n", + " [0, 50, 0, 0, 15, 35],\n", + " [0, 50, 0, 0, 20, 30],\n", + " [0, 50, 0, 0, 25, 25],\n", + " [0, 50, 0, 0, 30, 20],\n", + " [0, 50, 0, 0, 35, 15],\n", + " [0, 50, 0, 0, 40, 10],\n", + " [0, 50, 0, 0, 45, 5],\n", + " [0, 50, 0, 0, 50, 0],\n", + " [0, 50, 0, 10, 0, 40],\n", + " [0, 50, 0, 10, 5, 35],\n", + " [0, 50, 0, 10, 10, 30],\n", + " [0, 50, 0, 10, 15, 25],\n", + " [0, 50, 0, 10, 20, 20],\n", + " [0, 50, 0, 10, 25, 15],\n", + " [0, 50, 0, 10, 30, 10],\n", + " [0, 50, 0, 10, 35, 5],\n", + " [0, 50, 0, 10, 40, 0],\n", + " [0, 50, 0, 20, 0, 30],\n", + " [0, 50, 0, 20, 5, 25],\n", + " [0, 50, 0, 20, 10, 20],\n", + " [0, 50, 0, 20, 15, 15],\n", + " [0, 50, 0, 20, 20, 10],\n", + " [0, 50, 0, 20, 25, 5],\n", + " [0, 50, 0, 20, 30, 0],\n", + " [0, 50, 0, 30, 0, 20],\n", + " [0, 50, 0, 30, 5, 15],\n", + " [0, 50, 0, 30, 10, 10],\n", + " [0, 50, 0, 30, 15, 5],\n", + " [0, 50, 0, 30, 20, 0],\n", + " [0, 50, 0, 40, 0, 10],\n", + " [0, 50, 0, 40, 5, 5],\n", + " [0, 50, 0, 40, 10, 0],\n", + " [0, 50, 0, 50, 0, 0],\n", + " [0, 50, 25, 0, 0, 25],\n", + " [0, 50, 25, 0, 5, 20],\n", + " [0, 50, 25, 0, 10, 15],\n", + " [0, 50, 25, 0, 15, 10],\n", + " [0, 50, 25, 0, 20, 5],\n", + " [0, 50, 25, 0, 25, 0],\n", + " [0, 50, 25, 10, 0, 15],\n", + " [0, 50, 25, 10, 5, 10],\n", + " [0, 50, 25, 10, 10, 5],\n", + " [0, 50, 25, 10, 15, 0],\n", + " [0, 50, 25, 20, 0, 5],\n", + " [0, 50, 25, 20, 5, 0],\n", + " [0, 50, 50, 0, 0, 0],\n", + " [0, 100, 0, 0, 0, 0],\n", + " [100, 0, 0, 0, 0, 0]]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "combinations_amounts" ] @@ -230,7 +912,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -244,7 +926,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.12.1" } }, "nbformat": 4, diff --git a/ch01-datastructures/01_02_list_tuples.ipynb b/ch01-datastructures/01_02_list_tuples.ipynb index 605aed80b..bf592b2fd 100644 --- a/ch01-datastructures/01_02_list_tuples.ipynb +++ b/ch01-datastructures/01_02_list_tuples.ipynb @@ -34,72 +34,161 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['Huey', 'Dewey', 'Louie']" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "nephews" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "len(nephews)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "len([])" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'Huey'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "nephews[0]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'Louie'" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "nephews[2]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "IndexError", + "evalue": "list index out of range", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mIndexError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mnephews\u001b[49m\u001b[43m[\u001b[49m\u001b[32;43m3\u001b[39;49m\u001b[43m]\u001b[49m\n", + "\u001b[31mIndexError\u001b[39m: list index out of range" + ] + } + ], "source": [ "nephews[3]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'Louie'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "nephews[-1]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'Dewey'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "nephews[-2]" ] @@ -116,9 +205,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "['Huey Duck', 'Dewey Duck', 'Louie Duck']" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "nephews" ] @@ -134,45 +234,95 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[1, [2, 3], 'alpha']" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mix_it_up" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "'Huey' in nephews" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "'Huey Duck' in nephews" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ - "nephews.append('April Duck')" + "nephews.append(['May Duck', 'June Duck'])" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "['Huey Duck',\n", + " 'Dewey Duck',\n", + " 'Louie Duck',\n", + " 'April Duck',\n", + " 'May Duck',\n", + " 'June Duck',\n", + " ['May Duck', 'June Duck']]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "nephews" ] @@ -197,7 +347,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -206,16 +356,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "['Huey Duck',\n", + " 'Dewey Duck',\n", + " 'Louie Duck',\n", + " 'April Duck',\n", + " 'May Duck',\n", + " 'June Duck',\n", + " ['May Duck', 'June Duck'],\n", + " 'Donald Duck',\n", + " 'Daisy Duck']" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ducks" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -224,16 +393,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "['Scrooge McDuck',\n", + " 'Huey Duck',\n", + " 'Dewey Duck',\n", + " 'Louie Duck',\n", + " 'April Duck',\n", + " 'May Duck',\n", + " 'June Duck',\n", + " ['May Duck', 'June Duck'],\n", + " 'Donald Duck',\n", + " 'Daisy Duck']" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ducks" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -242,16 +431,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "['Huey Duck',\n", + " 'Dewey Duck',\n", + " 'Louie Duck',\n", + " 'April Duck',\n", + " 'May Duck',\n", + " 'June Duck',\n", + " ['May Duck', 'June Duck'],\n", + " 'Donald Duck',\n", + " 'Daisy Duck']" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ducks" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -532,11 +740,71 @@ "source": [ "any_args(1,2,3)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Understanding del vs remove" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Original: ['apple', 'banana', 'cherry', 'banana']\n", + "After del fruits[1]: ['apple', 'cherry', 'banana']\n" + ] + } + ], + "source": [ + "# del - deletes by INDEX\n", + "fruits = ['apple', 'banana', 'cherry', 'banana']\n", + "print(\"Original:\", fruits)\n", + "\n", + "del fruits[1] # Delete the item at index 1 (banana)\n", + "print(\"After del fruits[1]:\", fruits)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Original: ['apple', 'banana', 'cherry', 'banana']\n", + "After remove('banana'): ['apple', 'cherry', 'banana']\n" + ] + } + ], + "source": [ + "# remove() - removes by VALUE (first occurrence only!)\n", + "fruits = ['apple', 'banana', 'cherry', 'banana']\n", + "print(\"Original:\", fruits)\n", + "\n", + "fruits.remove('banana') # Removes the FIRST 'banana' it finds\n", + "print(\"After remove('banana'):\", fruits)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -550,7 +818,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.12.1" } }, "nbformat": 4, diff --git a/ch01-datastructures/01_03_dicts_sets.ipynb b/ch01-datastructures/01_03_dicts_sets.ipynb index a8e0ade0b..140e9e5c0 100644 --- a/ch01-datastructures/01_03_dicts_sets.ipynb +++ b/ch01-datastructures/01_03_dicts_sets.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -25,7 +25,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -34,34 +34,67 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'United States': 'Washington, DC', 'France': 'Paris', 'Italy': 'Rome'}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "capitals" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(3, 0)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "len(capitals), len({})" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'Rome'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "capitals['Italy']" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -70,34 +103,70 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'United States': 'Washington, DC',\n", + " 'France': 'Paris',\n", + " 'Italy': 'Rome',\n", + " 'Spain': 'Madrid'}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "capitals" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'KeyError'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "capitals['Germany']" + "capitals['Germany'] if 'Germany' in capitals else 'KeyError'" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(False, True)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "'Germany' in capitals, 'Italy' in capitals" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -106,16 +175,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'United States': 'Washington, DC',\n", + " 'France': 'Paris',\n", + " 'Italy': 'Rome',\n", + " 'Spain': 'Madrid',\n", + " 'Germany': 'Berlin',\n", + " 'United Kingdom': 'London'}" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "{**capitals, **morecapitals}" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -124,16 +209,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'United States': 'Washington, DC',\n", + " 'France': 'Paris',\n", + " 'Italy': 'Rome',\n", + " 'Spain': 'Madrid',\n", + " 'Germany': 'Berlin',\n", + " 'United Kingdom': 'London'}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "capitals" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -142,16 +243,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'United States': 'Washington, DC',\n", + " 'France': 'Paris',\n", + " 'Italy': 'Rome',\n", + " 'Spain': 'Madrid',\n", + " 'Germany': 'Berlin'}" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "capitals" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -160,9 +276,40 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{(7, 15): 'Michele', (3, 14): 'Albert'}" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "birthdays" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Michele'" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "birthdays[(7,15)]" ] @@ -333,11 +480,321 @@ "for c in continents:\n", " print(c)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Example: dictionaries with various hashable key types**\n", + "\n", + "Below is a compact example that uses many kinds of hashable objects as dictionary keys and demonstrates retrieval and iteration. Mutable objects like `list` are not hashable and cannot be used as keys." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dictionary with mixed hashable keys:\n", + " {42: 'an int key', 3.14: 'a float key', 'name': 'a str key', (1, 2): 'a tuple key', frozenset({1, 2}): 'a frozenset key', True: 'a bool key', b'bytes': 'a bytes key', datetime.date(2025, 12, 11): 'a date key', Point(x=1, y=2): 'a frozen dataclass instance key'}\n", + "Access some values:\n", + " a tuple key a date key a frozen dataclass instance key\n", + "\n", + "Types of keys:\n", + " -> 42\n", + " -> 3.14\n", + " -> name\n", + " -> (1, 2)\n", + " -> frozenset({1, 2})\n", + " -> True\n", + " -> b'bytes'\n", + " -> 2025-12-11\n", + " -> Point(x=1, y=2)\n", + " This key is a Point with coordinates: 1 2\n", + "\n", + "Collision example (1 and True): {1: 'true'}\n" + ] + } + ], + "source": [ + "from dataclasses import dataclass\n", + "import datetime\n", + "\n", + "@dataclass(frozen=True)\n", + "class Point:\n", + " x: int\n", + " y: int\n", + "\n", + "p = Point(1, 2)\n", + "\n", + "d = {\n", + " 42: \"an int key\",\n", + " 3.14: \"a float key\",\n", + " \"name\": \"a str key\",\n", + " (1, 2): \"a tuple key\",\n", + " frozenset({1, 2}): \"a frozenset key\",\n", + " True: \"a bool key\",\n", + " b'bytes': \"a bytes key\",\n", + " datetime.date(2025, 12, 11): \"a date key\",\n", + " p: \"a frozen dataclass instance key\",\n", + "}\n", + "\n", + "print(\"Dictionary with mixed hashable keys:\\n\", d)\n", + "print(\"Access some values:\\n\", d[(1, 2)], d[datetime.date(2025, 12, 11)], d[p])\n", + "\n", + "print('\\nTypes of keys:')\n", + "for k in d:\n", + " print(type(k), '->', k)\n", + " if isinstance(k, Point):\n", + " print(' This key is a Point with coordinates:', k.x, k.y)\n", + "\n", + "# Note: the following would raise TypeError (unhashable):\n", + "# d[[1,2]] = 'list as key' # TypeError: unhashable type: 'list'\n", + "\n", + "# Special note: bool is a subclass of int, so True and 1 collide as keys:\n", + "d2 = {1: 'one', True: 'true'}\n", + "print('\\nCollision example (1 and True):', d2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Frozenset examples**\n", + "\n", + "A `frozenset` is an immutable `set`. It supports non-mutating set operations and is hashable, so it can be used as a dictionary key or stored inside a `set`." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fs: frozenset({1, 2, 3})\n", + "fs.add -> AttributeError 'frozenset' object has no attribute 'add'\n", + "union with {3,4}: frozenset({1, 2, 3, 4})\n", + "intersection with [2,3]: frozenset({2, 3})\n", + "fs == set([1,2,3]): True\n", + "dict access by frozenset key: value for frozenset key\n", + "set containing frozensets: {frozenset({1}), frozenset({2, 3})}\n", + "fs after union (original unchanged): frozenset({1, 2, 3}) -> new: frozenset({1, 2, 3, 4})\n" + ] + } + ], + "source": [ + "# frozenset demo\n", + "fs = frozenset([1, 2, 3])\n", + "print('fs:', fs)\n", + "\n", + "# immutability: mutating methods don't exist (this will raise AttributeError)\n", + "try:\n", + " fs.add(4)\n", + "except Exception as e:\n", + " print('fs.add ->', type(e).__name__, e)\n", + "\n", + "# non-mutating operations return new frozensets\n", + "print('union with {3,4}:', fs.union({3, 4}))\n", + "print('intersection with [2,3]:', fs.intersection([2, 3]))\n", + "\n", + "# equality with set compares by membership\n", + "print('fs == set([1,2,3]):', fs == set([1, 2, 3]))\n", + "\n", + "# frozenset can be used as a dict key or as an element of a set\n", + "d = {fs: 'value for frozenset key'}\n", + "print('dict access by frozenset key:', d[fs])\n", + "\n", + "s = {frozenset([1]), frozenset([2, 3])}\n", + "print('set containing frozensets:', s)\n", + "\n", + "# unhashable example (would raise TypeError):\n", + "# d[set([1,2])] = 'bad' # TypeError: unhashable type: 'set' (not hashable)\n", + "\n", + "# note: frozenset methods do not modify in-place; they return new frozensets\n", + "fs2 = fs.union([4])\n", + "print('fs after union (original unchanged):', fs, '-> new:', fs2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Making classes immutable/hashable: dataclass vs manual dunder methods**\n", + "\n", + "There are two main approaches:\n", + "1. **`@dataclass(frozen=True)`** — Simple, automatic immutability and hashability \n", + "2. **Manual `__hash__` & `__eq__` overrides** — More control, but requires you to handle immutability separately\n", + "\n", + "For finality (preventing subclassing), use `@final` from `typing` module.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dataclass approach:\n", + " p1: PointDataclass(x=1, y=2)\n", + " hash(p1): -3550055125485641917\n", + " Can use as dict key: {PointDataclass(x=1, y=2): 'success'}\n", + " p1.x = 5 -> FrozenInstanceError: cannot assign to field 'x'\n", + "\n", + "Manual approach:\n", + " p2: PointManual(1, 2)\n", + " hash(p2): -3550055125485641917\n", + " Can use as dict key: {PointManual(1, 2): 'success'}\n", + " Equality works: True\n", + " p2.x = 5 -> AttributeError (property read-only)\n", + "\n", + "Final class (with @final decorator):\n", + " FinalPoint(3, 4): FinalPoint(x=3, y=4)\n" + ] + } + ], + "source": [ + "# Approach 1: dataclass with frozen=True (simple, automatic)\n", + "from dataclasses import dataclass\n", + "from typing import final\n", + "\n", + "@dataclass(frozen=True)\n", + "class PointDataclass:\n", + " x: int\n", + " y: int\n", + "\n", + "p1 = PointDataclass(1, 2)\n", + "print(\"Dataclass approach:\")\n", + "print(\" p1:\", p1)\n", + "print(\" hash(p1):\", hash(p1))\n", + "print(\" Can use as dict key:\", {p1: \"success\"})\n", + "\n", + "# Try to mutate (will raise FrozenInstanceError)\n", + "try:\n", + " p1.x = 5\n", + "except Exception as e:\n", + " print(f\" p1.x = 5 -> {type(e).__name__}: {e}\")\n", + "\n", + "print()\n", + "\n", + "# Approach 2: Manual __hash__ and __eq__ (more control, but more code)\n", + "class PointManual:\n", + " def __init__(self, x: int, y: int):\n", + " # Store in private attributes to prevent direct mutation\n", + " self._x = x\n", + " self._y = y\n", + " \n", + " @property\n", + " def x(self):\n", + " return self._x\n", + " \n", + " @property\n", + " def y(self):\n", + " return self._y\n", + " \n", + " def __eq__(self, other):\n", + " if not isinstance(other, PointManual):\n", + " return False\n", + " return self._x == other._x and self._y == other._y\n", + " \n", + " def __hash__(self):\n", + " return hash((self._x, self._y))\n", + " \n", + " def __repr__(self):\n", + " return f\"PointManual({self._x}, {self._y})\"\n", + "\n", + "p2 = PointManual(1, 2)\n", + "print(\"Manual approach:\")\n", + "print(\" p2:\", p2)\n", + "print(\" hash(p2):\", hash(p2))\n", + "print(\" Can use as dict key:\", {p2: \"success\"})\n", + "print(\" Equality works:\", PointManual(1, 2) == p2)\n", + "\n", + "# Attempting direct mutation is harder (properties prevent it)\n", + "try:\n", + " p2.x = 5\n", + "except AttributeError as e:\n", + " print(f\" p2.x = 5 -> AttributeError (property read-only)\")\n", + "\n", + "print()\n", + "\n", + "# Approach 3: Using @final to prevent subclassing\n", + "@final\n", + "@dataclass(frozen=True)\n", + "class FinalPoint:\n", + " x: int\n", + " y: int\n", + "\n", + "print(\"Final class (with @final decorator):\")\n", + "print(\" FinalPoint(3, 4):\", FinalPoint(3, 4))\n", + "# Trying to subclass FinalPoint would raise TypeError at class definition time\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Trying to subclass TrulyFinalPoint:\n", + " ✓ Correctly raised: Cannot subclass subTrulyFinalPoint; it is final\n", + "\n", + "@final (from typing) is only for static type checkers:\n", + " - Mypy will flag violations\n", + " - But Python allows subclassing at runtime\n", + " - Use __init_subclass__ to enforce at runtime\n" + ] + } + ], + "source": [ + "# IMPORTANT: @final only works at type-checking time, NOT at runtime!\n", + "# This means Mypy will complain, but Python won't prevent it.\n", + "\n", + "# To actually enforce immutability at runtime, use __init_subclass__:\n", + "@dataclass(frozen=True)\n", + "class TrulyFinalPoint:\n", + " x: int\n", + " y: int\n", + " \n", + " def __init_subclass__(cls, **kwargs):\n", + " raise TypeError(f\"Cannot subclass {cls.__name__}; it is final\")\n", + "\n", + "print(\"Trying to subclass TrulyFinalPoint:\")\n", + "try:\n", + " class subTrulyFinalPoint(TrulyFinalPoint):\n", + " pass\n", + "except TypeError as e:\n", + " print(f\" ✓ Correctly raised: {e}\")\n", + "\n", + "print(\"\\n@final (from typing) is only for static type checkers:\")\n", + "print(\" - Mypy will flag violations\")\n", + "print(\" - But Python allows subclassing at runtime\")\n", + "print(\" - Use __init_subclass__ to enforce at runtime\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -351,7 +808,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.12.1" } }, "nbformat": 4,