Skip to content

Commit cc24b62

Browse files
committed
feat: introduce experements
1 parent 5e5b276 commit cc24b62

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

‎experiments/base.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from abc import ABC, abstractmethod
2+
import streamlit as st
3+
4+
class Experiment(ABC):
5+
@abstractmethod
6+
def run(self):
7+
pass
8+
9+
@abstractmethod
10+
def get_description(self) -> str:
11+
pass
12+
13+
@property
14+
def name(self) -> str:
15+
return self.__class__.__name__.replace('Experiment', '')

‎experiments/coin_flip.py‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from .base import Experiment
4+
import streamlit as st
5+
6+
class CoinFlipExperiment(Experiment):
7+
def run(self):
8+
col1, col2, col3 = st.columns([1, 1, 1])
9+
10+
with col1:
11+
num_flips = st.slider("Number of flips", 1, 10000, 100)
12+
flips = np.random.choice(['Heads', 'Tails'], size=num_flips)
13+
unique, counts = np.unique(flips, return_counts=True)
14+
probabilities = dict(zip(unique, counts/num_flips))
15+
st.metric("Heads Probability", f"{probabilities.get('Heads', 0):.3f}")
16+
st.metric("Tails Probability", f"{probabilities.get('Tails', 0):.3f}")
17+
18+
with col2:
19+
fig, ax = plt.subplots()
20+
ax.bar(probabilities.keys(), probabilities.values())
21+
ax.set_ylabel('Probability')
22+
ax.set_title(f'Probability Distribution ({num_flips} flips)')
23+
st.pyplot(fig)
24+
25+
with col3:
26+
st.write("Coin Flip Properties:")
27+
st.write("""
28+
- Each flip is independent
29+
- Probability of heads = 0.5
30+
- Probability of tails = 0.5
31+
- Expected value = 0.5
32+
- Variance = 0.25
33+
""")
34+
st.markdown("📚 **Learn More:** [Coin Flipping Probability](https://en.wikipedia.org/wiki/Coin_flipping#Physics)")
35+
36+
def get_description(self) -> str:
37+
return "Simulate coin flips and observe probability distribution"

‎experiments/manager.py‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from typing import Dict, Type
2+
from .base import Experiment
3+
from .coin_flip import CoinFlipExperiment
4+
import streamlit as st
5+
6+
class ExperimentManager:
7+
def __init__(self):
8+
self.experiments: Dict[str, Type[Experiment]] = {
9+
'Coin Flip': CoinFlipExperiment(),
10+
}
11+
12+
def get_experiment_names(self):
13+
return list(self.experiments.keys())
14+
15+
def run_experiment(self, name: str):
16+
if name not in self.experiments:
17+
raise ValueError(f"Unknown experiment: {name}")
18+
19+
experiment = self.experiments[name]
20+
st.header(name)
21+
st.markdown(experiment.get_description())
22+
experiment.run()

‎main.py‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from distributions.discrete import *
44
from ui.sidebar import Sidebar
55
import matplotlib.pyplot as plt
6+
import numpy as np
7+
from experiments.manager import ExperimentManager
68

79

810
class ProbabilityExplorer:
@@ -49,6 +51,7 @@ def __init__(self):
4951
'Hypergeometric': HypergeometricDistribution(),
5052
'UniformDiscrete': UniformDiscreteDistribution(),
5153
}
54+
self.experiment_manager = ExperimentManager()
5255

5356

5457
def run(self):
@@ -83,8 +86,14 @@ def run(self):
8386
st.error("Error plotting distribution: " + str(e))
8487

8588
def show_experiments_page(self):
86-
pass
89+
with st.sidebar:
90+
experiment = st.selectbox(
91+
"Choose an experiment:",
92+
self.experiment_manager.get_experiment_names()
93+
)
8794

95+
self.experiment_manager.run_experiment(experiment)
96+
8897
def show_about_page(self):
8998
st.header("About project:")
9099

0 commit comments

Comments
 (0)