Add the latest bossfight dash webapp

This commit is contained in:
cegranger 2023-12-05 14:35:45 -05:00 committed by GitHub
parent 0e684ed82e
commit 4f813eb502
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 449 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View file

@ -0,0 +1,73 @@
id,roll
1,6
2,3
3,1
4,5
5,5
6,2
7,4
8,4
9,4
10,6
11,4
12,2
13,2
14,2
15,4
16,6
17,5
18,6
19,2
20,3
21,6
22,5
23,1
24,4
25,3
26,3
27,3
28,3
29,5
30,1
31,5
32,6
33,1
34,4
35,3
36,1
37,2
38,2
39,2
40,1
41,2
42,6
43,1
44,3
45,4
46,1
47,4
48,2
49,4
50,2
51,2
52,3
53,5
54,2
55,1
56,2
57,3
58,2
59,1
60,5
61,2
62,4
63,5
64,4
65,3
66,3
67,2
68,5
69,3
1,2
2,5
3,3
1 id roll
2 1 6
3 2 3
4 3 1
5 4 5
6 5 5
7 6 2
8 7 4
9 8 4
10 9 4
11 10 6
12 11 4
13 12 2
14 13 2
15 14 2
16 15 4
17 16 6
18 17 5
19 18 6
20 19 2
21 20 3
22 21 6
23 22 5
24 23 1
25 24 4
26 25 3
27 26 3
28 27 3
29 28 3
30 29 5
31 30 1
32 31 5
33 32 6
34 33 1
35 34 4
36 35 3
37 36 1
38 37 2
39 38 2
40 39 2
41 40 1
42 41 2
43 42 6
44 43 1
45 44 3
46 45 4
47 46 1
48 47 4
49 48 2
50 49 4
51 50 2
52 51 2
53 52 3
54 53 5
55 54 2
56 55 1
57 56 2
58 57 3
59 58 2
60 59 1
61 60 5
62 61 2
63 62 4
64 63 5
65 64 4
66 65 3
67 66 3
68 67 2
69 68 5
70 69 3
71 1 2
72 2 5
73 3 3

View file

@ -0,0 +1 @@
13019,76.81,1.73

375
bossfight-webapp/main.py Normal file
View file

