File size: 5,032 Bytes
0ef03ea 41afdc7 dee01c8 0ef03ea 9b59fc5 dee01c8 0ef03ea 3831198 dee01c8 3831198 41afdc7 3831198 41afdc7 0ef03ea 3831198 41afdc7 3831198 41afdc7 0ef03ea dee01c8 fd0fa88 41afdc7 fd0fa88 dee01c8 3831198 dee01c8 41afdc7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
import os
import json
import threading
import gradio as gr
import statistics
from scipy import stats
import numpy as np # Added import for numpy to compute percentiles
import altair as alt
import pandas as pd
DATA_DIR = './storage'
DATA_FILE = os.path.join(DATA_DIR, 'guesses.json')
lock = threading.Lock()
def ensure_data_directory():
os.makedirs(DATA_DIR, exist_ok=True)
def load_guesses():
ensure_data_directory()
if not os.path.exists(DATA_FILE):
with open(DATA_FILE, 'w') as f:
json.dump([], f)
with open(DATA_FILE, 'r') as f:
return json.load(f)
def save_guesses(guesses):
with open(DATA_FILE, 'w') as f:
json.dump(guesses, f)
def add_guess(guess):
with lock:
guesses = load_guesses()
guesses.append(guess)
save_guesses(guesses)
message = compute_statistics(guesses, include_message=True)
chart = generate_plot(guesses) # Generate the Altair chart
return message, None, chart # Return message, cleared input, and chart
def get_current_results():
with lock:
guesses = load_guesses()
message = compute_statistics(guesses, include_message=False)
chart = generate_plot(guesses)
return message, chart
def compute_statistics(guesses, include_message):
n = len(guesses)
if n == 0:
return "No guesses have been made yet."
average = sum(guesses) / n
median = statistics.median(guesses)
# Calculate IQR
Q1 = np.percentile(guesses, 25)
Q3 = np.percentile(guesses, 75)
IQR = Q3 - Q1
# Initialize the message
message = (
(f"Your guess has been recorded.\n" if include_message else "") +
f"Current average of all {n} guesses: {average:.2f}\n" +
f"Median of all guesses: {median:.2f}\n" +
f"Interquartile Range (IQR): {IQR:.2f}\n" +
"(The IQR is the range between the 25th percentile and 75th percentile of the data.)\n"
)
if n >= 2:
# Calculate sample standard deviation
s = statistics.stdev(guesses)
# Calculate standard error
SE = s / (n ** 0.5)
# Degrees of freedom
df = n - 1
# Confidence level (e.g., 95%)
confidence_level = 0.95
alpha = 1 - confidence_level
# Calculate critical t-value
t_value = stats.t.ppf(1 - alpha/2, df)
# Calculate margin of error
ME = t_value * SE
# Calculate confidence interval
ci_lower = average - ME
ci_upper = average + ME
# Append confidence interval to the message
message += f"95% confidence interval for the average: ({ci_lower:.2f}, {ci_upper:.2f})"
else:
# Not enough data to compute confidence interval
message += "Not enough data to compute confidence interval for the average."
return message
def generate_plot(guesses):
if len(guesses) < 2:
return None # Not enough data to plot
# Convert the list of guesses into a Pandas DataFrame
df = pd.DataFrame({'Guess': guesses})
# Histogram
histogram = alt.Chart(df).mark_bar().encode(
alt.X('Guess', bin=alt.Bin(maxbins=20), title='Guess Value'),
alt.Y('count()', title='Frequency'),
tooltip=[alt.Tooltip('count()', title='Frequency')]
).properties(
title='Histogram of Guesses',
width=500,
height=300
)
# CDF
df_sorted = df.sort_values('Guess').reset_index(drop=True)
df_sorted['ECDF'] = (df_sorted.index + 1) / len(df_sorted)
cdf = alt.Chart(df_sorted).mark_line(interpolate='step-after').encode(
x=alt.X('Guess', title='Guess Value'),
y=alt.Y('ECDF', title='Cumulative Probability'),
tooltip=[
alt.Tooltip('Guess', title='Guess Value'),
alt.Tooltip('ECDF', title='Cumulative Probability', format='.2f')
]
).properties(
title='Cumulative Distribution Function (CDF)',
width=500,
height=300
)
# Combine the two charts vertically
combined_chart = alt.vconcat(histogram, cdf).configure_title(
fontSize=16,
anchor='middle'
).interactive()
return combined_chart
with gr.Blocks() as demo:
gr.Markdown("# Collective Guessing Game")
gr.Markdown("Submit your guess and contribute to the global statistics!")
guess_input = gr.Number(label="Enter your guess")
submit_button = gr.Button("Submit Guess")
with gr.Accordion("View Current Results!", open=False):
output_text = gr.Textbox(label="Results", lines=10)
output_plot = gr.Plot(label="Data Visualization") # Plot component for Altair charts
refresh_button = gr.Button("Refresh Results")
submit_button.click(
fn=add_guess,
inputs=guess_input,
outputs=[output_text, guess_input, output_plot]
)
refresh_button.click(
fn=get_current_results,
outputs=[output_text, output_plot]
)
demo.load(fn=get_current_results, outputs=[output_text, output_plot])
demo.launch() |