{
 "cells": [
  {
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-08-29T18:56:41.319525Z",
     "start_time": "2025-08-29T18:56:41.316861Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from src.benchmark import shuffle_benchmark\n",
    "from src.utils import ShuffleTypes\n",
    "import matplotlib.pyplot as plt\n",
    "from pathlib import Path"
   ],
   "id": "initial_id",
   "outputs": [],
   "execution_count": 11
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-29T18:56:56.212133Z",
     "start_time": "2025-08-29T18:56:41.328565Z"
    }
   },
   "cell_type": "code",
   "source": [
    "multiple = 1\n",
    "number_of_keys=6* multiple\n",
    "properties_per_key=10 * multiple\n",
    "passcode_len=4\n",
    "max_tries_before_lockout= 3\n",
    "complexity=2\n",
    "disparity=2\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",
    ")\n",
    "\n",
    "bench_full = 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.FULL_SHUFFLE\n",
    ")\n",
    "\n",
    "bench_tower = 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.TOWER_SHUFFLE\n",
    ")\n"
   ],
   "id": "c86c6ed5014dac44",
   "outputs": [],
   "execution_count": 12
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-29T18:56:56.226642Z",
     "start_time": "2025-08-29T18:56:56.224017Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(f\"Bench Split Mean {bench_split.mean}\\n\"\n",
    "      f\"Bench Split Var: {bench_split.variance}\")\n",
    "print(f\"Bench full Mean {bench_full.mean}\\n\"\n",
    "      f\"Bench full Var: {bench_full.variance}\")\n",
    "print(f\"Bench full Mean {bench_tower.mean}\\n\"\n",
    "      f\"Bench full Var: {bench_tower.variance}\")\n"
   ],
   "id": "6de455d5097d9c3d",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Bench Split Mean 7.4017\n",
      "Bench Split Var: 2.4483819481948195\n",
      "Bench full Mean 4.2212\n",
      "Bench full Var: 0.2624968096809681\n",
      "Bench full Mean 6.7561\n",
      "Bench full Var: 1.6323760276027603\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "cell_type": "code",
   "id": "99ddd0fbd421b058",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-29T18:56:56.239558Z",
     "start_time": "2025-08-29T18:56:56.236307Z"
    }
   },
   "source": [
    "def bench_histogram(data, title, number_of_keys, properties_per_key, \n",
    "                    passcode_len, max_tries_before_lockout, complexity, disparity, run_count, save_path: Path = None):\n",
    "    # Create the histogram\n",
    "    min_val = min(data)\n",
    "    max_val = max(data)\n",
    "    \n",
    "    # Create bins for each integer\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('# of Login Observations')\n",
    "    plt.ylabel('Simulations')\n",
    "    \n",
    "    # Display parameters as text in the plot\n",
    "    text = (f\"number_of_keys={number_of_keys}\\n\"\n",
    "            f\"properties_per_key={properties_per_key}\\n\"\n",
    "            f\"passcode_len={passcode_len}\\n\"\n",
    "            f\"max_tries_before_lockout={max_tries_before_lockout}\\n\"\n",
    "            f\"complexity={complexity}\\n\"\n",
    "            f\"disparity={disparity}\\n\"\n",
    "            f\"run_count={run_count}\")\n",
    "    \n",
    "    plt.text(0.95, 0.95, text, transform=plt.gca().transAxes, fontsize=10,\n",
    "             verticalalignment='top', horizontalalignment='right', bbox=dict(facecolor='white', alpha=0.5))\n",
    "    \n",
    "   # Save plot if a path is provided\n",
    "    if save_path:\n",
    "        save_path.mkdir(parents=True, exist_ok=True)\n",
    "        filename = (f\"{title.replace(' ', '_')}_multi{multiple}_keys{number_of_keys}_\"\n",
    "                    f\"props{properties_per_key}_pass{passcode_len}_tries{max_tries_before_lockout}_\"\n",
    "                    f\"comp{complexity}_disp{disparity}_runs{run_count}.png\")\n",
    "        plt.savefig(save_path / filename, bbox_inches='tight', dpi=300)\n",
    "         \n",
    "    # Display the plot\n",
    "    plt.show()\n"
   ],
   "outputs": [],
   "execution_count": 14
  },
  {
   "cell_type": "code",
   "id": "9cbf9282eba285e6",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-29T18:56:56.959009Z",
     "start_time": "2025-08-29T18:56:56.245415Z"
    }
   },
   "source": [
    "bench_histogram(bench_split.runs, \"Key Logger Split Shuffle\", number_of_keys, properties_per_key, passcode_len, max_tries_before_lockout, complexity, disparity, run_count, Path(\"../output/histograms\"))\n",
    "bench_histogram(bench_full.runs, \"Key Logger Random Shuffle\", number_of_keys, properties_per_key, passcode_len, max_tries_before_lockout, complexity, disparity, run_count, Path(\"../output/histograms\"))\n",
    "bench_histogram(bench_tower.runs, \"Key Logger Tower Shuffle\", number_of_keys, properties_per_key, passcode_len, max_tries_before_lockout, complexity, disparity, run_count, Path(\"../output/histograms\"))"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "[encoded data, 45276 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "[encoded data, 47844 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "[encoded data, 46096 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 15
  }
 ],
 "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.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
