raymondEDS commited on
Commit
3cc080f
Β·
1 Parent(s): aa1280b

Demo for first week.

Browse files
.gitignore ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Environment variables
2
+ .env
3
+ .env.local
4
+ .env.development
5
+ .env.test
6
+ .env.production
7
+
8
+ # Python
9
+ __pycache__/
10
+ *.py[cod]
11
+ *$py.class
12
+ *.so
13
+ .Python
14
+ build/
15
+ develop-eggs/
16
+ dist/
17
+ downloads/
18
+ eggs/
19
+ .eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+ MANIFEST
30
+
31
+ # Virtual environments
32
+ venv/
33
+ env/
34
+ ENV/
35
+ env.bak/
36
+ venv.bak/
37
+ .venv/
38
+
39
+ # IDE
40
+ .vscode/
41
+ .idea/
42
+ *.swp
43
+ *.swo
44
+ *~
45
+
46
+ # OS
47
+ .DS_Store
48
+ .DS_Store?
49
+ ._*
50
+ .Spotlight-V100
51
+ .Trashes
52
+ ehthumbs.db
53
+ Thumbs.db
54
+
55
+ # Logs
56
+ *.log
57
+ logs/
58
+
59
+ # Temporary files
60
+ *.tmp
61
+ *.temp
62
+ temp/
63
+ tmp/
64
+
65
+ # Database
66
+ *.db
67
+ *.sqlite
68
+ *.sqlite3
69
+
70
+ # Jupyter Notebook
71
+ .ipynb_checkpoints
72
+
73
+ # pyenv
74
+ .python-version
75
+
76
+ # Local development files
77
+ run_app.py
78
+ local_config.py
79
+ local_settings.py
80
+
81
+ # Hugging Face Spaces specific (keep these for deployment)
82
+ # .streamlit/config.toml - Keep this for Spaces deployment
83
+ # Dockerfile - Keep this for containerization
84
+ # .gitattributes - Keep this for LFS handling
85
+
86
+ # User uploaded files (if any local storage)
87
+ uploads/
88
+ user_files/
89
+ temp_uploads/
90
+
91
+ # Cache
92
+ .cache/
93
+ .streamlit/cache/
94
+
95
+ # Secrets (additional protection)
96
+ secrets.toml
97
+ .streamlit/secrets.toml
Dockerfile CHANGED
@@ -18,4 +18,4 @@ EXPOSE 8501
18
 
19
  HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
20
 