@ -0,0 +1,375 @@
import dash
from dash import dcc, html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import pandas as pd
import plotly.express as px
from datetime import datetime, timedelta
import itertools
from PIL import Image
# Use the Dash Bootstrap Components theme
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
# Load the initial data from the dice_roll_data.csv file into a Pandas DataFrame
df = pd.read_csv('dice_roll_data.csv')
# Calculate initial statistics
result_counts = df['roll'].value_counts().sort_index()
total_rolls = result_counts.sum()
# Assuming df is the DataFrame containing the rolls
current_roll = df['roll'].iloc[-1] if not df.empty else 0 # Default to 0 if the DataFrame is empty
# Count consecutive occurrences of the current roll value
consecutive_count = sum(1 for _ in itertools.takewhile(lambda x: x == current_roll, reversed(df['roll'])))
# Initial health value, adjust as needed
progress_value = 2000
max_progress_value = 2000
max_damage = 0
# Create initial figure with px.bar
fig = px.bar(y=result_counts.index, x=result_counts.values, labels={'x': 'Count', 'y': 'Result'}, orientation='h')
# Update layout for the bar chart to make the axis titles and tick labels larger
fig.update_xaxes(tickfont=dict(size=24), title_font=dict(size=28))
fig.update_yaxes(tickfont=dict(size=24), title_font=dict(size=28))
# Add title to the bar chart
# fig.update_layout(title_text="Allo", title_font=dict(size=32), title_x=0.5)
# Calculate the end time for the countdown timer (December 2, 2023, at 3:30 pm)
end_time = datetime(2023, 12, 2, 15, 30, 0)
# Function to find the maximal consecutive occurrence of a given roll value
def find_max_consecutive_occurrence(series, roll_value):
max_consecutive_occurrence = 0
current_consecutive_occurrence = 0
for i in range(1, len(series)):
if series.iloc[i] == roll_value and series.iloc[i - 1] == roll_value and (series.index[i] - series.index[i - 1]) == 1:
current_consecutive_occurrence += 1
elif series.iloc[i] == roll_value:
current_consecutive_occurrence = 1
else:
current_consecutive_occurrence = 0
max_consecutive_occurrence = max(max_consecutive_occurrence, current_consecutive_occurrence)
return max_consecutive_occurrence
def calculate_cumulative_damage(rolls):
cumulative_damage = []
current_value = None
consecutive_count = 0
for roll in rolls:
if roll == current_value:
consecutive_count += 1
else:
consecutive_count = 1
current_value = roll
damage = roll * (2 ** (consecutive_count - 1))
cumulative_damage.append(damage)
return cumulative_damage
# Function to read values from the info.txt file
def read_info_file():
try:
with open('info.txt', 'r') as file:
lines = file.readlines()
if lines:
values = lines[0].strip().split(',')
if len(values) == 3:
inference_rate, latency, power_consumption = map(float, values)
return inference_rate, latency, power_consumption
except Exception as e:
print(f"Error reading info.txt: {e}")
return None, None, None
# Calculate the maximal consecutive occurrence for each roll
max_consecutive_occurrences = {roll: find_max_consecutive_occurrence(df['roll'], roll) for roll in range(1, 7)}
# Define layout using Dash components and Dash Bootstrap Components
app.layout = dbc.Container(
fluid=True,
children=[
# Row 1: Cells 1 and 2
dbc.Row([
dbc.Col(
dbc.Card(
dbc.CardBody(
[
html.Img(src=dash.get_asset_url('oogie.gif'), alt='Oogie Boogie', className='img-fluid mx-auto my-auto', style={'width': '75%', 'max-height': '100%', 'border-radius': '25px'}),
dbc.Progress(
id='progress-bar',
value=progress_value,
color="success",
max=max_progress_value,
style={'margin-top': '20px', 'height': '30px', 'background-color': 'red'},
),
html.P(f'Health: {progress_value:.0f}/{max_progress_value}', id='health-text', className='lead text-center fw-bold', style={'font-size': '24px', 'margin-top': '10px'}),
],
className='text-center'
),
className='border p-3',
style={'height': '100%'}
),
width=6
),
dbc.Col(
# Cell 2: Countdown, System infos, and Table with max consecutive occurrences for each roll
dbc.Card(
[
dcc.Interval(
id='interval-component',
interval=1*1000, # in milliseconds
n_intervals=0
),
html.P(id='countdown-timer', className='lead text-center fw-bold', style={'font-size': '32px'}),
dbc.CardBody(
[
# Add new text and values from info.txt
html.Div(
[
html.P(id='inference-rate-text', className='lead text-center fw-bold', style={'font-size': '24px', 'margin-right': '10px'}),
html.P(id='latency-text', className='lead text-center fw-bold', style={'font-size': '24px', 'margin-right': '10px'}),
html.P(id='power-consumption-text', className='lead text-center fw-bold', style={'font-size': '24px'}),
],
style={'display': 'flex', 'align-items': 'center', 'justify-content': 'center', 'margin-top': '20px'},
),
html.Div(
[
html.Img(src=dash.get_asset_url('dice-pc.png'), alt='Actuel', className='img-fluid mx-auto my-auto', style={'width': '50%', 'max-height': '100%', 'border-radius': '25px'}),
],
style={'display': 'flex', 'align-items': 'center', 'justify-content': 'center'},
),
html.Div(
[
html.Img(src=dash.get_asset_url('dice-fpga.png'), alt='Cible', className='img-fluid mx-auto my-auto', style={'width': '60%', 'max-height': '100%', 'border-radius': '25px'}),
],
style={'display': 'flex', 'align-items': 'center', 'justify-content': 'center', 'margin-top': '20px'},
),
# html.Img(src=dash.get_asset_url('dice-pc.png'), alt='Actuel', className='img-fluid mx-auto my-auto', style={'width': '55%', 'max-height': '100%', 'border-radius': '25px'}),
# html.Img(src=dash.get_asset_url('dice-fpga.png'), alt='Cible', className='img-fluid mx-auto my-auto', style={'width': '5%', 'max-height': '100%', 'border-radius': '25px'}),
# dbc.Table(
# id='max-consecutive-occurrence-table',
# children=[
# html.Thead(
# html.Tr([html.Th('Roll', style={'font-size': '28px'}), html.Th('Max Consecutive Occurrence', style={'font-size': '28px'})])
# ),
# html.Tbody(
# [html.Tr([html.Td(f'{roll}', style={'font-size': '24px'}), html.Td(f'{max_consecutive_occurrences[roll]}', style={'font-size': '24px'})]) for roll in range(1, 7)]
# )
# ],
# className='text-center',
# style={'margin-top': '20px'}
# ),
],
className='text-center'
),
],
className='border p-3',
style={'height': '100%'}
),
width=6
)
], align='stretch', style={'margin-bottom': '20px'}),
# Row 2: Cells 3 and 4
dbc.Row([
dbc.Col(
# Cell 3
dbc.Card(
dbc.CardBody(
[
html.Div(
[
html.Div(
[
html.H5("Previous Roll", className="card-title fw-bold", style={'margin-bottom': '10px', 'font-size': '32px'}),
html.Img(id='previous-roll-image', alt='previous roll image', className='img-fluid mx-auto my-auto', style={'width': '70%', 'max-height': '100%', 'border-radius': '15px'}),
],
style={'padding-bottom': '20px', 'padding-right': '75px'}
),
html.Div(
[
html.H5("Current Roll", className="card-title fw-bold", style={'margin-bottom': '10px', 'font-size': '32px'}),
html.Img(id='current-roll-image', alt='current roll image', className='img-fluid mx-auto my-auto', style={'width': '70%', 'max-height': '100%', 'border-radius': '15px'}),
],
style={'padding-bottom': '20px'}
),
],
style={'display': 'flex', 'justify-content': 'center', 'margin-top': '75px'}
),
html.P(id='consecutive-count-text', className='lead text-center fw-bold', style={'font-size': '24px'}),
html.P(id='damage-dealt-text', className='lead text-center fw-bold', style={'font-size': '24px'}),
html.P(id='max-damage-text', className='lead text-center fw-bold', style={'font-size': '24px'}),
],
className='text-center'
),
className='border p-3',
style={'height': '100%'}
),
width=6
),
dbc.Col(
# Cell 4: Bar Chart and Probability Table
dbc.Card(
[
dbc.CardBody(
[
html.P(id='total-rolls-text', className='lead text-center fw-bold', style={'font-size': '32px'}),
html.Div(
[
# Bar Chart
dcc.Graph(
id='bar-chart',
figure=fig,
style={'height': '80%', 'width': '70%', 'display': 'inline-block'}
),
# Probability Table
dbc.Table(
id='probability-table',
style={'margin-top': '20px', 'width': '30%', 'display': 'inline-block'},
),
],
style={'width': '100%', 'display': 'flex', 'justify-content': 'space-between'}
),
],
className='text-center'
),
],
# Cell 4
className='border p-3',
style={'height': '100%'}
),
width=6
)
], align='stretch')
]
)
# Callback to update countdown timer text
@app.callback(Output('countdown-timer', 'children'),
[Input('interval-component', 'n_intervals')])
def update_timer(n_intervals):
time_left = end_time - datetime.now()
days, seconds = divmod(time_left.total_seconds(), 86400)
hours, remainder = divmod(seconds, 3600)
minutes, seconds = divmod(remainder, 60)
# Format components with leading zeros
formatted_hours = str(int(hours)).zfill(2)
formatted_minutes = str(int(minutes)).zfill(2)
formatted_seconds = str(int(seconds)).zfill(2)
return f'Temps restant: {formatted_hours}:{formatted_minutes}:{formatted_seconds}'
# Callback to update data every second
@app.callback([Output('bar-chart', 'figure'),
Output('total-rolls-text', 'children'),
# Output('max-consecutive-occurrence-table', 'children'),
Output('probability-table', 'children'),
Output('inference-rate-text', 'children'),
Output('latency-text', 'children'),
Output('power-consumption-text', 'children'),
Output('consecutive-count-text', 'children'),
Output('damage-dealt-text', 'children'),
Output('previous-roll-image', 'src'),
Output('current-roll-image', 'src'),
Output('progress-bar', 'value'),
Output('health-text', 'children'),
Output('max-damage-text', 'children'),],
[Input('interval-component', 'n_intervals')])
def update_data(n_intervals):
global df, max_consecutive_occurrences, total_rolls, consecutive_count, current_roll, progress_value, max_damage
# Load the data from the dice_roll_data.csv file into a Pandas DataFrame
df = pd.read_csv('dice_roll_data.csv')
# Calculate statistics
result_counts = df['roll'].value_counts().sort_index()
total_rolls = result_counts.sum()
# Create figure with px.bar
fig = px.bar(y=result_counts.index, x=result_counts.values, labels={'x': 'Compte', 'y': 'Résultat'},
orientation='h')
# Update layout for the bar chart to make the axis titles and tick labels larger
fig.update_xaxes(tickfont=dict(size=24), title_font=dict(size=28))
fig.update_yaxes(tickfont=dict(size=24), title_font=dict(size=28))
# Add numbers on the bars
fig.update_traces(text=result_counts.values, textposition='inside', textfont_size=20)
# Calculate the maximal consecutive occurrence for each roll
max_consecutive_occurrences = {roll: find_max_consecutive_occurrence(df['roll'], roll) for roll in range(1, 7)}
# Calculate the total and maximal damage dealt and apply it to the progress bar
total_damage_dealt = sum(calculate_cumulative_damage(df['roll']))
progress_value = max_progress_value - total_damage_dealt
health_text = f'Points de vie: {progress_value:.0f}/{max_progress_value}'
# Update the table in Cell 2 with the new max consecutive occurrences
max_occurrence_table = [
html.Thead(
html.Tr([html.Th('Résultat', style={'font-size': '28px'}), html.Th('Occurence Consécutive Max', style={'font-size': '28px'})])
),
html.Tbody(
[html.Tr([html.Td(f'{roll}', style={'font-size': '24px'}), html.Td(f'{max_consecutive_occurrences[roll]}', style={'font-size': '24px'})]) for roll in range(1, 7)]
)
]
# Read values from the info.txt file
inference_rate, latency, power_consumption = read_info_file()
# Update text in Cell 2 with values from info.txt
inference_rate_text = f"Débit d'Inference: {inference_rate} fps" if inference_rate is not None else "Débit d'Inference: N/A"
latency_text = f'Latence: {latency} µs' if latency is not None else 'Latence: N/A'
power_consumption_text = f'Consomation Énergétique: {power_consumption} W' if power_consumption is not None else 'Consomation Énergétique: N/A'
# Calculate probabilities
probabilities = result_counts / total_rolls * 100
probability_table = [
html.Thead(
html.Tr([html.Th('Résultat', style={'font-size': '28px'}), html.Th('Probabilités', style={'font-size': '28px'})])
),
html.Tbody(
[html.Tr([html.Td(f'{roll}', style={'font-size': '24px'}), html.Td(f'{probabilities[roll]:.2f}%', style={'font-size': '24px'})]) for roll in range(1, 7)]
)
]
# Update consecutive count and text
current_roll = df['roll'].iloc[-1] if not df.empty else 0
consecutive_count = sum(1 for _ in itertools.takewhile(lambda x: x == current_roll, reversed(df['roll'])))
consecutive_count_text = f'Vous avez lancé {current_roll} pour la {consecutive_count}{"ère" if consecutive_count == 1 else "ème"} fois de suite!'
# Calculate damage dealt
damage_dealt = current_roll * (2 ** (consecutive_count-1))
damage_dealt_text = f'Dégat infligé: {damage_dealt}'
# Calculate max damage dealt
if max_damage > damage_dealt:
max_damage_text = f'Dégat Maximal: {max_damage}'
else:
max_damage = damage_dealt
max_damage_text = f'Nouveau Dégat Maximal: {max_damage}! Bravo!'
# Get image sources based on the current and previous rolls
previous_roll_image_source = Image.open('assets/previous_roll.jpg')
current_roll_image_source = Image.open('assets/current_roll.jpg')
return fig, f'Total de tirs: {total_rolls}', probability_table, inference_rate_text, latency_text, power_consumption_text, consecutive_count_text, damage_dealt_text, previous_roll_image_source, current_roll_image_source, progress_value, health_text, max_damage_text
if __name__ == '__main__':
app.run_server(debug=True, host='0.0.0.0', dev_tools_hot_reload=False)