Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from collections import defaultdict
|
2 |
+
|
3 |
+
|
4 |
+
import streamlit as st
|
5 |
+
import streamlit.components.v1 as components
|
6 |
+
import plotly.express as px
|
7 |
+
|
8 |
+
|
9 |
+
st.set_page_config(page_title='Can you be truly random ?', layout = 'wide', page_icon = 'favicon.jpg', initial_sidebar_state = 'auto')
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
# Custom CSS to styles
|
14 |
+
st.markdown("""
|
15 |
+
<style>
|
16 |
+
button {
|
17 |
+
padding-top: 50px !important;
|
18 |
+
padding-bottom: 50px !important;
|
19 |
+
}
|
20 |
+
</style>
|
21 |
+
""", unsafe_allow_html=True)
|
22 |
+
|
23 |
+
|
24 |
+
max_history = 4
|
25 |
+
|
26 |
+
|
27 |
+
def set_state(x):
|
28 |
+
if x == 1: st.toast('The journey begins!', icon='π')
|
29 |
+
if x == 2: st.toast('Welcome!', icon='π')
|
30 |
+
if x == 3: st.toast("Let's play!", icon='π₯°')
|
31 |
+
if x == 4: st.toast("Meet your friends!", icon='π€ͺ')
|
32 |
+
st.session_state.stage = x
|
33 |
+
|
34 |
+
|
35 |
+
def reset_game():
|
36 |
+
set_state(0)
|
37 |
+
if 'n_buttons' not in st.session_state:
|
38 |
+
st.session_state.n_buttons = 2
|
39 |
+
st.session_state.history = []
|
40 |
+
st.session_state.preds = defaultdict(lambda: defaultdict(int))
|
41 |
+
st.session_state.pnl = [0]
|
42 |
+
|
43 |
+
if 'stage' not in st.session_state:
|
44 |
+
reset_game()
|
45 |
+
|
46 |
+
st.title('How random can you truly be?')
|
47 |
+
|
48 |
+
if st.session_state.stage == 0:
|
49 |
+
st.button('Begin', on_click=set_state, args=[1],use_container_width=True)
|
50 |
+
|
51 |
+
st.session_state.n_buttons = st.slider(label="How many buttons to play with?", min_value=2, max_value=5,value=2)
|
52 |
+
|
53 |
+
st.markdown(f'You will be presented with {st.session_state.n_buttons} to randomly choose from')
|
54 |
+
|
55 |
+
st.markdown("At each round, I will try to predict which button you click :-)")
|
56 |
+
st.markdown(f"If I get it right, I earn {st.session_state.n_buttons-1} point(s), otherwise you earn 1 point")
|
57 |
+
st.markdown(f"Play as long as you want and try to beat me!")
|
58 |
+
|
59 |
+
|
60 |
+
|
61 |
+
|
62 |
+
def get_prev_seqs(history):
|
63 |
+
# st.write(history)
|
64 |
+
|
65 |
+
seqs = []
|
66 |
+
for h in range(max_history+1):
|
67 |
+
if len(history) >= h:
|
68 |
+
previous_seq = ''.join(history[-h:]) if h > 0 else ""
|
69 |
+
# st.write(previous_seq)
|
70 |
+
seqs.append(previous_seq) # from small to largest
|
71 |
+
return seqs
|
72 |
+
|
73 |
+
def refresh_preds():
|
74 |
+
played = st.session_state.history[-1]
|
75 |
+
seqs = get_prev_seqs(st.session_state.history[:-1])
|
76 |
+
for seq in seqs:
|
77 |
+
# st.write(f'"{seq}"',played)
|
78 |
+
st.session_state.preds[seq][played] += 1
|
79 |
+
|
80 |
+
def make_pred():
|
81 |
+
seqs = get_prev_seqs(st.session_state.history)
|
82 |
+
# st.write('seqs',seqs)
|
83 |
+
scores = defaultdict(float)
|
84 |
+
denominator = 0
|
85 |
+
for i,seq in enumerate(seqs):
|
86 |
+
weight = (i+1)**2
|
87 |
+
preds = st.session_state.preds[seq]
|
88 |
+
total = sum(preds.values())
|
89 |
+
|
90 |
+
if total:
|
91 |
+
for played,value in preds.items():
|
92 |
+
scores[played] += weight*value/total
|
93 |
+
denominator += weight
|
94 |
+
if denominator:
|
95 |
+
scores = {played:value/denominator for played,value in scores.items()}
|
96 |
+
return scores
|
97 |
+
else:
|
98 |
+
return {str(i):1/st.session_state.n_buttons for i in range(st.session_state.n_buttons)}
|
99 |
+
|
100 |
+
|
101 |
+
def update_pnl(user_win):
|
102 |
+
current_score = st.session_state.pnl[-1]
|
103 |
+
current_score += -1 if user_win else (st.session_state.n_buttons-1)
|
104 |
+
st.session_state.pnl.append(current_score)
|
105 |
+
|
106 |
+
def user_select(i,choice):
|
107 |
+
st.session_state.history.append(str(i))
|
108 |
+
if i == choice:
|
109 |
+
st.toast("I win!", icon='π€ͺ')
|
110 |
+
update_pnl(user_win=False)
|
111 |
+
else:
|
112 |
+
st.toast('Well done!', icon='π')
|
113 |
+
update_pnl(user_win=True)
|
114 |
+
|
115 |
+
refresh_preds()
|
116 |
+
|
117 |
+
|
118 |
+
|
119 |
+
if st.session_state.stage == 1:
|
120 |
+
pred = make_pred()
|
121 |
+
choice = max(pred,key=pred.get)
|
122 |
+
|
123 |
+
cols = st.columns(st.session_state.n_buttons)
|
124 |
+
for i,col in enumerate(cols):
|
125 |
+
col.button(str(i),on_click=user_select, args=[str(i),choice],
|
126 |
+
use_container_width=True)
|
127 |
+
|
128 |
+
st.plotly_chart(px.line(st.session_state.pnl), use_container_width=True)
|
129 |
+
|
130 |
+
st.button('Start over', on_click=reset_game, args=[],
|
131 |
+
use_container_width=True)
|