> ## Documentation Index
> Fetch the complete documentation index at: https://genai.codewithsiva.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Progress Report Layout

> Practical project guiding you through layouts, columns, tabs, and pages in Streamlit

In this tutorial, we will build a **Student Progress Report Application** to practice structuring and laying out user interfaces in Streamlit.

We will cover layout elements step-by-step:

1. **Containers, Borders, and Dividers** (`st.container`, `st.divider`)
2. **Columns** (`st.columns`)
3. **Tabs** (`st.tabs`)
4. **Multipage Apps** (`pages/` directory)

### 📄 Sample Dataset (`grades.csv`)

Before starting the exercises, create a file named `grades.csv` in your project folder with the following Indian school grades dataset:

```csv theme={null}
Subject,Marks,Grade
Mathematics,95,O
Science,89,A+
English,91,O
Social Science,84,A
Hindi,88,A+
Sanskrit,92,O
Computer Science,96,O
```

## 🛠️ Step 1: Layout, Borders, & Dividers

We will organize the student info and AI feedback inside distinct visual boxes (containers with borders) separated by clean horizontal lines.

Create a file named `exercise_1_basic_layout.py` and add the following:

```python theme={null}
import streamlit as st

st.set_page_config(page_title="Student Progress Report", layout="centered")

st.title("🎓 Student Progress Report (Layout & Borders)")
st.write("Organizing data with containers, borders, and dividers.")

student_name = "Jane Doe"
student_class = "Grade 10"

# 1. Main container with a border
with st.container(border=True):
    st.subheader("👤 Student Profile")
    st.write(f"**Name:** {student_name}")
    st.write(f"**Class:** {student_class}")
    
    # 2. Divider line
    st.divider()
    
    st.subheader("📚 Subject Performance")
    st.write("Mathematics: 92/100 (A+)")
    st.write("Science: 88/100 (A)")
    st.write("English: 95/100 (O)")

st.divider()

# 3. Gen AI Feedback section with border
with st.container(border=True):
    st.subheader("🤖 GenAI Automated Analysis")
    st.info(
        "Jane shows outstanding performance, particularly in English and Mathematics. "
        "Recommendation: Encourage participation in advanced mathematics competitions."
    )
```

Run the script to see the borders and dividers:

```bash theme={null}
streamlit run exercise_1_basic_layout.py
```

## 🛠️ Step 2: Arranging Content in Columns

Next, let's display the student profile on the left and the academic grades side-by-side on the right using `st.columns`.

Create a file named `exercise_2_columns.py` and add the following:

```python theme={null}
import streamlit as st

st.set_page_config(page_title="Student Progress Report", layout="wide")

st.title("🎓 Student Progress Report (Columns)")
st.write("Displaying details side-by-side using columns.")

student_name = "Jane Doe"
student_class = "Grade 10"

# 1. Define two main side-by-side columns (ratio 1:2)
col_left, col_right = st.columns([1, 2])

with col_left:
    with st.container(border=True):
        st.subheader("👤 Profile")
        st.write(f"**Name:** {student_name}")
        st.write(f"**Class:** {student_class}")

with col_right:
    with st.container(border=True):
        st.subheader("📊 Subject Grades")
        
        # 2. Display grades in 3 equal inner columns
        c1, c2, c3 = st.columns(3)
        c1.metric("Mathematics", "92%", "A+")
        c2.metric("Science", "88%", "A")
        c3.metric("English", "95%", "O")

st.divider()

with st.container(border=True):
    st.subheader("🤖 GenAI Automated Analysis")
    st.success("Jane shows outstanding performance. Focus on STEM extra-curricular activities.")
```

Run the script:

```bash theme={null}
streamlit run exercise_2_columns.py
```

## 🛠️ Step 3: Structuring Views in Tabs

When you have a lot of content, columns can get cramped. We can use `st.tabs` to create clean, switchable views for Overview, Grades, and AI Insights.

Create a file named `exercise_3_tabs.py` and add the following:

```python theme={null}
import streamlit as st

st.set_page_config(page_title="Student Progress Report", layout="wide")

st.title("🎓 Student Progress Report (Tabs)")
st.write("Organizing views using tabs.")

student_name = "Jane Doe"
student_class = "Grade 10"

with st.container(border=True):
    st.subheader(f"👤 {student_name} ({student_class})")

# 1. Define tabs
tab_overview, tab_subjects, tab_ai = st.tabs(["📋 Overview", "📊 Subject Grades", "🤖 AI Recommendations"])

with tab_overview:
    st.write("### General Summary")
    st.write("Attendance: **96%**")
    st.write("Overall GPA: **3.91 / 4.0**")

with tab_subjects:
    st.write("### Subject Breakdown")
    c1, c2, c3 = st.columns(3)
    c1.metric("Mathematics", "92%", "A+")
    c2.metric("Science", "88%", "A")
    c3.metric("English", "95%", "O")

with tab_ai:
    st.write("### GenAI Analysis Feedback")
    st.info("Based on grade patterns: Strong deductive reasoning. Recommend joining the coding club.")
```

Run the script:

```bash theme={null}
streamlit run exercise_3_tabs.py
```

## 🛠️ Step 4: Structuring a Multipage App

Finally, to create a fully production-ready structure, let's separate these features into multiple pages using Streamlit's native `pages/` directory layout.

### File Structure

Set up the files exactly as shown below:

```text theme={null}
student_report/
├── app.py          # Main Landing Page
└── pages/          # Must be named "pages"
    ├── 1_📊_Detailed_Metrics.py
    └── 2_🤖_AI_Feedback.py
```

### 1. Main Page (`app.py`)

```python theme={null}
import streamlit as st

st.set_page_config(page_title="Student Progress Report Hub", layout="centered")

st.title("🎓 Student Progress Report Hub (Multipage)")
st.write("Welcome to the Student Portal. Please use the sidebar to navigate:")

with st.container(border=True):
    st.subheader("👤 Active Student Profile")
    st.write("**Name:** Jane Doe")
    st.write("**Class:** Grade 10")
```

### 2. Metrics Page (`pages/1_📊_Detailed_Metrics.py`)

```python theme={null}
import streamlit as st

st.set_page_config(page_title="Detailed Metrics", layout="wide")

st.title("📊 Academic Scorecard & Metrics")

with st.container(border=True):
    col1, col2, col3 = st.columns(3)
    col1.metric("Mathematics", "92%", "A+")
    col2.metric("Science", "88%", "A")
    col3.metric("English", "95%", "O")
```

### 3. AI Feedback Page (`pages/2_🤖_AI_Feedback.py`)

```python theme={null}
import streamlit as st

st.title("🤖 GenAI Automated Student Feedback")

with st.container(border=True):
    st.subheader("Automated Comments")
    st.info("Jane shows outstanding performance. Focus on STEM extra-curricular activities.")
```

Run the multipage app from the root directory:

```bash theme={null}
streamlit run app.py
```

## 🛠️ Step 5: Capstone Exercise — Dynamic CSV Report Generator

### ❓ Question / Goal

Build an application where a teacher can enter student details (Name, Roll Number, Branch) and upload a CSV file containing marks in various subjects. The application should dynamically parse the uploaded file, display the student details in a clean layout, show the detailed scorecard, and render a performance summary (average score, highest marks, etc.) with custom remarks.

### 📋 Implementation Plan

1. **Define Layout**: Use `st.columns([1, 2])` to split the page into an **Input Form** (left column, width 1) and the **Generated Report** (right column, width 2).
2. **Collect Inputs**: Place student metadata fields inside a `st.form` block on the left column.
3. **Handle CSV Upload**: Include a `st.file_uploader` inside the form to accept `.csv` files.
4. **Parse & Verify Data**: On submit, parse the CSV using `pandas` and check that the required columns (`Subject`, `Marks`, `Grade`) exist.
5. **Render Report Card**:
   * Render student details inside a bordered container.
   * Display the subject grades using `st.dataframe`.
   * Calculate summary stats (average, max marks) and display them in columns using `st.metric`.
   * Output rule-based feedback remarks in a color-coded alert (`st.success`, `st.warning`).