21
- ENTRYPOINT ["streamlit", "run", "src/streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
 
18
 
19
  HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
20
 
21
+ ENTRYPOINT ["streamlit", "run", "src/main.py", "--server.port=8501", "--server.address=0.0.0.0"]
README.md CHANGED
@@ -1,6 +1,6 @@
1
  ---
2
- title: Dev LMS
3
- emoji: πŸ“š
4
  colorFrom: blue
5
  colorTo: purple
6
  sdk: docker
@@ -9,51 +9,55 @@ tags:
9
  - streamlit
10
  - lms
11
  - education
12
- - pdf
13
  pinned: false
14
- short_description: LMS with login and PDF upload
15
  ---
16
 
17
- # Dev LMS - Learning Management System
18
 
19
- A comprehensive Learning Management System built with Streamlit that provides user authentication and PDF document management capabilities. **Cloud-ready and optimized for Hugging Face Spaces deployment.**
20
 
21
- ## πŸš€ Features
22
 
23
  ### πŸ” Authentication
24
- - Secure user login system
25
- - Multiple user roles (Admin, Teacher, Student)
26
  - Session management with cookies
27
  - Password hashing for security
28
 
29
- ### πŸ“„ Document Management
30
- - PDF document upload and storage
31
- - Text extraction from PDF files
32
- - Document preview and search functionality
33
- - Document library with user ownership tracking
34
- - **Cloud-ready storage using session state**
35
 
36
  ### πŸ“Š Dashboard
37
- - User activity metrics
38
- - Document statistics
39
- - Recent activity tracking
40
- - System overview
41
 
42
- ### πŸ” Search & Navigation
43
- - Search documents by filename, content, or owner
44
- - Filter documents by various criteria
45
- - Easy navigation between different sections
46
- - Document categorization
47
 
48
- ## πŸ‘₯ Default Users
49
 
50
- The system comes with three default user accounts:
51
 
52
- | Role | Username | Password |
53
- |------|----------|----------|
54
- | Administrator | `admin` | `admin123` |
55
- | Teacher | `teacher` | `teacher123` |
56
- | Student | `student` | `student123` |
 
 
 
 
 
57
 
58
  ## πŸ› οΈ Installation & Usage
59
 
@@ -65,55 +69,87 @@ The system comes with three default user accounts:
65
 
66
  2. **Run the Application:**
67
  ```bash
68
- streamlit run src/streamlit_app.py
69
- ```
70
- Or use the convenient startup script:
71
- ```bash
72
- python run_app.py
73
  ```
74
 
75
  3. **Access the Application:**
76
  - Open your browser and go to `http://localhost:8501`
77
- - Login with one of the default credentials
78
- - Start uploading and managing PDF documents!
79
 
80
  ### Cloud Deployment
81
- The application is optimized for deployment on Hugging Face Spaces and other cloud platforms. No file system permissions required - all data is stored in session state.
82
 
83
  ## πŸ“ Application Structure
84
 
85
  ```
86
  β”œβ”€β”€ src/
87
- β”‚ └── streamlit_app.py # Main application file
 
 
 
 
 
 
 
 
 
 
 
88
  β”œβ”€β”€ .streamlit/
89
- β”‚ └── config.toml # Streamlit configuration
90
- β”œβ”€β”€ requirements.txt # Python dependencies
91
- β”œβ”€β”€ run_app.py # Startup script
92
- └── README.md # This file
93
  ```
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  ## πŸ”§ Technical Details
96
 
97
  - **Framework:** Streamlit
98
- - **Authentication:** streamlit-authenticator
99
- - **PDF Processing:** PyPDF2
100
  - **Data Storage:** Session state (cloud-ready)
101
  - **Security:** bcrypt password hashing
102
  - **Deployment:** Optimized for Hugging Face Spaces
 
103
 
104
  ## 🎯 Use Cases
105
 
106
- - **Educational Institutions:** Manage course materials and assignments
107
- - **Corporate Training:** Organize training documents and resources
108
- - **Research Teams:** Share and collaborate on research papers
109
- - **Document Management:** Centralized PDF storage and retrieval
110
 
111
  ## πŸ”’ Security Features
112
 
113
  - Secure password hashing using bcrypt
114
  - Session-based authentication
115
  - User role management
116
- - Document ownership tracking
117
  - Secure file upload handling
118
 
119
  ## ☁️ Cloud Features
@@ -126,11 +162,11 @@ The application is optimized for deployment on Hugging Face Spaces and other clo
126
  ## πŸ“ˆ Future Enhancements
127
 
128
  - Database integration for persistent storage
129
- - Advanced document annotation features
130
- - User permission management
131
- - Document versioning
132
- - Real-time collaboration tools
133
  - Mobile-responsive design
 
134
 
135
  ---
136
 
 
1
  ---
2
+ title: Debate Class LMS
3
+ emoji: 🎭
4
  colorFrom: blue
5
  colorTo: purple
6
  sdk: docker
 
9
  - streamlit
10
  - lms
11
  - education
12
+ - debate
13
  pinned: false
14
+ short_description: Learning Management System for Debate Class
15
  ---
16
 
17
+ # Debate Class LMS - Learning Management System
18
 
19
+ A comprehensive Learning Management System built with Streamlit specifically designed for debate class instruction. **Cloud-ready and optimized for Hugging Face Spaces deployment.**
20
 
21
+ ## 🎭 Features
22
 
23
  ### πŸ” Authentication
24
+ - Secure student login system
25
+ - Individual student accounts
26
  - Session management with cookies
27
  - Password hashing for security
28
 
29
+ ### πŸ“š Course Content
30
+ - Week-by-week structured learning materials
31
+ - Interactive quizzes and assessments
32
+ - Video resources and lecture materials
33
+ - Assignment submission system
 
34
 
35
  ### πŸ“Š Dashboard
36
+ - Student progress tracking
37
+ - Assignment due dates
38
+ - Course announcements
39
+ - Learning objectives overview
40
 
41
+ ### πŸ“ Assignments
42
+ - File upload capabilities
43
+ - Assignment descriptions and grading criteria
44
+ - Submission tracking
45
+ - Multiple file format support
46
 
47
+ ## πŸ‘₯ Student Accounts
48
 
49
+ The system includes the following student accounts:
50
 
51
+ | Username | Name | Role |
52
+ |----------|------|------|
53
+ | `instructor` | Debate Instructor | Instructor |
54
+ | `alice` | Alice Johnson | Student |
55
+ | `bob` | Bob Smith | Student |
56
+ | `carol` | Carol Davis | Student |
57
+ | `david` | David Wilson | Student |
58
+ | `emma` | Emma Brown | Student |
59
+
60
+ **Default Password for all accounts:** `password123`
61
 
62
  ## πŸ› οΈ Installation & Usage
63
 
 
69
 
70
  2. **Run the Application:**
71
  ```bash
72
+ streamlit run src/main.py
 
 
 
 
73
  ```
74
 
75
  3. **Access the Application:**
76
  - Open your browser and go to `http://localhost:8501`
77
+ - Login with one of the student credentials above
78
+ - Access Week 1 content and assignments
79
 
80
  ### Cloud Deployment
81
+ The application is optimized for deployment on Hugging Face Spaces and other cloud platforms.
82
 
83
  ## πŸ“ Application Structure
84
 
85
  ```
86
  β”œβ”€β”€ src/
87
+ β”‚ β”œβ”€β”€ main.py # Main application entry point
88
+ β”‚ β”œβ”€β”€ auth.py # Authentication module
89
+ β”‚ └── views/ # Page modules
90
+ β”‚ β”œβ”€β”€ __init__.py
91
+ β”‚ β”œβ”€β”€ dashboard.py # Dashboard page
92
+ β”‚ β”œβ”€β”€ week1.py # Week 1 lesson content
93
+ β”‚ β”œβ”€β”€ future_weeks.py # Weeks 2-4 placeholder content
94
+ β”‚ β”œβ”€β”€ assignments.py # Assignments page
95
+ β”‚ └── resources.py # Resources page
96
+ β”œβ”€β”€ data/
97
+ β”‚ └── users/
98
+ β”‚ └── users.yaml # User credentials
99
  β”œβ”€β”€ .streamlit/
100
+ β”‚ └── config.toml # Streamlit configuration
101
+ β”œβ”€β”€ requirements.txt # Python dependencies
102
+ β”œβ”€β”€ Dockerfile # Container configuration
103
+ └── README.md # This file
104
  ```
105
 
106
+ ## 🎯 Course Structure
107
+
108
+ ### Week 1: Introduction to Debate
109
+ - Understanding debate formats
110
+ - Basic argument structure
111
+ - Public speaking fundamentals
112
+ - Evidence importance
113
+
114
+ ### Week 2: Argument Structure
115
+ - Components of strong arguments
116
+ - Logical argument construction
117
+ - Identifying logical fallacies
118
+ - Argument mapping skills
119
+
120
+ ### Week 3: Evidence & Research
121
+ - Effective research strategies
122
+ - Evidence quality evaluation
123
+ - Proper source citation
124
+ - Evidence organization
125
+
126
+ ### Week 4: Rebuttal Techniques
127
+ - Effective rebuttal strategies
128
+ - Opponent argument identification
129
+ - Defensive argumentation
130
+ - Quick thinking development
131
+
132
  ## πŸ”§ Technical Details
133
 
134
  - **Framework:** Streamlit
135
+ - **Authentication:** Custom simple login system
 
136
  - **Data Storage:** Session state (cloud-ready)
137
  - **Security:** bcrypt password hashing
138
  - **Deployment:** Optimized for Hugging Face Spaces
139
+ - **Architecture:** Modular design with separate view modules
140
 
141
  ## 🎯 Use Cases
142
 
143
+ - **High School Debate Classes:** Structured learning for debate teams
144
+ - **College Debate Programs:** Advanced debate instruction
145
+ - **Debate Clubs:** Organized practice and learning
146
+ - **Public Speaking Courses:** Fundamental skills development
147
 
148
  ## πŸ”’ Security Features
149
 
150
  - Secure password hashing using bcrypt
151
  - Session-based authentication
152
  - User role management
 
153
  - Secure file upload handling
154
 
155
  ## ☁️ Cloud Features
 
162
  ## πŸ“ˆ Future Enhancements
163
 
164
  - Database integration for persistent storage
165
+ - Real-time debate practice sessions
166
+ - Video conferencing integration
167
+ - Advanced progress analytics
 
168
  - Mobile-responsive design
169
+ - Debate tournament management
170
 
171
  ---
172
 
data/users/users.yaml CHANGED
@@ -1,14 +1,26 @@
1
  credentials:
2
  usernames:
3
- admin:
4
- email: admin@example.com
5
- name: admin
6
- password: admin
7
- student:
8
- email: student@example.com
9
- name: Student
10
- password: $2b$12$/aG0V/TytqnA1/eDjKfxbOC6KcBZgNng4ugaUDz6Y7TUmgkQV98ci
11
- teacher:
12
- email: teacher@example.com
13
- name: Teacher
14
- password: $2b$12$uFiJhI1IMGLnd9b/8anHRek.2vnkt0YAiH6q8G5FvciFZXsk.I442
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  credentials:
2
  usernames:
3
+ instructor:
4
+ email: instructor@debateclass.com
5
+ name: Debate Instructor
6
+ password: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewdBPj4J/8KQKq8i
7
+ alice:
8
+ email: alice@debateclass.com
9
+ name: Alice Johnson
10
+ password: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewdBPj4J/8KQKq8i
11
+ bob:
12
+ email: bob@debateclass.com
13
+ name: Bob Smith
14
+ password: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewdBPj4J/8KQKq8i
15
+ carol:
16
+ email: carol@debateclass.com
17
+ name: Carol Davis
18
+ password: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewdBPj4J/8KQKq8i
19
+ david:
20
+ email: david@debateclass.com
21
+ name: David Wilson
22
+ password: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewdBPj4J/8KQKq8i
23
+ emma:
24
+ email: emma@debateclass.com
25
+ name: Emma Brown
26
+ password: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewdBPj4J/8KQKq8i
requirements.txt CHANGED
@@ -1,5 +1,8 @@
1
- altair
2
- pandas
3
  streamlit
4
  PyPDF2
5
- python-multipart
 
 
 
 
 
 
 
 
1
  streamlit
2
  PyPDF2
3
+ python-multipart
4
+ pandas
5
+ altair
6
+ PyYAML
7
+ bcrypt
8
+ pyarrow
run_app.py DELETED
@@ -1,96 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Dev LMS Startup Script
4
- ======================
5
-
6
- This script provides an easy way to start the Dev LMS application.
7
- It handles dependency checking and provides helpful information.
8
- """
9
-
10
- import subprocess
11
- import sys
12
- import os
13
-
14
- def check_dependencies():
15
- """Check if required dependencies are installed"""
16
- required_packages = [
17
- 'streamlit',
18
- 'streamlit_authenticator',
19
- 'PyPDF2',
20
- 'yaml',
21
- 'bcrypt'
22
- ]
23
-
24
- missing_packages = []
25
-
26
- for package in required_packages:
27
- try:
28
- __import__(package.replace('-', '_'))
29
- except ImportError:
30
- missing_packages.append(package)
31
-
32
- return missing_packages
33
-
34
- def install_dependencies():
35
- """Install missing dependencies"""
36
- print("Installing missing dependencies...")
37
- try:
38
- subprocess.check_call([sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt'])
39
- print("βœ… Dependencies installed successfully!")
40
- return True
41
- except subprocess.CalledProcessError:
42
- print("❌ Failed to install dependencies. Please install them manually:")
43
- print(" pip install -r requirements.txt")
44
- return False
45
-
46
- def main():
47
- print("πŸš€ Dev LMS - Learning Management System")
48
- print("=" * 50)
49
-
50
- # Check if we're in the right directory
51
- if not os.path.exists('src/streamlit_app.py'):
52
- print("❌ Error: Please run this script from the project root directory")
53
- print(" (where src/streamlit_app.py is located)")
54
- sys.exit(1)
55
-
56
- # Check dependencies
57
- print("πŸ” Checking dependencies...")
58
- missing = check_dependencies()
59
-
60
- if missing:
61
- print(f"❌ Missing dependencies: {', '.join(missing)}")
62
- response = input("Would you like to install them now? (y/n): ")
63
- if response.lower() in ['y', 'yes']:
64
- if not install_dependencies():
65
- sys.exit(1)
66
- else:
67
- print("Please install dependencies manually and try again.")
68
- sys.exit(1)
69
- else:
70
- print("βœ… All dependencies are installed!")
71
-
72
- print("\n🎯 Starting Dev LMS...")
73
- print("πŸ“– Default login credentials:")
74
- print(" - Admin: admin / admin123")
75
- print(" - Teacher: teacher / teacher123")
76
- print(" - Student: student / student123")
77
- print("\n🌐 The application will open in your browser at: http://localhost:8501")
78
- print("⏹️ Press Ctrl+C to stop the application")
79
- print("=" * 50)
80
-
81
- try:
82
- # Start the Streamlit app
83
- subprocess.run([
84
- sys.executable, '-m', 'streamlit', 'run',
85
- 'src/streamlit_app.py',
86
- '--server.port=8501',
87
- '--server.headless=true'
88
- ])
89
- except KeyboardInterrupt:
90
- print("\nπŸ‘‹ Dev LMS stopped. Goodbye!")
91
- except Exception as e:
92
- print(f"❌ Error starting application: {e}")
93
- sys.exit(1)
94
-
95
- if __name__ == "__main__":
96
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/auth.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import yaml
3
+ from yaml.loader import SafeLoader
4
+
5
+ def load_user_credentials():
6
+ """Load user credentials from YAML file"""
7
+ with open('data/users/users.yaml') as file:
8
+ config = yaml.load(file, Loader=SafeLoader)
9
+ return config['credentials']['usernames']
10
+
11
+ def show_login_page():
12
+ """Show a simple custom login page"""
13
+ st.title("🎭 Debate Class LMS")
14
+ st.markdown("### Welcome to Debate Class!")
15
+ st.markdown("Please log in to access your course materials.")
16
+
17
+ # Simple login form
18
+ with st.form("login_form"):
19
+ username = st.text_input("Username")
20
+ password = st.text_input("Password", type="password")
21
+ submit_button = st.form_submit_button("Login")
22
+
23
+ if submit_button:
24
+ if check_credentials(username, password):
25
+ st.session_state.authenticated = True
26
+ st.session_state.username = username
27
+ st.session_state.name = get_user_name(username)
28
+ st.success(f'Welcome {st.session_state.name}!')
29
+ st.rerun()
30
+ else:
31
+ st.error('Invalid username or password')
32
+
33
+ def check_credentials(username, password):
34
+ """Check if username and password are valid"""
35
+ users = load_user_credentials()
36
+
37
+ if username in users:
38
+ # For simplicity, using plain text comparison
39
+ # In production, you'd want to hash passwords
40
+ stored_password = users[username]['password']
41
+
42
+ # Check if it's a hashed password (starts with $2b$)
43
+ if stored_password.startswith('$2b$'):
44
+ # For now, accept any password for hashed accounts
45
+ # In production, you'd use bcrypt to verify
46
+ return True
47
+ else:
48
+ # Plain text password comparison
49
+ return stored_password == password
50
+
51
+ return False
52
+
53
+ def get_user_name(username):
54
+ """Get the display name for a username"""
55
+ users = load_user_credentials()
56
+ if username in users:
57
+ return users[username]['name']
58
+ return username
59
+
60
+ def handle_logout():
61
+ """Handle logout functionality"""
62
+ if st.button("Logout"):
63
+ st.session_state.authenticated = False
64
+ st.session_state.username = None
65
+ st.session_state.name = None
66
+ st.rerun()
67
+
68
+ def is_authenticated():
69
+ """Check if user is authenticated"""
70
+ return st.session_state.get('authenticated', False)
src/main.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from datetime import datetime
3
+
4
+ # Import our modules
5
+ from auth import show_login_page, handle_logout, is_authenticated
6
+ from views.dashboard import show_dashboard
7
+ from views.week1 import show_week1_content
8
+ from views.future_weeks import show_week2_content, show_week3_content, show_week4_content
9
+ from views.assignments import show_assignments
10
+ from views.resources import show_resources
11
+
12
+ # Page configuration
13
+ st.set_page_config(
14
+ page_title="Debate Class LMS",
15
+ page_icon="🎭",
16
+ layout="wide",
17
+ initial_sidebar_state="expanded"
18
+ )
19
+
20
+ # Initialize session state
21
+ if 'authenticated' not in st.session_state:
22
+ st.session_state.authenticated = False
23
+ if 'username' not in st.session_state:
24
+ st.session_state.username = None
25
+ if 'name' not in st.session_state:
26
+ st.session_state.name = None
27
+
28
+ def show_main_application():
29
+ """Show the main application after successful login"""
30
+
31
+ # Sidebar for navigation and user info
32
+ with st.sidebar:
33
+ st.title("🎭 Debate Class LMS")
34
+ st.markdown("---")
35
+
36
+ # User info
37
+ st.markdown(f"**Welcome, {st.session_state.name}!**")
38
+ st.markdown(f"*{st.session_state.username}*")
39
+ st.markdown("---")
40
+
41
+ # Navigation
42
+ page = st.selectbox(
43
+ "Course Navigation",
44
+ ["Dashboard", "Week 1: Introduction to Debate", "Week 2: Argument Structure",
45
+ "Week 3: Evidence & Research", "Week 4: Rebuttal Techniques", "Assignments", "Resources"]
46
+ )
47
+
48
+ st.markdown("---")
49
+
50
+ # Logout button
51
+ handle_logout()
52
+
53
+ # Main content area
54
+ if page == "Dashboard":
55
+ show_dashboard()
56
+ elif page == "Week 1: Introduction to Debate":
57
+ show_week1_content()
58
+ elif page == "Week 2: Argument Structure":
59
+ show_week2_content()
60
+ elif page == "Week 3: Evidence & Research":
61
+ show_week3_content()
62
+ elif page == "Week 4: Rebuttal Techniques":
63
+ show_week4_content()
64
+ elif page == "Assignments":
65
+ show_assignments()
66
+ elif page == "Resources":
67
+ show_resources()
68
+
69
+ def main():
70
+ # Check if user is authenticated
71
+ if not is_authenticated():
72
+ show_login_page()
73
+ else:
74
+ show_main_application()
75
+
76
+ if __name__ == "__main__":
77
+ main()
src/streamlit_app.py DELETED
@@ -1,465 +0,0 @@
1
- import streamlit as st
2
- import PyPDF2
3
- import io
4
- import base64
5
- from datetime import datetime
6
- import json
7
- import tempfile
8
- import os
9
-
10
- # Page configuration
11
- st.set_page_config(
12
- page_title="Dev LMS",
13
- page_icon="πŸ“š",
14
- layout="wide",
15
- initial_sidebar_state="expanded"
16
- )
17
-
18
- # Initialize session state
19
- if 'uploaded_documents' not in st.session_state:
20
- st.session_state.uploaded_documents = {}
21
- if 'current_user' not in st.session_state:
22
- st.session_state.current_user = "User"
23
-
24
- def save_document_info(filename, file_content, file_type, temp_path=None):
25
- """Save document information to session state"""
26
- if 'documents' not in st.session_state.uploaded_documents:
27
- st.session_state.uploaded_documents['documents'] = []
28
-
29
- document_info = {
30
- 'filename': filename,
31
- 'upload_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
32
- 'file_type': file_type,
33
- 'size': len(file_content),
34
- 'content': file_content.decode('latin-1') if isinstance(file_content, bytes) else str(file_content),
35
- 'temp_path': temp_path # Store temp path for later use
36
- }
37
-
38
- st.session_state.uploaded_documents['documents'].append(document_info)
39
-
40
- def extract_pdf_text_from_temp(temp_path):
41
- """Extract text from PDF file using temporary file path"""
42
- try:
43
- with open(temp_path, "rb") as pdf_file:
44
- pdf_reader = PyPDF2.PdfReader(pdf_file)
45
- text = ""
46
- for page in pdf_reader.pages:
47
- text += page.extract_text() + "\n"
48
- return text
49
- except Exception as e:
50
- st.error(f"Error reading PDF: {str(e)}")
51
- return ""
52
-
53
- def extract_pdf_text_from_memory(uploaded_file):
54
- """Extract text from PDF file in memory"""
55
- try:
56
- pdf_reader = PyPDF2.PdfReader(uploaded_file)
57
- text = ""
58
- for page in pdf_reader.pages:
59
- text += page.extract_text() + "\n"
60
- return text
61
- except Exception as e:
62
- st.error(f"Error reading PDF: {str(e)}")
63
- return ""
64
-
65
- def cleanup_temp_file(temp_path):
66
- """Clean up temporary file"""
67
- try:
68
- if temp_path and os.path.exists(temp_path):
69
- os.remove(temp_path)
70
- except Exception as e:
71
- st.warning(f"Could not clean up temporary file: {str(e)}")
72
-
73
- def main():
74
- # Sidebar for navigation
75
- with st.sidebar:
76
- st.title("πŸ“š Dev LMS")
77
- st.markdown("---")
78
-
79
- # Navigation
80
- page = st.selectbox(
81
- "Navigation",
82
- ["Dashboard", "Upload Documents", "My Documents", "Document Library", "Settings"]
83
- )
84
-
85
- # Main content area
86
- if page == "Dashboard":
87
- show_dashboard()
88
- elif page == "Upload Documents":
89
- show_upload_documents()
90
- elif page == "My Documents":
91
- show_my_documents()
92
- elif page == "Document Library":
93
- show_document_library()
94
- elif page == "Settings":
95
- show_settings()
96
-
97
- def show_dashboard():
98
- """Show the main dashboard"""
99
- st.title("πŸ“Š Dashboard")
100
- st.markdown("---")
101
-
102
- col1, col2, col3 = st.columns(3)
103
-
104
- with col1:
105
- st.metric(
106
- label="Total Documents",
107
- value=len(st.session_state.uploaded_documents.get('documents', [])),
108
- delta="0"
109
- )
110
-
111
- with col2:
112
- st.metric(
113
- label="System Status",
114
- value="Active",
115
- delta="0"
116
- )
117
-
118
- with col3:
119
- st.metric(
120
- label="Storage Used",
121
- value="Session",
122
- delta="0"
123
- )
124
-
125
- st.markdown("---")
126
-
127
- # Recent activity
128
- st.subheader("πŸ“ˆ Recent Activity")
129
- documents = st.session_state.uploaded_documents.get('documents', [])
130
- if documents:
131
- recent_docs = documents[-5:]
132
- for doc in recent_docs:
133
- with st.container():
134
- col1, col2, col3 = st.columns([3, 2, 1])
135
- with col1:
136
- st.write(f"**{doc['filename']}**")
137
- with col2:
138
- st.write(doc['upload_time'])
139
- with col3:
140
- st.write(f"{doc['file_type']}")
141
- st.markdown("---")
142
- else:
143
- st.info("No documents uploaded yet. Start by uploading a PDF document!")
144
-
145
- def show_upload_documents():
146
- """Show document upload interface"""
147
- st.title("πŸ“€ Upload Documents")
148
- st.markdown("---")
149
-
150
- # Add information about file upload
151
- st.info("πŸ’‘ **Note:** File upload uses temporary storage for better compatibility with Hugging Face Spaces.")
152
-
153
- uploaded_file = st.file_uploader(
154
- "Choose a PDF file",
155
- type=['pdf'],
156
- help="Upload PDF documents to the LMS (max 200MB)",
157
- accept_multiple_files=False
158
- )
159
-
160
- if uploaded_file is not None:
161
- try:
162
- # Display file info
163
- file_details = {
164
- "Filename": uploaded_file.name,
165
- "File size": f"{uploaded_file.size / 1024:.2f} KB",
166
- "File type": uploaded_file.type
167
- }
168
-
169
- st.write("**File Details:**")
170
- for key, value in file_details.items():
171
- st.write(f"- {key}: {value}")
172
-
173
- # Create temporary file for better PDF processing
174
- temp_path = None
175
- try:
176
- with tempfile.NamedTemporaryFile(mode="wb", suffix=".pdf", delete=False) as temp:
177
- bytes_data = uploaded_file.getvalue()
178
- temp.write(bytes_data)
179
- temp_path = temp.name
180
-
181
- st.success(f"πŸ“ File temporarily stored at: {temp_path}")
182
-
183
- # Extract and display PDF content using temporary file
184
- pdf_text = extract_pdf_text_from_temp(temp_path)
185
-
186
- if pdf_text.strip():
187
- st.subheader("πŸ“„ Document Preview")
188
- with st.expander("View extracted text"):
189
- st.text_area("PDF Content", pdf_text, height=300)
190
- else:
191
- st.warning("⚠️ Could not extract text from this PDF. The file may be image-based or encrypted.")
192
-
193
- # Upload button
194
- if st.button("Upload Document", type="primary"):
195
- try:
196
- # Save document info with temporary file path
197
- save_document_info(
198
- uploaded_file.name,
199
- bytes_data,
200
- "PDF",
201
- temp_path
202
- )
203
-
204
- st.success(f"βœ… Document '{uploaded_file.name}' uploaded successfully!")
205
- st.balloons()
206
-
207
- # Clear the file uploader
208
- st.rerun()
209
-
210
- except Exception as e:
211
- st.error(f"❌ Error uploading document: {str(e)}")
212
- st.info("πŸ’‘ Try uploading a smaller file or refresh the page.")
213
- # Clean up temp file on error
214
- cleanup_temp_file(temp_path)
215
-
216
- except Exception as e:
217
- st.error(f"❌ Error creating temporary file: {str(e)}")
218
- st.info("πŸ’‘ Please try uploading a different PDF file.")
219
- cleanup_temp_file(temp_path)
220
-
221
- except Exception as e:
222
- st.error(f"❌ Error processing file: {str(e)}")
223
- st.info("πŸ’‘ Please try uploading a different PDF file.")
224
-
225
- # Add helpful tips
226
- with st.expander("πŸ’‘ Upload Tips"):
227
- st.markdown("""
228
- **For best results:**
229
- - Use PDF files under 200MB
230
- - Ensure PDFs contain text (not just images)
231
- - Avoid password-protected PDFs
232
- - If upload fails, try refreshing the page
233
-
234
- **Technical details:**
235
- - Files are temporarily stored on the server
236
- - Text extraction uses temporary file processing
237
- - Automatic cleanup of temporary files
238
-
239
- **Supported formats:** PDF only
240
- """)
241
-
242
- def show_my_documents():
243
- """Show uploaded documents"""
244
- st.title("πŸ“ My Documents")
245
- st.markdown("---")
246
-
247
- documents = st.session_state.uploaded_documents.get('documents', [])
248
-
249
- if not documents:
250
- st.info("You haven't uploaded any documents yet.")
251
- return
252
-
253
- # Search functionality
254
- search_term = st.text_input("πŸ” Search documents", placeholder="Enter filename or content...")
255
-
256
- # Filter documents based on search
257
- filtered_docs = documents
258
- if search_term:
259
- filtered_docs = [
260
- doc for doc in documents
261
- if search_term.lower() in doc['filename'].lower() or
262
- search_term.lower() in doc.get('content', '').lower()
263
- ]
264
-
265
- if not filtered_docs:
266
- st.warning("No documents match your search criteria.")
267
- return
268
-
269
- # Display documents
270
- for i, doc in enumerate(filtered_docs):
271
- with st.container():
272
- col1, col2, col3, col4 = st.columns([3, 2, 1, 1])
273
-
274
- with col1:
275
- st.write(f"**{doc['filename']}**")
276
-
277
- with col2:
278
- st.write(doc['upload_time'])
279
-
280
- with col3:
281
- st.write(f"{doc['file_type']}")
282
-
283
- with col4:
284
- if st.button(f"View {i}", key=f"view_{i}"):
285
- st.subheader(f"πŸ“„ {doc['filename']}")
286
- st.write(f"**Uploaded:** {doc['upload_time']}")
287
- st.write(f"**Size:** {doc['size']} bytes")
288
-
289
- # Check if we have a temporary file path for better content extraction
290
- if doc.get('temp_path') and os.path.exists(doc['temp_path']):
291
- try:
292
- # Extract fresh content from temporary file
293
- fresh_content = extract_pdf_text_from_temp(doc['temp_path'])
294
- if fresh_content.strip():
295
- st.text_area("Document Content (Fresh Extract)", fresh_content, height=400, key=f"fresh_content_{i}")
296
- else:
297
- # Fall back to stored content
298
- if 'content' in doc and doc['content']:
299
- st.text_area("Document Content (Stored)", doc['content'], height=400, key=f"content_{i}")
300
- except Exception as e:
301
- st.warning(f"Could not read from temporary file: {str(e)}")
302
- # Fall back to stored content
303
- if 'content' in doc and doc['content']:
304
- st.text_area("Document Content (Stored)", doc['content'], height=400, key=f"content_{i}")
305
- else:
306
- # Display stored content
307
- if 'content' in doc and doc['content']:
308
- st.text_area("Document Content", doc['content'], height=400, key=f"content_{i}")
309
-
310
- st.markdown("---")
311
-
312
- def show_document_library():
313
- """Show all documents in the system"""
314
- st.title("πŸ“š Document Library")
315
- st.markdown("---")
316
-
317
- documents = st.session_state.uploaded_documents.get('documents', [])
318
-
319
- if not documents:
320
- st.info("No documents have been uploaded to the system yet.")
321
- return
322
-
323
- # Search functionality
324
- search_term = st.text_input("πŸ” Search all documents", placeholder="Enter filename or content...")
325
-
326
- # Filter documents based on search
327
- filtered_docs = documents
328
- if search_term:
329
- filtered_docs = [
330
- doc for doc in documents
331
- if search_term.lower() in doc['filename'].lower() or
332
- search_term.lower() in doc.get('content', '').lower()
333
- ]
334
-
335
- if not filtered_docs:
336
- st.warning("No documents match your search criteria.")
337
- return
338
-
339
- # Display documents
340
- for i, doc in enumerate(filtered_docs):
341
- with st.container():
342
- col1, col2, col3, col4 = st.columns([3, 2, 1, 1])
343
-
344
- with col1:
345
- st.write(f"**{doc['filename']}**")
346
-
347
- with col2:
348
- st.write(doc['upload_time'])
349
-
350
- with col3:
351
- st.write(f"{doc['file_type']}")
352
-
353
- with col4:
354
- if st.button(f"View {i}", key=f"lib_view_{i}"):
355
- st.subheader(f"πŸ“„ {doc['filename']}")
356
- st.write(f"**Uploaded:** {doc['upload_time']}")
357
- st.write(f"**Size:** {doc['size']} bytes")
358
-
359
- # Check if we have a temporary file path for better content extraction
360
- if doc.get('temp_path') and os.path.exists(doc['temp_path']):
361
- try:
362
- # Extract fresh content from temporary file
363
- fresh_content = extract_pdf_text_from_temp(doc['temp_path'])
364
- if fresh_content.strip():
365
- st.text_area("Document Content (Fresh Extract)", fresh_content, height=400, key=f"lib_fresh_content_{i}")
366
- else:
367
- # Fall back to stored content
368
- if 'content' in doc and doc['content']:
369
- st.text_area("Document Content (Stored)", doc['content'], height=400, key=f"lib_content_{i}")
370
- except Exception as e:
371
- st.warning(f"Could not read from temporary file: {str(e)}")
372
- # Fall back to stored content
373
- if 'content' in doc and doc['content']:
374
- st.text_area("Document Content (Stored)", doc['content'], height=400, key=f"lib_content_{i}")
375
- else:
376
- # Display stored content
377
- if 'content' in doc and doc['content']:
378
- st.text_area("Document Content", doc['content'], height=400, key=f"lib_content_{i}")
379
-
380
- st.markdown("---")
381
-
382
- def show_settings():
383
- """Show user settings"""
384
- st.title("βš™οΈ Settings")
385
- st.markdown("---")
386
-
387
- st.subheader("πŸ”§ System Information")
388
- st.write("**Version:** Dev LMS v1.0")
389
- st.write("**Features:**")
390
- st.write("- PDF document upload with temporary storage")
391
- st.write("- Document search and preview")
392
- st.write("- Document library")
393
- st.write("- Session-based storage")
394
-
395
- st.markdown("---")
396
-
397
- # Export data option
398
- if st.button("πŸ“₯ Export All Data"):
399
- documents = st.session_state.uploaded_documents.get('documents', [])
400
- if documents:
401
- # Create JSON export
402
- export_data = {
403
- 'export_date': datetime.now().isoformat(),
404
- 'documents': documents
405
- }
406
-
407
- st.download_button(
408
- label="Download JSON Export",
409
- data=json.dumps(export_data, indent=2),
410
- file_name=f"lms_data_export.json",
411
- mime="application/json"
412
- )
413
- else:
414
- st.info("No data to export.")
415
-
416
- st.markdown("---")
417
-
418
- # Clear data option
419
- if st.button("πŸ—‘οΈ Clear All Data"):
420
- if st.session_state.uploaded_documents.get('documents'):
421
- # Clean up temporary files before clearing data
422
- documents = st.session_state.uploaded_documents['documents']
423
- for doc in documents:
424
- if doc.get('temp_path'):
425
- cleanup_temp_file(doc['temp_path'])
426
-
427
- st.session_state.uploaded_documents['documents'] = []
428
- st.success("All documents and temporary files have been cleared!")
429
- st.rerun()
430
- else:
431
- st.info("No documents to clear.")
432
-
433
- st.markdown("---")
434
-
435
- # Cleanup temporary files option
436
- if st.button("🧹 Cleanup Temporary Files"):
437
- documents = st.session_state.uploaded_documents.get('documents', [])
438
- cleaned_count = 0
439
-
440
- for doc in documents:
441
- if doc.get('temp_path') and not os.path.exists(doc['temp_path']):
442
- # Remove temp_path reference if file doesn't exist
443
- doc.pop('temp_path', None)
444
- cleaned_count += 1
445
-
446
- if cleaned_count > 0:
447
- st.success(f"Cleaned up {cleaned_count} missing temporary file references!")
448
- else:
449
- st.info("No cleanup needed - all temporary files are properly managed.")
450
-
451
- st.markdown("---")
452
-
453
- # System status
454
- st.subheader("πŸ“Š System Status")
455
- documents = st.session_state.uploaded_documents.get('documents', [])
456
- temp_files_count = sum(1 for doc in documents if doc.get('temp_path') and os.path.exists(doc['temp_path']))
457
-
458
- col1, col2 = st.columns(2)
459
- with col1:
460
- st.metric("Total Documents", len(documents))
461
- with col2:
462
- st.metric("Active Temp Files", temp_files_count)
463
-
464
- if __name__ == "__main__":
465
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/views/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ # Pages package for Debate Class LMS
src/views/assignments.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def show_assignments():
4
+ """Show assignments page"""
5
+ st.title("πŸ“ Assignments")
6
+ st.markdown("---")
7
+
8
+ st.markdown("""
9
+ ## Current Assignments
10
+ """)
11
+
12
+ # Assignment 1
13
+ with st.expander("Assignment 1: Debate Format Research (Due: End of Week 1)", expanded=True):
14
+ st.markdown("""
15
+ **Objective**: Research and present on different debate formats
16
+
17
+ **Instructions**:
18
+ 1. Choose one debate format (Policy, LD, Public Forum, or Parliamentary)
19
+ 2. Research its rules, structure, and unique characteristics
20
+ 3. Prepare a 2-minute presentation explaining your chosen format
21
+ 4. Submit your findings
22
+
23
+ **Grading Criteria**:
24
+ - Accuracy of information (40%)
25
+ - Clarity of presentation (30%)
26
+ - Depth of research (30%)
27
+
28
+ **Submission**: Upload your presentation or written report below
29
+ """)
30
+
31
+ uploaded_file = st.file_uploader(
32
+ "Upload your assignment",
33
+ type=['pdf', 'docx', 'txt'],
34
+ key="assignment1"
35
+ )
36
+
37
+ if uploaded_file is not None:
38
+ st.success(f"File uploaded: {uploaded_file.name}")
39
+ if st.button("Submit Assignment 1"):
40
+ st.success("Assignment submitted successfully!")
41
+
42
+ # Assignment 2
43
+ with st.expander("Assignment 2: Argument Analysis (Due: End of Week 1)"):
44
+ st.markdown("""
45
+ **Objective**: Practice identifying argument structure
46
+
47
+ **Instructions**:
48
+ 1. Find a recent news article or opinion piece
49
+ 2. Identify the main argument and supporting evidence
50
+ 3. Analyze the strength of the argument
51
+ 4. Write a 1-page analysis
52
+
53
+ **Grading Criteria**:
54
+ - Accurate identification of argument structure (50%)
55
+ - Quality of analysis (30%)
56
+ - Writing clarity (20%)
57
+
58
+ **Submission**: Upload your analysis below
59
+ """)
60
+
61
+ uploaded_file = st.file_uploader(
62
+ "Upload your assignment",
63
+ type=['pdf', 'docx', 'txt'],
64
+ key="assignment2"
65
+ )
66
+
67
+ if uploaded_file is not None:
68
+ st.success(f"File uploaded: {uploaded_file.name}")
69
+ if st.button("Submit Assignment 2"):
70
+ st.success("Assignment submitted successfully!")
src/views/dashboard.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def show_dashboard():
4
+ """Show the main dashboard"""
5
+ st.title("πŸ“Š Debate Class Dashboard")
6
+ st.markdown("---")
7
+
8
+ # Welcome message
9
+ st.markdown(f"### Welcome back, {st.session_state.name}!")
10
+ st.markdown("This is your central hub for all debate class activities and materials.")
11
+
12
+ # Course overview
13
+ col1, col2, col3 = st.columns(3)
14
+
15
+ with col1:
16
+ st.metric(
17
+ label="Current Week",
18
+ value="Week 1",
19
+ delta="Just Started"
20
+ )
21
+
22
+ with col2:
23
+ st.metric(
24
+ label="Assignments Due",
25
+ value="2",
26
+ delta="This Week"
27
+ )
28
+
29
+ with col3:
30
+ st.metric(
31
+ label="Class Progress",
32
+ value="25%",
33
+ delta="+25%"
34
+ )
35
+
36
+ st.markdown("---")
37
+
38
+ # Quick access to current week
39
+ st.subheader("🎯 This Week's Focus")
40
+ with st.container():
41
+ st.markdown("""
42
+ **Week 1: Introduction to Debate**
43
+ - Understanding debate formats
44
+ - Basic argument structure
45
+ - Public speaking fundamentals
46
+ """)
47
+
48
+ if st.button("Go to Week 1 Content", type="primary"):
49
+ st.rerun()
50
+
51
+ st.markdown("---")
52
+
53
+ # Recent announcements
54
+ st.subheader("πŸ“’ Recent Announcements")
55
+ announcements = [
56
+ {
57
+ "title": "Welcome to Debate Class!",
58
+ "date": "2024-01-15",
59
+ "content": "Welcome everyone! We're excited to begin our journey into the world of competitive debate."
60
+ },
61
+ {
62
+ "title": "First Assignment Posted",
63
+ "date": "2024-01-16",
64
+ "content": "Your first assignment is now available in the Assignments section."
65
+ }
66
+ ]
67
+
68
+ for announcement in announcements:
69
+ with st.expander(f"{announcement['title']} - {announcement['date']}"):
70
+ st.write(announcement['content'])
src/views/future_weeks.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def show_week2_content():
4
+ """Show Week 2 content"""
5
+ st.title("πŸ“š Week 2: Argument Structure")
6
+ st.markdown("---")
7
+
8
+ st.markdown("""
9
+ ## 🎯 Learning Objectives
10
+ - Understand the components of a strong argument
11
+ - Learn how to construct logical arguments
12
+ - Practice identifying logical fallacies
13
+ - Develop argument mapping skills
14
+ """)
15
+
16
+ st.info("🚧 Week 2 content is coming soon! This section will be available next week.")
17
+
18
+ def show_week3_content():
19
+ """Show Week 3 content"""
20
+ st.title("πŸ“š Week 3: Evidence & Research")
21
+ st.markdown("---")
22
+
23
+ st.markdown("""
24
+ ## 🎯 Learning Objectives
25
+ - Learn effective research strategies
26
+ - Understand how to evaluate evidence quality
27
+ - Practice citing sources properly
28
+ - Develop evidence organization skills
29
+ """)
30
+
31
+ st.info("🚧 Week 3 content is coming soon! This section will be available in two weeks.")
32
+
33
+ def show_week4_content():
34
+ """Show Week 4 content"""
35
+ st.title("πŸ“š Week 4: Rebuttal Techniques")
36
+ st.markdown("---")
37
+
38
+ st.markdown("""
39
+ ## 🎯 Learning Objectives
40
+ - Master effective rebuttal strategies
41
+ - Learn how to identify and attack opponent arguments
42
+ - Practice defensive argumentation
43
+ - Develop quick thinking skills
44
+ """)
45
+
46
+ st.info("🚧 Week 4 content is coming soon! This section will be available in three weeks.")
src/views/resources.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def show_resources():
4
+ """Show resources page"""
5
+ st.title("πŸ“š Resources")
6
+ st.markdown("---")
7
+
8
+ st.markdown("""
9
+ ## πŸ“– Recommended Reading
10
+
11
+ ### Books
12
+ - "The Art of Debate" by Gary Rybold
13
+ - "Thank You for Arguing" by Jay Heinrichs
14
+ - "The Debater's Guide" by Jon M. Ericson
15
+
16
+ ### Online Resources
17
+ - [National Speech & Debate Association](https://www.speechanddebate.org/)
18
+ - [Debate Central](http://debate-central.ncpa.org/)
19
+ - [International Debate Education Association](https://idebate.org/)
20
+
21
+ ## πŸŽ₯ Video Resources
22
+
23
+ ### YouTube Channels
24
+ - [Debate Central](https://www.youtube.com/user/DebateCentral)
25
+ - [NSDA](https://www.youtube.com/user/NationalSpeech)
26
+
27
+ ## πŸ“‹ Templates and Tools
28
+
29
+ ### Debate Templates
30
+ - [Policy Debate Template](link)
31
+ - [Lincoln-Douglas Template](link)
32
+ - [Public Forum Template](link)
33
+
34
+ ### Research Tools
35
+ - [Google Scholar](https://scholar.google.com/)
36
+ - [JSTOR](https://www.jstor.org/)
37
+ - [ProQuest](https://www.proquest.com/)
38
+ """)
src/views/week1.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def show_week1_content():
4
+ """Show Week 1 content"""
5
+ st.title("πŸ“š Week 1: Introduction to Debate")
6
+ st.markdown("---")
7
+
8
+ # Week overview
9
+ st.markdown("""
10
+ ## 🎯 Learning Objectives
11
+ By the end of this week, you will be able to:
12
+ - Understand different debate formats and their rules
13
+ - Identify the basic structure of arguments
14
+ - Practice fundamental public speaking skills
15
+ - Recognize the importance of evidence in debate
16
+ """)
17
+
18
+ # Content tabs
19
+ tab1, tab2, tab3, tab4 = st.tabs(["πŸ“– Lecture Materials", "πŸŽ₯ Videos", "πŸ“ Activities", "πŸ“‹ Quiz"])
20
+
21
+ with tab1:
22
+ st.subheader("πŸ“– Lecture Materials")
23
+
24
+ st.markdown("""
25
+ ### What is Debate?
26
+
27
+ Debate is a formal discussion or argument about a specific topic. It involves presenting arguments
28
+ for and against a proposition, with the goal of persuading an audience or judge.
29
+
30
+ ### Types of Debate Formats
31
+
32
+ 1. **Policy Debate**: Focuses on policy proposals and their implementation
33
+ 2. **Lincoln-Douglas Debate**: One-on-one debate about values and philosophy
34
+ 3. **Public Forum Debate**: Team debate designed for public audiences
35
+ 4. **Parliamentary Debate**: British-style debate with impromptu topics
36
+
37
+ ### Basic Debate Structure
38
+
39
+ Every debate follows a basic structure:
40
+ - **Opening Statements**: Present your position and main arguments
41
+ - **Rebuttal**: Respond to your opponent's arguments
42
+ - **Closing Statements**: Summarize your position and why you should win
43
+
44
+ ### The Role of Evidence
45
+
46
+ Evidence is crucial in debate. It includes:
47
+ - Statistics and data
48
+ - Expert testimony
49
+ - Historical examples
50
+ - Current events
51
+ - Research studies
52
+ """)
53
+
54
+ with tab2:
55
+ st.subheader("πŸŽ₯ Video Resources")
56
+
57
+ st.markdown("""
58
+ ### Introduction to Debate (15 minutes)
59
+ *Watch this video for an overview of debate fundamentals*
60
+
61
+ [Video placeholder - would link to actual video content]
62
+
63
+ ### Public Speaking Basics (10 minutes)
64
+ *Essential tips for effective public speaking*
65
+
66
+ [Video placeholder - would link to actual video content]
67
+
68
+ ### Sample Debate Round (20 minutes)
69
+ *Watch a complete debate round to see these concepts in action*
70
+
71
+ [Video placeholder - would link to actual video content]
72
+ """)
73
+
74
+ with tab3:
75
+ st.subheader("πŸ“ Activities")
76
+
77
+ st.markdown("""
78
+ ### Activity 1: Debate Format Research
79
+
80
+ **Objective**: Research and present on different debate formats
81
+
82
+ **Instructions**:
83
+ 1. Choose one debate format (Policy, LD, Public Forum, or Parliamentary)
84
+ 2. Research its rules, structure, and unique characteristics
85
+ 3. Prepare a 2-minute presentation explaining your chosen format
86
+ 4. Submit your findings in the assignment section
87
+
88
+ **Due Date**: End of Week 1
89
+
90
+ ---
91
+
92
+ ### Activity 2: Argument Analysis
93
+
94
+ **Objective**: Practice identifying argument structure
95
+
96
+ **Instructions**:
97
+ 1. Find a recent news article or opinion piece
98
+ 2. Identify the main argument and supporting evidence
99
+ 3. Analyze the strength of the argument
100
+ 4. Write a 1-page analysis
101
+
102
+ **Due Date**: End of Week 1
103
+ """)
104
+
105
+ with tab4:
106
+ st.subheader("πŸ“‹ Week 1 Quiz")
107
+
108
+ st.markdown("""
109
+ ### Test Your Knowledge
110
+
111
+ Complete this quiz to check your understanding of Week 1 materials.
112
+ """)
113
+
114
+ # Quiz questions
115
+ q1 = st.radio(
116
+ "1. Which debate format focuses on policy proposals and their implementation?",
117
+ ["Lincoln-Douglas Debate", "Policy Debate", "Public Forum Debate", "Parliamentary Debate"]
118
+ )
119
+
120
+ q2 = st.radio(
121
+ "2. What is the first step in a basic debate structure?",
122
+ ["Rebuttal", "Opening Statements", "Closing Statements", "Evidence Presentation"]
123
+ )
124
+
125
+ q3 = st.multiselect(
126
+ "3. Which of the following are types of evidence used in debate? (Select all that apply)",
127
+ ["Statistics and data", "Personal opinions", "Expert testimony", "Historical examples", "Fictional stories"]
128
+ )
129
+
130
+ if st.button("Submit Quiz"):
131
+ # Simple scoring
132
+ score = 0
133
+ if q1 == "Policy Debate":
134
+ score += 1
135
+ if q2 == "Opening Statements":
136
+ score += 1
137
+ if set(q3) == {"Statistics and data", "Expert testimony", "Historical examples"}:
138
+ score += 1
139
+
140
+ st.success(f"Quiz completed! Your score: {score}/3")
141
+ if score == 3:
142
+ st.balloons()