Skip to content

Commit

Permalink
feat: Add table to simulation route
Browse files Browse the repository at this point in the history
Table is useful for diagnostics
  • Loading branch information
chriskelly committed Oct 16, 2023
1 parent 9bd1d63 commit 58ee8dd
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 16 deletions.
46 changes: 46 additions & 0 deletions app/models/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
SimulationEngine:
"""
from dataclasses import dataclass, field
import pandas as pd
from app.data import constants
from app.models.config import User, get_config
from app.models.controllers import (
Expand Down Expand Up @@ -98,6 +99,51 @@ class Results:

trials: list[SimulationTrial] = None

def as_dataframes(self) -> list[pd.DataFrame]:
"""
Returns a list of pandas DataFrames, where each DataFrame represents a trial in the simulator.
Each DataFrame contains the following columns:
- Date: The date of the interval.
- Net Worth: The net worth of the interval.
- Inflation: The inflation rate of the interval.
- Job Income: The job income of the interval.
- SS User: The social security income of the interval for the user.
- SS Partner: The social security income of the interval for the partner.
- Pension: The pension income of the interval.
- Portfolio Return: The portfolio return of the interval.
- Annuity: The annuity income of the interval.
"""
columns = [
"Date",
"Net Worth",
"Inflation",
"Job Income",
"SS User",
"SS Partner",
"Pension",
"Portfolio Return",
"Annuity",
]
dataframes = []
for trial in self.trials:
data = [
[
interval.state.date,
interval.state.net_worth,
interval.state.inflation,
interval.state_change_components.net_transactions.income.job_income,
interval.state_change_components.net_transactions.income.social_security_user,
interval.state_change_components.net_transactions.income.social_security_partner,
interval.state_change_components.net_transactions.income.pension,
interval.state_change_components.net_transactions.portfolio_return,
interval.state_change_components.net_transactions.annuity,
]
for interval in trial.intervals
]
df = pd.DataFrame(data, columns=columns)
dataframes.append(df)
return dataframes


class SimulationEngine:
"""Simulation Controller
Expand Down
7 changes: 5 additions & 2 deletions app/routes/api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""API Endpoints"""
from flask import Blueprint
from flask import Blueprint, render_template
from app.models.simulator import SimulationEngine

api = Blueprint("api", __name__)
Expand All @@ -10,4 +10,7 @@ def run_simulation():
"""Run the simulation"""
engine = SimulationEngine()
engine.gen_all_trials()
return "Here's the simulation!"
df = engine.results.as_dataframes()[0]
return render_template(
"simulation.html", table=df.to_html(classes="table table-striped")
)
62 changes: 49 additions & 13 deletions app/templates/simulation.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
{% extends 'base.html' %}

{% block content %}
<h1>{% block title %} Simulation {% endblock %}</h1>
<form method="post">
<input type="submit" name="submit_button" value="Run Simulation!">
</form>
{% if results %}
<p>{{ s_rate }}</p>
<img src="data:image/png;base64,{{ img_data }}"\>
{% endif %}

{% endblock %}
<!DOCTYPE html>
<html>

<head>
<title>Simulation</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<style>
.table-container {
max-height: 450px;
/* Set the maximum height of the table container */
overflow-y: auto;
/* Enable vertical scrolling if the table overflows */
}

table {
border-collapse: collapse;
width: 100%;
}

/* All cell rules */
th,
td {
padding: 8px;
text-align: left;
}

/* Header rules */
th {
position: -webkit-sticky;
/* For Safari */
position: sticky;
top: 0;
background-color: #f2f2f2;
}
</style>
</head>

<body>
<div class="container">
<h1>First Result</h1>
<div class="table-container">
<table class="table table-striped">
{{ table | safe }}
</table>
</div>
</div>
</body>

</html>
2 changes: 1 addition & 1 deletion tests/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def routes_to_test() -> dict:
"""Returns dictionary of `route:expected_response`"""
return {
"/": "Hello, World!",
"/api/simulation": "Here's the simulation!",
"/api/simulation": "First Result",
}


Expand Down

0 comments on commit 58ee8dd

Please sign in to comment.