### 📦 Key Components Used

* `st.form` & `st.form_submit_button`: Groups input elements together to prevent page reruns on every keystroke.
* `st.file_uploader`: Reads user-supplied CSV files into memory.
* `st.columns`: Organizes the sidebar layout as well as the inner metrics side-by-side.
* `st.container(border=True)`: Visually isolates the Profile, Grades, and Summary sections.
* `st.dataframe`: Formats the parsed tabular marks data.
* `st.metric`: Displays the computed GPA, average score, and total count.

### 📝 Code Implementation (`exercise_4_csv_report.py`)

```python theme={null}
import streamlit as st
import pandas as pd

st.set_page_config(page_title="Student CSV Progress Report", layout="wide")

st.title("🎓 Dynamic Student Progress Report")
st.write("Generate a structured academic report card by entering details and uploading a marks CSV file.")

# Layout: Split page into Input Form (left) and Generated Report (right)
col_input, col_report = st.columns([1, 2])

# Left column: Inputs
with col_input:
    st.subheader("📝 Input Information")
    with st.form("report_form"):
        student_name = st.text_input("Student Name", value="Jane Doe")
        roll_number = st.text_input("Roll Number", value="CSE-2026-104")
        branch = st.selectbox("Branch", ["Computer Science", "Electronics", "Mechanical", "Civil"])
        
        uploaded_file = st.file_uploader("Upload Marks CSV File", type=["csv"])
        
        generate = st.form_submit_button("Generate Report Card")

# Right column: Output Report Card
with col_report:
    st.subheader("📄 Generated Report Card")
    
    if generate:
        if not student_name.strip() or not roll_number.strip():
            st.error("Please enter a valid Student Name and Roll Number.")
        elif uploaded_file is None:
            st.warning("Please upload a CSV file containing the marks.")
        else:
            try:
                # Load and parse CSV
                df = pd.read_csv(uploaded_file)
                
                # Check for required columns
                required_cols = {"Subject", "Marks", "Grade"}
                if not required_cols.issubset(df.columns):
                    st.error("The CSV file must contain 'Subject', 'Marks', and 'Grade' columns.")
                else:
                    # 1. Student Details Section
                    with st.container(border=True):
                        st.subheader("👤 Student Profile Details")
                        c1, c2, c3 = st.columns(3)
                        c1.markdown(f"**Name:** {student_name}")
                        c2.markdown(f"**Roll Number:** {roll_number}")
                        c3.markdown(f"**Branch:** {branch}")
                    
                    st.divider()
                    
                    # 2. Subject Marks Table
                    with st.container(border=True):
                        st.subheader("📚 Academic Grades Breakdown")
                        st.dataframe(df, use_container_width=True, hide_index=True)
                    
                    st.divider()
                    
                    # 3. Summary Analytics
                    with st.container(border=True):
                        st.subheader("📊 Performance Summary")
                        
                        avg_score = df["Marks"].mean()
                        max_score = df["Marks"].max()
                        total_subjects = len(df)
                        
                        sm1, sm2, sm3 = st.columns(3)
                        sm1.metric("Total Subjects", total_subjects)
                        sm2.metric("Average Score", f"{avg_score:.2f}%")
                        sm3.metric("Highest Mark", f"{max_score}%")
                        
                        # Remarks
                        st.write("**Overall Remarks:**")
                        if avg_score >= 90:
                            st.success("Outstanding! The student shows exceptional performance across all subjects.")
                        elif avg_score >= 75:
                            st.info("Good! Consistent performance, with room for improvement in specific areas.")
                        else:
                            st.warning("Needs Attention. Recommend regular extra sessions and tutorial support.")
            
            except Exception as e:
                st.error(f"Error reading CSV file: {e}")
    else:
        st.info("Fill out the form and click 'Generate Report Card' to view the report.")
```

To run this exercise:

```bash theme={null}
streamlit run exercise_4_csv_report.py
```
