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()