Hi Everyone,
First time poster here so please excuse any rookie mistakes.
I’m creating a Dash App which is essentially a Monte Carlo simulation with a few additional criteria to define the parameters of the simulation.
I’ve created the exact same code both as part of the Dash App, and standalone without the app framework. The code runs perfectly when I use the standalone version, but when I use the App version, I get a callback error
dash.exceptions.InvalidCallbackReturnValue: The callback for
[<Output
br_graph.figure>, <Output
mean-br-end.children>, <Output
min-br-end.children>, <Output
max-br-end.children>, <Output
mode-end-stake.children>, <Output
min-end-stake.children>, <Output
max-end-stake.children>]
returned a value having typeFigure
which is not JSON serializable.The value in question is either the only value returned,
or is in the top level of the returned list, and has string representation
My callback looks like this:
@br_app.callback(
Output(component_id = 'br_graph', component_property = 'figure'),
Output(component_id = 'mean-br-end', component_property = 'children'),
Output(component_id = 'min-br-end', component_property = 'children'),
Output(component_id = 'max-br-end', component_property = 'children'),
Output(component_id = 'mode-end-stake', component_property = 'children'),
Output(component_id = 'min-end-stake', component_property = 'children'),
Output(component_id = 'max-end-stake', component_property = 'children'),
inputs = [Input('br-button', 'n_clicks')],
state = [State('winrate-input', 'value'),
State('std-input', 'value'),
State('hands-input', 'value'),
State('starting-br-input', 'value'),
State('move-up-input', 'value'),
State('move-down-input', 'value')])
def update_br_graph(n_clicks, wr, std, hands, br, move_up, move_down_input):
#Create simulated BB winnings
list_wrperhand = float(wr/100)
list_stdperhand = float(std/10)
list_hands = int(hands)
#Create list of simulations
sims_list = ['sim' +" " + str(x) for x in range(1,21)]
#populate each simulation with results for each hand
for i in range(0,20):
sims_list[i] = np.random.normal(list_wrperhand, list_stdperhand, list_hands)
sims_list[i][0] = 0
#cumulate results for each hand for overall results in BBs
sims_list_cum = [np.cumsum(x) for x in sims_list]
#Pass to dictionary to give each sim a label
names = ['sim ' + str(x) for x in range(1,21)]
sim_dict = {}
for i in range(0,20):
sim_dict['sim '+str(i+1)] = sims_list[i]
xaxis = ()
sim_graph_test = []
if hands > 100000:
sim_graph_test = [x[0:List_hands-1:10] for x in sims_list_cum]
xaxis = np.arange(0, list_hands/10)
else:
sim_graph_test = [x[:] for x in sims_list_cum]
xaxis = np.arange(0, list_hands)
starting_br = float(br)
move_down = float(move_down_input)
stakes = [2, 5, 10, 25, 50, 100, 200, 500, 1000, 2000]
#Iterate through simulated winnings
def Check_Stakes(br, move_down):#, move_up, move_down):
if br <= move_down*stakes[9]:
current_stake = stakes[8]
if move_down*stakes[7]< br <= move_down*stakes[8]:
current_stake = stakes[7]
if move_down * stakes[6] < br <= move_down*stakes[7]:
current_stake = stakes[6]
if move_down * stakes[5] < br <= move_down * stakes[6]:
current_stake = stakes[5]
if move_down*stakes[4] < br <= move_down * stakes[5]:
current_stake = stakes[4]
if move_down*stakes[3] < br <= move_down * stakes[4]:
current_stake = stakes[3]
if move_down*stakes[2] < br <= move_down * stakes[3]:
current_stake = stakes[2]
if move_down*stakes[1] < br <= move_down * stakes[2]:
current_stake = stakes[1]
if 0 < br <= move_down * stakes[1]:
current_stake = stakes[0]
elif move_down*stakes[7] <= br:
current_stake = stakes[7]
return current_stake
bank_roll_dict = {}
def Iterate(bank_roll_dict):
for sim in names:
bank_roll_dict[sim][0] = starting_br
for hand in range(1, list_hands):
stake = Check_Stakes(bank_roll_dict[sim][hand-1], move_down)#, move_up, move_down)
if bank_roll_dict[sim][hand-1] <= 0:
bank_roll_dict[sim][hand] = 0
else:
bank_roll_dict[sim][hand] = bank_roll_dict[sim][hand]*(stake/100) + bank_roll_dict[sim][hand-1]
return bank_roll_dict
bank_roll_dict =Iterate(sim_dict)
bank_roll_list = [x for x in bank_roll_dict.values()]
bank_roll_df = pd.DataFrame(bank_roll_dict)
#Table Data
end_br = bank_roll_df.iloc[-1, :]
end_br = pd.DataFrame(end_br)
mean_end_br = round(end_br.mean(), 2)
min_end_br = round(end_br.min(), 2)
max_end_br = round(end_br.max(), 2)
#Determine End Stakes
end_stake_list = [Check_Stakes(x, move_down) for x in end_br]
end_stake = pd.DataFrame(end_stake_list)
end_stake.columns = ["End Stake"]
end_stake.reindex(names)
mode_end_stake = end_stake.mode()
max_end_stake = end_stake.max()
min_end_stake = end_stake.min()
br_graph = px.line(x = xaxis, y = bank_roll_list)
br_graph.update_layout(yaxis_title = 'BR Amount ($)')
if hands > 1000000:
br_graph.update_traces(hovertemplate = 'Hand %{x*10} <br> BR Amount $%{y}')
else:
br_graph.update_traces(hovertemplate = 'Hand %{x} <br> BR Amount $%{y}')
return br_graph, mean_end_br, min_end_br, max_end_br, mode_end_stake, min_end_stake, max_end_stake
br_app.run_server(debug = True, port = '8000')
Any advice would be appreciated!