mswhite commited on
Commit
64539da
·
verified ·
1 Parent(s): d84f577

Upload 61 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. pages/Bonus.py +26 -0
  2. pages/Module_01.py +26 -0
  3. pages/Module_02.py +26 -0
  4. pages/Module_03.py +26 -0
  5. pages/Module_04.py +26 -0
  6. pages/Module_05.py +26 -0
  7. pages/Module_06.py +26 -0
  8. pages/Module_07.py +26 -0
  9. pages/Module_08.py +26 -0
  10. pages/Module_09.py +26 -0
  11. pages/Module_10.py +26 -0
  12. pages/Module_11.py +26 -0
  13. pages/Module_12.py +26 -0
  14. pages/Module_13.py +26 -0
  15. pages/Module_14.py +26 -0
  16. pages/Module_15.py +26 -0
  17. pages/Module_16.py +26 -0
  18. pages/Module_17.py +26 -0
  19. pages/Module_18.py +26 -0
  20. pages/Module_19.py +26 -0
  21. pages/Module_20.py +26 -0
  22. pages/Overview.py +26 -0
  23. pages/__init__.py +14 -0
  24. pages/assets/formulas.txt +221 -0
  25. pages/assets/logo.jpg +0 -0
  26. pages/assets/profile.txt +17 -0
  27. pages/assets/progress.txt +43 -0
  28. pages/load_pages.py +483 -0
  29. pages/modules/Bonus/Overview.txt +5 -0
  30. pages/modules/Copy_Overview.bat +21 -0
  31. pages/modules/Module_01/Overview.txt +5 -0
  32. pages/modules/Module_01/flashcards - template.html +148 -0
  33. pages/modules/Module_01/flashcards01.html +212 -0
  34. pages/modules/Module_01/flashcards02.html +215 -0
  35. pages/modules/Module_02/Overview.txt +5 -0
  36. pages/modules/Module_03/Overview.txt +5 -0
  37. pages/modules/Module_04/Overview.txt +5 -0
  38. pages/modules/Module_05/Overview.txt +5 -0
  39. pages/modules/Module_06/Overview.txt +5 -0
  40. pages/modules/Module_07/Overview.txt +5 -0
  41. pages/modules/Module_08/Overview.txt +5 -0
  42. pages/modules/Module_09/Overview.txt +5 -0
  43. pages/modules/Module_10/Overview.txt +5 -0
  44. pages/modules/Module_11/Overview.txt +5 -0
  45. pages/modules/Module_12/Overview.txt +5 -0
  46. pages/modules/Module_13/Overview.txt +5 -0
  47. pages/modules/Module_14/Overview.txt +5 -0
  48. pages/modules/Module_15/Overview.txt +5 -0
  49. pages/modules/Module_16/Overview.txt +5 -0
  50. pages/modules/Module_17/Overview.txt +5 -0
