diff --git a/README.md b/README.md index 9741fef..2e4efd7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,61 @@ -# README -Play around with the code in /notebooks +# Readme + +pynkode is a tutorial of how nkode works. +There are jupyter notebooks in /notebooks covering these topics: +- dispersion +- nkode enrollment, login, and renewal +- split shuffle + +## Installation + +- Python version 3.10 or greater is required +- Install pyenv or conda for environment management + +### Option 1: Using conda +```bash +# Create a new conda environment named pynkode +conda create -n pynkode python=3.10 +# Activate the environment +conda activate pynkode +# Install the requirements +pip install -r requirements.txt +``` + +### Option 2: Using pyenv +```bash +# Install Python 3.10 using pyenv +pyenv install 3.10.0 +# Create a virtualenv named pynkode +pyenv virtualenv 3.10.0 pynkode +# Set the local version to pynkode +pyenv local pynkode +# Install the requirements +pip install -r requirements.txt +``` + +## Starting a Jupyter Notebook + +### Option 1: Using classic Jupyter Notebook +```bash +# Ensure your environment is activated +# For conda: conda activate pynkode +# For pyenv: (should be automatic if in the directory) + +# Start the Jupyter Notebook server +jupyter notebook +``` + +### Option 2: Using JupyterLab +```bash +# Ensure your environment is activated +# Start JupyterLab +jupyter lab +``` + +## Exploring the Tutorials + +1. Navigate to the `/notebooks` directory in the Jupyter interface +2. Open the tutorials in the following recommended order: + - `Enrollment_Login_Renewal.ipynb` - Learn how to manage user accounts in nkode + - `Dispersion.ipynb` - Understand the basic concepts of dispersion in nkode + - `Split_Shuffle.ipynb` - Explore the split shuffle functionality diff --git a/notebooks/dispersion_tutorial.ipynb b/notebooks/Dispersion.ipynb similarity index 64% rename from notebooks/dispersion_tutorial.ipynb rename to notebooks/Dispersion.ipynb index a7d59eb..69bb5e3 100644 --- a/notebooks/dispersion_tutorial.ipynb +++ b/notebooks/Dispersion.ipynb @@ -2,26 +2,32 @@ "cells": [ { "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-21T10:41:27.004729Z", + "start_time": "2025-03-21T10:41:26.963236Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], "source": [ + "import sys\n", + "import os\n", + "sys.path.append(os.path.abspath('..')) # Adds the parent directory to path\n", "from src.user_keypad import UserKeypad\n", "from IPython.display import Markdown, display\n", "from src.models import KeypadSize\n", "from src.utils import random_property_rotation, keypad_md_table\n", "import numpy as np" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2025-03-21T09:28:57.936307Z", - "start_time": "2025-03-21T09:28:57.933359Z" - } - }, - "outputs": [], - "execution_count": 5 + ] }, { - "metadata": {}, "cell_type": "markdown", + "metadata": {}, "source": [ "## Keypad Dispersion\n", "\n", @@ -34,13 +40,48 @@ ] }, { + "cell_type": "code", + "execution_count": 3, "metadata": { "ExecuteTime": { - "end_time": "2025-03-21T09:28:57.950591Z", - "start_time": "2025-03-21T09:28:57.945584Z" + "end_time": "2025-03-21T10:41:27.020289Z", + "start_time": "2025-03-21T10:41:27.014493Z" } }, - "cell_type": "code", + "outputs": [ + { + "data": { + "text/markdown": [ + "\n", + "## Example Keypad\n", + "5 X 4 keypad (5 keys, 4 properties per key).\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/markdown": [ + "||position 0|position 1|position 2|position 3|\n", + "|-|-|-|-|-|\n", + "|key 0|1|10|11|100|\n", + "|key 1|2|20|22|200|\n", + "|key 2|3|30|33|300|\n", + "|key 3|4|40|44|400|\n", + "|key 4|5|50|55|500|" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "keypad_size = KeypadSize(numb_of_keys=5, props_per_key=4)\n", "props = [1, 10, 11, 100]\n", @@ -54,47 +95,26 @@ "{keypad_size.numb_of_keys} X {keypad_size.props_per_key} keypad ({keypad_size.numb_of_keys} keys, {keypad_size.props_per_key} properties per key).\n", "\"\"\"))\n", "display(Markdown(keypad_md_table(user_keypad.keypad, keypad_size)))\n" - ], - "outputs": [ - { - "data": { - "text/plain": [ - "" - ], - "text/markdown": "\n## Example Keypad\n5 X 4 keypad (5 keys, 4 properties per key).\n" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ], - "text/markdown": "||position 0|position 1|position 2|position 3|\n|-|-|-|-|-|\n|key 0|1|10|11|100|\n|key 1|2|20|22|200|\n|key 2|3|30|33|300|\n|key 3|4|40|44|400|\n|key 4|5|50|55|500|" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "execution_count": 6 + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "### Create Property Rotation Array" + "metadata": {}, + "source": [ + "### Create Property Rotation Array" + ] }, { "cell_type": "code", - "source": [ - "prop_rotation = np.random.choice(keypad_size.numb_of_keys, size=keypad_size.props_per_key, replace=False)\n", - "print(f\"Property Rotation: {prop_rotation}\")\n" - ], + "execution_count": 4, "metadata": { - "collapsed": false, "ExecuteTime": { - "end_time": "2025-03-21T09:28:57.961890Z", - "start_time": "2025-03-21T09:28:57.959507Z" + "end_time": "2025-03-21T10:41:27.065332Z", + "start_time": "2025-03-21T10:41:27.056656Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false } }, "outputs": [ @@ -102,66 +122,103 @@ "name": "stdout", "output_type": "stream", "text": [ - "Property Rotation: [0 3 1 2]\n" + "Property Rotation: [4 2 0 1]\n" ] } ], - "execution_count": 7 + "source": [ + "prop_rotation = np.random.choice(keypad_size.numb_of_keys, size=keypad_size.props_per_key, replace=False)\n", + "print(f\"Property Rotation: {prop_rotation}\")\n" + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "### Apply the Rotation" + "metadata": {}, + "source": [ + "### Apply the Rotation" + ] }, { + "cell_type": "code", + "execution_count": 5, "metadata": { "ExecuteTime": { - "end_time": "2025-03-21T09:28:57.976227Z", - "start_time": "2025-03-21T09:28:57.973183Z" + "end_time": "2025-03-21T10:41:27.074908Z", + "start_time": "2025-03-21T10:41:27.072449Z" } }, - "cell_type": "code", + "outputs": [ + { + "data": { + "text/markdown": [ + "||position 0|position 1|position 2|position 3|\n", + "|-|-|-|-|-|\n", + "|key 0|2|40|11|500|\n", + "|key 1|3|50|22|100|\n", + "|key 2|4|10|33|200|\n", + "|key 3|5|20|44|300|\n", + "|key 4|1|30|55|400|" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "dispersed_interface = random_property_rotation(\n", " user_keypad.keypad_matrix(),\n", " prop_rotation\n", ")\n", "display(Markdown(keypad_md_table(dispersed_interface.reshape(-1), keypad_size)))" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "" - ], - "text/markdown": "||position 0|position 1|position 2|position 3|\n|-|-|-|-|-|\n|key 0|1|30|55|400|\n|key 1|2|40|11|500|\n|key 2|3|50|22|100|\n|key 3|4|10|33|200|\n|key 4|5|20|44|300|" - }, - "metadata": {}, - "output_type": "display_data" + "name": "stdout", + "output_type": "stream", + "text": [ + "hello\n" + ] } ], - "execution_count": 8 + "source": [ + "print(\"hello\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.10.14" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 4 } diff --git a/notebooks/nkode_tutorial.ipynb b/notebooks/Enrollment_Login_Renewal.ipynb similarity index 99% rename from notebooks/nkode_tutorial.ipynb rename to notebooks/Enrollment_Login_Renewal.ipynb index 7960aab..af5515d 100644 --- a/notebooks/nkode_tutorial.ipynb +++ b/notebooks/Enrollment_Login_Renewal.ipynb @@ -3,6 +3,9 @@ { "cell_type": "code", "source": [ + "import sys\n", + "import os\n", + "sys.path.append(os.path.abspath('..')) # Adds the parent directory to path\n", "from src.nkode_api import NKodeAPI\n", "from src.models import NKodePolicy, KeypadSize\n", "from secrets import choice\n", diff --git a/notebooks/split_shuffle_tutorial.ipynb b/notebooks/Split_Shuffle.ipynb similarity index 97% rename from notebooks/split_shuffle_tutorial.ipynb rename to notebooks/Split_Shuffle.ipynb index 84578ef..7ac6e52 100644 --- a/notebooks/split_shuffle_tutorial.ipynb +++ b/notebooks/Split_Shuffle.ipynb @@ -9,6 +9,9 @@ }, "cell_type": "code", "source": [ + "import sys\n", + "import os\n", + "sys.path.append(os.path.abspath('..')) # Adds the parent directory to path\n", "from src.models import KeypadSize\n", "from src.user_keypad import UserKeypad\n", "from src.utils import keypad_md_table\n", diff --git a/requirements.txt b/requirements.txt index fe1c025..dcd35dd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ bcrypt~=4.1.3 numpy~=2.0.0 -jinja2~=3.1.4 pytest~=8.2.2 ipython~=8.25.0 \ No newline at end of file