Spaces:
Sleeping
Sleeping
File size: 20,301 Bytes
84512f8 2679bb0 df73164 84512f8 2679bb0 8ba5c6a 2679bb0 84512f8 2679bb0 8ba5c6a 2679bb0 84512f8 75ef56d 2679bb0 8ba5c6a 2679bb0 84512f8 75ef56d 2679bb0 8ba5c6a 2679bb0 84512f8 2679bb0 84512f8 2679bb0 84512f8 327366d 75ef56d 327366d 75ef56d 327366d 75ef56d 327366d 75ef56d 327366d 75ef56d 8baabec 75ef56d 327366d 75ef56d 2679bb0 8ba5c6a 2679bb0 84512f8 75ef56d 8baabec 75ef56d 2679bb0 8ba5c6a 2679bb0 8ba5c6a 2679bb0 84512f8 75ef56d 8baabec 0ad02c4 8baabec 3d60be0 0ad02c4 3d60be0 8baabec 3d60be0 0ad02c4 3d60be0 0ad02c4 3d60be0 0ad02c4 3d60be0 0ad02c4 3d60be0 0ad02c4 df73164 a8ebce6 0ad02c4 ca54b24 75ef56d 8ba5c6a 75ef56d 8ba5c6a 75ef56d fed9126 8ba5c6a 75ef56d 8ba5c6a fed9126 8ba5c6a 75ef56d fed9126 8ba5c6a fed9126 75ef56d fed9126 75ef56d fed9126 75ef56d fed9126 75ef56d fed9126 75ef56d fed9126 7f69afa 75ef56d fed9126 75ef56d fed9126 8ba5c6a 7f69afa fed9126 8ba5c6a 75ef56d 8ba5c6a fed9126 8ba5c6a fed9126 8ba5c6a fed9126 8ba5c6a 75ef56d fed9126 75ef56d 8baabec 75ef56d 8ba5c6a 75ef56d 8ba5c6a abbb230 84512f8 abbb230 75ef56d 8ba5c6a abbb230 b216fb7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 |
import streamlit as st
from typing import List, Dict, Tuple, Optional, Any
import traceback
class StreamlitTutorial:
"""
Main class for the Streamlit Tutorial application.
Handles rendering of all tutorial content, user interaction, and state management.
Provides modular components for different tutorial topics and interactive examples.
"""
def __init__(self):
"""
Initializes the Streamlit Tutorial application.
Sets up page configuration, session state, and custom styling.
Prepares the application environment for tutorial content.
"""
st.set_page_config(page_title="Learn Streamlit", layout="wide")
self.init_session_state()
self.setup_styles()
def init_session_state(self) -> None:
"""
Initializes session state variables for persistent data storage.
Creates state variables for code input and current topic tracking.
Ensures consistent state across reruns.
Returns:
None
"""
if 'code_input' not in st.session_state:
st.session_state.code_input = ""
st.session_state.current_topic = "Basic Text Elements"
def setup_styles(self) -> None:
"""
Configures custom CSS styles for the application.
Sets up consistent styling for code examples, outputs, and layout.
Enhances visual presentation of tutorial content.
Returns:
None
"""
st.markdown("""
<style>
.code-example { margin-bottom: 1.5rem; }
.live-output {
border: 1px solid #ddd;
border-radius: 4px;
padding: 1rem;
margin: 0.5rem 0 1.5rem 0;
}
.section-title {
margin-bottom: 1rem;
padding: 0.5rem 0;
}
.button-container {
display: flex;
justify-content: space-between;
gap: 1rem;
}
</style>
""", unsafe_allow_html=True)
# Add these helper methods in the StreamlitTutorial class
def _get_basic_concepts_content(self) -> str:
"""
Provides content for Basic Concepts section.
Contains fundamental explanations and examples.
Returns:
str: Markdown formatted basic concepts content
"""
return """
**What are Text Elements?**
- Basic building blocks for displaying text
- Range from titles to formatted text
- Support markdown formatting
**Key Components:**
1. Title & Headers
2. Regular text
3. Formatted text
4. Colored text
"""
def _get_best_practices_content(self) -> str:
"""
Provides content for Best Practices section.
Contains guidelines and recommended approaches.
Returns:
str: Markdown formatted best practices content
"""
return """
**Writing Tips:**
1. Use appropriate heading levels
2. Keep text concise and clear
3. Use formatting for emphasis
4. Add visual hierarchy with headers
**Code Structure:**
```python
st.title('Main Title')
st.header('Section Header')
st.subheader('Sub-section')
st.write('Regular text')
```
"""
def _get_examples_content(self) -> str:
"""
Provides content for Examples section.
Contains practical examples and use cases.
Returns:
str: Markdown formatted examples content
"""
return """
**Common Patterns:**
1. Page Structure
```python
st.title('Dashboard')
st.header('Sales Data')
st.subheader('Monthly Trends')
```
2. Formatted Text
```python
st.markdown('**Bold** and *italic*')
st.markdown(':blue[Colored text]')
```
3. Mixed Elements
```python
st.title('Report')
st.write('Regular text')
st.markdown('- Bullet point')
```
"""
def _get_common_mistakes_content(self) -> str:
"""
Provides content for Common Mistakes section.
Contains typical errors and how to avoid them.
Returns:
str: Markdown formatted common mistakes content
"""
return """
1. Skipping header levels
2. Overusing formatting
3. Inconsistent styling
4. Missing hierarchy
**How to Avoid:**
- Plan your page structure
- Use consistent formatting
- Test different screen sizes
- Keep it simple
"""
def _get_widgets_help_content(self) -> str:
"""
Enhanced help content for widgets section
"""
return """
**Widget Best Practices:**
1. Input Validation
```python
# Add validation to inputs
age = st.number_input('Age', min_value=0, max_value=150, key='age_1')
if age < 18:
st.warning('Must be 18 or older')
```
2. Default Values
```python
# Provide sensible defaults
st.text_input('Name', value='Guest User', key='name_2')
st.slider('Rating', 1, 5, value=3, key='rating_1')
```
3. Responsive Widgets
```python
# React to widget changes
if st.checkbox('Show advanced options', key='advanced_1'):
st.number_input('Threshold', key='threshold_1')
st.slider('Sensitivity', key='sensitivity_1')
```
4. Form Submission
```python
with st.form('my_form'):
st.text_input('Username', key='form_user')
st.text_input('Password', type='password', key='form_pass')
submitted = st.form_submit_button('Login')
```
5. File Handling
```python
file = st.file_uploader('Upload CSV', key='file_2')
if file is not None:
# Handle file upload
st.success('File uploaded!')
```
6. Interactive Filters
```python
col1, col2 = st.columns(2)
with col1:
category = st.selectbox('Category', ['A', 'B', 'C'], key='cat_1')
with col2:
subcategory = st.multiselect('Subcategory', ['X', 'Y', 'Z'], key='subcat_1')
```
**Tips for Widget Usage:**
- Use clear, concise labels
- Group related widgets together
- Provide help text when needed
- Use appropriate widget types
- Handle all possible states
- Validate inputs properly
- Always use unique keys
- Consider mobile responsiveness
"""
def _get_advanced_tips_content(self) -> str:
"""
Provides content for Advanced Tips section.
Contains advanced usage and techniques.
Returns:
str: Markdown formatted advanced tips content
"""
return """
**Advanced Formatting:**
```python
# Custom HTML
st.markdown('''
<span style='color:blue'>
Custom styled text
</span>
''', unsafe_allow_html=True)
# Complex Markdown
st.markdown('''
# Title
## Subtitle
* Point 1
* Subpoint
> Quote
''')
```
**Layout Combinations:**
```python
col1, col2 = st.columns(2)
with col1:
st.header('Column 1')
with col2:
st.header('Column 2')
```
"""
def get_text_elements(self) -> List[Tuple[str, str]]:
"""
Provides collection of text element examples with corresponding code.
Defines basic text manipulation and display examples.
Used for generating code examples and quick snippets.
Returns:
List[Tuple[str, str]]: List of (element name, code snippet) pairs
"""
return [
("Title", "st.title('Main Title')"),
("Header", "st.header('Header')"),
("Subheader", "st.subheader('Subheader')"),
("Normal text", "st.write('Normal text')"),
("Markdown text", "st.markdown('**Bold** and *italic*')"),
("Colored text", "st.markdown(':blue[Blue text]')")
]
def render_text_elements(self, col: st.delta_generator.DeltaGenerator) -> None:
"""
Renders text element examples in the specified column.
Displays code snippets with live output for each text element.
Creates interactive learning environment for text elements.
Arguments:
col: Streamlit column object for content rendering
Returns:
None
"""
with col:
st.markdown("### π Code Examples")
for title, code in self.get_text_elements():
with st.container(border=True):
st.markdown(f"**{title}**")
st.code(code)
st.markdown("Live output:")
with st.container(border=True):
exec(code)
def get_input_elements(self) -> List[Tuple[str, str]]:
"""
Cross-validated collection of input widgets with unique keys
"""
return [
("Text Input", """st.text_input('Enter your name',
key='text_input_demo_1',
placeholder='John Doe')"""),
("Text Area", """st.text_area('Enter long text',
key='text_area_demo_1',
height=100,
placeholder='Write something...')"""),
("Number Input", """st.number_input('Enter a number',
key='number_input_demo_1',
min_value=0,
max_value=100,
value=50,
step=5)"""),
("Slider", """st.slider('Select value',
key='slider_demo_1',
min_value=0,
max_value=100,
value=50,
step=5)"""),
("Select Box", """st.selectbox('Choose an option',
key='select_box_demo_1',
options=['Option 1', 'Option 2', 'Option 3'],
index=0)""")
]
def render_input_elements(self, col: st.delta_generator.DeltaGenerator) -> None:
"""
Renders input examples with unique keys for both examples and live output
"""
with col:
st.markdown("### π Code Examples")
for idx, (title, code) in enumerate(self.get_input_elements()):
with st.container(border=True, key=f"demo_container_{idx}"):
st.markdown(f"**{title}**")
st.code(code)
st.markdown("Live output:")
with st.container(border=True, key=f"output_container_{idx}"):
try:
# Create runtime version with unique key
runtime_code = code.replace('demo_1', f'runtime_{idx}')
exec(runtime_code)
except Exception as e:
st.error(f"Error: {str(e)}")
def render_help_section(self, col: st.delta_generator.DeltaGenerator) -> None:
"""
Renders comprehensive help content in the specified column.
Provides educational content, best practices, and examples.
Creates expandable sections for different learning topics.
Arguments:
col: Streamlit column object for content rendering
Returns:
None
"""
with col:
st.markdown("### π Learning Guide")
# Basic Concepts Section
with st.expander("π― Basic Concepts", expanded=True):
st.markdown(self._get_basic_concepts_content())
# Best Practices Section
with st.expander("π‘ Best Practices"):
st.markdown(self._get_best_practices_content())
# Examples Section
with st.expander("π Examples & Use Cases"):
st.markdown(self._get_examples_content())
# Common Mistakes Section
with st.expander("β οΈ Common Mistakes"):
st.markdown(self._get_common_mistakes_content())
# Advanced Tips Section
with st.expander("π Advanced Tips"):
st.markdown(self._get_advanced_tips_content())
def render_playground(self, col: st.delta_generator.DeltaGenerator, snippets: Dict[str, str]) -> None:
"""
Renders interactive coding playground with live execution.
Arguments:
col: Streamlit column object for rendering
snippets: Dictionary of available code snippets
"""
with col:
st.markdown("### π» Practice Playground")
# Code input area
code_input = st.text_area(
"Try Streamlit commands:",
key="playground_input",
value=st.session_state.get('code_input', ''),
height=200,
placeholder="Example:\nst.title('My Title')"
)
# Quick Snippets section
st.markdown("#### Quick Snippets")
# Split into two columns with better ratio for button alignment
snippet_col, button_col = st.columns([4, 1])
with snippet_col:
selected_snippet = st.selectbox(
"Choose snippet:",
list(snippets.keys()),
label_visibility="collapsed"
)
with button_col:
if st.button("Add", type="primary", use_container_width=True):
if 'code_input' not in st.session_state:
st.session_state.code_input = snippets[selected_snippet]
else:
# Add new line only if there's existing code
existing_code = st.session_state.code_input.strip()
new_code = snippets[selected_snippet]
st.session_state.code_input = f"{existing_code}\n{new_code}" if existing_code else new_code
st.rerun()
# Control buttons in equal columns
col1, col2, col3 = st.columns(3)
with col1:
if st.button("βΆοΈ Run", use_container_width=True):
try:
if code_input.strip():
exec(code_input)
except Exception as e:
st.error(f"Error: {str(e)}")
with col2:
if st.button("π Reset", use_container_width=True):
st.session_state.code_input = ""
st.rerun()
with col3:
if st.button("πΎ Copy", use_container_width=True):
st.code(code_input)
# Live output section
st.markdown("#### π¨ Live Output")
with st.container(border=True):
if code_input.strip():
try:
exec(code_input)
except Exception as e:
st.error(f"Error: {str(e)}")
# Tips section
with st.expander("π‘ Tips & Help"):
st.markdown("""
**Quick Tips:**
- Type or paste Streamlit commands
- Use snippets for quick start
- Click Run to see results
- Reset to clear all code
""")
def render_widget_help(self, col: st.delta_generator.DeltaGenerator) -> None:
"""
Renders comprehensive widget help content
"""
with col:
st.markdown("### π Widget Guide")
with st.expander("π― Basic Concepts", expanded=True):
st.markdown("""
**Widget Types:**
- Input widgets (text, numbers, dates)
- Selection widgets (dropdown, checkbox, radio)
- File widgets (uploaders, downloads)
- Display widgets (progress, status)
**Key Features:**
- Real-time updates
- State management
- Input validation
- Responsive layout
- Form handling
- Unique widget keys
""")
with st.expander("π‘ Best Practices"):
st.markdown(self._get_widgets_help_content())
with st.expander("π Examples"):
st.code("""
# Basic form example
with st.form('contact'):
name = st.text_input('Name', key='contact_name')
email = st.text_input('Email', key='contact_email')
message = st.text_area('Message', key='contact_message')
submit = st.form_submit_button('Send')
if submit:
st.success('Message sent!')
""")
def get_topic_tips(self, topic: str) -> str:
"""
Provides topic-specific tips and guidance.
Returns formatted markdown string with helpful information.
Customizes content based on current tutorial topic.
Arguments:
topic: Current tutorial topic name
Returns:
str: Markdown formatted tips and help content
"""
tips = {
"Basic Text Elements": """
**Quick Tips:**
- Use markdown for formatting
- Try different header levels
- Combine text elements
- Use colored text with :color[text]
""",
"Input Widgets": """
**Quick Tips:**
- Use unique keys for widgets
- Store widget values in variables
- Add validation for inputs
- Combine widgets for complex inputs
"""
}
return tips.get(topic, "Tips coming soon!")
def run(self) -> None:
"""
Main execution method for the Streamlit Tutorial application.
Handles topic selection and content rendering.
Manages overall application flow and state.
"""
with st.sidebar:
st.title("Streamlit Tutorial")
st.session_state.current_topic = st.radio(
"Choose a Topic:",
["Basic Text Elements", "Input Widgets", "Layouts & Containers",
"Data Display", "Charts & Plots", "Interactive Components"]
)
if st.session_state.current_topic == "Basic Text Elements":
cols = st.columns([1.2, 1, 1])
self.render_text_elements(cols[0])
self.render_help_section(cols[1])
self.render_playground(cols[2], dict(self.get_text_elements()))
elif st.session_state.current_topic == "Input Widgets":
cols = st.columns([1.2, 1, 1])
self.render_input_elements(cols[0])
self.render_help_section(cols[1])
self.render_playground(cols[2], dict(self.get_input_elements()))
def main():
try:
app = StreamlitTutorial()
app.run()
except Exception as e:
st.error(f"Application Error: {str(e)}")
st.write(f"Traceback: {traceback.format_exc()}")
if __name__ == "__main__":
main()
|