{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 28,
      "metadata": {
        "vscode": {
          "languageId": "plaintext"
        }
      },
      "outputs": [
        {
          "ename": "TypeError",
          "evalue": "list indices must be integers or slices, not str",
          "output_type": "error",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
            "Cell \u001b[0;32mIn[28], line 60\u001b[0m\n\u001b[1;32m     54\u001b[0m                     average_utilization \u001b[38;5;241m=\u001b[39m calculate_average_utilization(values)\n\u001b[1;32m     55\u001b[0m                     \u001b[38;5;66;03m# Store results\u001b[39;00m\n\u001b[1;32m     56\u001b[0m                     results[provider][setup][mode] \u001b[38;5;241m=\u001b[39m {\n\u001b[1;32m     57\u001b[0m                         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mScaling Speed\u001b[39m\u001b[38;5;124m\"\u001b[39m: scaling_speed,\n\u001b[1;32m     58\u001b[0m                         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCPU Utilization\u001b[39m\u001b[38;5;124m\"\u001b[39m: average_utilization,\n\u001b[1;32m     59\u001b[0m                         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mMemory Utilization\u001b[39m\u001b[38;5;124m\"\u001b[39m: average_utilization,  \u001b[38;5;66;03m# Placeholder for memory\u001b[39;00m\n\u001b[0;32m---> 60\u001b[0m                         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCost Efficiency\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[43mget_cost_from_billing\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprovider\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msetup\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmode\u001b[49m\u001b[43m)\u001b[49m,\n\u001b[1;32m     61\u001b[0m                         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mResource Provisioning\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mDynamic\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m mode \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mkarpenter\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mStatic\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m     62\u001b[0m                     }\n\u001b[1;32m     64\u001b[0m \u001b[38;5;66;03m# Convert results to DataFrame for display\u001b[39;00m\n\u001b[1;32m     65\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mformat_results\u001b[39m(results, setup_type):\n",
            "Cell \u001b[0;32mIn[28], line 35\u001b[0m, in \u001b[0;36mget_cost_from_billing\u001b[0;34m(provider, setup, mode)\u001b[0m\n\u001b[1;32m     33\u001b[0m data \u001b[38;5;241m=\u001b[39m json\u001b[38;5;241m.\u001b[39mload(file)\n\u001b[1;32m     34\u001b[0m \u001b[38;5;66;03m# Get the most recent time period's cost\u001b[39;00m\n\u001b[0;32m---> 35\u001b[0m latest_period \u001b[38;5;241m=\u001b[39m \u001b[43mdata\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mResultsByTime\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m]\n\u001b[1;32m     36\u001b[0m cost \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mfloat\u001b[39m(latest_period[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTotal\u001b[39m\u001b[38;5;124m\"\u001b[39m][\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mUnblendedCost\u001b[39m\u001b[38;5;124m\"\u001b[39m][\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAmount\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n\u001b[1;32m     37\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m$\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mcost\u001b[38;5;132;01m:\u001b[39;00m\u001b[38;5;124m.2f\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m per hour\u001b[39m\u001b[38;5;124m\"\u001b[39m\n",
            "\u001b[0;31mTypeError\u001b[0m: list indices must be integers or slices, not str"
          ]
        }
      ],
      "source": [
        "# Import required libraries\n",
        "import os\n",
        "import json\n",
        "import pandas as pd\n",
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "import json\n",
        "\n",
        "# Directories for analysis\n",
        "providers = [\"aws\", \"ibm\"]\n",
        "modes = [\"cas\", \"karpenter\"]\n",
        "\n",
        "# Initialize results dictionary\n",
        "results = {}\n",
        "\n",
        "# Function to calculate scaling speed\n",
        "def calculate_scaling_speed(values):\n",
        "    timestamps = [val[0] for val in values]\n",
        "    deltas = np.diff(timestamps)\n",
        "    return np.mean(deltas)\n",
        "\n",
        "# Function to calculate average utilization\n",
        "def calculate_average_utilization(values):\n",
        "    utilizations = [float(val[1]) for val in values]\n",
        "    return np.mean(utilizations)\n",
        "\n",
        "# Function to get cost from billing metrics\n",
        "def get_cost_from_billing(provider, setup, mode):\n",
        "    billing_file = os.path.join(provider, setup, mode, f\"{provider}_billing_metrics_{mode}.json\")\n",
        "    if os.path.exists(billing_file):\n",
        "        with open(billing_file, \"r\") as file:\n",
        "            data = json.load(file)\n",
        "            # Get the most recent time period's cost\n",
        "            latest_period = data[\"ResultsByTime\"][-1]\n",
        "            cost = float(latest_period[\"Total\"][\"UnblendedCost\"][\"Amount\"])\n",
        "            return f\"${cost:.2f} per hour\"\n",
        "    return \"$X per hour\"  # Keep original placeholder if file not found\n",
        "\n",
        "# Traverse directories and process files\n",
        "for provider in providers:\n",
        "    results[provider] = {}\n",
        "    for setup in setups:\n",
        "        results[provider][setup] = {}\n",
        "        for mode in modes:\n",
        "            # Define the path to the JSON file\n",
        "            json_path = os.path.join(provider, setup, mode, \"NodeCount.json\")\n",
        "            if os.path.exists(json_path):\n",
        "                with open(json_path, \"r\") as file:\n",
        "                    data = json.load(file)\n",
        "                    values = data[\"data\"][\"result\"][0][\"values\"]\n",
        "                    # Calculate metrics\n",
        "                    scaling_speed = calculate_scaling_speed(values)\n",
        "                    average_utilization = calculate_average_utilization(values)\n",
        "                    # Store results\n",
        "                    results[provider][setup][mode] = {\n",
        "                        \"Scaling Speed\": scaling_speed,\n",
        "                        \"CPU Utilization\": average_utilization,\n",
        "                        \"Memory Utilization\": average_utilization,  # Placeholder for memory\n",
        "                        \"Cost Efficiency\": get_cost_from_billing(provider, setup, mode),\n",
        "                        \"Resource Provisioning\": \"Dynamic\" if mode == \"karpenter\" else \"Static\"\n",
        "                    }\n",
        "\n",
        "# Convert results to DataFrame for display\n",
        "def format_results(results, setup_type):\n",
        "    rows = []\n",
        "    scenario = \"1 (Homogenous)\" if setup_type == \"homogenous\" else \"2 (Heterogenous)\"\n",
        "    \n",
        "    for provider, setups in results.items():\n",
        "        if setup_type in setups:\n",
        "            for mode, metrics in setups[setup_type].items():\n",
        "                rows.append([\n",
        "                    f\"Scenario {scenario}: {provider.upper()}\",\n",
        "                    mode.capitalize(),\n",
        "                    metrics[\"Scaling Speed\"],\n",
        "                    metrics[\"CPU Utilization\"],\n",
        "                    metrics[\"Memory Utilization\"],\n",
        "                    metrics[\"Cost Efficiency\"],\n",
        "                    metrics[\"Resource Provisioning\"]\n",
        "                ])\n",
        "    \n",
        "    return pd.DataFrame(rows, columns=[\n",
        "        \"Scenario\", \"Mode\", \"Scaling Speed (mins)\",\n",
        "        \"CPU Utilization (%)\", \"Memory Utilization (%)\",\n",
        "        \"Cost Efficiency\", \"Resource Provisioning\"\n",
        "    ])\n",
        "\n",
        "# Format results for homogenous (Scenario 1) and heterogenous (Scenario 2)\n",
        "homogenous_results = format_results(results, \"homogenous\")\n",
        "heterogenous_results = format_results(results, \"heterogenous\")\n",
        "\n",
        "# Display results as tables\n",
        "from IPython.display import display\n",
        "print(\"Scenario 1 (Homogenous) Results:\")\n",
        "display(homogenous_results)\n",
        "print(\"\\nScenario 2 (Heterogenous) Results:\")\n",
        "display(heterogenous_results)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "metadata": {},
      "outputs": [],
      "source": [
        "plt.rcParams['figure.dpi'] = 1200\n",
        "\n",
        "# Load IBM data\n",
        "with open('ibm/homogenous/karpenter/NodeCount.json', 'r') as f:\n",
        "    karpenter_data = json.load(f)\n",
        "with open('ibm/homogenous/cas/NodeCount.json', 'r') as f:\n",
        "    cas_data = json.load(f)\n",
        "\n",
        "# Extract timestamps and values\n",
        "karpenter_times = [val[0] for val in karpenter_data['data']['result'][0]['values']]\n",
        "karpenter_nodes = [float(val[1]) for val in karpenter_data['data']['result'][0]['values']]\n",
        "\n",
        "cas_times = [val[0] for val in cas_data['data']['result'][0]['values']]\n",
        "cas_nodes = [float(val[1]) for val in cas_data['data']['result'][0]['values']]\n",
        "\n",
        "# Convert timestamps to minutes from start\n",
        "karpenter_times = np.array([(t - karpenter_times[0])/60 for t in karpenter_times])\n",
        "cas_times = np.array([(t - cas_times[0])/60 for t in cas_times])\n",
        "\n",
        "# Plot the data\n",
        "fig, ax = plt.subplots(figsize=(5, 3))\n",
        "ax.plot(cas_times, cas_nodes, label='CAS', linestyle='-', marker='o', markersize=3)\n",
        "ax.plot(karpenter_times, karpenter_nodes, label='Karpenter', linestyle='--', marker='x', markersize=3)\n",
        "\n",
        "ax.set_xlabel('Time (minutes)')\n",
        "ax.set_ylabel('Number of Nodes')\n",
        "ax.set_title('IBM Node Count Over Time')\n",
        "ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.5), ncol=2)\n",
        "ax.grid(True)\n",
        "\n",
        "# Ensure y-axis shows integer values\n",
        "ax.yaxis.set_major_locator(plt.MaxNLocator(integer=True))\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.savefig('plots/ibm_node_count.png')\n",
        "plt.close()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 26,
      "metadata": {},
      "outputs": [],
      "source": [
        "plt.rcParams['figure.dpi'] = 1200\n",
        "\n",
        "# Load the data\n",
        "with open('ibm/homogenous/karpenter/NodeMemoryPercantage.json', 'r') as f:\n",
        "    karpenter_data = json.load(f)\n",
        "with open('ibm/homogenous/cas/NodeMemoryPercantage.json', 'r') as f:\n",
        "    cas_data = json.load(f)\n",
        "\n",
        "# Process Karpenter data\n",
        "karpenter_times = karpenter_data['data']['result'][0]['values']\n",
        "karpenter_timestamps = [float(val[0]) for val in karpenter_times]\n",
        "karpenter_values = []\n",
        "\n",
        "# For each timestamp, calculate average across all nodes\n",
        "for i in range(len(karpenter_timestamps)):\n",
        "    values_at_timestamp = []\n",
        "    for node in karpenter_data['data']['result']:\n",
        "        if i < len(node['values']):\n",
        "            values_at_timestamp.append(float(node['values'][i][1]))\n",
        "    karpenter_values.append(np.mean(values_at_timestamp))\n",
        "\n",
        "# Process CAS data\n",
        "cas_times = cas_data['data']['result'][0]['values']\n",
        "cas_timestamps = [float(val[0]) for val in cas_times]\n",
        "cas_values = []\n",
        "\n",
        "# For each timestamp, calculate average across all nodes\n",
        "for i in range(len(cas_timestamps)):\n",
        "    values_at_timestamp = []\n",
        "    for node in cas_data['data']['result']:\n",
        "        if i < len(node['values']):\n",
        "            values_at_timestamp.append(float(node['values'][i][1]))\n",
        "    cas_values.append(np.mean(values_at_timestamp))\n",
        "\n",
        "# Convert timestamps to minutes from start\n",
        "start_time = min(karpenter_timestamps[0], cas_timestamps[0])\n",
        "karpenter_times = [(t - start_time)/60 for t in karpenter_timestamps]\n",
        "cas_times = [(t - start_time)/60 for t in cas_timestamps]\n",
        "\n",
        "# Create the plot\n",
        "fig, ax = plt.subplots(figsize=(5, 3))\n",
        "ax.plot(cas_times, cas_values, label='CAS', linestyle='-', marker='o', markersize=3)\n",
        "ax.plot(karpenter_times, karpenter_values, label='Karpenter', linestyle='--', marker='x', markersize=3)\n",
        "\n",
        "ax.set_xlabel('Time (minutes)')\n",
        "ax.set_ylabel('Memory Usage (%)')\n",
        "ax.set_title('IBM Memory Utilization Over Time')\n",
        "ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.5), ncol=2)\n",
        "ax.grid(True)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.savefig('plots/ibm_memory_utilization.png')\n",
        "plt.close()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {},
      "outputs": [],
      "source": [
        "plt.rcParams['figure.dpi'] = 1200\n",
        "\n",
        "# Load the data\n",
        "with open('ibm/homogenous/karpenter/CPUPercentageAllCores.json', 'r') as f:\n",
        "    karpenter_data = json.load(f)\n",
        "with open('ibm/homogenous/cas/CPUPercentageAllCores.json', 'r') as f:\n",
        "    cas_data = json.load(f)\n",
        "\n",
        "# Process Karpenter data\n",
        "karpenter_times = karpenter_data['data']['result'][0]['values']\n",
        "karpenter_timestamps = [float(val[0]) for val in karpenter_times]\n",
        "karpenter_values = []\n",
        "\n",
        "# For each timestamp, calculate average across all nodes\n",
        "for i in range(len(karpenter_timestamps)):\n",
        "    values_at_timestamp = []\n",
        "    for node in karpenter_data['data']['result']:\n",
        "        if i < len(node['values']):\n",
        "            values_at_timestamp.append(float(node['values'][i][1]))\n",
        "    karpenter_values.append(np.mean(values_at_timestamp))\n",
        "\n",
        "# Process CAS data\n",
        "cas_times = cas_data['data']['result'][0]['values']\n",
        "cas_timestamps = [float(val[0]) for val in cas_times]\n",
        "cas_values = []\n",
        "\n",
        "# For each timestamp, calculate average across all nodes\n",
        "for i in range(len(cas_timestamps)):\n",
        "    values_at_timestamp = []\n",
        "    for node in cas_data['data']['result']:\n",
        "        if i < len(node['values']):\n",
        "            values_at_timestamp.append(float(node['values'][i][1]))\n",
        "    cas_values.append(np.mean(values_at_timestamp))\n",
        "\n",
        "# Convert timestamps to minutes from start\n",
        "start_time = min(karpenter_timestamps[0], cas_timestamps[0])\n",
        "karpenter_times = [(t - start_time)/60 for t in karpenter_timestamps]\n",
        "cas_times = [(t - start_time)/60 for t in cas_timestamps]\n",
        "\n",
        "# Create the plot\n",
        "fig, ax = plt.subplots(figsize=(5, 3))\n",
        "ax.plot(cas_times, cas_values, label='CAS', linestyle='-', marker='o', markersize=3)\n",
        "ax.plot(karpenter_times, karpenter_values, label='Karpenter', linestyle='--', marker='x', markersize=3)\n",
        "\n",
        "ax.set_xlabel('Time (minutes)')\n",
        "ax.set_ylabel('CPU Usage (%)')\n",
        "ax.set_title('IBM CPU Utilization Over Time')\n",
        "ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.5), ncol=2)\n",
        "ax.grid(True)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.savefig('plots/ibm_cpu_utilization.png')\n",
        "plt.close()\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "metadata": {},
      "outputs": [],
      "source": [
        "plt.rcParams['figure.dpi'] = 1200\n",
        "\n",
        "# Load the data\n",
        "with open('ibm/homogenous/karpenter/NodeLatency.json', 'r') as f:\n",
        "    karpenter_data = json.load(f)\n",
        "with open('ibm/homogenous/cas/NodeLatency.json', 'r') as f:\n",
        "    cas_data = json.load(f)\n",
        "\n",
        "# Process Karpenter data\n",
        "karpenter_times = karpenter_data['data']['result'][0]['values']\n",
        "karpenter_timestamps = [float(val[0]) for val in karpenter_times]\n",
        "karpenter_values = []\n",
        "\n",
        "# For each timestamp, calculate average across all nodes\n",
        "for i in range(len(karpenter_timestamps)):\n",
        "    values_at_timestamp = []\n",
        "    for node in karpenter_data['data']['result']:\n",
        "        if i < len(node['values']):\n",
        "            values_at_timestamp.append(float(node['values'][i][1]))\n",
        "    karpenter_values.append(np.mean(values_at_timestamp))\n",
        "\n",
        "# Process CAS data\n",
        "cas_times = cas_data['data']['result'][0]['values']\n",
        "cas_timestamps = [float(val[0]) for val in cas_times]\n",
        "cas_values = []\n",
        "\n",
        "# For each timestamp, calculate average across all nodes\n",
        "for i in range(len(cas_timestamps)):\n",
        "    values_at_timestamp = []\n",
        "    for node in cas_data['data']['result']:\n",
        "        if i < len(node['values']):\n",
        "            values_at_timestamp.append(float(node['values'][i][1]))\n",
        "    cas_values.append(np.mean(values_at_timestamp))\n",
        "\n",
        "# Convert timestamps to minutes from start\n",
        "start_time = min(karpenter_timestamps[0], cas_timestamps[0])\n",
        "karpenter_times = [(t - start_time)/60 for t in karpenter_timestamps]\n",
        "cas_times = [(t - start_time)/60 for t in cas_timestamps]\n",
        "\n",
        "# Create the plot\n",
        "fig, ax = plt.subplots(figsize=(5, 3))\n",
        "ax.plot(cas_times, cas_values, label='CAS', linestyle='-', marker='o', markersize=3)\n",
        "ax.plot(karpenter_times, karpenter_values, label='Karpenter', linestyle='--', marker='x', markersize=3)\n",
        "\n",
        "ax.set_xlabel('Time (minutes)')\n",
        "ax.set_ylabel('Node Latency (ms)')\n",
        "ax.set_title('IBM Node Latency Over Time')\n",
        "ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.5), ncol=2)\n",
        "ax.grid(True)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.savefig('plots/ibm_node_latency.png')\n",
        "plt.close()\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "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.20"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}