pages/Bonus.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Bonus"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_01.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_01"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_02.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_02"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_03.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_03"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_04.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_04"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_05.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_05"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_06.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_06"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_07.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_07"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_08.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_08"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_09.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_09"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_10.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_10"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_11.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_11"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_12.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_11"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_13.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_11"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_14.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_11"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_15.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_11"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_16.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_11"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_17.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_11"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_18.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_11"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_19.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_11"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Module_20.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Module_11"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/Overview.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CURRENT_MODULE = "Overview"
2
+
3
+ # Imports
4
+
5
+ import streamlit as st
6
+ import streamlit.components.v1 as components
7
+ from pages import load_pages
8
+
9
+ if "logged_in" not in st.session_state:
10
+ pass
11
+ else:
12
+ load_pages.load_page(CURRENT_MODULE)
13
+
14
+ if __name__ == "__main__":
15
+ load_pages.test_load()
16
+ print("<<< Module [", CURRENT_MODULE, "] Compile Successful >>>")
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
pages/__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ if __name__ == "__main__":
3
+ print("<<< __init__ Compile Successful >>>")
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
pages/assets/formulas.txt ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Expander: Null Hypothesis
2
+ **The “no‐effect” or “no‐difference” assumption**
3
+
4
+ Mathematical Notation:
5
+ H₀: θ = θ₀ (e.g. H₀: μ = 0)
6
+
7
+ *Example (one‐sample t‐test against μ₀ = 5):*
8
+ *x = c(5.1, 4.9, 5.0, 5.2)*
9
+ *t.test(x, mu = 5)*
10
+ End Expander:
11
+ Expander: Alternative Hypothesis
12
+ **The different claim you wish to support**
13
+
14
+ Mathematical Notation:
15
+ – Two‐sided: Hₐ: θ ≠ θ₀
16
+ – One‐sided: Hₐ: θ > θ₀ or Hₐ: θ < θ₀
17
+
18
+ *Example (test if mean > 5):*
19
+ *t.test(x, mu = 5, alternative = "greater")*
20
+ *or alternative = "two.sided" (default), "greater" or "less"*
21
+ End Expander:
22
+ Expander: p-value
23
+ **Assuming H₀ is true, this is the probability of seeing data**
24
+ **in your statistical test that is at least as extreme as yours**
25
+
26
+ Mathematical Notation:
27
+ p = P(Test statistic ≥ observed | H₀) (one‐tailed)
28
+ p = 2·P(|Test statistic| ≥ |observed| | H₀) (two‐tailed)
29
+
30
+ R function:
31
+ returned by many tests as $p.value
32
+
33
+ *Example (from t.test above):*
34
+ *res = t.test(x, mu = 5)*
35
+ *res$p.value*
36
+ End Expander:
37
+ Expander: Confidence Interval
38
+ A range of plausible values for the parameter calculated so that
39
+ e.g. 95% of such intervals (in repeated sampling) contain the true value
40
+ Mathematical form & notation:
41
+ CI₁₋α = [θ̂ ± z₁₋α/₂·SE(θ̂)] for normal distribution
42
+ CI₁₋α = [θ̂ ± t_{n–1,1–α/₂}·SE(θ̂)] for an unknown σ
43
+
44
+ *Example (95% CI for mean):*
45
+ *t.test(x, conf.level = 0.95)$conf.int*
46
+ End Expander:
47
+ Expander: Significance Level (α)
48
+ **The cutoff probability for a rare result under H₀**
49
+ **if p ≤ α you reject H₀**
50
+
51
+ Mathematical Notation:
52
+ α = P(Type I error)
53
+ = P(reject H₀ | H₀ true)
54
+
55
+ R function:
56
+ you compare to see if p.value ≤ α
57
+ and conf.level = 1–α
58
+ End Expander:
59
+ Expander: One-tailed test
60
+ **A test that looks for an effect in only one direction (greater or less)**
61
+
62
+ Mathematical Notation:
63
+ Hₐ: θ > θ₀ or Hₐ: θ < θ₀
64
+
65
+ R function:
66
+ alternative = "greater" or "less"
67
+
68
+ *Example:*
69
+ *t.test(x, mu = 5, alternative = "less")*
70
+ End Expander:
71
+ Expander: Two-tailed Test
72
+ **A test that looks for an effect in either direction**
73
+
74
+ Mathematical Notation:
75
+ Hₐ: θ ≠ θ₀
76
+
77
+ R function:
78
+ alternative = "two.sided" (default)
79
+
80
+ *Example:*
81
+ *t.test(x, mu = 5, alternative = "two.sided")*
82
+ End Expander:
83
+ Expander: Normal Distribution
84
+ **The symmetric bell‐shaped distribution**
85
+ Many statistical curves “look normal” when the sample size is large
86
+
87
+ Mathematical Notation:
88
+ X ~ N(μ, σ²)
89
+ The amount of area under the normal curve when 2 standard deviations
90
+ away to the right is written as P(Z ≤ 2.0) = 97.72% of the curve
91
+
92
+ R functions:
93
+ – dnorm(x, mean, sd) density
94
+ – pnorm(q, mean, sd) pdf
95
+ – qnorm(p, mean, sd) inverse of pnorm
96
+ – rnorm(n, mean, sd) n random samples
97
+
98
+ *Example:*
99
+ *pnorm(2.0, mean = 0, sd = 1) # = 97.72%*
100
+ *qnorm(0.9772, mean = 0, sd = 1) # = 2.0 = inverse of p*
101
+ End Expander:
102
+ Expander: False Positive (Type I Error)
103
+ **Rejecting H₀ when it is actually true**
104
+ *e.g. Unicorns do not exist but the statistical test said they did*
105
+ *when the null hypothesis (H₀) or base assumption is unicorns do not exist*
106
+ Mathematical Notation:
107
+ P(Type I error) = α
108
+ End Expander:
109
+ Expander: False Negative (Type II error)
110
+ **Failing to reject H₀ when it is actually false**
111
+ *e.g. Unicorns exist but the statistical test said they do not*
112
+ *when the null hypothesis (H₀) or base assumption is unicorns do not exist*
113
+ Also called Beta(β)
114
+
115
+ Mathematical Notation:
116
+ β = P(Type II error)
117
+ End Expander:
118
+ Expander: Power
119
+ Power is defined as 1 - Beta (β)
120
+ Reminder: Beta is a False Negative (Type II error)
121
+ so Beta is Failing to reject H₀ when it is actually false
122
+
123
+ Mathematical Notation:
124
+ Power = 1 – β
125
+ Power = P(reject H₀ | Hₐ true)
126
+ the conditional probability of rejecting the null hypothesis
127
+ when the alternative hypothesis is true and the null is false
128
+
129
+ R function:
130
+ use power.t.test(), power.prop.test(), etc.
131
+
132
+ *Example (power for one‐sample t):*
133
+ *power.t.test(n = 20, delta = 1, sd = 2, sig.level = 0.05, type = "one.sample")*
134
+ End Expander:
135
+ Expander: One-Sample T-Test
136
+ **Tests whether the mean of one group differs from a given value μ₀**
137
+
138
+ Mathematical Notation:
139
+ t = (x̄ – μ₀) / (s / √n), df = n – 1
140
+
141
+ R function:
142
+ t.test(x, mu, alternative, conf.level)
143
+ *where:*
144
+ – x: numeric vector
145
+ – mu: hypothesized mean μ₀
146
+ – alternative: "two.sided"/"greater"/"less"
147
+ – conf.level: e.g. 0.95
148
+
149
+ *Example:*
150
+ *x = c(5.1, 4.9, 5.0, 5.2)*
151
+ *t.test(x, mu = 5, alternative = "two.sided", conf.level = 0.95)*
152
+ End Expander:
153
+ Expander: Two-Sample T-Test
154
+ **Tests whether two group means differ.**
155
+
156
+ Mathematical Notation (unequal variances):
157
+ t = (x̄₁ – x̄₂) / √(s₁²/n₁ + s₂²/n₂), df by Welch’s formula
158
+
159
+ R function:
160
+ t.test(x, y, var.equal = FALSE, alternative, conf.level)
161
+ *where:*
162
+ – x, y: numeric vectors for each group
163
+ – var.equal: TRUE for pooled‐variance test, FALSE for Welch’s
164
+
165
+ *Example:*
166
+ *groupA = c(5.1,4.9,5.0,5.2)*
167
+ *groupB = c(5.3,5.4,5.2,5.5)*
168
+ *t.test(groupA, groupB, var.equal = FALSE)*
169
+ End Expander:
170
+ Expander: Z-test
171
+ **Like a t-test but uses a known σ or large-n approximation**
172
+
173
+ Mathematical Notation:
174
+ z = (x̄ – μ₀) / (σ / √n), compare to N(0,1)
175
+
176
+ R function:
177
+ use BSDA::z.test() or do manually (below)
178
+
179
+ *Example*
180
+ *x = c(102, 98, 100, 101, 99)*
181
+ *n = length(x)*
182
+ *mu0 = 100*
183
+ *sigma = 2*
184
+ *z = (mean(x) - mu0) / (sigma / sqrt(n))*
185
+ *p_value = 2 * pnorm(-abs(z)) # two‐sided*
186
+ End Expander:
187
+ Expander: Chi-Squared Test of Independence
188
+ **Tests whether two Categorical variables are related**
189
+
190
+ Mathematical Notation:
191
+ χ² = Σ_{i,j} (O_{i,j} – E_{i,j})² / E_{i,j}, df = (rows–1)(cols–1)
192
+
193
+ R function:
194
+ chisq.test(x, correct = TRUE/FALSE)
195
+ *where:*
196
+ – x: contingency table (matrix or table)
197
+ – correct: apply Yates’s continuity correction for 2×2 tables
198
+
199
+ *Example:*
200
+ *tbl = matrix(c(12, 5,7, 16), nrow = 2,*
201
+ * dimnames = list(Gene = c("A","B"),*
202
+ * Outcome = c("Yes","No")))*
203
+ *chisq.test(tbl, correct = FALSE)*
204
+ End Expander:
205
+ Expander: Chi-Squared Goodness-of-Fit Test (Frequencies)
206
+ **Tests if observed sample counts match expected proportions**
207
+
208
+ Mathematical Notation:
209
+ χ² = Σ (O_i – E_i)² / E_i, df = k – 1
210
+
211
+ R function:
212
+ chisq.test(x, p)
213
+ *where:*
214
+ – x: vector of observed counts
215
+ – p: vector of hypothesized probabilities (sum to 1)
216
+
217
+ *Example:*
218
+ *observed = c(50, 30, 20)*
219
+ *expected_probs = c(0.5, 0.3, 0.2)*
220
+ *chisq.test(observed, p = expected_probs)*
221
+ End Expander:
pages/assets/logo.jpg ADDED
pages/assets/profile.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 Student Profile
2
+
3
+ - **Student Name:** Charlie B
4
+ - **Department:** BMO Wealth
5
+ - **Expertise:** Intermediate
6
+
7
+ ## 🎯 Interests:
8
+ - Data science and analytics
9
+ - Predictive models
10
+ - Capital market applications
11
+
12
+ ## 🎯 Goals for Next Review:
13
+ - Complete topics in **Supervised Learning**.
14
+ - Begin study on Advanced Optimization Methods.
15
+ - Initiate **Computer Vision** topics.
16
+
17
+ ** Keep up the excellent work **
pages/assets/progress.txt ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 Progress Report
2
+
3
+ - **Student Name:** <Your Name>
4
+ - **Enrollment Date:** Sept 15, 2025
5
+ - **Report Date:** Nov 2, 2025
6
+
7
+ ---
8
+
9
+ # 📚 Progress Overview
10
+ Completed topics are marked with a checkmark (✔️),
11
+ while incomplete or pending topics remain unchecked.
12
+
13
+ ## 📈 Overall Progress Summary
14
+
15
+ | Curriculum Area | Completion (%) |
16
+ |------------------------------|----------------|
17
+ | Overview | 100% |
18
+ | Inference Concepts | 100% |
19
+ | One and Two-Tailed Tests | 100% |
20
+ | Mathematical Concepts | 75% |
21
+ | Normal Distribution | 75% |
22
+ | T-tests | 70% |
23
+ | Paired T-tests | 65% |
24
+ | Chi-Squared Independence | 0% |
25
+ | Chi-Squared Frequencies | 0% |
26
+ | Summary | 0% |
27
+
28
+ ---
29
+
30
+ ## ✅ Statistics and Probability
31
+ | Subtopic | Status |
32
+ |----------------------------------------|---------|
33
+ | Measures of Central Tendency | ✔️ |
34
+ | Variance and Standard Deviation | ✔️ |
35
+ | Probability Distributions | ✔️ |
36
+ | Central Limit Theorem & Applications | ✔️ |
37
+ | Hypothesis Testing | ✔️ |
38
+ | Bayesian Statistics | |
39
+
40
+ ---
41
+
42
+ **Keep up the excellent work, you're well on your way**
43
+ **to mastering this module! 🚀**
pages/load_pages.py ADDED
@@ -0,0 +1,483 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # =========================================================================
3
+ # Imports
4
+ # =========================================================================
5
+
6
+ import os, time, re, sys
7
+ import numpy as np
8
+ from openai import OpenAI
9
+
10
+ import streamlit as st
11
+ import streamlit.components.v1 as components
12
+
13
+ import urllib.parse
14
+
15
+ # =========================================================================
16
+ # AI Response Dialog
17
+ # =========================================================================
18
+
19
+ @st.dialog("🤖 Response")
20
+ def AI_gen_response(prompt):
21
+
22
+ MIN_PROMPT_LENGTH = 6
23
+
24
+ if len(prompt.strip()) < MIN_PROMPT_LENGTH:
25
+ print("ERROR: AI prompt too short")
26
+ st.markdown("*Your input is too short, please retype ...*") # clear output and print statement in italics
27
+ return
28
+
29
+ # AI API Call
30
+
31
+ with st.spinner("Thinking ...", show_time=True):
32
+
33
+ st.markdown("*Thinking about your response ...*") # clear output and print statement in italics
34
+
35
+ full_text = []
36
+ client = st.session_state["openai_client"]
37
+
38
+ stream = client.chat.completions.create(
39
+ model = st.session_state["openai_model"],
40
+ messages = [{"role": "user", "content": prompt}], # {"role": "admin", "content": admin_prompt},
41
+ stream = True,
42
+ )
43
+
44
+ for chunk in stream: # chunk is a ChatCompletionChunk
45
+ delta = chunk.choices[0].delta # “what changed since the prev. chunk”
46
+ if delta.content: # sometimes None (e.g. first chunk)
47
+ print(delta.content, end="", flush=True) # live printing
48
+ full_text.append(delta.content) # keep it if you need it
49
+ response = "".join(full_text) # the entire response as one string
50
+
51
+ format_text(response, input_directory="") # there is no input directory for the OpenAI API
52
+
53
+ return response # return the response for more programming if needed
54
+
55
+
56
+ # =========================================================================
57
+ # Symbolic Lookup Table - Greek (lower and upper, math and equality signs)
58
+ # =========================================================================
59
+
60
+ SYMBOLS: dict[str, str] = {
61
+ r"\alpha": "α", r"\beta": "β", r"\gamma": "γ", r"\delta": "δ",r"\epsilon": "ε",r"\zeta": "ζ", r"\eta": "η", r"\theta": "θ", r"\iota": "ι", r"\kappa": "κ", r"\lambda": "λ", r"\mu": "μ", r"\nu": "ν", r"\xi": "ξ", r"\omicron": "ο", r"\pi": "π", r"\rho": "ρ", r"\sigma": "σ", r"\tau": "τ", r"\upsilon": "υ", r"\phi": "φ", r"\chi": "χ", r"\psi": "ψ", r"\omega": "ω",
62
+ r"\Alpha": "Α", r"\Beta": "Β", r"\Gamma": "Γ", r"\Delta": "Δ", r"\Epsilon": "Ε",r"\Zeta": "Ζ", r"\Eta": "Η", r"\Theta": "Θ", r"\Iota": "Ι", r"\Kappa": "Κ", r"\Lambda": "Λ", r"\Mu": "Μ", r"\Nu": "Ν", r"\Xi": "Ξ", r"\Omicron": "Ο", r"\Pi": "Π", r"\Rho": "Ρ", r"\Sigma": "Σ", r"\Tau": "Τ", r"\Upsilon": "Υ", r"\Phi": "Φ", r"\Chi": "Χ", r"\Psi": "Ψ", r"\Omega": "Ω",
63
+ r"\pm": "±", r"\times": "×", r"\div": "÷", r"\cdot": "·", r"\sqrt": "√", r"\sum": "∑", r"\prod": "∏", r"\int": "∫", r"\infty": "∞", r"\partial": "∂", r"\nabla": "∇", r"\le": "≤", r"\ge": "≥", r"\neq": "≠", r"\approx": "≈",
64
+ r"\and": "∧", r"\or": "∨", r"\neg": "¬", r"\in": "∈", r"\notin": "∉", r"\subset": "⊂", r"\subseteq": "⊆",r"\supset": "⊃", r"\supseteq": "⊇", r"\cup": "∪", r"\cap": "∩", r"\angle": "∠", r"\triangle": "△",
65
+ r"\therefore": "∴", r"\because": "∵", r"\propto": "∝", r"\parallel": "∥",r"\perp": "⊥", r"\degree": "°", r"\bullet": "•", r"\rightarrow": "→", r"\leftarrow": "←", r"\uparrow": "↑",
66
+ r"\downarrow": "↓", r"\leftrightarrow": "↔", r"\ell": "ℓ", r"\Re": "ℜ", r"\Im": "ℑ", r"\aleph": "ℵ", r"\wp": "℘"
67
+ }
68
+
69
+ # =====================================================
70
+ # Functions - to convert symbol tags to symbols
71
+ # =====================================================
72
+
73
+ FORMULA_REGEX = re.compile(r'\\[A-Za-z]+')
74
+ BOLD_TXT_REGEX = re.compile(r'\\[A-Za-z]+{([^{}]*)}')
75
+
76
+ def test_load():
77
+ # print("load_pages - testing external call") # DEBUG
78
+ pass
79
+
80
+ def latex_to_unicode(text: str, table: dict[str, str] = SYMBOLS) -> str:
81
+ return FORMULA_REGEX.sub(lambda m: table.get(m.group(0), m.group(0)), text)
82
+
83
+ def latex_bold_to_markdown(text: str) -> str:
84
+ return BOLD_TXT_REGEX.sub(r'**\1**', text)
85
+
86
+ # =====================================================================================
87
+ # format_text - loads a text file, formats it and places streamlit components
88
+ # based on instructions from the text file (lesson/learning module) file
89
+ # =====================================================================================
90
+
91
+ def format_text(input_text, input_directory=""):
92
+
93
+ # --------------------------------------------------------------------------------
94
+ # Uses text file as input - input_text
95
+ # within the text are instructional tags used to build the content for the page
96
+ # This code parses the text line-by-line to determine what to display for the page
97
+ # --------------------------------------------------------------------------------
98
+
99
+ # Parse the raw text for certain backslashes for mathematical formulae and
100
+ # instruct the program to call the st.latex function to render
101
+
102
+ input_text = input_text.replace("\\[\n",'st.latex("')
103
+ input_text = input_text.replace("\\[",'st.latex("')
104
+ input_text = input_text.replace("\n\\]\n",'")\n')
105
+ input_text = input_text.replace("\\]\n",'")\n')
106
+
107
+ # Split the text line by line to parse
108
+
109
+ lines = input_text.split("\n")
110
+ idx = 0
111
+
112
+ # Scan each line
113
+
114
+ while(idx<len(lines)):
115
+
116
+ line = lines[idx].strip()
117
+
118
+ # -------------------------------
119
+ # Single-line interface tags
120
+ # -------------------------------
121
+
122
+ # Latex expression - render using st.latex()
123
+
124
+ if line[:len("st.latex(")]=="st.latex(":
125
+ if line[-2:]=='")':
126
+ st.latex(line[len("st.latex(")+1:-2]) # closed expression
127
+ else:
128
+ st.latex(line[len("st.latex(")+1:]) # open expression
129
+
130
+ elif line[:2]=='")': # closed expression notation - ignore
131
+ pass
132
+
133
+ # Question tag
134
+
135
+ elif line[:len("Question: ")]=="Question: ":
136
+ #st.text_area(label, value="", height=None, max_chars=None, key=None, help=None, on_change=None, args=None, kwargs=None, *, placeholder=None, disabled=False, label_visibility="visible")
137
+ with st.expander(label = line[len("Question: [00_01_02]")+1:] + "...", expanded=False, icon=":material/live_help:"):
138
+ question_key = line[11:19] # e.g. Question: [14_01_02]
139
+ print(line, question_key)
140
+ answer_text = st.text_area(label="Answer to Question", value="", height=200, key=question_key)
141
+
142
+ # Hint tag
143
+
144
+ elif line[:len("Hint: ")]=="Hint: ":
145
+ Hint_text = line.split("...")
146
+ with st.expander(label = Hint_text[0]+"...", expanded=False, icon=":material/voice_selection:"):
147
+ st.markdown(Hint_text[1])
148
+
149
+ # Load image tag - image is located in the module content folder and the tag has the file path
150
+
151
+ elif line[:len("Image: ")]=="Image: ":
152
+ file_str = line[len("Image: "):].strip()
153
+ default_width = 700
154
+ if file_str[-1]=="]": # a picture width (optional) is given
155
+ default_width = int(file_str[file_str.find("[")+1:-1])
156
+ file_str = file_str[:file_str.find("[")]
157
+ st.image(file_str, width=default_width) # st.image(image, caption=None, width=None, use_column_width=None, clamp=False, channels="RGB", output_format="auto", *, use_container_width=False)
158
+
159
+ # iFrame tag - render a web site in a container within a tab
160
+
161
+ elif line[:len("iframe: ")]=="iframe: ":
162
+
163
+ default_width = 500
164
+ default_height = 500
165
+
166
+ print("Running iframe")
167
+ file_str = line[len("iframe: "):].strip() # Get web site
168
+
169
+ if file_str[-1]=="]": # an optional width is given
170
+ default_width = int(file_str[file_str.find("[")+1:-1])
171
+ default_height = default_width # square by default
172
+ file_str = file_str[:file_str.find("[")]
173
+
174
+ file_str = file_str[1:-1] # Remove string delimiters for HTML page
175
+ print("Loading iframe:",file_str)
176
+
177
+ components.iframe(file_str,width=default_width,height=default_height)
178
+
179
+ # Link to sample code hosted externally e.g. Google Colab
180
+
181
+ elif line[:len("Code: ")]=="Code: ":
182
+ file_str = line[len("Code: "):].strip()
183
+ with st.expander(label = "Code for this lesson ...", expanded=True, icon=":material/terminal:"):
184
+ st.markdown(file_str)
185
+
186
+ # HTML instructions rendered inside a frame e.g. an interactive javascript element
187
+ # the HTML page is stored in the module content directory or is loaded from external source
188
+
189
+ elif line[:len("HTML: ")]=="HTML: ": # An HTML page to load and display - eg Web Widget
190
+
191
+ default_width = 700
192
+ default_height = 700
193
+
194
+ # print("HTML ",input_directory) # DEBUG
195
+
196
+ file_str = line[len("HTML: "):].strip()
197
+
198
+ if file_str[-1]=="]": # an optional video width is given
199
+ default_width = int(file_str[file_str.find("[")+1:-1])
200
+ default_height = default_width # square by default
201
+ file_str = file_str[:file_str.find("[")]
202
+
203
+ if file_str[:4] != "http":
204
+ file_str = os.path.join(input_directory,file_str)
205
+
206
+ # print(file_str) # DEBUG
207
+
208
+ try:
209
+ html_str = open(file_str, "r", encoding="UTF-8").read()
210
+ except Exception as err:
211
+ print(f"Unexpected {err=}, {type(err)=}",file_str)
212
+ else:
213
+ components.html(html_str, height=default_height, width=default_width, scrolling=True)
214
+
215
+ # External Web Link
216
+
217
+ elif line[:len("Link: ")]=="Link: ":
218
+ file_str = line[len("Link: "):].strip()
219
+ st.markdown(file_str)
220
+
221
+ # Text that can be copied
222
+
223
+ elif line[:len("Copy: ")]=="Copy: ":
224
+ file_str = line[len("Copy: "):].strip()
225
+ st.code(file_str,language="")
226
+
227
+ # Video
228
+
229
+ elif line[:len("Video: ")]=="Video: ":
230
+
231
+ default_width = 700
232
+
233
+ file_str = line[len("Video: "):].strip()
234
+
235
+ if file_str[-1]=="]": # an optional video width is given
236
+ default_width = int(file_str[file_str.find("[")+1:-1])
237
+ file_str = file_str[:file_str.find("[")]
238
+
239
+ video_filepath = os.path.join(st.session_state["start_dir"],"pages",input_directory,file_str)
240
+ video_file = open(video_filepath,"rb")
241
+
242
+ if video_file is None:
243
+ print("ERROR: Video did not load: ",video_filepath)
244
+ else:
245
+ intro_video = video_file.read()
246
+ st.video(intro_video, loop=True, autoplay=True, muted=False, width=default_width)
247
+
248
+
249
+ # ---------------------------------------------------------------------
250
+ # Multi-line interface tags
251
+ # These tags tell the program to scan ahead and read lines until a
252
+ # closure tag is found. The line pointer is advanced accordingly
253
+ # ---------------------------------------------------------------------
254
+
255
+ # R Code is run in an embedded widget. This will prepopluate the widget with the example code
256
+
257
+ elif line[:len("Expander:")]=="Expander:":
258
+
259
+ default_width = 800
260
+
261
+ expander_headline = line[len("Expander:"):].strip()
262
+ expander_string = ""
263
+
264
+ for c, expander_line in enumerate(lines[idx+1:]):
265
+ if expander_line[:len("End Expander:")]=="End Expander:":
266
+ idx+=1 # skip this line
267
+ break
268
+ else:
269
+ expander_string += expander_line + "\n"
270
+
271
+ idx+=c # Set global counter to skip past the lines already read in lookahead mode
272
+
273
+ with st.expander(label = expander_headline+"...", expanded=False, icon=":material/stars_2:"): #,width=default_width):
274
+ for expander_line in expander_string.split("\n"):
275
+ #st.write(expander_line)
276
+ st.markdown(expander_line)
277
+
278
+ # R Code is run in an embedded widget. This will prepopluate the widget with the example code
279
+
280
+ elif line[:len("R Code:")]=="R Code:":
281
+
282
+ r_code_string = ""
283
+
284
+ for c, r_code_line in enumerate(lines[idx+1:]):
285
+ if r_code_line[:len("End R Code:")]=="End R Code:":
286
+ idx+=1 # skip this line
287
+ break
288
+ else:
289
+ r_code_string += r_code_line + "\n"
290
+
291
+ idx+=c # Set global counter to skip past the lines already read in lookahead mode
292
+
293
+ URI_code = urllib.parse.quote(r_code_string)
294
+ components.html("<iframe width='675' height='575' src='https://rdrr.io/snippets/embed/?code=" + URI_code + "' frameborder='0'></iframe>", height=600, width = 700, scrolling=True)
295
+
296
+ # ---------------------------------------------------------------------
297
+ # A Cognitive Checkpoint is a point in the module where the student is asked to
298
+ # write a briefing that demonstrates whether they understand a concept
299
+ # The briefing is sent to the AI for evaluation
300
+ # Constructing this as a multi-line input gives the ability to enhance the admin prompt
301
+ # which will need custom instructions based on the checkpoint
302
+ # ---------------------------------------------------------------------
303
+
304
+ elif line[:len("Cognitive Checkpoint:")]=="Cognitive Checkpoint:":
305
+
306
+ question_key = line[23:31] # Unique key for response
307
+ question = "" # Multi-line question for cognitive response
308
+
309
+ for c, question_line in enumerate(lines[idx+1:]):
310
+ if question_line[:len("End Cognitive Checkpoint:")]=="End Cognitive Checkpoint:":
311
+ idx+=1 # skip this line
312
+ break
313
+ else:
314
+ question += question_line + "\n"
315
+
316
+ idx+=c # Set global counter to skip past the lines already read in lookahead mode
317
+
318
+ st.write(question) # Write question
319
+
320
+ # Provide area to write response
321
+
322
+ with st.expander(label = "Cognitive Checkpoint:", expanded=True, icon=":material/live_help:"):
323
+
324
+ if answer_text := st.text_area(label="Answer to Question", value="", height=150, key=question_key): # := is the "Walrus Operator - assigns, checks and runs function"
325
+
326
+ admin_prompt = '''
327
+ You are a teacher.
328
+ Evaluate the following statement delimited in square brackets for accuracy from your student.
329
+ For each logical statement, grade it as one of three options: correct, misunderstanding, incorrect.
330
+ For each statement cite the grade, student comment, your response, corrected response if required.
331
+ Provide a summary at the end, not in table form, with the grade and a summary of the student comment
332
+ '''
333
+
334
+ # Return your assessment in JSON format # Optional - for eval purposes
335
+
336
+ AI_question = admin_prompt + "[" + answer_text + "]"
337
+
338
+ try:
339
+ AI_gen_response(prompt=AI_question)
340
+ except Exception as e:
341
+ print("ERROR: Dialog box open. Message suppressed\n",str(e))
342
+
343
+
344
+ # ------------------------------------------
345
+ # DEFAULT Instructions if no tag is provided
346
+ # ------------------------------------------
347
+
348
+ else:
349
+ line_unicode = latex_to_unicode(line) # convert text to unicode symbols if needed
350
+ line_bold = latex_bold_to_markdown(line_unicode) # bold text
351
+ # print(line_bold)
352
+ st.markdown(line_bold) # markdown that line
353
+
354
+ # ------------------------------------------
355
+ # Increment line counter / go to next line
356
+ # ------------------------------------------
357
+
358
+ idx+=1
359
+
360
+
361
+ # END Parse text
362
+
363
+ return
364
+
365
+
366
+ # =====================================================
367
+ # Load Content
368
+ # =====================================================
369
+
370
+ def load_content(module):
371
+
372
+ input_directory = os.path.join(st.session_state["start_dir"],"pages","modules",module)
373
+
374
+ # if file exists - otherwise do nothing
375
+ content_str = open(os.path.join(input_directory,"Overview.txt"), "r", encoding="UTF-8").read()
376
+ tab_content = content_str.split("---\n")
377
+
378
+ # Display Module title if one is given, otherwise blank
379
+
380
+ title = tab_content[0].strip()
381
+ if len(title)>0:
382
+ st.subheader(title)
383
+
384
+ # Draw tabs according to page count
385
+
386
+ tab_list = ["🚀"+str(idx+1) for idx,x in enumerate(tab_content[1:])]
387
+ tabs = st.tabs(tab_list)
388
+
389
+ # For each tab, render the appropriate content
390
+
391
+ for idx,tab in enumerate(tabs):
392
+ with tab:
393
+ format_text(tab_content[idx+1], input_directory)
394
+
395
+ # Add AI Bot Interface to bottom of page
396
+
397
+ ## if prompt := st.chat_input("I would like to learn about ..."):
398
+ ## AI_gen_response(prompt=prompt)
399
+
400
+ return
401
+
402
+ # =====================================================
403
+ # Load Page
404
+ # =====================================================
405
+
406
+ def load_page(module):
407
+
408
+ if "logged_in" not in st.session_state: # User is not logged in - don't load content
409
+ return
410
+
411
+ # --------------------------------------------------
412
+ # Sidebar
413
+ # --------------------------------------------------
414
+
415
+ asset_dir = os.path.join(st.session_state["start_dir"],"pages","assets")
416
+
417
+ with st.sidebar:
418
+
419
+ with st.expander("Lessons", expanded=True, icon=":material/library_books:"):
420
+
421
+ st.page_link("pages/Overview.py", label="Laurier Years", icon=":material/rocket_launch:")
422
+ st.page_link("pages/Module_01.py", label="World War 1", icon=":material/rocket_launch:")
423
+ ## st.page_link("pages/Module_02.py", label="Mathematical Foundations", icon=":material/difference:")
424
+ ## st.page_link("pages/Module_03.py", label="The Normal Distribution", icon=":material/cadence:")
425
+ ## st.page_link("pages/Module_04.py", label="One Sided Tests", icon=":material/compare:")
426
+ ## st.page_link("pages/Module_05.py", label="Tests for Two Samples", icon=":material/speed_2x:")
427
+ ## st.page_link("pages/Module_06.py", label="Paired Tests", icon=":material/speed_2x:")
428
+ ## st.page_link("pages/Module_07.py", label="Testing Independence", icon=":material/superscript:")
429
+ ## st.page_link("pages/Module_08.py", label="Testing Frequencies", icon=":material/superscript:")
430
+ ## st.page_link("pages/Module_09.py", label="Summary", icon=":material/format_list_numbered:")
431
+ ## st.page_link("pages/Overview.py", label="Amelia History Quiz", icon=":material/rocket_launch:")
432
+
433
+ ## with st.expander("Ask the AI", expanded=False, icon=":material/smart_toy:"):
434
+ ##
435
+ ## if AI_question := st.text_input(label="Ask the AI", value="", key="AI_Question"):
436
+ ## try:
437
+ ## AI_gen_response(prompt=AI_question)
438
+ ## except Exception as e:
439
+ ## print("ERROR: Dialog box open. Message suppressed\n",str(e))
440
+ ##
441
+ ## # Callback function to clear text from previous AI question inputs
442
+ ##
443
+ ## def set_name(new_text):
444
+ ## st.session_state.AI_Question = new_text
445
+ ##
446
+ ## st.button('Clear',on_click=set_name, args=[''])
447
+
448
+ ## with st.expander("R Calculator", expanded=False, icon=":material/calculate:"):
449
+ ## components.html("<iframe width='500' height='500' src='https://rdrr.io/snippets/embed/?code=""' frameborder='0'></iframe>", height=550, width = 550, scrolling=True)
450
+ ##
451
+ ## with st.expander("Statistical Glossary", expanded=False, icon=":material/functions:"):
452
+ ## overview_dir = os.path.join(st.session_state["start_dir"],"pages","assets")
453
+ ## overview_str = open(os.path.join(overview_dir,"formulas.txt"), "r", encoding="UTF-8").read()
454
+ ## format_text(overview_str, overview_dir)
455
+ ##
456
+ ## with st.expander("Your Progress",expanded=False, icon=":material/preliminary:"):
457
+ ## progress_str = open(os.path.join(st.session_state["start_dir"],"pages","assets","progress.txt"), "r", encoding="UTF-8").read()
458
+ ## st.markdown(progress_str)
459
+
460
+ with st.expander("Logout", expanded=False, icon=":material/logout:"): #
461
+ if st.button("Logout"):
462
+ del st.session_state["logged_in"]
463
+ st.switch_page("app.py") # switch to main page
464
+ st.rerun() # should invoke login dialog
465
+
466
+ # END Sidebar
467
+
468
+ # --------------------------------------------------
469
+ # Main Screen Content - e.g. Pages with Tabs
470
+ # --------------------------------------------------
471
+
472
+ if "logged_in" not in st.session_state: # check if user has logged out with sidebar
473
+ pass
474
+ else:
475
+ load_content(module) # otherwise load and provide access to the content
476
+
477
+ # =================================================
478
+ # Standalone Code if Program is Run as Main
479
+ # =================================================
480
+
481
+ if __name__ == "__main__":
482
+ pass
483
+
pages/modules/Bonus/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Copy_Overview.bat ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ copy overview.txt c:.\Module_01
2
+ copy overview.txt c:.\Module_02
3
+ copy overview.txt c:.\Module_03
4
+ copy overview.txt c:.\Module_04
5
+ copy overview.txt c:.\Module_05
6
+ copy overview.txt c:.\Module_06
7
+ copy overview.txt c:.\Module_07
8
+ copy overview.txt c:.\Module_08
9
+ copy overview.txt c:.\Module_09
10
+ copy overview.txt c:.\Module_10
11
+ copy overview.txt c:.\Module_11
12
+ copy overview.txt c:.\Module_12
13
+ copy overview.txt c:.\Module_13
14
+ copy overview.txt c:.\Module_14
15
+ copy overview.txt c:.\Module_15
16
+ copy overview.txt c:.\Module_16
17
+ copy overview.txt c:.\Module_17
18
+ copy overview.txt c:.\Module_18
19
+ copy overview.txt c:.\Module_19
20
+ copy overview.txt c:.\Module_20
21
+ copy overview.txt c:.\Overview
pages/modules/Module_01/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Canadian History Flashcards
2
+ ---
3
+ HTML: flashcards01.html
4
+ ---
5
+ HTML: flashcards02.html
pages/modules/Module_01/flashcards - template.html ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Canadian History Flashcards</title>
6
+ <style>
7
+ body {
8
+ font-family: Arial, sans-serif;
9
+ background: #f0f0f0;
10
+ margin: 0;
11
+ padding: 20px;
12
+ }
13
+ h1 {
14
+ text-align: center;
15
+ }
16
+ .flashcard {
17
+ position: relative;
18
+ width: 400px;
19
+ height: 400px;
20
+ margin: 40px auto;
21
+ padding: 20px;
22
+ background: #fff;
23
+ border-radius: 8px;
24
+ box-shadow: 0 4px 8px rgba(0,0,0,0.2);
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ text-align: center;
29
+ font-size: 18px;
30
+ cursor: pointer;
31
+ user-select: none;
32
+ }
33
+ .checkmark {
34
+ position: absolute;
35
+ top: 10px;
36
+ right: 10px;
37
+ font-size: 24px;
38
+ color: gray;
39
+ cursor: pointer;
40
+ }
41
+ #controls {
42
+ text-align: center;
43
+ margin-top: 20px;
44
+ }
45
+ #controls button {
46
+ padding: 8px 16px;
47
+ margin: 0 10px;
48
+ font-size: 16px;
49
+ }
50
+ #controls button:disabled {
51
+ opacity: 0.5;
52
+ cursor: not-allowed;
53
+ }
54
+ </style>
55
+ </head>
56
+ <body>
57
+ <div id="flashcard" class="flashcard">
58
+ <div id="checkmark" class="checkmark">✔</div>
59
+ <div id="content"></div>
60
+ </div>
61
+
62
+ <div id="controls">
63
+ <button id="prev">Previous</button>
64
+ <button id="next">Next</button>
65
+ </div>
66
+
67
+
68
+
69
+
70
+
71
+
72
+ <script>
73
+ // sample flashcards
74
+ const flashcards =
75
+ [
76
+ ];
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+ let currentIndex = 0;
91
+ let showAnswer = false;
92
+
93
+ const cardEl = document.getElementById('flashcard');
94
+ const contentEl = document.getElementById('content');
95
+ const checkEl = document.getElementById('checkmark');
96
+ const prevBtn = document.getElementById('prev');
97
+ const nextBtn = document.getElementById('next');
98
+
99
+ function renderCard() {
100
+ const card = flashcards[currentIndex];
101
+
102
+ if (showAnswer) {
103
+ contentEl.textContent = card.answer;
104
+ checkEl.style.display = 'none';
105
+ } else {
106
+ contentEl.textContent = card.question;
107
+ checkEl.style.display = 'block';
108
+ checkEl.style.color = card.correct ? 'green' : 'gray';
109
+ }
110
+
111
+ prevBtn.disabled = currentIndex === 0;
112
+ nextBtn.disabled = currentIndex === flashcards.length - 1;
113
+ }
114
+
115
+ // Flip card on click (except when clicking the checkmark)
116
+ cardEl.addEventListener('click', () => {
117
+ showAnswer = !showAnswer;
118
+ renderCard();
119
+ });
120
+
121
+ // Toggle correct mark
122
+ checkEl.addEventListener('click', e => {
123
+ e.stopPropagation(); // don't also flip the card
124
+ flashcards[currentIndex].correct = !flashcards[currentIndex].correct;
125
+ renderCard();
126
+ });
127
+
128
+ prevBtn.addEventListener('click', () => {
129
+ if (currentIndex > 0) {
130
+ currentIndex--;
131
+ showAnswer = false;
132
+ renderCard();
133
+ }
134
+ });
135
+
136
+ nextBtn.addEventListener('click', () => {
137
+ if (currentIndex < flashcards.length - 1) {
138
+ currentIndex++;
139
+ showAnswer = false;
140
+ renderCard();
141
+ }
142
+ });
143
+
144
+ // Initial display
145
+ renderCard();
146
+ </script>
147
+ </body>
148
+ </html>
pages/modules/Module_01/flashcards01.html ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Canadian History Flashcards</title>
6
+ <style>
7
+ body {
8
+ font-family: Arial, sans-serif;
9
+ background: #f0f0f0;
10
+ margin: 0;
11
+ padding: 20px;
12
+ }
13
+ h1 {
14
+ text-align: center;
15
+ }
16
+ .flashcard {
17
+ position: relative;
18
+ width: 400px;
19
+ height: 400px;
20
+ margin: 40px auto;
21
+ padding: 20px;
22
+ background: #fff;
23
+ border-radius: 8px;
24
+ box-shadow: 0 4px 8px rgba(0,0,0,0.2);
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ text-align: center;
29
+ font-size: 18px;
30
+ cursor: pointer;
31
+ user-select: none;
32
+ }
33
+ .checkmark {
34
+ position: absolute;
35
+ top: 10px;
36
+ right: 10px;
37
+ font-size: 24px;
38
+ color: gray;
39
+ cursor: pointer;
40
+ }
41
+ #controls {
42
+ text-align: center;
43
+ margin-top: 20px;
44
+ }
45
+ #controls button {
46
+ padding: 8px 16px;
47
+ margin: 0 10px;
48
+ font-size: 16px;
49
+ }
50
+ #controls button:disabled {
51
+ opacity: 0.5;
52
+ cursor: not-allowed;
53
+ }
54
+ </style>
55
+ </head>
56
+ <body>
57
+ <div id="flashcard" class="flashcard">
58
+ <div id="checkmark" class="checkmark">✔</div>
59
+ <div id="content"></div>
60
+ </div>
61
+
62
+ <div id="controls">
63
+ <button id="prev">Previous</button>
64
+ <button id="next">Next</button>
65
+ </div>
66
+
67
+ <script>
68
+ // sample flashcards
69
+ const flashcards =
70
+
71
+ [
72
+ {
73
+ "question": "What does the acronym 'M.A.I.N.S.' stand for in the context of the causes of World War I?",
74
+ "answer": "'M.A.I.N.S.' stands for Militarism, Alliances, Imperialism, Nationalism, and the Spark.",
75
+ "correct": false
76
+ },
77
+ {
78
+ "question": "What is nationalism?",
79
+ "answer": "Nationalism refers to loyalty to one's country and people.",
80
+ "correct": false
81
+ },
82
+ {
83
+ "question": "How does imperialism contribute to conflict?",
84
+ "answer": "Imperialism involves extending a country's power through diplomacy, military force, and colonization, exemplified by events like the Scramble for Africa.",
85
+ "correct": false
86
+ },
87
+ {
88
+ "question": "Define militarism.",
89
+ "answer": "Militarism is the belief in the power of a strong military.",
90
+ "correct": false
91
+ },
92
+ {
93
+ "question": "What was the arms race?",
94
+ "answer": "The arms race was a competition among countries to build up large arsenals of weapons, leading to increased tension and vulnerability.",
95
+ "correct": false
96
+ },
97
+ {
98
+ "question": "What is the concept of 'mutually assured destruction' (MAD)?",
99
+ "answer": "MAD is a military strategy where both sides in a conflict have the ability to destroy each other, leading to a deterrent against starting a war.",
100
+ "correct": false
101
+ },
102
+ {
103
+ "question": "How did alliances contribute to the outbreak of World War I?",
104
+ "answer": "The formation of alliances increased fear and suspicion among nations, making conflicts more likely due to mutual defense agreements.",
105
+ "correct": false
106
+ },
107
+ {
108
+ "question": "What were the major countries in the Triple Entente?",
109
+ "answer": "The Triple Entente included France, Russia, and Britain.",
110
+ "correct": false
111
+ },
112
+ {
113
+ "question": "What countries were part of the Triple Alliance?",
114
+ "answer": "The Triple Alliance consisted of Germany, Austria-Hungary, and Italy.",
115
+ "correct": false
116
+ },
117
+ {
118
+ "question": "What event triggered the start of World War I?",
119
+ "answer": "The assassination of Archduke Franz Ferdinand on June 28, 1914, triggered the start of World War I.",
120
+ "correct": false
121
+ },
122
+ {
123
+ "question": "Who assassinated Archduke Franz Ferdinand?",
124
+ "answer": "Archduke Ferdinand was assassinated by Gavrilo Princip, a member of the Black Hand.",
125
+ "correct": false
126
+ },
127
+ {
128
+ "question": "What ultimatum did Austria-Hungary issue to Serbia?",
129
+ "answer": "Austria-Hungary issued an ultimatum demanding that Serbia meet certain demands, leading to conflict after Serbia's partial acceptance.",
130
+ "correct": false
131
+ },
132
+ {
133
+ "question": "Which countries declared war after the assassination of Archduke Ferdinand?",
134
+ "answer": "Germany declared war on Russia and France, followed by Britain's entry into the war.",
135
+ "correct": false
136
+ },
137
+ {
138
+ "question": "What was Canada's role in World War I?",
139
+ "answer": "Canada, as a dominion of Britain, automatically entered the war in support of the Allies, contributing troops and resources.",
140
+ "correct": false
141
+ },
142
+ {
143
+ "question": "What was the significance of the Battle of Vimy Ridge for Canada?",
144
+ "answer": "The Battle of Vimy Ridge is often regarded as a defining moment for Canada, marking a sense of national pride and unity.",
145
+ "correct": false
146
+ },
147
+ {
148
+ "question": "How did World War I impact Canada socially and politically?",
149
+ "answer": "The war led to changes in Canadian society, including increased roles for women, economic impact, and heightened nationalism.",
150
+ "correct": false
151
+ }
152
+ ];
153
+
154
+ let currentIndex = 0;
155
+ let showAnswer = false;
156
+
157
+ const cardEl = document.getElementById('flashcard');
158
+ const contentEl = document.getElementById('content');
159
+ const checkEl = document.getElementById('checkmark');
160
+ const prevBtn = document.getElementById('prev');
161
+ const nextBtn = document.getElementById('next');
162
+
163
+ function renderCard() {
164
+ const card = flashcards[currentIndex];
165
+
166
+ if (showAnswer) {
167
+ contentEl.textContent = card.answer;
168
+ checkEl.style.display = 'none';
169
+ } else {
170
+ contentEl.textContent = card.question;
171
+ checkEl.style.display = 'block';
172
+ checkEl.style.color = card.correct ? 'green' : 'gray';
173
+ }
174
+
175
+ prevBtn.disabled = currentIndex === 0;
176
+ nextBtn.disabled = currentIndex === flashcards.length - 1;
177
+ }
178
+
179
+ // Flip card on click (except when clicking the checkmark)
180
+ cardEl.addEventListener('click', () => {
181
+ showAnswer = !showAnswer;
182
+ renderCard();
183
+ });
184
+
185
+ // Toggle correct mark
186
+ checkEl.addEventListener('click', e => {
187
+ e.stopPropagation(); // don't also flip the card
188
+ flashcards[currentIndex].correct = !flashcards[currentIndex].correct;
189
+ renderCard();
190
+ });
191
+
192
+ prevBtn.addEventListener('click', () => {
193
+ if (currentIndex > 0) {
194
+ currentIndex--;
195
+ showAnswer = false;
196
+ renderCard();
197
+ }
198
+ });
199
+
200
+ nextBtn.addEventListener('click', () => {
201
+ if (currentIndex < flashcards.length - 1) {
202
+ currentIndex++;
203
+ showAnswer = false;
204
+ renderCard();
205
+ }
206
+ });
207
+
208
+ // Initial display
209
+ renderCard();
210
+ </script>
211
+ </body>
212
+ </html>
pages/modules/Module_01/flashcards02.html ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Canadian History Flashcards</title>
6
+ <style>
7
+ body {
8
+ font-family: Arial, sans-serif;
9
+ background: #f0f0f0;
10
+ margin: 0;
11
+ padding: 20px;
12
+ }
13
+ h1 {
14
+ text-align: center;
15
+ }
16
+ .flashcard {
17
+ position: relative;
18
+ width: 400px;
19
+ height: 400px;
20
+ margin: 40px auto;
21
+ padding: 20px;
22
+ background: #fff;
23
+ border-radius: 8px;
24
+ box-shadow: 0 4px 8px rgba(0,0,0,0.2);
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ text-align: center;
29
+ font-size: 18px;
30
+ cursor: pointer;
31
+ user-select: none;
32
+ }
33
+ .checkmark {
34
+ position: absolute;
35
+ top: 10px;
36
+ right: 10px;
37
+ font-size: 24px;
38
+ color: gray;
39
+ cursor: pointer;
40
+ }
41
+ #controls {
42
+ text-align: center;
43
+ margin-top: 20px;
44
+ }
45
+ #controls button {
46
+ padding: 8px 16px;
47
+ margin: 0 10px;
48
+ font-size: 16px;
49
+ }
50
+ #controls button:disabled {
51
+ opacity: 0.5;
52
+ cursor: not-allowed;
53
+ }
54
+ </style>
55
+ </head>
56
+ <body>
57
+ <div id="flashcard" class="flashcard">
58
+ <div id="checkmark" class="checkmark">✔</div>
59
+ <div id="content"></div>
60
+ </div>
61
+
62
+ <div id="controls">
63
+ <button id="prev">Previous</button>
64
+ <button id="next">Next</button>
65
+ </div>
66
+
67
+ <script>
68
+ // sample flashcards
69
+ const flashcards =
70
+
71
+ [
72
+ {
73
+ "question": "What was the main goal of the Paris Peace Conference in 1919?",
74
+ "answer": "The main goal was to create a treaty that would promote peace and prevent future wars.",
75
+ "correct": false
76
+ },
77
+ {
78
+ "question": "Who represented Canada at the Paris Peace Conference?",
79
+ "answer": "Prime Minister Robert Borden represented Canada.",
80
+ "correct": false
81
+ },
82
+ {
83
+ "question": "What was Woodrow Wilson's 14-point plan focused on?",
84
+ "answer": "It focused on political and territorial changes aimed at maintaining long-term stability in Europe.",
85
+ "correct": false
86
+ },
87
+ {
88
+ "question": "What were two key political changes proposed in the 14 points?",
89
+ "answer": "Two key political changes were the elimination of secret treaties and the establishment of free trade between nations.",
90
+ "correct": false
91
+ },
92
+ {
93
+ "question": "What was a significant territorial change proposed in Wilson's 14 points?",
94
+ "answer": "Belgium was to be freed as it was before the war.",
95
+ "correct": false
96
+ },
97
+ {
98
+ "question": "Why was Germany not invited to the Paris Peace Conference?",
99
+ "answer": "Germany was not invited because the victorious countries held a grudge and wanted to impose strict terms without German input.",
100
+ "correct": false
101
+ },
102
+ {
103
+ "question": "What was the 'War Guilt Clause' in the Treaty of Versailles?",
104
+ "answer": "The 'War Guilt Clause' (Article 231) required Germany to accept full responsibility for causing the war.",
105
+ "correct": false
106
+ },
107
+ {
108
+ "question": "What reparations did Germany have to pay as a result of the Treaty of Versailles?",
109
+ "answer": "Germany was required to pay approximately $33 billion in war damages.",
110
+ "correct": false
111
+ },
112
+ {
113
+ "question": "What was the League of Nations?",
114
+ "answer": "The League of Nations was an organization founded to protect world peace and prevent future conflicts.",
115
+ "correct": false
116
+ },
117
+ {
118
+ "question": "What impact did the Treaty of Versailles have on Germany's military?",
119
+ "answer": "The treaty severely limited the size of the German military, allowing only a small army and prohibiting air forces and submarines.",
120
+ "correct": false
121
+ },
122
+ {
123
+ "question": "What was one of the main outcomes of the Treaty of Versailles for Canada?",
124
+ "answer": "Canada gained recognition for its contributions in the war and was allowed to sign the treaty under Britain's name.",
125
+ "correct": false
126
+ },
127
+ {
128
+ "question": "What significant changes occurred in international borders after the Treaty of Versailles?",
129
+ "answer": "New countries were created, and territories were adjusted, such as Alsace-Lorraine being returned to France and the division of Austria-Hungary.",
130
+ "correct": false
131
+ },
132
+ {
133
+ "question": "What was the consequence of the Treaty of Versailles on Germany's economy?",
134
+ "answer": "Germany's economy was severely weakened due to the reparations and the loss of territories and resources.",
135
+ "correct": false
136
+ },
137
+ {
138
+ "question": "What global event did Canada face shortly after World War I?",
139
+ "answer": "Canada faced the Spanish Flu Epidemic, which killed nearly 50 million people worldwide.",
140
+ "correct": false
141
+ },
142
+ {
143
+ "question": "How did the Treaty of Versailles contribute to the rise of Adolf Hitler?",
144
+ "answer": "The severe terms and national humiliation felt by Germans created widespread resentment that fueled Hitler's rise to power.",
145
+ "correct": false
146
+ },
147
+ {
148
+ "question": "What impact did the Treaty of Versailles have on future conflicts?",
149
+ "answer": "The treaty's harsh terms and Germany's resentment contributed to a cycle of conflict that eventually led to World War II.",
150
+ "correct": false
151
+ }
152
+
153
+ ];
154
+
155
+
156
+
157
+ let currentIndex = 0;
158
+ let showAnswer = false;
159
+
160
+ const cardEl = document.getElementById('flashcard');
161
+ const contentEl = document.getElementById('content');
162
+ const checkEl = document.getElementById('checkmark');
163
+ const prevBtn = document.getElementById('prev');
164
+ const nextBtn = document.getElementById('next');
165
+
166
+ function renderCard() {
167
+ const card = flashcards[currentIndex];
168
+
169
+ if (showAnswer) {
170
+ contentEl.textContent = card.answer;
171
+ checkEl.style.display = 'none';
172
+ } else {
173
+ contentEl.textContent = card.question;
174
+ checkEl.style.display = 'block';
175
+ checkEl.style.color = card.correct ? 'green' : 'gray';
176
+ }
177
+
178
+ prevBtn.disabled = currentIndex === 0;
179
+ nextBtn.disabled = currentIndex === flashcards.length - 1;
180
+ }
181
+
182
+ // Flip card on click (except when clicking the checkmark)
183
+ cardEl.addEventListener('click', () => {
184
+ showAnswer = !showAnswer;
185
+ renderCard();
186
+ });
187
+
188
+ // Toggle correct mark
189
+ checkEl.addEventListener('click', e => {
190
+ e.stopPropagation(); // don't also flip the card
191
+ flashcards[currentIndex].correct = !flashcards[currentIndex].correct;
192
+ renderCard();
193
+ });
194
+
195
+ prevBtn.addEventListener('click', () => {
196
+ if (currentIndex > 0) {
197
+ currentIndex--;
198
+ showAnswer = false;
199
+ renderCard();
200
+ }
201
+ });
202
+
203
+ nextBtn.addEventListener('click', () => {
204
+ if (currentIndex < flashcards.length - 1) {
205
+ currentIndex++;
206
+ showAnswer = false;
207
+ renderCard();
208
+ }
209
+ });
210
+
211
+ // Initial display
212
+ renderCard();
213
+ </script>
214
+ </body>
215
+ </html>
pages/modules/Module_02/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_03/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_04/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_05/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_06/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_07/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_08/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_09/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_10/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_11/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_12/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_13/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_14/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_15/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_16/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page
pages/modules/Module_17/Overview.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Title
2
+ ---
3
+ #### Blank Page
4
+ ---
5
+ #### Last Page