From eceb1682f1e921653451c6f4eb27b155be836d2d Mon Sep 17 00:00:00 2001 From: Wojtek Date: Sun, 2 Nov 2025 16:09:39 +0100 Subject: [PATCH 1/3] demo notebooks --- dbzero/dbzero/memo.py | 4 +- .../hello-db0-1_pl-checkpoint.ipynb | 234 ++ .../hello.db0_1-checkpoint.ipynb | 260 ++ .../hello.db0_2-checkpoint.ipynb | 2303 +++++++++++++++++ .../hello.db0_3-checkpoint.ipynb | 640 +++++ .../hello.db0_4-checkpoint.ipynb | 1125 ++++++++ .../hello.db0_5-checkpoint.ipynb | 945 +++++++ notebooks/hello/hello-db0-1_pl.ipynb | 248 ++ notebooks/hello/hello-db0-2_pl.ipynb | 374 +++ notebooks/hello/hello-db0-3_pl.ipynb | 265 ++ notebooks/hello/hello.db0_1.ipynb | 340 +++ notebooks/hello/hello.db0_2.ipynb | 2303 +++++++++++++++++ notebooks/hello/hello.db0_3.ipynb | 329 +++ notebooks/hello/hello.db0_4.ipynb | 1125 ++++++++ notebooks/hello/hello.db0_5.ipynb | 945 +++++++ notebooks/hello/mem_charts.py | 99 + notebooks/hello/ram-utilization-chart.ipynb | 167 ++ .../add_tag_in_init-checkpoint.ipynb | 129 + .../attribute_error-checkpoint.ipynb | 319 +++ .../import_tests-checkpoint.ipynb | 6 + .../test-parse-checkpoint.ipynb | 6 + .../issues/db0-test-data/my-test-prefix2.db0 | Bin 0 -> 176128 bytes notebooks/issues/import_tests.ipynb | 122 + notebooks/issues/test-parse.ipynb | 113 + 24 files changed, 12399 insertions(+), 2 deletions(-) create mode 100644 notebooks/hello/.ipynb_checkpoints/hello-db0-1_pl-checkpoint.ipynb create mode 100644 notebooks/hello/.ipynb_checkpoints/hello.db0_1-checkpoint.ipynb create mode 100644 notebooks/hello/.ipynb_checkpoints/hello.db0_2-checkpoint.ipynb create mode 100644 notebooks/hello/.ipynb_checkpoints/hello.db0_3-checkpoint.ipynb create mode 100644 notebooks/hello/.ipynb_checkpoints/hello.db0_4-checkpoint.ipynb create mode 100644 notebooks/hello/.ipynb_checkpoints/hello.db0_5-checkpoint.ipynb create mode 100644 notebooks/hello/hello-db0-1_pl.ipynb create mode 100644 notebooks/hello/hello-db0-2_pl.ipynb create mode 100644 notebooks/hello/hello-db0-3_pl.ipynb create mode 100644 notebooks/hello/hello.db0_1.ipynb create mode 100644 notebooks/hello/hello.db0_2.ipynb create mode 100644 notebooks/hello/hello.db0_3.ipynb create mode 100644 notebooks/hello/hello.db0_4.ipynb create mode 100644 notebooks/hello/hello.db0_5.ipynb create mode 100644 notebooks/hello/mem_charts.py create mode 100644 notebooks/hello/ram-utilization-chart.ipynb create mode 100644 notebooks/issues/.ipynb_checkpoints/add_tag_in_init-checkpoint.ipynb create mode 100644 notebooks/issues/.ipynb_checkpoints/attribute_error-checkpoint.ipynb create mode 100644 notebooks/issues/.ipynb_checkpoints/import_tests-checkpoint.ipynb create mode 100644 notebooks/issues/.ipynb_checkpoints/test-parse-checkpoint.ipynb create mode 100644 notebooks/issues/db0-test-data/my-test-prefix2.db0 create mode 100644 notebooks/issues/import_tests.ipynb create mode 100644 notebooks/issues/test-parse.ipynb diff --git a/dbzero/dbzero/memo.py b/dbzero/dbzero/memo.py index 59f8303f..d1b1e09d 100644 --- a/dbzero/dbzero/memo.py +++ b/dbzero/dbzero/memo.py @@ -65,10 +65,10 @@ def memo(cls: Optional[type] = None, **kwargs) -> type: >>> print(settings2.theme) # "light" """ def getfile(cls_): - # inspect.getfile() can raise TypeError if cls_ is a built-in class (e.g. defined in a notebook). + # inspect.getfile() can raise TypeError, OSError if cls_ is a built-in class (e.g. defined in a notebook). try: return inspect.getfile(cls_) - except TypeError: + except (TypeError, OSError): return None def dyn_prefix(from_type): diff --git a/notebooks/hello/.ipynb_checkpoints/hello-db0-1_pl-checkpoint.ipynb b/notebooks/hello/.ipynb_checkpoints/hello-db0-1_pl-checkpoint.ipynb new file mode 100644 index 00000000..800b2844 --- /dev/null +++ b/notebooks/hello/.ipynb_checkpoints/hello-db0-1_pl-checkpoint.ipynb @@ -0,0 +1,234 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4d79e2e4", + "metadata": {}, + "source": [ + "## Wprowadzenie do dbzero (1/12): Rozpoczynamy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "421ce30a", + "metadata": {}, + "outputs": [], + "source": [ + "!rm -rf /dbzero\n", + "import dbzero as db0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "311bbaaa", + "metadata": {}, + "outputs": [], + "source": [ + "db0.init(dbzero_root=\"/dbzero\", prefix = \"data\")" + ] + }, + { + "cell_type": "markdown", + "id": "f63f0a43", + "metadata": {}, + "source": [ + "#### Nasza pierwsza klasa" + ] + }, + { + "cell_type": "markdown", + "id": "b3e207bb", + "metadata": {}, + "source": [ + "Klasy oznaczone `@db0.memo` są przechowywane w nieskończonej pamięci dbzero po utworzeniu.\n", + "Wystarczy oznaczyć klasę i zainicjować jej pola wewnątrz metody `__init__`, tak jak w przypadku każdej zwykłej klasy Pythona." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c5a28b7", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo\n", + "class HelloWorld:\n", + " def __init__(self, name):\n", + " self.name = name\n", + " \n", + " def greet(self):\n", + " print(f\"Cześć {self.name}. Witaj w dbzero!!\")" + ] + }, + { + "cell_type": "markdown", + "id": "e85c296f", + "metadata": {}, + "source": [ + "Możesz używać tej klasy tak jak każdej zwykłej klasy Pythona—tworzyć nowe obiekty i wywoływać jej metody." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a8cd5802", + "metadata": {}, + "outputs": [], + "source": [ + "jan = HelloWorld(\"Jan\")" + ] + }, + { + "cell_type": "markdown", + "id": "19966147", + "metadata": {}, + "source": [ + "Dodajemy tag, aby zapobiec usunięciu tego obiektu przez dbzero po zamknięciu procesu. (Omówimy to zachowanie bardziej szczegółowo później.)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8044af92", + "metadata": {}, + "outputs": [], + "source": [ + "db0.tags(jan).add(\"najlepszy przyjaciel\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10a2d421", + "metadata": {}, + "outputs": [], + "source": [ + "jan.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "6cb872ec", + "metadata": {}, + "source": [ + "#### Więc jaka jest różnica?" + ] + }, + { + "cell_type": "markdown", + "id": "7606d58e", + "metadata": {}, + "source": [ + "Klasy **dbzero** żyją w innej przestrzeni pamięci o specjalnych właściwościach DIST:\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "b091d04f", + "metadata": {}, + "source": [ + "#### Jak mogę uzyskać dostęp do obiektu po zamknięciu programu?\n", + "Jednym ze sposobów jest pobranie jego UUID db0, a następnie odwołanie się do niego za pomocą tego ID. Pamiętasz funkcję `id()` Pythona?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bac6f1bb", + "metadata": {}, + "outputs": [], + "source": [ + "id(jan)" + ] + }, + { + "cell_type": "markdown", + "id": "2f19ae02", + "metadata": {}, + "source": [ + "Każdy obiekt **dbzero** ma zarówno ID Pythona (krótkotrwałe), jak i UUID db0 (trwałe do momentu usunięcia obiektu—podobnie jak usunięcie wiersza w bazie danych)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d6a2874", + "metadata": {}, + "outputs": [], + "source": [ + "db0.uuid(jan)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "098bba05", + "metadata": {}, + "outputs": [], + "source": [ + "dir(jan)" + ] + }, + { + "cell_type": "markdown", + "id": "29a1cebe", + "metadata": {}, + "source": [ + "#### Zapamiętajmy to UUID i kontynuujmy w innym notebooku..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bf98853a", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c5fc541c", + "metadata": {}, + "outputs": [], + "source": [ + "dir(jan)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c71491c6", + "metadata": {}, + "outputs": [], + "source": [ + "type(jan)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8c698420", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/.ipynb_checkpoints/hello.db0_1-checkpoint.ipynb b/notebooks/hello/.ipynb_checkpoints/hello.db0_1-checkpoint.ipynb new file mode 100644 index 00000000..1335b5c2 --- /dev/null +++ b/notebooks/hello/.ipynb_checkpoints/hello.db0_1-checkpoint.ipynb @@ -0,0 +1,260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f95d58f5", + "metadata": {}, + "source": [ + "## Introducing dbzero (1/12). Getting started." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31d81a69", + "metadata": {}, + "outputs": [], + "source": [ + "!rm -rf /dbzero\n", + "import dbzero as db0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "02f628c6", + "metadata": {}, + "outputs": [], + "source": [ + "db0.init(dbzero_root=\"/dbzero\", prefix = \"data\")" + ] + }, + { + "cell_type": "markdown", + "id": "60812c5b", + "metadata": {}, + "source": [ + "#### Our first class" + ] + }, + { + "cell_type": "markdown", + "id": "6ca86246", + "metadata": {}, + "source": [ + "Classes marked with @db0.memo after creation will be kept in the dbzero's infinite memory.\n", + "Simply annotate the class and initialize its fields inside the \"__init__\" method just as you'd do with any Python class." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fb50ed27", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo\n", + "class HelloWorld:\n", + " def __init__(self, name):\n", + " self.name = name\n", + " \n", + " def greet(self):\n", + " print(f\"Hello {self.name}. Welcome to dbzero!!\")" + ] + }, + { + "cell_type": "markdown", + "id": "ffc8adc2", + "metadata": {}, + "source": [ + "... and you can use the class just as any regular Python class - e.g. instantiate new objects and call its members." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3c76c92", + "metadata": {}, + "outputs": [], + "source": [ + "john = HelloWorld(\"john\")" + ] + }, + { + "cell_type": "markdown", + "id": "194cb956-61ed-4acc-a8fc-5e197f7a67d3", + "metadata": {}, + "source": [ + "We're adding a tag so that the object is not deleted by dbzero after we close the process (we'll discuss this behaviour later)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2014006f-94ba-4bb8-96a0-a6c0426950ad", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'db0' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mdb0\u001b[49m\u001b[38;5;241m.\u001b[39mtags(john)\u001b[38;5;241m.\u001b[39madd(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mFriends\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "\u001b[0;31mNameError\u001b[0m: name 'db0' is not defined" + ] + } + ], + "source": [ + "db0.tags(john).add(\"best friend\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0b5521dc", + "metadata": {}, + "outputs": [], + "source": [ + "john.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "105d74af", + "metadata": {}, + "source": [ + "#### Ok ..., so what's the difference?" + ] + }, + { + "cell_type": "markdown", + "id": "4f17de79", + "metadata": {}, + "source": [ + "**dbzero** classes live in a different memory space which has some special (DIST) properties:\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "6b23e610", + "metadata": {}, + "source": [ + "#### Let's check this out. So how do I access the object after closing my program?\n", + "One way to do it is to retrieve its db0 UUID and then access (reference) it by this ID. Remember Python's 'id' function?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6004ce3", + "metadata": {}, + "outputs": [], + "source": [ + "id(john)" + ] + }, + { + "cell_type": "markdown", + "id": "8315c56c", + "metadata": {}, + "source": [ + "Each **dbzero** object has its Python id (short lived) but also its db0 UUID (persisted until you decide to delete the object - similarly as deleting a row in a database)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7586d999", + "metadata": {}, + "outputs": [], + "source": [ + "db0.uuid(john)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d326b2e5-10e2-4f9c-8bee-bb492fee99f4", + "metadata": {}, + "outputs": [], + "source": [ + "dir(john)" + ] + }, + { + "cell_type": "markdown", + "id": "feb005c8", + "metadata": {}, + "source": [ + "#### So let's remember this UUID and see you in another notebook ..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52fbeebc", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7ed4bd71", + "metadata": {}, + "outputs": [], + "source": [ + "dir(john)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0bb6af53", + "metadata": {}, + "outputs": [], + "source": [ + "type(john)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c1e7758", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/.ipynb_checkpoints/hello.db0_2-checkpoint.ipynb b/notebooks/hello/.ipynb_checkpoints/hello.db0_2-checkpoint.ipynb new file mode 100644 index 00000000..683c1aed --- /dev/null +++ b/notebooks/hello/.ipynb_checkpoints/hello.db0_2-checkpoint.ipynb @@ -0,0 +1,2303 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "58718db2", + "metadata": {}, + "source": [ + "## Introducing **dbzero** (2/12). Lists, relations and singletons." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "edf34c16", + "metadata": {}, + "outputs": [], + "source": [ + "import dbzero as db0\n", + "db0.init(dbzero_root = \"/dbzero\", prefix=\"data\")" + ] + }, + { + "cell_type": "markdown", + "id": "2231a803", + "metadata": {}, + "source": [ + "We need to define our class again. In a typical Python program we'd just import it from a module." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ec1c2e4c", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo\n", + "class HelloWorld:\n", + " def __init__(self, name):\n", + " self.name = name\n", + " \n", + " def greet(self):\n", + " print(f\"Hello {self.name}. Welcome to dbzero!!\")" + ] + }, + { + "cell_type": "markdown", + "id": "44b004ad", + "metadata": {}, + "source": [ + "And let's open its instance by a priorly generated ID (< paste your ID below >)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "eaa0ed2d", + "metadata": {}, + "outputs": [], + "source": [ + "h = db0.fetch(HelloWorld, \"\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "9409153e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello john. Welcome to dbzero!!\n" + ] + } + ], + "source": [ + "h.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "7a389fa5", + "metadata": {}, + "source": [ + "### Allright, it worked. The instance remembers its data members.\n", + "But pulling by ID does not seem very convenient, how can I access my objects in a more practical way?" + ] + }, + { + "cell_type": "markdown", + "id": "9ee0a339", + "metadata": {}, + "source": [ + "One possibility is to keep references to your objects in a different (parent) object. In the database world such an association would be called a 'relation'. If our intention is to keep only one instance of HelloMany, we can mark it with " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "19c71ee7", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo(singleton = True)\n", + "class HelloMany:\n", + " # we pass a list of names and many HelloWorld instances will be created, then added to 'hellos' DB0 list\n", + " def __init__(self, names):\n", + " self.hellos = [HelloWorld(name) for name in names]\n", + " \n", + " def greet(self):\n", + " for hw in self.hellos:\n", + " hw.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "24da7013", + "metadata": {}, + "source": [ + "Note that the **dbzero** object mof a class marked as ``singleton`` will be only created once." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "21021621", + "metadata": {}, + "outputs": [], + "source": [ + "many_hellos = HelloMany([\"Andrew\", \"Alice\", \"Bob\", \"Frank\", \"Rohan\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "69c51083", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello Andrew. Welcome to dbzero!!\n", + "Hello Alice. Welcome to dbzero!!\n", + "Hello Bob. Welcome to dbzero!!\n", + "Hello Frank. Welcome to dbzero!!\n", + "Hello Rohan. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-298. Welcome to dbzero!!\n", + "Hello name-299. Welcome to dbzero!!\n", + "Hello name-300. Welcome to dbzero!!\n", + "Hello name-301. Welcome to dbzero!!\n", + "Hello name-302. Welcome to dbzero!!\n", + "Hello name-303. Welcome to dbzero!!\n", + "Hello name-304. Welcome to dbzero!!\n", + "Hello name-305. Welcome to dbzero!!\n", + "Hello name-306. Welcome to dbzero!!\n", + "Hello name-307. Welcome to dbzero!!\n", + "Hello name-308. Welcome to dbzero!!\n", + "Hello name-309. Welcome to dbzero!!\n", + "Hello name-310. Welcome to dbzero!!\n", + "Hello name-311. Welcome to dbzero!!\n", + "Hello name-312. Welcome to dbzero!!\n", + "Hello name-313. Welcome to dbzero!!\n", + "Hello name-314. Welcome to dbzero!!\n", + "Hello name-315. Welcome to dbzero!!\n", + "Hello name-316. Welcome to dbzero!!\n", + "Hello name-317. Welcome to dbzero!!\n", + "Hello name-318. Welcome to dbzero!!\n", + "Hello name-319. Welcome to dbzero!!\n", + "Hello name-320. Welcome to dbzero!!\n", + "Hello name-321. Welcome to dbzero!!\n", + "Hello name-322. Welcome to dbzero!!\n", + "Hello name-323. Welcome to dbzero!!\n", + "Hello name-324. Welcome to dbzero!!\n", + "Hello name-325. Welcome to dbzero!!\n", + "Hello name-326. Welcome to dbzero!!\n", + "Hello name-327. Welcome to dbzero!!\n", + "Hello name-328. Welcome to dbzero!!\n", + "Hello name-329. Welcome to dbzero!!\n", + "Hello name-330. Welcome to dbzero!!\n", + "Hello name-331. Welcome to dbzero!!\n", + "Hello name-332. Welcome to dbzero!!\n", + "Hello name-333. Welcome to dbzero!!\n", + "Hello name-334. Welcome to dbzero!!\n", + "Hello name-335. Welcome to dbzero!!\n", + "Hello name-336. Welcome to dbzero!!\n", + "Hello name-337. Welcome to dbzero!!\n", + "Hello name-338. Welcome to dbzero!!\n", + "Hello name-339. Welcome to dbzero!!\n", + "Hello name-340. Welcome to dbzero!!\n", + "Hello name-341. Welcome to dbzero!!\n", + "Hello name-342. Welcome to dbzero!!\n", + "Hello name-343. Welcome to dbzero!!\n", + "Hello name-344. Welcome to dbzero!!\n", + "Hello name-345. Welcome to dbzero!!\n", + "Hello name-346. Welcome to dbzero!!\n", + "Hello name-347. Welcome to dbzero!!\n", + "Hello name-348. Welcome to dbzero!!\n", + "Hello name-349. Welcome to dbzero!!\n", + "Hello name-350. Welcome to dbzero!!\n", + "Hello name-351. Welcome to dbzero!!\n", + "Hello name-352. Welcome to dbzero!!\n", + "Hello name-353. Welcome to dbzero!!\n", + "Hello name-354. Welcome to dbzero!!\n", + "Hello name-355. Welcome to dbzero!!\n", + "Hello name-356. Welcome to dbzero!!\n", + "Hello name-357. Welcome to dbzero!!\n", + "Hello name-358. Welcome to dbzero!!\n", + "Hello name-359. Welcome to dbzero!!\n", + "Hello name-360. Welcome to dbzero!!\n", + "Hello name-361. Welcome to dbzero!!\n", + "Hello name-362. Welcome to dbzero!!\n", + "Hello name-363. Welcome to dbzero!!\n", + "Hello name-364. Welcome to dbzero!!\n", + "Hello name-365. Welcome to dbzero!!\n", + "Hello name-366. Welcome to dbzero!!\n", + "Hello name-367. Welcome to dbzero!!\n", + "Hello name-368. Welcome to dbzero!!\n", + "Hello name-369. Welcome to dbzero!!\n", + "Hello name-370. Welcome to dbzero!!\n", + "Hello name-371. Welcome to dbzero!!\n", + "Hello name-372. Welcome to dbzero!!\n", + "Hello name-373. Welcome to dbzero!!\n", + "Hello name-374. Welcome to dbzero!!\n", + "Hello name-375. Welcome to dbzero!!\n", + "Hello name-376. Welcome to dbzero!!\n", + "Hello name-377. Welcome to dbzero!!\n", + "Hello name-378. Welcome to dbzero!!\n", + "Hello name-379. Welcome to dbzero!!\n", + "Hello name-380. Welcome to dbzero!!\n", + "Hello name-381. Welcome to dbzero!!\n", + "Hello name-382. Welcome to dbzero!!\n", + "Hello name-383. Welcome to dbzero!!\n", + "Hello name-384. Welcome to dbzero!!\n", + "Hello name-385. Welcome to dbzero!!\n", + "Hello name-386. Welcome to dbzero!!\n", + "Hello name-387. Welcome to dbzero!!\n", + "Hello name-388. Welcome to dbzero!!\n", + "Hello name-389. Welcome to dbzero!!\n", + "Hello name-390. Welcome to dbzero!!\n", + "Hello name-391. Welcome to dbzero!!\n", + "Hello name-392. Welcome to dbzero!!\n", + "Hello name-393. Welcome to dbzero!!\n", + "Hello name-394. Welcome to dbzero!!\n", + "Hello name-395. Welcome to dbzero!!\n", + "Hello name-396. Welcome to dbzero!!\n", + "Hello name-397. Welcome to dbzero!!\n", + "Hello name-398. Welcome to dbzero!!\n", + "Hello name-399. Welcome to dbzero!!\n", + "Hello name-400. Welcome to dbzero!!\n", + "Hello name-401. Welcome to dbzero!!\n", + "Hello name-402. Welcome to dbzero!!\n", + "Hello name-403. Welcome to dbzero!!\n", + "Hello name-404. Welcome to dbzero!!\n", + "Hello name-405. Welcome to dbzero!!\n", + "Hello name-406. Welcome to dbzero!!\n", + "Hello name-407. Welcome to dbzero!!\n", + "Hello name-408. Welcome to dbzero!!\n", + "Hello name-409. Welcome to dbzero!!\n", + "Hello name-410. Welcome to dbzero!!\n", + "Hello name-411. Welcome to dbzero!!\n", + "Hello name-412. Welcome to dbzero!!\n", + "Hello name-413. Welcome to dbzero!!\n", + "Hello name-414. Welcome to dbzero!!\n", + "Hello name-415. Welcome to dbzero!!\n", + "Hello name-416. Welcome to dbzero!!\n", + "Hello name-417. Welcome to dbzero!!\n", + "Hello name-418. Welcome to dbzero!!\n", + "Hello name-419. Welcome to dbzero!!\n", + "Hello name-420. Welcome to dbzero!!\n", + "Hello name-421. Welcome to dbzero!!\n", + "Hello name-422. Welcome to dbzero!!\n", + "Hello name-423. Welcome to dbzero!!\n", + "Hello name-424. Welcome to dbzero!!\n", + "Hello name-425. Welcome to dbzero!!\n", + "Hello name-426. Welcome to dbzero!!\n", + "Hello name-427. Welcome to dbzero!!\n", + "Hello name-428. Welcome to dbzero!!\n", + "Hello name-429. Welcome to dbzero!!\n", + "Hello name-430. Welcome to dbzero!!\n", + "Hello name-431. Welcome to dbzero!!\n", + "Hello name-432. Welcome to dbzero!!\n", + "Hello name-433. Welcome to dbzero!!\n", + "Hello name-434. Welcome to dbzero!!\n", + "Hello name-435. Welcome to dbzero!!\n", + "Hello name-436. Welcome to dbzero!!\n", + "Hello name-437. Welcome to dbzero!!\n", + "Hello name-438. Welcome to dbzero!!\n", + "Hello name-439. Welcome to dbzero!!\n", + "Hello name-440. Welcome to dbzero!!\n", + "Hello name-441. Welcome to dbzero!!\n", + "Hello name-442. Welcome to dbzero!!\n", + "Hello name-443. Welcome to dbzero!!\n", + "Hello name-444. Welcome to dbzero!!\n", + "Hello name-445. Welcome to dbzero!!\n", + "Hello name-446. Welcome to dbzero!!\n", + "Hello name-447. Welcome to dbzero!!\n", + "Hello name-448. Welcome to dbzero!!\n", + "Hello name-449. Welcome to dbzero!!\n", + "Hello name-450. Welcome to dbzero!!\n", + "Hello name-451. Welcome to dbzero!!\n", + "Hello name-452. Welcome to dbzero!!\n", + "Hello name-453. Welcome to dbzero!!\n", + "Hello name-454. Welcome to dbzero!!\n", + "Hello name-455. Welcome to dbzero!!\n", + "Hello name-456. Welcome to dbzero!!\n", + "Hello name-457. Welcome to dbzero!!\n", + "Hello name-458. Welcome to dbzero!!\n", + "Hello name-459. Welcome to dbzero!!\n", + "Hello name-460. Welcome to dbzero!!\n", + "Hello name-461. Welcome to dbzero!!\n", + "Hello name-462. Welcome to dbzero!!\n", + "Hello name-463. Welcome to dbzero!!\n", + "Hello name-464. Welcome to dbzero!!\n", + "Hello name-465. Welcome to dbzero!!\n", + "Hello name-466. Welcome to dbzero!!\n", + "Hello name-467. Welcome to dbzero!!\n", + "Hello name-468. Welcome to dbzero!!\n", + "Hello name-469. Welcome to dbzero!!\n", + "Hello name-470. Welcome to dbzero!!\n", + "Hello name-471. Welcome to dbzero!!\n", + "Hello name-472. Welcome to dbzero!!\n", + "Hello name-473. Welcome to dbzero!!\n", + "Hello name-474. Welcome to dbzero!!\n", + "Hello name-475. Welcome to dbzero!!\n", + "Hello name-476. Welcome to dbzero!!\n", + "Hello name-477. Welcome to dbzero!!\n", + "Hello name-478. Welcome to dbzero!!\n", + "Hello name-479. Welcome to dbzero!!\n", + "Hello name-480. Welcome to dbzero!!\n", + "Hello name-481. Welcome to dbzero!!\n", + "Hello name-482. Welcome to dbzero!!\n", + "Hello name-483. Welcome to dbzero!!\n", + "Hello name-484. Welcome to dbzero!!\n", + "Hello name-485. Welcome to dbzero!!\n", + "Hello name-486. Welcome to dbzero!!\n", + "Hello name-487. Welcome to dbzero!!\n", + "Hello name-488. Welcome to dbzero!!\n", + "Hello name-489. Welcome to dbzero!!\n", + "Hello name-490. Welcome to dbzero!!\n", + "Hello name-491. Welcome to dbzero!!\n", + "Hello name-492. Welcome to dbzero!!\n", + "Hello name-493. Welcome to dbzero!!\n", + "Hello name-494. Welcome to dbzero!!\n", + "Hello name-495. Welcome to dbzero!!\n", + "Hello name-496. Welcome to dbzero!!\n", + "Hello name-497. Welcome to dbzero!!\n", + "Hello name-498. Welcome to dbzero!!\n", + "Hello name-499. Welcome to dbzero!!\n", + "Hello name-500. Welcome to dbzero!!\n", + "Hello name-501. Welcome to dbzero!!\n", + "Hello name-502. Welcome to dbzero!!\n", + "Hello name-503. Welcome to dbzero!!\n", + "Hello name-504. Welcome to dbzero!!\n", + "Hello name-505. Welcome to dbzero!!\n", + "Hello name-506. Welcome to dbzero!!\n", + "Hello name-507. Welcome to dbzero!!\n", + "Hello name-508. Welcome to dbzero!!\n", + "Hello name-509. Welcome to dbzero!!\n", + "Hello name-510. Welcome to dbzero!!\n", + "Hello name-511. Welcome to dbzero!!\n", + "Hello name-512. Welcome to dbzero!!\n", + "Hello name-513. Welcome to dbzero!!\n", + "Hello name-514. Welcome to dbzero!!\n", + "Hello name-515. Welcome to dbzero!!\n", + "Hello name-516. Welcome to dbzero!!\n", + "Hello name-517. Welcome to dbzero!!\n", + "Hello name-518. Welcome to dbzero!!\n", + "Hello name-519. Welcome to dbzero!!\n", + "Hello name-520. Welcome to dbzero!!\n", + "Hello name-521. Welcome to dbzero!!\n", + "Hello name-522. Welcome to dbzero!!\n", + "Hello name-523. Welcome to dbzero!!\n", + "Hello name-524. Welcome to dbzero!!\n", + "Hello name-525. Welcome to dbzero!!\n", + "Hello name-526. Welcome to dbzero!!\n", + "Hello name-527. Welcome to dbzero!!\n", + "Hello name-528. Welcome to dbzero!!\n", + "Hello name-529. Welcome to dbzero!!\n", + "Hello name-530. Welcome to dbzero!!\n", + "Hello name-531. Welcome to dbzero!!\n", + "Hello name-532. Welcome to dbzero!!\n", + "Hello name-533. Welcome to dbzero!!\n", + "Hello name-534. Welcome to dbzero!!\n", + "Hello name-535. Welcome to dbzero!!\n", + "Hello name-536. Welcome to dbzero!!\n", + "Hello name-537. Welcome to dbzero!!\n", + "Hello name-538. Welcome to dbzero!!\n", + "Hello name-539. Welcome to dbzero!!\n", + "Hello name-540. Welcome to dbzero!!\n", + "Hello name-541. Welcome to dbzero!!\n", + "Hello name-542. Welcome to dbzero!!\n", + "Hello name-543. Welcome to dbzero!!\n", + "Hello name-544. Welcome to dbzero!!\n", + "Hello name-545. Welcome to dbzero!!\n", + "Hello name-546. Welcome to dbzero!!\n", + "Hello name-547. Welcome to dbzero!!\n", + "Hello name-548. Welcome to dbzero!!\n", + "Hello name-549. Welcome to dbzero!!\n", + "Hello name-550. Welcome to dbzero!!\n", + "Hello name-551. Welcome to dbzero!!\n", + "Hello name-552. Welcome to dbzero!!\n", + "Hello name-553. Welcome to dbzero!!\n", + "Hello name-554. Welcome to dbzero!!\n", + "Hello name-555. Welcome to dbzero!!\n", + "Hello name-556. Welcome to dbzero!!\n", + "Hello name-557. Welcome to dbzero!!\n", + "Hello name-558. Welcome to dbzero!!\n", + "Hello name-559. Welcome to dbzero!!\n", + "Hello name-560. Welcome to dbzero!!\n", + "Hello name-561. Welcome to dbzero!!\n", + "Hello name-562. Welcome to dbzero!!\n", + "Hello name-563. Welcome to dbzero!!\n", + "Hello name-564. Welcome to dbzero!!\n", + "Hello name-565. Welcome to dbzero!!\n", + "Hello name-566. Welcome to dbzero!!\n", + "Hello name-567. Welcome to dbzero!!\n", + "Hello name-568. Welcome to dbzero!!\n", + "Hello name-569. Welcome to dbzero!!\n", + "Hello name-570. Welcome to dbzero!!\n", + "Hello name-571. Welcome to dbzero!!\n", + "Hello name-572. Welcome to dbzero!!\n", + "Hello name-573. Welcome to dbzero!!\n", + "Hello name-574. Welcome to dbzero!!\n", + "Hello name-575. Welcome to dbzero!!\n", + "Hello name-576. Welcome to dbzero!!\n", + "Hello name-577. Welcome to dbzero!!\n", + "Hello name-578. Welcome to dbzero!!\n", + "Hello name-579. Welcome to dbzero!!\n", + "Hello name-580. Welcome to dbzero!!\n", + "Hello name-581. Welcome to dbzero!!\n", + "Hello name-582. Welcome to dbzero!!\n", + "Hello name-583. Welcome to dbzero!!\n", + "Hello name-584. Welcome to dbzero!!\n", + "Hello name-585. Welcome to dbzero!!\n", + "Hello name-586. Welcome to dbzero!!\n", + "Hello name-587. Welcome to dbzero!!\n", + "Hello name-588. Welcome to dbzero!!\n", + "Hello name-589. Welcome to dbzero!!\n", + "Hello name-590. Welcome to dbzero!!\n", + "Hello name-591. Welcome to dbzero!!\n", + "Hello name-592. Welcome to dbzero!!\n", + "Hello name-593. Welcome to dbzero!!\n", + "Hello name-594. Welcome to dbzero!!\n", + "Hello name-595. Welcome to dbzero!!\n", + "Hello name-596. Welcome to dbzero!!\n", + "Hello name-597. Welcome to dbzero!!\n", + "Hello name-598. Welcome to dbzero!!\n", + "Hello name-599. Welcome to dbzero!!\n", + "Hello name-600. Welcome to dbzero!!\n", + "Hello name-601. Welcome to dbzero!!\n", + "Hello name-602. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-603. Welcome to dbzero!!\n", + "Hello name-604. Welcome to dbzero!!\n", + "Hello name-605. Welcome to dbzero!!\n", + "Hello name-606. Welcome to dbzero!!\n", + "Hello name-607. Welcome to dbzero!!\n", + "Hello name-608. Welcome to dbzero!!\n", + "Hello name-609. Welcome to dbzero!!\n", + "Hello name-610. Welcome to dbzero!!\n", + "Hello name-611. Welcome to dbzero!!\n", + "Hello name-612. Welcome to dbzero!!\n", + "Hello name-613. Welcome to dbzero!!\n", + "Hello name-614. Welcome to dbzero!!\n", + "Hello name-615. Welcome to dbzero!!\n", + "Hello name-616. Welcome to dbzero!!\n", + "Hello name-617. Welcome to dbzero!!\n", + "Hello name-618. Welcome to dbzero!!\n", + "Hello name-619. Welcome to dbzero!!\n", + "Hello name-620. Welcome to dbzero!!\n", + "Hello name-621. Welcome to dbzero!!\n", + "Hello name-622. Welcome to dbzero!!\n", + "Hello name-623. Welcome to dbzero!!\n", + "Hello name-624. Welcome to dbzero!!\n", + "Hello name-625. Welcome to dbzero!!\n", + "Hello name-626. Welcome to dbzero!!\n", + "Hello name-627. Welcome to dbzero!!\n", + "Hello name-628. Welcome to dbzero!!\n", + "Hello name-629. Welcome to dbzero!!\n", + "Hello name-630. Welcome to dbzero!!\n", + "Hello name-631. Welcome to dbzero!!\n", + "Hello name-632. Welcome to dbzero!!\n", + "Hello name-633. Welcome to dbzero!!\n", + "Hello name-634. Welcome to dbzero!!\n", + "Hello name-635. Welcome to dbzero!!\n", + "Hello name-636. Welcome to dbzero!!\n", + "Hello name-637. Welcome to dbzero!!\n", + "Hello name-638. Welcome to dbzero!!\n", + "Hello name-639. Welcome to dbzero!!\n", + "Hello name-640. Welcome to dbzero!!\n", + "Hello name-641. Welcome to dbzero!!\n", + "Hello name-642. Welcome to dbzero!!\n", + "Hello name-643. Welcome to dbzero!!\n", + "Hello name-644. Welcome to dbzero!!\n", + "Hello name-645. Welcome to dbzero!!\n", + "Hello name-646. Welcome to dbzero!!\n", + "Hello name-647. Welcome to dbzero!!\n", + "Hello name-648. Welcome to dbzero!!\n", + "Hello name-649. Welcome to dbzero!!\n", + "Hello name-650. Welcome to dbzero!!\n", + "Hello name-651. Welcome to dbzero!!\n", + "Hello name-652. Welcome to dbzero!!\n", + "Hello name-653. Welcome to dbzero!!\n", + "Hello name-654. Welcome to dbzero!!\n", + "Hello name-655. Welcome to dbzero!!\n", + "Hello name-656. Welcome to dbzero!!\n", + "Hello name-657. Welcome to dbzero!!\n", + "Hello name-658. Welcome to dbzero!!\n", + "Hello name-659. Welcome to dbzero!!\n", + "Hello name-660. Welcome to dbzero!!\n", + "Hello name-661. Welcome to dbzero!!\n", + "Hello name-662. Welcome to dbzero!!\n", + "Hello name-663. Welcome to dbzero!!\n", + "Hello name-664. Welcome to dbzero!!\n", + "Hello name-665. Welcome to dbzero!!\n", + "Hello name-666. Welcome to dbzero!!\n", + "Hello name-667. Welcome to dbzero!!\n", + "Hello name-668. Welcome to dbzero!!\n", + "Hello name-669. Welcome to dbzero!!\n", + "Hello name-670. Welcome to dbzero!!\n", + "Hello name-671. Welcome to dbzero!!\n", + "Hello name-672. Welcome to dbzero!!\n", + "Hello name-673. Welcome to dbzero!!\n", + "Hello name-674. Welcome to dbzero!!\n", + "Hello name-675. Welcome to dbzero!!\n", + "Hello name-676. Welcome to dbzero!!\n", + "Hello name-677. Welcome to dbzero!!\n", + "Hello name-678. Welcome to dbzero!!\n", + "Hello name-679. Welcome to dbzero!!\n", + "Hello name-680. Welcome to dbzero!!\n", + "Hello name-681. Welcome to dbzero!!\n", + "Hello name-682. Welcome to dbzero!!\n", + "Hello name-683. Welcome to dbzero!!\n", + "Hello name-684. Welcome to dbzero!!\n", + "Hello name-685. Welcome to dbzero!!\n", + "Hello name-686. Welcome to dbzero!!\n", + "Hello name-687. Welcome to dbzero!!\n", + "Hello name-688. Welcome to dbzero!!\n", + "Hello name-689. Welcome to dbzero!!\n", + "Hello name-690. Welcome to dbzero!!\n", + "Hello name-691. Welcome to dbzero!!\n", + "Hello name-692. Welcome to dbzero!!\n", + "Hello name-693. Welcome to dbzero!!\n", + "Hello name-694. Welcome to dbzero!!\n", + "Hello name-695. Welcome to dbzero!!\n", + "Hello name-696. Welcome to dbzero!!\n", + "Hello name-697. Welcome to dbzero!!\n", + "Hello name-698. Welcome to dbzero!!\n", + "Hello name-699. Welcome to dbzero!!\n", + "Hello name-700. Welcome to dbzero!!\n", + "Hello name-701. Welcome to dbzero!!\n", + "Hello name-702. Welcome to dbzero!!\n", + "Hello name-703. Welcome to dbzero!!\n", + "Hello name-704. Welcome to dbzero!!\n", + "Hello name-705. Welcome to dbzero!!\n", + "Hello name-706. Welcome to dbzero!!\n", + "Hello name-707. Welcome to dbzero!!\n", + "Hello name-708. Welcome to dbzero!!\n", + "Hello name-709. Welcome to dbzero!!\n", + "Hello name-710. Welcome to dbzero!!\n", + "Hello name-711. Welcome to dbzero!!\n", + "Hello name-712. Welcome to dbzero!!\n", + "Hello name-713. Welcome to dbzero!!\n", + "Hello name-714. Welcome to dbzero!!\n", + "Hello name-715. Welcome to dbzero!!\n", + "Hello name-716. Welcome to dbzero!!\n", + "Hello name-717. Welcome to dbzero!!\n", + "Hello name-718. Welcome to dbzero!!\n", + "Hello name-719. Welcome to dbzero!!\n", + "Hello name-720. Welcome to dbzero!!\n", + "Hello name-721. Welcome to dbzero!!\n", + "Hello name-722. Welcome to dbzero!!\n", + "Hello name-723. Welcome to dbzero!!\n", + "Hello name-724. Welcome to dbzero!!\n", + "Hello name-725. Welcome to dbzero!!\n", + "Hello name-726. Welcome to dbzero!!\n", + "Hello name-727. Welcome to dbzero!!\n", + "Hello name-728. Welcome to dbzero!!\n", + "Hello name-729. Welcome to dbzero!!\n", + "Hello name-730. Welcome to dbzero!!\n", + "Hello name-731. Welcome to dbzero!!\n", + "Hello name-732. Welcome to dbzero!!\n", + "Hello name-733. Welcome to dbzero!!\n", + "Hello name-734. Welcome to dbzero!!\n", + "Hello name-735. Welcome to dbzero!!\n", + "Hello name-736. Welcome to dbzero!!\n", + "Hello name-737. Welcome to dbzero!!\n", + "Hello name-738. Welcome to dbzero!!\n", + "Hello name-739. Welcome to dbzero!!\n", + "Hello name-740. Welcome to dbzero!!\n", + "Hello name-741. Welcome to dbzero!!\n", + "Hello name-742. Welcome to dbzero!!\n", + "Hello name-743. Welcome to dbzero!!\n", + "Hello name-744. Welcome to dbzero!!\n", + "Hello name-745. Welcome to dbzero!!\n", + "Hello name-746. Welcome to dbzero!!\n", + "Hello name-747. Welcome to dbzero!!\n", + "Hello name-748. Welcome to dbzero!!\n", + "Hello name-749. Welcome to dbzero!!\n", + "Hello name-750. Welcome to dbzero!!\n", + "Hello name-751. Welcome to dbzero!!\n", + "Hello name-752. Welcome to dbzero!!\n", + "Hello name-753. Welcome to dbzero!!\n", + "Hello name-754. Welcome to dbzero!!\n", + "Hello name-755. Welcome to dbzero!!\n", + "Hello name-756. Welcome to dbzero!!\n", + "Hello name-757. Welcome to dbzero!!\n", + "Hello name-758. Welcome to dbzero!!\n", + "Hello name-759. Welcome to dbzero!!\n", + "Hello name-760. Welcome to dbzero!!\n", + "Hello name-761. Welcome to dbzero!!\n", + "Hello name-762. Welcome to dbzero!!\n", + "Hello name-763. Welcome to dbzero!!\n", + "Hello name-764. Welcome to dbzero!!\n", + "Hello name-765. Welcome to dbzero!!\n", + "Hello name-766. Welcome to dbzero!!\n", + "Hello name-767. Welcome to dbzero!!\n", + "Hello name-768. Welcome to dbzero!!\n", + "Hello name-769. Welcome to dbzero!!\n", + "Hello name-770. Welcome to dbzero!!\n", + "Hello name-771. Welcome to dbzero!!\n", + "Hello name-772. Welcome to dbzero!!\n", + "Hello name-773. Welcome to dbzero!!\n", + "Hello name-774. Welcome to dbzero!!\n", + "Hello name-775. Welcome to dbzero!!\n", + "Hello name-776. Welcome to dbzero!!\n", + "Hello name-777. Welcome to dbzero!!\n", + "Hello name-778. Welcome to dbzero!!\n", + "Hello name-779. Welcome to dbzero!!\n", + "Hello name-780. Welcome to dbzero!!\n", + "Hello name-781. Welcome to dbzero!!\n", + "Hello name-782. Welcome to dbzero!!\n", + "Hello name-783. Welcome to dbzero!!\n", + "Hello name-784. Welcome to dbzero!!\n", + "Hello name-785. Welcome to dbzero!!\n", + "Hello name-786. Welcome to dbzero!!\n", + "Hello name-787. Welcome to dbzero!!\n", + "Hello name-788. Welcome to dbzero!!\n", + "Hello name-789. Welcome to dbzero!!\n", + "Hello name-790. Welcome to dbzero!!\n", + "Hello name-791. Welcome to dbzero!!\n", + "Hello name-792. Welcome to dbzero!!\n", + "Hello name-793. Welcome to dbzero!!\n", + "Hello name-794. Welcome to dbzero!!\n", + "Hello name-795. Welcome to dbzero!!\n", + "Hello name-796. Welcome to dbzero!!\n", + "Hello name-797. Welcome to dbzero!!\n", + "Hello name-798. Welcome to dbzero!!\n", + "Hello name-799. Welcome to dbzero!!\n", + "Hello name-800. Welcome to dbzero!!\n", + "Hello name-801. Welcome to dbzero!!\n", + "Hello name-802. Welcome to dbzero!!\n", + "Hello name-803. Welcome to dbzero!!\n", + "Hello name-804. Welcome to dbzero!!\n", + "Hello name-805. Welcome to dbzero!!\n", + "Hello name-806. Welcome to dbzero!!\n", + "Hello name-807. Welcome to dbzero!!\n", + "Hello name-808. Welcome to dbzero!!\n", + "Hello name-809. Welcome to dbzero!!\n", + "Hello name-810. Welcome to dbzero!!\n", + "Hello name-811. Welcome to dbzero!!\n", + "Hello name-812. Welcome to dbzero!!\n", + "Hello name-813. Welcome to dbzero!!\n", + "Hello name-814. Welcome to dbzero!!\n", + "Hello name-815. Welcome to dbzero!!\n", + "Hello name-816. Welcome to dbzero!!\n", + "Hello name-817. Welcome to dbzero!!\n", + "Hello name-818. Welcome to dbzero!!\n", + "Hello name-819. Welcome to dbzero!!\n", + "Hello name-820. Welcome to dbzero!!\n", + "Hello name-821. Welcome to dbzero!!\n", + "Hello name-822. Welcome to dbzero!!\n", + "Hello name-823. Welcome to dbzero!!\n", + "Hello name-824. Welcome to dbzero!!\n", + "Hello name-825. Welcome to dbzero!!\n", + "Hello name-826. Welcome to dbzero!!\n", + "Hello name-827. Welcome to dbzero!!\n", + "Hello name-828. Welcome to dbzero!!\n", + "Hello name-829. Welcome to dbzero!!\n", + "Hello name-830. Welcome to dbzero!!\n", + "Hello name-831. Welcome to dbzero!!\n", + "Hello name-832. Welcome to dbzero!!\n", + "Hello name-833. Welcome to dbzero!!\n", + "Hello name-834. Welcome to dbzero!!\n", + "Hello name-835. Welcome to dbzero!!\n", + "Hello name-836. Welcome to dbzero!!\n", + "Hello name-837. Welcome to dbzero!!\n", + "Hello name-838. Welcome to dbzero!!\n", + "Hello name-839. Welcome to dbzero!!\n", + "Hello name-840. Welcome to dbzero!!\n", + "Hello name-841. Welcome to dbzero!!\n", + "Hello name-842. Welcome to dbzero!!\n", + "Hello name-843. Welcome to dbzero!!\n", + "Hello name-844. Welcome to dbzero!!\n", + "Hello name-845. Welcome to dbzero!!\n", + "Hello name-846. Welcome to dbzero!!\n", + "Hello name-847. Welcome to dbzero!!\n", + "Hello name-848. Welcome to dbzero!!\n", + "Hello name-849. Welcome to dbzero!!\n", + "Hello name-850. Welcome to dbzero!!\n", + "Hello name-851. Welcome to dbzero!!\n", + "Hello name-852. Welcome to dbzero!!\n", + "Hello name-853. Welcome to dbzero!!\n", + "Hello name-854. Welcome to dbzero!!\n", + "Hello name-855. Welcome to dbzero!!\n", + "Hello name-856. Welcome to dbzero!!\n", + "Hello name-857. Welcome to dbzero!!\n", + "Hello name-858. Welcome to dbzero!!\n", + "Hello name-859. Welcome to dbzero!!\n", + "Hello name-860. Welcome to dbzero!!\n", + "Hello name-861. Welcome to dbzero!!\n", + "Hello name-862. Welcome to dbzero!!\n", + "Hello name-863. Welcome to dbzero!!\n", + "Hello name-864. Welcome to dbzero!!\n", + "Hello name-865. Welcome to dbzero!!\n", + "Hello name-866. Welcome to dbzero!!\n", + "Hello name-867. Welcome to dbzero!!\n", + "Hello name-868. Welcome to dbzero!!\n", + "Hello name-869. Welcome to dbzero!!\n", + "Hello name-870. Welcome to dbzero!!\n", + "Hello name-871. Welcome to dbzero!!\n", + "Hello name-872. Welcome to dbzero!!\n", + "Hello name-873. Welcome to dbzero!!\n", + "Hello name-874. Welcome to dbzero!!\n", + "Hello name-875. Welcome to dbzero!!\n", + "Hello name-876. Welcome to dbzero!!\n", + "Hello name-877. Welcome to dbzero!!\n", + "Hello name-878. Welcome to dbzero!!\n", + "Hello name-879. Welcome to dbzero!!\n", + "Hello name-880. Welcome to dbzero!!\n", + "Hello name-881. Welcome to dbzero!!\n", + "Hello name-882. Welcome to dbzero!!\n", + "Hello name-883. Welcome to dbzero!!\n", + "Hello name-884. Welcome to dbzero!!\n", + "Hello name-885. Welcome to dbzero!!\n", + "Hello name-886. Welcome to dbzero!!\n", + "Hello name-887. Welcome to dbzero!!\n", + "Hello name-888. Welcome to dbzero!!\n", + "Hello name-889. Welcome to dbzero!!\n", + "Hello name-890. Welcome to dbzero!!\n", + "Hello name-891. Welcome to dbzero!!\n", + "Hello name-892. Welcome to dbzero!!\n", + "Hello name-893. Welcome to dbzero!!\n", + "Hello name-894. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-895. Welcome to dbzero!!\n", + "Hello name-896. Welcome to dbzero!!\n", + "Hello name-897. Welcome to dbzero!!\n", + "Hello name-898. Welcome to dbzero!!\n", + "Hello name-899. Welcome to dbzero!!\n", + "Hello name-900. Welcome to dbzero!!\n", + "Hello name-901. Welcome to dbzero!!\n", + "Hello name-902. Welcome to dbzero!!\n", + "Hello name-903. Welcome to dbzero!!\n", + "Hello name-904. Welcome to dbzero!!\n", + "Hello name-905. Welcome to dbzero!!\n", + "Hello name-906. Welcome to dbzero!!\n", + "Hello name-907. Welcome to dbzero!!\n", + "Hello name-908. Welcome to dbzero!!\n", + "Hello name-909. Welcome to dbzero!!\n", + "Hello name-910. Welcome to dbzero!!\n", + "Hello name-911. Welcome to dbzero!!\n", + "Hello name-912. Welcome to dbzero!!\n", + "Hello name-913. Welcome to dbzero!!\n", + "Hello name-914. Welcome to dbzero!!\n", + "Hello name-915. Welcome to dbzero!!\n", + "Hello name-916. Welcome to dbzero!!\n", + "Hello name-917. Welcome to dbzero!!\n", + "Hello name-918. Welcome to dbzero!!\n", + "Hello name-919. Welcome to dbzero!!\n", + "Hello name-920. Welcome to dbzero!!\n", + "Hello name-921. Welcome to dbzero!!\n", + "Hello name-922. Welcome to dbzero!!\n", + "Hello name-923. Welcome to dbzero!!\n", + "Hello name-924. Welcome to dbzero!!\n", + "Hello name-925. Welcome to dbzero!!\n", + "Hello name-926. Welcome to dbzero!!\n", + "Hello name-927. Welcome to dbzero!!\n", + "Hello name-928. Welcome to dbzero!!\n", + "Hello name-929. Welcome to dbzero!!\n", + "Hello name-930. Welcome to dbzero!!\n", + "Hello name-931. Welcome to dbzero!!\n", + "Hello name-932. Welcome to dbzero!!\n", + "Hello name-933. Welcome to dbzero!!\n", + "Hello name-934. Welcome to dbzero!!\n", + "Hello name-935. Welcome to dbzero!!\n", + "Hello name-936. Welcome to dbzero!!\n", + "Hello name-937. Welcome to dbzero!!\n", + "Hello name-938. Welcome to dbzero!!\n", + "Hello name-939. Welcome to dbzero!!\n", + "Hello name-940. Welcome to dbzero!!\n", + "Hello name-941. Welcome to dbzero!!\n", + "Hello name-942. Welcome to dbzero!!\n", + "Hello name-943. Welcome to dbzero!!\n", + "Hello name-944. Welcome to dbzero!!\n", + "Hello name-945. Welcome to dbzero!!\n", + "Hello name-946. Welcome to dbzero!!\n", + "Hello name-947. Welcome to dbzero!!\n", + "Hello name-948. Welcome to dbzero!!\n", + "Hello name-949. Welcome to dbzero!!\n", + "Hello name-950. Welcome to dbzero!!\n", + "Hello name-951. Welcome to dbzero!!\n", + "Hello name-952. Welcome to dbzero!!\n", + "Hello name-953. Welcome to dbzero!!\n", + "Hello name-954. Welcome to dbzero!!\n", + "Hello name-955. Welcome to dbzero!!\n", + "Hello name-956. Welcome to dbzero!!\n", + "Hello name-957. Welcome to dbzero!!\n", + "Hello name-958. Welcome to dbzero!!\n", + "Hello name-959. Welcome to dbzero!!\n", + "Hello name-960. Welcome to dbzero!!\n", + "Hello name-961. Welcome to dbzero!!\n", + "Hello name-962. Welcome to dbzero!!\n", + "Hello name-963. Welcome to dbzero!!\n", + "Hello name-964. Welcome to dbzero!!\n", + "Hello name-965. Welcome to dbzero!!\n", + "Hello name-966. Welcome to dbzero!!\n", + "Hello name-967. Welcome to dbzero!!\n", + "Hello name-968. Welcome to dbzero!!\n", + "Hello name-969. Welcome to dbzero!!\n", + "Hello name-970. Welcome to dbzero!!\n", + "Hello name-971. Welcome to dbzero!!\n", + "Hello name-972. Welcome to dbzero!!\n", + "Hello name-973. Welcome to dbzero!!\n", + "Hello name-974. Welcome to dbzero!!\n", + "Hello name-975. Welcome to dbzero!!\n", + "Hello name-976. Welcome to dbzero!!\n", + "Hello name-977. Welcome to dbzero!!\n", + "Hello name-978. Welcome to dbzero!!\n", + "Hello name-979. Welcome to dbzero!!\n", + "Hello name-980. Welcome to dbzero!!\n", + "Hello name-981. Welcome to dbzero!!\n", + "Hello name-982. Welcome to dbzero!!\n", + "Hello name-983. Welcome to dbzero!!\n", + "Hello name-984. Welcome to dbzero!!\n", + "Hello name-985. Welcome to dbzero!!\n", + "Hello name-986. Welcome to dbzero!!\n", + "Hello name-987. Welcome to dbzero!!\n", + "Hello name-988. Welcome to dbzero!!\n", + "Hello name-989. Welcome to dbzero!!\n", + "Hello name-990. Welcome to dbzero!!\n", + "Hello name-991. Welcome to dbzero!!\n", + "Hello name-992. Welcome to dbzero!!\n", + "Hello name-993. Welcome to dbzero!!\n", + "Hello name-994. Welcome to dbzero!!\n", + "Hello name-995. Welcome to dbzero!!\n", + "Hello name-996. Welcome to dbzero!!\n", + "Hello name-997. Welcome to dbzero!!\n", + "Hello name-998. Welcome to dbzero!!\n", + "Hello name-999. Welcome to dbzero!!\n" + ] + } + ], + "source": [ + "many_hellos.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "abfbf9aa", + "metadata": {}, + "source": [ + "Once instantiated, the object can be accessed again (from other program or after closing this program) without any arguments." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "997e5acb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello Andrew. Welcome to dbzero!!\n", + "Hello Alice. Welcome to dbzero!!\n", + "Hello Bob. Welcome to dbzero!!\n", + "Hello Frank. Welcome to dbzero!!\n", + "Hello Rohan. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-314. Welcome to dbzero!!\n", + "Hello name-315. Welcome to dbzero!!\n", + "Hello name-316. Welcome to dbzero!!\n", + "Hello name-317. Welcome to dbzero!!\n", + "Hello name-318. Welcome to dbzero!!\n", + "Hello name-319. Welcome to dbzero!!\n", + "Hello name-320. Welcome to dbzero!!\n", + "Hello name-321. Welcome to dbzero!!\n", + "Hello name-322. Welcome to dbzero!!\n", + "Hello name-323. Welcome to dbzero!!\n", + "Hello name-324. Welcome to dbzero!!\n", + "Hello name-325. Welcome to dbzero!!\n", + "Hello name-326. Welcome to dbzero!!\n", + "Hello name-327. Welcome to dbzero!!\n", + "Hello name-328. Welcome to dbzero!!\n", + "Hello name-329. Welcome to dbzero!!\n", + "Hello name-330. Welcome to dbzero!!\n", + "Hello name-331. Welcome to dbzero!!\n", + "Hello name-332. Welcome to dbzero!!\n", + "Hello name-333. Welcome to dbzero!!\n", + "Hello name-334. Welcome to dbzero!!\n", + "Hello name-335. Welcome to dbzero!!\n", + "Hello name-336. Welcome to dbzero!!\n", + "Hello name-337. Welcome to dbzero!!\n", + "Hello name-338. Welcome to dbzero!!\n", + "Hello name-339. Welcome to dbzero!!\n", + "Hello name-340. Welcome to dbzero!!\n", + "Hello name-341. Welcome to dbzero!!\n", + "Hello name-342. Welcome to dbzero!!\n", + "Hello name-343. Welcome to dbzero!!\n", + "Hello name-344. Welcome to dbzero!!\n", + "Hello name-345. Welcome to dbzero!!\n", + "Hello name-346. Welcome to dbzero!!\n", + "Hello name-347. Welcome to dbzero!!\n", + "Hello name-348. Welcome to dbzero!!\n", + "Hello name-349. Welcome to dbzero!!\n", + "Hello name-350. Welcome to dbzero!!\n", + "Hello name-351. Welcome to dbzero!!\n", + "Hello name-352. Welcome to dbzero!!\n", + "Hello name-353. Welcome to dbzero!!\n", + "Hello name-354. Welcome to dbzero!!\n", + "Hello name-355. Welcome to dbzero!!\n", + "Hello name-356. Welcome to dbzero!!\n", + "Hello name-357. Welcome to dbzero!!\n", + "Hello name-358. Welcome to dbzero!!\n", + "Hello name-359. Welcome to dbzero!!\n", + "Hello name-360. Welcome to dbzero!!\n", + "Hello name-361. Welcome to dbzero!!\n", + "Hello name-362. Welcome to dbzero!!\n", + "Hello name-363. Welcome to dbzero!!\n", + "Hello name-364. Welcome to dbzero!!\n", + "Hello name-365. Welcome to dbzero!!\n", + "Hello name-366. Welcome to dbzero!!\n", + "Hello name-367. Welcome to dbzero!!\n", + "Hello name-368. Welcome to dbzero!!\n", + "Hello name-369. Welcome to dbzero!!\n", + "Hello name-370. Welcome to dbzero!!\n", + "Hello name-371. Welcome to dbzero!!\n", + "Hello name-372. Welcome to dbzero!!\n", + "Hello name-373. Welcome to dbzero!!\n", + "Hello name-374. Welcome to dbzero!!\n", + "Hello name-375. Welcome to dbzero!!\n", + "Hello name-376. Welcome to dbzero!!\n", + "Hello name-377. Welcome to dbzero!!\n", + "Hello name-378. Welcome to dbzero!!\n", + "Hello name-379. Welcome to dbzero!!\n", + "Hello name-380. Welcome to dbzero!!\n", + "Hello name-381. Welcome to dbzero!!\n", + "Hello name-382. Welcome to dbzero!!\n", + "Hello name-383. Welcome to dbzero!!\n", + "Hello name-384. Welcome to dbzero!!\n", + "Hello name-385. Welcome to dbzero!!\n", + "Hello name-386. Welcome to dbzero!!\n", + "Hello name-387. Welcome to dbzero!!\n", + "Hello name-388. Welcome to dbzero!!\n", + "Hello name-389. Welcome to dbzero!!\n", + "Hello name-390. Welcome to dbzero!!\n", + "Hello name-391. Welcome to dbzero!!\n", + "Hello name-392. Welcome to dbzero!!\n", + "Hello name-393. Welcome to dbzero!!\n", + "Hello name-394. Welcome to dbzero!!\n", + "Hello name-395. Welcome to dbzero!!\n", + "Hello name-396. Welcome to dbzero!!\n", + "Hello name-397. Welcome to dbzero!!\n", + "Hello name-398. Welcome to dbzero!!\n", + "Hello name-399. Welcome to dbzero!!\n", + "Hello name-400. Welcome to dbzero!!\n", + "Hello name-401. Welcome to dbzero!!\n", + "Hello name-402. Welcome to dbzero!!\n", + "Hello name-403. Welcome to dbzero!!\n", + "Hello name-404. Welcome to dbzero!!\n", + "Hello name-405. Welcome to dbzero!!\n", + "Hello name-406. Welcome to dbzero!!\n", + "Hello name-407. Welcome to dbzero!!\n", + "Hello name-408. Welcome to dbzero!!\n", + "Hello name-409. Welcome to dbzero!!\n", + "Hello name-410. Welcome to dbzero!!\n", + "Hello name-411. Welcome to dbzero!!\n", + "Hello name-412. Welcome to dbzero!!\n", + "Hello name-413. Welcome to dbzero!!\n", + "Hello name-414. Welcome to dbzero!!\n", + "Hello name-415. Welcome to dbzero!!\n", + "Hello name-416. Welcome to dbzero!!\n", + "Hello name-417. Welcome to dbzero!!\n", + "Hello name-418. Welcome to dbzero!!\n", + "Hello name-419. Welcome to dbzero!!\n", + "Hello name-420. Welcome to dbzero!!\n", + "Hello name-421. Welcome to dbzero!!\n", + "Hello name-422. Welcome to dbzero!!\n", + "Hello name-423. Welcome to dbzero!!\n", + "Hello name-424. Welcome to dbzero!!\n", + "Hello name-425. Welcome to dbzero!!\n", + "Hello name-426. Welcome to dbzero!!\n", + "Hello name-427. Welcome to dbzero!!\n", + "Hello name-428. Welcome to dbzero!!\n", + "Hello name-429. Welcome to dbzero!!\n", + "Hello name-430. Welcome to dbzero!!\n", + "Hello name-431. Welcome to dbzero!!\n", + "Hello name-432. Welcome to dbzero!!\n", + "Hello name-433. Welcome to dbzero!!\n", + "Hello name-434. Welcome to dbzero!!\n", + "Hello name-435. Welcome to dbzero!!\n", + "Hello name-436. Welcome to dbzero!!\n", + "Hello name-437. Welcome to dbzero!!\n", + "Hello name-438. Welcome to dbzero!!\n", + "Hello name-439. Welcome to dbzero!!\n", + "Hello name-440. Welcome to dbzero!!\n", + "Hello name-441. Welcome to dbzero!!\n", + "Hello name-442. Welcome to dbzero!!\n", + "Hello name-443. Welcome to dbzero!!\n", + "Hello name-444. Welcome to dbzero!!\n", + "Hello name-445. Welcome to dbzero!!\n", + "Hello name-446. Welcome to dbzero!!\n", + "Hello name-447. Welcome to dbzero!!\n", + "Hello name-448. Welcome to dbzero!!\n", + "Hello name-449. Welcome to dbzero!!\n", + "Hello name-450. Welcome to dbzero!!\n", + "Hello name-451. Welcome to dbzero!!\n", + "Hello name-452. Welcome to dbzero!!\n", + "Hello name-453. Welcome to dbzero!!\n", + "Hello name-454. Welcome to dbzero!!\n", + "Hello name-455. Welcome to dbzero!!\n", + "Hello name-456. Welcome to dbzero!!\n", + "Hello name-457. Welcome to dbzero!!\n", + "Hello name-458. Welcome to dbzero!!\n", + "Hello name-459. Welcome to dbzero!!\n", + "Hello name-460. Welcome to dbzero!!\n", + "Hello name-461. Welcome to dbzero!!\n", + "Hello name-462. Welcome to dbzero!!\n", + "Hello name-463. Welcome to dbzero!!\n", + "Hello name-464. Welcome to dbzero!!\n", + "Hello name-465. Welcome to dbzero!!\n", + "Hello name-466. Welcome to dbzero!!\n", + "Hello name-467. Welcome to dbzero!!\n", + "Hello name-468. Welcome to dbzero!!\n", + "Hello name-469. Welcome to dbzero!!\n", + "Hello name-470. Welcome to dbzero!!\n", + "Hello name-471. Welcome to dbzero!!\n", + "Hello name-472. Welcome to dbzero!!\n", + "Hello name-473. Welcome to dbzero!!\n", + "Hello name-474. Welcome to dbzero!!\n", + "Hello name-475. Welcome to dbzero!!\n", + "Hello name-476. Welcome to dbzero!!\n", + "Hello name-477. Welcome to dbzero!!\n", + "Hello name-478. Welcome to dbzero!!\n", + "Hello name-479. Welcome to dbzero!!\n", + "Hello name-480. Welcome to dbzero!!\n", + "Hello name-481. Welcome to dbzero!!\n", + "Hello name-482. Welcome to dbzero!!\n", + "Hello name-483. Welcome to dbzero!!\n", + "Hello name-484. Welcome to dbzero!!\n", + "Hello name-485. Welcome to dbzero!!\n", + "Hello name-486. Welcome to dbzero!!\n", + "Hello name-487. Welcome to dbzero!!\n", + "Hello name-488. Welcome to dbzero!!\n", + "Hello name-489. Welcome to dbzero!!\n", + "Hello name-490. Welcome to dbzero!!\n", + "Hello name-491. Welcome to dbzero!!\n", + "Hello name-492. Welcome to dbzero!!\n", + "Hello name-493. Welcome to dbzero!!\n", + "Hello name-494. Welcome to dbzero!!\n", + "Hello name-495. Welcome to dbzero!!\n", + "Hello name-496. Welcome to dbzero!!\n", + "Hello name-497. Welcome to dbzero!!\n", + "Hello name-498. Welcome to dbzero!!\n", + "Hello name-499. Welcome to dbzero!!\n", + "Hello name-500. Welcome to dbzero!!\n", + "Hello name-501. Welcome to dbzero!!\n", + "Hello name-502. Welcome to dbzero!!\n", + "Hello name-503. Welcome to dbzero!!\n", + "Hello name-504. Welcome to dbzero!!\n", + "Hello name-505. Welcome to dbzero!!\n", + "Hello name-506. Welcome to dbzero!!\n", + "Hello name-507. Welcome to dbzero!!\n", + "Hello name-508. Welcome to dbzero!!\n", + "Hello name-509. Welcome to dbzero!!\n", + "Hello name-510. Welcome to dbzero!!\n", + "Hello name-511. Welcome to dbzero!!\n", + "Hello name-512. Welcome to dbzero!!\n", + "Hello name-513. Welcome to dbzero!!\n", + "Hello name-514. Welcome to dbzero!!\n", + "Hello name-515. Welcome to dbzero!!\n", + "Hello name-516. Welcome to dbzero!!\n", + "Hello name-517. Welcome to dbzero!!\n", + "Hello name-518. Welcome to dbzero!!\n", + "Hello name-519. Welcome to dbzero!!\n", + "Hello name-520. Welcome to dbzero!!\n", + "Hello name-521. Welcome to dbzero!!\n", + "Hello name-522. Welcome to dbzero!!\n", + "Hello name-523. Welcome to dbzero!!\n", + "Hello name-524. Welcome to dbzero!!\n", + "Hello name-525. Welcome to dbzero!!\n", + "Hello name-526. Welcome to dbzero!!\n", + "Hello name-527. Welcome to dbzero!!\n", + "Hello name-528. Welcome to dbzero!!\n", + "Hello name-529. Welcome to dbzero!!\n", + "Hello name-530. Welcome to dbzero!!\n", + "Hello name-531. Welcome to dbzero!!\n", + "Hello name-532. Welcome to dbzero!!\n", + "Hello name-533. Welcome to dbzero!!\n", + "Hello name-534. Welcome to dbzero!!\n", + "Hello name-535. Welcome to dbzero!!\n", + "Hello name-536. Welcome to dbzero!!\n", + "Hello name-537. Welcome to dbzero!!\n", + "Hello name-538. Welcome to dbzero!!\n", + "Hello name-539. Welcome to dbzero!!\n", + "Hello name-540. Welcome to dbzero!!\n", + "Hello name-541. Welcome to dbzero!!\n", + "Hello name-542. Welcome to dbzero!!\n", + "Hello name-543. Welcome to dbzero!!\n", + "Hello name-544. Welcome to dbzero!!\n", + "Hello name-545. Welcome to dbzero!!\n", + "Hello name-546. Welcome to dbzero!!\n", + "Hello name-547. Welcome to dbzero!!\n", + "Hello name-548. Welcome to dbzero!!\n", + "Hello name-549. Welcome to dbzero!!\n", + "Hello name-550. Welcome to dbzero!!\n", + "Hello name-551. Welcome to dbzero!!\n", + "Hello name-552. Welcome to dbzero!!\n", + "Hello name-553. Welcome to dbzero!!\n", + "Hello name-554. Welcome to dbzero!!\n", + "Hello name-555. Welcome to dbzero!!\n", + "Hello name-556. Welcome to dbzero!!\n", + "Hello name-557. Welcome to dbzero!!\n", + "Hello name-558. Welcome to dbzero!!\n", + "Hello name-559. Welcome to dbzero!!\n", + "Hello name-560. Welcome to dbzero!!\n", + "Hello name-561. Welcome to dbzero!!\n", + "Hello name-562. Welcome to dbzero!!\n", + "Hello name-563. Welcome to dbzero!!\n", + "Hello name-564. Welcome to dbzero!!\n", + "Hello name-565. Welcome to dbzero!!\n", + "Hello name-566. Welcome to dbzero!!\n", + "Hello name-567. Welcome to dbzero!!\n", + "Hello name-568. Welcome to dbzero!!\n", + "Hello name-569. Welcome to dbzero!!\n", + "Hello name-570. Welcome to dbzero!!\n", + "Hello name-571. Welcome to dbzero!!\n", + "Hello name-572. Welcome to dbzero!!\n", + "Hello name-573. Welcome to dbzero!!\n", + "Hello name-574. Welcome to dbzero!!\n", + "Hello name-575. Welcome to dbzero!!\n", + "Hello name-576. Welcome to dbzero!!\n", + "Hello name-577. Welcome to dbzero!!\n", + "Hello name-578. Welcome to dbzero!!\n", + "Hello name-579. Welcome to dbzero!!\n", + "Hello name-580. Welcome to dbzero!!\n", + "Hello name-581. Welcome to dbzero!!\n", + "Hello name-582. Welcome to dbzero!!\n", + "Hello name-583. Welcome to dbzero!!\n", + "Hello name-584. Welcome to dbzero!!\n", + "Hello name-585. Welcome to dbzero!!\n", + "Hello name-586. Welcome to dbzero!!\n", + "Hello name-587. Welcome to dbzero!!\n", + "Hello name-588. Welcome to dbzero!!\n", + "Hello name-589. Welcome to dbzero!!\n", + "Hello name-590. Welcome to dbzero!!\n", + "Hello name-591. Welcome to dbzero!!\n", + "Hello name-592. Welcome to dbzero!!\n", + "Hello name-593. Welcome to dbzero!!\n", + "Hello name-594. Welcome to dbzero!!\n", + "Hello name-595. Welcome to dbzero!!\n", + "Hello name-596. Welcome to dbzero!!\n", + "Hello name-597. Welcome to dbzero!!\n", + "Hello name-598. Welcome to dbzero!!\n", + "Hello name-599. Welcome to dbzero!!\n", + "Hello name-600. Welcome to dbzero!!\n", + "Hello name-601. Welcome to dbzero!!\n", + "Hello name-602. Welcome to dbzero!!\n", + "Hello name-603. Welcome to dbzero!!\n", + "Hello name-604. Welcome to dbzero!!\n", + "Hello name-605. Welcome to dbzero!!\n", + "Hello name-606. Welcome to dbzero!!\n", + "Hello name-607. Welcome to dbzero!!\n", + "Hello name-608. Welcome to dbzero!!\n", + "Hello name-609. Welcome to dbzero!!\n", + "Hello name-610. Welcome to dbzero!!\n", + "Hello name-611. Welcome to dbzero!!\n", + "Hello name-612. Welcome to dbzero!!\n", + "Hello name-613. Welcome to dbzero!!\n", + "Hello name-614. Welcome to dbzero!!\n", + "Hello name-615. Welcome to dbzero!!\n", + "Hello name-616. Welcome to dbzero!!\n", + "Hello name-617. Welcome to dbzero!!\n", + "Hello name-618. Welcome to dbzero!!\n", + "Hello name-619. Welcome to dbzero!!\n", + "Hello name-620. Welcome to dbzero!!\n", + "Hello name-621. Welcome to dbzero!!\n", + "Hello name-622. Welcome to dbzero!!\n", + "Hello name-623. Welcome to dbzero!!\n", + "Hello name-624. Welcome to dbzero!!\n", + "Hello name-625. Welcome to dbzero!!\n", + "Hello name-626. Welcome to dbzero!!\n", + "Hello name-627. Welcome to dbzero!!\n", + "Hello name-628. Welcome to dbzero!!\n", + "Hello name-629. Welcome to dbzero!!\n", + "Hello name-630. Welcome to dbzero!!\n", + "Hello name-631. Welcome to dbzero!!\n", + "Hello name-632. Welcome to dbzero!!\n", + "Hello name-633. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-634. Welcome to dbzero!!\n", + "Hello name-635. Welcome to dbzero!!\n", + "Hello name-636. Welcome to dbzero!!\n", + "Hello name-637. Welcome to dbzero!!\n", + "Hello name-638. Welcome to dbzero!!\n", + "Hello name-639. Welcome to dbzero!!\n", + "Hello name-640. Welcome to dbzero!!\n", + "Hello name-641. Welcome to dbzero!!\n", + "Hello name-642. Welcome to dbzero!!\n", + "Hello name-643. Welcome to dbzero!!\n", + "Hello name-644. Welcome to dbzero!!\n", + "Hello name-645. Welcome to dbzero!!\n", + "Hello name-646. Welcome to dbzero!!\n", + "Hello name-647. Welcome to dbzero!!\n", + "Hello name-648. Welcome to dbzero!!\n", + "Hello name-649. Welcome to dbzero!!\n", + "Hello name-650. Welcome to dbzero!!\n", + "Hello name-651. Welcome to dbzero!!\n", + "Hello name-652. Welcome to dbzero!!\n", + "Hello name-653. Welcome to dbzero!!\n", + "Hello name-654. Welcome to dbzero!!\n", + "Hello name-655. Welcome to dbzero!!\n", + "Hello name-656. Welcome to dbzero!!\n", + "Hello name-657. Welcome to dbzero!!\n", + "Hello name-658. Welcome to dbzero!!\n", + "Hello name-659. Welcome to dbzero!!\n", + "Hello name-660. Welcome to dbzero!!\n", + "Hello name-661. Welcome to dbzero!!\n", + "Hello name-662. Welcome to dbzero!!\n", + "Hello name-663. Welcome to dbzero!!\n", + "Hello name-664. Welcome to dbzero!!\n", + "Hello name-665. Welcome to dbzero!!\n", + "Hello name-666. Welcome to dbzero!!\n", + "Hello name-667. Welcome to dbzero!!\n", + "Hello name-668. Welcome to dbzero!!\n", + "Hello name-669. Welcome to dbzero!!\n", + "Hello name-670. Welcome to dbzero!!\n", + "Hello name-671. Welcome to dbzero!!\n", + "Hello name-672. Welcome to dbzero!!\n", + "Hello name-673. Welcome to dbzero!!\n", + "Hello name-674. Welcome to dbzero!!\n", + "Hello name-675. Welcome to dbzero!!\n", + "Hello name-676. Welcome to dbzero!!\n", + "Hello name-677. Welcome to dbzero!!\n", + "Hello name-678. Welcome to dbzero!!\n", + "Hello name-679. Welcome to dbzero!!\n", + "Hello name-680. Welcome to dbzero!!\n", + "Hello name-681. Welcome to dbzero!!\n", + "Hello name-682. Welcome to dbzero!!\n", + "Hello name-683. Welcome to dbzero!!\n", + "Hello name-684. Welcome to dbzero!!\n", + "Hello name-685. Welcome to dbzero!!\n", + "Hello name-686. Welcome to dbzero!!\n", + "Hello name-687. Welcome to dbzero!!\n", + "Hello name-688. Welcome to dbzero!!\n", + "Hello name-689. Welcome to dbzero!!\n", + "Hello name-690. Welcome to dbzero!!\n", + "Hello name-691. Welcome to dbzero!!\n", + "Hello name-692. Welcome to dbzero!!\n", + "Hello name-693. Welcome to dbzero!!\n", + "Hello name-694. Welcome to dbzero!!\n", + "Hello name-695. Welcome to dbzero!!\n", + "Hello name-696. Welcome to dbzero!!\n", + "Hello name-697. Welcome to dbzero!!\n", + "Hello name-698. Welcome to dbzero!!\n", + "Hello name-699. Welcome to dbzero!!\n", + "Hello name-700. Welcome to dbzero!!\n", + "Hello name-701. Welcome to dbzero!!\n", + "Hello name-702. Welcome to dbzero!!\n", + "Hello name-703. Welcome to dbzero!!\n", + "Hello name-704. Welcome to dbzero!!\n", + "Hello name-705. Welcome to dbzero!!\n", + "Hello name-706. Welcome to dbzero!!\n", + "Hello name-707. Welcome to dbzero!!\n", + "Hello name-708. Welcome to dbzero!!\n", + "Hello name-709. Welcome to dbzero!!\n", + "Hello name-710. Welcome to dbzero!!\n", + "Hello name-711. Welcome to dbzero!!\n", + "Hello name-712. Welcome to dbzero!!\n", + "Hello name-713. Welcome to dbzero!!\n", + "Hello name-714. Welcome to dbzero!!\n", + "Hello name-715. Welcome to dbzero!!\n", + "Hello name-716. Welcome to dbzero!!\n", + "Hello name-717. Welcome to dbzero!!\n", + "Hello name-718. Welcome to dbzero!!\n", + "Hello name-719. Welcome to dbzero!!\n", + "Hello name-720. Welcome to dbzero!!\n", + "Hello name-721. Welcome to dbzero!!\n", + "Hello name-722. Welcome to dbzero!!\n", + "Hello name-723. Welcome to dbzero!!\n", + "Hello name-724. Welcome to dbzero!!\n", + "Hello name-725. Welcome to dbzero!!\n", + "Hello name-726. Welcome to dbzero!!\n", + "Hello name-727. Welcome to dbzero!!\n", + "Hello name-728. Welcome to dbzero!!\n", + "Hello name-729. Welcome to dbzero!!\n", + "Hello name-730. Welcome to dbzero!!\n", + "Hello name-731. Welcome to dbzero!!\n", + "Hello name-732. Welcome to dbzero!!\n", + "Hello name-733. Welcome to dbzero!!\n", + "Hello name-734. Welcome to dbzero!!\n", + "Hello name-735. Welcome to dbzero!!\n", + "Hello name-736. Welcome to dbzero!!\n", + "Hello name-737. Welcome to dbzero!!\n", + "Hello name-738. Welcome to dbzero!!\n", + "Hello name-739. Welcome to dbzero!!\n", + "Hello name-740. Welcome to dbzero!!\n", + "Hello name-741. Welcome to dbzero!!\n", + "Hello name-742. Welcome to dbzero!!\n", + "Hello name-743. Welcome to dbzero!!\n", + "Hello name-744. Welcome to dbzero!!\n", + "Hello name-745. Welcome to dbzero!!\n", + "Hello name-746. Welcome to dbzero!!\n", + "Hello name-747. Welcome to dbzero!!\n", + "Hello name-748. Welcome to dbzero!!\n", + "Hello name-749. Welcome to dbzero!!\n", + "Hello name-750. Welcome to dbzero!!\n", + "Hello name-751. Welcome to dbzero!!\n", + "Hello name-752. Welcome to dbzero!!\n", + "Hello name-753. Welcome to dbzero!!\n", + "Hello name-754. Welcome to dbzero!!\n", + "Hello name-755. Welcome to dbzero!!\n", + "Hello name-756. Welcome to dbzero!!\n", + "Hello name-757. Welcome to dbzero!!\n", + "Hello name-758. Welcome to dbzero!!\n", + "Hello name-759. Welcome to dbzero!!\n", + "Hello name-760. Welcome to dbzero!!\n", + "Hello name-761. Welcome to dbzero!!\n", + "Hello name-762. Welcome to dbzero!!\n", + "Hello name-763. Welcome to dbzero!!\n", + "Hello name-764. Welcome to dbzero!!\n", + "Hello name-765. Welcome to dbzero!!\n", + "Hello name-766. Welcome to dbzero!!\n", + "Hello name-767. Welcome to dbzero!!\n", + "Hello name-768. Welcome to dbzero!!\n", + "Hello name-769. Welcome to dbzero!!\n", + "Hello name-770. Welcome to dbzero!!\n", + "Hello name-771. Welcome to dbzero!!\n", + "Hello name-772. Welcome to dbzero!!\n", + "Hello name-773. Welcome to dbzero!!\n", + "Hello name-774. Welcome to dbzero!!\n", + "Hello name-775. Welcome to dbzero!!\n", + "Hello name-776. Welcome to dbzero!!\n", + "Hello name-777. Welcome to dbzero!!\n", + "Hello name-778. Welcome to dbzero!!\n", + "Hello name-779. Welcome to dbzero!!\n", + "Hello name-780. Welcome to dbzero!!\n", + "Hello name-781. Welcome to dbzero!!\n", + "Hello name-782. Welcome to dbzero!!\n", + "Hello name-783. Welcome to dbzero!!\n", + "Hello name-784. Welcome to dbzero!!\n", + "Hello name-785. Welcome to dbzero!!\n", + "Hello name-786. Welcome to dbzero!!\n", + "Hello name-787. Welcome to dbzero!!\n", + "Hello name-788. Welcome to dbzero!!\n", + "Hello name-789. Welcome to dbzero!!\n", + "Hello name-790. Welcome to dbzero!!\n", + "Hello name-791. Welcome to dbzero!!\n", + "Hello name-792. Welcome to dbzero!!\n", + "Hello name-793. Welcome to dbzero!!\n", + "Hello name-794. Welcome to dbzero!!\n", + "Hello name-795. Welcome to dbzero!!\n", + "Hello name-796. Welcome to dbzero!!\n", + "Hello name-797. Welcome to dbzero!!\n", + "Hello name-798. Welcome to dbzero!!\n", + "Hello name-799. Welcome to dbzero!!\n", + "Hello name-800. Welcome to dbzero!!\n", + "Hello name-801. Welcome to dbzero!!\n", + "Hello name-802. Welcome to dbzero!!\n", + "Hello name-803. Welcome to dbzero!!\n", + "Hello name-804. Welcome to dbzero!!\n", + "Hello name-805. Welcome to dbzero!!\n", + "Hello name-806. Welcome to dbzero!!\n", + "Hello name-807. Welcome to dbzero!!\n", + "Hello name-808. Welcome to dbzero!!\n", + "Hello name-809. Welcome to dbzero!!\n", + "Hello name-810. Welcome to dbzero!!\n", + "Hello name-811. Welcome to dbzero!!\n", + "Hello name-812. Welcome to dbzero!!\n", + "Hello name-813. Welcome to dbzero!!\n", + "Hello name-814. Welcome to dbzero!!\n", + "Hello name-815. Welcome to dbzero!!\n", + "Hello name-816. Welcome to dbzero!!\n", + "Hello name-817. Welcome to dbzero!!\n", + "Hello name-818. Welcome to dbzero!!\n", + "Hello name-819. Welcome to dbzero!!\n", + "Hello name-820. Welcome to dbzero!!\n", + "Hello name-821. Welcome to dbzero!!\n", + "Hello name-822. Welcome to dbzero!!\n", + "Hello name-823. Welcome to dbzero!!\n", + "Hello name-824. Welcome to dbzero!!\n", + "Hello name-825. Welcome to dbzero!!\n", + "Hello name-826. Welcome to dbzero!!\n", + "Hello name-827. Welcome to dbzero!!\n", + "Hello name-828. Welcome to dbzero!!\n", + "Hello name-829. Welcome to dbzero!!\n", + "Hello name-830. Welcome to dbzero!!\n", + "Hello name-831. Welcome to dbzero!!\n", + "Hello name-832. Welcome to dbzero!!\n", + "Hello name-833. Welcome to dbzero!!\n", + "Hello name-834. Welcome to dbzero!!\n", + "Hello name-835. Welcome to dbzero!!\n", + "Hello name-836. Welcome to dbzero!!\n", + "Hello name-837. Welcome to dbzero!!\n", + "Hello name-838. Welcome to dbzero!!\n", + "Hello name-839. Welcome to dbzero!!\n", + "Hello name-840. Welcome to dbzero!!\n", + "Hello name-841. Welcome to dbzero!!\n", + "Hello name-842. Welcome to dbzero!!\n", + "Hello name-843. Welcome to dbzero!!\n", + "Hello name-844. Welcome to dbzero!!\n", + "Hello name-845. Welcome to dbzero!!\n", + "Hello name-846. Welcome to dbzero!!\n", + "Hello name-847. Welcome to dbzero!!\n", + "Hello name-848. Welcome to dbzero!!\n", + "Hello name-849. Welcome to dbzero!!\n", + "Hello name-850. Welcome to dbzero!!\n", + "Hello name-851. Welcome to dbzero!!\n", + "Hello name-852. Welcome to dbzero!!\n", + "Hello name-853. Welcome to dbzero!!\n", + "Hello name-854. Welcome to dbzero!!\n", + "Hello name-855. Welcome to dbzero!!\n", + "Hello name-856. Welcome to dbzero!!\n", + "Hello name-857. Welcome to dbzero!!\n", + "Hello name-858. Welcome to dbzero!!\n", + "Hello name-859. Welcome to dbzero!!\n", + "Hello name-860. Welcome to dbzero!!\n", + "Hello name-861. Welcome to dbzero!!\n", + "Hello name-862. Welcome to dbzero!!\n", + "Hello name-863. Welcome to dbzero!!\n", + "Hello name-864. Welcome to dbzero!!\n", + "Hello name-865. Welcome to dbzero!!\n", + "Hello name-866. Welcome to dbzero!!\n", + "Hello name-867. Welcome to dbzero!!\n", + "Hello name-868. Welcome to dbzero!!\n", + "Hello name-869. Welcome to dbzero!!\n", + "Hello name-870. Welcome to dbzero!!\n", + "Hello name-871. Welcome to dbzero!!\n", + "Hello name-872. Welcome to dbzero!!\n", + "Hello name-873. Welcome to dbzero!!\n", + "Hello name-874. Welcome to dbzero!!\n", + "Hello name-875. Welcome to dbzero!!\n", + "Hello name-876. Welcome to dbzero!!\n", + "Hello name-877. Welcome to dbzero!!\n", + "Hello name-878. Welcome to dbzero!!\n", + "Hello name-879. Welcome to dbzero!!\n", + "Hello name-880. Welcome to dbzero!!\n", + "Hello name-881. Welcome to dbzero!!\n", + "Hello name-882. Welcome to dbzero!!\n", + "Hello name-883. Welcome to dbzero!!\n", + "Hello name-884. Welcome to dbzero!!\n", + "Hello name-885. Welcome to dbzero!!\n", + "Hello name-886. Welcome to dbzero!!\n", + "Hello name-887. Welcome to dbzero!!\n", + "Hello name-888. Welcome to dbzero!!\n", + "Hello name-889. Welcome to dbzero!!\n", + "Hello name-890. Welcome to dbzero!!\n", + "Hello name-891. Welcome to dbzero!!\n", + "Hello name-892. Welcome to dbzero!!\n", + "Hello name-893. Welcome to dbzero!!\n", + "Hello name-894. Welcome to dbzero!!\n", + "Hello name-895. Welcome to dbzero!!\n", + "Hello name-896. Welcome to dbzero!!\n", + "Hello name-897. Welcome to dbzero!!\n", + "Hello name-898. Welcome to dbzero!!\n", + "Hello name-899. Welcome to dbzero!!\n", + "Hello name-900. Welcome to dbzero!!\n", + "Hello name-901. Welcome to dbzero!!\n", + "Hello name-902. Welcome to dbzero!!\n", + "Hello name-903. Welcome to dbzero!!\n", + "Hello name-904. Welcome to dbzero!!\n", + "Hello name-905. Welcome to dbzero!!\n", + "Hello name-906. Welcome to dbzero!!\n", + "Hello name-907. Welcome to dbzero!!\n", + "Hello name-908. Welcome to dbzero!!\n", + "Hello name-909. Welcome to dbzero!!\n", + "Hello name-910. Welcome to dbzero!!\n", + "Hello name-911. Welcome to dbzero!!\n", + "Hello name-912. Welcome to dbzero!!\n", + "Hello name-913. Welcome to dbzero!!\n", + "Hello name-914. Welcome to dbzero!!\n", + "Hello name-915. Welcome to dbzero!!\n", + "Hello name-916. Welcome to dbzero!!\n", + "Hello name-917. Welcome to dbzero!!\n", + "Hello name-918. Welcome to dbzero!!\n", + "Hello name-919. Welcome to dbzero!!\n", + "Hello name-920. Welcome to dbzero!!\n", + "Hello name-921. Welcome to dbzero!!\n", + "Hello name-922. Welcome to dbzero!!\n", + "Hello name-923. Welcome to dbzero!!\n", + "Hello name-924. Welcome to dbzero!!\n", + "Hello name-925. Welcome to dbzero!!\n", + "Hello name-926. Welcome to dbzero!!\n", + "Hello name-927. Welcome to dbzero!!\n", + "Hello name-928. Welcome to dbzero!!\n", + "Hello name-929. Welcome to dbzero!!\n", + "Hello name-930. Welcome to dbzero!!\n", + "Hello name-931. Welcome to dbzero!!\n", + "Hello name-932. Welcome to dbzero!!\n", + "Hello name-933. Welcome to dbzero!!\n", + "Hello name-934. Welcome to dbzero!!\n", + "Hello name-935. Welcome to dbzero!!\n", + "Hello name-936. Welcome to dbzero!!\n", + "Hello name-937. Welcome to dbzero!!\n", + "Hello name-938. Welcome to dbzero!!\n", + "Hello name-939. Welcome to dbzero!!\n", + "Hello name-940. Welcome to dbzero!!\n", + "Hello name-941. Welcome to dbzero!!\n", + "Hello name-942. Welcome to dbzero!!\n", + "Hello name-943. Welcome to dbzero!!\n", + "Hello name-944. Welcome to dbzero!!\n", + "Hello name-945. Welcome to dbzero!!\n", + "Hello name-946. Welcome to dbzero!!\n", + "Hello name-947. Welcome to dbzero!!\n", + "Hello name-948. Welcome to dbzero!!\n", + "Hello name-949. Welcome to dbzero!!\n", + "Hello name-950. Welcome to dbzero!!\n", + "Hello name-951. Welcome to dbzero!!\n", + "Hello name-952. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-953. Welcome to dbzero!!\n", + "Hello name-954. Welcome to dbzero!!\n", + "Hello name-955. Welcome to dbzero!!\n", + "Hello name-956. Welcome to dbzero!!\n", + "Hello name-957. Welcome to dbzero!!\n", + "Hello name-958. Welcome to dbzero!!\n", + "Hello name-959. Welcome to dbzero!!\n", + "Hello name-960. Welcome to dbzero!!\n", + "Hello name-961. Welcome to dbzero!!\n", + "Hello name-962. Welcome to dbzero!!\n", + "Hello name-963. Welcome to dbzero!!\n", + "Hello name-964. Welcome to dbzero!!\n", + "Hello name-965. Welcome to dbzero!!\n", + "Hello name-966. Welcome to dbzero!!\n", + "Hello name-967. Welcome to dbzero!!\n", + "Hello name-968. Welcome to dbzero!!\n", + "Hello name-969. Welcome to dbzero!!\n", + "Hello name-970. Welcome to dbzero!!\n", + "Hello name-971. Welcome to dbzero!!\n", + "Hello name-972. Welcome to dbzero!!\n", + "Hello name-973. Welcome to dbzero!!\n", + "Hello name-974. Welcome to dbzero!!\n", + "Hello name-975. Welcome to dbzero!!\n", + "Hello name-976. Welcome to dbzero!!\n", + "Hello name-977. Welcome to dbzero!!\n", + "Hello name-978. Welcome to dbzero!!\n", + "Hello name-979. Welcome to dbzero!!\n", + "Hello name-980. Welcome to dbzero!!\n", + "Hello name-981. Welcome to dbzero!!\n", + "Hello name-982. Welcome to dbzero!!\n", + "Hello name-983. Welcome to dbzero!!\n", + "Hello name-984. Welcome to dbzero!!\n", + "Hello name-985. Welcome to dbzero!!\n", + "Hello name-986. Welcome to dbzero!!\n", + "Hello name-987. Welcome to dbzero!!\n", + "Hello name-988. Welcome to dbzero!!\n", + "Hello name-989. Welcome to dbzero!!\n", + "Hello name-990. Welcome to dbzero!!\n", + "Hello name-991. Welcome to dbzero!!\n", + "Hello name-992. Welcome to dbzero!!\n", + "Hello name-993. Welcome to dbzero!!\n", + "Hello name-994. Welcome to dbzero!!\n", + "Hello name-995. Welcome to dbzero!!\n", + "Hello name-996. Welcome to dbzero!!\n", + "Hello name-997. Welcome to dbzero!!\n", + "Hello name-998. Welcome to dbzero!!\n", + "Hello name-999. Welcome to dbzero!!\n" + ] + } + ], + "source": [ + "mh = HelloMany()\n", + "mh.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "c3e94994", + "metadata": {}, + "source": [ + "We can see that many_hellos and mh are different Python objects, but the same DB0 object." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "80ba330d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "140452238759472 140452238759472\n" + ] + } + ], + "source": [ + "print(f\"{id(many_hellos)} {id(mh)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "fcba2e21", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "QXW6HODE47E27IEBUGXYABQN QXW6HODE47E27IEBUGXYABQN\n" + ] + } + ], + "source": [ + "print(f\"{db0.uuid(many_hellos)} {db0.uuid(mh)}\")" + ] + }, + { + "cell_type": "markdown", + "id": "8ee99729", + "metadata": {}, + "source": [ + "### So what is actually stored in the list HelloMany.hellos ?\n", + "Similarly as with regular Python objects - the list stores references, not full instances. **dbzero** lists can store simple types (numbers / strings), other cllections (lists, dicts, sets, tuples etc.) or references to any other dbzero @memo instances." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "cee2abcb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "QXW6HODE47E27IEBUCAIAAIN\n", + "QXW6HODE47E27IEBUCRYAAQN\n", + "QXW6HODE47E27IEBUDDIAAYN\n", + "QXW6HODE47E27IEBUDUYABAN\n", + "QXW6HODE47E27IEBUGGIABIN\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "844424934367952\n", + "844424934367968\n", + "844424934367984\n", + "844424934368000\n", + "844424934368016\n", + "844424934368032\n", + "844424934368048\n", + "844424934368064\n", + "844424934368080\n", + "844424934368096\n", + "844424934368112\n", + "844424934368128\n", + "844424934368144\n", + "844424934368160\n", + "844424934368176\n", + "844424934368192\n", + "844424934368208\n", + "844424934368224\n", + "844424934368240\n", + "844424934368256\n", + "844424934368272\n", + "844424934368288\n", + "844424934368304\n", + "844424934368320\n", + "844424934368336\n", + "844424934368352\n", + "844424934368368\n", + "844424934368384\n", + "844424934368400\n", + "844424934368416\n", + "844424934368432\n", + "844424934368448\n", + "844424934368464\n", + "844424934368480\n", + "844424934368496\n", + "844424934368512\n", + "844424934368528\n", + "844424934368544\n", + "844424934368560\n", + "844424934368576\n", + "844424934368592\n", + "844424934368608\n", + "844424934368624\n", + "844424934368640\n", + "844424934368656\n", + "844424934368672\n", + "844424934368688\n", + "844424934368704\n", + "844424934368720\n", + "844424934368736\n", + "844424934368752\n", + "844424934368768\n", + "844424934368784\n", + "844424934368800\n", + "844424934368816\n", + "844424934368832\n", + "844424934368848\n", + "844424934368864\n", + "844424934368880\n", + "844424934368896\n", + "844424934368912\n", + "844424934368928\n", + "844424934368944\n", + "844424934368960\n", + "844424934368976\n", + "844424934368992\n", + "844424934369008\n", + "844424934369024\n", + "844424934369040\n", + "844424934369056\n", + "844424934369072\n", + "844424934369088\n", + "844424934369104\n", + "844424934369120\n", + "844424934369136\n", + "844424934369152\n", + "844424934369168\n", + "844424934369184\n", + "844424934369200\n", + "844424934369216\n", + "844424934369232\n", + "844424934369248\n", + "844424934369264\n", + "844424934369280\n", + "844424934369296\n", + "844424934369312\n", + "844424934369328\n", + "844424934369344\n", + "844424934369360\n", + "844424934369376\n", + "844424934369392\n", + "844424934369408\n", + "844424934369424\n", + "844424934369440\n", + "844424934369456\n", + "844424934369472\n", + "844424934369488\n", + "844424934369504\n", + "844424934369520\n", + "844424934369536\n", + "844424934369552\n", + "844424934369568\n", + "844424934369584\n", + "844424934369600\n", + "844424934369616\n", + "844424934369632\n", + "844424934369648\n", + "844424934369664\n", + "844424934369680\n", + "844424934369696\n", + "844424934369712\n", + "844424934369728\n", + "844424934369744\n", + "844424934369760\n", + "844424934369776\n", + "844424934369792\n", + "844424934369808\n", + "844424934369824\n", + "844424934369840\n", + "844424934369856\n", + "844424934369872\n", + "844424934369888\n", + "844424934369904\n", + "844424934369920\n", + "844424934369936\n", + "844424934369952\n", + "844424934369968\n", + "844424934369984\n", + "844424934370000\n", + "844424934370016\n", + "844424934370032\n", + "844424934370048\n", + "844424934370064\n", + "844424934370080\n", + "844424934370096\n", + "844424934370112\n", + "844424934370128\n", + "844424934370144\n", + "844424934370160\n", + "844424934370176\n", + "844424934370192\n", + "844424934370208\n", + "844424934370224\n", + "844424934370240\n", + "844424934370256\n", + "844424934370272\n", + "844424934370288\n", + "844424934370304\n", + "844424934370320\n", + "844424934370336\n", + "844424934370352\n", + "844424934370368\n", + "844424934370384\n", + "844424934370400\n", + "844424934370416\n", + "844424934370432\n", + "844424934370448\n", + "844424934370464\n", + "844424934370480\n", + "844424934370496\n", + "844424934370512\n", + "844424934370528\n", + "844424934370544\n", + "844424934370560\n", + "844424934370576\n", + "844424934370592\n", + "844424934370608\n", + "844424934370624\n", + "844424934370640\n", + "844424934370656\n", + "844424934370672\n", + "844424934370688\n", + "844424934370704\n", + "844424934370720\n", + "844424934370736\n", + "844424934370752\n", + "844424934370768\n", + "844424934370784\n", + "844424934370800\n", + "844424934370816\n", + "844424934370832\n", + "844424934370848\n", + "844424934370864\n", + "844424934370880\n", + "844424934370896\n", + "844424934370912\n", + "844424934370928\n", + "844424934370944\n", + "844424934370960\n", + "844424934370976\n", + "844424934370992\n", + "844424934371008\n", + "844424934371024\n", + "844424934371040\n", + "844424934371056\n", + "844424934371072\n", + "844424934371088\n", + "844424934371104\n", + "844424934371120\n", + "844424934371136\n", + "844424934371152\n", + "844424934371168\n", + "844424934371184\n", + "844424934371200\n", + "844424934371216\n", + "844424934371232\n", + "844424934371248\n", + "844424934371264\n", + "844424934371280\n", + "844424934371296\n", + "844424934371312\n", + "844424934371328\n", + "844424934371344\n", + "844424934371360\n", + "844424934371376\n", + "844424934371392\n", + "844424934371408\n", + "844424934371424\n", + "844424934371440\n", + "844424934371456\n", + "844424934371472\n", + "844424934371488\n", + "844424934371504\n", + "844424934371520\n", + "844424934371536\n", + "844424934371552\n", + "844424934371568\n", + "844424934371584\n", + "844424934371600\n", + "844424934371616\n", + "844424934371632\n", + "844424934371648\n", + "844424934371664\n", + "844424934371680\n", + "844424934371696\n", + "844424934371712\n", + "844424934371728\n", + "844424934371744\n", + "844424934371760\n", + "844424934371776\n", + "844424934371792\n", + "844424934371808\n", + "844424934371824\n", + "844424934371840\n", + "844424934371856\n", + "844424934371872\n", + "844424934371888\n", + "844424934371904\n", + "844424934371920\n", + "844424934371936\n", + "844424934371952\n", + "844424934371968\n", + "844424934371984\n", + "844424934372000\n", + "844424934372016\n", + "844424934372032\n", + "844424934372048\n", + "844424934372064\n", + "844424934372080\n", + "844424934372096\n", + "844424934372112\n", + "844424934372128\n", + "844424934372144\n", + "844424934372160\n", + "844424934372176\n", + "844424934372192\n", + "844424934372208\n", + "844424934372224\n", + "844424934372240\n", + "844424934372256\n", + "844424934372272\n", + "844424934372288\n", + "844424934372304\n", + "844424934372320\n", + "844424934372336\n", + "844424934372352\n", + "844424934372368\n", + "844424934372384\n", + "844424934372400\n", + "844424934372416\n", + "844424934372432\n", + "844424934372448\n", + "844424934372464\n", + "844424934372480\n", + "844424934372496\n", + "844424934372512\n", + "844424934372528\n", + "844424934372544\n", + "844424934372560\n", + "844424934372576\n", + "844424934372592\n", + "844424934372608\n", + "844424934372624\n", + "844424934372640\n", + "844424934372656\n", + "844424934372672\n", + "844424934372688\n", + "844424934372704\n", + "844424934372720\n", + "844424934372736\n", + "844424934372752\n", + "844424934372768\n", + "844424934372784\n", + "844424934372800\n", + "844424934372816\n", + "844424934372832\n", + "844424934372848\n", + "844424934372864\n", + "844424934372880\n", + "844424934372896\n", + "844424934372912\n", + "844424934372928\n", + "844424934372944\n", + "844424934372960\n", + "844424934372976\n", + "844424934372992\n", + "844424934373008\n", + "844424934373024\n", + "844424934373040\n", + "844424934373056\n", + "844424934373072\n", + "844424934373088\n", + "844424934373104\n", + "844424934373120\n", + "844424934373136\n", + "844424934373152\n", + "844424934373168\n", + "844424934373184\n", + "844424934373200\n", + "844424934373216\n", + "844424934373232\n", + "844424934373248\n", + "844424934373264\n", + "844424934373280\n", + "844424934373296\n", + "844424934373312\n", + "844424934373328\n", + "844424934373344\n", + "844424934373360\n", + "844424934373376\n", + "844424934373392\n", + "844424934373408\n", + "844424934373424\n", + "844424934373440\n", + "844424934373456\n", + "844424934373472\n", + "844424934373488\n", + "844424934373504\n", + "844424934373520\n", + "844424934373536\n", + "844424934373552\n", + "844424934373568\n", + "844424934373584\n", + "844424934373600\n", + "844424934373616\n", + "844424934373632\n", + "844424934373648\n", + "844424934373664\n", + "844424934373680\n", + "844424934373696\n", + "844424934373712\n", + "844424934373728\n", + "844424934373744\n", + "844424934373760\n", + "844424934373776\n", + "844424934373792\n", + "844424934373808\n", + "844424934373824\n", + "844424934373840\n", + "844424934373856\n", + "844424934373872\n", + "844424934373888\n", + "844424934373904\n", + "844424934373920\n", + "844424934373936\n", + "844424934373952\n", + "844424934373968\n", + "844424934373984\n", + "844424934374000\n", + "844424934374016\n", + "844424934374032\n", + "844424934374048\n", + "844424934374064\n", + "844424934374080\n", + "844424934374096\n", + "844424934374112\n", + "844424934374128\n", + "844424934374144\n", + "844424934374160\n", + "844424934374176\n", + "844424934374192\n", + "844424934374208\n", + "844424934374224\n", + "844424934374240\n", + "844424934374256\n", + "844424934374272\n", + "844424934374288\n", + "844424934374304\n", + "844424934374320\n", + "844424934374336\n", + "844424934374352\n", + "844424934374368\n", + "844424934374384\n", + "844424934374400\n", + "844424934374416\n", + "844424934374432\n", + "844424934374448\n", + "844424934374464\n", + "844424934374480\n", + "844424934374496\n", + "844424934374512\n", + "844424934374528\n", + "844424934374544\n", + "844424934374560\n", + "844424934374576\n", + "844424934374592\n", + "844424934374608\n", + "844424934374624\n", + "844424934374640\n", + "844424934374656\n", + "844424934374672\n", + "844424934374688\n", + "844424934374704\n", + "844424934374720\n", + "844424934374736\n", + "844424934374752\n", + "844424934374768\n", + "844424934374784\n", + "844424934374800\n", + "844424934374816\n", + "844424934374832\n", + "844424934374848\n", + "844424934374864\n", + "844424934374880\n", + "844424934374896\n", + "844424934374912\n", + "844424934374928\n", + "844424934374944\n", + "844424934374960\n", + "844424934374976\n", + "844424934374992\n", + "844424934375008\n", + "844424934375024\n", + "844424934375040\n", + "844424934375056\n", + "844424934375072\n", + "844424934375088\n", + "844424934375104\n", + "844424934375120\n", + "844424934375136\n", + "844424934375152\n", + "844424934375168\n", + "844424934375184\n", + "844424934375200\n", + "844424934375216\n", + "844424934375232\n", + "844424934375248\n", + "844424934375264\n", + "844424934375280\n", + "844424934375296\n", + "844424934375312\n", + "844424934375328\n", + "844424934375344\n", + "844424934375360\n", + "844424934375376\n", + "844424934375392\n", + "844424934375408\n", + "844424953171968\n", + "844424953171984\n", + "844424953172000\n", + "844424953172016\n", + "844424953172032\n", + "844424953172048\n", + "844424953172064\n", + "844424953172080\n", + "844424953172096\n", + "844424953172112\n", + "844424953172128\n", + "844424953172144\n" + ] + } + ], + "source": [ + "for obj in mh.hellos:\n", + " print(db0.uuid(obj))" + ] + }, + { + "cell_type": "markdown", + "id": "9e796db6", + "metadata": {}, + "source": [ + "And a **dbzero** list acts exactly as any regular Python list - you can iterate, slice, or access its elements by index." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "c12a5b4b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello Frank. Welcome to dbzero!!\n" + ] + } + ], + "source": [ + "mh.hellos[3].greet()" + ] + }, + { + "cell_type": "markdown", + "id": "32e73b42", + "metadata": {}, + "source": [ + "### So how big can a single list be?\n", + "In Python normally your list would be limited by the size of RAM available to your process (in practice, when running a program - who knows what this limit exactly is ???). For DB0 (cloud) users we have a good news. There're ZERO limits !!! If you wish so, you can create a list of size far exceeding your available memory. In case of the local version this size is limited by the available disk space." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "b6145d70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n" + ] + } + ], + "source": [ + "print(len(mh.hellos))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "99f60571", + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(1000):\n", + " mh.hellos.append(HelloWorld(f\"name-{i}\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "dd690238", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1005\n" + ] + } + ], + "source": [ + "print(len(mh.hellos))" + ] + }, + { + "cell_type": "markdown", + "id": "43594eb5", + "metadata": {}, + "source": [ + "Let's explore the memory utilization a limits in the next notebook." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "d3b681a3", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a29f46c", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/.ipynb_checkpoints/hello.db0_3-checkpoint.ipynb b/notebooks/hello/.ipynb_checkpoints/hello.db0_3-checkpoint.ipynb new file mode 100644 index 00000000..1c3fb76e --- /dev/null +++ b/notebooks/hello/.ipynb_checkpoints/hello.db0_3-checkpoint.ipynb @@ -0,0 +1,640 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "be05952a", + "metadata": {}, + "source": [ + "## Introducing **dbzero** (3/12). Exploring the limits." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "38c6322c", + "metadata": {}, + "outputs": [], + "source": [ + "import dbzero as db0\n", + "from mem_charts import mem_usage_chart, random_string\n", + "from bokeh.io import show, output_notebook\n", + "import concurrent.futures" + ] + }, + { + "cell_type": "markdown", + "id": "abf8826b", + "metadata": {}, + "source": [ + "We've imported 'bokeh' package to visualize current memory utilization on a chart." + ] + }, + { + "cell_type": "markdown", + "id": "9880fd22", + "metadata": {}, + "source": [ + "Let's also create executor to be able to run Python tasks in the background (separate thread)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "23d84849", + "metadata": {}, + "outputs": [], + "source": [ + "executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)" + ] + }, + { + "cell_type": "markdown", + "id": "5c0210f9", + "metadata": {}, + "source": [ + "The chart below presents live memory utilization of the current process refreshed every 1 sec." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "d9bda63f", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "'use strict';\n", + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + "const JS_MIME_TYPE = 'application/javascript';\n", + " const HTML_MIME_TYPE = 'text/html';\n", + " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " const CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " const script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " function drop(id) {\n", + " const view = Bokeh.index.get_by_id(id)\n", + " if (view != null) {\n", + " view.model.document.clear()\n", + " Bokeh.index.delete(view)\n", + " }\n", + " }\n", + "\n", + " const cell = handle.cell;\n", + "\n", + " const id = cell.output_area._bokeh_element_id;\n", + " const server_id = cell.output_area._bokeh_server_id;\n", + "\n", + " // Clean up Bokeh references\n", + " if (id != null) {\n", + " drop(id)\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd_clean, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " const id = msg.content.text.trim()\n", + " drop(id)\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd_destroy);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " const output_area = handle.output_area;\n", + " const output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " const bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " const script_attrs = bk_div.children[0].attributes;\n", + " for (let i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " const toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " const events = require('base/js/events');\n", + " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " const NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded(error = null) {\n", + " const el = document.getElementById(null);\n", + " if (el != null) {\n", + " const html = (() => {\n", + " if (typeof root.Bokeh === \"undefined\") {\n", + " if (error == null) {\n", + " return \"BokehJS is loading ...\";\n", + " } else {\n", + " return \"BokehJS failed to load.\";\n", + " }\n", + " } else {\n", + " const prefix = `BokehJS ${root.Bokeh.version}`;\n", + " if (error == null) {\n", + " return `${prefix} successfully loaded.`;\n", + " } else {\n", + " return `${prefix} encountered errors while loading and may not function as expected.`;\n", + " }\n", + " }\n", + " })();\n", + " el.innerHTML = html;\n", + "\n", + " if (error != null) {\n", + " const wrapper = document.createElement(\"div\");\n", + " wrapper.style.overflow = \"auto\";\n", + " wrapper.style.height = \"5em\";\n", + " wrapper.style.resize = \"vertical\";\n", + " const content = document.createElement(\"div\");\n", + " content.style.fontFamily = \"monospace\";\n", + " content.style.whiteSpace = \"pre-wrap\";\n", + " content.style.backgroundColor = \"rgb(255, 221, 221)\";\n", + " content.textContent = error.stack ?? error.toString();\n", + " wrapper.append(content);\n", + " el.append(wrapper);\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(() => display_loaded(error), 100);\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.6.3.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " try {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "\n", + " } catch (error) {throw error;\n", + " }} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "'use strict';\n(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded(error = null) {\n const el = document.getElementById(null);\n if (el != null) {\n const html = (() => {\n if (typeof root.Bokeh === \"undefined\") {\n if (error == null) {\n return \"BokehJS is loading ...\";\n } else {\n return \"BokehJS failed to load.\";\n }\n } else {\n const prefix = `BokehJS ${root.Bokeh.version}`;\n if (error == null) {\n return `${prefix} successfully loaded.`;\n } else {\n return `${prefix} encountered errors while loading and may not function as expected.`;\n }\n }\n })();\n el.innerHTML = html;\n\n if (error != null) {\n const wrapper = document.createElement(\"div\");\n wrapper.style.overflow = \"auto\";\n wrapper.style.height = \"5em\";\n wrapper.style.resize = \"vertical\";\n const content = document.createElement(\"div\");\n content.style.fontFamily = \"monospace\";\n content.style.whiteSpace = \"pre-wrap\";\n content.style.backgroundColor = \"rgb(255, 221, 221)\";\n content.textContent = error.stack ?? error.toString();\n wrapper.append(content);\n el.append(wrapper);\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(() => display_loaded(error), 100);\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.6.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n try {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n\n } catch (error) {throw error;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.bokehjs_exec.v0+json": "", + "text/html": [ + "" + ] + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "server_id": "48cdc89c96e848da8cd1f5b231ef05be" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "output_notebook(resources=None, verbose=False, hide_banner=True)\n", + "show(mem_usage_chart, notebook_url=\"http://127.0.0.1:8888\", port=8889)" + ] + }, + { + "cell_type": "markdown", + "id": "398da24c", + "metadata": {}, + "source": [ + "Let's first see how memory utilization grows when running a regular python code. We're adding 50k random string elements to a regular Python list in 100 iterations. This totals to 5M data elemens added. Let's see how this performs ..." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "1e8ae17f", + "metadata": {}, + "outputs": [], + "source": [ + "result = []\n", + "def generate_sequence(result, length, batch):\n", + " for _ in range(length):\n", + " result.extend([random_string() for _ in range(batch)])\n", + " print(\"Task finished\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "bc9ee05f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Task finished\n", + "Task finished\n" + ] + } + ], + "source": [ + "task = executor.submit(generate_sequence, result, length=100, batch = 50000)" + ] + }, + { + "cell_type": "markdown", + "id": "5284f2bb", + "metadata": {}, + "source": [ + "The memory just continues to grow and grow and would eventually crash the process with \"out of memory error\". In Python we can release memory by simply emptying the list." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "b410f3b0", + "metadata": {}, + "outputs": [], + "source": [ + "result = []" + ] + }, + { + "cell_type": "markdown", + "id": "b2a7007c", + "metadata": {}, + "source": [ + "### Ok, so how does **dbzero** differ in this matter ?\n", + "In ``dbzero`` you most of the time work like with a regular Python code but need not worry about memory limits anymore. That's right, even if its terabytes of data to deal with, your process will never exceed limits which you define by yourself." + ] + }, + { + "cell_type": "markdown", + "id": "9629b52a", + "metadata": {}, + "source": [ + "After initialized, ``dbzero`` will preoccupy some slight amount of your memory ..." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "b5765c47", + "metadata": {}, + "outputs": [], + "source": [ + "db0.init(dbzero_root = \"/dbzero\", prefix = \"data\")" + ] + }, + { + "cell_type": "markdown", + "id": "ea8e0a14", + "metadata": {}, + "source": [ + "But you can control how much of the additional memory it uses by invoking the 'set_cache_size' method." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "559db1c4", + "metadata": {}, + "outputs": [], + "source": [ + "db0.set_cache_size(128 << 20)" + ] + }, + { + "cell_type": "markdown", + "id": "a950abe1", + "metadata": {}, + "source": [ + "Let's now repeat the test using db0.list (a list object inside the DB0 space). Watch carefully how the memory utilization stops at some point (when the defined cache limit is reached) and does not grow no matter how much data you put into your list." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "630c5bdc", + "metadata": {}, + "outputs": [], + "source": [ + "db0_result = db0.list()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "2d7c89c2", + "metadata": {}, + "outputs": [], + "source": [ + "def db0_generate_sequence(result, length, batch):\n", + " for _ in range(length):\n", + " result.extend([random_string() for _ in range(batch)]) \n", + " print(\"Task finished\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "b275de08", + "metadata": {}, + "outputs": [], + "source": [ + "task = executor.submit(db0_generate_sequence, db0_result, length=100, batch = 50000)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "89276c91", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5000000\n" + ] + }, + { + "data": { + "text/plain": [ + "'1pXfgYf8dYXN'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(len(db0_result))\n", + "db0_result[12313]" + ] + }, + { + "cell_type": "markdown", + "id": "543fc1e3", + "metadata": {}, + "source": [ + "### Well, so where is the data actually stored in this case ?\n", + "DB0 implements memory exchange algorithms. It fetches data from the cloud or, in case of the local version from the filesystem on a need to basis and retains in a local cache to allow rapid access in the future. The process is completely transparent to the developer." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "50e3e662", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0eeec23a", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/.ipynb_checkpoints/hello.db0_4-checkpoint.ipynb b/notebooks/hello/.ipynb_checkpoints/hello.db0_4-checkpoint.ipynb new file mode 100644 index 00000000..e87d4348 --- /dev/null +++ b/notebooks/hello/.ipynb_checkpoints/hello.db0_4-checkpoint.ipynb @@ -0,0 +1,1125 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a0014c12", + "metadata": {}, + "source": [ + "## Introducing DBZero (4/12). So how fast is it?" + ] + }, + { + "cell_type": "markdown", + "id": "d045f70b", + "metadata": {}, + "source": [ + "Hey there! In this notebook, we'll be exploring how fast DBZero really is. Unfortunately, there's no straightforward answer to this question, as performance can be influenced by various factors such as hardware setup, available RAM, network latencies (in the cloud version), or even specific usage patterns. However, I can tell you that DBZero is definitely a speedy platform.\n", + "\n", + "To give you a better idea of how it stacks up against other technologies, we'll take a look at a few real-world use cases. We'll also discuss some techniques you can use to improve the performance of specific operations. So, buckle up and let's dive into the world of DBZero performance!" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "5a26338a", + "metadata": {}, + "outputs": [], + "source": [ + "import dbzero as db0\n", + "from performance_charts import performance_chart, performance_plot, add_measurement, init_chart\n", + "from bokeh.io import show, output_notebook\n", + "from demo_utils import Speedometer" + ] + }, + { + "cell_type": "markdown", + "id": "b981af4c", + "metadata": {}, + "source": [ + "To start, we'll create a bar chart that displays the number of operations that can be performed per second. As we run our test cases, the chart will be updated in real-time to reflect the latest results." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "9b5dd9a8", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + "const JS_MIME_TYPE = 'application/javascript';\n", + " const HTML_MIME_TYPE = 'text/html';\n", + " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " const CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " const script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " const cell = handle.cell;\n", + "\n", + " const id = cell.output_area._bokeh_element_id;\n", + " const server_id = cell.output_area._bokeh_server_id;\n", + " // Clean up Bokeh references\n", + " if (id != null && id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd_clean, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " const id = msg.content.text.trim();\n", + " if (id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd_destroy);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " const output_area = handle.output_area;\n", + " const output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " const bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " const script_attrs = bk_div.children[0].attributes;\n", + " for (let i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " const toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " const events = require('base/js/events');\n", + " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " const NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded() {\n", + " const el = document.getElementById(null);\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS is loading...\";\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(display_loaded, 100)\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(null);\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.bokehjs_exec.v0+json": "", + "text/html": [ + "" + ] + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "server_id": "3ae81c88c336426e8364323415cc1286" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "init_chart([\"python\", \"pg\", \"dbzero\"], title=\"Performance Comparison of Object Creation\")\n", + "output_notebook(resources=None, verbose=False, hide_banner=True)\n", + "show(performance_chart, notebook_url=\"http://192.168.8.125:8888\", port=8889)" + ] + }, + { + "cell_type": "markdown", + "id": "688f3f88", + "metadata": {}, + "source": [ + "To keep things simple, we'll be using a dataset that contains just three columns: first name, surname, and address." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3205d83e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
first_namesurnameaddress
0TawandaCAIZA250 Rt 59
1SandiTERISSI555 East Main St
2GemmaPISITELLO900 Boston Post Road
3KateBUTTERFLY1450 No Brindlee Mtn Pkwy
4MarileeNEAMȚU655 Boston Post Rd
............
39995BeckhamHOLOTESCU656 New Haven Ave
39996CosmoŠOBER655 Boston Post Rd
39997DurwardSTRICKER-BAROLIN330 Sutton Rd
39998PricillaBOCANERA100 Elm Ridge Center Dr
39999LenoraFINDLEY85 Crooked Hill Road
\n", + "

40000 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " first_name surname address\n", + "0 Tawanda CAIZA 250 Rt 59\n", + "1 Sandi TERISSI 555 East Main St\n", + "2 Gemma PISITELLO 900 Boston Post Road\n", + "3 Kate BUTTERFLY 1450 No Brindlee Mtn Pkwy\n", + "4 Marilee NEAMȚU 655 Boston Post Rd\n", + "... ... ... ...\n", + "39995 Beckham HOLOTESCU 656 New Haven Ave\n", + "39996 Cosmo ŠOBER 655 Boston Post Rd\n", + "39997 Durward STRICKER-BAROLIN 330 Sutton Rd\n", + "39998 Pricilla BOCANERA 100 Elm Ridge Center Dr\n", + "39999 Lenora FINDLEY 85 Crooked Hill Road\n", + "\n", + "[40000 rows x 3 columns]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "df = pd.read_csv(\"/src/dev/notebooks/data/identities_1M.csv.gzip\", compression=\"gzip\", nrows=40000)\n", + "df" + ] + }, + { + "cell_type": "markdown", + "id": "25c679f1", + "metadata": {}, + "source": [ + "We want to make sure our measurements are accurate, so it's best to avoid pulling rows from the data frame (which are stored as columns). Instead, let's work with in-memory row tuples to get the most reliable results." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "804aa715", + "metadata": {}, + "outputs": [], + "source": [ + "rows = [row for _, row in df.iterrows()]" + ] + }, + { + "cell_type": "markdown", + "id": "e46f7ae1", + "metadata": {}, + "source": [ + "What if we wanted to create regular Python in-memory objects that hold this same data? Well, we can measure the performance of this operation by tracking how many objects we're able to create in a given unit of time.\n", + "\n", + "To do this, I've included a function below that you can use to measure the performance of creating these objects. Once you run the code, be sure to check out the chart above to see the results (note that the chart displays the performance in kOPS)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "cd3cf5a0", + "metadata": {}, + "outputs": [], + "source": [ + "from demo_utils import Speedometer\n", + "\n", + "class PyPerson:\n", + " def __init__(self, *args):\n", + " self.first_name = args[0]\n", + " self.surname = args[1]\n", + " self.address = args[2]\n", + " \n", + "def test_load_objects_to_python():\n", + " meter = Speedometer()\n", + " meter.start()\n", + " for row in rows:\n", + " p = PyPerson(*row)\n", + " meter.measure(len(df))\n", + " add_measurement(\"python\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "70df1ff9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pure Python: 287347.48466536024 operations/sec\n" + ] + } + ], + "source": [ + "test_load_objects_to_python()" + ] + }, + { + "cell_type": "markdown", + "id": "bc21b6f1", + "metadata": {}, + "source": [ + "Just to give you an idea, on my machine, I was able to create these in-memory objects at a rate of roughly 300k per second. Now, let's take a look at what happens when we try the same operation with PostgreSQL using SQLAlchemy (without any indexing at this stage)." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f34f6b83", + "metadata": {}, + "outputs": [], + "source": [ + "from sqlalchemy import create_engine, text, Table, Column, Integer, String\n", + "from sqlalchemy.orm import Mapped\n", + "from sqlalchemy.orm import mapped_column\n", + "from sqlalchemy.orm import relationship\n", + "from sqlalchemy.orm import DeclarativeBase, Session\n", + "\n", + "\n", + "class Base(DeclarativeBase):\n", + " pass\n", + "\n", + "\n", + "class PgPerson(Base):\n", + " __tablename__ = \"Persons\"\n", + " \n", + " id: Mapped[int] = mapped_column(primary_key=True)\n", + " first_name: Mapped[str] = mapped_column(String(), index=False)\n", + " surname: Mapped[str] = mapped_column(String(), index=False)\n", + " address: Mapped[str] = mapped_column(String())\n", + " \n", + " def __repr__(self) -> str:\n", + " return f\"{self.surname}, {self.first_name}. Address: {self.address}\"\n", + " \n", + "engine = create_engine('postgresql+psycopg2://root:root@192.168.8.125/test_db', echo=False)\n", + "Base.metadata.create_all(engine)\n", + "\n", + "def test_load_objects_to_postgres():\n", + " meter = Speedometer()\n", + " session = Session(engine) \n", + " # Clear any data remnants\n", + " session.query(PgPerson).delete()\n", + " meter.start()\n", + " for row in rows:\n", + " session.add(PgPerson(first_name=row[0], surname=row[1], address=row[2]))\n", + " # Time without commit and session close\n", + " meter.measure(len(df))\n", + " session.commit()\n", + " session.close()\n", + " add_measurement(\"pg\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "fff18cb7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SQLAlchemy + PostgreSQL: 40428.21145158946 operations/sec\n" + ] + } + ], + "source": [ + "test_load_objects_to_postgres()" + ] + }, + { + "cell_type": "markdown", + "id": "fb88d2a7", + "metadata": {}, + "source": [ + "Interestingly, when using SQLAlchemy ORM with PostgreSQL, we found that the performance was only about 1/10th of the pure Python speed (excluding the commit time). This is understandable since we not only need to construct Python objects using the ORM, but we also need to translate them to SQL queries and send them to the engine, where they are finally persisted.\n", + "\n", + "Now, let's switch gears and see how the same operation performs on DBZero." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "22f3c575", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero initialized for tenant: itx\n" + ] + } + ], + "source": [ + "db0.init()" + ] + }, + { + "cell_type": "markdown", + "id": "6d5c5b7e", + "metadata": {}, + "source": [ + "Our first approach is to use a Python-native syntax for working with DBZero. It's worth noting that this code differs from the pure Python code by just a single annotation." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "e2f155c4", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.keepit\n", + "class DB0Person:\n", + " def __init__(self, *args):\n", + " self.first_name = args[0]\n", + " self.surname = args[1]\n", + " self.address = args[2]\n", + " \n", + "def test_load_objects_to_db0():\n", + " meter = Speedometer()\n", + " meter.start()\n", + " for row in rows:\n", + " p = DB0Person(*row)\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "ec875d8d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 145967.78836854364 operations/sec\n" + ] + } + ], + "source": [ + "test_load_objects_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "fd42b4f5", + "metadata": {}, + "source": [ + "When I ran this code, I was able to achieve a performance of around 154k objects per second, which is somewhere in between the performance of PostgreSQL and pure Python. This seems like a reasonable result, given that we need to create Python objects and put them into the DBZero space, which adds some additional time.\n", + "\n", + "However, the good news is that DBZero offers a few additional techniques that can significantly improve the performance of object creation tasks. So, let's explore those next!" + ] + }, + { + "cell_type": "markdown", + "id": "a5010c15", + "metadata": {}, + "source": [ + "#### Ok, so the performance is not too bad. But you say it can be improved... how then?" + ] + }, + { + "cell_type": "markdown", + "id": "c26732c6", + "metadata": {}, + "source": [ + "Before we dive into those techniques, let's take a moment to understand how the default object initializers in DBZero work.\n", + "\n", + "By default, if we omit the user-defined `__init__` method, DBZero will provide a built-in one. This is important to keep in mind as we explore ways to optimize object creation in DBZero." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "2e275a37", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.keepit\n", + "class DB0DefaultPerson:\n", + " def __repr__(self) -> str:\n", + " return f\"{self.surname}, {self.first_name}. Address: {self.address}\"\n", + "\n", + "def test_load_default_objects_to_db0():\n", + " meter = Speedometer()\n", + " meter.start()\n", + " for row in rows:\n", + " p = DB0DefaultPerson(first_name = row[0], surname=row[1], address=row[2])\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "f73a1473", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 116000.34588983137 operations/sec\n" + ] + } + ], + "source": [ + "test_load_default_objects_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "a77288b2", + "metadata": {}, + "source": [ + "#### While the performance of built-in initializers is similar, they can help avoid some boilerplate code. But are they useful in any other way?\n", + "Yes, they are. One key advantage is that default initializers can be fully controlled by DBZero. This means that DBZero knows that no special operations are performed on fields before they're assigned as object members, which enables optimizations.\n", + "\n", + "For example, DBZero adds a static method called `__batch_init__` to classes with built-in initializers. This method can be used to initialize multiple objects at once, which can be much faster than initializing objects one at a time." + ] + }, + { + "cell_type": "markdown", + "id": "4ba045a3", + "metadata": {}, + "source": [ + "#### What does __batch_init__ do and how can I use it?\n", + "Let's take a closer look at an example of how to use __batch_init__. This method takes two positional arguments: a tuple of field names and a source of rows (e.g. a list or a generator). The result is an iterable that must be iterated over to create new DB0 Python objects." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "ab0b7b9b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fox, Adam. Address: Dallas\n", + "Wasilewski, Jacek. Address: Gdynia\n" + ] + } + ], + "source": [ + "friends = [(\"Adam\", \"Fox\", \"Dallas\"), (\"Jacek\", \"Wasilewski\", \"Gdynia\")]\n", + "for p in DB0DefaultPerson.__batch_init__([\"first_name\", \"surname\", \"address\"], friends):\n", + " print(p)" + ] + }, + { + "cell_type": "markdown", + "id": "e2262e8f", + "metadata": {}, + "source": [ + "#### It's faster than the regular __init__, right?\n", + "Yes, you're right! Using `__batch_init__` can be much faster than using the regular `__init__` method.\n", + "\n", + "Let's measure how much faster it is. We can do this by pulling out Python objects that were initialized with rows using `__batch_init__`." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "8b5f6061", + "metadata": {}, + "outputs": [], + "source": [ + "def test_batch_load_objects_to_db0():\n", + " meter = Speedometer()\n", + " meter.start()\n", + " for _ in DB0DefaultPerson.__batch_init__((\"first_name\", \"surname\", \"address\"), rows):\n", + " pass\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "4d0bae61", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 230970.5340265098 operations/sec\n" + ] + } + ], + "source": [ + "test_batch_load_objects_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "b2e1171e", + "metadata": {}, + "source": [ + "On my machine, the performance improved by about 50% (as shown in the chart at the top of this document). However, if the objects are not needed immediately, we can further improve performance by using the \"express\" mode. In this mode, the objects are created in DB0 but are not returned to Python." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0b0300ce", + "metadata": {}, + "outputs": [], + "source": [ + "def test_express_batch_load_objects_to_db0():\n", + " meter = Speedometer()\n", + " meter.start()\n", + " DB0DefaultPerson.__batch_init__((\"first_name\", \"surname\", \"address\"), rows, express=True)\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "2da91f29", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 297775.37969338667 operations/sec\n" + ] + } + ], + "source": [ + "test_express_batch_load_objects_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "1d62a66d", + "metadata": {}, + "source": [ + "#### Nice, so now it's almost as fast as in-memory Python.\n", + "Yet it is, and we have even more techniques to further improve performance.\n", + "\n", + "As already mentioned, a pandas data frame actually consists of columns, which are numpy columns stored in memory. We can take advantage of this by passing the entire pandas data frame to `__batch_init__`, which will pull the relevant columns by name. This can make the process even more efficient." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "93dbb955", + "metadata": {}, + "outputs": [], + "source": [ + "def test_batch_load_objects_from_columns_to_db0():\n", + " meter = Speedometer()\n", + " meter.measure(0)\n", + " for p in DB0DefaultPerson.__batch_init__((\"first_name\", \"surname\", \"address\"), data=df):\n", + " pass\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "0c75b270", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 554914.6291588771 operations/sec\n" + ] + } + ], + "source": [ + "test_batch_load_objects_from_columns_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "e9458dd7", + "metadata": {}, + "source": [ + "Express mode can also be used when creating objects from a pandas data frame, which can further boost performance." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "0bd862b4", + "metadata": {}, + "outputs": [], + "source": [ + "def test_express_batch_load_objects_from_columns_to_db0():\n", + " meter = Speedometer()\n", + " meter.measure(0)\n", + " DB0DefaultPerson.__batch_init__((\"first_name\", \"surname\", \"address\"), data=df, express=True)\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "57588d6d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 904560.3568689611 operations/sec\n" + ] + } + ], + "source": [ + "test_express_batch_load_objects_from_columns_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "5e89cdbb", + "metadata": {}, + "source": [ + "Ok, let's take another look at our charts and see the results below." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "927e8d30", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"c0a4cfec-e1d5-4fdd-8d2c-8343b053570f\":{\"version\":\"3.0.3\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1162\",\"attributes\":{\"width\":800,\"height\":400,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1164\"},\"y_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1174\",\"attributes\":{\"factors\":[\"Pure Python\",\"DBZero\",\"SQLAlchemy + PostgreSQL\"]}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1176\"},\"y_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1178\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1165\",\"attributes\":{\"text\":\"Performance Comparison of Object Creation\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1214\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1159\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1160\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1161\"},\"data\":{\"type\":\"map\",\"entries\":[[\"bar_labels\",[\"Pure Python\",\"DBZero\",\"SQLAlchemy + PostgreSQL\"]],[\"bar_values\",[287.34748466536024,904.5603568689611,40.428211451589455]],[\"bar_colors\",[\"#0366d6\",\"#00b3b3\",\"#00008B\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1215\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1216\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1211\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1212\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1213\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1171\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1193\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1194\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1195\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1196\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1197\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1198\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1199\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1187\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1189\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1188\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1190\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1180\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1182\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1181\"},\"axis_label\":\"thousands of operations / sec\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1183\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1186\",\"attributes\":{\"axis\":{\"id\":\"p1180\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1192\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1187\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"c0a4cfec-e1d5-4fdd-8d2c-8343b053570f\",\"roots\":{\"p1162\":\"d5478d17-e004-4f39-a113-8a3ca719948a\"},\"root_ids\":[\"p1162\"]}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1162" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "show(performance_plot())" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "fd31fc95", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "markdown", + "id": "ab093114", + "metadata": {}, + "source": [ + "Stay tuned, in the next episode we'll dive into the performance of lookup queries." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "211dc688", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/.ipynb_checkpoints/hello.db0_5-checkpoint.ipynb b/notebooks/hello/.ipynb_checkpoints/hello.db0_5-checkpoint.ipynb new file mode 100644 index 00000000..1571442b --- /dev/null +++ b/notebooks/hello/.ipynb_checkpoints/hello.db0_5-checkpoint.ipynb @@ -0,0 +1,945 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "67771bd8", + "metadata": {}, + "source": [ + "## Introducing DBZero (5/12). Lookup query performance." + ] + }, + { + "cell_type": "markdown", + "id": "8472de76", + "metadata": {}, + "source": [ + "Hey there! In this tutorial, we'll be checking out how well some common queries used in apps perform. These queries include retrieving an object by its ID or searching for specific criteria." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "21f085da", + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "import dbzero as db0\n", + "import pandas as pd\n", + "from performance_charts import performance_plot, add_measurement, init_chart\n", + "from bokeh.io import show, output_notebook\n", + "from demo_utils import Speedometer\n", + "\n", + "from sqlalchemy import create_engine, text, Table, Column, Integer, String, func, and_\n", + "from sqlalchemy.orm import Mapped\n", + "from sqlalchemy.orm import mapped_column\n", + "from sqlalchemy.orm import relationship\n", + "from sqlalchemy.orm import DeclarativeBase, Session" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "dca44a5b", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + "const JS_MIME_TYPE = 'application/javascript';\n", + " const HTML_MIME_TYPE = 'text/html';\n", + " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " const CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " const script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " const cell = handle.cell;\n", + "\n", + " const id = cell.output_area._bokeh_element_id;\n", + " const server_id = cell.output_area._bokeh_server_id;\n", + " // Clean up Bokeh references\n", + " if (id != null && id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd_clean, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " const id = msg.content.text.trim();\n", + " if (id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd_destroy);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " const output_area = handle.output_area;\n", + " const output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " const bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " const script_attrs = bk_div.children[0].attributes;\n", + " for (let i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " const toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " const events = require('base/js/events');\n", + " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " const NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded() {\n", + " const el = document.getElementById(null);\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS is loading...\";\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(display_loaded, 100)\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(null);\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "init_chart([\"pg\", \"dbzero\"])\n", + "output_notebook(resources=None, verbose=False, hide_banner=True)" + ] + }, + { + "cell_type": "markdown", + "id": "6cd3e0c1", + "metadata": {}, + "source": [ + "Alright, let's go ahead and load up two datasets with just one column each. These columns will contain commonly used first names and surnames of individuals." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "92462b58", + "metadata": {}, + "outputs": [], + "source": [ + "surnames = pd.read_csv(\"/src/dev/notebooks/data/surnames.csv.gzip\", compression=\"gzip\", \n", + " header=None)[0].apply(lambda x: str(x)[:30])\n", + "first_names = pd.read_csv(\"/src/dev/notebooks/data/first_names.csv.gzip\", compression=\"gzip\", \n", + " header=None)[0].apply(lambda x: str(x)[:30])" + ] + }, + { + "cell_type": "markdown", + "id": "cfc6ec7e", + "metadata": {}, + "source": [ + "Assuming you've already used the `load_lookup_test_data.py` script to load the 1M datasets to PostgreSQL and DB0, we can now proceed. If you haven't done this yet, please go back and make sure to run the script now. This time around, we've indexed the \"first_name\" and \"surname\" columns to enable speedy lookups in PostgreSQL." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "94c10587", + "metadata": {}, + "outputs": [], + "source": [ + "class Base(DeclarativeBase):\n", + " pass\n", + "\n", + "\n", + "class PgPerson(Base):\n", + " __tablename__ = \"Persons1M\"\n", + " \n", + " id: Mapped[int] = mapped_column(primary_key=True)\n", + " first_name: Mapped[str] = mapped_column(String(), index=True)\n", + " surname: Mapped[str] = mapped_column(String(), index=True)\n", + " address: Mapped[str] = mapped_column(String(), nullable=True)\n", + " \n", + "engine = create_engine('postgresql+psycopg2://root:root@192.168.8.125/test_db', echo=False)\n", + "Base.metadata.create_all(engine)" + ] + }, + { + "cell_type": "markdown", + "id": "b9ee0ef2", + "metadata": {}, + "source": [ + "For the lookup performance test, we'll just be generating random IDs (within the range available in the data) and retrieving objects from the database based on those IDs." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "1d5ba4d0", + "metadata": {}, + "outputs": [], + "source": [ + "def test_postgres_lookup_by_id(limit = 100000):\n", + " meter = Speedometer()\n", + " with Session(engine) as session:\n", + " min_id = session.query(func.min(PgPerson.id)).scalar()\n", + " max_id = session.query(func.max(PgPerson.id)).scalar()\n", + " \n", + " meter.start()\n", + " for _ in range(limit):\n", + " person = session.query(PgPerson).filter_by(id=random.randrange(min_id, max_id)).one_or_none()\n", + " meter.measure(limit)\n", + " add_measurement(\"pg\", meter.speed(), test=\"lookup_by_id\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "399a6ec0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SQLAlchemy + PostgreSQL: 1792.9085100816772 operations/sec\n" + ] + } + ], + "source": [ + "test_postgres_lookup_by_id()" + ] + }, + { + "cell_type": "markdown", + "id": "a608dc51", + "metadata": {}, + "source": [ + "To present the results, we'll create a bar chart..." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "0133335b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"787d1fc3-d52b-412d-84ab-e8c1d3830588\":{\"version\":\"3.0.3\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1007\",\"attributes\":{\"width\":800,\"height\":400,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1009\"},\"y_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1019\",\"attributes\":{\"factors\":[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1021\"},\"y_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1023\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1010\",\"attributes\":{\"text\":\"Lookup by object ID performance comparison\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1059\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1004\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1006\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1005\"},\"data\":{\"type\":\"map\",\"entries\":[[\"bar_labels\",[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]],[\"bar_values\",[0,1.792908510081677]],[\"bar_colors\",[\"#00b3b3\",\"#00008B\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1060\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1061\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1056\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1057\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1058\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1015\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1038\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1039\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1040\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1041\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1042\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1043\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1044\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1032\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1035\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1033\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1034\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1025\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1028\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1026\"},\"axis_label\":\"thousands of operations / sec\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1027\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1031\",\"attributes\":{\"axis\":{\"id\":\"p1025\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1037\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1032\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"787d1fc3-d52b-412d-84ab-e8c1d3830588\",\"roots\":{\"p1007\":\"388eb638-9c6e-4f19-950d-dce47a047a6c\"},\"root_ids\":[\"p1007\"]}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1007" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "show(performance_plot(test=\"lookup_by_id\"))" + ] + }, + { + "cell_type": "markdown", + "id": "a47c533a", + "metadata": {}, + "source": [ + "As for DB0, the assigned IDs aren't consecutive, so we'll need to take a different approach. For instance, we could randomly select objects from the list of 1 million entries (instead of using IDs, we'll use list indices 0 - N-1). Now, let's see how well this approach performs." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "19dec8f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero initialized for tenant: itx\n" + ] + } + ], + "source": [ + "db0.init()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b708f592", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.keepit\n", + "class DB0_Person1M:\n", + " pass\n", + "\n", + "\n", + "def test_db0_lookup_by_index(limit = 100000):\n", + " meter = Speedometer()\n", + " l = db0.list(key=\"/dbzero/demo/hello.db0_5/object_list\")\n", + " min_id, max_id = 0, len(l) - 1\n", + " meter.start()\n", + " for _ in range(limit):\n", + " person = l[random.randrange(min_id, max_id)]\n", + " meter.measure(limit)\n", + " add_measurement(\"dbzero\", meter.speed(), test=\"lookup_by_id\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "dc265967", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 97350.61072253388 operations/sec\n" + ] + } + ], + "source": [ + "test_db0_lookup_by_index()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "5055015d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"d48fca5f-6ad9-44bc-8e7f-fab39c76a02a\":{\"version\":\"3.0.3\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1143\",\"attributes\":{\"width\":800,\"height\":400,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1145\"},\"y_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1155\",\"attributes\":{\"factors\":[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1157\"},\"y_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1159\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1146\",\"attributes\":{\"text\":\"Lookup by object ID performance comparison\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1195\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1140\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1142\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1141\"},\"data\":{\"type\":\"map\",\"entries\":[[\"bar_labels\",[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]],[\"bar_values\",[97.35061072253387,1.792908510081677]],[\"bar_colors\",[\"#00b3b3\",\"#00008B\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1196\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1197\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1192\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1193\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1194\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1151\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1174\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1175\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1176\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1177\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1178\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1179\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1180\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1168\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1171\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1169\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1170\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1161\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1164\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1162\"},\"axis_label\":\"thousands of operations / sec\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1163\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1167\",\"attributes\":{\"axis\":{\"id\":\"p1161\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1173\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1168\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"d48fca5f-6ad9-44bc-8e7f-fab39c76a02a\",\"roots\":{\"p1143\":\"8e5e6111-c0d3-40fa-99ca-112994e7fb26\"},\"root_ids\":[\"p1143\"]}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1143" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "show(performance_plot(test=\"lookup_by_id\"))" + ] + }, + { + "cell_type": "markdown", + "id": "3f06eb11", + "metadata": {}, + "source": [ + "For a more appropriate test that measures the actual fetch operation, we would first retrieve all existing IDs and then randomly select and fetch objects with those IDs." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "bb8a9d0e", + "metadata": {}, + "outputs": [], + "source": [ + "def test_db0_lookup_by_id(limit = 100000):\n", + " meter = Speedometer()\n", + " all_ids = [db0.id(o) for o in db0.list(key=\"/dbzero/demo/hello.db0_5/object_list\")]\n", + " meter.start()\n", + " for _ in range(limit):\n", + " person = db0.get(DB0_Person1M, random.choice(all_ids))\n", + " meter.measure(limit)\n", + " add_measurement(\"dbzero\", meter.speed(), test=\"lookup_by_id\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "c246db25", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 479393.0615380813 operations/sec\n" + ] + } + ], + "source": [ + "test_db0_lookup_by_id()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "6b026083", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"eb64eee6-0ceb-4d62-b2d8-2026d7020d5d\":{\"version\":\"3.0.3\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1292\",\"attributes\":{\"width\":800,\"height\":400,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1294\"},\"y_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1304\",\"attributes\":{\"factors\":[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1306\"},\"y_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1308\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1295\",\"attributes\":{\"text\":\"Lookup by object ID performance comparison\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1344\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1289\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1291\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1290\"},\"data\":{\"type\":\"map\",\"entries\":[[\"bar_labels\",[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]],[\"bar_values\",[479.3930615380813,1.792908510081677]],[\"bar_colors\",[\"#00b3b3\",\"#00008B\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1345\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1346\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1341\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1342\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1343\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1300\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1323\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1324\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1325\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1326\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1327\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1328\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1329\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1317\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1320\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1318\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1319\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1310\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1313\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1311\"},\"axis_label\":\"thousands of operations / sec\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1312\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1316\",\"attributes\":{\"axis\":{\"id\":\"p1310\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1322\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1317\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"eb64eee6-0ceb-4d62-b2d8-2026d7020d5d\",\"roots\":{\"p1292\":\"04070d81-9cee-4349-b782-5874634eb8cf\"},\"root_ids\":[\"p1292\"]}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1292" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "show(performance_plot(test=\"lookup_by_id\"))" + ] + }, + { + "cell_type": "markdown", + "id": "0e5b5941", + "metadata": {}, + "source": [ + "#### I understand what you're saying. Apps usually don't just retrieve objects based on their IDs.
How do other querying patterns perform in comparison?\n", + "In a more realistic scenario, you might want to look something up first and then add the record to the database - for example, checking if a person already exists and only registering them in the database if they're unique. Of course, we want to give the users some feedback (like \"name taken\") before actually committing the operation. So, we'll break this process down into two parts - the lookup and the commit." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "08718fc8", + "metadata": {}, + "outputs": [], + "source": [ + "class PgPersonMix(Base):\n", + " __tablename__ = \"PersonsMix\"\n", + " \n", + " id: Mapped[int] = mapped_column(primary_key=True)\n", + " first_name: Mapped[str] = mapped_column(String(), index=True)\n", + " surname: Mapped[str] = mapped_column(String(), index=True)\n", + " address: Mapped[str] = mapped_column(String(), nullable=True)\n", + " \n", + "Base.metadata.create_all(engine)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "2aa32ddd", + "metadata": {}, + "outputs": [], + "source": [ + "def test_postgres_mixed_lookup_then_commit(limit = 10000):\n", + " meter = Speedometer()\n", + " with Session(engine) as session:\n", + " # Clear any leftovers\n", + " session.query(PgPersonMix).delete()\n", + " meter.start()\n", + " for _ in range(limit):\n", + " first_name = random.choice(first_names)\n", + " surname = random.choice(surnames)\n", + " # add a new person if no such exists yet\n", + " if session.query(PgPersonMix).filter(\n", + " and_(PgPersonMix.first_name==first_name, PgPersonMix.surname==surname)).first() is None:\n", + " session.add(PgPersonMix(first_name=first_name, surname=surname))\n", + " session.commit()\n", + " meter.measure(limit)\n", + " add_measurement(\"pg\", meter.speed(), test=\"mixed_access\")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "4a8a2df4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SQLAlchemy + PostgreSQL: 46.48888203435324 operations/sec\n" + ] + } + ], + "source": [ + "test_postgres_mixed_lookup_then_commit(1000)" + ] + }, + { + "cell_type": "markdown", + "id": "00495f33", + "metadata": {}, + "source": [ + "To achieve this functionality in DB0, we can use tags! Let me show you an example of how this implementation might look. Just a heads up - we'll be prefixing the tags with \"F\" and \"S\" characters to distinguish between first names and surnames." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "ad4b535a", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.keepit\n", + "class DB0_PersonMix:\n", + " pass\n", + "\n", + "\n", + "def test_db0_mixed_lookup_then_commit(limit = 10000):\n", + " meter = Speedometer()\n", + " meter.start()\n", + " for _ in range(limit):\n", + " first_name = random.choice(first_names)\n", + " surname = random.choice(surnames)\n", + " if not any(db0.find(DB0_PersonMix, (\"F\" + first_name, \"S\" + surname))):\n", + " person = DB0_PersonMix(first_name=first_name, surname=surname, __tags__=(\"F\" + first_name, \"S\" + surname))\n", + " meter.measure(limit)\n", + " add_measurement(\"dbzero\", meter.speed(), test=\"mixed_access\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "b0a7e4d4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 12290.942181432823 operations/sec\n" + ] + } + ], + "source": [ + "test_db0_mixed_lookup_then_commit()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "f05872be", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"9b28670f-f8ee-4ea3-a102-27ee65fa3055\":{\"version\":\"3.0.3\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1454\",\"attributes\":{\"width\":800,\"height\":400,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1456\"},\"y_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1466\",\"attributes\":{\"factors\":[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1468\"},\"y_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1470\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1457\",\"attributes\":{\"text\":\"\\\"Lookup then commit\\\" performance comparison\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1506\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1451\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1453\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1452\"},\"data\":{\"type\":\"map\",\"entries\":[[\"bar_labels\",[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]],[\"bar_values\",[12.290942181432824,0.04648888203435324]],[\"bar_colors\",[\"#00b3b3\",\"#00008B\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1507\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1508\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1503\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1504\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1505\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1462\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1485\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1486\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1487\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1488\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1489\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1490\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1491\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1479\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1482\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1480\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1481\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1472\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1475\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1473\"},\"axis_label\":\"thousands of operations / sec\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1474\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1478\",\"attributes\":{\"axis\":{\"id\":\"p1472\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1484\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1479\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"9b28670f-f8ee-4ea3-a102-27ee65fa3055\",\"roots\":{\"p1454\":\"b9493507-864d-46f1-922d-4590e7c66a01\"},\"root_ids\":[\"p1454\"]}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1454" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "show(performance_plot(test=\"mixed_access\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "695009d6", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6e8b11a", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/hello-db0-1_pl.ipynb b/notebooks/hello/hello-db0-1_pl.ipynb new file mode 100644 index 00000000..b3b7fe0d --- /dev/null +++ b/notebooks/hello/hello-db0-1_pl.ipynb @@ -0,0 +1,248 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4d79e2e4", + "metadata": {}, + "source": [ + "## Wprowadzenie do dbzero (1/12): Rozpoczynamy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "421ce30a", + "metadata": {}, + "outputs": [], + "source": [ + "!rm -rf /dbzero\n", + "import dbzero as db0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "311bbaaa", + "metadata": {}, + "outputs": [], + "source": [ + "db0.init(dbzero_root=\"/dbzero\", prefix = \"data\")" + ] + }, + { + "cell_type": "markdown", + "id": "f63f0a43", + "metadata": {}, + "source": [ + "#### Nasza pierwsza klasa" + ] + }, + { + "cell_type": "markdown", + "id": "b3e207bb", + "metadata": {}, + "source": [ + "Klasy oznaczone `@db0.memo` są przechowywane w nieskończonej pamięci dbzero po utworzeniu.\n", + "Wystarczy oznaczyć klasę i zainicjować jej pola wewnątrz metody `__init__`, tak jak w przypadku każdej zwykłej klasy Pythona." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c5a28b7", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo\n", + "class HelloWorld:\n", + " def __init__(self, name):\n", + " self.name = name\n", + " \n", + " def greet(self):\n", + " print(f\"Cześć {self.name}. Witaj w dbzero!!\")" + ] + }, + { + "cell_type": "markdown", + "id": "e85c296f", + "metadata": {}, + "source": [ + "Możesz używać tej klasy tak jak każdej zwykłej klasy Pythona—tworzyć nowe obiekty i wywoływać jej metody." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a8cd5802", + "metadata": {}, + "outputs": [], + "source": [ + "jan = HelloWorld(\"Jan\")" + ] + }, + { + "cell_type": "markdown", + "id": "19966147", + "metadata": {}, + "source": [ + "Dodajemy tag, aby zapobiec usunięciu tego obiektu przez dbzero po zamknięciu procesu. (Omówimy to zachowanie bardziej szczegółowo później.)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8044af92", + "metadata": {}, + "outputs": [], + "source": [ + "db0.tags(jan).add(\"najlepszy przyjaciel\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10a2d421", + "metadata": {}, + "outputs": [], + "source": [ + "jan.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "6cb872ec", + "metadata": {}, + "source": [ + "#### Więc jaka jest różnica?" + ] + }, + { + "cell_type": "markdown", + "id": "7606d58e", + "metadata": {}, + "source": [ + "Klasy **dbzero** żyją w innej przestrzeni pamięci o specjalnych właściwościach DIST:\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "b091d04f", + "metadata": {}, + "source": [ + "#### Jak mogę uzyskać dostęp do obiektu po zamknięciu programu?\n", + "Jednym ze sposobów jest pobranie jego UUID db0, a następnie odwołanie się do niego za pomocą tego ID. Pamiętasz funkcję `id()` Pythona?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bac6f1bb", + "metadata": {}, + "outputs": [], + "source": [ + "id(jan)" + ] + }, + { + "cell_type": "markdown", + "id": "2f19ae02", + "metadata": {}, + "source": [ + "Każdy obiekt **dbzero** ma zarówno ID Pythona (krótkotrwałe), jak i UUID db0 (trwałe do momentu usunięcia obiektu—podobnie jak usunięcie wiersza w bazie danych)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d6a2874", + "metadata": {}, + "outputs": [], + "source": [ + "db0.uuid(jan)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "098bba05", + "metadata": {}, + "outputs": [], + "source": [ + "dir(jan)" + ] + }, + { + "cell_type": "markdown", + "id": "29a1cebe", + "metadata": {}, + "source": [ + "#### Zapamiętajmy to UUID i kontynuujmy w innym notebooku..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bf98853a", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c5fc541c", + "metadata": {}, + "outputs": [], + "source": [ + "dir(jan)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c71491c6", + "metadata": {}, + "outputs": [], + "source": [ + "type(jan)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8c698420", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/hello-db0-2_pl.ipynb b/notebooks/hello/hello-db0-2_pl.ipynb new file mode 100644 index 00000000..140e9527 --- /dev/null +++ b/notebooks/hello/hello-db0-2_pl.ipynb @@ -0,0 +1,374 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "cb08fd72", + "metadata": {}, + "source": [ + "## Wprowadzenie do **dbzero** (2/12). Listy, relacje i singletony." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "750f4f4d", + "metadata": {}, + "outputs": [], + "source": [ + "import dbzero as db0\n", + "db0.init(dbzero_root = \"/dbzero\", prefix=\"data\")" + ] + }, + { + "cell_type": "markdown", + "id": "0fa1ac68", + "metadata": {}, + "source": [ + "Musimy ponownie zdefiniować naszą klasę. W typowym programie Python po prostu zaimportowalibyśmy ją z modułu." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "edf69229", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo\n", + "class HelloWorld:\n", + " def __init__(self, name):\n", + " self.name = name\n", + " \n", + " def greet(self):\n", + " print(f\"Witaj {self.name}. Witamy w dbzero!!\")" + ] + }, + { + "cell_type": "markdown", + "id": "ea7ae0b9", + "metadata": {}, + "source": [ + "I otwórzmy jej instancję za pomocą wcześniej wygenerowanego UUID (< wklej swoje UUID poniżej >)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "10a881cd", + "metadata": {}, + "outputs": [ + { + "ename": "RuntimeError", + "evalue": "Prefix: 2098673055265944345 not found\n", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[3], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m h \u001b[38;5;241m=\u001b[39m \u001b[43mdb0\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfetch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mHelloWorld\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mDFZ46RQG7QPR3IEBUCAIAAIN\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n", + "\u001b[0;31mRuntimeError\u001b[0m: Prefix: 2098673055265944345 not found\n" + ] + } + ], + "source": [ + "h = db0.fetch(HelloWorld, \"DFZ46RQG7QPR3IEBUCAIAAIN\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "9b89ad62", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'h' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[4], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mh\u001b[49m\u001b[38;5;241m.\u001b[39mgreet()\n", + "\u001b[0;31mNameError\u001b[0m: name 'h' is not defined" + ] + } + ], + "source": [ + "h.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "f289de1c", + "metadata": {}, + "source": [ + "### W porządku, to zadziałało. Instancja pamięta swoje elementy danych.\n", + "Ale pobieranie po ID nie wydaje się zbyt wygodne, jak mogę uzyskać dostęp do moich obiektów w bardziej praktyczny sposób?" + ] + }, + { + "cell_type": "markdown", + "id": "5d23f657", + "metadata": {}, + "source": [ + "Jedną z możliwości jest przechowywanie odniesień do obiektów w innym (nadrzędnym) obiekcie. W świecie baz danych takie powiązanie nazywane byłoby 'relacją'. Jeśli naszym zamiarem jest przechowywanie tylko jednej instancji HelloMany, możemy oznaczyć ją jako" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "b0de389d", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo(singleton = True)\n", + "class HelloMany:\n", + " # przekazujemy listę imion i zostanie utworzonych wiele instancji HelloWorld, które następnie zostaną dodane do listy DB0 'hellos'\n", + " def __init__(self, names):\n", + " self.hellos = [HelloWorld(name) for name in names]\n", + " \n", + " def greet(self):\n", + " for hw in self.hellos:\n", + " hw.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "d0177bea", + "metadata": {}, + "source": [ + "Zwróć uwagę, że obiekt **dbzero** klasy oznaczonej jako ``singleton`` zostanie utworzony tylko raz." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "95243fbe", + "metadata": {}, + "outputs": [], + "source": [ + "many_hellos = HelloMany([\"Andrzej\", \"Alicja\", \"Bartek\", \"Filip\", \"Robert\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "2ee94827", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Witaj Andrzej. Witamy w dbzero!!\n", + "Witaj Alicja. Witamy w dbzero!!\n", + "Witaj Bartek. Witamy w dbzero!!\n", + "Witaj Filip. Witamy w dbzero!!\n", + "Witaj Robert. Witamy w dbzero!!\n" + ] + } + ], + "source": [ + "many_hellos.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "7716f750", + "metadata": {}, + "source": [ + "Po utworzeniu instancji obiekt można ponownie uzyskać dostęp (z innego programu lub po zamknięciu tego programu) bez żadnych argumentów." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3e9c03d3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Witaj Andrzej. Witamy w dbzero!!\n", + "Witaj Alicja. Witamy w dbzero!!\n", + "Witaj Bartek. Witamy w dbzero!!\n", + "Witaj Filip. Witamy w dbzero!!\n", + "Witaj Robert. Witamy w dbzero!!\n" + ] + } + ], + "source": [ + "mh = HelloMany()\n", + "mh.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "4e708260", + "metadata": {}, + "source": [ + "Widzimy, że many_hellos i mh to ten sam obiekt ``dbzero`` i nawet ten sam obiekt Python." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "9207be23", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "140401140747472 140401140747472\n" + ] + } + ], + "source": [ + "print(f\"{id(many_hellos)} {id(mh)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "af8c5898", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "UCEZKEPIYX26NIEBUHJIABYN UCEZKEPIYX26NIEBUHJIABYN\n" + ] + } + ], + "source": [ + "print(f\"{db0.uuid(many_hellos)} {db0.uuid(mh)}\")" + ] + }, + { + "cell_type": "markdown", + "id": "42c2805c", + "metadata": {}, + "source": [ + "### Co więc jest faktycznie przechowywane na liście HelloMany.hellos?\n", + "Podobnie jak w przypadku zwykłych obiektów Python - lista przechowuje odniesienia, a nie pełne instancje. Listy **dbzero** mogą przechowywać proste typy (liczby/ciągi znaków), inne kolekcje (listy, słowniki, zbiory, krotki itp.) lub odniesienia do innych instancji dbzero ``@memo``." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0fc48e00", + "metadata": {}, + "outputs": [], + "source": [ + "for obj in mh.hellos:\n", + " print(db0.uuid(obj))" + ] + }, + { + "cell_type": "markdown", + "id": "c31c34b9", + "metadata": {}, + "source": [ + "A lista **dbzero** działa dokładnie jak każda zwykła lista Python - możesz iterować, wycinać lub uzyskiwać dostęp do jej elementów przez indeks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6e2a7023", + "metadata": {}, + "outputs": [], + "source": [ + "mh.hellos[3].greet()" + ] + }, + { + "cell_type": "markdown", + "id": "9e33d730", + "metadata": {}, + "source": [ + "### Jak duża może być pojedyncza lista?\n", + "W Python normalnie twoja lista byłaby ograniczona przez rozmiar pamięci RAM dostępnej dla twojego procesu (w praktyce, podczas uruchamiania programu - kto wie, jaki jest dokładnie ten limit???). Dla użytkowników DB0 (chmurowych) mamy dobrą wiadomość. Nie ma limitów! Jeśli chcesz, możesz utworzyć listę o rozmiarze znacznie przekraczającym dostępną pamięć. W przypadku wersji lokalnej ten rozmiar jest ograniczony przez dostępną przestrzeń dyskową." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7951b626", + "metadata": {}, + "outputs": [], + "source": [ + "print(len(mh.hellos))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "436b4832", + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(1000):\n", + " mh.hellos.append(HelloWorld(f\"imię-{i}\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c42df9e9", + "metadata": {}, + "outputs": [], + "source": [ + "print(len(mh.hellos))" + ] + }, + { + "cell_type": "markdown", + "id": "045dfdad", + "metadata": {}, + "source": [ + "Zbadajmy wykorzystanie pamięci i limity w następnym notebooku." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "822fc22a", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "69fd898a", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/hello-db0-3_pl.ipynb b/notebooks/hello/hello-db0-3_pl.ipynb new file mode 100644 index 00000000..38cf6d7d --- /dev/null +++ b/notebooks/hello/hello-db0-3_pl.ipynb @@ -0,0 +1,265 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "15f77f54", + "metadata": {}, + "source": [ + "## Wprowadzenie do **dbzero** (3/12): Badanie ograniczeń" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20a5860e", + "metadata": {}, + "outputs": [], + "source": [ + "import dbzero as db0\n", + "from mem_charts import mem_usage_chart, random_string\n", + "from bokeh.io import show, output_notebook\n", + "import concurrent.futures" + ] + }, + { + "cell_type": "markdown", + "id": "529eb523", + "metadata": {}, + "source": [ + "Zaimportowaliśmy pakiet 'bokeh' do wizualizacji obecnego wykorzystania pamięci na wykresie." + ] + }, + { + "cell_type": "markdown", + "id": "5604673c", + "metadata": {}, + "source": [ + "Stwórzmy również executor, aby móc uruchamiać zadania Pythona w tle (w oddzielnym wątku)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dd90646c", + "metadata": {}, + "outputs": [], + "source": [ + "executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)" + ] + }, + { + "cell_type": "markdown", + "id": "ccbd6239", + "metadata": {}, + "source": [ + "Wykres poniżej przedstawia żywe wykorzystanie pamięci przez obecny proces, odświeżane co 1 sekundę." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0bf58a08", + "metadata": {}, + "outputs": [], + "source": [ + "output_notebook(resources=None, verbose=False, hide_banner=True)\n", + "show(mem_usage_chart, notebook_url=\"http://127.0.0.1:8888\", port=8889)" + ] + }, + { + "cell_type": "markdown", + "id": "1fc1acad", + "metadata": {}, + "source": [ + "Zobaczmy najpierw, jak rośnie wykorzystanie pamięci podczas uruchamiania zwykłego kodu Pythona. Dodajemy 50 000 losowych elementów tekstowych do zwykłej listy Pythona w 100 iteracjach. To łącznie 5 milionów dodanych elementów danych. Zobaczmy, jak to działa..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e1d5ab5e", + "metadata": {}, + "outputs": [], + "source": [ + "result = []\n", + "def generate_sequence(result, length, batch):\n", + " for _ in range(length):\n", + " result.extend([random_string() for _ in range(batch)])\n", + " print(\"Task finished\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "477cf909", + "metadata": {}, + "outputs": [], + "source": [ + "task = executor.submit(generate_sequence, result, length=100, batch = 50000)" + ] + }, + { + "cell_type": "markdown", + "id": "3a16cc37", + "metadata": {}, + "source": [ + "Pamięć po prostu nadal rośnie i rośnie i ostatecznie zakończyłaby proces błędem \"brak pamięci\". W Pythonie możemy zwolnić pamięć poprzez zwykłe opróżnienie listy." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e0a08dd8", + "metadata": {}, + "outputs": [], + "source": [ + "result = []" + ] + }, + { + "cell_type": "markdown", + "id": "62c8113d", + "metadata": {}, + "source": [ + "### Dobrze, więc jak **dbzero** różni się w tej kwestii?\n", + "W **dbzero** pracujesz przez większość czasu jak ze zwykłym kodem Pythona, ale nie musisz już martwić się o ograniczenia pamięci. To prawda, nawet jeśli masz do czynienia z terabajtami danych, Twój proces nigdy nie przekroczy limitów, które sam zdefiniujesz." + ] + }, + { + "cell_type": "markdown", + "id": "07cb8306", + "metadata": {}, + "source": [ + "Po inicjalizacji **dbzero** zajmie niewielką ilość Twojej pamięci..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27b340b7", + "metadata": {}, + "outputs": [], + "source": [ + "db0.init(dbzero_root = \"/dbzero\", prefix = \"data\")" + ] + }, + { + "cell_type": "markdown", + "id": "8de40443", + "metadata": {}, + "source": [ + "Ale możesz kontrolować, ile dodatkowej pamięci używa, wywołując metodę 'set_cache_size'." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45b3955f", + "metadata": {}, + "outputs": [], + "source": [ + "db0.set_cache_size(128 << 20)" + ] + }, + { + "cell_type": "markdown", + "id": "30ed17df", + "metadata": {}, + "source": [ + "Powtórzmy teraz test używając db0.list (obiekt listy w przestrzeni dbzero). Obserwuj uważnie, jak wykorzystanie pamięci zatrzymuje się w pewnym momencie (gdy zostanie osiągnięty zdefiniowany limit cache) i nie rośnie bez względu na to, ile danych umieścisz w swojej liście." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9fc1c062", + "metadata": {}, + "outputs": [], + "source": [ + "db0_result = db0.list()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb5949bb", + "metadata": {}, + "outputs": [], + "source": [ + "def db0_generate_sequence(result, length, batch):\n", + " for _ in range(length):\n", + " result.extend([random_string() for _ in range(batch)]) \n", + " print(\"Task finished\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39ec4824", + "metadata": {}, + "outputs": [], + "source": [ + "task = executor.submit(db0_generate_sequence, db0_result, length=100, batch = 50000)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29a62967", + "metadata": {}, + "outputs": [], + "source": [ + "print(len(db0_result))\n", + "db0_result[12313]" + ] + }, + { + "cell_type": "markdown", + "id": "b6e8e86c", + "metadata": {}, + "source": [ + "### No więc gdzie w rzeczywistości są przechowywane dane w tym przypadku?\n", + "dbzero implementuje algorytmy wymiany pamięci. Pobiera dane z chmury lub, w przypadku wersji lokalnej, z systemu plików na zasadzie \"według potrzeby\" i przechowuje je w lokalnym cache, aby umożliwić szybki dostęp w przyszłości. Proces jest całkowicie przezroczysty dla programisty." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bf6652e4", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dee24cf4", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/hello.db0_1.ipynb b/notebooks/hello/hello.db0_1.ipynb new file mode 100644 index 00000000..761c310f --- /dev/null +++ b/notebooks/hello/hello.db0_1.ipynb @@ -0,0 +1,340 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f95d58f5", + "metadata": {}, + "source": [ + "## Introducing dbzero (1/12): Getting Started" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "31d81a69", + "metadata": {}, + "outputs": [], + "source": [ + "!rm -rf /dbzero\n", + "import dbzero as db0" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "02f628c6", + "metadata": {}, + "outputs": [], + "source": [ + "db0.init(dbzero_root=\"/dbzero\", prefix = \"data\")" + ] + }, + { + "cell_type": "markdown", + "id": "60812c5b", + "metadata": {}, + "source": [ + "#### Our first class" + ] + }, + { + "cell_type": "markdown", + "id": "6ca86246", + "metadata": {}, + "source": [ + "Classes marked with `@db0.memo` are stored in dbzero's infinite memory after creation.\n", + "Simply annotate your class and initialize its fields inside the `__init__` method, just as you would with any regular Python class." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "fb50ed27", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo\n", + "class HelloWorld:\n", + " def __init__(self, name):\n", + " self.name = name\n", + " \n", + " def greet(self):\n", + " print(f\"Hello {self.name}. Welcome to dbzero!!\")" + ] + }, + { + "cell_type": "markdown", + "id": "ffc8adc2", + "metadata": {}, + "source": [ + "You can use the class just as any regular Python class—instantiate new objects and call its methods." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3c76c92", + "metadata": {}, + "outputs": [], + "source": [ + "john = HelloWorld(\"John\")" + ] + }, + { + "cell_type": "markdown", + "id": "194cb956-61ed-4acc-a8fc-5e197f7a67d3", + "metadata": {}, + "source": [ + "We're adding a tag to prevent dbzero from deleting this object when we close the process. (We'll discuss this behavior in more detail later.)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "2014006f-94ba-4bb8-96a0-a6c0426950ad", + "metadata": {}, + "outputs": [], + "source": [ + "db0.tags(john).add(\"best friend\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "0b5521dc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello john. Welcome to dbzero!!\n" + ] + } + ], + "source": [ + "john.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "105d74af", + "metadata": {}, + "source": [ + "#### So what's the difference?" + ] + }, + { + "cell_type": "markdown", + "id": "4f17de79", + "metadata": {}, + "source": [ + "**dbzero** classes live in a different memory space with special DIST properties:\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "6b23e610", + "metadata": {}, + "source": [ + "#### How do I access the object after closing my program?\n", + "One way is to retrieve its db0 UUID and then reference it by this ID. Remember Python's `id()` function?" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "e6004ce3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "140501092994576" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "id(john)" + ] + }, + { + "cell_type": "markdown", + "id": "8315c56c", + "metadata": {}, + "source": [ + "Each **dbzero** object has both a Python ID (short-lived) and a db0 UUID (persistent until you decide to delete the object—similar to deleting a row in a database)." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7586d999", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'DFZ46RQG7QPR3IEBUCAIAAIN'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "db0.uuid(john)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "d326b2e5-10e2-4f9c-8bee-bb492fee99f4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['__class__',\n", + " '__delattr__',\n", + " '__dict__',\n", + " '__dir__',\n", + " '__doc__',\n", + " '__eq__',\n", + " '__fields__',\n", + " '__format__',\n", + " '__ge__',\n", + " '__getattribute__',\n", + " '__getstate__',\n", + " '__gt__',\n", + " '__hash__',\n", + " '__init__',\n", + " '__init_subclass__',\n", + " '__le__',\n", + " '__lt__',\n", + " '__module__',\n", + " '__ne__',\n", + " '__new__',\n", + " '__reduce__',\n", + " '__reduce_ex__',\n", + " '__repr__',\n", + " '__setattr__',\n", + " '__sizeof__',\n", + " '__str__',\n", + " '__subclasshook__',\n", + " '__weakref__',\n", + " 'greet']" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dir(john)" + ] + }, + { + "cell_type": "markdown", + "id": "feb005c8", + "metadata": {}, + "source": [ + "#### Let's remember this UUID and continue in another notebook..." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "52fbeebc", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "7ed4bd71", + "metadata": {}, + "outputs": [ + { + "ename": "RuntimeError", + "evalue": "Object is no longer accessible\n", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[13], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43mdir\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mjohn\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[0;31mRuntimeError\u001b[0m: Object is no longer accessible\n" + ] + } + ], + "source": [ + "dir(john)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "0bb6af53", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "__main__.Memo_HelloWorld" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "type(john)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c1e7758", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/hello.db0_2.ipynb b/notebooks/hello/hello.db0_2.ipynb new file mode 100644 index 00000000..3f9d83f0 --- /dev/null +++ b/notebooks/hello/hello.db0_2.ipynb @@ -0,0 +1,2303 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "58718db2", + "metadata": {}, + "source": [ + "## Introducing **dbzero** (2/12). Lists, relations and singletons." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "edf34c16", + "metadata": {}, + "outputs": [], + "source": [ + "import dbzero as db0\n", + "db0.init(dbzero_root = \"/dbzero\", prefix=\"data\")" + ] + }, + { + "cell_type": "markdown", + "id": "2231a803", + "metadata": {}, + "source": [ + "We need to define our class again. In a typical Python program we'd just import it from a module." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ec1c2e4c", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo\n", + "class HelloWorld:\n", + " def __init__(self, name):\n", + " self.name = name\n", + " \n", + " def greet(self):\n", + " print(f\"Hello {self.name}. Welcome to dbzero!!\")" + ] + }, + { + "cell_type": "markdown", + "id": "44b004ad", + "metadata": {}, + "source": [ + "And let's open its instance by a previously generated ID (< paste your ID below >)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "eaa0ed2d", + "metadata": {}, + "outputs": [], + "source": [ + "h = db0.fetch(HelloWorld, \"DFZ46RQG7QPR3IEBUCAIAAIN\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "9409153e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello john. Welcome to dbzero!!\n" + ] + } + ], + "source": [ + "h.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "7a389fa5", + "metadata": {}, + "source": [ + "### Alright, it worked. The instance remembers its data members.\n", + "But pulling by ID does not seem very convenient. How can I access my objects in a more practical way?" + ] + }, + { + "cell_type": "markdown", + "id": "9ee0a339", + "metadata": {}, + "source": [ + "One possibility is to keep references to your objects in a different (parent) object. In the database world, such an association would be called a 'relation'. If our intention is to keep only one instance of HelloMany, we can mark it with" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "19c71ee7", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo(singleton = True)\n", + "class HelloMany:\n", + " # we pass a list of names and many HelloWorld instances will be created, then added to 'hellos' DB0 list\n", + " def __init__(self, names):\n", + " self.hellos = [HelloWorld(name) for name in names]\n", + " \n", + " def greet(self):\n", + " for hw in self.hellos:\n", + " hw.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "24da7013", + "metadata": {}, + "source": [ + "Note that the **dbzero** object of a class marked as ``singleton`` will be created only once." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "21021621", + "metadata": {}, + "outputs": [], + "source": [ + "many_hellos = HelloMany([\"Andrew\", \"Alice\", \"Bob\", \"Frank\", \"Rohan\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "69c51083", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello Andrew. Welcome to dbzero!!\n", + "Hello Alice. Welcome to dbzero!!\n", + "Hello Bob. Welcome to dbzero!!\n", + "Hello Frank. Welcome to dbzero!!\n", + "Hello Rohan. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-298. Welcome to dbzero!!\n", + "Hello name-299. Welcome to dbzero!!\n", + "Hello name-300. Welcome to dbzero!!\n", + "Hello name-301. Welcome to dbzero!!\n", + "Hello name-302. Welcome to dbzero!!\n", + "Hello name-303. Welcome to dbzero!!\n", + "Hello name-304. Welcome to dbzero!!\n", + "Hello name-305. Welcome to dbzero!!\n", + "Hello name-306. Welcome to dbzero!!\n", + "Hello name-307. Welcome to dbzero!!\n", + "Hello name-308. Welcome to dbzero!!\n", + "Hello name-309. Welcome to dbzero!!\n", + "Hello name-310. Welcome to dbzero!!\n", + "Hello name-311. Welcome to dbzero!!\n", + "Hello name-312. Welcome to dbzero!!\n", + "Hello name-313. Welcome to dbzero!!\n", + "Hello name-314. Welcome to dbzero!!\n", + "Hello name-315. Welcome to dbzero!!\n", + "Hello name-316. Welcome to dbzero!!\n", + "Hello name-317. Welcome to dbzero!!\n", + "Hello name-318. Welcome to dbzero!!\n", + "Hello name-319. Welcome to dbzero!!\n", + "Hello name-320. Welcome to dbzero!!\n", + "Hello name-321. Welcome to dbzero!!\n", + "Hello name-322. Welcome to dbzero!!\n", + "Hello name-323. Welcome to dbzero!!\n", + "Hello name-324. Welcome to dbzero!!\n", + "Hello name-325. Welcome to dbzero!!\n", + "Hello name-326. Welcome to dbzero!!\n", + "Hello name-327. Welcome to dbzero!!\n", + "Hello name-328. Welcome to dbzero!!\n", + "Hello name-329. Welcome to dbzero!!\n", + "Hello name-330. Welcome to dbzero!!\n", + "Hello name-331. Welcome to dbzero!!\n", + "Hello name-332. Welcome to dbzero!!\n", + "Hello name-333. Welcome to dbzero!!\n", + "Hello name-334. Welcome to dbzero!!\n", + "Hello name-335. Welcome to dbzero!!\n", + "Hello name-336. Welcome to dbzero!!\n", + "Hello name-337. Welcome to dbzero!!\n", + "Hello name-338. Welcome to dbzero!!\n", + "Hello name-339. Welcome to dbzero!!\n", + "Hello name-340. Welcome to dbzero!!\n", + "Hello name-341. Welcome to dbzero!!\n", + "Hello name-342. Welcome to dbzero!!\n", + "Hello name-343. Welcome to dbzero!!\n", + "Hello name-344. Welcome to dbzero!!\n", + "Hello name-345. Welcome to dbzero!!\n", + "Hello name-346. Welcome to dbzero!!\n", + "Hello name-347. Welcome to dbzero!!\n", + "Hello name-348. Welcome to dbzero!!\n", + "Hello name-349. Welcome to dbzero!!\n", + "Hello name-350. Welcome to dbzero!!\n", + "Hello name-351. Welcome to dbzero!!\n", + "Hello name-352. Welcome to dbzero!!\n", + "Hello name-353. Welcome to dbzero!!\n", + "Hello name-354. Welcome to dbzero!!\n", + "Hello name-355. Welcome to dbzero!!\n", + "Hello name-356. Welcome to dbzero!!\n", + "Hello name-357. Welcome to dbzero!!\n", + "Hello name-358. Welcome to dbzero!!\n", + "Hello name-359. Welcome to dbzero!!\n", + "Hello name-360. Welcome to dbzero!!\n", + "Hello name-361. Welcome to dbzero!!\n", + "Hello name-362. Welcome to dbzero!!\n", + "Hello name-363. Welcome to dbzero!!\n", + "Hello name-364. Welcome to dbzero!!\n", + "Hello name-365. Welcome to dbzero!!\n", + "Hello name-366. Welcome to dbzero!!\n", + "Hello name-367. Welcome to dbzero!!\n", + "Hello name-368. Welcome to dbzero!!\n", + "Hello name-369. Welcome to dbzero!!\n", + "Hello name-370. Welcome to dbzero!!\n", + "Hello name-371. Welcome to dbzero!!\n", + "Hello name-372. Welcome to dbzero!!\n", + "Hello name-373. Welcome to dbzero!!\n", + "Hello name-374. Welcome to dbzero!!\n", + "Hello name-375. Welcome to dbzero!!\n", + "Hello name-376. Welcome to dbzero!!\n", + "Hello name-377. Welcome to dbzero!!\n", + "Hello name-378. Welcome to dbzero!!\n", + "Hello name-379. Welcome to dbzero!!\n", + "Hello name-380. Welcome to dbzero!!\n", + "Hello name-381. Welcome to dbzero!!\n", + "Hello name-382. Welcome to dbzero!!\n", + "Hello name-383. Welcome to dbzero!!\n", + "Hello name-384. Welcome to dbzero!!\n", + "Hello name-385. Welcome to dbzero!!\n", + "Hello name-386. Welcome to dbzero!!\n", + "Hello name-387. Welcome to dbzero!!\n", + "Hello name-388. Welcome to dbzero!!\n", + "Hello name-389. Welcome to dbzero!!\n", + "Hello name-390. Welcome to dbzero!!\n", + "Hello name-391. Welcome to dbzero!!\n", + "Hello name-392. Welcome to dbzero!!\n", + "Hello name-393. Welcome to dbzero!!\n", + "Hello name-394. Welcome to dbzero!!\n", + "Hello name-395. Welcome to dbzero!!\n", + "Hello name-396. Welcome to dbzero!!\n", + "Hello name-397. Welcome to dbzero!!\n", + "Hello name-398. Welcome to dbzero!!\n", + "Hello name-399. Welcome to dbzero!!\n", + "Hello name-400. Welcome to dbzero!!\n", + "Hello name-401. Welcome to dbzero!!\n", + "Hello name-402. Welcome to dbzero!!\n", + "Hello name-403. Welcome to dbzero!!\n", + "Hello name-404. Welcome to dbzero!!\n", + "Hello name-405. Welcome to dbzero!!\n", + "Hello name-406. Welcome to dbzero!!\n", + "Hello name-407. Welcome to dbzero!!\n", + "Hello name-408. Welcome to dbzero!!\n", + "Hello name-409. Welcome to dbzero!!\n", + "Hello name-410. Welcome to dbzero!!\n", + "Hello name-411. Welcome to dbzero!!\n", + "Hello name-412. Welcome to dbzero!!\n", + "Hello name-413. Welcome to dbzero!!\n", + "Hello name-414. Welcome to dbzero!!\n", + "Hello name-415. Welcome to dbzero!!\n", + "Hello name-416. Welcome to dbzero!!\n", + "Hello name-417. Welcome to dbzero!!\n", + "Hello name-418. Welcome to dbzero!!\n", + "Hello name-419. Welcome to dbzero!!\n", + "Hello name-420. Welcome to dbzero!!\n", + "Hello name-421. Welcome to dbzero!!\n", + "Hello name-422. Welcome to dbzero!!\n", + "Hello name-423. Welcome to dbzero!!\n", + "Hello name-424. Welcome to dbzero!!\n", + "Hello name-425. Welcome to dbzero!!\n", + "Hello name-426. Welcome to dbzero!!\n", + "Hello name-427. Welcome to dbzero!!\n", + "Hello name-428. Welcome to dbzero!!\n", + "Hello name-429. Welcome to dbzero!!\n", + "Hello name-430. Welcome to dbzero!!\n", + "Hello name-431. Welcome to dbzero!!\n", + "Hello name-432. Welcome to dbzero!!\n", + "Hello name-433. Welcome to dbzero!!\n", + "Hello name-434. Welcome to dbzero!!\n", + "Hello name-435. Welcome to dbzero!!\n", + "Hello name-436. Welcome to dbzero!!\n", + "Hello name-437. Welcome to dbzero!!\n", + "Hello name-438. Welcome to dbzero!!\n", + "Hello name-439. Welcome to dbzero!!\n", + "Hello name-440. Welcome to dbzero!!\n", + "Hello name-441. Welcome to dbzero!!\n", + "Hello name-442. Welcome to dbzero!!\n", + "Hello name-443. Welcome to dbzero!!\n", + "Hello name-444. Welcome to dbzero!!\n", + "Hello name-445. Welcome to dbzero!!\n", + "Hello name-446. Welcome to dbzero!!\n", + "Hello name-447. Welcome to dbzero!!\n", + "Hello name-448. Welcome to dbzero!!\n", + "Hello name-449. Welcome to dbzero!!\n", + "Hello name-450. Welcome to dbzero!!\n", + "Hello name-451. Welcome to dbzero!!\n", + "Hello name-452. Welcome to dbzero!!\n", + "Hello name-453. Welcome to dbzero!!\n", + "Hello name-454. Welcome to dbzero!!\n", + "Hello name-455. Welcome to dbzero!!\n", + "Hello name-456. Welcome to dbzero!!\n", + "Hello name-457. Welcome to dbzero!!\n", + "Hello name-458. Welcome to dbzero!!\n", + "Hello name-459. Welcome to dbzero!!\n", + "Hello name-460. Welcome to dbzero!!\n", + "Hello name-461. Welcome to dbzero!!\n", + "Hello name-462. Welcome to dbzero!!\n", + "Hello name-463. Welcome to dbzero!!\n", + "Hello name-464. Welcome to dbzero!!\n", + "Hello name-465. Welcome to dbzero!!\n", + "Hello name-466. Welcome to dbzero!!\n", + "Hello name-467. Welcome to dbzero!!\n", + "Hello name-468. Welcome to dbzero!!\n", + "Hello name-469. Welcome to dbzero!!\n", + "Hello name-470. Welcome to dbzero!!\n", + "Hello name-471. Welcome to dbzero!!\n", + "Hello name-472. Welcome to dbzero!!\n", + "Hello name-473. Welcome to dbzero!!\n", + "Hello name-474. Welcome to dbzero!!\n", + "Hello name-475. Welcome to dbzero!!\n", + "Hello name-476. Welcome to dbzero!!\n", + "Hello name-477. Welcome to dbzero!!\n", + "Hello name-478. Welcome to dbzero!!\n", + "Hello name-479. Welcome to dbzero!!\n", + "Hello name-480. Welcome to dbzero!!\n", + "Hello name-481. Welcome to dbzero!!\n", + "Hello name-482. Welcome to dbzero!!\n", + "Hello name-483. Welcome to dbzero!!\n", + "Hello name-484. Welcome to dbzero!!\n", + "Hello name-485. Welcome to dbzero!!\n", + "Hello name-486. Welcome to dbzero!!\n", + "Hello name-487. Welcome to dbzero!!\n", + "Hello name-488. Welcome to dbzero!!\n", + "Hello name-489. Welcome to dbzero!!\n", + "Hello name-490. Welcome to dbzero!!\n", + "Hello name-491. Welcome to dbzero!!\n", + "Hello name-492. Welcome to dbzero!!\n", + "Hello name-493. Welcome to dbzero!!\n", + "Hello name-494. Welcome to dbzero!!\n", + "Hello name-495. Welcome to dbzero!!\n", + "Hello name-496. Welcome to dbzero!!\n", + "Hello name-497. Welcome to dbzero!!\n", + "Hello name-498. Welcome to dbzero!!\n", + "Hello name-499. Welcome to dbzero!!\n", + "Hello name-500. Welcome to dbzero!!\n", + "Hello name-501. Welcome to dbzero!!\n", + "Hello name-502. Welcome to dbzero!!\n", + "Hello name-503. Welcome to dbzero!!\n", + "Hello name-504. Welcome to dbzero!!\n", + "Hello name-505. Welcome to dbzero!!\n", + "Hello name-506. Welcome to dbzero!!\n", + "Hello name-507. Welcome to dbzero!!\n", + "Hello name-508. Welcome to dbzero!!\n", + "Hello name-509. Welcome to dbzero!!\n", + "Hello name-510. Welcome to dbzero!!\n", + "Hello name-511. Welcome to dbzero!!\n", + "Hello name-512. Welcome to dbzero!!\n", + "Hello name-513. Welcome to dbzero!!\n", + "Hello name-514. Welcome to dbzero!!\n", + "Hello name-515. Welcome to dbzero!!\n", + "Hello name-516. Welcome to dbzero!!\n", + "Hello name-517. Welcome to dbzero!!\n", + "Hello name-518. Welcome to dbzero!!\n", + "Hello name-519. Welcome to dbzero!!\n", + "Hello name-520. Welcome to dbzero!!\n", + "Hello name-521. Welcome to dbzero!!\n", + "Hello name-522. Welcome to dbzero!!\n", + "Hello name-523. Welcome to dbzero!!\n", + "Hello name-524. Welcome to dbzero!!\n", + "Hello name-525. Welcome to dbzero!!\n", + "Hello name-526. Welcome to dbzero!!\n", + "Hello name-527. Welcome to dbzero!!\n", + "Hello name-528. Welcome to dbzero!!\n", + "Hello name-529. Welcome to dbzero!!\n", + "Hello name-530. Welcome to dbzero!!\n", + "Hello name-531. Welcome to dbzero!!\n", + "Hello name-532. Welcome to dbzero!!\n", + "Hello name-533. Welcome to dbzero!!\n", + "Hello name-534. Welcome to dbzero!!\n", + "Hello name-535. Welcome to dbzero!!\n", + "Hello name-536. Welcome to dbzero!!\n", + "Hello name-537. Welcome to dbzero!!\n", + "Hello name-538. Welcome to dbzero!!\n", + "Hello name-539. Welcome to dbzero!!\n", + "Hello name-540. Welcome to dbzero!!\n", + "Hello name-541. Welcome to dbzero!!\n", + "Hello name-542. Welcome to dbzero!!\n", + "Hello name-543. Welcome to dbzero!!\n", + "Hello name-544. Welcome to dbzero!!\n", + "Hello name-545. Welcome to dbzero!!\n", + "Hello name-546. Welcome to dbzero!!\n", + "Hello name-547. Welcome to dbzero!!\n", + "Hello name-548. Welcome to dbzero!!\n", + "Hello name-549. Welcome to dbzero!!\n", + "Hello name-550. Welcome to dbzero!!\n", + "Hello name-551. Welcome to dbzero!!\n", + "Hello name-552. Welcome to dbzero!!\n", + "Hello name-553. Welcome to dbzero!!\n", + "Hello name-554. Welcome to dbzero!!\n", + "Hello name-555. Welcome to dbzero!!\n", + "Hello name-556. Welcome to dbzero!!\n", + "Hello name-557. Welcome to dbzero!!\n", + "Hello name-558. Welcome to dbzero!!\n", + "Hello name-559. Welcome to dbzero!!\n", + "Hello name-560. Welcome to dbzero!!\n", + "Hello name-561. Welcome to dbzero!!\n", + "Hello name-562. Welcome to dbzero!!\n", + "Hello name-563. Welcome to dbzero!!\n", + "Hello name-564. Welcome to dbzero!!\n", + "Hello name-565. Welcome to dbzero!!\n", + "Hello name-566. Welcome to dbzero!!\n", + "Hello name-567. Welcome to dbzero!!\n", + "Hello name-568. Welcome to dbzero!!\n", + "Hello name-569. Welcome to dbzero!!\n", + "Hello name-570. Welcome to dbzero!!\n", + "Hello name-571. Welcome to dbzero!!\n", + "Hello name-572. Welcome to dbzero!!\n", + "Hello name-573. Welcome to dbzero!!\n", + "Hello name-574. Welcome to dbzero!!\n", + "Hello name-575. Welcome to dbzero!!\n", + "Hello name-576. Welcome to dbzero!!\n", + "Hello name-577. Welcome to dbzero!!\n", + "Hello name-578. Welcome to dbzero!!\n", + "Hello name-579. Welcome to dbzero!!\n", + "Hello name-580. Welcome to dbzero!!\n", + "Hello name-581. Welcome to dbzero!!\n", + "Hello name-582. Welcome to dbzero!!\n", + "Hello name-583. Welcome to dbzero!!\n", + "Hello name-584. Welcome to dbzero!!\n", + "Hello name-585. Welcome to dbzero!!\n", + "Hello name-586. Welcome to dbzero!!\n", + "Hello name-587. Welcome to dbzero!!\n", + "Hello name-588. Welcome to dbzero!!\n", + "Hello name-589. Welcome to dbzero!!\n", + "Hello name-590. Welcome to dbzero!!\n", + "Hello name-591. Welcome to dbzero!!\n", + "Hello name-592. Welcome to dbzero!!\n", + "Hello name-593. Welcome to dbzero!!\n", + "Hello name-594. Welcome to dbzero!!\n", + "Hello name-595. Welcome to dbzero!!\n", + "Hello name-596. Welcome to dbzero!!\n", + "Hello name-597. Welcome to dbzero!!\n", + "Hello name-598. Welcome to dbzero!!\n", + "Hello name-599. Welcome to dbzero!!\n", + "Hello name-600. Welcome to dbzero!!\n", + "Hello name-601. Welcome to dbzero!!\n", + "Hello name-602. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-603. Welcome to dbzero!!\n", + "Hello name-604. Welcome to dbzero!!\n", + "Hello name-605. Welcome to dbzero!!\n", + "Hello name-606. Welcome to dbzero!!\n", + "Hello name-607. Welcome to dbzero!!\n", + "Hello name-608. Welcome to dbzero!!\n", + "Hello name-609. Welcome to dbzero!!\n", + "Hello name-610. Welcome to dbzero!!\n", + "Hello name-611. Welcome to dbzero!!\n", + "Hello name-612. Welcome to dbzero!!\n", + "Hello name-613. Welcome to dbzero!!\n", + "Hello name-614. Welcome to dbzero!!\n", + "Hello name-615. Welcome to dbzero!!\n", + "Hello name-616. Welcome to dbzero!!\n", + "Hello name-617. Welcome to dbzero!!\n", + "Hello name-618. Welcome to dbzero!!\n", + "Hello name-619. Welcome to dbzero!!\n", + "Hello name-620. Welcome to dbzero!!\n", + "Hello name-621. Welcome to dbzero!!\n", + "Hello name-622. Welcome to dbzero!!\n", + "Hello name-623. Welcome to dbzero!!\n", + "Hello name-624. Welcome to dbzero!!\n", + "Hello name-625. Welcome to dbzero!!\n", + "Hello name-626. Welcome to dbzero!!\n", + "Hello name-627. Welcome to dbzero!!\n", + "Hello name-628. Welcome to dbzero!!\n", + "Hello name-629. Welcome to dbzero!!\n", + "Hello name-630. Welcome to dbzero!!\n", + "Hello name-631. Welcome to dbzero!!\n", + "Hello name-632. Welcome to dbzero!!\n", + "Hello name-633. Welcome to dbzero!!\n", + "Hello name-634. Welcome to dbzero!!\n", + "Hello name-635. Welcome to dbzero!!\n", + "Hello name-636. Welcome to dbzero!!\n", + "Hello name-637. Welcome to dbzero!!\n", + "Hello name-638. Welcome to dbzero!!\n", + "Hello name-639. Welcome to dbzero!!\n", + "Hello name-640. Welcome to dbzero!!\n", + "Hello name-641. Welcome to dbzero!!\n", + "Hello name-642. Welcome to dbzero!!\n", + "Hello name-643. Welcome to dbzero!!\n", + "Hello name-644. Welcome to dbzero!!\n", + "Hello name-645. Welcome to dbzero!!\n", + "Hello name-646. Welcome to dbzero!!\n", + "Hello name-647. Welcome to dbzero!!\n", + "Hello name-648. Welcome to dbzero!!\n", + "Hello name-649. Welcome to dbzero!!\n", + "Hello name-650. Welcome to dbzero!!\n", + "Hello name-651. Welcome to dbzero!!\n", + "Hello name-652. Welcome to dbzero!!\n", + "Hello name-653. Welcome to dbzero!!\n", + "Hello name-654. Welcome to dbzero!!\n", + "Hello name-655. Welcome to dbzero!!\n", + "Hello name-656. Welcome to dbzero!!\n", + "Hello name-657. Welcome to dbzero!!\n", + "Hello name-658. Welcome to dbzero!!\n", + "Hello name-659. Welcome to dbzero!!\n", + "Hello name-660. Welcome to dbzero!!\n", + "Hello name-661. Welcome to dbzero!!\n", + "Hello name-662. Welcome to dbzero!!\n", + "Hello name-663. Welcome to dbzero!!\n", + "Hello name-664. Welcome to dbzero!!\n", + "Hello name-665. Welcome to dbzero!!\n", + "Hello name-666. Welcome to dbzero!!\n", + "Hello name-667. Welcome to dbzero!!\n", + "Hello name-668. Welcome to dbzero!!\n", + "Hello name-669. Welcome to dbzero!!\n", + "Hello name-670. Welcome to dbzero!!\n", + "Hello name-671. Welcome to dbzero!!\n", + "Hello name-672. Welcome to dbzero!!\n", + "Hello name-673. Welcome to dbzero!!\n", + "Hello name-674. Welcome to dbzero!!\n", + "Hello name-675. Welcome to dbzero!!\n", + "Hello name-676. Welcome to dbzero!!\n", + "Hello name-677. Welcome to dbzero!!\n", + "Hello name-678. Welcome to dbzero!!\n", + "Hello name-679. Welcome to dbzero!!\n", + "Hello name-680. Welcome to dbzero!!\n", + "Hello name-681. Welcome to dbzero!!\n", + "Hello name-682. Welcome to dbzero!!\n", + "Hello name-683. Welcome to dbzero!!\n", + "Hello name-684. Welcome to dbzero!!\n", + "Hello name-685. Welcome to dbzero!!\n", + "Hello name-686. Welcome to dbzero!!\n", + "Hello name-687. Welcome to dbzero!!\n", + "Hello name-688. Welcome to dbzero!!\n", + "Hello name-689. Welcome to dbzero!!\n", + "Hello name-690. Welcome to dbzero!!\n", + "Hello name-691. Welcome to dbzero!!\n", + "Hello name-692. Welcome to dbzero!!\n", + "Hello name-693. Welcome to dbzero!!\n", + "Hello name-694. Welcome to dbzero!!\n", + "Hello name-695. Welcome to dbzero!!\n", + "Hello name-696. Welcome to dbzero!!\n", + "Hello name-697. Welcome to dbzero!!\n", + "Hello name-698. Welcome to dbzero!!\n", + "Hello name-699. Welcome to dbzero!!\n", + "Hello name-700. Welcome to dbzero!!\n", + "Hello name-701. Welcome to dbzero!!\n", + "Hello name-702. Welcome to dbzero!!\n", + "Hello name-703. Welcome to dbzero!!\n", + "Hello name-704. Welcome to dbzero!!\n", + "Hello name-705. Welcome to dbzero!!\n", + "Hello name-706. Welcome to dbzero!!\n", + "Hello name-707. Welcome to dbzero!!\n", + "Hello name-708. Welcome to dbzero!!\n", + "Hello name-709. Welcome to dbzero!!\n", + "Hello name-710. Welcome to dbzero!!\n", + "Hello name-711. Welcome to dbzero!!\n", + "Hello name-712. Welcome to dbzero!!\n", + "Hello name-713. Welcome to dbzero!!\n", + "Hello name-714. Welcome to dbzero!!\n", + "Hello name-715. Welcome to dbzero!!\n", + "Hello name-716. Welcome to dbzero!!\n", + "Hello name-717. Welcome to dbzero!!\n", + "Hello name-718. Welcome to dbzero!!\n", + "Hello name-719. Welcome to dbzero!!\n", + "Hello name-720. Welcome to dbzero!!\n", + "Hello name-721. Welcome to dbzero!!\n", + "Hello name-722. Welcome to dbzero!!\n", + "Hello name-723. Welcome to dbzero!!\n", + "Hello name-724. Welcome to dbzero!!\n", + "Hello name-725. Welcome to dbzero!!\n", + "Hello name-726. Welcome to dbzero!!\n", + "Hello name-727. Welcome to dbzero!!\n", + "Hello name-728. Welcome to dbzero!!\n", + "Hello name-729. Welcome to dbzero!!\n", + "Hello name-730. Welcome to dbzero!!\n", + "Hello name-731. Welcome to dbzero!!\n", + "Hello name-732. Welcome to dbzero!!\n", + "Hello name-733. Welcome to dbzero!!\n", + "Hello name-734. Welcome to dbzero!!\n", + "Hello name-735. Welcome to dbzero!!\n", + "Hello name-736. Welcome to dbzero!!\n", + "Hello name-737. Welcome to dbzero!!\n", + "Hello name-738. Welcome to dbzero!!\n", + "Hello name-739. Welcome to dbzero!!\n", + "Hello name-740. Welcome to dbzero!!\n", + "Hello name-741. Welcome to dbzero!!\n", + "Hello name-742. Welcome to dbzero!!\n", + "Hello name-743. Welcome to dbzero!!\n", + "Hello name-744. Welcome to dbzero!!\n", + "Hello name-745. Welcome to dbzero!!\n", + "Hello name-746. Welcome to dbzero!!\n", + "Hello name-747. Welcome to dbzero!!\n", + "Hello name-748. Welcome to dbzero!!\n", + "Hello name-749. Welcome to dbzero!!\n", + "Hello name-750. Welcome to dbzero!!\n", + "Hello name-751. Welcome to dbzero!!\n", + "Hello name-752. Welcome to dbzero!!\n", + "Hello name-753. Welcome to dbzero!!\n", + "Hello name-754. Welcome to dbzero!!\n", + "Hello name-755. Welcome to dbzero!!\n", + "Hello name-756. Welcome to dbzero!!\n", + "Hello name-757. Welcome to dbzero!!\n", + "Hello name-758. Welcome to dbzero!!\n", + "Hello name-759. Welcome to dbzero!!\n", + "Hello name-760. Welcome to dbzero!!\n", + "Hello name-761. Welcome to dbzero!!\n", + "Hello name-762. Welcome to dbzero!!\n", + "Hello name-763. Welcome to dbzero!!\n", + "Hello name-764. Welcome to dbzero!!\n", + "Hello name-765. Welcome to dbzero!!\n", + "Hello name-766. Welcome to dbzero!!\n", + "Hello name-767. Welcome to dbzero!!\n", + "Hello name-768. Welcome to dbzero!!\n", + "Hello name-769. Welcome to dbzero!!\n", + "Hello name-770. Welcome to dbzero!!\n", + "Hello name-771. Welcome to dbzero!!\n", + "Hello name-772. Welcome to dbzero!!\n", + "Hello name-773. Welcome to dbzero!!\n", + "Hello name-774. Welcome to dbzero!!\n", + "Hello name-775. Welcome to dbzero!!\n", + "Hello name-776. Welcome to dbzero!!\n", + "Hello name-777. Welcome to dbzero!!\n", + "Hello name-778. Welcome to dbzero!!\n", + "Hello name-779. Welcome to dbzero!!\n", + "Hello name-780. Welcome to dbzero!!\n", + "Hello name-781. Welcome to dbzero!!\n", + "Hello name-782. Welcome to dbzero!!\n", + "Hello name-783. Welcome to dbzero!!\n", + "Hello name-784. Welcome to dbzero!!\n", + "Hello name-785. Welcome to dbzero!!\n", + "Hello name-786. Welcome to dbzero!!\n", + "Hello name-787. Welcome to dbzero!!\n", + "Hello name-788. Welcome to dbzero!!\n", + "Hello name-789. Welcome to dbzero!!\n", + "Hello name-790. Welcome to dbzero!!\n", + "Hello name-791. Welcome to dbzero!!\n", + "Hello name-792. Welcome to dbzero!!\n", + "Hello name-793. Welcome to dbzero!!\n", + "Hello name-794. Welcome to dbzero!!\n", + "Hello name-795. Welcome to dbzero!!\n", + "Hello name-796. Welcome to dbzero!!\n", + "Hello name-797. Welcome to dbzero!!\n", + "Hello name-798. Welcome to dbzero!!\n", + "Hello name-799. Welcome to dbzero!!\n", + "Hello name-800. Welcome to dbzero!!\n", + "Hello name-801. Welcome to dbzero!!\n", + "Hello name-802. Welcome to dbzero!!\n", + "Hello name-803. Welcome to dbzero!!\n", + "Hello name-804. Welcome to dbzero!!\n", + "Hello name-805. Welcome to dbzero!!\n", + "Hello name-806. Welcome to dbzero!!\n", + "Hello name-807. Welcome to dbzero!!\n", + "Hello name-808. Welcome to dbzero!!\n", + "Hello name-809. Welcome to dbzero!!\n", + "Hello name-810. Welcome to dbzero!!\n", + "Hello name-811. Welcome to dbzero!!\n", + "Hello name-812. Welcome to dbzero!!\n", + "Hello name-813. Welcome to dbzero!!\n", + "Hello name-814. Welcome to dbzero!!\n", + "Hello name-815. Welcome to dbzero!!\n", + "Hello name-816. Welcome to dbzero!!\n", + "Hello name-817. Welcome to dbzero!!\n", + "Hello name-818. Welcome to dbzero!!\n", + "Hello name-819. Welcome to dbzero!!\n", + "Hello name-820. Welcome to dbzero!!\n", + "Hello name-821. Welcome to dbzero!!\n", + "Hello name-822. Welcome to dbzero!!\n", + "Hello name-823. Welcome to dbzero!!\n", + "Hello name-824. Welcome to dbzero!!\n", + "Hello name-825. Welcome to dbzero!!\n", + "Hello name-826. Welcome to dbzero!!\n", + "Hello name-827. Welcome to dbzero!!\n", + "Hello name-828. Welcome to dbzero!!\n", + "Hello name-829. Welcome to dbzero!!\n", + "Hello name-830. Welcome to dbzero!!\n", + "Hello name-831. Welcome to dbzero!!\n", + "Hello name-832. Welcome to dbzero!!\n", + "Hello name-833. Welcome to dbzero!!\n", + "Hello name-834. Welcome to dbzero!!\n", + "Hello name-835. Welcome to dbzero!!\n", + "Hello name-836. Welcome to dbzero!!\n", + "Hello name-837. Welcome to dbzero!!\n", + "Hello name-838. Welcome to dbzero!!\n", + "Hello name-839. Welcome to dbzero!!\n", + "Hello name-840. Welcome to dbzero!!\n", + "Hello name-841. Welcome to dbzero!!\n", + "Hello name-842. Welcome to dbzero!!\n", + "Hello name-843. Welcome to dbzero!!\n", + "Hello name-844. Welcome to dbzero!!\n", + "Hello name-845. Welcome to dbzero!!\n", + "Hello name-846. Welcome to dbzero!!\n", + "Hello name-847. Welcome to dbzero!!\n", + "Hello name-848. Welcome to dbzero!!\n", + "Hello name-849. Welcome to dbzero!!\n", + "Hello name-850. Welcome to dbzero!!\n", + "Hello name-851. Welcome to dbzero!!\n", + "Hello name-852. Welcome to dbzero!!\n", + "Hello name-853. Welcome to dbzero!!\n", + "Hello name-854. Welcome to dbzero!!\n", + "Hello name-855. Welcome to dbzero!!\n", + "Hello name-856. Welcome to dbzero!!\n", + "Hello name-857. Welcome to dbzero!!\n", + "Hello name-858. Welcome to dbzero!!\n", + "Hello name-859. Welcome to dbzero!!\n", + "Hello name-860. Welcome to dbzero!!\n", + "Hello name-861. Welcome to dbzero!!\n", + "Hello name-862. Welcome to dbzero!!\n", + "Hello name-863. Welcome to dbzero!!\n", + "Hello name-864. Welcome to dbzero!!\n", + "Hello name-865. Welcome to dbzero!!\n", + "Hello name-866. Welcome to dbzero!!\n", + "Hello name-867. Welcome to dbzero!!\n", + "Hello name-868. Welcome to dbzero!!\n", + "Hello name-869. Welcome to dbzero!!\n", + "Hello name-870. Welcome to dbzero!!\n", + "Hello name-871. Welcome to dbzero!!\n", + "Hello name-872. Welcome to dbzero!!\n", + "Hello name-873. Welcome to dbzero!!\n", + "Hello name-874. Welcome to dbzero!!\n", + "Hello name-875. Welcome to dbzero!!\n", + "Hello name-876. Welcome to dbzero!!\n", + "Hello name-877. Welcome to dbzero!!\n", + "Hello name-878. Welcome to dbzero!!\n", + "Hello name-879. Welcome to dbzero!!\n", + "Hello name-880. Welcome to dbzero!!\n", + "Hello name-881. Welcome to dbzero!!\n", + "Hello name-882. Welcome to dbzero!!\n", + "Hello name-883. Welcome to dbzero!!\n", + "Hello name-884. Welcome to dbzero!!\n", + "Hello name-885. Welcome to dbzero!!\n", + "Hello name-886. Welcome to dbzero!!\n", + "Hello name-887. Welcome to dbzero!!\n", + "Hello name-888. Welcome to dbzero!!\n", + "Hello name-889. Welcome to dbzero!!\n", + "Hello name-890. Welcome to dbzero!!\n", + "Hello name-891. Welcome to dbzero!!\n", + "Hello name-892. Welcome to dbzero!!\n", + "Hello name-893. Welcome to dbzero!!\n", + "Hello name-894. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-895. Welcome to dbzero!!\n", + "Hello name-896. Welcome to dbzero!!\n", + "Hello name-897. Welcome to dbzero!!\n", + "Hello name-898. Welcome to dbzero!!\n", + "Hello name-899. Welcome to dbzero!!\n", + "Hello name-900. Welcome to dbzero!!\n", + "Hello name-901. Welcome to dbzero!!\n", + "Hello name-902. Welcome to dbzero!!\n", + "Hello name-903. Welcome to dbzero!!\n", + "Hello name-904. Welcome to dbzero!!\n", + "Hello name-905. Welcome to dbzero!!\n", + "Hello name-906. Welcome to dbzero!!\n", + "Hello name-907. Welcome to dbzero!!\n", + "Hello name-908. Welcome to dbzero!!\n", + "Hello name-909. Welcome to dbzero!!\n", + "Hello name-910. Welcome to dbzero!!\n", + "Hello name-911. Welcome to dbzero!!\n", + "Hello name-912. Welcome to dbzero!!\n", + "Hello name-913. Welcome to dbzero!!\n", + "Hello name-914. Welcome to dbzero!!\n", + "Hello name-915. Welcome to dbzero!!\n", + "Hello name-916. Welcome to dbzero!!\n", + "Hello name-917. Welcome to dbzero!!\n", + "Hello name-918. Welcome to dbzero!!\n", + "Hello name-919. Welcome to dbzero!!\n", + "Hello name-920. Welcome to dbzero!!\n", + "Hello name-921. Welcome to dbzero!!\n", + "Hello name-922. Welcome to dbzero!!\n", + "Hello name-923. Welcome to dbzero!!\n", + "Hello name-924. Welcome to dbzero!!\n", + "Hello name-925. Welcome to dbzero!!\n", + "Hello name-926. Welcome to dbzero!!\n", + "Hello name-927. Welcome to dbzero!!\n", + "Hello name-928. Welcome to dbzero!!\n", + "Hello name-929. Welcome to dbzero!!\n", + "Hello name-930. Welcome to dbzero!!\n", + "Hello name-931. Welcome to dbzero!!\n", + "Hello name-932. Welcome to dbzero!!\n", + "Hello name-933. Welcome to dbzero!!\n", + "Hello name-934. Welcome to dbzero!!\n", + "Hello name-935. Welcome to dbzero!!\n", + "Hello name-936. Welcome to dbzero!!\n", + "Hello name-937. Welcome to dbzero!!\n", + "Hello name-938. Welcome to dbzero!!\n", + "Hello name-939. Welcome to dbzero!!\n", + "Hello name-940. Welcome to dbzero!!\n", + "Hello name-941. Welcome to dbzero!!\n", + "Hello name-942. Welcome to dbzero!!\n", + "Hello name-943. Welcome to dbzero!!\n", + "Hello name-944. Welcome to dbzero!!\n", + "Hello name-945. Welcome to dbzero!!\n", + "Hello name-946. Welcome to dbzero!!\n", + "Hello name-947. Welcome to dbzero!!\n", + "Hello name-948. Welcome to dbzero!!\n", + "Hello name-949. Welcome to dbzero!!\n", + "Hello name-950. Welcome to dbzero!!\n", + "Hello name-951. Welcome to dbzero!!\n", + "Hello name-952. Welcome to dbzero!!\n", + "Hello name-953. Welcome to dbzero!!\n", + "Hello name-954. Welcome to dbzero!!\n", + "Hello name-955. Welcome to dbzero!!\n", + "Hello name-956. Welcome to dbzero!!\n", + "Hello name-957. Welcome to dbzero!!\n", + "Hello name-958. Welcome to dbzero!!\n", + "Hello name-959. Welcome to dbzero!!\n", + "Hello name-960. Welcome to dbzero!!\n", + "Hello name-961. Welcome to dbzero!!\n", + "Hello name-962. Welcome to dbzero!!\n", + "Hello name-963. Welcome to dbzero!!\n", + "Hello name-964. Welcome to dbzero!!\n", + "Hello name-965. Welcome to dbzero!!\n", + "Hello name-966. Welcome to dbzero!!\n", + "Hello name-967. Welcome to dbzero!!\n", + "Hello name-968. Welcome to dbzero!!\n", + "Hello name-969. Welcome to dbzero!!\n", + "Hello name-970. Welcome to dbzero!!\n", + "Hello name-971. Welcome to dbzero!!\n", + "Hello name-972. Welcome to dbzero!!\n", + "Hello name-973. Welcome to dbzero!!\n", + "Hello name-974. Welcome to dbzero!!\n", + "Hello name-975. Welcome to dbzero!!\n", + "Hello name-976. Welcome to dbzero!!\n", + "Hello name-977. Welcome to dbzero!!\n", + "Hello name-978. Welcome to dbzero!!\n", + "Hello name-979. Welcome to dbzero!!\n", + "Hello name-980. Welcome to dbzero!!\n", + "Hello name-981. Welcome to dbzero!!\n", + "Hello name-982. Welcome to dbzero!!\n", + "Hello name-983. Welcome to dbzero!!\n", + "Hello name-984. Welcome to dbzero!!\n", + "Hello name-985. Welcome to dbzero!!\n", + "Hello name-986. Welcome to dbzero!!\n", + "Hello name-987. Welcome to dbzero!!\n", + "Hello name-988. Welcome to dbzero!!\n", + "Hello name-989. Welcome to dbzero!!\n", + "Hello name-990. Welcome to dbzero!!\n", + "Hello name-991. Welcome to dbzero!!\n", + "Hello name-992. Welcome to dbzero!!\n", + "Hello name-993. Welcome to dbzero!!\n", + "Hello name-994. Welcome to dbzero!!\n", + "Hello name-995. Welcome to dbzero!!\n", + "Hello name-996. Welcome to dbzero!!\n", + "Hello name-997. Welcome to dbzero!!\n", + "Hello name-998. Welcome to dbzero!!\n", + "Hello name-999. Welcome to dbzero!!\n" + ] + } + ], + "source": [ + "many_hellos.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "abfbf9aa", + "metadata": {}, + "source": [ + "Once instantiated, the object can be accessed again (from another program or after closing this program) without any arguments." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "997e5acb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello Andrew. Welcome to dbzero!!\n", + "Hello Alice. Welcome to dbzero!!\n", + "Hello Bob. Welcome to dbzero!!\n", + "Hello Frank. Welcome to dbzero!!\n", + "Hello Rohan. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-314. Welcome to dbzero!!\n", + "Hello name-315. Welcome to dbzero!!\n", + "Hello name-316. Welcome to dbzero!!\n", + "Hello name-317. Welcome to dbzero!!\n", + "Hello name-318. Welcome to dbzero!!\n", + "Hello name-319. Welcome to dbzero!!\n", + "Hello name-320. Welcome to dbzero!!\n", + "Hello name-321. Welcome to dbzero!!\n", + "Hello name-322. Welcome to dbzero!!\n", + "Hello name-323. Welcome to dbzero!!\n", + "Hello name-324. Welcome to dbzero!!\n", + "Hello name-325. Welcome to dbzero!!\n", + "Hello name-326. Welcome to dbzero!!\n", + "Hello name-327. Welcome to dbzero!!\n", + "Hello name-328. Welcome to dbzero!!\n", + "Hello name-329. Welcome to dbzero!!\n", + "Hello name-330. Welcome to dbzero!!\n", + "Hello name-331. Welcome to dbzero!!\n", + "Hello name-332. Welcome to dbzero!!\n", + "Hello name-333. Welcome to dbzero!!\n", + "Hello name-334. Welcome to dbzero!!\n", + "Hello name-335. Welcome to dbzero!!\n", + "Hello name-336. Welcome to dbzero!!\n", + "Hello name-337. Welcome to dbzero!!\n", + "Hello name-338. Welcome to dbzero!!\n", + "Hello name-339. Welcome to dbzero!!\n", + "Hello name-340. Welcome to dbzero!!\n", + "Hello name-341. Welcome to dbzero!!\n", + "Hello name-342. Welcome to dbzero!!\n", + "Hello name-343. Welcome to dbzero!!\n", + "Hello name-344. Welcome to dbzero!!\n", + "Hello name-345. Welcome to dbzero!!\n", + "Hello name-346. Welcome to dbzero!!\n", + "Hello name-347. Welcome to dbzero!!\n", + "Hello name-348. Welcome to dbzero!!\n", + "Hello name-349. Welcome to dbzero!!\n", + "Hello name-350. Welcome to dbzero!!\n", + "Hello name-351. Welcome to dbzero!!\n", + "Hello name-352. Welcome to dbzero!!\n", + "Hello name-353. Welcome to dbzero!!\n", + "Hello name-354. Welcome to dbzero!!\n", + "Hello name-355. Welcome to dbzero!!\n", + "Hello name-356. Welcome to dbzero!!\n", + "Hello name-357. Welcome to dbzero!!\n", + "Hello name-358. Welcome to dbzero!!\n", + "Hello name-359. Welcome to dbzero!!\n", + "Hello name-360. Welcome to dbzero!!\n", + "Hello name-361. Welcome to dbzero!!\n", + "Hello name-362. Welcome to dbzero!!\n", + "Hello name-363. Welcome to dbzero!!\n", + "Hello name-364. Welcome to dbzero!!\n", + "Hello name-365. Welcome to dbzero!!\n", + "Hello name-366. Welcome to dbzero!!\n", + "Hello name-367. Welcome to dbzero!!\n", + "Hello name-368. Welcome to dbzero!!\n", + "Hello name-369. Welcome to dbzero!!\n", + "Hello name-370. Welcome to dbzero!!\n", + "Hello name-371. Welcome to dbzero!!\n", + "Hello name-372. Welcome to dbzero!!\n", + "Hello name-373. Welcome to dbzero!!\n", + "Hello name-374. Welcome to dbzero!!\n", + "Hello name-375. Welcome to dbzero!!\n", + "Hello name-376. Welcome to dbzero!!\n", + "Hello name-377. Welcome to dbzero!!\n", + "Hello name-378. Welcome to dbzero!!\n", + "Hello name-379. Welcome to dbzero!!\n", + "Hello name-380. Welcome to dbzero!!\n", + "Hello name-381. Welcome to dbzero!!\n", + "Hello name-382. Welcome to dbzero!!\n", + "Hello name-383. Welcome to dbzero!!\n", + "Hello name-384. Welcome to dbzero!!\n", + "Hello name-385. Welcome to dbzero!!\n", + "Hello name-386. Welcome to dbzero!!\n", + "Hello name-387. Welcome to dbzero!!\n", + "Hello name-388. Welcome to dbzero!!\n", + "Hello name-389. Welcome to dbzero!!\n", + "Hello name-390. Welcome to dbzero!!\n", + "Hello name-391. Welcome to dbzero!!\n", + "Hello name-392. Welcome to dbzero!!\n", + "Hello name-393. Welcome to dbzero!!\n", + "Hello name-394. Welcome to dbzero!!\n", + "Hello name-395. Welcome to dbzero!!\n", + "Hello name-396. Welcome to dbzero!!\n", + "Hello name-397. Welcome to dbzero!!\n", + "Hello name-398. Welcome to dbzero!!\n", + "Hello name-399. Welcome to dbzero!!\n", + "Hello name-400. Welcome to dbzero!!\n", + "Hello name-401. Welcome to dbzero!!\n", + "Hello name-402. Welcome to dbzero!!\n", + "Hello name-403. Welcome to dbzero!!\n", + "Hello name-404. Welcome to dbzero!!\n", + "Hello name-405. Welcome to dbzero!!\n", + "Hello name-406. Welcome to dbzero!!\n", + "Hello name-407. Welcome to dbzero!!\n", + "Hello name-408. Welcome to dbzero!!\n", + "Hello name-409. Welcome to dbzero!!\n", + "Hello name-410. Welcome to dbzero!!\n", + "Hello name-411. Welcome to dbzero!!\n", + "Hello name-412. Welcome to dbzero!!\n", + "Hello name-413. Welcome to dbzero!!\n", + "Hello name-414. Welcome to dbzero!!\n", + "Hello name-415. Welcome to dbzero!!\n", + "Hello name-416. Welcome to dbzero!!\n", + "Hello name-417. Welcome to dbzero!!\n", + "Hello name-418. Welcome to dbzero!!\n", + "Hello name-419. Welcome to dbzero!!\n", + "Hello name-420. Welcome to dbzero!!\n", + "Hello name-421. Welcome to dbzero!!\n", + "Hello name-422. Welcome to dbzero!!\n", + "Hello name-423. Welcome to dbzero!!\n", + "Hello name-424. Welcome to dbzero!!\n", + "Hello name-425. Welcome to dbzero!!\n", + "Hello name-426. Welcome to dbzero!!\n", + "Hello name-427. Welcome to dbzero!!\n", + "Hello name-428. Welcome to dbzero!!\n", + "Hello name-429. Welcome to dbzero!!\n", + "Hello name-430. Welcome to dbzero!!\n", + "Hello name-431. Welcome to dbzero!!\n", + "Hello name-432. Welcome to dbzero!!\n", + "Hello name-433. Welcome to dbzero!!\n", + "Hello name-434. Welcome to dbzero!!\n", + "Hello name-435. Welcome to dbzero!!\n", + "Hello name-436. Welcome to dbzero!!\n", + "Hello name-437. Welcome to dbzero!!\n", + "Hello name-438. Welcome to dbzero!!\n", + "Hello name-439. Welcome to dbzero!!\n", + "Hello name-440. Welcome to dbzero!!\n", + "Hello name-441. Welcome to dbzero!!\n", + "Hello name-442. Welcome to dbzero!!\n", + "Hello name-443. Welcome to dbzero!!\n", + "Hello name-444. Welcome to dbzero!!\n", + "Hello name-445. Welcome to dbzero!!\n", + "Hello name-446. Welcome to dbzero!!\n", + "Hello name-447. Welcome to dbzero!!\n", + "Hello name-448. Welcome to dbzero!!\n", + "Hello name-449. Welcome to dbzero!!\n", + "Hello name-450. Welcome to dbzero!!\n", + "Hello name-451. Welcome to dbzero!!\n", + "Hello name-452. Welcome to dbzero!!\n", + "Hello name-453. Welcome to dbzero!!\n", + "Hello name-454. Welcome to dbzero!!\n", + "Hello name-455. Welcome to dbzero!!\n", + "Hello name-456. Welcome to dbzero!!\n", + "Hello name-457. Welcome to dbzero!!\n", + "Hello name-458. Welcome to dbzero!!\n", + "Hello name-459. Welcome to dbzero!!\n", + "Hello name-460. Welcome to dbzero!!\n", + "Hello name-461. Welcome to dbzero!!\n", + "Hello name-462. Welcome to dbzero!!\n", + "Hello name-463. Welcome to dbzero!!\n", + "Hello name-464. Welcome to dbzero!!\n", + "Hello name-465. Welcome to dbzero!!\n", + "Hello name-466. Welcome to dbzero!!\n", + "Hello name-467. Welcome to dbzero!!\n", + "Hello name-468. Welcome to dbzero!!\n", + "Hello name-469. Welcome to dbzero!!\n", + "Hello name-470. Welcome to dbzero!!\n", + "Hello name-471. Welcome to dbzero!!\n", + "Hello name-472. Welcome to dbzero!!\n", + "Hello name-473. Welcome to dbzero!!\n", + "Hello name-474. Welcome to dbzero!!\n", + "Hello name-475. Welcome to dbzero!!\n", + "Hello name-476. Welcome to dbzero!!\n", + "Hello name-477. Welcome to dbzero!!\n", + "Hello name-478. Welcome to dbzero!!\n", + "Hello name-479. Welcome to dbzero!!\n", + "Hello name-480. Welcome to dbzero!!\n", + "Hello name-481. Welcome to dbzero!!\n", + "Hello name-482. Welcome to dbzero!!\n", + "Hello name-483. Welcome to dbzero!!\n", + "Hello name-484. Welcome to dbzero!!\n", + "Hello name-485. Welcome to dbzero!!\n", + "Hello name-486. Welcome to dbzero!!\n", + "Hello name-487. Welcome to dbzero!!\n", + "Hello name-488. Welcome to dbzero!!\n", + "Hello name-489. Welcome to dbzero!!\n", + "Hello name-490. Welcome to dbzero!!\n", + "Hello name-491. Welcome to dbzero!!\n", + "Hello name-492. Welcome to dbzero!!\n", + "Hello name-493. Welcome to dbzero!!\n", + "Hello name-494. Welcome to dbzero!!\n", + "Hello name-495. Welcome to dbzero!!\n", + "Hello name-496. Welcome to dbzero!!\n", + "Hello name-497. Welcome to dbzero!!\n", + "Hello name-498. Welcome to dbzero!!\n", + "Hello name-499. Welcome to dbzero!!\n", + "Hello name-500. Welcome to dbzero!!\n", + "Hello name-501. Welcome to dbzero!!\n", + "Hello name-502. Welcome to dbzero!!\n", + "Hello name-503. Welcome to dbzero!!\n", + "Hello name-504. Welcome to dbzero!!\n", + "Hello name-505. Welcome to dbzero!!\n", + "Hello name-506. Welcome to dbzero!!\n", + "Hello name-507. Welcome to dbzero!!\n", + "Hello name-508. Welcome to dbzero!!\n", + "Hello name-509. Welcome to dbzero!!\n", + "Hello name-510. Welcome to dbzero!!\n", + "Hello name-511. Welcome to dbzero!!\n", + "Hello name-512. Welcome to dbzero!!\n", + "Hello name-513. Welcome to dbzero!!\n", + "Hello name-514. Welcome to dbzero!!\n", + "Hello name-515. Welcome to dbzero!!\n", + "Hello name-516. Welcome to dbzero!!\n", + "Hello name-517. Welcome to dbzero!!\n", + "Hello name-518. Welcome to dbzero!!\n", + "Hello name-519. Welcome to dbzero!!\n", + "Hello name-520. Welcome to dbzero!!\n", + "Hello name-521. Welcome to dbzero!!\n", + "Hello name-522. Welcome to dbzero!!\n", + "Hello name-523. Welcome to dbzero!!\n", + "Hello name-524. Welcome to dbzero!!\n", + "Hello name-525. Welcome to dbzero!!\n", + "Hello name-526. Welcome to dbzero!!\n", + "Hello name-527. Welcome to dbzero!!\n", + "Hello name-528. Welcome to dbzero!!\n", + "Hello name-529. Welcome to dbzero!!\n", + "Hello name-530. Welcome to dbzero!!\n", + "Hello name-531. Welcome to dbzero!!\n", + "Hello name-532. Welcome to dbzero!!\n", + "Hello name-533. Welcome to dbzero!!\n", + "Hello name-534. Welcome to dbzero!!\n", + "Hello name-535. Welcome to dbzero!!\n", + "Hello name-536. Welcome to dbzero!!\n", + "Hello name-537. Welcome to dbzero!!\n", + "Hello name-538. Welcome to dbzero!!\n", + "Hello name-539. Welcome to dbzero!!\n", + "Hello name-540. Welcome to dbzero!!\n", + "Hello name-541. Welcome to dbzero!!\n", + "Hello name-542. Welcome to dbzero!!\n", + "Hello name-543. Welcome to dbzero!!\n", + "Hello name-544. Welcome to dbzero!!\n", + "Hello name-545. Welcome to dbzero!!\n", + "Hello name-546. Welcome to dbzero!!\n", + "Hello name-547. Welcome to dbzero!!\n", + "Hello name-548. Welcome to dbzero!!\n", + "Hello name-549. Welcome to dbzero!!\n", + "Hello name-550. Welcome to dbzero!!\n", + "Hello name-551. Welcome to dbzero!!\n", + "Hello name-552. Welcome to dbzero!!\n", + "Hello name-553. Welcome to dbzero!!\n", + "Hello name-554. Welcome to dbzero!!\n", + "Hello name-555. Welcome to dbzero!!\n", + "Hello name-556. Welcome to dbzero!!\n", + "Hello name-557. Welcome to dbzero!!\n", + "Hello name-558. Welcome to dbzero!!\n", + "Hello name-559. Welcome to dbzero!!\n", + "Hello name-560. Welcome to dbzero!!\n", + "Hello name-561. Welcome to dbzero!!\n", + "Hello name-562. Welcome to dbzero!!\n", + "Hello name-563. Welcome to dbzero!!\n", + "Hello name-564. Welcome to dbzero!!\n", + "Hello name-565. Welcome to dbzero!!\n", + "Hello name-566. Welcome to dbzero!!\n", + "Hello name-567. Welcome to dbzero!!\n", + "Hello name-568. Welcome to dbzero!!\n", + "Hello name-569. Welcome to dbzero!!\n", + "Hello name-570. Welcome to dbzero!!\n", + "Hello name-571. Welcome to dbzero!!\n", + "Hello name-572. Welcome to dbzero!!\n", + "Hello name-573. Welcome to dbzero!!\n", + "Hello name-574. Welcome to dbzero!!\n", + "Hello name-575. Welcome to dbzero!!\n", + "Hello name-576. Welcome to dbzero!!\n", + "Hello name-577. Welcome to dbzero!!\n", + "Hello name-578. Welcome to dbzero!!\n", + "Hello name-579. Welcome to dbzero!!\n", + "Hello name-580. Welcome to dbzero!!\n", + "Hello name-581. Welcome to dbzero!!\n", + "Hello name-582. Welcome to dbzero!!\n", + "Hello name-583. Welcome to dbzero!!\n", + "Hello name-584. Welcome to dbzero!!\n", + "Hello name-585. Welcome to dbzero!!\n", + "Hello name-586. Welcome to dbzero!!\n", + "Hello name-587. Welcome to dbzero!!\n", + "Hello name-588. Welcome to dbzero!!\n", + "Hello name-589. Welcome to dbzero!!\n", + "Hello name-590. Welcome to dbzero!!\n", + "Hello name-591. Welcome to dbzero!!\n", + "Hello name-592. Welcome to dbzero!!\n", + "Hello name-593. Welcome to dbzero!!\n", + "Hello name-594. Welcome to dbzero!!\n", + "Hello name-595. Welcome to dbzero!!\n", + "Hello name-596. Welcome to dbzero!!\n", + "Hello name-597. Welcome to dbzero!!\n", + "Hello name-598. Welcome to dbzero!!\n", + "Hello name-599. Welcome to dbzero!!\n", + "Hello name-600. Welcome to dbzero!!\n", + "Hello name-601. Welcome to dbzero!!\n", + "Hello name-602. Welcome to dbzero!!\n", + "Hello name-603. Welcome to dbzero!!\n", + "Hello name-604. Welcome to dbzero!!\n", + "Hello name-605. Welcome to dbzero!!\n", + "Hello name-606. Welcome to dbzero!!\n", + "Hello name-607. Welcome to dbzero!!\n", + "Hello name-608. Welcome to dbzero!!\n", + "Hello name-609. Welcome to dbzero!!\n", + "Hello name-610. Welcome to dbzero!!\n", + "Hello name-611. Welcome to dbzero!!\n", + "Hello name-612. Welcome to dbzero!!\n", + "Hello name-613. Welcome to dbzero!!\n", + "Hello name-614. Welcome to dbzero!!\n", + "Hello name-615. Welcome to dbzero!!\n", + "Hello name-616. Welcome to dbzero!!\n", + "Hello name-617. Welcome to dbzero!!\n", + "Hello name-618. Welcome to dbzero!!\n", + "Hello name-619. Welcome to dbzero!!\n", + "Hello name-620. Welcome to dbzero!!\n", + "Hello name-621. Welcome to dbzero!!\n", + "Hello name-622. Welcome to dbzero!!\n", + "Hello name-623. Welcome to dbzero!!\n", + "Hello name-624. Welcome to dbzero!!\n", + "Hello name-625. Welcome to dbzero!!\n", + "Hello name-626. Welcome to dbzero!!\n", + "Hello name-627. Welcome to dbzero!!\n", + "Hello name-628. Welcome to dbzero!!\n", + "Hello name-629. Welcome to dbzero!!\n", + "Hello name-630. Welcome to dbzero!!\n", + "Hello name-631. Welcome to dbzero!!\n", + "Hello name-632. Welcome to dbzero!!\n", + "Hello name-633. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-634. Welcome to dbzero!!\n", + "Hello name-635. Welcome to dbzero!!\n", + "Hello name-636. Welcome to dbzero!!\n", + "Hello name-637. Welcome to dbzero!!\n", + "Hello name-638. Welcome to dbzero!!\n", + "Hello name-639. Welcome to dbzero!!\n", + "Hello name-640. Welcome to dbzero!!\n", + "Hello name-641. Welcome to dbzero!!\n", + "Hello name-642. Welcome to dbzero!!\n", + "Hello name-643. Welcome to dbzero!!\n", + "Hello name-644. Welcome to dbzero!!\n", + "Hello name-645. Welcome to dbzero!!\n", + "Hello name-646. Welcome to dbzero!!\n", + "Hello name-647. Welcome to dbzero!!\n", + "Hello name-648. Welcome to dbzero!!\n", + "Hello name-649. Welcome to dbzero!!\n", + "Hello name-650. Welcome to dbzero!!\n", + "Hello name-651. Welcome to dbzero!!\n", + "Hello name-652. Welcome to dbzero!!\n", + "Hello name-653. Welcome to dbzero!!\n", + "Hello name-654. Welcome to dbzero!!\n", + "Hello name-655. Welcome to dbzero!!\n", + "Hello name-656. Welcome to dbzero!!\n", + "Hello name-657. Welcome to dbzero!!\n", + "Hello name-658. Welcome to dbzero!!\n", + "Hello name-659. Welcome to dbzero!!\n", + "Hello name-660. Welcome to dbzero!!\n", + "Hello name-661. Welcome to dbzero!!\n", + "Hello name-662. Welcome to dbzero!!\n", + "Hello name-663. Welcome to dbzero!!\n", + "Hello name-664. Welcome to dbzero!!\n", + "Hello name-665. Welcome to dbzero!!\n", + "Hello name-666. Welcome to dbzero!!\n", + "Hello name-667. Welcome to dbzero!!\n", + "Hello name-668. Welcome to dbzero!!\n", + "Hello name-669. Welcome to dbzero!!\n", + "Hello name-670. Welcome to dbzero!!\n", + "Hello name-671. Welcome to dbzero!!\n", + "Hello name-672. Welcome to dbzero!!\n", + "Hello name-673. Welcome to dbzero!!\n", + "Hello name-674. Welcome to dbzero!!\n", + "Hello name-675. Welcome to dbzero!!\n", + "Hello name-676. Welcome to dbzero!!\n", + "Hello name-677. Welcome to dbzero!!\n", + "Hello name-678. Welcome to dbzero!!\n", + "Hello name-679. Welcome to dbzero!!\n", + "Hello name-680. Welcome to dbzero!!\n", + "Hello name-681. Welcome to dbzero!!\n", + "Hello name-682. Welcome to dbzero!!\n", + "Hello name-683. Welcome to dbzero!!\n", + "Hello name-684. Welcome to dbzero!!\n", + "Hello name-685. Welcome to dbzero!!\n", + "Hello name-686. Welcome to dbzero!!\n", + "Hello name-687. Welcome to dbzero!!\n", + "Hello name-688. Welcome to dbzero!!\n", + "Hello name-689. Welcome to dbzero!!\n", + "Hello name-690. Welcome to dbzero!!\n", + "Hello name-691. Welcome to dbzero!!\n", + "Hello name-692. Welcome to dbzero!!\n", + "Hello name-693. Welcome to dbzero!!\n", + "Hello name-694. Welcome to dbzero!!\n", + "Hello name-695. Welcome to dbzero!!\n", + "Hello name-696. Welcome to dbzero!!\n", + "Hello name-697. Welcome to dbzero!!\n", + "Hello name-698. Welcome to dbzero!!\n", + "Hello name-699. Welcome to dbzero!!\n", + "Hello name-700. Welcome to dbzero!!\n", + "Hello name-701. Welcome to dbzero!!\n", + "Hello name-702. Welcome to dbzero!!\n", + "Hello name-703. Welcome to dbzero!!\n", + "Hello name-704. Welcome to dbzero!!\n", + "Hello name-705. Welcome to dbzero!!\n", + "Hello name-706. Welcome to dbzero!!\n", + "Hello name-707. Welcome to dbzero!!\n", + "Hello name-708. Welcome to dbzero!!\n", + "Hello name-709. Welcome to dbzero!!\n", + "Hello name-710. Welcome to dbzero!!\n", + "Hello name-711. Welcome to dbzero!!\n", + "Hello name-712. Welcome to dbzero!!\n", + "Hello name-713. Welcome to dbzero!!\n", + "Hello name-714. Welcome to dbzero!!\n", + "Hello name-715. Welcome to dbzero!!\n", + "Hello name-716. Welcome to dbzero!!\n", + "Hello name-717. Welcome to dbzero!!\n", + "Hello name-718. Welcome to dbzero!!\n", + "Hello name-719. Welcome to dbzero!!\n", + "Hello name-720. Welcome to dbzero!!\n", + "Hello name-721. Welcome to dbzero!!\n", + "Hello name-722. Welcome to dbzero!!\n", + "Hello name-723. Welcome to dbzero!!\n", + "Hello name-724. Welcome to dbzero!!\n", + "Hello name-725. Welcome to dbzero!!\n", + "Hello name-726. Welcome to dbzero!!\n", + "Hello name-727. Welcome to dbzero!!\n", + "Hello name-728. Welcome to dbzero!!\n", + "Hello name-729. Welcome to dbzero!!\n", + "Hello name-730. Welcome to dbzero!!\n", + "Hello name-731. Welcome to dbzero!!\n", + "Hello name-732. Welcome to dbzero!!\n", + "Hello name-733. Welcome to dbzero!!\n", + "Hello name-734. Welcome to dbzero!!\n", + "Hello name-735. Welcome to dbzero!!\n", + "Hello name-736. Welcome to dbzero!!\n", + "Hello name-737. Welcome to dbzero!!\n", + "Hello name-738. Welcome to dbzero!!\n", + "Hello name-739. Welcome to dbzero!!\n", + "Hello name-740. Welcome to dbzero!!\n", + "Hello name-741. Welcome to dbzero!!\n", + "Hello name-742. Welcome to dbzero!!\n", + "Hello name-743. Welcome to dbzero!!\n", + "Hello name-744. Welcome to dbzero!!\n", + "Hello name-745. Welcome to dbzero!!\n", + "Hello name-746. Welcome to dbzero!!\n", + "Hello name-747. Welcome to dbzero!!\n", + "Hello name-748. Welcome to dbzero!!\n", + "Hello name-749. Welcome to dbzero!!\n", + "Hello name-750. Welcome to dbzero!!\n", + "Hello name-751. Welcome to dbzero!!\n", + "Hello name-752. Welcome to dbzero!!\n", + "Hello name-753. Welcome to dbzero!!\n", + "Hello name-754. Welcome to dbzero!!\n", + "Hello name-755. Welcome to dbzero!!\n", + "Hello name-756. Welcome to dbzero!!\n", + "Hello name-757. Welcome to dbzero!!\n", + "Hello name-758. Welcome to dbzero!!\n", + "Hello name-759. Welcome to dbzero!!\n", + "Hello name-760. Welcome to dbzero!!\n", + "Hello name-761. Welcome to dbzero!!\n", + "Hello name-762. Welcome to dbzero!!\n", + "Hello name-763. Welcome to dbzero!!\n", + "Hello name-764. Welcome to dbzero!!\n", + "Hello name-765. Welcome to dbzero!!\n", + "Hello name-766. Welcome to dbzero!!\n", + "Hello name-767. Welcome to dbzero!!\n", + "Hello name-768. Welcome to dbzero!!\n", + "Hello name-769. Welcome to dbzero!!\n", + "Hello name-770. Welcome to dbzero!!\n", + "Hello name-771. Welcome to dbzero!!\n", + "Hello name-772. Welcome to dbzero!!\n", + "Hello name-773. Welcome to dbzero!!\n", + "Hello name-774. Welcome to dbzero!!\n", + "Hello name-775. Welcome to dbzero!!\n", + "Hello name-776. Welcome to dbzero!!\n", + "Hello name-777. Welcome to dbzero!!\n", + "Hello name-778. Welcome to dbzero!!\n", + "Hello name-779. Welcome to dbzero!!\n", + "Hello name-780. Welcome to dbzero!!\n", + "Hello name-781. Welcome to dbzero!!\n", + "Hello name-782. Welcome to dbzero!!\n", + "Hello name-783. Welcome to dbzero!!\n", + "Hello name-784. Welcome to dbzero!!\n", + "Hello name-785. Welcome to dbzero!!\n", + "Hello name-786. Welcome to dbzero!!\n", + "Hello name-787. Welcome to dbzero!!\n", + "Hello name-788. Welcome to dbzero!!\n", + "Hello name-789. Welcome to dbzero!!\n", + "Hello name-790. Welcome to dbzero!!\n", + "Hello name-791. Welcome to dbzero!!\n", + "Hello name-792. Welcome to dbzero!!\n", + "Hello name-793. Welcome to dbzero!!\n", + "Hello name-794. Welcome to dbzero!!\n", + "Hello name-795. Welcome to dbzero!!\n", + "Hello name-796. Welcome to dbzero!!\n", + "Hello name-797. Welcome to dbzero!!\n", + "Hello name-798. Welcome to dbzero!!\n", + "Hello name-799. Welcome to dbzero!!\n", + "Hello name-800. Welcome to dbzero!!\n", + "Hello name-801. Welcome to dbzero!!\n", + "Hello name-802. Welcome to dbzero!!\n", + "Hello name-803. Welcome to dbzero!!\n", + "Hello name-804. Welcome to dbzero!!\n", + "Hello name-805. Welcome to dbzero!!\n", + "Hello name-806. Welcome to dbzero!!\n", + "Hello name-807. Welcome to dbzero!!\n", + "Hello name-808. Welcome to dbzero!!\n", + "Hello name-809. Welcome to dbzero!!\n", + "Hello name-810. Welcome to dbzero!!\n", + "Hello name-811. Welcome to dbzero!!\n", + "Hello name-812. Welcome to dbzero!!\n", + "Hello name-813. Welcome to dbzero!!\n", + "Hello name-814. Welcome to dbzero!!\n", + "Hello name-815. Welcome to dbzero!!\n", + "Hello name-816. Welcome to dbzero!!\n", + "Hello name-817. Welcome to dbzero!!\n", + "Hello name-818. Welcome to dbzero!!\n", + "Hello name-819. Welcome to dbzero!!\n", + "Hello name-820. Welcome to dbzero!!\n", + "Hello name-821. Welcome to dbzero!!\n", + "Hello name-822. Welcome to dbzero!!\n", + "Hello name-823. Welcome to dbzero!!\n", + "Hello name-824. Welcome to dbzero!!\n", + "Hello name-825. Welcome to dbzero!!\n", + "Hello name-826. Welcome to dbzero!!\n", + "Hello name-827. Welcome to dbzero!!\n", + "Hello name-828. Welcome to dbzero!!\n", + "Hello name-829. Welcome to dbzero!!\n", + "Hello name-830. Welcome to dbzero!!\n", + "Hello name-831. Welcome to dbzero!!\n", + "Hello name-832. Welcome to dbzero!!\n", + "Hello name-833. Welcome to dbzero!!\n", + "Hello name-834. Welcome to dbzero!!\n", + "Hello name-835. Welcome to dbzero!!\n", + "Hello name-836. Welcome to dbzero!!\n", + "Hello name-837. Welcome to dbzero!!\n", + "Hello name-838. Welcome to dbzero!!\n", + "Hello name-839. Welcome to dbzero!!\n", + "Hello name-840. Welcome to dbzero!!\n", + "Hello name-841. Welcome to dbzero!!\n", + "Hello name-842. Welcome to dbzero!!\n", + "Hello name-843. Welcome to dbzero!!\n", + "Hello name-844. Welcome to dbzero!!\n", + "Hello name-845. Welcome to dbzero!!\n", + "Hello name-846. Welcome to dbzero!!\n", + "Hello name-847. Welcome to dbzero!!\n", + "Hello name-848. Welcome to dbzero!!\n", + "Hello name-849. Welcome to dbzero!!\n", + "Hello name-850. Welcome to dbzero!!\n", + "Hello name-851. Welcome to dbzero!!\n", + "Hello name-852. Welcome to dbzero!!\n", + "Hello name-853. Welcome to dbzero!!\n", + "Hello name-854. Welcome to dbzero!!\n", + "Hello name-855. Welcome to dbzero!!\n", + "Hello name-856. Welcome to dbzero!!\n", + "Hello name-857. Welcome to dbzero!!\n", + "Hello name-858. Welcome to dbzero!!\n", + "Hello name-859. Welcome to dbzero!!\n", + "Hello name-860. Welcome to dbzero!!\n", + "Hello name-861. Welcome to dbzero!!\n", + "Hello name-862. Welcome to dbzero!!\n", + "Hello name-863. Welcome to dbzero!!\n", + "Hello name-864. Welcome to dbzero!!\n", + "Hello name-865. Welcome to dbzero!!\n", + "Hello name-866. Welcome to dbzero!!\n", + "Hello name-867. Welcome to dbzero!!\n", + "Hello name-868. Welcome to dbzero!!\n", + "Hello name-869. Welcome to dbzero!!\n", + "Hello name-870. Welcome to dbzero!!\n", + "Hello name-871. Welcome to dbzero!!\n", + "Hello name-872. Welcome to dbzero!!\n", + "Hello name-873. Welcome to dbzero!!\n", + "Hello name-874. Welcome to dbzero!!\n", + "Hello name-875. Welcome to dbzero!!\n", + "Hello name-876. Welcome to dbzero!!\n", + "Hello name-877. Welcome to dbzero!!\n", + "Hello name-878. Welcome to dbzero!!\n", + "Hello name-879. Welcome to dbzero!!\n", + "Hello name-880. Welcome to dbzero!!\n", + "Hello name-881. Welcome to dbzero!!\n", + "Hello name-882. Welcome to dbzero!!\n", + "Hello name-883. Welcome to dbzero!!\n", + "Hello name-884. Welcome to dbzero!!\n", + "Hello name-885. Welcome to dbzero!!\n", + "Hello name-886. Welcome to dbzero!!\n", + "Hello name-887. Welcome to dbzero!!\n", + "Hello name-888. Welcome to dbzero!!\n", + "Hello name-889. Welcome to dbzero!!\n", + "Hello name-890. Welcome to dbzero!!\n", + "Hello name-891. Welcome to dbzero!!\n", + "Hello name-892. Welcome to dbzero!!\n", + "Hello name-893. Welcome to dbzero!!\n", + "Hello name-894. Welcome to dbzero!!\n", + "Hello name-895. Welcome to dbzero!!\n", + "Hello name-896. Welcome to dbzero!!\n", + "Hello name-897. Welcome to dbzero!!\n", + "Hello name-898. Welcome to dbzero!!\n", + "Hello name-899. Welcome to dbzero!!\n", + "Hello name-900. Welcome to dbzero!!\n", + "Hello name-901. Welcome to dbzero!!\n", + "Hello name-902. Welcome to dbzero!!\n", + "Hello name-903. Welcome to dbzero!!\n", + "Hello name-904. Welcome to dbzero!!\n", + "Hello name-905. Welcome to dbzero!!\n", + "Hello name-906. Welcome to dbzero!!\n", + "Hello name-907. Welcome to dbzero!!\n", + "Hello name-908. Welcome to dbzero!!\n", + "Hello name-909. Welcome to dbzero!!\n", + "Hello name-910. Welcome to dbzero!!\n", + "Hello name-911. Welcome to dbzero!!\n", + "Hello name-912. Welcome to dbzero!!\n", + "Hello name-913. Welcome to dbzero!!\n", + "Hello name-914. Welcome to dbzero!!\n", + "Hello name-915. Welcome to dbzero!!\n", + "Hello name-916. Welcome to dbzero!!\n", + "Hello name-917. Welcome to dbzero!!\n", + "Hello name-918. Welcome to dbzero!!\n", + "Hello name-919. Welcome to dbzero!!\n", + "Hello name-920. Welcome to dbzero!!\n", + "Hello name-921. Welcome to dbzero!!\n", + "Hello name-922. Welcome to dbzero!!\n", + "Hello name-923. Welcome to dbzero!!\n", + "Hello name-924. Welcome to dbzero!!\n", + "Hello name-925. Welcome to dbzero!!\n", + "Hello name-926. Welcome to dbzero!!\n", + "Hello name-927. Welcome to dbzero!!\n", + "Hello name-928. Welcome to dbzero!!\n", + "Hello name-929. Welcome to dbzero!!\n", + "Hello name-930. Welcome to dbzero!!\n", + "Hello name-931. Welcome to dbzero!!\n", + "Hello name-932. Welcome to dbzero!!\n", + "Hello name-933. Welcome to dbzero!!\n", + "Hello name-934. Welcome to dbzero!!\n", + "Hello name-935. Welcome to dbzero!!\n", + "Hello name-936. Welcome to dbzero!!\n", + "Hello name-937. Welcome to dbzero!!\n", + "Hello name-938. Welcome to dbzero!!\n", + "Hello name-939. Welcome to dbzero!!\n", + "Hello name-940. Welcome to dbzero!!\n", + "Hello name-941. Welcome to dbzero!!\n", + "Hello name-942. Welcome to dbzero!!\n", + "Hello name-943. Welcome to dbzero!!\n", + "Hello name-944. Welcome to dbzero!!\n", + "Hello name-945. Welcome to dbzero!!\n", + "Hello name-946. Welcome to dbzero!!\n", + "Hello name-947. Welcome to dbzero!!\n", + "Hello name-948. Welcome to dbzero!!\n", + "Hello name-949. Welcome to dbzero!!\n", + "Hello name-950. Welcome to dbzero!!\n", + "Hello name-951. Welcome to dbzero!!\n", + "Hello name-952. Welcome to dbzero!!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello name-953. Welcome to dbzero!!\n", + "Hello name-954. Welcome to dbzero!!\n", + "Hello name-955. Welcome to dbzero!!\n", + "Hello name-956. Welcome to dbzero!!\n", + "Hello name-957. Welcome to dbzero!!\n", + "Hello name-958. Welcome to dbzero!!\n", + "Hello name-959. Welcome to dbzero!!\n", + "Hello name-960. Welcome to dbzero!!\n", + "Hello name-961. Welcome to dbzero!!\n", + "Hello name-962. Welcome to dbzero!!\n", + "Hello name-963. Welcome to dbzero!!\n", + "Hello name-964. Welcome to dbzero!!\n", + "Hello name-965. Welcome to dbzero!!\n", + "Hello name-966. Welcome to dbzero!!\n", + "Hello name-967. Welcome to dbzero!!\n", + "Hello name-968. Welcome to dbzero!!\n", + "Hello name-969. Welcome to dbzero!!\n", + "Hello name-970. Welcome to dbzero!!\n", + "Hello name-971. Welcome to dbzero!!\n", + "Hello name-972. Welcome to dbzero!!\n", + "Hello name-973. Welcome to dbzero!!\n", + "Hello name-974. Welcome to dbzero!!\n", + "Hello name-975. Welcome to dbzero!!\n", + "Hello name-976. Welcome to dbzero!!\n", + "Hello name-977. Welcome to dbzero!!\n", + "Hello name-978. Welcome to dbzero!!\n", + "Hello name-979. Welcome to dbzero!!\n", + "Hello name-980. Welcome to dbzero!!\n", + "Hello name-981. Welcome to dbzero!!\n", + "Hello name-982. Welcome to dbzero!!\n", + "Hello name-983. Welcome to dbzero!!\n", + "Hello name-984. Welcome to dbzero!!\n", + "Hello name-985. Welcome to dbzero!!\n", + "Hello name-986. Welcome to dbzero!!\n", + "Hello name-987. Welcome to dbzero!!\n", + "Hello name-988. Welcome to dbzero!!\n", + "Hello name-989. Welcome to dbzero!!\n", + "Hello name-990. Welcome to dbzero!!\n", + "Hello name-991. Welcome to dbzero!!\n", + "Hello name-992. Welcome to dbzero!!\n", + "Hello name-993. Welcome to dbzero!!\n", + "Hello name-994. Welcome to dbzero!!\n", + "Hello name-995. Welcome to dbzero!!\n", + "Hello name-996. Welcome to dbzero!!\n", + "Hello name-997. Welcome to dbzero!!\n", + "Hello name-998. Welcome to dbzero!!\n", + "Hello name-999. Welcome to dbzero!!\n" + ] + } + ], + "source": [ + "mh = HelloMany()\n", + "mh.greet()" + ] + }, + { + "cell_type": "markdown", + "id": "c3e94994", + "metadata": {}, + "source": [ + "We can see that many_hellos and mh are different Python objects, but they represent the same DB0 object." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "80ba330d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "140189569273360 140189569273360\n" + ] + } + ], + "source": [ + "print(f\"{id(many_hellos)} {id(mh)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "fcba2e21", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DFZ46RQG7QPR3IEBUHJIABYN DFZ46RQG7QPR3IEBUHJIABYN\n" + ] + } + ], + "source": [ + "print(f\"{db0.uuid(many_hellos)} {db0.uuid(mh)}\")" + ] + }, + { + "cell_type": "markdown", + "id": "8ee99729", + "metadata": {}, + "source": [ + "### So what is actually stored in the list HelloMany.hellos?\n", + "Similarly to regular Python objects - the list stores references, not full instances. **dbzero** lists can store simple types (numbers/strings), other collections (lists, dicts, sets, tuples etc.) or references to any other dbzero @memo instances." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "cee2abcb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DFZ46RQG7QPR3IEBUCRYAAQN\n", + "DFZ46RQG7QPR3IEBUDDIAAYN\n", + "DFZ46RQG7QPR3IEBUDUYABAN\n", + "DFZ46RQG7QPR3IEBUGGIABIN\n", + "DFZ46RQG7QPR3IEBUGXYABQN\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "844424934367952\n", + "844424934367968\n", + "844424934367984\n", + "844424934368000\n", + "844424934368016\n", + "844424934368032\n", + "844424934368048\n", + "844424934368064\n", + "844424934368080\n", + "844424934368096\n", + "844424934368112\n", + "844424934368128\n", + "844424934368144\n", + "844424934368160\n", + "844424934368176\n", + "844424934368192\n", + "844424934368208\n", + "844424934368224\n", + "844424934368240\n", + "844424934368256\n", + "844424934368272\n", + "844424934368288\n", + "844424934368304\n", + "844424934368320\n", + "844424934368336\n", + "844424934368352\n", + "844424934368368\n", + "844424934368384\n", + "844424934368400\n", + "844424934368416\n", + "844424934368432\n", + "844424934368448\n", + "844424934368464\n", + "844424934368480\n", + "844424934368496\n", + "844424934368512\n", + "844424934368528\n", + "844424934368544\n", + "844424934368560\n", + "844424934368576\n", + "844424934368592\n", + "844424934368608\n", + "844424934368624\n", + "844424934368640\n", + "844424934368656\n", + "844424934368672\n", + "844424934368688\n", + "844424934368704\n", + "844424934368720\n", + "844424934368736\n", + "844424934368752\n", + "844424934368768\n", + "844424934368784\n", + "844424934368800\n", + "844424934368816\n", + "844424934368832\n", + "844424934368848\n", + "844424934368864\n", + "844424934368880\n", + "844424934368896\n", + "844424934368912\n", + "844424934368928\n", + "844424934368944\n", + "844424934368960\n", + "844424934368976\n", + "844424934368992\n", + "844424934369008\n", + "844424934369024\n", + "844424934369040\n", + "844424934369056\n", + "844424934369072\n", + "844424934369088\n", + "844424934369104\n", + "844424934369120\n", + "844424934369136\n", + "844424934369152\n", + "844424934369168\n", + "844424934369184\n", + "844424934369200\n", + "844424934369216\n", + "844424934369232\n", + "844424934369248\n", + "844424934369264\n", + "844424934369280\n", + "844424934369296\n", + "844424934369312\n", + "844424934369328\n", + "844424934369344\n", + "844424934369360\n", + "844424934369376\n", + "844424934369392\n", + "844424934369408\n", + "844424934369424\n", + "844424934369440\n", + "844424934369456\n", + "844424934369472\n", + "844424934369488\n", + "844424934369504\n", + "844424934369520\n", + "844424934369536\n", + "844424934369552\n", + "844424934369568\n", + "844424934369584\n", + "844424934369600\n", + "844424934369616\n", + "844424934369632\n", + "844424934369648\n", + "844424934369664\n", + "844424934369680\n", + "844424934369696\n", + "844424934369712\n", + "844424934369728\n", + "844424934369744\n", + "844424934369760\n", + "844424934369776\n", + "844424934369792\n", + "844424934369808\n", + "844424934369824\n", + "844424934369840\n", + "844424934369856\n", + "844424934369872\n", + "844424934369888\n", + "844424934369904\n", + "844424934369920\n", + "844424934369936\n", + "844424934369952\n", + "844424934369968\n", + "844424934369984\n", + "844424934370000\n", + "844424934370016\n", + "844424934370032\n", + "844424934370048\n", + "844424934370064\n", + "844424934370080\n", + "844424934370096\n", + "844424934370112\n", + "844424934370128\n", + "844424934370144\n", + "844424934370160\n", + "844424934370176\n", + "844424934370192\n", + "844424934370208\n", + "844424934370224\n", + "844424934370240\n", + "844424934370256\n", + "844424934370272\n", + "844424934370288\n", + "844424934370304\n", + "844424934370320\n", + "844424934370336\n", + "844424934370352\n", + "844424934370368\n", + "844424934370384\n", + "844424934370400\n", + "844424934370416\n", + "844424934370432\n", + "844424934370448\n", + "844424934370464\n", + "844424934370480\n", + "844424934370496\n", + "844424934370512\n", + "844424934370528\n", + "844424934370544\n", + "844424934370560\n", + "844424934370576\n", + "844424934370592\n", + "844424934370608\n", + "844424934370624\n", + "844424934370640\n", + "844424934370656\n", + "844424934370672\n", + "844424934370688\n", + "844424934370704\n", + "844424934370720\n", + "844424934370736\n", + "844424934370752\n", + "844424934370768\n", + "844424934370784\n", + "844424934370800\n", + "844424934370816\n", + "844424934370832\n", + "844424934370848\n", + "844424934370864\n", + "844424934370880\n", + "844424934370896\n", + "844424934370912\n", + "844424934370928\n", + "844424934370944\n", + "844424934370960\n", + "844424934370976\n", + "844424934370992\n", + "844424934371008\n", + "844424934371024\n", + "844424934371040\n", + "844424934371056\n", + "844424934371072\n", + "844424934371088\n", + "844424934371104\n", + "844424934371120\n", + "844424934371136\n", + "844424934371152\n", + "844424934371168\n", + "844424934371184\n", + "844424934371200\n", + "844424934371216\n", + "844424934371232\n", + "844424934371248\n", + "844424934371264\n", + "844424934371280\n", + "844424934371296\n", + "844424934371312\n", + "844424934371328\n", + "844424934371344\n", + "844424934371360\n", + "844424934371376\n", + "844424934371392\n", + "844424934371408\n", + "844424934371424\n", + "844424934371440\n", + "844424934371456\n", + "844424934371472\n", + "844424934371488\n", + "844424934371504\n", + "844424934371520\n", + "844424934371536\n", + "844424934371552\n", + "844424934371568\n", + "844424934371584\n", + "844424934371600\n", + "844424934371616\n", + "844424934371632\n", + "844424934371648\n", + "844424934371664\n", + "844424934371680\n", + "844424934371696\n", + "844424934371712\n", + "844424934371728\n", + "844424934371744\n", + "844424934371760\n", + "844424934371776\n", + "844424934371792\n", + "844424934371808\n", + "844424934371824\n", + "844424934371840\n", + "844424934371856\n", + "844424934371872\n", + "844424934371888\n", + "844424934371904\n", + "844424934371920\n", + "844424934371936\n", + "844424934371952\n", + "844424934371968\n", + "844424934371984\n", + "844424934372000\n", + "844424934372016\n", + "844424934372032\n", + "844424934372048\n", + "844424934372064\n", + "844424934372080\n", + "844424934372096\n", + "844424934372112\n", + "844424934372128\n", + "844424934372144\n", + "844424934372160\n", + "844424934372176\n", + "844424934372192\n", + "844424934372208\n", + "844424934372224\n", + "844424934372240\n", + "844424934372256\n", + "844424934372272\n", + "844424934372288\n", + "844424934372304\n", + "844424934372320\n", + "844424934372336\n", + "844424934372352\n", + "844424934372368\n", + "844424934372384\n", + "844424934372400\n", + "844424934372416\n", + "844424934372432\n", + "844424934372448\n", + "844424934372464\n", + "844424934372480\n", + "844424934372496\n", + "844424934372512\n", + "844424934372528\n", + "844424934372544\n", + "844424934372560\n", + "844424934372576\n", + "844424934372592\n", + "844424934372608\n", + "844424934372624\n", + "844424934372640\n", + "844424934372656\n", + "844424934372672\n", + "844424934372688\n", + "844424934372704\n", + "844424934372720\n", + "844424934372736\n", + "844424934372752\n", + "844424934372768\n", + "844424934372784\n", + "844424934372800\n", + "844424934372816\n", + "844424934372832\n", + "844424934372848\n", + "844424934372864\n", + "844424934372880\n", + "844424934372896\n", + "844424934372912\n", + "844424934372928\n", + "844424934372944\n", + "844424934372960\n", + "844424934372976\n", + "844424934372992\n", + "844424934373008\n", + "844424934373024\n", + "844424934373040\n", + "844424934373056\n", + "844424934373072\n", + "844424934373088\n", + "844424934373104\n", + "844424934373120\n", + "844424934373136\n", + "844424934373152\n", + "844424934373168\n", + "844424934373184\n", + "844424934373200\n", + "844424934373216\n", + "844424934373232\n", + "844424934373248\n", + "844424934373264\n", + "844424934373280\n", + "844424934373296\n", + "844424934373312\n", + "844424934373328\n", + "844424934373344\n", + "844424934373360\n", + "844424934373376\n", + "844424934373392\n", + "844424934373408\n", + "844424934373424\n", + "844424934373440\n", + "844424934373456\n", + "844424934373472\n", + "844424934373488\n", + "844424934373504\n", + "844424934373520\n", + "844424934373536\n", + "844424934373552\n", + "844424934373568\n", + "844424934373584\n", + "844424934373600\n", + "844424934373616\n", + "844424934373632\n", + "844424934373648\n", + "844424934373664\n", + "844424934373680\n", + "844424934373696\n", + "844424934373712\n", + "844424934373728\n", + "844424934373744\n", + "844424934373760\n", + "844424934373776\n", + "844424934373792\n", + "844424934373808\n", + "844424934373824\n", + "844424934373840\n", + "844424934373856\n", + "844424934373872\n", + "844424934373888\n", + "844424934373904\n", + "844424934373920\n", + "844424934373936\n", + "844424934373952\n", + "844424934373968\n", + "844424934373984\n", + "844424934374000\n", + "844424934374016\n", + "844424934374032\n", + "844424934374048\n", + "844424934374064\n", + "844424934374080\n", + "844424934374096\n", + "844424934374112\n", + "844424934374128\n", + "844424934374144\n", + "844424934374160\n", + "844424934374176\n", + "844424934374192\n", + "844424934374208\n", + "844424934374224\n", + "844424934374240\n", + "844424934374256\n", + "844424934374272\n", + "844424934374288\n", + "844424934374304\n", + "844424934374320\n", + "844424934374336\n", + "844424934374352\n", + "844424934374368\n", + "844424934374384\n", + "844424934374400\n", + "844424934374416\n", + "844424934374432\n", + "844424934374448\n", + "844424934374464\n", + "844424934374480\n", + "844424934374496\n", + "844424934374512\n", + "844424934374528\n", + "844424934374544\n", + "844424934374560\n", + "844424934374576\n", + "844424934374592\n", + "844424934374608\n", + "844424934374624\n", + "844424934374640\n", + "844424934374656\n", + "844424934374672\n", + "844424934374688\n", + "844424934374704\n", + "844424934374720\n", + "844424934374736\n", + "844424934374752\n", + "844424934374768\n", + "844424934374784\n", + "844424934374800\n", + "844424934374816\n", + "844424934374832\n", + "844424934374848\n", + "844424934374864\n", + "844424934374880\n", + "844424934374896\n", + "844424934374912\n", + "844424934374928\n", + "844424934374944\n", + "844424934374960\n", + "844424934374976\n", + "844424934374992\n", + "844424934375008\n", + "844424934375024\n", + "844424934375040\n", + "844424934375056\n", + "844424934375072\n", + "844424934375088\n", + "844424934375104\n", + "844424934375120\n", + "844424934375136\n", + "844424934375152\n", + "844424934375168\n", + "844424934375184\n", + "844424934375200\n", + "844424934375216\n", + "844424934375232\n", + "844424934375248\n", + "844424934375264\n", + "844424934375280\n", + "844424934375296\n", + "844424934375312\n", + "844424934375328\n", + "844424934375344\n", + "844424934375360\n", + "844424934375376\n", + "844424934375392\n", + "844424934375408\n", + "844424953171968\n", + "844424953171984\n", + "844424953172000\n", + "844424953172016\n", + "844424953172032\n", + "844424953172048\n", + "844424953172064\n", + "844424953172080\n", + "844424953172096\n", + "844424953172112\n", + "844424953172128\n", + "844424953172144\n" + ] + } + ], + "source": [ + "for obj in mh.hellos:\n", + " print(db0.uuid(obj))" + ] + }, + { + "cell_type": "markdown", + "id": "9e796db6", + "metadata": {}, + "source": [ + "And a **dbzero** list acts exactly like any regular Python list - you can iterate, slice, or access its elements by index." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "c12a5b4b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello Frank. Welcome to dbzero!!\n" + ] + } + ], + "source": [ + "mh.hellos[3].greet()" + ] + }, + { + "cell_type": "markdown", + "id": "32e73b42", + "metadata": {}, + "source": [ + "### So how big can a single list be?\n", + "In Python, normally your list would be limited by the size of RAM available to your process (in practice, when running a program - who knows what this limit exactly is?). For DB0 (cloud) users, we have good news. There are no limits! If you wish, you can create a list of size far exceeding your available memory. In the case of the local version, this size is limited by the available disk space." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "b6145d70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n" + ] + } + ], + "source": [ + "print(len(mh.hellos))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "99f60571", + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(1000):\n", + " mh.hellos.append(HelloWorld(f\"name-{i}\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "dd690238", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1005\n" + ] + } + ], + "source": [ + "print(len(mh.hellos))" + ] + }, + { + "cell_type": "markdown", + "id": "43594eb5", + "metadata": {}, + "source": [ + "Let's explore memory utilization and limits in the next notebook." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "d3b681a3", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a29f46c", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/hello.db0_3.ipynb b/notebooks/hello/hello.db0_3.ipynb new file mode 100644 index 00000000..4b2c1354 --- /dev/null +++ b/notebooks/hello/hello.db0_3.ipynb @@ -0,0 +1,329 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "be05952a", + "metadata": {}, + "source": [ + "## Introducing **dbzero** (3/12): Exploring the Limits" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "38c6322c", + "metadata": {}, + "outputs": [], + "source": [ + "import dbzero as db0\n", + "from mem_charts import mem_usage_chart, random_string\n", + "from bokeh.io import show, output_notebook\n", + "import concurrent.futures" + ] + }, + { + "cell_type": "markdown", + "id": "abf8826b", + "metadata": {}, + "source": [ + "We've imported the 'bokeh' package to visualize current memory utilization on a chart." + ] + }, + { + "cell_type": "markdown", + "id": "9880fd22", + "metadata": {}, + "source": [ + "Let's also create an executor to be able to run Python tasks in the background (in a separate thread)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "23d84849", + "metadata": {}, + "outputs": [], + "source": [ + "executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)" + ] + }, + { + "cell_type": "markdown", + "id": "5c0210f9", + "metadata": {}, + "source": [ + "The chart below presents live memory utilization of the current process, refreshed every 1 second." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "d9bda63f", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": "'use strict';\n(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\nconst JS_MIME_TYPE = 'application/javascript';\n const HTML_MIME_TYPE = 'text/html';\n const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n const CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n const script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n function drop(id) {\n const view = Bokeh.index.get_by_id(id)\n if (view != null) {\n view.model.document.clear()\n Bokeh.index.delete(view)\n }\n }\n\n const cell = handle.cell;\n\n const id = cell.output_area._bokeh_element_id;\n const server_id = cell.output_area._bokeh_server_id;\n\n // Clean up Bokeh references\n if (id != null) {\n drop(id)\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd_clean, {\n iopub: {\n output: function(msg) {\n const id = msg.content.text.trim()\n drop(id)\n }\n }\n });\n // Destroy server and session\n const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd_destroy);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n const output_area = handle.output_area;\n const output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n return\n }\n\n const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n const bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n const script_attrs = bk_div.children[0].attributes;\n for (let i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n const toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n const events = require('base/js/events');\n const OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded(error = null) {\n const el = document.getElementById(null);\n if (el != null) {\n const html = (() => {\n if (typeof root.Bokeh === \"undefined\") {\n if (error == null) {\n return \"BokehJS is loading ...\";\n } else {\n return \"BokehJS failed to load.\";\n }\n } else {\n const prefix = `BokehJS ${root.Bokeh.version}`;\n if (error == null) {\n return `${prefix} successfully loaded.`;\n } else {\n return `${prefix} encountered errors while loading and may not function as expected.`;\n }\n }\n })();\n el.innerHTML = html;\n\n if (error != null) {\n const wrapper = document.createElement(\"div\");\n wrapper.style.overflow = \"auto\";\n wrapper.style.height = \"5em\";\n wrapper.style.resize = \"vertical\";\n const content = document.createElement(\"div\");\n content.style.fontFamily = \"monospace\";\n content.style.whiteSpace = \"pre-wrap\";\n content.style.backgroundColor = \"rgb(255, 221, 221)\";\n content.textContent = error.stack ?? error.toString();\n wrapper.append(content);\n el.append(wrapper);\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(() => display_loaded(error), 100);\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.6.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n try {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n\n } catch (error) {throw error;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));", + "application/vnd.bokehjs_load.v0+json": "" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.bokehjs_exec.v0+json": "", + "text/html": [ + "" + ] + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "server_id": "48cdc89c96e848da8cd1f5b231ef05be" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "output_notebook(resources=None, verbose=False, hide_banner=True)\n", + "show(mem_usage_chart, notebook_url=\"http://127.0.0.1:8888\", port=8889)" + ] + }, + { + "cell_type": "markdown", + "id": "398da24c", + "metadata": {}, + "source": [ + "Let's first see how memory utilization grows when running regular Python code. We're adding 50k random string elements to a regular Python list in 100 iterations. This totals 5M data elements added. Let's see how this performs..." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "1e8ae17f", + "metadata": {}, + "outputs": [], + "source": [ + "result = []\n", + "def generate_sequence(result, length, batch):\n", + " for _ in range(length):\n", + " result.extend([random_string() for _ in range(batch)])\n", + " print(\"Task finished\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "bc9ee05f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Task finished\n", + "Task finished\n" + ] + } + ], + "source": [ + "task = executor.submit(generate_sequence, result, length=100, batch = 50000)" + ] + }, + { + "cell_type": "markdown", + "id": "5284f2bb", + "metadata": {}, + "source": [ + "The memory just continues to grow and grow and would eventually crash the process with an \"out of memory\" error. In Python we can release memory by simply emptying the list." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "b410f3b0", + "metadata": {}, + "outputs": [], + "source": [ + "result = []" + ] + }, + { + "cell_type": "markdown", + "id": "b2a7007c", + "metadata": {}, + "source": [ + "### OK, so how does **dbzero** differ in this matter?\n", + "In **dbzero**, you work most of the time like with regular Python code but no longer need to worry about memory limits. That's right, even if it's terabytes of data to deal with, your process will never exceed the limits which you define yourself." + ] + }, + { + "cell_type": "markdown", + "id": "9629b52a", + "metadata": {}, + "source": [ + "After initialization, **dbzero** will occupy a small amount of your memory..." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "b5765c47", + "metadata": {}, + "outputs": [], + "source": [ + "db0.init(dbzero_root = \"/dbzero\", prefix = \"data\")" + ] + }, + { + "cell_type": "markdown", + "id": "ea8e0a14", + "metadata": {}, + "source": [ + "But you can control how much additional memory it uses by invoking the 'set_cache_size' method." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "559db1c4", + "metadata": {}, + "outputs": [], + "source": [ + "db0.set_cache_size(128 << 20)" + ] + }, + { + "cell_type": "markdown", + "id": "a950abe1", + "metadata": {}, + "source": [ + "Let's now repeat the test using db0.list (a list object inside the dbzero space). Watch carefully how the memory utilization stops at some point (when the defined cache limit is reached) and does not grow no matter how much data you put into your list." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "630c5bdc", + "metadata": {}, + "outputs": [], + "source": [ + "db0_result = db0.list()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "2d7c89c2", + "metadata": {}, + "outputs": [], + "source": [ + "def db0_generate_sequence(result, length, batch):\n", + " for _ in range(length):\n", + " result.extend([random_string() for _ in range(batch)]) \n", + " print(\"Task finished\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "b275de08", + "metadata": {}, + "outputs": [], + "source": [ + "task = executor.submit(db0_generate_sequence, db0_result, length=100, batch = 50000)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "89276c91", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5000000\n" + ] + }, + { + "data": { + "text/plain": [ + "'1pXfgYf8dYXN'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(len(db0_result))\n", + "db0_result[12313]" + ] + }, + { + "cell_type": "markdown", + "id": "543fc1e3", + "metadata": {}, + "source": [ + "### Well, so where is the data actually stored in this case?\n", + "dbzero implements memory exchange algorithms. It fetches data from the cloud or, in the case of the local version, from the filesystem on a need-to-know basis and retains it in a local cache to allow rapid access in the future. The process is completely transparent to the developer." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "50e3e662", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0eeec23a", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/hello.db0_4.ipynb b/notebooks/hello/hello.db0_4.ipynb new file mode 100644 index 00000000..e87d4348 --- /dev/null +++ b/notebooks/hello/hello.db0_4.ipynb @@ -0,0 +1,1125 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a0014c12", + "metadata": {}, + "source": [ + "## Introducing DBZero (4/12). So how fast is it?" + ] + }, + { + "cell_type": "markdown", + "id": "d045f70b", + "metadata": {}, + "source": [ + "Hey there! In this notebook, we'll be exploring how fast DBZero really is. Unfortunately, there's no straightforward answer to this question, as performance can be influenced by various factors such as hardware setup, available RAM, network latencies (in the cloud version), or even specific usage patterns. However, I can tell you that DBZero is definitely a speedy platform.\n", + "\n", + "To give you a better idea of how it stacks up against other technologies, we'll take a look at a few real-world use cases. We'll also discuss some techniques you can use to improve the performance of specific operations. So, buckle up and let's dive into the world of DBZero performance!" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "5a26338a", + "metadata": {}, + "outputs": [], + "source": [ + "import dbzero as db0\n", + "from performance_charts import performance_chart, performance_plot, add_measurement, init_chart\n", + "from bokeh.io import show, output_notebook\n", + "from demo_utils import Speedometer" + ] + }, + { + "cell_type": "markdown", + "id": "b981af4c", + "metadata": {}, + "source": [ + "To start, we'll create a bar chart that displays the number of operations that can be performed per second. As we run our test cases, the chart will be updated in real-time to reflect the latest results." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "9b5dd9a8", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + "const JS_MIME_TYPE = 'application/javascript';\n", + " const HTML_MIME_TYPE = 'text/html';\n", + " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " const CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " const script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " const cell = handle.cell;\n", + "\n", + " const id = cell.output_area._bokeh_element_id;\n", + " const server_id = cell.output_area._bokeh_server_id;\n", + " // Clean up Bokeh references\n", + " if (id != null && id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd_clean, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " const id = msg.content.text.trim();\n", + " if (id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd_destroy);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " const output_area = handle.output_area;\n", + " const output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " const bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " const script_attrs = bk_div.children[0].attributes;\n", + " for (let i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " const toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " const events = require('base/js/events');\n", + " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " const NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded() {\n", + " const el = document.getElementById(null);\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS is loading...\";\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(display_loaded, 100)\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(null);\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.bokehjs_exec.v0+json": "", + "text/html": [ + "" + ] + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "server_id": "3ae81c88c336426e8364323415cc1286" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "init_chart([\"python\", \"pg\", \"dbzero\"], title=\"Performance Comparison of Object Creation\")\n", + "output_notebook(resources=None, verbose=False, hide_banner=True)\n", + "show(performance_chart, notebook_url=\"http://192.168.8.125:8888\", port=8889)" + ] + }, + { + "cell_type": "markdown", + "id": "688f3f88", + "metadata": {}, + "source": [ + "To keep things simple, we'll be using a dataset that contains just three columns: first name, surname, and address." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3205d83e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
first_namesurnameaddress
0TawandaCAIZA250 Rt 59
1SandiTERISSI555 East Main St
2GemmaPISITELLO900 Boston Post Road
3KateBUTTERFLY1450 No Brindlee Mtn Pkwy
4MarileeNEAMȚU655 Boston Post Rd
............
39995BeckhamHOLOTESCU656 New Haven Ave
39996CosmoŠOBER655 Boston Post Rd
39997DurwardSTRICKER-BAROLIN330 Sutton Rd
39998PricillaBOCANERA100 Elm Ridge Center Dr
39999LenoraFINDLEY85 Crooked Hill Road
\n", + "

40000 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " first_name surname address\n", + "0 Tawanda CAIZA 250 Rt 59\n", + "1 Sandi TERISSI 555 East Main St\n", + "2 Gemma PISITELLO 900 Boston Post Road\n", + "3 Kate BUTTERFLY 1450 No Brindlee Mtn Pkwy\n", + "4 Marilee NEAMȚU 655 Boston Post Rd\n", + "... ... ... ...\n", + "39995 Beckham HOLOTESCU 656 New Haven Ave\n", + "39996 Cosmo ŠOBER 655 Boston Post Rd\n", + "39997 Durward STRICKER-BAROLIN 330 Sutton Rd\n", + "39998 Pricilla BOCANERA 100 Elm Ridge Center Dr\n", + "39999 Lenora FINDLEY 85 Crooked Hill Road\n", + "\n", + "[40000 rows x 3 columns]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "df = pd.read_csv(\"/src/dev/notebooks/data/identities_1M.csv.gzip\", compression=\"gzip\", nrows=40000)\n", + "df" + ] + }, + { + "cell_type": "markdown", + "id": "25c679f1", + "metadata": {}, + "source": [ + "We want to make sure our measurements are accurate, so it's best to avoid pulling rows from the data frame (which are stored as columns). Instead, let's work with in-memory row tuples to get the most reliable results." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "804aa715", + "metadata": {}, + "outputs": [], + "source": [ + "rows = [row for _, row in df.iterrows()]" + ] + }, + { + "cell_type": "markdown", + "id": "e46f7ae1", + "metadata": {}, + "source": [ + "What if we wanted to create regular Python in-memory objects that hold this same data? Well, we can measure the performance of this operation by tracking how many objects we're able to create in a given unit of time.\n", + "\n", + "To do this, I've included a function below that you can use to measure the performance of creating these objects. Once you run the code, be sure to check out the chart above to see the results (note that the chart displays the performance in kOPS)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "cd3cf5a0", + "metadata": {}, + "outputs": [], + "source": [ + "from demo_utils import Speedometer\n", + "\n", + "class PyPerson:\n", + " def __init__(self, *args):\n", + " self.first_name = args[0]\n", + " self.surname = args[1]\n", + " self.address = args[2]\n", + " \n", + "def test_load_objects_to_python():\n", + " meter = Speedometer()\n", + " meter.start()\n", + " for row in rows:\n", + " p = PyPerson(*row)\n", + " meter.measure(len(df))\n", + " add_measurement(\"python\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "70df1ff9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pure Python: 287347.48466536024 operations/sec\n" + ] + } + ], + "source": [ + "test_load_objects_to_python()" + ] + }, + { + "cell_type": "markdown", + "id": "bc21b6f1", + "metadata": {}, + "source": [ + "Just to give you an idea, on my machine, I was able to create these in-memory objects at a rate of roughly 300k per second. Now, let's take a look at what happens when we try the same operation with PostgreSQL using SQLAlchemy (without any indexing at this stage)." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f34f6b83", + "metadata": {}, + "outputs": [], + "source": [ + "from sqlalchemy import create_engine, text, Table, Column, Integer, String\n", + "from sqlalchemy.orm import Mapped\n", + "from sqlalchemy.orm import mapped_column\n", + "from sqlalchemy.orm import relationship\n", + "from sqlalchemy.orm import DeclarativeBase, Session\n", + "\n", + "\n", + "class Base(DeclarativeBase):\n", + " pass\n", + "\n", + "\n", + "class PgPerson(Base):\n", + " __tablename__ = \"Persons\"\n", + " \n", + " id: Mapped[int] = mapped_column(primary_key=True)\n", + " first_name: Mapped[str] = mapped_column(String(), index=False)\n", + " surname: Mapped[str] = mapped_column(String(), index=False)\n", + " address: Mapped[str] = mapped_column(String())\n", + " \n", + " def __repr__(self) -> str:\n", + " return f\"{self.surname}, {self.first_name}. Address: {self.address}\"\n", + " \n", + "engine = create_engine('postgresql+psycopg2://root:root@192.168.8.125/test_db', echo=False)\n", + "Base.metadata.create_all(engine)\n", + "\n", + "def test_load_objects_to_postgres():\n", + " meter = Speedometer()\n", + " session = Session(engine) \n", + " # Clear any data remnants\n", + " session.query(PgPerson).delete()\n", + " meter.start()\n", + " for row in rows:\n", + " session.add(PgPerson(first_name=row[0], surname=row[1], address=row[2]))\n", + " # Time without commit and session close\n", + " meter.measure(len(df))\n", + " session.commit()\n", + " session.close()\n", + " add_measurement(\"pg\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "fff18cb7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SQLAlchemy + PostgreSQL: 40428.21145158946 operations/sec\n" + ] + } + ], + "source": [ + "test_load_objects_to_postgres()" + ] + }, + { + "cell_type": "markdown", + "id": "fb88d2a7", + "metadata": {}, + "source": [ + "Interestingly, when using SQLAlchemy ORM with PostgreSQL, we found that the performance was only about 1/10th of the pure Python speed (excluding the commit time). This is understandable since we not only need to construct Python objects using the ORM, but we also need to translate them to SQL queries and send them to the engine, where they are finally persisted.\n", + "\n", + "Now, let's switch gears and see how the same operation performs on DBZero." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "22f3c575", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero initialized for tenant: itx\n" + ] + } + ], + "source": [ + "db0.init()" + ] + }, + { + "cell_type": "markdown", + "id": "6d5c5b7e", + "metadata": {}, + "source": [ + "Our first approach is to use a Python-native syntax for working with DBZero. It's worth noting that this code differs from the pure Python code by just a single annotation." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "e2f155c4", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.keepit\n", + "class DB0Person:\n", + " def __init__(self, *args):\n", + " self.first_name = args[0]\n", + " self.surname = args[1]\n", + " self.address = args[2]\n", + " \n", + "def test_load_objects_to_db0():\n", + " meter = Speedometer()\n", + " meter.start()\n", + " for row in rows:\n", + " p = DB0Person(*row)\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "ec875d8d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 145967.78836854364 operations/sec\n" + ] + } + ], + "source": [ + "test_load_objects_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "fd42b4f5", + "metadata": {}, + "source": [ + "When I ran this code, I was able to achieve a performance of around 154k objects per second, which is somewhere in between the performance of PostgreSQL and pure Python. This seems like a reasonable result, given that we need to create Python objects and put them into the DBZero space, which adds some additional time.\n", + "\n", + "However, the good news is that DBZero offers a few additional techniques that can significantly improve the performance of object creation tasks. So, let's explore those next!" + ] + }, + { + "cell_type": "markdown", + "id": "a5010c15", + "metadata": {}, + "source": [ + "#### Ok, so the performance is not too bad. But you say it can be improved... how then?" + ] + }, + { + "cell_type": "markdown", + "id": "c26732c6", + "metadata": {}, + "source": [ + "Before we dive into those techniques, let's take a moment to understand how the default object initializers in DBZero work.\n", + "\n", + "By default, if we omit the user-defined `__init__` method, DBZero will provide a built-in one. This is important to keep in mind as we explore ways to optimize object creation in DBZero." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "2e275a37", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.keepit\n", + "class DB0DefaultPerson:\n", + " def __repr__(self) -> str:\n", + " return f\"{self.surname}, {self.first_name}. Address: {self.address}\"\n", + "\n", + "def test_load_default_objects_to_db0():\n", + " meter = Speedometer()\n", + " meter.start()\n", + " for row in rows:\n", + " p = DB0DefaultPerson(first_name = row[0], surname=row[1], address=row[2])\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "f73a1473", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 116000.34588983137 operations/sec\n" + ] + } + ], + "source": [ + "test_load_default_objects_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "a77288b2", + "metadata": {}, + "source": [ + "#### While the performance of built-in initializers is similar, they can help avoid some boilerplate code. But are they useful in any other way?\n", + "Yes, they are. One key advantage is that default initializers can be fully controlled by DBZero. This means that DBZero knows that no special operations are performed on fields before they're assigned as object members, which enables optimizations.\n", + "\n", + "For example, DBZero adds a static method called `__batch_init__` to classes with built-in initializers. This method can be used to initialize multiple objects at once, which can be much faster than initializing objects one at a time." + ] + }, + { + "cell_type": "markdown", + "id": "4ba045a3", + "metadata": {}, + "source": [ + "#### What does __batch_init__ do and how can I use it?\n", + "Let's take a closer look at an example of how to use __batch_init__. This method takes two positional arguments: a tuple of field names and a source of rows (e.g. a list or a generator). The result is an iterable that must be iterated over to create new DB0 Python objects." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "ab0b7b9b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fox, Adam. Address: Dallas\n", + "Wasilewski, Jacek. Address: Gdynia\n" + ] + } + ], + "source": [ + "friends = [(\"Adam\", \"Fox\", \"Dallas\"), (\"Jacek\", \"Wasilewski\", \"Gdynia\")]\n", + "for p in DB0DefaultPerson.__batch_init__([\"first_name\", \"surname\", \"address\"], friends):\n", + " print(p)" + ] + }, + { + "cell_type": "markdown", + "id": "e2262e8f", + "metadata": {}, + "source": [ + "#### It's faster than the regular __init__, right?\n", + "Yes, you're right! Using `__batch_init__` can be much faster than using the regular `__init__` method.\n", + "\n", + "Let's measure how much faster it is. We can do this by pulling out Python objects that were initialized with rows using `__batch_init__`." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "8b5f6061", + "metadata": {}, + "outputs": [], + "source": [ + "def test_batch_load_objects_to_db0():\n", + " meter = Speedometer()\n", + " meter.start()\n", + " for _ in DB0DefaultPerson.__batch_init__((\"first_name\", \"surname\", \"address\"), rows):\n", + " pass\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "4d0bae61", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 230970.5340265098 operations/sec\n" + ] + } + ], + "source": [ + "test_batch_load_objects_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "b2e1171e", + "metadata": {}, + "source": [ + "On my machine, the performance improved by about 50% (as shown in the chart at the top of this document). However, if the objects are not needed immediately, we can further improve performance by using the \"express\" mode. In this mode, the objects are created in DB0 but are not returned to Python." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0b0300ce", + "metadata": {}, + "outputs": [], + "source": [ + "def test_express_batch_load_objects_to_db0():\n", + " meter = Speedometer()\n", + " meter.start()\n", + " DB0DefaultPerson.__batch_init__((\"first_name\", \"surname\", \"address\"), rows, express=True)\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "2da91f29", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 297775.37969338667 operations/sec\n" + ] + } + ], + "source": [ + "test_express_batch_load_objects_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "1d62a66d", + "metadata": {}, + "source": [ + "#### Nice, so now it's almost as fast as in-memory Python.\n", + "Yet it is, and we have even more techniques to further improve performance.\n", + "\n", + "As already mentioned, a pandas data frame actually consists of columns, which are numpy columns stored in memory. We can take advantage of this by passing the entire pandas data frame to `__batch_init__`, which will pull the relevant columns by name. This can make the process even more efficient." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "93dbb955", + "metadata": {}, + "outputs": [], + "source": [ + "def test_batch_load_objects_from_columns_to_db0():\n", + " meter = Speedometer()\n", + " meter.measure(0)\n", + " for p in DB0DefaultPerson.__batch_init__((\"first_name\", \"surname\", \"address\"), data=df):\n", + " pass\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "0c75b270", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 554914.6291588771 operations/sec\n" + ] + } + ], + "source": [ + "test_batch_load_objects_from_columns_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "e9458dd7", + "metadata": {}, + "source": [ + "Express mode can also be used when creating objects from a pandas data frame, which can further boost performance." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "0bd862b4", + "metadata": {}, + "outputs": [], + "source": [ + "def test_express_batch_load_objects_from_columns_to_db0():\n", + " meter = Speedometer()\n", + " meter.measure(0)\n", + " DB0DefaultPerson.__batch_init__((\"first_name\", \"surname\", \"address\"), data=df, express=True)\n", + " meter.measure(len(df))\n", + " add_measurement(\"dbzero\", meter.speed())" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "57588d6d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 904560.3568689611 operations/sec\n" + ] + } + ], + "source": [ + "test_express_batch_load_objects_from_columns_to_db0()" + ] + }, + { + "cell_type": "markdown", + "id": "5e89cdbb", + "metadata": {}, + "source": [ + "Ok, let's take another look at our charts and see the results below." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "927e8d30", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"c0a4cfec-e1d5-4fdd-8d2c-8343b053570f\":{\"version\":\"3.0.3\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1162\",\"attributes\":{\"width\":800,\"height\":400,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1164\"},\"y_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1174\",\"attributes\":{\"factors\":[\"Pure Python\",\"DBZero\",\"SQLAlchemy + PostgreSQL\"]}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1176\"},\"y_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1178\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1165\",\"attributes\":{\"text\":\"Performance Comparison of Object Creation\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1214\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1159\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1160\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1161\"},\"data\":{\"type\":\"map\",\"entries\":[[\"bar_labels\",[\"Pure Python\",\"DBZero\",\"SQLAlchemy + PostgreSQL\"]],[\"bar_values\",[287.34748466536024,904.5603568689611,40.428211451589455]],[\"bar_colors\",[\"#0366d6\",\"#00b3b3\",\"#00008B\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1215\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1216\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1211\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1212\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1213\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1171\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1193\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1194\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1195\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1196\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1197\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1198\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1199\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1187\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1189\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1188\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1190\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1180\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1182\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1181\"},\"axis_label\":\"thousands of operations / sec\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1183\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1186\",\"attributes\":{\"axis\":{\"id\":\"p1180\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1192\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1187\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"c0a4cfec-e1d5-4fdd-8d2c-8343b053570f\",\"roots\":{\"p1162\":\"d5478d17-e004-4f39-a113-8a3ca719948a\"},\"root_ids\":[\"p1162\"]}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1162" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "show(performance_plot())" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "fd31fc95", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "markdown", + "id": "ab093114", + "metadata": {}, + "source": [ + "Stay tuned, in the next episode we'll dive into the performance of lookup queries." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "211dc688", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/hello.db0_5.ipynb b/notebooks/hello/hello.db0_5.ipynb new file mode 100644 index 00000000..1571442b --- /dev/null +++ b/notebooks/hello/hello.db0_5.ipynb @@ -0,0 +1,945 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "67771bd8", + "metadata": {}, + "source": [ + "## Introducing DBZero (5/12). Lookup query performance." + ] + }, + { + "cell_type": "markdown", + "id": "8472de76", + "metadata": {}, + "source": [ + "Hey there! In this tutorial, we'll be checking out how well some common queries used in apps perform. These queries include retrieving an object by its ID or searching for specific criteria." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "21f085da", + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "import dbzero as db0\n", + "import pandas as pd\n", + "from performance_charts import performance_plot, add_measurement, init_chart\n", + "from bokeh.io import show, output_notebook\n", + "from demo_utils import Speedometer\n", + "\n", + "from sqlalchemy import create_engine, text, Table, Column, Integer, String, func, and_\n", + "from sqlalchemy.orm import Mapped\n", + "from sqlalchemy.orm import mapped_column\n", + "from sqlalchemy.orm import relationship\n", + "from sqlalchemy.orm import DeclarativeBase, Session" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "dca44a5b", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + "const JS_MIME_TYPE = 'application/javascript';\n", + " const HTML_MIME_TYPE = 'text/html';\n", + " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " const CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " const script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " const cell = handle.cell;\n", + "\n", + " const id = cell.output_area._bokeh_element_id;\n", + " const server_id = cell.output_area._bokeh_server_id;\n", + " // Clean up Bokeh references\n", + " if (id != null && id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd_clean, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " const id = msg.content.text.trim();\n", + " if (id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd_destroy);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " const output_area = handle.output_area;\n", + " const output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " const bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " const script_attrs = bk_div.children[0].attributes;\n", + " for (let i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " const toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " const events = require('base/js/events');\n", + " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " const NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded() {\n", + " const el = document.getElementById(null);\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS is loading...\";\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(display_loaded, 100)\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(null);\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "init_chart([\"pg\", \"dbzero\"])\n", + "output_notebook(resources=None, verbose=False, hide_banner=True)" + ] + }, + { + "cell_type": "markdown", + "id": "6cd3e0c1", + "metadata": {}, + "source": [ + "Alright, let's go ahead and load up two datasets with just one column each. These columns will contain commonly used first names and surnames of individuals." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "92462b58", + "metadata": {}, + "outputs": [], + "source": [ + "surnames = pd.read_csv(\"/src/dev/notebooks/data/surnames.csv.gzip\", compression=\"gzip\", \n", + " header=None)[0].apply(lambda x: str(x)[:30])\n", + "first_names = pd.read_csv(\"/src/dev/notebooks/data/first_names.csv.gzip\", compression=\"gzip\", \n", + " header=None)[0].apply(lambda x: str(x)[:30])" + ] + }, + { + "cell_type": "markdown", + "id": "cfc6ec7e", + "metadata": {}, + "source": [ + "Assuming you've already used the `load_lookup_test_data.py` script to load the 1M datasets to PostgreSQL and DB0, we can now proceed. If you haven't done this yet, please go back and make sure to run the script now. This time around, we've indexed the \"first_name\" and \"surname\" columns to enable speedy lookups in PostgreSQL." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "94c10587", + "metadata": {}, + "outputs": [], + "source": [ + "class Base(DeclarativeBase):\n", + " pass\n", + "\n", + "\n", + "class PgPerson(Base):\n", + " __tablename__ = \"Persons1M\"\n", + " \n", + " id: Mapped[int] = mapped_column(primary_key=True)\n", + " first_name: Mapped[str] = mapped_column(String(), index=True)\n", + " surname: Mapped[str] = mapped_column(String(), index=True)\n", + " address: Mapped[str] = mapped_column(String(), nullable=True)\n", + " \n", + "engine = create_engine('postgresql+psycopg2://root:root@192.168.8.125/test_db', echo=False)\n", + "Base.metadata.create_all(engine)" + ] + }, + { + "cell_type": "markdown", + "id": "b9ee0ef2", + "metadata": {}, + "source": [ + "For the lookup performance test, we'll just be generating random IDs (within the range available in the data) and retrieving objects from the database based on those IDs." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "1d5ba4d0", + "metadata": {}, + "outputs": [], + "source": [ + "def test_postgres_lookup_by_id(limit = 100000):\n", + " meter = Speedometer()\n", + " with Session(engine) as session:\n", + " min_id = session.query(func.min(PgPerson.id)).scalar()\n", + " max_id = session.query(func.max(PgPerson.id)).scalar()\n", + " \n", + " meter.start()\n", + " for _ in range(limit):\n", + " person = session.query(PgPerson).filter_by(id=random.randrange(min_id, max_id)).one_or_none()\n", + " meter.measure(limit)\n", + " add_measurement(\"pg\", meter.speed(), test=\"lookup_by_id\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "399a6ec0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SQLAlchemy + PostgreSQL: 1792.9085100816772 operations/sec\n" + ] + } + ], + "source": [ + "test_postgres_lookup_by_id()" + ] + }, + { + "cell_type": "markdown", + "id": "a608dc51", + "metadata": {}, + "source": [ + "To present the results, we'll create a bar chart..." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "0133335b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"787d1fc3-d52b-412d-84ab-e8c1d3830588\":{\"version\":\"3.0.3\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1007\",\"attributes\":{\"width\":800,\"height\":400,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1009\"},\"y_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1019\",\"attributes\":{\"factors\":[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1021\"},\"y_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1023\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1010\",\"attributes\":{\"text\":\"Lookup by object ID performance comparison\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1059\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1004\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1006\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1005\"},\"data\":{\"type\":\"map\",\"entries\":[[\"bar_labels\",[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]],[\"bar_values\",[0,1.792908510081677]],[\"bar_colors\",[\"#00b3b3\",\"#00008B\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1060\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1061\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1056\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1057\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1058\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1015\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1038\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1039\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1040\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1041\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1042\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1043\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1044\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1032\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1035\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1033\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1034\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1025\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1028\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1026\"},\"axis_label\":\"thousands of operations / sec\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1027\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1031\",\"attributes\":{\"axis\":{\"id\":\"p1025\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1037\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1032\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"787d1fc3-d52b-412d-84ab-e8c1d3830588\",\"roots\":{\"p1007\":\"388eb638-9c6e-4f19-950d-dce47a047a6c\"},\"root_ids\":[\"p1007\"]}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1007" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "show(performance_plot(test=\"lookup_by_id\"))" + ] + }, + { + "cell_type": "markdown", + "id": "a47c533a", + "metadata": {}, + "source": [ + "As for DB0, the assigned IDs aren't consecutive, so we'll need to take a different approach. For instance, we could randomly select objects from the list of 1 million entries (instead of using IDs, we'll use list indices 0 - N-1). Now, let's see how well this approach performs." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "19dec8f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero initialized for tenant: itx\n" + ] + } + ], + "source": [ + "db0.init()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b708f592", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.keepit\n", + "class DB0_Person1M:\n", + " pass\n", + "\n", + "\n", + "def test_db0_lookup_by_index(limit = 100000):\n", + " meter = Speedometer()\n", + " l = db0.list(key=\"/dbzero/demo/hello.db0_5/object_list\")\n", + " min_id, max_id = 0, len(l) - 1\n", + " meter.start()\n", + " for _ in range(limit):\n", + " person = l[random.randrange(min_id, max_id)]\n", + " meter.measure(limit)\n", + " add_measurement(\"dbzero\", meter.speed(), test=\"lookup_by_id\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "dc265967", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 97350.61072253388 operations/sec\n" + ] + } + ], + "source": [ + "test_db0_lookup_by_index()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "5055015d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"d48fca5f-6ad9-44bc-8e7f-fab39c76a02a\":{\"version\":\"3.0.3\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1143\",\"attributes\":{\"width\":800,\"height\":400,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1145\"},\"y_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1155\",\"attributes\":{\"factors\":[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1157\"},\"y_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1159\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1146\",\"attributes\":{\"text\":\"Lookup by object ID performance comparison\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1195\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1140\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1142\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1141\"},\"data\":{\"type\":\"map\",\"entries\":[[\"bar_labels\",[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]],[\"bar_values\",[97.35061072253387,1.792908510081677]],[\"bar_colors\",[\"#00b3b3\",\"#00008B\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1196\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1197\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1192\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1193\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1194\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1151\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1174\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1175\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1176\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1177\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1178\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1179\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1180\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1168\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1171\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1169\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1170\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1161\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1164\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1162\"},\"axis_label\":\"thousands of operations / sec\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1163\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1167\",\"attributes\":{\"axis\":{\"id\":\"p1161\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1173\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1168\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"d48fca5f-6ad9-44bc-8e7f-fab39c76a02a\",\"roots\":{\"p1143\":\"8e5e6111-c0d3-40fa-99ca-112994e7fb26\"},\"root_ids\":[\"p1143\"]}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1143" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "show(performance_plot(test=\"lookup_by_id\"))" + ] + }, + { + "cell_type": "markdown", + "id": "3f06eb11", + "metadata": {}, + "source": [ + "For a more appropriate test that measures the actual fetch operation, we would first retrieve all existing IDs and then randomly select and fetch objects with those IDs." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "bb8a9d0e", + "metadata": {}, + "outputs": [], + "source": [ + "def test_db0_lookup_by_id(limit = 100000):\n", + " meter = Speedometer()\n", + " all_ids = [db0.id(o) for o in db0.list(key=\"/dbzero/demo/hello.db0_5/object_list\")]\n", + " meter.start()\n", + " for _ in range(limit):\n", + " person = db0.get(DB0_Person1M, random.choice(all_ids))\n", + " meter.measure(limit)\n", + " add_measurement(\"dbzero\", meter.speed(), test=\"lookup_by_id\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "c246db25", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 479393.0615380813 operations/sec\n" + ] + } + ], + "source": [ + "test_db0_lookup_by_id()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "6b026083", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"eb64eee6-0ceb-4d62-b2d8-2026d7020d5d\":{\"version\":\"3.0.3\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1292\",\"attributes\":{\"width\":800,\"height\":400,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1294\"},\"y_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1304\",\"attributes\":{\"factors\":[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1306\"},\"y_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1308\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1295\",\"attributes\":{\"text\":\"Lookup by object ID performance comparison\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1344\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1289\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1291\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1290\"},\"data\":{\"type\":\"map\",\"entries\":[[\"bar_labels\",[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]],[\"bar_values\",[479.3930615380813,1.792908510081677]],[\"bar_colors\",[\"#00b3b3\",\"#00008B\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1345\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1346\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1341\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1342\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1343\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1300\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1323\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1324\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1325\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1326\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1327\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1328\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1329\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1317\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1320\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1318\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1319\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1310\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1313\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1311\"},\"axis_label\":\"thousands of operations / sec\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1312\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1316\",\"attributes\":{\"axis\":{\"id\":\"p1310\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1322\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1317\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"eb64eee6-0ceb-4d62-b2d8-2026d7020d5d\",\"roots\":{\"p1292\":\"04070d81-9cee-4349-b782-5874634eb8cf\"},\"root_ids\":[\"p1292\"]}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1292" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "show(performance_plot(test=\"lookup_by_id\"))" + ] + }, + { + "cell_type": "markdown", + "id": "0e5b5941", + "metadata": {}, + "source": [ + "#### I understand what you're saying. Apps usually don't just retrieve objects based on their IDs.
How do other querying patterns perform in comparison?\n", + "In a more realistic scenario, you might want to look something up first and then add the record to the database - for example, checking if a person already exists and only registering them in the database if they're unique. Of course, we want to give the users some feedback (like \"name taken\") before actually committing the operation. So, we'll break this process down into two parts - the lookup and the commit." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "08718fc8", + "metadata": {}, + "outputs": [], + "source": [ + "class PgPersonMix(Base):\n", + " __tablename__ = \"PersonsMix\"\n", + " \n", + " id: Mapped[int] = mapped_column(primary_key=True)\n", + " first_name: Mapped[str] = mapped_column(String(), index=True)\n", + " surname: Mapped[str] = mapped_column(String(), index=True)\n", + " address: Mapped[str] = mapped_column(String(), nullable=True)\n", + " \n", + "Base.metadata.create_all(engine)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "2aa32ddd", + "metadata": {}, + "outputs": [], + "source": [ + "def test_postgres_mixed_lookup_then_commit(limit = 10000):\n", + " meter = Speedometer()\n", + " with Session(engine) as session:\n", + " # Clear any leftovers\n", + " session.query(PgPersonMix).delete()\n", + " meter.start()\n", + " for _ in range(limit):\n", + " first_name = random.choice(first_names)\n", + " surname = random.choice(surnames)\n", + " # add a new person if no such exists yet\n", + " if session.query(PgPersonMix).filter(\n", + " and_(PgPersonMix.first_name==first_name, PgPersonMix.surname==surname)).first() is None:\n", + " session.add(PgPersonMix(first_name=first_name, surname=surname))\n", + " session.commit()\n", + " meter.measure(limit)\n", + " add_measurement(\"pg\", meter.speed(), test=\"mixed_access\")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "4a8a2df4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SQLAlchemy + PostgreSQL: 46.48888203435324 operations/sec\n" + ] + } + ], + "source": [ + "test_postgres_mixed_lookup_then_commit(1000)" + ] + }, + { + "cell_type": "markdown", + "id": "00495f33", + "metadata": {}, + "source": [ + "To achieve this functionality in DB0, we can use tags! Let me show you an example of how this implementation might look. Just a heads up - we'll be prefixing the tags with \"F\" and \"S\" characters to distinguish between first names and surnames." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "ad4b535a", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.keepit\n", + "class DB0_PersonMix:\n", + " pass\n", + "\n", + "\n", + "def test_db0_mixed_lookup_then_commit(limit = 10000):\n", + " meter = Speedometer()\n", + " meter.start()\n", + " for _ in range(limit):\n", + " first_name = random.choice(first_names)\n", + " surname = random.choice(surnames)\n", + " if not any(db0.find(DB0_PersonMix, (\"F\" + first_name, \"S\" + surname))):\n", + " person = DB0_PersonMix(first_name=first_name, surname=surname, __tags__=(\"F\" + first_name, \"S\" + surname))\n", + " meter.measure(limit)\n", + " add_measurement(\"dbzero\", meter.speed(), test=\"mixed_access\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "b0a7e4d4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DBZero: 12290.942181432823 operations/sec\n" + ] + } + ], + "source": [ + "test_db0_mixed_lookup_then_commit()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "f05872be", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"9b28670f-f8ee-4ea3-a102-27ee65fa3055\":{\"version\":\"3.0.3\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1454\",\"attributes\":{\"width\":800,\"height\":400,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1456\"},\"y_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1466\",\"attributes\":{\"factors\":[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1468\"},\"y_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1470\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1457\",\"attributes\":{\"text\":\"\\\"Lookup then commit\\\" performance comparison\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1506\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1451\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1453\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1452\"},\"data\":{\"type\":\"map\",\"entries\":[[\"bar_labels\",[\"DBZero\",\"SQLAlchemy + PostgreSQL\"]],[\"bar_values\",[12.290942181432824,0.04648888203435324]],[\"bar_colors\",[\"#00b3b3\",\"#00008B\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1507\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1508\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1503\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1504\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"HBar\",\"id\":\"p1505\",\"attributes\":{\"y\":{\"type\":\"field\",\"field\":\"bar_labels\"},\"height\":{\"type\":\"value\",\"value\":0.375},\"right\":{\"type\":\"field\",\"field\":\"bar_values\"},\"line_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"bar_colors\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1462\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1485\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1486\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1487\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1488\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1489\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1490\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1491\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1479\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1482\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1480\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1481\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1472\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1475\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1473\"},\"axis_label\":\"thousands of operations / sec\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1474\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1478\",\"attributes\":{\"axis\":{\"id\":\"p1472\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1484\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1479\"}}}]}}]}};\n", + " const render_items = [{\"docid\":\"9b28670f-f8ee-4ea3-a102-27ee65fa3055\",\"roots\":{\"p1454\":\"b9493507-864d-46f1-922d-4590e7c66a01\"},\"root_ids\":[\"p1454\"]}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1454" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "show(performance_plot(test=\"mixed_access\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "695009d6", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6e8b11a", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/hello/mem_charts.py b/notebooks/hello/mem_charts.py new file mode 100644 index 00000000..f5b01c80 --- /dev/null +++ b/notebooks/hello/mem_charts.py @@ -0,0 +1,99 @@ +import yaml + +from bokeh.layouts import column +from bokeh.models import ColumnDataSource, Slider, PreText +from bokeh.plotting import figure +from bokeh.themes import Theme +from bokeh.io import show, output_notebook +from datetime import datetime +import psutil +import os +import collections +import bisect +import string +import random + + +class MemUsageHistory: + def __init__(self, size=60): + self.size = size + self.start = datetime.now() + self.measurements = collections.OrderedDict() + + @staticmethod + def current_memory_usage(): + process = psutil.Process(pid=os.getpid()) + mem_info = process.memory_info() + return mem_info.rss / 1024 / 1024 + + def measure(self): + e = (datetime.now() - self.start).total_seconds() + self.measurements[e] = MemUsageHistory.current_memory_usage() + + def source(self): + time = [] + mem_usage = [] + e = (datetime.now() - self.start).total_seconds() + + def find_measurement(e): + if e > 0: + keys = list(self.measurements.keys()) + if len(keys) > 0: + index = bisect.bisect_left(keys, e) + if index > 0 and index < len(keys): + return self.measurements[keys[index]] + return 0 + + for i in range(self.size): + time.append(e - self.size + i) + mem_usage.append(find_measurement(e - self.size + i)) + + return {"time": time, "mem_usage": mem_usage} + + +usage_history = MemUsageHistory() +source = ColumnDataSource(data=usage_history.source()) + + +def callback(attr, old, new): + global usage_history + global source + + usage_history.measure() + source.data = usage_history.source() + + +def mem_usage_chart(doc): + global source + + plot = figure(x_axis_type='auto', y_range=(0, MemUsageHistory.current_memory_usage() * 5), + y_axis_label='Memory usage [MB]', + title="Memory usage of the current process") + plot.vbar(x='time', top='mem_usage', width=0.7, source=source, fill_color="#a9ebe0", line_alpha=50) + + hidden_text = PreText(text='', css_classes=['hidden']) + hidden_text.on_change('text', callback) + + def update(): + hidden_text.text = '0' if hidden_text.text == '1' else '1' + + doc.add_root(column(plot)) + doc.theme = Theme(json=yaml.load(""" + attrs: + figure: + background_fill_color: white + outline_line_color: black + toolbar_location: above + height: 500 + width: 800 + Grid: + grid_line_dash: [6, 4] + grid_line_color: gray + """, Loader=yaml.FullLoader)) + + doc.add_periodic_callback(update, 1000) + + +def random_string(length = 12): + letters = string.ascii_letters + string.digits + return ''.join(random.choice(letters) for _ in range(length)) diff --git a/notebooks/hello/ram-utilization-chart.ipynb b/notebooks/hello/ram-utilization-chart.ipynb new file mode 100644 index 00000000..1e7ccfb9 --- /dev/null +++ b/notebooks/hello/ram-utilization-chart.ipynb @@ -0,0 +1,167 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "15feaac6", + "metadata": {}, + "outputs": [], + "source": [ + "import yaml\n", + "\n", + "from bokeh.layouts import column\n", + "from bokeh.models import ColumnDataSource, Slider, PreText\n", + "from bokeh.plotting import figure\n", + "from bokeh.themes import Theme\n", + "from bokeh.io import show, output_notebook\n", + "from datetime import datetime\n", + "import psutil\n", + "import os\n", + "import collections\n", + "import bisect" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c298336a", + "metadata": {}, + "outputs": [], + "source": [ + "output_notebook()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1b2b8bfe", + "metadata": {}, + "outputs": [], + "source": [ + "class MemUsageHistory:\n", + " def __init__(self, size = 60):\n", + " self.size = size\n", + " self.start = datetime.now()\n", + " self.measurements = collections.OrderedDict()\n", + " \n", + " @staticmethod\n", + " def current_memory_usage():\n", + " process = psutil.Process(pid=os.getpid())\n", + " mem_info = process.memory_info()\n", + " return mem_info.rss / 1024 / 1024\n", + " \n", + " def measure(self):\n", + " e = (datetime.now() - self.start).total_seconds()\n", + " self.measurements[e] = MemUsageHistory.current_memory_usage()\n", + " \n", + " def source(self):\n", + " time = []\n", + " mem_usage = []\n", + " e = (datetime.now() - self.start).total_seconds() \n", + " \n", + " def find_measurement(e):\n", + " if e > 0:\n", + " keys = list(self.measurements.keys())\n", + " if len(keys) > 0:\n", + " index = bisect.bisect_left(keys, e)\n", + " if index > 0 and index < len(keys):\n", + " return self.measurements[keys[index]]\n", + " return 0\n", + " \n", + " for i in range(self.size):\n", + " time.append(e - self.size + i)\n", + " mem_usage.append(find_measurement(e - self.size + i))\n", + " \n", + " return {\"time\": time, \"mem_usage\": mem_usage}\n", + " \n", + "\n", + "usage_history = MemUsageHistory()\n", + "source = ColumnDataSource(data = usage_history.source())\n", + "\n", + "def callback(attr, old, new):\n", + " global usage_history\n", + " global source\n", + " \n", + " usage_history.measure()\n", + " source.data = usage_history.source()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cfb09af1", + "metadata": {}, + "outputs": [], + "source": [ + "def bkapp(doc):\n", + " global source\n", + " \n", + " plot = figure(x_axis_type='auto', y_range=(0, MemUsageHistory.current_memory_usage() * 5),\n", + " y_axis_label='Memory usage [MB]',\n", + " title=\"Memory usage of the current process\")\n", + " plot.vbar(x='time', top='mem_usage', width=0.7, source=source, fill_color=\"#a9ebe0\", line_alpha=50)\n", + " \n", + " hidden_text = PreText(text='', css_classes=['hidden'])\n", + " hidden_text.on_change('text', callback)\n", + " \n", + " def update():\n", + " hidden_text.text = '0' if hidden_text.text == '1' else '1'\n", + " \n", + " doc.add_root(column(plot))\n", + " doc.theme = Theme(json=yaml.load(\"\"\"\n", + " attrs:\n", + " figure:\n", + " background_fill_color: white\n", + " outline_line_color: black\n", + " toolbar_location: above\n", + " height: 500\n", + " width: 800\n", + " Grid:\n", + " grid_line_dash: [6, 4]\n", + " grid_line_color: gray\n", + " \"\"\", Loader=yaml.FullLoader))\n", + " \n", + " doc.add_periodic_callback(update, 1000)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19291156", + "metadata": {}, + "outputs": [], + "source": [ + "show(bkapp, notebook_url=\"http://127.0.0.1:8888\", port=8889)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b999c111", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/issues/.ipynb_checkpoints/add_tag_in_init-checkpoint.ipynb b/notebooks/issues/.ipynb_checkpoints/add_tag_in_init-checkpoint.ipynb new file mode 100644 index 00000000..bc9c2ff0 --- /dev/null +++ b/notebooks/issues/.ipynb_checkpoints/add_tag_in_init-checkpoint.ipynb @@ -0,0 +1,129 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "cb8baf12-6df6-483a-80fd-ea234e2bf593", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PATH: /usr/local/lib/python3.9/dist-packages/dbzero_ce\n", + "PATH: /usr/local/lib/python3/dist-packages/dbzero_ce/\n" + ] + } + ], + "source": [ + "import os\n", + "import dbzero_ce as db0\n", + "\n", + "DB0_DIR = os.path.join(os.getcwd(), \"db0-test-data\")\n", + "PREFIX = \"my-test-prefix\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "9b6a4157-1fc6-41de-8592-f1c94a6bef82", + "metadata": {}, + "outputs": [], + "source": [ + "db0.init(DB0_DIR, config = {\"autocommit\": False})\n", + "db0.open(PREFIX)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "506d76dc-7743-40a7-baf7-319406d880ac", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo\n", + "class Test:\n", + " def __init__(self, a, b, c):\n", + " self.a = a\n", + " self.b = b\n", + " self.c = c\n", + " db0.tags(self).add(\"tag1\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "0e9422cb-56b8-4c93-905c-fcde552255c5", + "metadata": {}, + "outputs": [], + "source": [ + "obj1 = Test(1,2,3)\n", + "obj2 = Test(4,5,6)\n", + "db0.commit()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4174874b-441b-4973-afff-3540e152611c", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mThe Kernel crashed while executing code in the current cell or a previous cell. \n", + "\u001b[1;31mPlease review the code in the cell(s) to identify a possible cause of the failure. \n", + "\u001b[1;31mClick here for more info. \n", + "\u001b[1;31mView Jupyter log for further details." + ] + } + ], + "source": [ + "list(db0.find(Test))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "bb556a2a-7654-43cb-9b81-ec1748c8b812", + "metadata": {}, + "outputs": [], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3cf4a40a-0b35-4bcd-9a68-190afa9215ae", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/issues/.ipynb_checkpoints/attribute_error-checkpoint.ipynb b/notebooks/issues/.ipynb_checkpoints/attribute_error-checkpoint.ipynb new file mode 100644 index 00000000..efd87f7f --- /dev/null +++ b/notebooks/issues/.ipynb_checkpoints/attribute_error-checkpoint.ipynb @@ -0,0 +1,319 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "id": "cb8baf12-6df6-483a-80fd-ea234e2bf593", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PATH: /usr/local/lib/python3.9/dist-packages/dbzero_ce\n", + "PATH: /usr/local/lib/python3/dist-packages/dbzero_ce/\n" + ] + } + ], + "source": [ + "from dataclasses import dataclass\n", + "import os\n", + "import dbzero_ce as db0\n", + "\n", + "DB0_DIR = os.path.join(os.getcwd(), \"db0-test-data\")\n", + "PREFIX = \"my-test-prefix2\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "9b6a4157-1fc6-41de-8592-f1c94a6bef82", + "metadata": {}, + "outputs": [], + "source": [ + "db0.init(DB0_DIR, config = {\"autocommit\": False})\n", + "db0.open(PREFIX)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "506d76dc-7743-40a7-baf7-319406d880ac", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo\n", + "@dataclass\n", + "class Test:\n", + " def __init__(self, a, b, c):\n", + " self.a = a\n", + " self.b = b\n", + " self.c = c\n", + " def __iter__(self):\n", + " return (x for x in [self.a, self.b, self.c])\n", + "\n", + " def __gt__(self, other):\n", + " return self.a > other.a\n", + "\n", + " def times2(self):\n", + " return self.a*2 " + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "0e9422cb-56b8-4c93-905c-fcde552255c5", + "metadata": {}, + "outputs": [], + "source": [ + "obj1 = Test(1,2,3)\n", + "obj2 = Test(4,5,6)\n", + "db0.tags(obj1).add(\"tag1\")\n", + "db0.tags(obj2).add(\"tag2\")\n", + "db0.commit()" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "4174874b-441b-4973-afff-3540e152611c", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(db0.find(Test))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b052571-d277-4c4f-b687-2feb0bac2893", + "metadata": {}, + "outputs": [], + "source": [ + "list(db0.filter(lambda x: x.d + x.c == 4, db0.find(\"tag1\")))" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "fec7c10c-5aab-40b9-8844-fbcd2601ee34", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj1.times2()" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b611f203-2cf8-4786-9b9c-f6c1379e355c", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'db0' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mdb0\u001b[49m\u001b[38;5;241m.\u001b[39mclose()\n", + "\u001b[0;31mNameError\u001b[0m: name 'db0' is not defined" + ] + } + ], + "source": [ + "db0.close()" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "id": "cabbcdba-7c02-44fe-9ab0-dc1185e4e03a", + "metadata": {}, + "outputs": [], + "source": [ + "@db0.memo\n", + "class Test2:\n", + " def __init__(self, a, b, c):\n", + " self.a = a\n", + " self.b = b\n", + " self.c = c\n", + " def __iter__(self):\n", + " return (x for x in [self.a, self.b, self.c])\n", + "\n", + " def __gt__(self, other):\n", + " return self.a > other.a\n", + "\n", + " def __lt__(self, other):\n", + " return self.a < other.a\n", + "\n", + " def __mul__(self, other):\n", + " return self.a * other.a\n", + "\n", + " # def __repr__(self):\n", + " # return repr(\"\")\n", + "\n", + " def __eq__(self, other):\n", + " return self.a == other.a\n", + "\n", + " def times2(self):\n", + " return self.a*2 " + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "c83ee150-490f-4c03-9cfd-9ab79240b677", + "metadata": {}, + "outputs": [], + "source": [ + "obj3 = Test2(1,2,3)\n", + "obj4 = Test2(4,5,6)" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "031f9a55-654a-4a42-8994-c5c860d28265", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "isinstance(obj3, Test2)" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "9f7ae708-987f-4da4-b549-53a062709ab3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj3 != obj4" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "1303983e-2272-4fb3-a546-0c1f38db6594", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "''" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "repr(obj3)" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "id": "5fb6444d-f30c-4ef9-b5aa-0f0da3b5cd4c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Test2(1,2,3) == Test2(1,2,3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5f17ff20-ea1b-4553-b2af-42a5f6d6edff", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/issues/.ipynb_checkpoints/import_tests-checkpoint.ipynb b/notebooks/issues/.ipynb_checkpoints/import_tests-checkpoint.ipynb new file mode 100644 index 00000000..363fcab7 --- /dev/null +++ b/notebooks/issues/.ipynb_checkpoints/import_tests-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/issues/.ipynb_checkpoints/test-parse-checkpoint.ipynb b/notebooks/issues/.ipynb_checkpoints/test-parse-checkpoint.ipynb new file mode 100644 index 00000000..363fcab7 --- /dev/null +++ b/notebooks/issues/.ipynb_checkpoints/test-parse-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/issues/db0-test-data/my-test-prefix2.db0 b/notebooks/issues/db0-test-data/my-test-prefix2.db0 new file mode 100644 index 0000000000000000000000000000000000000000..3903dffa6cd6a8461297f9e0edfcaa151662423f GIT binary patch literal 176128 zcmeI*O>7)R7Qpdpdu#$B%oyhj^AX1+d__uZXCVl(*oiR#g@7Y*SuWOiGFVySc){K* zAdrU(NC*ko1IuMsd$Kr2;=}<6M-EsyfP_FuD8Pzi#BxAUlG*pV>W!P4iQ~26;7tB4 zdR|p`RZaKLgD35IU2}ZRH^=qA#K|%!Yay%>ei)F45m|M4+Xr_tL;?Z`AbSFGp;#XV4#h9Df+F78bjFLw8Szx;_1?L8xcL?0~gyaZdho zu99?Uh|6bZlFmlkUwPZ*{a)YA8x# z&9=8x+^tqVKjUt(vfa0?$9ZPPrFX%n$Lx~ZYi%m&#Cz$vv{&3F+rG-VwN^em<8HR{ zuQTo@E4Mqh(aJLJdMoFg+hAph>$J>*00IagfB*srAb&n09b6Df3md4eASoc@~!DmhYQYq{b05Aj_fSUw z0R#|0009ILKmY**5I_Kd-&a7c`&a1^#Bssv|FlPZ+dJxu0tg_000IagfB*srAb)p9;sCW3YK7U{z>}-61orlI=DnCCtS}JcpP@b3^eX2Y)y}#Gx^u~b6 zsL#ZpA0sJ_h87z4g{^*{b8lIzv0`Xt{j7z>q*MwmY)dmlHPJI)>bY2dwb3!+pWM%T z{K&cK;&|V40r2y%F@92Q)PF2Aig#Xxbxm@yIWN>s3BLTJKIRI_q@^_v>Eo)xNUzVL znH|!)>rNjp;X`;{d%jCJGD9JN00IagfB*srAb`MCBp|c($&zzEF2l9URbfQ?tw+{Ftnho)%5cTNOGdLASilhDwBmFx@%YA+Xi~me-^7aW1ze#e~5++En=(}Ye zheHF4nO(m4OlV-SuEFb}fyKH8?}r8!>l#EGB#GlxkZKKG?eOg=x5;-uEOr?PZO!Fi zu#002cj1BM==}209v^FeVXE!17Aq^-tIuAZHuJ)UXpRh>C}VGNs_eqN3ih(Lv#}X5 zZh!djvBOh`Cy#dTeX;v#nPp=~ZJ-@C#>Qxj&OtwlP3Uk#t;_ZadD`8fx&8R$>?AL;wiT(Q9UOF=M!2C-po$|$AirfG4?09CMzTE7kV!t75xLOP^ zrFVAKwoqswp#Q(wZ&x$5=|vheUvQJX&Dgt%y=k0_eg;;zxZt4dM4-t9h9C4N_@@vT zbGko|EkwvT2ZPd)JVah>H=h*Mr52^|33G zxZQ>ZZ_PRzo4rry`-e=%-sm51t+`w}VVe$VZ!@)*tZrzza6f-R=vCuVFL**m)KUExm?C7EL3&ZQeZ-n>?)x3Hd^zQ2)I#QgP zdZbvIo_zkr;qSvGn?130wYa&_5Pic(|2knKd>h{C?I5hDMSBfcornMe2q1s}0tg_0 z00IagfB*tbC~#svtG@})j#EMa0R#|0009ILKmY**5I_I{5$ONUU;oF^&jp}FX^ypn-aTZ+|3ftNx%Cgme)9^U%$3h`n@Mn7tKd1 zN&QiY-^+pjL1L#I$CDCUWV{^`KalYrm-vp1W8+#~HnSjr00IagfB*srAbm;{9a~!O_=0@oG$kXal(cA~!Z*|Ra(BseRUfHj?4w~~| z{WaHNC{x!QioKb-=3H#c)HN4Eb0Vz&KB@O)>Y8JrIT5yBb2xOr9gpUA$R^ug`ABj( zGW8RmOI>q3tiR@ZWa^c8{CGU+%7Op_2q1s}0tg_000IagfB*srAbw=E)qCCdhq43~1Q0*~0R#|0009ILKmY**5V*Vor~TgnoJF11jRgS&5I_I{1Q0*~ z0R#|0009J=LO|yI*9rMu9P2;-Pn&7e&_j#aWiIbq=;!=4|GSp;vwy2=PJreHSY2}g zvh(?mN?mgZY=1G-ZT|V^q^>yywqJ7#GWCj7Sr9+~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|ea)C`vetw)D0tg_000Icq3#6ZtUu6D&ZS&^ATgLyk=kGh@tLJmOW!)&Nj<%F3 z`gOdo4m|zE%R}RD?+@eXSh~E*l>Z)rM+6W+009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1eQzSbaiz)v_" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "importlib.import_module('zorch')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3343fd2b-a6d7-41d0-8b38-bdab286b6d7f", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/issues/test-parse.ipynb b/notebooks/issues/test-parse.ipynb new file mode 100644 index 00000000..1b229abd --- /dev/null +++ b/notebooks/issues/test-parse.ipynb @@ -0,0 +1,113 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 53, + "id": "bd5571f9-2a4b-4f29-9338-0ce6ea7e6a96", + "metadata": {}, + "outputs": [], + "source": [ + "import re\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "0af3890c-b5bd-4856-bc66-1a60c663cfca", + "metadata": {}, + "outputs": [], + "source": [ + "f = open(\"/src/dev/ops.txt\", \"r\")\n", + "w = open(\"/src/dev/data.txt\", \"w\")" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "89149029-de61-484b-9dbf-38b416c9daeb", + "metadata": {}, + "outputs": [], + "source": [ + "lines = f.readlines()" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "b49a479c-d309-45f7-9d0c-cb1e0b3cef38", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'DiffIndex::insert(4, 1055, 5348)\\n'" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lines[-1]" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "9311c65a-b6ea-4f96-a7c5-d6e5c8862681", + "metadata": {}, + "outputs": [], + "source": [ + "i = 0\n", + "for l in lines:\n", + " group = re.match(\".*\\(([0-9]*), ([0-9]*), ([0-9]*)\\).*\", l)\n", + " page, state, storage = tuple([group[1], group[2], group[3]])\n", + " w.write(\"{\" + str(page) + \", \" + str(state) + \", \" + str(storage) + \"},\")\n", + " i += 1\n", + " if i % 10 == 0:\n", + " w.write(\"\\r\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "5115f1d3-35ee-4453-89a3-404de00604fa", + "metadata": {}, + "outputs": [], + "source": [ + "w.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b411556-039c-417b-a48c-73c97e74a5c4", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 310d9e01964bc915898902e7d46802f7168287c7 Mon Sep 17 00:00:00 2001 From: Wojtek Date: Sun, 2 Nov 2025 16:54:39 +0100 Subject: [PATCH 2/3] demo notebook fixes --- .../hello-db0-1_pl-checkpoint.ipynb | 271 +++++++-- notebooks/hello/hello-db0-1_pl.ipynb | 255 ++++++-- notebooks/hello/hello-db0-2_pl.ipynb | 294 ++++++++-- notebooks/hello/hello-db0-3_pl.ipynb | 549 +++++++++++++++++- 4 files changed, 1189 insertions(+), 180 deletions(-) diff --git a/notebooks/hello/.ipynb_checkpoints/hello-db0-1_pl-checkpoint.ipynb b/notebooks/hello/.ipynb_checkpoints/hello-db0-1_pl-checkpoint.ipynb index 800b2844..2cfd6093 100644 --- a/notebooks/hello/.ipynb_checkpoints/hello-db0-1_pl-checkpoint.ipynb +++ b/notebooks/hello/.ipynb_checkpoints/hello-db0-1_pl-checkpoint.ipynb @@ -5,12 +5,25 @@ "id": "4d79e2e4", "metadata": {}, "source": [ - "## Wprowadzenie do dbzero (1/12): Rozpoczynamy" + "
\n", + "

\n", + " 🚀 Wprowadzenie do dbzero\n", + "

\n", + "

\n", + " Część 1/12: Rozpoczynamy naszą przygodę\n", + "

\n", + "
\n", + "\n", + "
\n", + "

\n", + " 💡 Witaj w dbzero! Przygotuj się na poznanie nowej generacji systemu zarządzania danymi.\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "421ce30a", "metadata": {}, "outputs": [], @@ -21,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "311bbaaa", "metadata": {}, "outputs": [], @@ -34,7 +47,11 @@ "id": "f63f0a43", "metadata": {}, "source": [ - "#### Nasza pierwsza klasa" + "
\n", + "

\n", + " 👩‍💻 Nasza pierwsza klasa\n", + "

\n", + "
" ] }, { @@ -42,13 +59,24 @@ "id": "b3e207bb", "metadata": {}, "source": [ - "Klasy oznaczone `@db0.memo` są przechowywane w nieskończonej pamięci dbzero po utworzeniu.\n", - "Wystarczy oznaczyć klasę i zainicjować jej pola wewnątrz metody `__init__`, tak jak w przypadku każdej zwykłej klasy Pythona." + "
\n", + "
\n", + "
📝
\n", + "
\n", + "

\n", + " Klasy oznaczone @db0.memo są przechowywane w nieskończonej pamięci dbzero po utworzeniu.\n", + "

\n", + "

\n", + " Wystarczy oznaczyć klasę i zainicjować jej pola wewnątrz metody __init__, tak jak w przypadku każdej zwykłej klasy Pythona.\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "6c5a28b7", "metadata": {}, "outputs": [], @@ -67,12 +95,17 @@ "id": "e85c296f", "metadata": {}, "source": [ - "Możesz używać tej klasy tak jak każdej zwykłej klasy Pythona—tworzyć nowe obiekty i wywoływać jej metody." + "
\n", + "

\n", + " \n", + " Użytkowanie:  Możesz używać tej klasy tak jak każdej zwykłej klasy Pythona—tworzyć nowe obiekty i wywoływać jej metody.\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "a8cd5802", "metadata": {}, "outputs": [], @@ -85,12 +118,17 @@ "id": "19966147", "metadata": {}, "source": [ - "Dodajemy tag, aby zapobiec usunięciu tego obiektu przez dbzero po zamknięciu procesu. (Omówimy to zachowanie bardziej szczegółowo później.)" + "
\n", + "

\n", + " ⚠️\n", + " Ważne:  Dodajemy tag, aby zapobiec usunięciu tego obiektu przez dbzero po zamknięciu procesu. (Omówimy to zachowanie bardziej szczegółowo później.)\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "8044af92", "metadata": {}, "outputs": [], @@ -100,10 +138,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "10a2d421", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cześć Jan. Witaj w dbzero!!\n" + ] + } + ], "source": [ "jan.greet()" ] @@ -113,7 +159,11 @@ "id": "6cb872ec", "metadata": {}, "source": [ - "#### Więc jaka jest różnica?" + "
\n", + "

\n", + " 🤔 Więc jaka jest różnica?\n", + "

\n", + "
" ] }, { @@ -121,13 +171,45 @@ "id": "7606d58e", "metadata": {}, "source": [ - "Klasy **dbzero** żyją w innej przestrzeni pamięci o specjalnych właściwościach DIST:\n", - "
    \n", - "
  • Trwałe (Durable) - Obiekty utrzymują się po zamknięciu programu
  • \n", - "
  • Nieskończone (Infinite) - Nigdy więcej zmartwień o pojemność pamięci maszyny
  • \n", - "
  • Współdzielone (Shared) - Obiekty mogą być dostępne dla innych aplikacji po udzieleniu uprawnień
  • \n", - "
  • Transakcyjne (Transactional) - Obiekty zawsze utrzymują spójny stan
  • \n", - "
" + "
\n", + "

\n", + " 🏗️ Klasy dbzero żyją w innej przestrzeni pamięci o specjalnych właściwościach DIST:\n", + "

\n", + "
\n", + "
\n", + "

\n", + " 💾 Trwałe (Durable)\n", + "

\n", + "

\n", + " Obiekty utrzymują się po zamknięciu programu\n", + "

\n", + "
\n", + "
\n", + "

\n", + " ♾️ Nieskończone (Infinite)\n", + "

\n", + "

\n", + " Nigdy więcej zmartwień o pojemność pamięci maszyny\n", + "

\n", + "
\n", + "
\n", + "

\n", + " 🤝 Współdzielone (Shared)\n", + "

\n", + "

\n", + " Obiekty mogą być dostępne dla innych aplikacji po udzieleniu uprawnień\n", + "

\n", + "
\n", + "
\n", + "

\n", + " 🔄 Transakcyjne (Transactional)\n", + "

\n", + "

\n", + " Obiekty zawsze utrzymują spójny stan\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { @@ -135,16 +217,33 @@ "id": "b091d04f", "metadata": {}, "source": [ - "#### Jak mogę uzyskać dostęp do obiektu po zamknięciu programu?\n", - "Jednym ze sposobów jest pobranie jego UUID db0, a następnie odwołanie się do niego za pomocą tego ID. Pamiętasz funkcję `id()` Pythona?" + "
\n", + "

\n", + " 🔑 Jak mogę uzyskać dostęp do obiektu po zamknięciu programu?\n", + "

\n", + "

\n", + " Jednym ze sposobów jest pobranie jego UUID db0, a następnie odwołanie się do niego za pomocą jego wartości. Pamiętasz funkcję id() Pythona?\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "bac6f1bb", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "140127282818224" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "id(jan)" ] @@ -154,40 +253,57 @@ "id": "2f19ae02", "metadata": {}, "source": [ - "Każdy obiekt **dbzero** ma zarówno ID Pythona (krótkotrwałe), jak i UUID db0 (trwałe do momentu usunięcia obiektu—podobnie jak usunięcie wiersza w bazie danych)." + "
\n", + "
\n", + "
🆔
\n", + "
\n", + "

\n", + " Każdy obiekt dbzero ma zarówno ID Pythona (krótkotrwałe), jak i UUID db0 (trwałe) do momentu usunięcia obiektu—podobnie jak usunięcie wiersza w bazie danych.\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "9d6a2874", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'WYPBVJBH2FAPFIEBUCAIAAIN'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "db0.uuid(jan)" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "098bba05", - "metadata": {}, - "outputs": [], - "source": [ - "dir(jan)" - ] - }, { "cell_type": "markdown", "id": "29a1cebe", "metadata": {}, "source": [ - "#### Zapamiętajmy to UUID i kontynuujmy w innym notebooku..." + "
\n", + "

\n", + " 📝 Zapamiętajmy to UUID i kontynuujmy w innym notebooku...\n", + "

\n", + "

\n", + " 🎯 Przygotuj się na kolejną część przygody!\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "bf98853a", "metadata": {}, "outputs": [], @@ -197,36 +313,91 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "c5fc541c", "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "RuntimeError", + "evalue": "Object is no longer accessible\n", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[11], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43mdir\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mjan\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[0;31mRuntimeError\u001b[0m: Object is no longer accessible\n" + ] + } + ], "source": [ "dir(jan)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "c71491c6", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "__main__.Memo_HelloWorld" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "type(jan)" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "8c698420", + "cell_type": "markdown", + "id": "f20dec70", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "
\n", + "

\n", + " 🎉 Gratulacje! \n", + "

\n", + "

\n", + " Ukończyłeś pierwszą część kursu dbzero\n", + "

\n", + "
\n", + "
\n", + " 📚 Część 1/12 ukończona\n", + "
\n", + "
\n", + " ⏭️ Następna: Część 2\n", + "
\n", + "
\n", + "

\n", + " 💡 Teraz wiesz jak tworzyć obiekty dbzero i zarządzać nimi!\n", + "

\n", + "
" + ] } ], "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, "language_info": { - "name": "python" + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" } }, "nbformat": 4, diff --git a/notebooks/hello/hello-db0-1_pl.ipynb b/notebooks/hello/hello-db0-1_pl.ipynb index b3b7fe0d..1aac49c2 100644 --- a/notebooks/hello/hello-db0-1_pl.ipynb +++ b/notebooks/hello/hello-db0-1_pl.ipynb @@ -5,12 +5,25 @@ "id": "4d79e2e4", "metadata": {}, "source": [ - "## Wprowadzenie do dbzero (1/12): Rozpoczynamy" + "
\n", + "

\n", + " 🚀 Wprowadzenie do dbzero\n", + "

\n", + "

\n", + " Część 1/12: Rozpoczynamy naszą przygodę\n", + "

\n", + "
\n", + "\n", + "
\n", + "

\n", + " 💡 Witaj w dbzero! Przygotuj się na poznanie nowej generacji systemu zarządzania danymi.\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "421ce30a", "metadata": {}, "outputs": [], @@ -21,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "311bbaaa", "metadata": {}, "outputs": [], @@ -34,7 +47,11 @@ "id": "f63f0a43", "metadata": {}, "source": [ - "#### Nasza pierwsza klasa" + "
\n", + "

\n", + " 👩‍💻 Nasza pierwsza klasa\n", + "

\n", + "
" ] }, { @@ -42,13 +59,24 @@ "id": "b3e207bb", "metadata": {}, "source": [ - "Klasy oznaczone `@db0.memo` są przechowywane w nieskończonej pamięci dbzero po utworzeniu.\n", - "Wystarczy oznaczyć klasę i zainicjować jej pola wewnątrz metody `__init__`, tak jak w przypadku każdej zwykłej klasy Pythona." + "
\n", + "
\n", + "
📝
\n", + "
\n", + "

\n", + " Klasy oznaczone @db0.memo są przechowywane w nieskończonej pamięci dbzero po utworzeniu.\n", + "

\n", + "

\n", + " Wystarczy oznaczyć klasę i zainicjować jej pola wewnątrz metody __init__, tak jak w przypadku każdej zwykłej klasy Pythona.\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "6c5a28b7", "metadata": {}, "outputs": [], @@ -67,12 +95,17 @@ "id": "e85c296f", "metadata": {}, "source": [ - "Możesz używać tej klasy tak jak każdej zwykłej klasy Pythona—tworzyć nowe obiekty i wywoływać jej metody." + "
\n", + "

\n", + " \n", + " Użytkowanie:  Możesz używać tej klasy tak jak każdej zwykłej klasy Pythona—tworzyć nowe obiekty i wywoływać jej metody.\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "a8cd5802", "metadata": {}, "outputs": [], @@ -85,12 +118,17 @@ "id": "19966147", "metadata": {}, "source": [ - "Dodajemy tag, aby zapobiec usunięciu tego obiektu przez dbzero po zamknięciu procesu. (Omówimy to zachowanie bardziej szczegółowo później.)" + "
\n", + "

\n", + " ⚠️\n", + " Ważne:  Dodajemy tag, aby zapobiec usunięciu tego obiektu przez dbzero po zamknięciu procesu. (Omówimy to zachowanie bardziej szczegółowo później.)\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "8044af92", "metadata": {}, "outputs": [], @@ -100,10 +138,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "10a2d421", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cześć Jan. Witaj w dbzero!!\n" + ] + } + ], "source": [ "jan.greet()" ] @@ -113,7 +159,11 @@ "id": "6cb872ec", "metadata": {}, "source": [ - "#### Więc jaka jest różnica?" + "
\n", + "

\n", + " 🤔 Więc jaka jest różnica?\n", + "

\n", + "
" ] }, { @@ -121,13 +171,45 @@ "id": "7606d58e", "metadata": {}, "source": [ - "Klasy **dbzero** żyją w innej przestrzeni pamięci o specjalnych właściwościach DIST:\n", - "
    \n", - "
  • Trwałe (Durable) - Obiekty utrzymują się po zamknięciu programu
  • \n", - "
  • Nieskończone (Infinite) - Nigdy więcej zmartwień o pojemność pamięci maszyny
  • \n", - "
  • Współdzielone (Shared) - Obiekty mogą być dostępne dla innych aplikacji po udzieleniu uprawnień
  • \n", - "
  • Transakcyjne (Transactional) - Obiekty zawsze utrzymują spójny stan
  • \n", - "
" + "
\n", + "

\n", + " 🏗️ Klasy dbzero żyją w innej przestrzeni pamięci o specjalnych właściwościach DIST:\n", + "

\n", + "
\n", + "
\n", + "

\n", + " 💾 Trwałe (Durable)\n", + "

\n", + "

\n", + " Obiekty utrzymują się po zamknięciu programu\n", + "

\n", + "
\n", + "
\n", + "

\n", + " ♾️ Nieskończone (Infinite)\n", + "

\n", + "

\n", + " Nigdy więcej zmartwień o pojemność pamięci maszyny\n", + "

\n", + "
\n", + "
\n", + "

\n", + " 🤝 Współdzielone (Shared)\n", + "

\n", + "

\n", + " Obiekty mogą być dostępne dla innych aplikacji po udzieleniu uprawnień\n", + "

\n", + "
\n", + "
\n", + "

\n", + " 🔄 Transakcyjne (Transactional)\n", + "

\n", + "

\n", + " Obiekty zawsze utrzymują spójny stan\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { @@ -135,16 +217,33 @@ "id": "b091d04f", "metadata": {}, "source": [ - "#### Jak mogę uzyskać dostęp do obiektu po zamknięciu programu?\n", - "Jednym ze sposobów jest pobranie jego UUID db0, a następnie odwołanie się do niego za pomocą tego ID. Pamiętasz funkcję `id()` Pythona?" + "
\n", + "

\n", + " 🔑 Jak mogę uzyskać dostęp do obiektu po zamknięciu programu?\n", + "

\n", + "

\n", + " Jednym ze sposobów jest pobranie jego UUID db0, a następnie odwołanie się do niego za pomocą jego wartości. Pamiętasz funkcję id() Pythona?\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "bac6f1bb", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "139667831597456" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "id(jan)" ] @@ -154,40 +253,57 @@ "id": "2f19ae02", "metadata": {}, "source": [ - "Każdy obiekt **dbzero** ma zarówno ID Pythona (krótkotrwałe), jak i UUID db0 (trwałe do momentu usunięcia obiektu—podobnie jak usunięcie wiersza w bazie danych)." + "
\n", + "
\n", + "
🆔
\n", + "
\n", + "

\n", + " Każdy obiekt dbzero ma zarówno ID Pythona (krótkotrwałe), jak i UUID db0 (trwałe) do momentu usunięcia obiektu—podobnie jak usunięcie wiersza w bazie danych.\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "9d6a2874", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'UC4N7ZET2LZY3IEBUCAIAAIN'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "db0.uuid(jan)" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "098bba05", - "metadata": {}, - "outputs": [], - "source": [ - "dir(jan)" - ] - }, { "cell_type": "markdown", "id": "29a1cebe", "metadata": {}, "source": [ - "#### Zapamiętajmy to UUID i kontynuujmy w innym notebooku..." + "
\n", + "

\n", + " 📝 Zapamiętajmy to UUID i kontynuujmy w innym notebooku...\n", + "

\n", + "

\n", + " 🎯 Przygotuj się na kolejną część przygody!\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "bf98853a", "metadata": {}, "outputs": [], @@ -197,28 +313,77 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "c5fc541c", "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "RuntimeError", + "evalue": "Object is no longer accessible\n", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[10], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43mdir\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mjan\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[0;31mRuntimeError\u001b[0m: Object is no longer accessible\n" + ] + } + ], "source": [ "dir(jan)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "c71491c6", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "__main__.Memo_HelloWorld" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "type(jan)" ] }, + { + "cell_type": "markdown", + "id": "f20dec70", + "metadata": {}, + "source": [ + "
\n", + "

\n", + " 🎉 Gratulacje! \n", + "

\n", + "

\n", + " Ukończyłeś pierwszą część kursu dbzero\n", + "

\n", + "
\n", + "
\n", + " 📚 Część 1/12 ukończona\n", + "
\n", + "
\n", + " ⏭️ Następna: Część 2\n", + "
\n", + "
\n", + "

\n", + " 💡 Teraz wiesz jak tworzyć obiekty dbzero i zarządzać nimi!\n", + "

\n", + "
" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "8c698420", + "id": "acb46669-563e-410a-a5b5-e5d9b7780d82", "metadata": {}, "outputs": [], "source": [] diff --git a/notebooks/hello/hello-db0-2_pl.ipynb b/notebooks/hello/hello-db0-2_pl.ipynb index 140e9527..72efb141 100644 --- a/notebooks/hello/hello-db0-2_pl.ipynb +++ b/notebooks/hello/hello-db0-2_pl.ipynb @@ -5,7 +5,20 @@ "id": "cb08fd72", "metadata": {}, "source": [ - "## Wprowadzenie do **dbzero** (2/12). Listy, relacje i singletony." + "
\n", + "

\n", + " 📋 Listy, relacje i singletony\n", + "

\n", + "

\n", + " Część 2/12: Zarządzanie kolekcjami obiektów w dbzero\n", + "

\n", + "
\n", + "\n", + "
\n", + "

\n", + " 🔗 W tej części:  Nauczymy się jak dbzero obsługuje kolekcje, relacje między obiektami oraz wzorzec singleton dla unikatowych instancji.\n", + "

\n", + "
" ] }, { @@ -24,7 +37,16 @@ "id": "0fa1ac68", "metadata": {}, "source": [ - "Musimy ponownie zdefiniować naszą klasę. W typowym programie Python po prostu zaimportowalibyśmy ją z modułu." + "
\n", + "
\n", + "
🔄
\n", + "
\n", + "

\n", + " Musimy ponownie zdefiniować naszą klasę. W typowym programie Python po prostu zaimportowalibyśmy ją z modułu.\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { @@ -48,7 +70,12 @@ "id": "ea7ae0b9", "metadata": {}, "source": [ - "I otwórzmy jej instancję za pomocą wcześniej wygenerowanego UUID (< wklej swoje UUID poniżej >)" + "
\n", + "

\n", + " 🆔\n", + " Otwórzmy instancję:  Użyjemy wcześniej wygenerowanego UUID (< wklej swoje UUID poniżej >)\n", + "

\n", + "
" ] }, { @@ -56,21 +83,9 @@ "execution_count": 3, "id": "10a881cd", "metadata": {}, - "outputs": [ - { - "ename": "RuntimeError", - "evalue": "Prefix: 2098673055265944345 not found\n", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[3], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m h \u001b[38;5;241m=\u001b[39m \u001b[43mdb0\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfetch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mHelloWorld\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mDFZ46RQG7QPR3IEBUCAIAAIN\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n", - "\u001b[0;31mRuntimeError\u001b[0m: Prefix: 2098673055265944345 not found\n" - ] - } - ], + "outputs": [], "source": [ - "h = db0.fetch(HelloWorld, \"DFZ46RQG7QPR3IEBUCAIAAIN\")" + "h = db0.fetch(HelloWorld, \"UC4N7ZET2LZY3IEBUCAIAAIN\")" ] }, { @@ -80,14 +95,10 @@ "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'h' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[4], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mh\u001b[49m\u001b[38;5;241m.\u001b[39mgreet()\n", - "\u001b[0;31mNameError\u001b[0m: name 'h' is not defined" + "name": "stdout", + "output_type": "stream", + "text": [ + "Witaj Jan. Witamy w dbzero!!\n" ] } ], @@ -100,8 +111,22 @@ "id": "f289de1c", "metadata": {}, "source": [ - "### W porządku, to zadziałało. Instancja pamięta swoje elementy danych.\n", - "Ale pobieranie po ID nie wydaje się zbyt wygodne, jak mogę uzyskać dostęp do moich obiektów w bardziej praktyczny sposób?" + "
\n", + "

\n", + " ✅ Sukces! Instancja pamięta swoje dane\n", + "

\n", + "
\n", + "\n", + "
\n", + "
\n", + "
🤔
\n", + "
\n", + "

\n", + " Ale pobieranie po UUID nie wydaje się zbyt wygodne. Jak mogę uzyskać dostęp do moich obiektów w bardziej praktyczny sposób?\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { @@ -109,7 +134,25 @@ "id": "5d23f657", "metadata": {}, "source": [ - "Jedną z możliwości jest przechowywanie odniesień do obiektów w innym (nadrzędnym) obiekcie. W świecie baz danych takie powiązanie nazywane byłoby 'relacją'. Jeśli naszym zamiarem jest przechowywanie tylko jednej instancji HelloMany, możemy oznaczyć ją jako" + "
\n", + "

\n", + " 🔗 Wzorzec Singleton\n", + "

\n", + "
\n", + "\n", + "
\n", + "
\n", + "
📦
\n", + "
\n", + "

\n", + " Jedną z możliwości jest przechowywanie odniesień do obiektów w innym (nadrzędnym) obiekcie. W świecie baz danych takie powiązanie nazywane byłoby 'relacją'.\n", + "

\n", + "

\n", + " Jeśli naszym zamiarem jest przechowywanie tylko jednej instancji HelloMany, możemy oznaczyć ją jako singleton.\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { @@ -135,7 +178,12 @@ "id": "d0177bea", "metadata": {}, "source": [ - "Zwróć uwagę, że obiekt **dbzero** klasy oznaczonej jako ``singleton`` zostanie utworzony tylko raz." + "
\n", + "

\n", + " \n", + " Ważne:  Obiekt dbzero  klasy oznaczonej jako  singleton  zostanie utworzony tylko raz.\n", + "

\n", + "
" ] }, { @@ -175,7 +223,12 @@ "id": "7716f750", "metadata": {}, "source": [ - "Po utworzeniu instancji obiekt można ponownie uzyskać dostęp (z innego programu lub po zamknięciu tego programu) bez żadnych argumentów." + "
\n", + "

\n", + " 🔄\n", + " Ponowny dostęp:  Po utworzeniu instancji obiektu można ponownie uzyskać do niego dostęp (z innego programu lub po zamknięciu tego programu) bez żadnych argumentów lub przy użyciu funkcji db0.fetch.\n", + "

\n", + "
" ] }, { @@ -201,17 +254,42 @@ "mh.greet()" ] }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8ee70fad-129c-490f-9902-158644a00342", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.Memo_HelloMany at 0x7fe24a6b47d0>" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "db0.fetch(HelloMany)" + ] + }, { "cell_type": "markdown", "id": "4e708260", "metadata": {}, "source": [ - "Widzimy, że many_hellos i mh to ten sam obiekt ``dbzero`` i nawet ten sam obiekt Python." + "
\n", + "

\n", + " 🔍 Obserwacja: Widzimy, że many_hellos i mh to ten sam obiekt dbzero i nawet ten sam obiekt Python.\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "9207be23", "metadata": {}, "outputs": [ @@ -219,7 +297,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "140401140747472 140401140747472\n" + "140609887882448 140609887882448\n" ] } ], @@ -229,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "af8c5898", "metadata": {}, "outputs": [ @@ -237,7 +315,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "UCEZKEPIYX26NIEBUHJIABYN UCEZKEPIYX26NIEBUHJIABYN\n" + "UC4N7ZET2LZY3IEBUHJIABYN UC4N7ZET2LZY3IEBUHJIABYN\n" ] } ], @@ -250,16 +328,36 @@ "id": "42c2805c", "metadata": {}, "source": [ - "### Co więc jest faktycznie przechowywane na liście HelloMany.hellos?\n", - "Podobnie jak w przypadku zwykłych obiektów Python - lista przechowuje odniesienia, a nie pełne instancje. Listy **dbzero** mogą przechowywać proste typy (liczby/ciągi znaków), inne kolekcje (listy, słowniki, zbiory, krotki itp.) lub odniesienia do innych instancji dbzero ``@memo``." + "
\n", + "
\n", + "
💾
\n", + "
\n", + "

\n", + " Podobnie jak w przypadku zwykłych obiektów Python - lista przechowuje odniesienia, a nie pełne instancje. Listy dbzero mogą przechowywać proste typy (liczby/ciągi znaków), inne kolekcje (listy, słowniki, zbiory, krotki) lub odniesienia do innych instancji @memo.\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "0fc48e00", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "UC4N7ZET2LZY3IEBUCRYAAQN\n", + "UC4N7ZET2LZY3IEBUDDIAAYN\n", + "UC4N7ZET2LZY3IEBUDUYABAN\n", + "UC4N7ZET2LZY3IEBUGGIABIN\n", + "UC4N7ZET2LZY3IEBUGXYABQN\n" + ] + } + ], "source": [ "for obj in mh.hellos:\n", " print(db0.uuid(obj))" @@ -270,15 +368,28 @@ "id": "c31c34b9", "metadata": {}, "source": [ - "A lista **dbzero** działa dokładnie jak każda zwykła lista Python - możesz iterować, wycinać lub uzyskiwać dostęp do jej elementów przez indeks." + "
\n", + "

\n", + " 🐍\n", + " Kompatybilność:  Lista  dbzero działa dokładnie jak każda zwykła lista Python - możesz iterować, wycinać lub uzyskiwać dostęp do jej elementów przez indeks.\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "6e2a7023", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Witaj Filip. Witamy w dbzero!!\n" + ] + } + ], "source": [ "mh.hellos[3].greet()" ] @@ -288,23 +399,61 @@ "id": "9e33d730", "metadata": {}, "source": [ - "### Jak duża może być pojedyncza lista?\n", - "W Python normalnie twoja lista byłaby ograniczona przez rozmiar pamięci RAM dostępnej dla twojego procesu (w praktyce, podczas uruchamiania programu - kto wie, jaki jest dokładnie ten limit???). Dla użytkowników DB0 (chmurowych) mamy dobrą wiadomość. Nie ma limitów! Jeśli chcesz, możesz utworzyć listę o rozmiarze znacznie przekraczającym dostępną pamięć. W przypadku wersji lokalnej ten rozmiar jest ograniczony przez dostępną przestrzeń dyskową." + "
\n", + "

\n", + " ♾️ Jak duża może być pojedyncza lista?\n", + "

\n", + "

\n", + " W Python normalnie twoja lista byłaby ograniczona przez rozmiar pamięci RAM dostępnej dla twojego procesu.\n", + "

\n", + "
\n", + "\n", + "
\n", + "

\n", + " 🎉 Dla użytkowników dbzero mamy dobrą wiadomość:\n", + "

\n", + "
\n", + "
\n", + "

\n", + " ☁️ Wersja chmurowa\n", + "

\n", + "

\n", + " Brak limitów! Lista może przekraczać dostępną pamięć\n", + "

\n", + "
\n", + "
\n", + "

\n", + " 💻 Wersja lokalna\n", + "

\n", + "

\n", + " Ograniczona przez dostępną przestrzeń dyskową\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "7951b626", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n" + ] + } + ], "source": [ "print(len(mh.hellos))" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "436b4832", "metadata": {}, "outputs": [], @@ -315,10 +464,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "id": "c42df9e9", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1005\n" + ] + } + ], "source": [ "print(len(mh.hellos))" ] @@ -328,12 +485,19 @@ "id": "045dfdad", "metadata": {}, "source": [ - "Zbadajmy wykorzystanie pamięci i limity w następnym notebooku." + "
\n", + "

\n", + " 🔬 Badajmy dalej wykorzystanie pamięci i limity...\n", + "

\n", + "

\n", + " ⏭️ Zobacz następny notebook, aby poznać więcej szczegółów!\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "822fc22a", "metadata": {}, "outputs": [], @@ -342,12 +506,30 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "id": "69fd898a", + "cell_type": "markdown", + "id": "c97ed8de", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "
\n", + "

\n", + " 🎉 Świetnie! \n", + "

\n", + "

\n", + " Ukończyłeś drugą część kursu dbzero\n", + "

\n", + "
\n", + "
\n", + " 📚 Część 2/12 ukończona\n", + "
\n", + "
\n", + " ⏭️ Następna: Część 3\n", + "
\n", + "
\n", + "

\n", + " 💡 Teraz wiesz jak używać list, relacji i singletonów w dbzero!\n", + "

\n", + "
" + ] } ], "metadata": { diff --git a/notebooks/hello/hello-db0-3_pl.ipynb b/notebooks/hello/hello-db0-3_pl.ipynb index 38cf6d7d..7d0926b7 100644 --- a/notebooks/hello/hello-db0-3_pl.ipynb +++ b/notebooks/hello/hello-db0-3_pl.ipynb @@ -5,12 +5,25 @@ "id": "15f77f54", "metadata": {}, "source": [ - "## Wprowadzenie do **dbzero** (3/12): Badanie ograniczeń" + "
\n", + "

\n", + " 🔍 Badanie ograniczeń dbzero\n", + "

\n", + "

\n", + " Część 3/12: Sprawdzamy granice możliwości pamięci\n", + "

\n", + "
\n", + "\n", + "
\n", + "

\n", + " 💡 W tej części: Poznamy jak dbzero radzi sobie z ograniczeniami pamięci i dlaczego nigdy więcej nie będziesz się martwić o błędy \"out of memory\".\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "20a5860e", "metadata": {}, "outputs": [], @@ -26,7 +39,12 @@ "id": "529eb523", "metadata": {}, "source": [ - "Zaimportowaliśmy pakiet 'bokeh' do wizualizacji obecnego wykorzystania pamięci na wykresie." + "
\n", + "

\n", + " 📊\n", + " Wizualizacja:  Zaimportowaliśmy pakiet 'bokeh' do wizualizacji obecnego wykorzystania pamięci na wykresie.\n", + "

\n", + "
" ] }, { @@ -34,12 +52,17 @@ "id": "5604673c", "metadata": {}, "source": [ - "Stwórzmy również executor, aby móc uruchamiać zadania Pythona w tle (w oddzielnym wątku)." + "
\n", + "

\n", + " 🔧\n", + " Setup:  Stwórzmy również executor, aby móc uruchamiać zadania Pythona w tle (w oddzielnym wątku).\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "dd90646c", "metadata": {}, "outputs": [], @@ -52,15 +75,370 @@ "id": "ccbd6239", "metadata": {}, "source": [ - "Wykres poniżej przedstawia żywe wykorzystanie pamięci przez obecny proces, odświeżane co 1 sekundę." + "
\n", + "

\n", + " 📈 Monitor pamięci w czasie rzeczywistym\n", + "

\n", + "

\n", + " Wykres poniżej przedstawia żywe wykorzystanie pamięci przez obecny proces, odświeżane co 1 sekundę.\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "0bf58a08", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/javascript": [ + "'use strict';\n", + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + "const JS_MIME_TYPE = 'application/javascript';\n", + " const HTML_MIME_TYPE = 'text/html';\n", + " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " const CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " const script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " function drop(id) {\n", + " const view = Bokeh.index.get_by_id(id)\n", + " if (view != null) {\n", + " view.model.document.clear()\n", + " Bokeh.index.delete(view)\n", + " }\n", + " }\n", + "\n", + " const cell = handle.cell;\n", + "\n", + " const id = cell.output_area._bokeh_element_id;\n", + " const server_id = cell.output_area._bokeh_server_id;\n", + "\n", + " // Clean up Bokeh references\n", + " if (id != null) {\n", + " drop(id)\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd_clean, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " const id = msg.content.text.trim()\n", + " drop(id)\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd_destroy);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " const output_area = handle.output_area;\n", + " const output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " const bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " const script_attrs = bk_div.children[0].attributes;\n", + " for (let i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " const toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " const events = require('base/js/events');\n", + " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " const NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"
    \\n\"+\n", + " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", + " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", + " \"
\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded(error = null) {\n", + " const el = document.getElementById(null);\n", + " if (el != null) {\n", + " const html = (() => {\n", + " if (typeof root.Bokeh === \"undefined\") {\n", + " if (error == null) {\n", + " return \"BokehJS is loading ...\";\n", + " } else {\n", + " return \"BokehJS failed to load.\";\n", + " }\n", + " } else {\n", + " const prefix = `BokehJS ${root.Bokeh.version}`;\n", + " if (error == null) {\n", + " return `${prefix} successfully loaded.`;\n", + " } else {\n", + " return `${prefix} encountered errors while loading and may not function as expected.`;\n", + " }\n", + " }\n", + " })();\n", + " el.innerHTML = html;\n", + "\n", + " if (error != null) {\n", + " const wrapper = document.createElement(\"div\");\n", + " wrapper.style.overflow = \"auto\";\n", + " wrapper.style.height = \"5em\";\n", + " wrapper.style.resize = \"vertical\";\n", + " const content = document.createElement(\"div\");\n", + " content.style.fontFamily = \"monospace\";\n", + " content.style.whiteSpace = \"pre-wrap\";\n", + " content.style.backgroundColor = \"rgb(255, 221, 221)\";\n", + " content.textContent = error.stack ?? error.toString();\n", + " wrapper.append(content);\n", + " el.append(wrapper);\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(() => display_loaded(error), 100);\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.6.3.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " try {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "\n", + " } catch (error) {throw error;\n", + " }} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "'use strict';\n(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded(error = null) {\n const el = document.getElementById(null);\n if (el != null) {\n const html = (() => {\n if (typeof root.Bokeh === \"undefined\") {\n if (error == null) {\n return \"BokehJS is loading ...\";\n } else {\n return \"BokehJS failed to load.\";\n }\n } else {\n const prefix = `BokehJS ${root.Bokeh.version}`;\n if (error == null) {\n return `${prefix} successfully loaded.`;\n } else {\n return `${prefix} encountered errors while loading and may not function as expected.`;\n }\n }\n })();\n el.innerHTML = html;\n\n if (error != null) {\n const wrapper = document.createElement(\"div\");\n wrapper.style.overflow = \"auto\";\n wrapper.style.height = \"5em\";\n wrapper.style.resize = \"vertical\";\n const content = document.createElement(\"div\");\n content.style.fontFamily = \"monospace\";\n content.style.whiteSpace = \"pre-wrap\";\n content.style.backgroundColor = \"rgb(255, 221, 221)\";\n content.textContent = error.stack ?? error.toString();\n wrapper.append(content);\n el.append(wrapper);\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(() => display_loaded(error), 100);\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.6.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n try {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n\n } catch (error) {throw error;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.bokehjs_exec.v0+json": "", + "text/html": [ + "" + ] + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "server_id": "e251939db72a4906ae39470a8a76e359" + } + }, + "output_type": "display_data" + } + ], "source": [ "output_notebook(resources=None, verbose=False, hide_banner=True)\n", "show(mem_usage_chart, notebook_url=\"http://127.0.0.1:8888\", port=8889)" @@ -71,12 +449,25 @@ "id": "1fc1acad", "metadata": {}, "source": [ - "Zobaczmy najpierw, jak rośnie wykorzystanie pamięci podczas uruchamiania zwykłego kodu Pythona. Dodajemy 50 000 losowych elementów tekstowych do zwykłej listy Pythona w 100 iteracjach. To łącznie 5 milionów dodanych elementów danych. Zobaczmy, jak to działa..." + "
\n", + "
\n", + "
⚠️
\n", + "
\n", + "

Test standardowego Pythona - Uwaga na pamięć!

\n", + "

\n", + " Zobaczmy najpierw, jak rośnie wykorzystanie pamięci podczas uruchamiania zwykłego kodu Pythona. Dodajemy 50 000 losowych elementów tekstowych do zwykłej listy Pythona w 100 iteracjach.\n", + "

\n", + "

\n", + " To łącznie 5 milionów dodanych elementów danych. Zobaczmy, jak to działa...\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "e1d5ab5e", "metadata": {}, "outputs": [], @@ -90,10 +481,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "477cf909", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Task finished\n", + "Task finished\n" + ] + } + ], "source": [ "task = executor.submit(generate_sequence, result, length=100, batch = 50000)" ] @@ -103,12 +503,22 @@ "id": "3a16cc37", "metadata": {}, "source": [ - "Pamięć po prostu nadal rośnie i rośnie i ostatecznie zakończyłaby proces błędem \"brak pamięci\". W Pythonie możemy zwolnić pamięć poprzez zwykłe opróżnienie listy." + "
\n", + "
\n", + "
💥
\n", + "
\n", + "

Typowy problem Pythona

\n", + "

\n", + " Pamięć po prostu nadal rośnie i rośnie i ostatecznie zakończyłaby proces błędem \"brak pamięci\". W Pythonie możemy zwolnić pamięć poprzez zwykłe opróżnienie listy.\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "e0a08dd8", "metadata": {}, "outputs": [], @@ -121,8 +531,14 @@ "id": "62c8113d", "metadata": {}, "source": [ - "### Dobrze, więc jak **dbzero** różni się w tej kwestii?\n", - "W **dbzero** pracujesz przez większość czasu jak ze zwykłym kodem Pythona, ale nie musisz już martwić się o ograniczenia pamięci. To prawda, nawet jeśli masz do czynienia z terabajtami danych, Twój proces nigdy nie przekroczy limitów, które sam zdefiniujesz." + "
\n", + "

\n", + " 🚀 Dobrze, więc jak dbzero różni się w tej kwestii?\n", + "

\n", + "

\n", + " W dbzero pracujesz przez większość czasu jak ze zwykłym kodem Pythona, ale nie musisz już martwić się o ograniczenia pamięci. To prawda, nawet jeśli masz do czynienia z terabajtami danych, Twój proces nigdy nie przekroczy limitów, które sam zdefiniujesz.\n", + "

\n", + "
" ] }, { @@ -130,12 +546,17 @@ "id": "07cb8306", "metadata": {}, "source": [ - "Po inicjalizacji **dbzero** zajmie niewielką ilość Twojej pamięci..." + "
\n", + "

\n", + " 🔧\n", + " Inicjalizacja:  Po inicjalizacji dbzero zajmie niewielką ilość Twojej pamięci...\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "27b340b7", "metadata": {}, "outputs": [], @@ -148,12 +569,17 @@ "id": "8de40443", "metadata": {}, "source": [ - "Ale możesz kontrolować, ile dodatkowej pamięci używa, wywołując metodę 'set_cache_size'." + "
\n", + "

\n", + " ⚙️\n", + " Kontrola pamięci:  Ale możesz kontrolować, ile dodatkowej pamięci używa, wywołując metodę set_cache_size.\n", + "

\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "45b3955f", "metadata": {}, "outputs": [], @@ -166,12 +592,22 @@ "id": "30ed17df", "metadata": {}, "source": [ - "Powtórzmy teraz test używając db0.list (obiekt listy w przestrzeni dbzero). Obserwuj uważnie, jak wykorzystanie pamięci zatrzymuje się w pewnym momencie (gdy zostanie osiągnięty zdefiniowany limit cache) i nie rośnie bez względu na to, ile danych umieścisz w swojej liście." + "
\n", + "
\n", + "
🎯
\n", + "
\n", + "

Test dbzero - Obserwuj magię!

\n", + "

\n", + " Powtórzmy teraz test używając db0.list (obiekt listy w przestrzeni dbzero). Obserwuj uważnie, jak wykorzystanie pamięci zatrzymuje się w pewnym momencie (gdy zostanie osiągnięty zdefiniowany limit cache) i nie rośnie bez względu na to, ile danych umieścisz w swojej liście.\n", + "

\n", + "
\n", + "
\n", + "
" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "9fc1c062", "metadata": {}, "outputs": [], @@ -181,7 +617,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "cb5949bb", "metadata": {}, "outputs": [], @@ -194,7 +630,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "39ec4824", "metadata": {}, "outputs": [], @@ -204,10 +640,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "29a62967", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5000000\n" + ] + }, + { + "data": { + "text/plain": [ + "'oeqVRJbN24Un'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "print(len(db0_result))\n", "db0_result[12313]" @@ -218,8 +672,19 @@ "id": "b6e8e86c", "metadata": {}, "source": [ - "### No więc gdzie w rzeczywistości są przechowywane dane w tym przypadku?\n", - "dbzero implementuje algorytmy wymiany pamięci. Pobiera dane z chmury lub, w przypadku wersji lokalnej, z systemu plików na zasadzie \"według potrzeby\" i przechowuje je w lokalnym cache, aby umożliwić szybki dostęp w przyszłości. Proces jest całkowicie przezroczysty dla programisty." + "
\n", + "

\n", + " 🤔 No więc gdzie w rzeczywistości są przechowywane dane w tym przypadku?\n", + "

\n", + "
\n", + "

\n", + " dbzero implementuje algorytmy wymiany pamięci. Pobiera dane z chmury lub, w przypadku wersji lokalnej, z systemu plików na zasadzie \"według potrzeby\" i przechowuje je w lokalnym cache, aby umożliwić szybki dostęp w przyszłości.\n", + "

\n", + "

\n", + " 💡 Proces jest całkowicie przezroczysty dla programisty.\n", + "

\n", + "
\n", + "
" ] }, { @@ -232,10 +697,36 @@ "db0.close()" ] }, + { + "cell_type": "markdown", + "id": "757ed1d8-6df0-41b4-9135-03dfee14e75f", + "metadata": {}, + "source": [ + "
\n", + "

\n", + " Świetna robota! \n", + "

\n", + "

\n", + " Ukończyłeś trzecią część kursu dbzero\n", + "

\n", + "
\n", + "
\n", + " Część 3/12 ukończona\n", + "
\n", + "
\n", + " Następna: Część 4\n", + "
\n", + "
\n", + "

\n", + " 💡 Teraz wiesz jak dbzero radzi sobie z ograniczeniami pamięci!\n", + "

\n", + "
" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "dee24cf4", + "id": "5c7435e6-924e-4528-b659-45f7cd5a9c53", "metadata": {}, "outputs": [], "source": [] From 8f9dcbade4c21f8f13a912e3191280f61d5daeb8 Mon Sep 17 00:00:00 2001 From: Wojtek Date: Mon, 3 Nov 2025 11:16:32 +0100 Subject: [PATCH 3/3] mem charts --- notebooks/hello/hello-db0-1_pl.ipynb | 18 +- notebooks/hello/hello-db0-2_pl.ipynb | 40 +-- notebooks/hello/hello-db0-3_pl.ipynb | 407 ++------------------------- 3 files changed, 45 insertions(+), 420 deletions(-) diff --git a/notebooks/hello/hello-db0-1_pl.ipynb b/notebooks/hello/hello-db0-1_pl.ipynb index 1aac49c2..d63c7519 100644 --- a/notebooks/hello/hello-db0-1_pl.ipynb +++ b/notebooks/hello/hello-db0-1_pl.ipynb @@ -236,7 +236,7 @@ { "data": { "text/plain": [ - "139667831597456" + "140367238964688" ] }, "execution_count": 7, @@ -267,17 +267,17 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "9d6a2874", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'UC4N7ZET2LZY3IEBUCAIAAIN'" + "'HOHKGLN4SOLAXIEBUCAIAAIN'" ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -303,7 +303,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "bf98853a", "metadata": {}, "outputs": [], @@ -313,7 +313,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "c5fc541c", "metadata": {}, "outputs": [ @@ -324,7 +324,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[10], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43mdir\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mjan\u001b[49m\u001b[43m)\u001b[49m\n", + "Cell \u001b[0;32mIn[11], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43mdir\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mjan\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[0;31mRuntimeError\u001b[0m: Object is no longer accessible\n" ] } @@ -335,7 +335,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "c71491c6", "metadata": {}, "outputs": [ @@ -345,7 +345,7 @@ "__main__.Memo_HelloWorld" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/hello/hello-db0-2_pl.ipynb b/notebooks/hello/hello-db0-2_pl.ipynb index 72efb141..10766fa7 100644 --- a/notebooks/hello/hello-db0-2_pl.ipynb +++ b/notebooks/hello/hello-db0-2_pl.ipynb @@ -85,12 +85,12 @@ "metadata": {}, "outputs": [], "source": [ - "h = db0.fetch(HelloWorld, \"UC4N7ZET2LZY3IEBUCAIAAIN\")" + "h = db0.fetch(HelloWorld, \"HOHKGLN4SOLAXIEBUCAIAAIN\")" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "9b89ad62", "metadata": {}, "outputs": [ @@ -157,7 +157,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "b0de389d", "metadata": {}, "outputs": [], @@ -188,7 +188,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "95243fbe", "metadata": {}, "outputs": [], @@ -198,7 +198,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "2ee94827", "metadata": {}, "outputs": [ @@ -233,7 +233,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "3e9c03d3", "metadata": {}, "outputs": [ @@ -256,17 +256,17 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "8ee70fad-129c-490f-9902-158644a00342", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "<__main__.Memo_HelloMany at 0x7fe24a6b47d0>" + "<__main__.Memo_HelloMany at 0x7f64541eceb0>" ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -289,7 +289,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "9207be23", "metadata": {}, "outputs": [ @@ -297,7 +297,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "140609887882448 140609887882448\n" + "140068884761648 140068884761648\n" ] } ], @@ -307,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "af8c5898", "metadata": {}, "outputs": [ @@ -315,7 +315,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "UC4N7ZET2LZY3IEBUHJIABYN UC4N7ZET2LZY3IEBUHJIABYN\n" + "HOHKGLN4SOLAXIEBUHJIABYN HOHKGLN4SOLAXIEBUHJIABYN\n" ] } ], @@ -342,7 +342,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "0fc48e00", "metadata": {}, "outputs": [ @@ -350,11 +350,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "UC4N7ZET2LZY3IEBUCRYAAQN\n", - "UC4N7ZET2LZY3IEBUDDIAAYN\n", - "UC4N7ZET2LZY3IEBUDUYABAN\n", - "UC4N7ZET2LZY3IEBUGGIABIN\n", - "UC4N7ZET2LZY3IEBUGXYABQN\n" + "HOHKGLN4SOLAXIEBUCRYAAQN\n", + "HOHKGLN4SOLAXIEBUDDIAAYN\n", + "HOHKGLN4SOLAXIEBUDUYABAN\n", + "HOHKGLN4SOLAXIEBUGGIABIN\n", + "HOHKGLN4SOLAXIEBUGXYABQN\n" ] } ], @@ -378,7 +378,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "6e2a7023", "metadata": {}, "outputs": [ diff --git a/notebooks/hello/hello-db0-3_pl.ipynb b/notebooks/hello/hello-db0-3_pl.ipynb index 7d0926b7..bca57bd4 100644 --- a/notebooks/hello/hello-db0-3_pl.ipynb +++ b/notebooks/hello/hello-db0-3_pl.ipynb @@ -23,7 +23,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "20a5860e", "metadata": {}, "outputs": [], @@ -62,7 +62,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "dd90646c", "metadata": {}, "outputs": [], @@ -87,358 +87,10 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "0bf58a08", "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "'use strict';\n", - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " const force = true;\n", - "\n", - " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - "const JS_MIME_TYPE = 'application/javascript';\n", - " const HTML_MIME_TYPE = 'text/html';\n", - " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " const CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " const script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " function drop(id) {\n", - " const view = Bokeh.index.get_by_id(id)\n", - " if (view != null) {\n", - " view.model.document.clear()\n", - " Bokeh.index.delete(view)\n", - " }\n", - " }\n", - "\n", - " const cell = handle.cell;\n", - "\n", - " const id = cell.output_area._bokeh_element_id;\n", - " const server_id = cell.output_area._bokeh_server_id;\n", - "\n", - " // Clean up Bokeh references\n", - " if (id != null) {\n", - " drop(id)\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd_clean, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " const id = msg.content.text.trim()\n", - " drop(id)\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd_destroy);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " const output_area = handle.output_area;\n", - " const output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " const bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " const script_attrs = bk_div.children[0].attributes;\n", - " for (let i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " const toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " const events = require('base/js/events');\n", - " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " const NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

\\n\"+\n", - " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", - " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", - " \"

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded(error = null) {\n", - " const el = document.getElementById(null);\n", - " if (el != null) {\n", - " const html = (() => {\n", - " if (typeof root.Bokeh === \"undefined\") {\n", - " if (error == null) {\n", - " return \"BokehJS is loading ...\";\n", - " } else {\n", - " return \"BokehJS failed to load.\";\n", - " }\n", - " } else {\n", - " const prefix = `BokehJS ${root.Bokeh.version}`;\n", - " if (error == null) {\n", - " return `${prefix} successfully loaded.`;\n", - " } else {\n", - " return `${prefix} encountered errors while loading and may not function as expected.`;\n", - " }\n", - " }\n", - " })();\n", - " el.innerHTML = html;\n", - "\n", - " if (error != null) {\n", - " const wrapper = document.createElement(\"div\");\n", - " wrapper.style.overflow = \"auto\";\n", - " wrapper.style.height = \"5em\";\n", - " wrapper.style.resize = \"vertical\";\n", - " const content = document.createElement(\"div\");\n", - " content.style.fontFamily = \"monospace\";\n", - " content.style.whiteSpace = \"pre-wrap\";\n", - " content.style.backgroundColor = \"rgb(255, 221, 221)\";\n", - " content.textContent = error.stack ?? error.toString();\n", - " wrapper.append(content);\n", - " el.append(wrapper);\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(() => display_loaded(error), 100);\n", - " }\n", - " }\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - "\n", - " function on_error(url) {\n", - " console.error(\"failed to load \" + url);\n", - " }\n", - "\n", - " for (let i = 0; i < css_urls.length; i++) {\n", - " const url = css_urls[i];\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error.bind(null, url);\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " for (let i = 0; i < js_urls.length; i++) {\n", - " const url = js_urls[i];\n", - " const element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error.bind(null, url);\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " };\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.6.3.min.js\"];\n", - " const css_urls = [];\n", - "\n", - " const inline_js = [ function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - "function(Bokeh) {\n", - " }\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " if (root.Bokeh !== undefined || force === true) {\n", - " try {\n", - " for (let i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }\n", - "\n", - " } catch (error) {throw error;\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(css_urls, js_urls, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "'use strict';\n(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded(error = null) {\n const el = document.getElementById(null);\n if (el != null) {\n const html = (() => {\n if (typeof root.Bokeh === \"undefined\") {\n if (error == null) {\n return \"BokehJS is loading ...\";\n } else {\n return \"BokehJS failed to load.\";\n }\n } else {\n const prefix = `BokehJS ${root.Bokeh.version}`;\n if (error == null) {\n return `${prefix} successfully loaded.`;\n } else {\n return `${prefix} encountered errors while loading and may not function as expected.`;\n }\n }\n })();\n el.innerHTML = html;\n\n if (error != null) {\n const wrapper = document.createElement(\"div\");\n wrapper.style.overflow = \"auto\";\n wrapper.style.height = \"5em\";\n wrapper.style.resize = \"vertical\";\n const content = document.createElement(\"div\");\n content.style.fontFamily = \"monospace\";\n content.style.whiteSpace = \"pre-wrap\";\n content.style.backgroundColor = \"rgb(255, 221, 221)\";\n content.textContent = error.stack ?? error.toString();\n wrapper.append(content);\n el.append(wrapper);\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(() => display_loaded(error), 100);\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.6.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.6.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n try {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n\n } catch (error) {throw error;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.bokehjs_exec.v0+json": "", - "text/html": [ - "" - ] - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "server_id": "e251939db72a4906ae39470a8a76e359" - } - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "output_notebook(resources=None, verbose=False, hide_banner=True)\n", "show(mem_usage_chart, notebook_url=\"http://127.0.0.1:8888\", port=8889)" @@ -467,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "e1d5ab5e", "metadata": {}, "outputs": [], @@ -481,19 +133,10 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "477cf909", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Task finished\n", - "Task finished\n" - ] - } - ], + "outputs": [], "source": [ "task = executor.submit(generate_sequence, result, length=100, batch = 50000)" ] @@ -518,7 +161,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "e0a08dd8", "metadata": {}, "outputs": [], @@ -556,7 +199,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "27b340b7", "metadata": {}, "outputs": [], @@ -579,12 +222,12 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "45b3955f", "metadata": {}, "outputs": [], "source": [ - "db0.set_cache_size(128 << 20)" + "db0.set_cache_size(128 * 1024 * 1024)" ] }, { @@ -607,7 +250,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "9fc1c062", "metadata": {}, "outputs": [], @@ -617,7 +260,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "cb5949bb", "metadata": {}, "outputs": [], @@ -630,7 +273,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "39ec4824", "metadata": {}, "outputs": [], @@ -640,28 +283,10 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "29a62967", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "5000000\n" - ] - }, - { - "data": { - "text/plain": [ - "'oeqVRJbN24Un'" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "print(len(db0_result))\n", "db0_result[12313]"