{ "cells": [ { "cell_type": "code", "id": "initial_id", "metadata": { "collapsed": true, "ExecuteTime": { "end_time": "2024-12-12T17:09:58.749289Z", "start_time": "2024-12-12T17:09:58.747461Z" } }, "source": [ "from src.benchmark import shuffle_benchmark, ShuffleTypes\n", "import matplotlib.pyplot as plt" ], "outputs": [], "execution_count": 6 }, { "metadata": { "ExecuteTime": { "end_time": "2024-12-12T17:09:58.765574Z", "start_time": "2024-12-12T17:09:58.758204Z" } }, "cell_type": "code", "source": [ "multiple = 3\n", "number_of_keys=6 * multiple\n", "properties_per_key=12 * multiple\n", "passcode_len=1\n", "max_tries_before_lockout= 5\n", "complexity=1\n", "disparity=1\n", "run_count=10000\n", "\n", "bench_split = shuffle_benchmark(\n", " number_of_keys=number_of_keys,\n", " properties_per_key=properties_per_key,\n", " passcode_len=passcode_len,\n", " max_tries_before_lockout=max_tries_before_lockout,\n", " run_count=run_count,\n", " complexity=complexity,\n", " disparity=disparity,\n", " shuffle_type=ShuffleTypes.SPLIT_SHUFFLE\n", ")" ], "id": "c86c6ed5014dac44", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "file exists ../output\n" ] } ], "execution_count": 7 }, { "metadata": { "ExecuteTime": { "end_time": "2024-12-12T17:09:58.835376Z", "start_time": "2024-12-12T17:09:58.833451Z" } }, "cell_type": "code", "source": [ "print(f\"Bench Split Mean {bench_split.mean}\\n\"\n", " f\"Bench Split Var: {bench_split.variance}\")" ], "id": "6de455d5097d9c3d", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bench Split Mean 5.571\n", "Bench Split Var: 0.5252115211521152\n" ] } ], "execution_count": 8 }, { "metadata": { "ExecuteTime": { "end_time": "2024-12-12T17:09:58.908054Z", "start_time": "2024-12-12T17:09:58.905569Z" } }, "cell_type": "code", "source": [ "def bench_histogram(data, title):\n", " # Create the histogram\n", " min_val = min(data)\n", " max_val = max(data)\n", " \n", " # Create bins for each integer. \n", " # For example, if the data goes from 1 to 5, \n", " # then bins = [1, 2, 3, 4, 5, 6]\n", " bins = range(min_val, max_val + 2)\n", " plt.hist(data, bins=bins, edgecolor='black')\n", " \n", " # Add titles and labels\n", " plt.title(title)\n", " plt.xlabel('Value')\n", " plt.ylabel('Frequency')\n", " \n", " # Display the plot\n", " plt.show()\n" ], "id": "99ddd0fbd421b058", "outputs": [], "execution_count": 9 }, { "metadata": { "ExecuteTime": { "end_time": "2024-12-12T17:09:58.989830Z", "start_time": "2024-12-12T17:09:58.918011Z" } }, "cell_type": "code", "source": "bench_histogram(bench_split.runs, \"bench split\")", "id": "9cbf9282eba285e6", "outputs": [ { "data": { "text/plain": [ "
" ], "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAHHCAYAAABeLEexAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/GU6VOAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA2dklEQVR4nO3dfXzP9f7H8efXroxdMbZZtpmrXOeYEyvK1TFaDvE7lMuY09EZYYfKqRA5SgcRcTppyymFTnWKwgglk4tMklxOU7ZJLmZqF7bP7w8331vfSJrt+xnvx/12+9xufd6f1/fzfb2/XXj2+bw/36/DsixLAAAABqtkdwMAAAB2IxABAADjEYgAAIDxCEQAAMB4BCIAAGA8AhEAADAegQgAABiPQAQAAIxHIAIAAMYjEAEoc5MnT5bD4dCJEyfsbuWyjhw5IofDoX/+8592tyJJcjgcmjx5snM/JSVFDodDR44csa0nwDQEIgC4DrzwwgtKSUmxuw3ghkUgAoAKZtCgQfrxxx8VFRXlHCMQAeXL0+4GAACuPDw85OHhYXcbgFG4QgSg3Jw4cUJ9+/ZVQECAgoODNXr0aOXn519S9+qrryomJka+vr6qXr267r33Xh09etSlpkOHDmrWrJm+/PJLdezYUVWqVNFNN92kGTNmXHK+/Px8TZ48WQ0bNlTlypVVq1Yt9e7dW4cOHbqk9sUXX1S9evXk4+Oj3//+99q2bduvzquoqEhPPvmkGjRooMqVKys4OFjt2rVTamqqs+b++++Xn5+fDh8+rLi4OFWtWlXh4eGaMmWKLMu64vl/voaoTp062rNnjzZu3CiHwyGHw6EOHTr8ap8Arh5XiACUm759+6pOnTqaPn26tmzZorlz5+rUqVNavHixs2batGl64okn1LdvXw0fPlzfffednn/+ed1xxx3auXOngoKCnLWnTp1St27d1Lt3b/Xt21dvvvmmHnnkETVv3lzdu3eXJBUXF+vuu+/WunXrdO+992r06NE6e/asUlNT9cUXX6hevXrO8y1ZskRnz57VX/7yFzkcDs2YMUO9e/fW4cOH5eXl9Yvzmjx5sqZPn67hw4fr1ltvVW5urrZv367PPvtMf/jDH5x1xcXF6tatm9q2basZM2Zo1apVmjRpks6fP68pU6Zc9ef43HPPadSoUfLz89Njjz0mSQoNDb3q1wO4ChYAlLFJkyZZkqw//vGPLuN//etfLUnWrl27LMuyrCNHjlgeHh7WtGnTXOp2795teXp6uozfeeedliRr8eLFzrGCggIrLCzM6tOnj3Ps5ZdftiRZs2bNuqSvkpISy7IsKyMjw5JkBQcHWydPnnQe/9///mdJst57770rzu+WW26x4uPjr1gzZMgQS5I1atQol/ePj4+3vL29re+++845LsmaNGmScz85OdmSZGVkZDjHmjZtat15551XfE8ApcctMwDlJjEx0WV/1KhRkqT3339fkvTWW2+ppKREffv21YkTJ5xbWFiYGjRooPXr17u83s/PTwMHDnTue3t769Zbb9Xhw4edY//9739Vo0YN53v9lMPhcNnv16+fqlWr5txv3769JLmc73KCgoK0Z88eHThw4Ip1kjRy5EiX9x85cqQKCwu1du3aX30tAPfhlhmActOgQQOX/Xr16qlSpUrOtTEHDhyQZVmX1F3089tWtWvXviTUVKtWTZ9//rlz/9ChQ7r55pvl6fnr/3mLjIy85FzShVtzVzJlyhT17NlTDRs2VLNmzdStWzcNGjRILVq0cKmrVKmS6tat6zLWsGFDSeI7hoAKhkAEwG1+HmZKSkrkcDj0wQcfXPapKj8/P5f9X3ryyvqVRcq/pLTnu+OOO3To0CH973//05o1a/TSSy9p9uzZWrhwoYYPH16qXgDYi0AEoNwcOHBA0dHRzv2DBw+qpKREderUkXThipFlWYqOjnZeOblW9erV06effqqioqIrLoy+VtWrV9fQoUM1dOhQ5eXl6Y477tDkyZNdAlFJSYkOHz7sMrf9+/dLkvMzuFo/D5MAyhZriACUm/nz57vsP//885LkfCKsd+/e8vDw0JNPPnnJVRnLsvT999//5vfs06ePTpw4oXnz5l1yrLRXkn7u5335+fmpfv36KigouKT2p31YlqV58+bJy8tLnTt3/k3vWbVqVZ0+fbpU/QL4dVwhAlBuMjIy9Mc//lHdunVTWlqaXn31VfXv31+33HKLpAtXc5566ilNmDBBR44cUa9eveTv76+MjAy9/fbbeuCBBzRu3Ljf9J6DBw/W4sWLlZSUpK1bt6p9+/Y6d+6c1q5dq7/+9a/q2bPnNc+rSZMm6tChg2JiYlS9enVt375db775pssCakmqXLmyVq1apSFDhqhNmzb64IMPtHLlSv39739X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V1RUlE0d2Sc5OVkhISGKj4+3uxW3+uGHH1Spkut/gj08PFRSUmJTR/apWrWqatWqpVOnTmn16tXq2bOn3S25XXR0tMLCwrRu3TrnWG5urj799FPFxsba2Jk5uGVmA39/fzVr1sxlrGrVqgoODr5k/EY1btw49ejRQ1FRUTp27JgmTZokDw8P3XfffXa35hZjx47Vbbfdpn/84x/q27evtm7dqhdffFEvvvii3a25VUlJiZKTkzVkyBB5epr1n6MePXpo2rRpioyMVNOmTbVz507NmjVLw4YNs7s1t1m9erUsy9LNN9+sgwcPavz48WrUqJGGDh1qd2vlIi8vz+UqeEZGhtLT01W9enVFRkZqzJgxeuqpp9SgQQNFR0friSeeUHh4uHr16mVf02Xs1z6DkydPKjMzU8eOHZMk5/84hoWFlf+VMrc9z4YrMu2x+379+lm1atWyvL29rZtuusnq16+fdfDgQbvbcqv33nvPatasmeXj42M1atTIevHFF+1uye1Wr15tSbL27dtndytul5uba40ePdqKjIy0KleubNWtW9d67LHHrIKCArtbc5ulS5dadevWtby9va2wsDArMTHROn36tN1tlZv169dbki7ZhgwZYlnWhUfvn3jiCSs0NNTy8fGxOnfufMP9u/Frn0FycvJlj0+aNKnce3NYlkFfiwoAAHAZrCECAADGIxABAADjEYgAAIDxCEQAAMB4BCIAAGA8AhEAADAegQgAABiPQATAWB06dNCYMWPsbgNABUAgAnBd6tGjh7p163bZYx9//LEcDoc+//xzN3cF4HpFIAJwXUpISFBqaqq++eabS44lJyerdevWatGihQ2dAbgeEYgAXJfuvvtu1axZUykpKS7jeXl5Wr58uXr16qX77rtPN910k6pUqaLmzZvr9ddfv+I5HQ6H3nnnHZexoKAgl/c4evSo+vbtq6CgIFWvXl09e/bUkSNHymZSAGxDIAJwXfL09NTgwYOVkpKin/4k4/Lly1VcXKyBAwcqJiZGK1eu1BdffKEHHnhAgwYN0tatW0v9nkVFRYqLi5O/v78+/vhjffLJJ/Lz81O3bt1UWFhYFtMCYBMCEYDr1rBhw3To0CFt3LjROZacnKw+ffooKipK48aNU8uWLVW3bl2NGjVK3bp107Jly0r9fkuXLlVJSYleeuklNW/eXI0bN1ZycrIyMzO1YcOGMpgRALsQiABctxo1aqTbbrtNL7/8siTp4MGD+vjjj5WQkKDi4mJNnTpVzZs3V/Xq1eXn56fVq1crMzOz1O+3a9cuHTx4UP7+/vLz85Ofn5+qV6+u/Px8HTp0qKymBcAGnnY3AADXIiEhQaNGjdL8+fOVnJysevXq6c4779QzzzyjOXPm6LnnnlPz5s1VtWpVjRkz5oq3thwOh8vtN+nCbbKL8vLyFBMTo9dee+2S19asWbPsJgXA7QhEAK5rffv21ejRo7VkyRItXrxYDz74oBwOhz755BP17NlTAwcOlCSVlJRo//79atKkyS+eq2bNmsrKynLuHzhwQD/88INzv1WrVlq6dKlCQkIUEBBQfpMC4HbcMgNwXfPz81O/fv00YcIEZWVl6f7775ckNWjQQKmpqdq8ebP27t2rv/zlL8rJybniuTp16qR58+Zp586d2r59u0aMGCEvLy/n8QEDBqhGjRrq2bOnPv74Y2VkZGjDhg166KGHLvv4P4DrB4EIwHUvISFBp06dUlxcnMLDwyVJjz/+uFq1aqW4uDh16NBBYWFh6tWr1xXPM3PmTEVERKh9+/bq37+/xo0bpypVqjiPV6lSRR999JEiIyPVu3dvNW7cWAkJCcrPz+eKEXCdc1g/v2EOAABgGK4QAQAA4xGIAACA8QhEAADAeAQiAABgPAIRAAAwHoEIAAAYj0AEAACMRyACAADGIxABAADjEYgAAIDxCEQAAMB4BCIAAGC8/wc8sF2slnCLTgAAAABJRU5ErkJggg==" }, "metadata": {}, "output_type": "display_data" } ], "execution_count": 10 } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 5 }