Refactor visulization code to python module
This commit is contained in:
parent
b8680f8c07
commit
6b7fca23b1
@ -17,7 +17,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"execution_count": 1,
|
||||
"id": "setup-imports",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@ -26,12 +26,12 @@
|
||||
"from lockdrop_calculations import (\n",
|
||||
" configure_matplotlib, print_constants_summary, calculate_dynamic_allocations,\n",
|
||||
" calculate_bonus_pools, calculate_final_allocations, generate_test_output,\n",
|
||||
" print_analysis_tables, create_visualization, PENALTY_RATES, NUM_STARS, NUM_GALAXIES\n",
|
||||
" print_analysis_tables, create_visualization, PENALTY_RATES, NUM_STARS, NUM_GALAXIES,\n",
|
||||
" create_experiment_widgets, create_calculate_function, create_scenario_loader, create_export_function\n",
|
||||
")\n",
|
||||
"import json\n",
|
||||
"from decimal import Decimal\n",
|
||||
"import pandas as pd\n",
|
||||
"import ipywidgets as widgets\n",
|
||||
"from IPython.display import display, clear_output\n",
|
||||
"\n",
|
||||
"# Configure matplotlib\n",
|
||||
@ -40,7 +40,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"execution_count": 2,
|
||||
"id": "show-constants",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@ -53,24 +53,41 @@
|
||||
"================================================================================\n",
|
||||
"\n",
|
||||
"🔒 LOCKDROP ALLOCATION\n",
|
||||
" Parameter Value\n",
|
||||
"Total Supply (1 $Z per Urbit ID) 4,294,967,296\n",
|
||||
" Lockdrop Allocation % 30.0%\n",
|
||||
" Lockdrop Allocation ($Z) 1,288,490,188.8\n",
|
||||
"+----------------------------------+-----------------+\n",
|
||||
"| Parameter | Value |\n",
|
||||
"+==================================+=================+\n",
|
||||
"| Total Supply (1 $Z per Urbit ID) | 4,294,967,296 |\n",
|
||||
"+----------------------------------+-----------------+\n",
|
||||
"| Lockdrop Allocation % | 30.0% |\n",
|
||||
"+----------------------------------+-----------------+\n",
|
||||
"| Lockdrop Allocation ($Z) | 1,288,490,188.8 |\n",
|
||||
"+----------------------------------+-----------------+\n",
|
||||
"\n",
|
||||
"⭐ URBIT POINTS DISTRIBUTION\n",
|
||||
"Point Type Count Allocation %\n",
|
||||
" Galaxies 256 0.39%\n",
|
||||
" Stars 65,280 99.61%\n",
|
||||
" Planets 4,294,901,760 0%\n",
|
||||
"+--------------+---------------+----------------+\n",
|
||||
"| Point Type | Count | Allocation % |\n",
|
||||
"+==============+===============+================+\n",
|
||||
"| Galaxies | 256 | 0.39% |\n",
|
||||
"+--------------+---------------+----------------+\n",
|
||||
"| Stars | 65,280 | 99.61% |\n",
|
||||
"+--------------+---------------+----------------+\n",
|
||||
"| Planets | 4,294,901,760 | 0% |\n",
|
||||
"+--------------+---------------+----------------+\n",
|
||||
"\n",
|
||||
"⏱️ LOCKDROP PARAMETERS\n",
|
||||
" Parameter Value\n",
|
||||
" Block Duration 2 seconds\n",
|
||||
"Max Point Lock Duration (5 yrs) 157,788,000 seconds\n",
|
||||
" Total Blocks 78,894,000\n",
|
||||
" Star Allocation % 0.996093\n",
|
||||
" Galaxy Allocation % 0.003906\n",
|
||||
"+---------------------------------+---------------------+\n",
|
||||
"| Parameter | Value |\n",
|
||||
"+=================================+=====================+\n",
|
||||
"| Block Duration | 2 seconds |\n",
|
||||
"+---------------------------------+---------------------+\n",
|
||||
"| Max Point Lock Duration (5 yrs) | 157,788,000 seconds |\n",
|
||||
"+---------------------------------+---------------------+\n",
|
||||
"| Total Blocks | 78,894,000 |\n",
|
||||
"+---------------------------------+---------------------+\n",
|
||||
"| Star Allocation % | 99.609375% |\n",
|
||||
"+---------------------------------+---------------------+\n",
|
||||
"| Galaxy Allocation % | 0.390625% |\n",
|
||||
"+---------------------------------+---------------------+\n",
|
||||
"\n",
|
||||
"================================================================================\n"
|
||||
]
|
||||
@ -93,7 +110,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"execution_count": 3,
|
||||
"id": "input-parameters",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@ -101,6 +118,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"==================================================\n",
|
||||
"🎯 PARTICIPATION INPUT CONTROLS\n",
|
||||
"==================================================\n",
|
||||
"\n",
|
||||
@ -110,7 +128,7 @@
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "79244d07df4e4ee6923dda69c1febc2e",
|
||||
"model_id": "75120f519bd64aeb88163fdfb2f9aaed",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
@ -132,7 +150,7 @@
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "4071b25411c44a67b26f5924a2507c0c",
|
||||
"model_id": "83e348a914854ce0a4b3e75c58ecc94e",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
@ -146,7 +164,7 @@
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "1c785fe3828d4d5eb62a9f35755f29f8",
|
||||
"model_id": "d851d648f30247e2b98b4bd57a101562",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
@ -157,18 +175,10 @@
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"🌌 CALCULATIONS\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "bc3937e163a34ff58f215f94a36aee3e",
|
||||
"model_id": "39b0b853b4bb4971b0ebbaa2fcd2e8e0",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
@ -181,159 +191,38 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Define reasonable default values\n",
|
||||
"DEFAULT_PARTICIPANTS = {\n",
|
||||
" 'stars_1_years': 8000,\n",
|
||||
" 'stars_2_years': 8000,\n",
|
||||
" 'stars_3_years': 8000,\n",
|
||||
" 'stars_4_years': 8000,\n",
|
||||
" 'stars_5_years': 8000,\n",
|
||||
" 'galaxies_1_years': 40,\n",
|
||||
" 'galaxies_2_years': 40,\n",
|
||||
" 'galaxies_3_years': 40,\n",
|
||||
" 'galaxies_4_years': 40,\n",
|
||||
" 'galaxies_5_years': 40\n",
|
||||
"}\n",
|
||||
"# Create experiment widgets using refactored function\n",
|
||||
"widget_dict = create_experiment_widgets()\n",
|
||||
"\n",
|
||||
"# Create input widgets\n",
|
||||
"# Display widgets\n",
|
||||
"print(\"🎯 PARTICIPATION INPUT CONTROLS\")\n",
|
||||
"print(\"=\"*50)\n",
|
||||
"\n",
|
||||
"# Star participation widgets\n",
|
||||
"print(\"\\n⭐ STAR PARTICIPATION\")\n",
|
||||
"stars_1_years = widgets.IntText(value=DEFAULT_PARTICIPANTS['stars_1_years'], description='1 Year:', style={'description_width': '80px'})\n",
|
||||
"stars_2_years = widgets.IntText(value=DEFAULT_PARTICIPANTS['stars_2_years'], description='2 Years:', style={'description_width': '80px'})\n",
|
||||
"stars_3_years = widgets.IntText(value=DEFAULT_PARTICIPANTS['stars_3_years'], description='3 Years:', style={'description_width': '80px'})\n",
|
||||
"stars_4_years = widgets.IntText(value=DEFAULT_PARTICIPANTS['stars_4_years'], description='4 Years:', style={'description_width': '80px'})\n",
|
||||
"stars_5_years = widgets.IntText(value=DEFAULT_PARTICIPANTS['stars_5_years'], description='5 Years:', style={'description_width': '80px'})\n",
|
||||
"\n",
|
||||
"star_controls = widgets.VBox([stars_1_years, stars_2_years, stars_3_years, stars_4_years, stars_5_years])\n",
|
||||
"display(star_controls)\n",
|
||||
"display(widget_dict['star_controls'])\n",
|
||||
"\n",
|
||||
"print(\"\\n🌌 GALAXY PARTICIPATION\")\n",
|
||||
"galaxies_1_years = widgets.IntText(value=DEFAULT_PARTICIPANTS['galaxies_1_years'], description='1 Year:', style={'description_width': '80px'})\n",
|
||||
"galaxies_2_years = widgets.IntText(value=DEFAULT_PARTICIPANTS['galaxies_2_years'], description='2 Years:', style={'description_width': '80px'})\n",
|
||||
"galaxies_3_years = widgets.IntText(value=DEFAULT_PARTICIPANTS['galaxies_3_years'], description='3 Years:', style={'description_width': '80px'})\n",
|
||||
"galaxies_4_years = widgets.IntText(value=DEFAULT_PARTICIPANTS['galaxies_4_years'], description='4 Years:', style={'description_width': '80px'})\n",
|
||||
"galaxies_5_years = widgets.IntText(value=DEFAULT_PARTICIPANTS['galaxies_5_years'], description='5 Years:', style={'description_width': '80px'})\n",
|
||||
"\n",
|
||||
"galaxy_controls = widgets.VBox([galaxies_1_years, galaxies_2_years, galaxies_3_years, galaxies_4_years, galaxies_5_years])\n",
|
||||
"display(galaxy_controls)\n",
|
||||
"display(widget_dict['galaxy_controls'])\n",
|
||||
"\n",
|
||||
"# Calculate button\n",
|
||||
"calculate_button = widgets.Button(description='🔄 Calculate Allocations', button_style='success', layout={'width': '200px', 'margin': '20px 0'})\n",
|
||||
"display(calculate_button)\n",
|
||||
"display(widget_dict['calculate_button'])\n",
|
||||
"\n",
|
||||
"# Output area\n",
|
||||
"print(\"\\n🌌 CALCULATIONS\")\n",
|
||||
"output_area = widgets.Output()\n",
|
||||
"display(output_area)"
|
||||
"display(widget_dict['output_area'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"execution_count": 4,
|
||||
"id": "calculation-function",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def calculate_and_display(button=None):\n",
|
||||
" \"\"\"Calculate allocations and display results based on input parameters.\"\"\"\n",
|
||||
" with output_area:\n",
|
||||
" clear_output(wait=True)\n",
|
||||
"\n",
|
||||
" # Get current values from widgets\n",
|
||||
" participation_counts = {\n",
|
||||
" 'stars_1_years': stars_1_years.value,\n",
|
||||
" 'stars_2_years': stars_2_years.value,\n",
|
||||
" 'stars_3_years': stars_3_years.value,\n",
|
||||
" 'stars_4_years': stars_4_years.value,\n",
|
||||
" 'stars_5_years': stars_5_years.value,\n",
|
||||
" 'galaxies_1_years': galaxies_1_years.value,\n",
|
||||
" 'galaxies_2_years': galaxies_2_years.value,\n",
|
||||
" 'galaxies_3_years': galaxies_3_years.value,\n",
|
||||
" 'galaxies_4_years': galaxies_4_years.value,\n",
|
||||
" 'galaxies_5_years': galaxies_5_years.value\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" # Validate inputs\n",
|
||||
" total_stars = sum(participation_counts[key] for key in participation_counts if 'stars' in key)\n",
|
||||
" total_galaxies = sum(participation_counts[key] for key in participation_counts if 'galaxies' in key)\n",
|
||||
"\n",
|
||||
" if total_stars > NUM_STARS:\n",
|
||||
" print(f\"⚠️ ERROR: Total stars ({total_stars:,}) exceeds maximum available ({NUM_STARS:,})\")\n",
|
||||
" return\n",
|
||||
"\n",
|
||||
" if total_galaxies > NUM_GALAXIES:\n",
|
||||
" print(f\"⚠️ ERROR: Total galaxies ({total_galaxies:,}) exceeds maximum available ({NUM_GALAXIES:,})\")\n",
|
||||
" return\n",
|
||||
"\n",
|
||||
" if total_stars == 0 and total_galaxies == 0:\n",
|
||||
" print(\"⚠️ ERROR: Must have at least some participants\")\n",
|
||||
" return\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" # Perform calculations\n",
|
||||
" print(\"🔄 Calculating allocations...\\n\")\n",
|
||||
"\n",
|
||||
" allocation_data = calculate_dynamic_allocations(participation_counts)\n",
|
||||
" bonus_data = calculate_bonus_pools(allocation_data)\n",
|
||||
" final_data = calculate_final_allocations(allocation_data, bonus_data)\n",
|
||||
"\n",
|
||||
" # Display results\n",
|
||||
" print_analysis_tables(allocation_data, bonus_data, final_data)\n",
|
||||
"\n",
|
||||
" # Show penalty rates for reference\n",
|
||||
" print(\"\\n📋 PENALTY SYSTEM REFERENCE\")\n",
|
||||
" penalty_df = pd.DataFrame({\n",
|
||||
" 'Lock Period': ['5 Years', '4 Years', '3 Years', '2 Years', '1 Year'],\n",
|
||||
" 'Penalty Rate': [f\"{PENALTY_RATES[year]:.1%}\" for year in [5, 4, 3, 2, 1]],\n",
|
||||
" 'Description': ['No penalty + Bonus', '20% penalty', '40% penalty', '60% penalty', '80% penalty']\n",
|
||||
" })\n",
|
||||
" print(penalty_df.to_string(index=False))\n",
|
||||
"\n",
|
||||
" # Create visualization\n",
|
||||
" print(\"\\n📊 Generating visualization...\")\n",
|
||||
" create_visualization(allocation_data, final_data)\n",
|
||||
"\n",
|
||||
" # Calculate participation insights\n",
|
||||
" star_participation_rate = Decimal(total_stars) / NUM_STARS\n",
|
||||
" galaxy_participation_rate = Decimal(total_galaxies) / NUM_GALAXIES\n",
|
||||
"\n",
|
||||
" print(\"\\n\" + \"=\"*80)\n",
|
||||
" print(\"🎯 EXPERIMENT INSIGHTS\")\n",
|
||||
" print(\"=\"*80)\n",
|
||||
"\n",
|
||||
" insights_df = pd.DataFrame({\n",
|
||||
" 'Metric': [\n",
|
||||
" 'Total Participants',\n",
|
||||
" 'Star Participation Rate',\n",
|
||||
" 'Galaxy Participation Rate',\n",
|
||||
" '5-Year Star Bonus',\n",
|
||||
" '5-Year Galaxy Bonus',\n",
|
||||
" 'Highest Individual Allocation',\n",
|
||||
" 'Lowest Individual Allocation'\n",
|
||||
" ],\n",
|
||||
" 'Value': [\n",
|
||||
" f\"{total_stars + total_galaxies:,}\",\n",
|
||||
" f\"{star_participation_rate:.1%}\",\n",
|
||||
" f\"{galaxy_participation_rate:.1%}\",\n",
|
||||
" f\"{float(bonus_data['bonus_per_star_5_years']):,.2f} $Z\" if participation_counts['stars_5_years'] > 0 else \"N/A (no 5Y stars)\",\n",
|
||||
" f\"{float(bonus_data['bonus_per_galaxy_5_years']):,.2f} $Z\" if participation_counts['galaxies_5_years'] > 0 else \"N/A (no 5Y galaxies)\",\n",
|
||||
" f\"{max(float(final_data['final_star_allocations'][5]), float(final_data['final_galaxy_allocations'][5])):,.2f} $Z\",\n",
|
||||
" f\"{min(float(final_data['final_star_allocations'][1]), float(final_data['final_galaxy_allocations'][1])):,.2f} $Z\"\n",
|
||||
" ]\n",
|
||||
" })\n",
|
||||
" print(insights_df.to_string(index=False))\n",
|
||||
" print(\"\\n\" + \"=\"*80)\n",
|
||||
"\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"❌ Error during calculation: {str(e)}\")\n",
|
||||
" import traceback\n",
|
||||
" traceback.print_exc()\n",
|
||||
"# Create calculation function using refactored approach\n",
|
||||
"calculate_and_display = create_calculate_function(widget_dict)\n",
|
||||
"\n",
|
||||
"# Connect button to calculation function\n",
|
||||
"calculate_button.on_click(calculate_and_display)"
|
||||
"widget_dict['calculate_button'].on_click(calculate_and_display)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -348,7 +237,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"execution_count": 5,
|
||||
"id": "preset-scenarios",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@ -376,75 +265,23 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Define preset scenarios\n",
|
||||
"SCENARIOS = {\n",
|
||||
" 'balanced': {\n",
|
||||
" 'description': 'Balanced distribution across all lock periods',\n",
|
||||
" 'params': {\n",
|
||||
" 'stars_1_years': 8000, 'stars_2_years': 8000, 'stars_3_years': 8000, 'stars_4_years': 8000, 'stars_5_years': 8000,\n",
|
||||
" 'galaxies_1_years': 40, 'galaxies_2_years': 40, 'galaxies_3_years': 40, 'galaxies_4_years': 40, 'galaxies_5_years': 40\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" 'five_year_focused': {\n",
|
||||
" 'description': 'Most participants choose 5-year lock (maximum bonus scenario)',\n",
|
||||
" 'params': {\n",
|
||||
" 'stars_1_years': 2000, 'stars_2_years': 2000, 'stars_3_years': 3000, 'stars_4_years': 5000, 'stars_5_years': 28000,\n",
|
||||
" 'galaxies_1_years': 10, 'galaxies_2_years': 10, 'galaxies_3_years': 20, 'galaxies_4_years': 30, 'galaxies_5_years': 130\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" 'short_term_focused': {\n",
|
||||
" 'description': 'Most participants choose shorter locks (high penalty scenario)',\n",
|
||||
" 'params': {\n",
|
||||
" 'stars_1_years': 20000, 'stars_2_years': 15000, 'stars_3_years': 4000, 'stars_4_years': 800, 'stars_5_years': 200,\n",
|
||||
" 'galaxies_1_years': 100, 'galaxies_2_years': 80, 'galaxies_3_years': 15, 'galaxies_4_years': 3, 'galaxies_5_years': 2\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" 'polarized': {\n",
|
||||
" 'description': 'Split between 1-year and 5-year locks (maximum bonus per 5Y participant)',\n",
|
||||
" 'params': {\n",
|
||||
" 'stars_1_years': 25000, 'stars_2_years': 0, 'stars_3_years': 0, 'stars_4_years': 0, 'stars_5_years': 15000,\n",
|
||||
" 'galaxies_1_years': 150, 'galaxies_2_years': 0, 'galaxies_3_years': 0, 'galaxies_4_years': 0, 'galaxies_5_years': 50\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" 'low_participation': {\n",
|
||||
" 'description': 'Low overall participation scenario',\n",
|
||||
" 'params': {\n",
|
||||
" 'stars_1_years': 1000, 'stars_2_years': 800, 'stars_3_years': 600, 'stars_4_years': 400, 'stars_5_years': 200,\n",
|
||||
" 'galaxies_1_years': 8, 'galaxies_2_years': 6, 'galaxies_3_years': 4, 'galaxies_4_years': 2, 'galaxies_5_years': 5\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"def load_scenario(scenario_name):\n",
|
||||
" \"\"\"Load a preset scenario into the input widgets.\"\"\"\n",
|
||||
" if scenario_name not in SCENARIOS:\n",
|
||||
" print(f\"❌ Unknown scenario: {scenario_name}\")\n",
|
||||
" return\n",
|
||||
"\n",
|
||||
" scenario = SCENARIOS[scenario_name]\n",
|
||||
" params = scenario['params']\n",
|
||||
"\n",
|
||||
" # Update widget values\n",
|
||||
" stars_1_years.value = params['stars_1_years']\n",
|
||||
" stars_2_years.value = params['stars_2_years']\n",
|
||||
" stars_3_years.value = params['stars_3_years']\n",
|
||||
" stars_4_years.value = params['stars_4_years']\n",
|
||||
" stars_5_years.value = params['stars_5_years']\n",
|
||||
" galaxies_1_years.value = params['galaxies_1_years']\n",
|
||||
" galaxies_2_years.value = params['galaxies_2_years']\n",
|
||||
" galaxies_3_years.value = params['galaxies_3_years']\n",
|
||||
" galaxies_4_years.value = params['galaxies_4_years']\n",
|
||||
" galaxies_5_years.value = params['galaxies_5_years']\n",
|
||||
"\n",
|
||||
" print(f\"✅ Loaded scenario: {scenario_name}\")\n",
|
||||
" print(f\"📝 Description: {scenario['description']}\")\n",
|
||||
" print(\"\\n🔄 Click 'Calculate Allocations' button above to see results!\")\n",
|
||||
"# Create scenario loader using refactored function\n",
|
||||
"load_scenario = create_scenario_loader(widget_dict)\n",
|
||||
"\n",
|
||||
"# Display available scenarios\n",
|
||||
"print(\"📋 AVAILABLE PRESET SCENARIOS:\")\n",
|
||||
"print(\"=\"*50)\n",
|
||||
"for name, scenario in SCENARIOS.items():\n",
|
||||
" print(f\"\\n• {name}: {scenario['description']}\")\n",
|
||||
"\n",
|
||||
"scenarios = {\n",
|
||||
" 'balanced': 'Balanced distribution across all lock periods',\n",
|
||||
" 'five_year_focused': 'Most participants choose 5-year lock (maximum bonus scenario)',\n",
|
||||
" 'short_term_focused': 'Most participants choose shorter locks (high penalty scenario)',\n",
|
||||
" 'polarized': 'Split between 1-year and 5-year locks (maximum bonus per 5Y participant)',\n",
|
||||
" 'low_participation': 'Low overall participation scenario'\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"for name, description in scenarios.items():\n",
|
||||
" print(f\"\\n• {name}: {description}\")\n",
|
||||
"\n",
|
||||
"print(\"\\n🎯 To load a scenario, call: load_scenario('scenario_name')\")\n",
|
||||
"print(\"\\nExample: load_scenario('five_year_focused')\")"
|
||||
@ -452,24 +289,13 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"execution_count": 6,
|
||||
"id": "load-scenario-example",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"✅ Loaded scenario: five_year_focused\n",
|
||||
"📝 Description: Most participants choose 5-year lock (maximum bonus scenario)\n",
|
||||
"\n",
|
||||
"🔄 Click 'Calculate Allocations' button above to see results!\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Load the balanced scenario as default\n",
|
||||
"load_scenario('five_year_focused')"
|
||||
"# load_scenario('short_term_focused')"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -479,12 +305,12 @@
|
||||
"source": [
|
||||
"## 💾 Export Results\n",
|
||||
"\n",
|
||||
"Export your experimental results for use with the test suite:"
|
||||
"Export your experimental results."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"execution_count": 7,
|
||||
"id": "export-results",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@ -501,50 +327,8 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def export_current_scenario(filename='lockdrop_allocations_experiment.json'):\n",
|
||||
" \"\"\"Export current scenario results to JSON file.\"\"\"\n",
|
||||
" # Get current values from widgets\n",
|
||||
" participation_counts = {\n",
|
||||
" 'stars_1_years': stars_1_years.value,\n",
|
||||
" 'stars_2_years': stars_2_years.value,\n",
|
||||
" 'stars_3_years': stars_3_years.value,\n",
|
||||
" 'stars_4_years': stars_4_years.value,\n",
|
||||
" 'stars_5_years': stars_5_years.value,\n",
|
||||
" 'galaxies_1_years': galaxies_1_years.value,\n",
|
||||
" 'galaxies_2_years': galaxies_2_years.value,\n",
|
||||
" 'galaxies_3_years': galaxies_3_years.value,\n",
|
||||
" 'galaxies_4_years': galaxies_4_years.value,\n",
|
||||
" 'galaxies_5_years': galaxies_5_years.value\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" # Calculate allocations\n",
|
||||
" allocation_data = calculate_dynamic_allocations(participation_counts)\n",
|
||||
" bonus_data = calculate_bonus_pools(allocation_data)\n",
|
||||
" final_data = calculate_final_allocations(allocation_data, bonus_data)\n",
|
||||
"\n",
|
||||
" # Generate test output\n",
|
||||
" test_output = generate_test_output(final_data)\n",
|
||||
"\n",
|
||||
" # Add metadata\n",
|
||||
" export_data = {\n",
|
||||
" 'metadata': {\n",
|
||||
" 'source': 'lockdrop-experiment.ipynb',\n",
|
||||
" 'scenario': 'custom',\n",
|
||||
" 'participation_counts': participation_counts\n",
|
||||
" },\n",
|
||||
" 'allocations': test_output\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" # Save to file\n",
|
||||
" with open(filename, 'w') as f:\n",
|
||||
" json.dump(export_data, f, indent=2)\n",
|
||||
"\n",
|
||||
" print(f\"✅ Results exported to: {filename}\")\n",
|
||||
" print(f\"📊 Total participants: {sum(participation_counts.values()):,}\")\n",
|
||||
"\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"❌ Export failed: {str(e)}\")\n",
|
||||
"# Create export function using refactored approach\n",
|
||||
"export_current_scenario = create_export_function(widget_dict)\n",
|
||||
"\n",
|
||||
"# Usage example\n",
|
||||
"print(\"💾 Export your current scenario results:\")\n",
|
||||
@ -554,39 +338,20 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "tips-section",
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "3c93c9c2-9cec-4d2b-a2db-065602a3871c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"## 💡 Experimentation Tips\n",
|
||||
"\n",
|
||||
"### Interesting Things to Try:\n",
|
||||
"\n",
|
||||
"1. **Bonus Pool Impact**: Set most participants to 1-2 years and a few to 5 years to see massive bonuses\n",
|
||||
"2. **Participation Rate Effects**: Try very low participation vs. high participation scenarios\n",
|
||||
"3. **Star vs Galaxy Balance**: Experiment with different star/galaxy ratios\n",
|
||||
"4. **Edge Cases**: What happens with only 5-year participants? Only 1-year?\n",
|
||||
"5. **Realistic Scenarios**: Model expected real-world behavior patterns\n",
|
||||
"\n",
|
||||
"### Key Metrics to Watch:\n",
|
||||
"\n",
|
||||
"- **5-Year Bonus Multiplier**: How much extra do 5-year participants get?\n",
|
||||
"- **Participation Rates**: What percentage of each point type participates?\n",
|
||||
"- **Penalty Pool Size**: How much bonus is generated from penalties?\n",
|
||||
"- **Allocation Spread**: Difference between highest and lowest allocations\n",
|
||||
"\n",
|
||||
"### Understanding the Math:\n",
|
||||
"\n",
|
||||
"- Penalties from shorter lock periods create bonus pools\n",
|
||||
"- All bonus pools go to 5-year participants\n",
|
||||
"- More penalty = more bonus for 5-year participants\n",
|
||||
"- Lower participation = higher individual allocations"
|
||||
"# Export allocation results from the experiment\n",
|
||||
"# export_current_scenario(\"lockdrop_allocations_experiment.json\")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "venv",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
|
||||
@ -509,8 +509,8 @@ def print_final_allocations_and_verification(allocation_data, final_data):
|
||||
star_final_df = pd.DataFrame({
|
||||
'Lock Period': ['5 Years', '4 Years', '3 Years', '2 Years', '1 Year'],
|
||||
'Penalty': [f"{PENALTY_RATES[year]:.1%}" for year in [5, 4, 3, 2, 1]],
|
||||
'Final Allocation ($Z)': [f"{final_star_allocations[year]:.12f}" for year in [5, 4, 3, 2, 1]],
|
||||
'Z per Block': [f"{star_z_per_block[year]:.12f}" for year in [5, 4, 3, 2, 1]],
|
||||
'Final Allocation ($Z)': [f"{final_star_allocations[year]:.8f}" for year in [5, 4, 3, 2, 1]],
|
||||
'Z per Block': [f"{star_z_per_block[year]:.8f}" for year in [5, 4, 3, 2, 1]],
|
||||
'Participants': [f"{stars_counts[year]:,}" for year in [5, 4, 3, 2, 1]]
|
||||
})
|
||||
print_table_with_borders(star_final_df, "⭐ FINAL STAR ALLOCATIONS")
|
||||
@ -519,8 +519,8 @@ def print_final_allocations_and_verification(allocation_data, final_data):
|
||||
galaxy_final_df = pd.DataFrame({
|
||||
'Lock Period': ['5 Years', '4 Years', '3 Years', '2 Years', '1 Year'],
|
||||
'Penalty': [f"{PENALTY_RATES[year]:.1%}" for year in [5, 4, 3, 2, 1]],
|
||||
'Final Allocation ($Z)': [f"{final_galaxy_allocations[year]:.12f}" for year in [5, 4, 3, 2, 1]],
|
||||
'Z per Block': [f"{galaxy_z_per_block[year]:.12f}" for year in [5, 4, 3, 2, 1]],
|
||||
'Final Allocation ($Z)': [f"{final_galaxy_allocations[year]:.8f}" for year in [5, 4, 3, 2, 1]],
|
||||
'Z per Block': [f"{galaxy_z_per_block[year]:.8f}" for year in [5, 4, 3, 2, 1]],
|
||||
'Participants': [f"{galaxies_counts[year]:,}" for year in [5, 4, 3, 2, 1]]
|
||||
})
|
||||
print_table_with_borders(galaxy_final_df, "🌌 FINAL GALAXY ALLOCATIONS")
|
||||
@ -534,14 +534,15 @@ def print_final_allocations_and_verification(allocation_data, final_data):
|
||||
|
||||
verification_df = pd.DataFrame({
|
||||
'Category': ['Star Allocations', 'Galaxy Allocations', 'Combined'],
|
||||
'Calculated Total': [f"{total_stars_allocation:.12f} $Z", f"{total_galaxies_allocation:.12f} $Z",
|
||||
f"{total_stars_allocation + total_galaxies_allocation:.12f} $Z"],
|
||||
'Expected Total': [f"{lockdrop_allocation_stars:.12f} $Z", f"{lockdrop_allocation_galaxies:.12f} $Z",
|
||||
f"{LOCKDROP_ALLOCATION:.12f} $Z"],
|
||||
'Rounding Error': [f"{final_rounding_error_stars:.12f} $Z", f"{final_rounding_error_galaxies:.12f} $Z",
|
||||
f"{final_rounding_error:.12f} $Z"]
|
||||
'Calculated Total': [f"{total_stars_allocation:.8f} $Z", f"{total_galaxies_allocation:.8f} $Z",
|
||||
f"{total_stars_allocation + total_galaxies_allocation:.8f} $Z"],
|
||||
'Expected Total': [f"{lockdrop_allocation_stars:.8f} $Z", f"{lockdrop_allocation_galaxies:.8f} $Z",
|
||||
f"{LOCKDROP_ALLOCATION:.8f} $Z"],
|
||||
'Rounding Error': [f"{final_rounding_error_stars:.8f} $Z", f"{final_rounding_error_galaxies:.8f} $Z",
|
||||
f"{final_rounding_error:.8f} $Z"]
|
||||
})
|
||||
print_table_with_borders(verification_df, "🔍 ALLOCATION VERIFICATION")
|
||||
print("\n📝 NOTE: Final rounding errors go to Zenith Foundation")
|
||||
print("\n" + "="*80)
|
||||
|
||||
|
||||
@ -685,3 +686,297 @@ def load_watcher_events_data(generated_dir='generated'):
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error loading watcher events: {e}")
|
||||
return None, False
|
||||
|
||||
|
||||
# Experimental notebook widget and interaction functions
|
||||
def create_experiment_widgets():
|
||||
"""Create input widgets for the experimental notebook."""
|
||||
try:
|
||||
import ipywidgets as widgets
|
||||
except ImportError:
|
||||
raise ImportError("ipywidgets is required for the experimental interface. Install with: pip install ipywidgets")
|
||||
|
||||
# Define reasonable default values
|
||||
default_participants = {
|
||||
'stars_1_years': 8000,
|
||||
'stars_2_years': 8000,
|
||||
'stars_3_years': 8000,
|
||||
'stars_4_years': 8000,
|
||||
'stars_5_years': 8000,
|
||||
'galaxies_1_years': 40,
|
||||
'galaxies_2_years': 40,
|
||||
'galaxies_3_years': 40,
|
||||
'galaxies_4_years': 40,
|
||||
'galaxies_5_years': 40
|
||||
}
|
||||
|
||||
# Create input widgets
|
||||
print("="*50)
|
||||
|
||||
# Star participation widgets
|
||||
stars_1_years = widgets.IntText(value=default_participants['stars_1_years'], description='1 Year:', style={'description_width': '80px'})
|
||||
stars_2_years = widgets.IntText(value=default_participants['stars_2_years'], description='2 Years:', style={'description_width': '80px'})
|
||||
stars_3_years = widgets.IntText(value=default_participants['stars_3_years'], description='3 Years:', style={'description_width': '80px'})
|
||||
stars_4_years = widgets.IntText(value=default_participants['stars_4_years'], description='4 Years:', style={'description_width': '80px'})
|
||||
stars_5_years = widgets.IntText(value=default_participants['stars_5_years'], description='5 Years:', style={'description_width': '80px'})
|
||||
|
||||
star_controls = widgets.VBox([stars_1_years, stars_2_years, stars_3_years, stars_4_years, stars_5_years])
|
||||
|
||||
galaxies_1_years = widgets.IntText(value=default_participants['galaxies_1_years'], description='1 Year:', style={'description_width': '80px'})
|
||||
galaxies_2_years = widgets.IntText(value=default_participants['galaxies_2_years'], description='2 Years:', style={'description_width': '80px'})
|
||||
galaxies_3_years = widgets.IntText(value=default_participants['galaxies_3_years'], description='3 Years:', style={'description_width': '80px'})
|
||||
galaxies_4_years = widgets.IntText(value=default_participants['galaxies_4_years'], description='4 Years:', style={'description_width': '80px'})
|
||||
galaxies_5_years = widgets.IntText(value=default_participants['galaxies_5_years'], description='5 Years:', style={'description_width': '80px'})
|
||||
|
||||
galaxy_controls = widgets.VBox([galaxies_1_years, galaxies_2_years, galaxies_3_years, galaxies_4_years, galaxies_5_years])
|
||||
|
||||
# Calculate button
|
||||
calculate_button = widgets.Button(description='🔄 Calculate Allocations', button_style='success', layout={'width': '200px', 'margin': '20px 0'})
|
||||
|
||||
# Output area
|
||||
output_area = widgets.Output()
|
||||
|
||||
# Return all widgets as a dictionary
|
||||
return {
|
||||
'star_controls': star_controls,
|
||||
'galaxy_controls': galaxy_controls,
|
||||
'calculate_button': calculate_button,
|
||||
'output_area': output_area,
|
||||
'widgets': {
|
||||
'stars_1_years': stars_1_years,
|
||||
'stars_2_years': stars_2_years,
|
||||
'stars_3_years': stars_3_years,
|
||||
'stars_4_years': stars_4_years,
|
||||
'stars_5_years': stars_5_years,
|
||||
'galaxies_1_years': galaxies_1_years,
|
||||
'galaxies_2_years': galaxies_2_years,
|
||||
'galaxies_3_years': galaxies_3_years,
|
||||
'galaxies_4_years': galaxies_4_years,
|
||||
'galaxies_5_years': galaxies_5_years
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def create_calculate_function(widget_dict):
|
||||
"""Create the calculation and display function for the experimental notebook."""
|
||||
def calculate_and_display(button=None):
|
||||
"""Calculate allocations and display results based on input parameters."""
|
||||
try:
|
||||
from IPython.display import clear_output
|
||||
except ImportError:
|
||||
raise ImportError("IPython is required for the experimental interface")
|
||||
|
||||
widgets_map = widget_dict['widgets']
|
||||
output_area = widget_dict['output_area']
|
||||
|
||||
with output_area:
|
||||
clear_output(wait=True)
|
||||
|
||||
# Get current values from widgets
|
||||
participation_counts = {
|
||||
'stars_1_years': widgets_map['stars_1_years'].value,
|
||||
'stars_2_years': widgets_map['stars_2_years'].value,
|
||||
'stars_3_years': widgets_map['stars_3_years'].value,
|
||||
'stars_4_years': widgets_map['stars_4_years'].value,
|
||||
'stars_5_years': widgets_map['stars_5_years'].value,
|
||||
'galaxies_1_years': widgets_map['galaxies_1_years'].value,
|
||||
'galaxies_2_years': widgets_map['galaxies_2_years'].value,
|
||||
'galaxies_3_years': widgets_map['galaxies_3_years'].value,
|
||||
'galaxies_4_years': widgets_map['galaxies_4_years'].value,
|
||||
'galaxies_5_years': widgets_map['galaxies_5_years'].value
|
||||
}
|
||||
|
||||
# Validate inputs
|
||||
total_stars = sum(participation_counts[key] for key in participation_counts if 'stars' in key)
|
||||
total_galaxies = sum(participation_counts[key] for key in participation_counts if 'galaxies' in key)
|
||||
|
||||
if total_stars > NUM_STARS:
|
||||
print(f"⚠️ ERROR: Total stars ({total_stars:,}) exceeds maximum available ({NUM_STARS:,})")
|
||||
return
|
||||
|
||||
if total_galaxies > NUM_GALAXIES:
|
||||
print(f"⚠️ ERROR: Total galaxies ({total_galaxies:,}) exceeds maximum available ({NUM_GALAXIES:,})")
|
||||
return
|
||||
|
||||
if total_stars == 0 and total_galaxies == 0:
|
||||
print("⚠️ ERROR: Must have at least some participants")
|
||||
return
|
||||
|
||||
try:
|
||||
# Perform calculations
|
||||
print("🔄 Calculating allocations...\n")
|
||||
|
||||
allocation_data = calculate_dynamic_allocations(participation_counts)
|
||||
bonus_data = calculate_bonus_pools(allocation_data)
|
||||
final_data = calculate_final_allocations(allocation_data, bonus_data)
|
||||
|
||||
# Display results
|
||||
print_analysis_tables(allocation_data, bonus_data, final_data)
|
||||
|
||||
# Create visualization
|
||||
print("\n📊 Generating visualization...")
|
||||
create_visualization(allocation_data, final_data)
|
||||
|
||||
# Calculate participation insights
|
||||
star_participation_rate = Decimal(total_stars) / NUM_STARS
|
||||
galaxy_participation_rate = Decimal(total_galaxies) / NUM_GALAXIES
|
||||
|
||||
print("\n" + "="*80)
|
||||
print("🎯 EXPERIMENT INSIGHTS")
|
||||
print("=" * 80)
|
||||
|
||||
insights_df = pd.DataFrame({
|
||||
'Metric': [
|
||||
'Total Participants',
|
||||
'Star Participation Rate',
|
||||
'Galaxy Participation Rate',
|
||||
'5-Year Star Bonus',
|
||||
'5-Year Galaxy Bonus',
|
||||
'Highest Individual Allocation',
|
||||
'Lowest Individual Allocation'
|
||||
],
|
||||
'Value': [
|
||||
f"{total_stars + total_galaxies:,}",
|
||||
f"{star_participation_rate:.1%}",
|
||||
f"{galaxy_participation_rate:.1%}",
|
||||
f"{float(bonus_data['bonus_per_star_5_years']):,.2f} $Z" if participation_counts['stars_5_years'] > 0 else "N/A (no 5Y stars)",
|
||||
f"{float(bonus_data['bonus_per_galaxy_5_years']):,.2f} $Z" if participation_counts['galaxies_5_years'] > 0 else "N/A (no 5Y galaxies)",
|
||||
f"{max(float(final_data['final_star_allocations'][5]), float(final_data['final_galaxy_allocations'][5])):,.2f} $Z",
|
||||
f"{min(float(final_data['final_star_allocations'][1]), float(final_data['final_galaxy_allocations'][1])):,.2f} $Z"
|
||||
]
|
||||
})
|
||||
print_table_with_borders(insights_df, "🎯 EXPERIMENT INSIGHTS")
|
||||
print("\n" + "="*80)
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error during calculation: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
return calculate_and_display
|
||||
|
||||
|
||||
def get_preset_scenarios():
|
||||
"""Get preset scenario definitions for experimentation."""
|
||||
return {
|
||||
'balanced': {
|
||||
'description': 'Balanced distribution across all lock periods',
|
||||
'params': {
|
||||
'stars_1_years': 8000, 'stars_2_years': 8000, 'stars_3_years': 8000, 'stars_4_years': 8000, 'stars_5_years': 8000,
|
||||
'galaxies_1_years': 40, 'galaxies_2_years': 40, 'galaxies_3_years': 40, 'galaxies_4_years': 40, 'galaxies_5_years': 40
|
||||
}
|
||||
},
|
||||
'five_year_focused': {
|
||||
'description': 'Most participants choose 5-year lock (maximum bonus scenario)',
|
||||
'params': {
|
||||
'stars_1_years': 2000, 'stars_2_years': 2000, 'stars_3_years': 3000, 'stars_4_years': 5000, 'stars_5_years': 28000,
|
||||
'galaxies_1_years': 10, 'galaxies_2_years': 10, 'galaxies_3_years': 20, 'galaxies_4_years': 30, 'galaxies_5_years': 130
|
||||
}
|
||||
},
|
||||
'short_term_focused': {
|
||||
'description': 'Most participants choose shorter locks (high penalty scenario)',
|
||||
'params': {
|
||||
'stars_1_years': 20000, 'stars_2_years': 15000, 'stars_3_years': 4000, 'stars_4_years': 800, 'stars_5_years': 200,
|
||||
'galaxies_1_years': 100, 'galaxies_2_years': 80, 'galaxies_3_years': 15, 'galaxies_4_years': 3, 'galaxies_5_years': 2
|
||||
}
|
||||
},
|
||||
'polarized': {
|
||||
'description': 'Split between 1-year and 5-year locks (maximum bonus per 5Y participant)',
|
||||
'params': {
|
||||
'stars_1_years': 25000, 'stars_2_years': 0, 'stars_3_years': 0, 'stars_4_years': 0, 'stars_5_years': 15000,
|
||||
'galaxies_1_years': 150, 'galaxies_2_years': 0, 'galaxies_3_years': 0, 'galaxies_4_years': 0, 'galaxies_5_years': 50
|
||||
}
|
||||
},
|
||||
'low_participation': {
|
||||
'description': 'Low overall participation scenario',
|
||||
'params': {
|
||||
'stars_1_years': 1000, 'stars_2_years': 800, 'stars_3_years': 600, 'stars_4_years': 400, 'stars_5_years': 200,
|
||||
'galaxies_1_years': 8, 'galaxies_2_years': 6, 'galaxies_3_years': 4, 'galaxies_4_years': 2, 'galaxies_5_years': 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def create_scenario_loader(widget_dict):
|
||||
"""Create scenario loading function for the experimental notebook."""
|
||||
def load_scenario(scenario_name):
|
||||
"""Load a preset scenario into the input widgets."""
|
||||
scenarios = get_preset_scenarios()
|
||||
|
||||
if scenario_name not in scenarios:
|
||||
print(f"❌ Unknown scenario: {scenario_name}")
|
||||
return
|
||||
|
||||
scenario = scenarios[scenario_name]
|
||||
params = scenario['params']
|
||||
widgets_map = widget_dict['widgets']
|
||||
|
||||
# Update widget values
|
||||
widgets_map['stars_1_years'].value = params['stars_1_years']
|
||||
widgets_map['stars_2_years'].value = params['stars_2_years']
|
||||
widgets_map['stars_3_years'].value = params['stars_3_years']
|
||||
widgets_map['stars_4_years'].value = params['stars_4_years']
|
||||
widgets_map['stars_5_years'].value = params['stars_5_years']
|
||||
widgets_map['galaxies_1_years'].value = params['galaxies_1_years']
|
||||
widgets_map['galaxies_2_years'].value = params['galaxies_2_years']
|
||||
widgets_map['galaxies_3_years'].value = params['galaxies_3_years']
|
||||
widgets_map['galaxies_4_years'].value = params['galaxies_4_years']
|
||||
widgets_map['galaxies_5_years'].value = params['galaxies_5_years']
|
||||
|
||||
print(f"✅ Loaded scenario: {scenario_name}")
|
||||
print(f"📝 Description: {scenario['description']}")
|
||||
print("\n🔄 Click 'Calculate Allocations' button above to see results!")
|
||||
|
||||
return load_scenario
|
||||
|
||||
|
||||
def create_export_function(widget_dict):
|
||||
"""Create export function for the experimental notebook."""
|
||||
def export_current_scenario(filename='lockdrop_allocations_experiment.json'):
|
||||
"""Export current scenario results to JSON file."""
|
||||
widgets_map = widget_dict['widgets']
|
||||
|
||||
# Get current values from widgets
|
||||
participation_counts = {
|
||||
'stars_1_years': widgets_map['stars_1_years'].value,
|
||||
'stars_2_years': widgets_map['stars_2_years'].value,
|
||||
'stars_3_years': widgets_map['stars_3_years'].value,
|
||||
'stars_4_years': widgets_map['stars_4_years'].value,
|
||||
'stars_5_years': widgets_map['stars_5_years'].value,
|
||||
'galaxies_1_years': widgets_map['galaxies_1_years'].value,
|
||||
'galaxies_2_years': widgets_map['galaxies_2_years'].value,
|
||||
'galaxies_3_years': widgets_map['galaxies_3_years'].value,
|
||||
'galaxies_4_years': widgets_map['galaxies_4_years'].value,
|
||||
'galaxies_5_years': widgets_map['galaxies_5_years'].value
|
||||
}
|
||||
|
||||
try:
|
||||
# Calculate allocations
|
||||
allocation_data = calculate_dynamic_allocations(participation_counts)
|
||||
bonus_data = calculate_bonus_pools(allocation_data)
|
||||
final_data = calculate_final_allocations(allocation_data, bonus_data)
|
||||
|
||||
# Generate test output
|
||||
test_output = generate_test_output(final_data)
|
||||
|
||||
# Add metadata
|
||||
export_data = {
|
||||
'metadata': {
|
||||
'source': 'lockdrop-experiment.ipynb',
|
||||
'scenario': 'custom',
|
||||
'participation_counts': participation_counts
|
||||
},
|
||||
'allocations': test_output
|
||||
}
|
||||
|
||||
# Save to file
|
||||
with open(filename, 'w') as f:
|
||||
json.dump(export_data, f, indent=2)
|
||||
|
||||
print(f"✅ Results exported to: {filename}")
|
||||
print(f"📊 Total participants: {sum(participation_counts.values()):,}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Export failed: {str(e)}")
|
||||
|
||||
return export_current_scenario
|
||||
|
||||
Loading…
Reference in New Issue
Block a user